The past few weeks I’ve been on loan to work on Ubuntu Touch, specifically the power daemon, powerd. Seth Forshee and I have been working to enhance the power daemon so that system services can interact with it to request that the device stay active, that is, that the device not suspend. The initial round of this work is complete and is landing today. (Note: There is a lot of low-level kernel interaction stuff landing in the code today too, that is not covered here)
What’s landing today allows a system service, talking on the system bus, to request the Active system power state. We currently only have two states, Active and Suspend. When there are no Active state requests, powerd will drop the state to Suspend and suspend the device. This is best illustrated by showing how we use the states internally: For example, the user activity timer holds an Active state request until it expires at which point the request is dropped. The system then scans the list of outstanding state requests and if none are left, it drops the system to Suspend and suspends the system. Pressing the power button works in the same way, except as a toggle. When the screen is on, pressing the power button drops an active request, when off, it makes an active request.
For now, this ties screen state to system power state, although we plan to change that later. There is no way currently to request a display state independently of a system state, however that is planned for the future as well. For example, a request may be made to keep the screen at a specified brightness.
The API is subject to change and has a few trouble spots, but is all available to look at in the code here. Taking a look at the testclient C code or tester.sh will best illustrate the usage, but remember this is not for apps, it is for other system services. The usage for an app will be to request from a system service via an API something like “playVideoWithScreenOn()”, and then the system service will translate that into a system state request.
Trying it Out
If you want to play with it on your phone, use gdbus to take an active state request and you can block system suspend. You will need to install libglib2.0-bin on your phone if not already installed.
# request active state from PID 99 (a made-up PID). This returns a cookie, which you need to later drop the request. The cookie here is “1″
phablet@localhost:~$ sudo gdbus call --system --dest com.canonical.powerd --object-path\ /com/canonical/powerd --method com.canonical.powerd.requestSysState 1 99 [sudo] password for phablet: (uint32 1,)
show the outstanding requests.
phablet@localhost:~$ sudo gdbus call --system --dest com.canonical.powerd --object-path /com/canonical/powerd --method com.canonical.powerd.listSysRequests ([(':1.29', 99), ('internal', 36)],)
now we pass in the cookie we received earlier and clear our request
phablet@localhost:~$ sudo gdbus call --system --dest com.canonical.powerd --object-path /com/canonical/powerd --method com.canonical.powerd.clearSysState 1 ()
recheck the list
phablet@localhost:~$ sudo gdbus call --system --dest com.canonical.powerd --object-path /com/canonical/powerd --method com.canonical.powerd.listSysRequests ([('internal', 36)],)
If you want to see everything that is going on, check the powerd log file. sudo tail -f /var/log/upstart/powerd.log. For now we have it logging in debug mode, so it will tell you everything.
But My Device Isn’t Suspending
Even though we request suspend, we may not get to suspend, because it appears that at least on some devices (Nexus4 and maybe others) Android’s sensor service is holding a wakelock. We are also working on this issue.
<6>[ 1249.183061] lm3530_backlight_off, on: 0 <6>[ 1249.185105] request_suspend_state: sleep (0->3) at 1249179158043 (2013-05-21 16:38:57.769127486 UTC) <4>[ 1249.185441] [Touch D]touch disable <4>[ 1250.217488] stop_drawing_early_suspend: timeout waiting for userspace to stop drawing <3>[ 1250.244132] dtv_pipe is not configured yet --> <6>[ 1250.248679] active wake lock sns_periodic_wakelock <6>[ 1250.248710] PM: Syncing filesystems... <6>[ 1250.329741] sync done.
We have a bunch of stuff left to do here, the first obvious one is that using a monotonically increasing int for the cookie is not a great plan, so we will switch that to something like a UUID. We also need to send out dbus signals when the system goes into suspend so that services can react. We need to clean-up some of the dbus code while we’re doing that. Finally we plan on implementing display state requests using a similar model to the power state requests. Throughout all of this we need to start integration with the rest of the system.