Chapter 6: OnNow/ACPI Support

 

The OnNow design initiative is a set of design specifications for system hardware and software applications which enable a PC to deliver the instantly available capabilities consumers expect from TVs, VCRs, stereos and other appliances.

Applications must participate in system-wide power management decision-making to establish error-free handling of power down and power up scenarios. This participation includes responding appropriately to events such as sleep requests and wake notifications so that user and application data is preserved.

Note   In this chapter, the term "sleep" means that the system is on standby or is in hibernation. To the application, standby and hibernation are the same. The difference occurs in how the operating system determines what gets powered-down. The application does not need to provide any additional feedback to make this determination.

Customer Benefits

  • OnNow reduces power consumption via the Advanced Configuration and Power Interface (ACPI); the system is able to enter a lower power state (or sleep mode) that appears to be "off" but is still powered enough to enable the system to power up (or wake) to handle timed events or device related needs such as receiving a fax
  • The PC is instantly available to the user because it can rapidly return from a low power state to a fully-functional state
  • Customers can rely on their PCs to power down and up in a way that is easily understood and predictable

Requirements

6.1  For applications allowed to prevent sleep when busy, indicate busy application status properly

6.2  In the non-connected state, your application must allow sleep and resume normally

6.3  In the connected case, handle sleep requests properly

6.4  Handle wake from normal sleep without losing data

6.5  Handle wake from critical sleep properly

References

How to Comply with OnNow/ACPI Requirements

About OnNow Power Management in Windows

The key issue for applications is that upon waking from a sleep state it is possible that previously available network connections and removable drives (such as disks in docking stations) may no longer be available. To help reduce the risk of data loss problems, applications are notified of power management events through the WM_POWERBROADCAST message. Applications must respond to these messages properly so the system can transparently enter and wake from sleep.

When the operating system initiates a sleep request, it sends the running applications a query to determine if it is safe to go to sleep. It does this by sending a WM_POWERBROADCAST message with a wParam value of PBT_APMQUERYSUSPEND.

Once all running applications have responded to the suspend query, the OS will send out a new WM_POWERBROADCAST with one of two wParam values. If all applications responded TRUE to the PBT_APMQUERYSUSPEND message, the operating system will send PBT_APMSUSPEND to notify applications that the system is about to go into sleep. If any application returned BROADCAST_QUERY_DENY to the PBT_APMQUERYSUSPEND message, the OS will send a PBT_APMSUSPENDFAILED message. In this case, the application should restore its state and resume normal operations.

Note   OS will wait indefinitely, provided the app has pulled the message from the message queue.

Key Windows Messages

PBT_APMQUERYSUSPEND:
This message serves as a request to the application to determine if it can go to sleep and provides the primary opportunity for applications to take any necessary actions to prepare for sleep. Note that the system will wait approximately 20 seconds for an app to pull this message from the message queue. If the system doesn’t see the message pulled then it will assume a true response. (This is done to handle applications that are not processing system messages, perhaps because they are no longer functioning properly.) However, once the message is pulled from the message queue, applications have as long as they need to determine if they can allow sleep, perform any required operations, and respond to the message. Of course, applications should use the minimal amount of time needed to prepare for sleep so as not to cause unreasonable delays.

PBT_APMSUSPEND:
This message is merely a notification that the system is about to sleep. The operating system allows approximately 20 seconds for an application to handle this notification. After 20 seconds the OS will continue the sleep state processing. Thus, applications that are performing operations after their 20 second allotment could potentially have their operations interrupted. Therefore, applications should initiate the majority of their shut-down tasks when they receive the PBT_APMQUERYSUSPEND, as there may not be enough time if they wait till receiving PBT_APMSUSPEND.

Note   In some circumstances, the sleep request may be canceled. If this occurs, the operating system follows the WM_POWERBROADCAST/PBT_APMQUERYSUSPEND message with WM_POWERBROADCAST/PBT_APM_QUERYSUSPENDFAILED message. In this case, the application should restore all its data to a working state and continue all operations normally.

The zero bit of the lParam value, known as the UI bit, indicates whether user interaction is possible. If no user display device is available (e.g. the user has closed the laptop lid or the system believes there is no user present), the system will set the UI bit to 0. Otherwise the UI bit will be 1.

Considerations for Applications that Install as Services

By default, the system does not notify services of power management events. The system will initiate power state transitions without any action required on the part of the service.

