Power-Efficient applications on Windows Mobile

Sometimes it happens that a developer asks for suggestions about how to design an application from the very beginning so that it'll be power-efficient, and therefore I now have a list of links\suggestions that may be interesting to share...

 DWORD PwrFlag, NameLength; 
TCHAR StateName[64] = { 0 }; 
GetSystemPowerState(StateName, NameLength, &PwrFlag); 
if(POWER_STATE_ON != PwrFlag) 
   //perform action only if display is on.
   //for example, in case of Home plugins:
   InvalidateRect(hPlugInWnd, NULL, TRUE);
  • Or the application may listen on Activity Timers through the State&Notification Broker to perform tasks only when necessary.
  • In some cases you may want to turn off only the display when performing some actions - I knew a solution based on ExtEscape API (see old Alex Feinmain's managed sample) and thought that this was supported for OEMs only, however looking at the official doc it's for ISV Application Developers as well (in any case, note that "[...] The device capabilities this function accesses must be implemented by an OEM. ", thus meaning that you can see different behaviors on different devices):
 HDC gdc = ::GetDC(NULL);
VIDEO_POWER_MANAGEMENT vpm;
vpm.Length = sizeof(VIDEO_POWER_MANAGEMENT);
vpm.DPMSVersion = 0x0001;
vpm.PowerState = VideoPowerOff;
 
// Power off the display
ExtEscape(gdc, SETPOWERMANAGEMENT, vpm.Length, (LPCSTR) &vpm, 0, NULL);
Sleep(5000); //just for demonstration purposes
vpm.PowerState = VideoPowerOn;
 
// Power on the display
ExtEscape(gdc, SETPOWERMANAGEMENT, vpm.Length, (LPCSTR) &vpm, 0, NULL);
::ReleaseDC(NULL, gdc);
  • You may want to have applications continue running when the device is suspended. This is simply not possible, as the processor is in idle state and doesn't offer any CPU cycle to be used by applications. Moreover, an application can't detect entering suspend state: "[...] While an application cannot detect the transition into SUSPEND mode, it is able to detect the transition from SUSPEND mode. It does this by calling the CeRunAppAtEvent function, which takes two parameters: a path and an event code" (from Power Management Features of Windows CE .NET). So if you really want to continue having the application running you can use CeRunAppAtTime() invoking SystemIdleTimerReset() every minute to prevent the device to suspend. You may turn the display off to save battery tough, at least. In such cases, I would encourage revisiting the architecture of the application. In many cases you can simply use CeAppRunAtTime() to perform a task: consider that the API will wake the device up if it's suspended. Note that if the device was suspended and waken up by CeRunAppAtTime it will be in a state between Power On and Suspend: you need to call SetSystemPowerState API to really turn the device on:
 SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE)

 

I imagine there are many other techniques out there to save devices to drain battery... feel free to add whatever link or suggestions in a comment! Smile

 

Cheers,

~raffaele