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.
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
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.
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.
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:
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 |
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.
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. For details on this API, visit: http://msdn.microsoft.com/library/psdk/shellcc/shell/functions/SHIsFileAvailableOffline.htm.
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:
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:
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.
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.