If your application installs services and those services must participate in power management decisions:

  1. You must follow these steps to receive notification of power management events:
    • The service must notify the system that the service will accept and process power events as follows: When the service calls SetServiceStatus, it must set the SERVICE_ACCEPT_POWEREVENT bit in the dwControlsAccepted field in the SERVICE_STATUS structure.
    • The service’s control handler must be a "HandlerEx" function. Services must use the RegisterServiceCtrlHandlerEx function to register a "HandlerEx" control handler function. "HandlerEx" control handler functions support the new power event control codes (whereas "Handler" control handler functions do not).
  2. Once you have enabled notification of power management events for your service, the service must respond and process the SERVICE_CONTROL_POWEREVENT control requests in the same manner as for WM_POWERBROADCAST messages enumerated earlier in this chapter to comply with the OnNow/ACPI requirements. A SERVICE_CONTROL_POWEREVENT is equivalent to an application receiving a WM_POWERBROADCAST message.

Comparison of Power Management Notifications

  Non-Service Service
Power Event WM_POWERBROADCAST SERVICE_CONTROL_POWEREVENT
Event parameter Wparam DwEventType
Event parameter Lparam LpEventData
Accept Request Return TRUE Return NO_ERROR
Deny Request Return BROADCAST_QUERY_DENY Return any Error code

6.1  For applications allowed to prevent sleep when busy, indicate busy application status properly

If the system detects that it is idle for extended periods of time, it will attempt to go to sleep. The idle times that Windows uses for putting the system to sleep are set using the power management control applet.

Some applications perform functions that are readily visible to the user but may appear to the system as being idle (e.g. slide presentations, DVD movie viewing, CD audio playing). In these cases, the expectation of the user is that the system will not sleep during these operations because he/she considers the system to be busy. In these scenarios only, an application must signal to the system that it is not idle. One way to achieve this is to call the SetThreadExecutionState() API function, which marks the computer as busy.

When marked as busy, the operating system will not send sleep requests as a result of the computer being idle. For example, the Windows 2000 redirector will mark a thread as busy if the thread has an open file on a network device, so in this case an application would not receive sleep requests from the operating system unless the user specifically requests the system to sleep.

Note   Applications that use SetThreadExecutionState() will still receive sleep requests if the user specifically requests the system to sleep. These requests must be handled as specified in all the other requirements in this chapter.

Calling SetThreadExecutionState with the ES_SYSTEM_REQUIRED flag will keep the system from going to sleep if it thinks it is idle. Calling it with the ES_DISPLAY_REQUIRED flag will keep the display from being turned off if the system thinks the display is idle.

Note   Calling the SetThreadExecutionState function without the ES_CONTINUOUS flag will simply reset the idle timers and the system will go to sleep if the timers run out again. To keep the system or the display awake it may be necessary to use the ES_CONTINUOUS flag along with either the ES_SYSTEM_REQUIRED or the ES_DISPLAY_REQUIRED flag. This will freeze the respective timers. If the ES_CONTINUOUS flag is used in conjunction with ES_DISPLAY_REQUIRED or ES_SYSTEM_REQUIRED, applications should then release the idle timers by resending just the ES_CONTINUOUS flag when there is no longer a need to prevent them from timing out.

6.2  In the non-connected state, your application must allow sleep and resume normally

The "non-connected" case is when the application does not have any network resources open.

If an application is in the non-connected state, it must respond TRUE when it receives a PBT_APMQUERYSUSPEND request from the operating system. Upon waking, it must resume to stable state (see: Requirement 6.4).

About Client Side Caching
If the user has enabled Client Side Caching (CSC), it is not readily apparent whether a file is on a network or not. The Client Side Caching feature in Windows 2000 allows a user to store an offline version of a network file locally. This is done transparently to the application. Thus, even in the non-connected case, a file in the client side cache will appear as a network file.

If the file is in the cache, your application must still allow sleep. To determine whether the file or folder is in the cache, use the SHIsFileAvailableOffline API. It also determines whether the file would be opened from the network, from the local Offline Files cache, or from both locations.

6.3  In the connected case, handle sleep requests properly

The "connected" case is when the application has a network resource open. An example would be if your application has a file open on the network.

Your application must respond to PBT_APMQUERYSUSPEND in one of the following ways:

  1. If your application can avoid data loss, the application should prepare for sleep by ensuring that all outgoing operations are completed and then return a value of TRUE for this message.

  2. If data loss is possible (e.g. an application has unsaved data on a network location), the application should check the UI bit to see if interaction with the user is possible.

    If the UI bit is 0 (e.g. user interaction is not possible), the application must either return BROADCAST_QUERY_DENY, or wait until the operation causing the busy status is finished, and then prepare to go to a sleep state and return TRUE.

    If the UI bit is 1, the application should query the user to determine the user’s desired course of action. Some suggested courses of action are:

    • Offer to save the user’s work and proceed to sleep
    • Offer to discard the user’s work and proceed to sleep
    • Offer to cancel the sleep event
    • Instruct the user on the actions required by the user to allow a sleep request
    • If the risk of data of loss is eliminated while waiting for user input (for example your app was processing a transaction when the sleep request was sent, and the transaction completes before the user responds), your app should automatically allow sleep
  3. Your application may deny sleep, provided it either gives the user the option to rectify the non-sleeping situation or gives direction on how the user can get to a state that allows sleep (though this is not preferred behavior).

