In fact it's possible to do this with only minimal changes to the
userspace, providing you can specify all your possible hardware wakeup
sources. (On the Android this list probably isn't very large -- I
imagine it includes the keypad, the radio link(s), the RTC, and maybe
a few switches, buttons, or other things.)
Here's how you can do it. Extend the userspace suspend-blocker API, so
that each suspend blocker can optionally have an associated wakeup
The power-manager process should keep a list of "active" wakeup
sources. A source gets removed from the list when an associated
suspend blocker is activated.
When the "active" list is empty and no suspend blockers are activated,
the power manager freezes ALL other processes, trusted and untrusted
alike. It then does a big poll() on all the wakeup sources. When the
poll() returns, its output is used to repopulate the "active" list and
processes are unfrozen.
(You can also include some error detection: If a source remains on the
"active" list for too long then something has gone wrong.)
To do all this you don't even need to use cgroups. The existing PM
implementation allows a user process to freeze everything but itself;
that's how swsusp and related programs work.
This is still a big-hammer sort of approach, but it doesn't require any
How do you do this safely? If you remove the active wakeup only when
activating the suspend blocker, you will never unblock suspend if
another wakeup event happens after user-space blocked suspend but
before user-space read the events.
Also, I'm not sure we can easily associate a wakeup event with a user
space suspend blocker. For instance when an alarm triggers it is
sometimes because of a user-space alarm and sometimes because an