Da un mio recente Webcast (che potete andarvi a vedere qui), ho voluto estrapolare le informazioni essenziali per metterle a disposizione di tutta la community di questo blog. Anzitutto chiariamo una cosa fondamentale: la gestione della batteria in un dispositivo Pocket PC e in uno Smartphone è completamente diversa. Infatti il primo può (anzi ...deve) dormire, mentre il secondo no. In pratica il modello SmartPhone è molto semplice...o è acceso o è spento...più chiaro di così :-).
Quando lo Smartphone è On tutte le funzionalità sono attive, mentre quando è Off tutte le applicazioni sono inattive, non si possono ricevere telefonate, non si ricevono i remainders degli appuntamenti e la batteria è preservata da qualunque tipo di consumo. Infatti possiamo toglierla senza effetti collaterali (considerando l’eventuale presenza della batteria di ricarica dell’orologio per non resettare il time alla successiva riaccensione).
Il modello PPC è molto più complesso, in quanto può essere On, Off oppure...“Asleep”. Ai fini della conservazione della batteria va sottolineato che nel caso in cui il dispositivo stia dormendo alcune funzionalità continuano ad essere attive (il pulsante on/off per es.). Una chiamata può risvegliare il dispositivo, così come un’applicazione schedulata per funzionare in un certo momento. PPC cercherà sempre di “dormire” e nelle impostazioni viene indicato “quanto” il dispositivo dovrà rimanere sveglio in mancanza di attività (tap, softkeys…). Questo tempo solitamente è di 3 minuti, scaduti i quali il sistema cade in uno stato di "dormi-veglia", a meno che non invochiamo esplicitamente una funzione void WINAPI SystemIdleTimerReset( void). E' così per esempio che riusciamo a far eseguire Windows Media Player per più di 3 minuti, o riusciamo a effettuare un lungo download da IE senza toccare il dispositivo.
Ma quanti stati esistono in un PPC oltre a ON e Off? Qui dovete avere la pazienza di andare a vedere nella chiave di registro [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Power\State] con l'aiuto dei remote tools di VS2005. Per esempo nell'emulatore SDK 6 Professional trovate una situazione del genere:
Vediamoli nel dettaglio i più importanti
On
L’utente può interagire con il sistema e tutte le funzionalità sono attive
BacklightOff
Introdotto in WM5, sta ad indicare che c’è stato un periodo di inattività e la backlight è stata spenta, ma le funzionalità sono ancora attive
UserIdle
C’è stato un lungo periodo di inattività per cui sia la backlight che lo schermo LCD sono stati spenti. Non viene generalmente utilizzato in dispositivi PPC (se vado in stato di sleep già lo schermo viene spento), ma prevalentemente negli SmartPhone.
ScreenOff
Ci sono delle applicazioni (Media Player) dove ad un certo punto lo schermo non è necessario. Si fornisce un bottone per spengere lo schermo, ma tutte le funzionalità sono su. E’ differente da UserIdle: lo schermo viene spento dall’utente esplicitamente e non dopo un periodo di inattività. In questo stato la pressione di un bottone o il tap dello schermo, non riattivano lo schermo stesso (solo il bottone On/Off). E' usato sia da PocketPC che da Smartphone.
Unattended
Lo schermo, la backlight e l’audio sono spenti. Usato solo nei PocketPC da applicazioni che non vogliono lanciare alert all’utente. L’utente pensa che il PPC sia “asleep”. ActiveSync usa per esempio questo stato quando ogni 5 minuti sincronizza il dispositivo senza chiedere nulla all'utente.
Resuming
PocketPC si sta risvegliando dallo stato di “asleep”. Lo schermo è spento. E’ utilizzato per dare al sistema la possibilità di passare in stato di Unattended senza…disturbare l’utente.
Suspended
E' lo stato di “R.E.M” del PocketPC. E’ tutto disattivato e il sistema non si risveglia a meno che qualche periferica non faccia un pò di …confusione
----------------------------------------------------
Power Manager
A beneficio di chi sviluppa applicazioni sui dispositivi, dalla versione Mobile 2003 viene fornita una libreria Pm.dll Power Manager che permette di interagire con gli stati di sistema e delle singole periferiche. L'architettura è la seguente:
Come si intuisce dalla figura, PM implementa diverse funzionalità che vanno dal comunicare con i drivers per la gestione dell’alimentazione dei devices, al comunicare con le applicazioni che vogliono modificare lo stato del sistema sino a notificate alle applicazioni i cambiamenti di stato del sistema. PM permette di gestire i devices in maniera indipendente dal modello di gestione di Windows Embedded CE dove questi ultimi ricevevano notifiche sullo stato del sistema tramite interrupt. I devices erano quindi “costretti” in uno spazio limitato per quanto riguarda quando e cosa fare.
Il Power Manager permette invece ai devices di ricevere notifiche sul cambiamento di stato tramite I/O control codes (IOCTLs). Questo permette una maggiore flessibilità (vengono gestiti dentro il contesto del thread) e disaccoppia la gestione del power state tra ogni device e il sistema nel suo intero. Alcuni device possono quindi essere spenti mentre il sistema è On…e viceversa.
Il Power Manager è implementato come una dynamic-link library DLL chiamata Pm.dll e linkata direttamente al processo Device.exe. Quest'ultimo invoca le entry points in Pm.dll quando vengono invocate le primitive (API) nelle applicazioni. Così facendo si permetterà ai devices di gestire intelligentemente il loro stato, dandogli tra l'altro la possibilità di implementare uno o più "device power states".
|
Device Power State
|
Registry Key |
|
Full On
|
D0
|
|
Low On
|
D1
|
|
StandBy
|
D2
|
|
Sleep
|
D3
|
|
Off
|
D4
|
Questi stati (D0-D4) rappresentano differenti situazioni in cui il device ricade per gestire la batteria in maniera differenziata. Vi rimando alla documentazione o al webcast per vedere come un'applicazione si sottoscrive al Pm, come quest'ultimo notifica in broadcast a tutte le applicazioni interessate a qualche cambiamento nello stato di gestione della batteria da parte del sistema e di come un'applicazione invii le proprie richieste a PM per far sì che il sistema cambi il proprio stato. In pratica dovranno essere viste le funzioni
HANDLE RequestPowerNotifications(
HANDLE hMsgQ,
DWORD Flags
);
BOOL StopPowerNotifications(
HANDLE h
);
HANDLE SetPowerRequirement(
PVOID pvDevice,
CEDEVICE_POWER_STATE DeviceState,
ULONG DeviceFlags,
PVOID pvSystemState,
ULONG StateFlags
);
DWORD GetSystemPowerState(
LPWSTR pBuffer,
DWORD Length,
PDWORD pFlags
);
DWORD GetDevicePower(
PVOID pvDevice,
DWORD dwDeviceFlags,
PCEDEVICE_POWER_STATE pDeviceState
);
Nella documentazione SDK 6 trovate tra gli altri un esempio di utilizzo delle API di PM.dll (che potete anche scaricarvi da qui). E' un esempio in cui l' applicazione comunica a PM.dll che è interessata ai cambiamenti di stato del sistema (subscription). L'applicazione poi tramite un bottone comunica a Pm.dll di modificare lo stato della BackLight. Quest'ultima azione farà saltare in uno stato diverso il sistema che verrà quindi notificato (notification) all'applicazione stessa. C'è insomma l'invocazione di quasi tutte le primitive più importanti di Pm.dll.