6.4  Handle wake from normal sleep without losing data

When the system wakes from sleep mode the operating system will notify the applications with a WM_POWERBROADCAST/PBT_APMRESUMESUSPEND message. The application must then restore itself to its pre-sleep state, preserving all data while maintaining app and system stability. If any data cannot be fully restored, the application must notify the user, and it may seek the user’s aid in restoring data to a state acceptable to the user.

Note that when the system wakes automatically (from a timer), the system broadcasts the PBT_APMRESUMEAUTOMATIC event to all applications. Because the user is not present, most applications should do nothing at this point. Event-handling applications, such as fax servers, should handle their events. If you wish to determine whether the system is in this state, call the IsSystemResumeAutomatic function.

Important   Whenever the system wakes from S4 (for whatever reason) the OS always treats this as an automatic event because it has no way of knowing why it woke from S4. In this case, it will always send the PBT_APMRESUMEAUTOMATIC message.

If the system detects user activity after broadcasting PBT_APMRESUMEAUTOMATIC, the system will broadcast the PBT_APMRESUMESUSPEND event and turn on the display. At this point this message (PBT_APMRESUMESUSPEND) should be handled by all apps as described above.

6.5  Handle wake from critical sleep properly

In certain situations, the operating system may need to perform a critical sleep operation. For example, if battery capacity is critically low, or if the computer temperature is critically high and must be shut down to prevent hardware damage. A user may also initiate a critical sleep request in an urgent situation. For example, the user has to board a plane and must power down the computer instantly. In cases of critical sleep, the applications will not be notified by the operating system of the impending sleep event. Your application will not get the opportunity to perform any actions defined in the previous requirements. When the computer is wakened, the operating system will indicate in its wake notification whether the shut down was critical by sending the PBT_APMRESUMECRITICAL notification.

Upon waking from critical sleep, applications must not crash and must wake to a stable state: no stalls, crashes, or corruption of files that were not opened by the application. Data may be lost, but the application should notify the user of the data loss that occurred. In general, the application should handle the at least as well as they recover when restarted after either a system or application crash.

How to Pretest Applications for OnNow/ACPI Support

Verify Applications Allow and Resume from Normal Sleep in the Non-connected Case

  • Open a file on a local hard disk, edit it (don't save) and put the computer to sleep, and then wake the computer
  • Verify that the application continues to run, the file can be saved, and so forth
  • To test sleep when client-side caching is enabled:
    • Make a file that is on a network share available for offline line (right-click on the file and select "Make Available Offline")
    • Disconnect from the network
    • Open that file from within your application
    • Request the system to sleep and verify that the system goes to sleep correctly
    • Then wake the computer and verify that the application continues to run and the file is loaded

Verify Applications Respond Properly in the Connected Case

  • Open a file on the network
  • Attempt to put the system to sleep
  • Verify that the one of the following occurs:
    • The system goes to sleep correctly; upon waking the computer, verify that the application continues to run and that the application attempts to reopen the file
    • The application prompts the user to determine the appropriate course of action
    • If the application denies sleep, it must provide the user information on how he or she can get to a state that allows sleep

Pretest Presentation Applications for OnNow/ACPI Compliance

  1. In the Power control panel, set the system idle time as low as possible.
  2. Start the application and play a presentation.
  3. Wait for a time longer than the system idle time, and verify that the computer does not go to sleep and that the display does not go blank during that time.

Verify that Applications Respond Properly to Sleep Requests when Data Loss Could Occur

  1. Start the application and get it to a point where it starts operations that might corrupt data if interrupted.
  2. Press the power button to put the computer to sleep.
  3. Verify that the application puts up a dialog box to prompt the user about possible loss of data. Test the following cases:
    • Respond "NO" to the dialog box and verify that the computer doesn't go to sleep and that the application continues as normal without losing any data
    • Respond "YES" to the dialog box and verify that the computer goes to sleep
    • Wake the computer and ensure that the computer doesn’t hang or cause the operating system to crash
    • Ensure that the application doesn't hang or crash, but that it notifies the user of any possible data loss and attempts to recover all possible data

Verify Response to Critical Sleep Requests

  1. Under the start menu select "Shut Down". In the Shut Down dialog box, select the "standby" option while holding down the CTRL key. This will force a critical standby to occur.
  2. Wake the computer by pressing the power button. Verify that your application does not cause any destabilizing behavior such as hanging or crashing, and that it attempts to recover all possible data. If user data is lost, the application must inform the user.