From Android's point of view, whether the system goes to sleep or not should be decided by the upper level application, so Android introduced Wakelocks and SystemSuspend service
- For an introduction to wakelocks, see:Wakelocks framework design and implementation
- For SystemSuspend Service, see:SystemSuspend Service
- Code path: system/hardware/interfaces/suspend/1.0/default/
- The service creates two threads:
- Main thread: respond to requests from Client to allocate wakelock, increase/decrease suspend counter
- Pending thread: control system hibernation, determine whether the system meets the conditions to enter the hibernation (in the framework will be based on a number of events, such as resting and lighting the screen, dynamic switch autosuspend, and thus dynamically open/end the pending thread)
The implementation of hanging threads is similar to the process of autosleep (but needs to handle the synchronization of suspend counter with the main thread), and its pseudo-code can be referred to as follows:
while (1) { do { ret = read(&cnt, "/sys/power/wakeup_count"); //It's usually blocked here.,tillcntbecause of0 if (ret) { ret = write(cnt, "/sys/power/wakeup_count"); } else { countine; } } while (!ret); write("mem", "/sys/power/state"); /* goto here after wakeup */ ...... }
At the Android application level, wakelocks is used to provide a voting mechanism for each system module to vote on whether or not to allow the system to enter hibernation. When all modules vote to allow the system to enter hibernation and the PowerManagerService enables autosuspend, the pending thread in the SystemSuspend service detects this and attempts to allow the system to go to sleep.