Android battery and memory optimizations – Google I/O 2016

ASHISH SHARMA: Welcome. And thank you for coming. And first of all, I want to thank everyone of you to have waited patiently outside and in the line. I know it’s really hot. So thank you for that. My name is Ashish Sharma. And I’m the tech lead of the Volta team inside Android. And we focus on making the battery lives of Android devices great. And I’m joined with my colleague Meghan. MEGHAN DESAI: Hi, everyone. My name is Meghan Desai. I’m a product manager on the Android framework team, working on battery life and memory optimizations.

ASHISH SHARMA: So today, we’re going to talk about two key resources on any mobile device that, when running low, can severely impact the way users use their phones, battery and memory. We’re going to look at some optimization techniques and some platform features, some APIs and battery diagnostic tools to take away the pain from diagnosing battery problems. Because we know it’s a non-trivial problem. Battery life, or extended battery life, is one at the top requested features on mobile devices today. The phones in our pockets are more powerful and more capable than any time before us. And there are hundreds and thousands of applications that keep us informed and entertained throughout the day.

But if there is one thing that all of us wish we had, it’s a phone whose battery doesn’t die at the end of the day. Now, how many here in the audience are worried that their phones will not last through the end of the day? All right. Almost everyone. And to speak for the same fact, we’ve seen that on the Play Store there are hundreds, if not more, of battery apps that claim to help extend battery life of mobile devices, and some with as many as 100 million downloads or more. So clearly, it’s a problem that our users face. We care about. And we in the Volta team in Android are very passionate about making it awesome. So let’s start looking at where does the power on our mobile phones go? Turns out, when the screen is on, it dominates the power consumption on your phone more than anything else.

When you have your screen on, you’re either playing a game, or watching a video, or maybe you’re surfing the internet. And screen turns out to be a very expensive component on the device, which is many orders of magnitude more, in terms of power consumption, than most components on the device. But our phones also spend a lot of the time in our pockets when the screen’s off, like right now. I hope it is. So when the screen is off and the user is not actively engaged or interacting with the device, the power consumption now starts getting dominated by the CPU and the networking radios. So it might be an application holding a Wakelock to do some activity. Or there might be a background job, or a background sync, trying to access the internet to sync some data in the background.

And all of that costs power. So when it comes to optimizing for power when the screen is off, we want you to think about three main design principles, Reduce, Defer, and Coalesce any and all background activity that you can. Now, what do I mean by this? Reducing the background activity for an app when the user is not actively engaged, or is not actively using the device, is something that only application developers that only you can do. You know the logic of your applications best. You know the constraints that you’re operating in.

And you also know what your users want from the application. But it’s really, really important that we try and stay away from that urge, from that temptation, to push data onto our devices and keep them fresh even when the user is not actively using the app. All of you raised your hands when I asked you if you thought battery was important. And our users are just like us. So we really want you to think about reducing any background activity that is possible that you can help. For activity that you cannot completely eliminate, and there’s going to be some cases like that, we want you to really think hard about deferring it until the time when the device is on charger. Because the moment the device is plugged in, any activity that you do essentially becomes free. And the user does not incur any battery cost for it. And finally, we realize, and we know, that there is going to be cases where you cannot get rid of them completely. You cannot defer them until the device gets on the charger. So for those, we want you to start using the JobScheduler API.

Because that is an API that lets Android batch and coalesce a lot of the background activity, not just from your applications, but from other applications as well, in order to make the most efficient use of the CPU and the background networking traffic. Now, this is really important. I want to spend a minute here. Every time your device wakes up from suspend, or it activates the mobile radio to do any networking connectivity, be it for a very small amount of data packet, there is a fixed cost that needs to get incurred. Your device goes into this high power state. And there is going to be a fixed overhead every time you wake up the device. So there’s an access cost. Now, the more applications can batch together any of their background activity and coalesce them, the more efficient the system becomes. And power on the device can be really, really reduced. Now, there are some features in the platform, in the Android operating system, that automatically help you do a lot of this Defer and Coalesce in your applications. MEGHAN DESAI: Yeah, that’s right, Ashish. Let’s start by reviewing a couple of features we launched with the Marshmallow release, Doze and App Standby.

Say you leave your phone on the nightstand overnight without plugging it in. And you wake up in the morning and your phone’s dead. You’re going to have a bad day. But what Doze tries to do is coalesce a lot of that power [INAUDIBLE] background activity that Ashish just talked about so that when you do wake up in the morning, and you’ve left this device unused overnight, it’s not draining your battery. And you have some juice left to go on with your day. So let’s take a look at how Doze works. Let’s suppose these orange bars that you’re seeing are some kind of background activity. And at some point, as I said, you put this device down. It’s stationary. So it’s sitting on your nightstand. It’s on battery. It’s not plugged in. And the screen’s off. And the way we tell that it’s stationary is we use a significant motion detector on the device. So that’s required for Doze. And at some point, we realize, oh, the device actually has been stationary for quite some time. At that point, we actually do a finer motion detection, just to make sure the device is not in a steadily moving vehicle.

We want to make sure that it’s stationary with respect to Earth as the reference point. OK. If this happens, at that point, the first phase of Doze kicks in. And this stays there for an order of tens of minutes. At this point, applications lose Wakelocks, Network Access, and there are no more GPS or Wi-Fi scans. And their Jobs and Syncs and Alarms get deferred until the next maintenance window. So maintenance window is where all that background activity gets coalesced to. This is where all these restrictions are lifted for a brief period of time for applications to be able to perform any kind of pending background activity to refresh the content. So what we’re really trying to do is balance battery life with the expectation of constant freshness that users have on their devices. Now, the device continues to be stationary, on battery with the screen off, then, we can see this repeated pattern, where the Doze windows are growing exponentially with maintenance windows in between. And this will continue until the Doze time, the green bars, get to about a few hours. So that’s Doze in the Marshmallow release.

Now, we also wanted to improve the power consumption of applications that you haven’t used over a period of time. And so to optimize that, we launched App Standby. Let’s keep going. Apps that are unused after some period of time get considered to be on standby. So usage, in this case, means applications that have had a foreground service, some kind of an activity or process, they have had a notification on the lock screen that you’ve seen, or the app is explicitly launched by the user. And if this hasn’t happened over a period of time, then that application loses network access. And its jobs and syncs are deferred while the device is on battery. So they’re deferred to when you plug in the device. But once you plug in the device, if the application is still not used, then it will still be considered standby. And the next time you unplug the device, it will still, again, lose network access, and its jobs and syncs will be deferred to the next time the device gets plugged in.

ASHISH SHARMA: Wait, Meghan. So you’re saying if I have an instant messaging app, and I don’t receive a message for a long time, and it goes in app standby, then I might miss the incoming instant messages or video calls because the app is in App Standby? MEGHAN DESAI: No, no. Your instant messages are going to make it through. So for that use case, we, as part of Doze and App Standby, we launched something called a high-priority Google Cloud Messaging message, which now is Firebase Cloud Messaging, if you saw the announcements today.

So this high-priority message, it’s a push message that grants the application temporary wakelock and network access, independent of the device’s Doze state, or if the app happens to be in App Standby. And this allows the application to react to the message and put up whatever immediate notification it needs to put up to the user, whether it’s an instant message, or an incoming call. Normal Firebase Cloud Messaging messages during Doze gets batched to the maintenance windows. So for devices that don’t have Google Play services, this is where Google Cloud Messaging lives, or Firebase Cloud Messaging lives, for devices that don’t have Google Play services, we actually ship Doze and App Standby disabled, by default in AOSP. And we instruct our device vendors in markets where Google Play Services is not available to work with their ecosystems to identify an alternate cloud push messaging service. So we don’t have them enable Doze and App Standby unless they have Google Play services, or some alternate cloud-based push messaging service. ASHISH SHARMA: So, Meghan, that takes care of my instant messaging and my video calling apps. But what about the other use case? I often listen to music on my device when it’s just lying at home and the music is playing off of my Bluetooth speakers.

Does that mean that when the device goes indoors my music stops playing? MEGHAN DESAI: No, no. We’ve got you covered there, as well. We’re going to make sure your music keeps playing, Ashish. So for that use case, we actually exempt foreground services from Doze and App Standby. Often, when you’re playing music, music applications rely on what’s called a foreground service. This is a service that has to have a persistent notification. And such a service is going to be exempt from Doze and App Standby.

So even though your device will enter Doze, this service will retain its network access and wakelock access. So it can still play Ashish’s music. ASHISH SHARMA: All right, thanks. MEGHAN DESAI: I also said that alarms get deferred. Now, there are some use cases where alarms are important, part of what the application needs to do on behalf of the user. So for those kinds of use cases, we launched new alarm APIs that will trigger in a limited way during Doze.

And then, finally, for use cases that cannot be accomplished by Doze and App Standby, we have a Whitelist on the system that users can add applications to that will cause the application to be exempt from Doze and App Standby. Applications can also prompt users at runtime to be added to this Whitelist, but this is only for very specific, narrow, acceptable use cases that you can read about on our developer site.

And doing so would trigger a Play Store review before your application gets published to the Play Store. ASHISH SHARMA: So all this sounds great, Meghan. The features make a lot of intuitive sense. Doze and App Standby for cases when my device is not being used, or when I’m not using my applications. How did we do? Do we have any numbers? MEGHAN DESAI: I think we do. I think we have some numbers. ASHISH SHARMA: Oh, great. So last year, when we announced Marshmallow, we saw that Doze and App Standby combined together can increase the standby battery life of a Nexus 9 tablet almost twice. And so the battery life almost doubled there. And we also saw up to 30% average improvement in the screen-off battery life of Nexus 6 devices. There are in a control group population of Googlers that we have. So clearly, Doze and App Standby are very important features. And these principles do seem to work.

But I’m still thinking about one thing. These cases make sense when I’m not using my device or the apps that I’m not using. But what if I’m actually walking around with my device like I am today and I’m actively using all of the apps on my phone? MEGHAN DESAI: Yeah, that’s right, Ashish. It turns out that most of the time our devices aren’t stationary, right? We have them in our hands, or in our pockets, and we’re moving about the world doing what we need to do.

So we wanted to bring the power of Doze, the battery gains of Doze, to that situation as well. And that’s why we’re extending Doze in the Android N-release. So let’s take a look at how that’s going to work. Again, think of these orange bars as background activity. And at some point, you turn the screen off. And you put the phone in your pocket. So it’s not being charged right now. Well, shortly after that, and this time on the order of minutes, so shortly after that, the first phase of Doze kicks in. And now, this is a lighter, gentler Doze than what you saw with Marshmallow in that it’s only going to restrict the application’s network access, and any of these jobs and syncs will get deferred.

When do they get deferred to, you might ask? To the next maintenance window. So sort of the familiar maintenance window and Doze repeated cycle will ensue after that so long as the screen continues to be off. And again, the idea here is that we’re balancing battery life with freshness of content. And in the maintenance windows, these restrictions are lifted to allow any pending activity to resume. And all this will end when the screen comes on, or you plug in the device, as you would expect. OK. So let’s quickly review the Doze that we just talked about in Marshmallow and figure out how this extended Doze that I talked about will work with the Doze that I talked about in Marshmallow. So for that, we’re going to zoom into this red box on the screen. Let’s take a look at what happens. So as you’d expect, the device is stationary. It’s on battery. And it’s screen off. But the amount of time hasn’t passed yet for Doze to trigger.

Only a few minutes have passed. At this point, this extended Doze, or this lighter, gentler version of Doze will kick in, the N-release. And you’ll see that same pattern of Doze and maintenance window. And at some point, the device will realize, oh, hey, the device actually has been stationary for quite some time. And it’s been stationary for the amount of time required for Doze to kick in.

And then, at that point, just like it does in Marshmallow, the full set of Doze restrictions will kick in. So at that point, applications, again, will Wakelocks, their alarms will get deferred, and there’ll be no more GPS or Wi-Fi scans because the device has been stationary. Great. So we were very excited about the battery life gains of this extended Doze. But the even better news for all of you is if you’ve already optimized your applications for Doze and App Standby, you don’t need to do too much more.

High-priority Firebase Cloud Messaging messages continue to provide the application temporary Wakelock and network access. And foreground services continue to be exempt from Doze and App Standby. So we make sure that Ashish’s music keeps playing. ASHISH SHARMA: All right. MEGHAN DESAI: Cool. So we’ve been talking a lot about background services and their impact on battery life. We’re going to switch gears a little bit and talk about background services and their impact on memory. So let’s say you’re trying to do something on your phone and it’s just really slow and sluggish. Say you’re trying to take a picture with the camera, and you miss that moment because your phone was just too slow.

You know what I’m talking about. Background services have an impact when the screen is on, as well. And that’s what we’re going to focus on next. So again, let’s say you have an application you’re trying to use, that’s the Top App here. At any given time, there’s a number of things happening in the background, lots of stuff happening in the background services. When a device enters a low memory situation, or if it just happens to be a low memory device, what happens is there’s not enough memory to run all that stuff in the background while you’re trying to use the device with that thing at the top.

Well, at that point, Android is too busy trying to swap applications in and out of memory to let them do what they need to do in the background, which applies pressure on the application you’re actually trying to use. And the net result is that you get this frustrating, slow experience of the device. So that’s the problem we’re trying to tackle. But background work is pretty important. So let’s figure out why background work is happening. One such trigger for background service is something called an implicit broadcast. A broadcast is just a signal that gets sent out on the device whenever something happens, the minute something changes. And the implicit type of broadcast is the type that gets sent to any app, or any application can listen to it, versus the explicit side, which would be something that gets sent to a specific application. What makes this particularly bad is that often these broadcasts are listened to, the receivers for these broadcasts are declared in a static way in the application’s manifest file. What that means is that the application doesn’t actually have to be running for it to receive this broadcast and react to it.

In fact, a broadcast sent in this manner would cause the applications that are not even running, but listening for it, to be woken up, brought into memory, and react to it in some way. And while Android is too busy doing that, the application that you’re actually trying to use starts to be sluggish and slow. Let’s take a quick example of this, a broadcast called CONNECTIVITY_CHANGE. This is a broadcast that gets sent quite frequently on your device. You know, any time you switch from Wi-Fi to cell, or back, or any kind of connectivity change happens, this broadcast gets sent.

And it turns out, a lot of applications listen to this broadcast in a static way, by declaring receivers in the manifest file. And so, whenever this broadcast gets sent, lots and lots of applications are woken up to perform activity in the background. And you get a frustrating experience on your device. So this is the problem that we’re trying to solve. So what do we do? Well, we could just get rid of background services and implicit broadcast in Android All right. It’s not that simple. Because background activity is actually pretty important. So what we’re envisioning here is that applications perform any background activity using exclusively JobScheduler jobs. And they reduce their reliance on background services and statically declared receivers for implicit broadcasts. Let’s take a quick look at what I mean. So what we envision here is that applications’ statically declared implicit broadcast receivers would no longer get woken up. One time declared receivers would continue to work. Explicit broadcast receivers would continue to work, both declared statically, or at one time.

But the statically declared implicit broadcast receivers would be the ones that are specifically affected. Second, for background services, we envision that apps are no longer running background services, or dependent on that for any kind of background execution. Now, I said, background execution is important. And for that, we want developers to use JobScheduler or Jobs. Now, foreground services will still continue to work. So, Ashish, your music will still continue to play. ASHISH SHARMA: Well, thank you for that, Meghan.

But all of this sounds pretty scary. These are pretty big changes. Are they coming in N? Do we need to change all of our apps in time for N, which is very soon? MEGHAN DESAI: It’s not coming in N. But you need to change your app soon. So today, we’re just giving you a preview of what we envision to be the future of Android, where we think Android is going with respect to background activity.

We know that background activity plays a huge factor in both battery life and the overall performance of the system. So this is sort of where we are going. And we’re planning to launch these when we think they’re going to be ready in some future release. And they’ll apply to the apps that target that release. In the N-release, we want to give you tools to start testing your applications under those conditions and giving us feedback on, as you think about changing your applications to use job scheduler, where you can’t. We’re also removing a few broadcasts that we think are particularly harmful in the system today. And I’ll talk about that in just a second. So we have some adb commands you can use today in the preview and apply them to your application.

Start testing to see what happens, how your applications behave under these conditions. And send us feedback. Let us know what implicit broadcasts that you’re currently dependent on in your manifest files that you can’t live without, what kind of background services use cases you have that you can’t move over to job scheduler or jobs. OK, Ashish, so I think your specific question was what’s actually going to be changing in the N-release, so let me talk a little bit about that. First, I already talked about CONNECTIVITY_CHANGE as being a particularly harmful broadcast. So that’s one that we’re getting rid of. So applications that are targeting the N-release will no longer be woken up as a result of this broadcast. This means that if you’ve declared a receiver for this broadcast in your manifest file, that’s no longer going to work. If you declare it at runtime, as I said, runtime receivers for broadcast will continue to work because your applications are already running at that point. And for other use cases, we want you to use JobScheduler. And JobScheduler already has network trigger semantics. The other two are NEW_PICTURE and NEW_VIDEO.

These are two more implicit broadcasts that are sent right when the user takes a picture. And they’re sent by the camera. And that’s sort of the worst time when you want a lot of other background stuff to be happening because you want to focus on taking that next picture, or whatever it is you’re doing with the camera application. So starting with the N-release, all applications will no longer be able to send or receive these two broadcasts. So not just those targeting N, all applications. And in fact, these broadcasts are actually pretty important because they unleash some pretty cool use cases. So one of them is uploading photos.

As soon as you take a photo, you want that uploaded. But maybe you can wait. And so for that, we’re actually expanding JobScheduler to be able to be triggered on content provider changes. So the media folder has a content provider URI. That could be the trigger whenever something updates there to upload that photo. And the cool thing about this is that now, because you’re using Java scheduler, the system can optimize when that action takes place. It doesn’t have to happen immediately when you’re trying to take that next picture. It can find the next opportune time to do it, depending on the memory conditions. Cool. So I’ve been talking a lot about JobScheduler and how awesome it is. But just a show of hands, how many of you have actually heard of JobScheduler? ASHISH SHARMA: Well, that’s a good number. But I also see a lot of the hands that are not up. So maybe it’s a good time for us to review what this really important JobScheduler API really looks like and what the features are.

Because you made it sound very important. OK. Let’s do a quick review of the JobScheduler API so that everyone here is on the same page. The JobScheduler API, think of it like a wrapper around any background activity. So any background sync, any background activity that you have, JobScheduler is the way to think about scheduling those. And this is slightly a paradigm shift, where what you’re doing is you’re letting Android know that I have some tasks that need to get done, and you specify certain triggers when Android will schedule those jobs for you, rather than something that you try and take care of yourself. So let’s take a couple of examples.

These triggers, when you request Android to schedule your job, could be used on a certain time window. So say you have a job that’s important, not exactly urgent. It doesn’t need to happen right away. You can tell Android that, schedule this job any time within the next one hour. And what Android would do is once many applications are using the JobScheduler API, it now has this context about all the background activity from the different apps that needs to happen. And it’s going to do a good job at scheduling your job at just the right time, so that the efficiency of the CPU and the networking radios can be maximized. Now, what you can also do is specify triggers based on network connectivity, or the type of network that becomes available. So say, for example, an application that’s uploading a whole bunch of photos or videos that you might have on your phone, now, it’s a very good idea for such an app to schedule or to specify a trigger for of Wi-Fi network. Because what that’s going to do is, Wi-Fi typically has more bandwidth. And it’s less expensive, in terms of money.

And it costs also less power than the cellular radio. So that can be a constraint, or a trigger, that you can specify. And finally, the thing which is my favorite, which comes back to the whole deferring until the device is on charger, you can specify that control too. So you can tell that here’s a job that I want to get done and trigger it when the device is charging. But not just that. Because every time you plug in the device may not be the best time for all of the background jobs to start firing up.

Say, for example, I saw some power outlets outside. You’ve been here since morning. Your phones are running low. And you find that power outlet. And you plug in your device to get maybe 5 minutes of charge. And right then, if all of the photos and the videos that you took today start getting uploaded to the cloud, that’s going to be a not so pleasant experience for you. Because your device might get slow. But also, you might not get enough charge out of the outlet because you’re spending all of that energy. So what you can do is you can say the device should be charging and should be relatively unused. Now Android’s smart enough to figure out when you are not actively engaged or interacting with your device. So it’ll wait a little while, make sure that this is a nice time to schedule all of those background jobs, and it will trigger your job right then.

So we have seen that the JobScheduler API is really important and it will help you optimize, defer, and coalesce your background activity, not just based on battery constraints or connectivity conditions, but also, in terms of memory. So let’s take a look at a quick example of how the JobScheduler API works and how easy it is, in a few lines of code, to get your jobs done. I’m showing you a JobInfo object. Let’s create an object using a builder. We can specify a required network capability to be that of network type Unmetered. Now, what that typically translates to is a network that doesn’t cost the user money. And most Wi-Fi networks fall into that category. So in a way, you’re specifying the Wi-Fi connectivity here. What you are doing then is, say I want my job, or my app, to sync up with my cloud backend server every 24 hours. It doesn’t have to be by the hour, but once every day is fine for me. So what I’m going to do is set up a periodicity of 24 hours. And here comes the favorite part, which is, you do this when the device is on charger.

So you specify the set requires charging constraint. And those four lines, you can schedule a job and it’s done. Now, Meghan also talked about something very interesting and an extension to the JobScheduler API that we’re introducing in N, and that is to take into account the memory conditions, or the RAM conditions on your device. So now, JobScheduler also supports triggers based on content provider updates. So the example that Meghan gave was, if you’re trying to take a picture, or that selfie, or of your kid, and if at that moment, you’ve just taken a picture and you want to click another shot, and if your phone gets low, then that may not be a good time for you to start uploading your pictures.

And what you can do is now you can tell JobScheduler that I’m listening for this content provider update when a new picture appears. But there’s a little bit of wiggle room there. It doesn’t have to start right at the very second when the picture was taken. And the JobScheduler API is intelligent enough to prioritize all of the jobs for the processes, or for the application that is in the foreground, or that is running foreground service, to account for the fact that if you’re interacting with an app, all of the jobs for that particular app should get priority, an automatic priority, or all of the other jobs that may not be as time critical. And finally, JobScheduler is aware of the available RAM on your device.

So depending on how much RAM is available, it might choose to schedule more than one job at the time. Or, if the memory conditions are not ideal, or if you are running low on memory, then only a few jobs, or the top priority jobs, will get scheduled first before all of the other ones get precedence. So these changes are interesting. Let’s take a look at a quick code sample of how you want to use the JobScheduler API for something like a NEW_PICTURES content provider update. You get an instance of your JobScheduler service. You create a builder object. And you specify now, instead of in the last example, where we had specified constraints on the network type and the periodicity, what we add here is a trigger for a ContentUri update for NEW_PICTURE. And you can schedule your job. And that’s it. You’re done. So this is all good. JobScheduler API was introduced in Lollipop, which was API 21. We also have, and have had for awhile, a backward compatibility library, which lets you do almost all of those same things that I talked about on devices that may be running a previous version of Android, or an earlier version of Android, and that is Google GCMNetworkManager.

Wait. This slide doesn’t say GCMNetworkManager. Meghan, what did you do? MEGHAN DESAI: Yeah, yeah, that’s right. It’s actually Firebase JobDispatcher. So today, as part of the Firebase announcements, we’re launching Firebase JobDispatcher, which was formerly known as GCMNetworkManager. The cool thing about Firebase JobDispatcher though is that it’s an open source SDK that is, effectively, providing you the same capabilities that JobScheduler does in the platform, but in a backwards compatible way. That is, it’s a wrapper, again, for background activity. It’s available not only on Android, but coming soon, also, on iOS. And it, on Android pre-Lollipop, Google Play Services will act as the central scheduling driver. On Lollipop and onwards, where JobScheduler is available, it will just use JobScheduler. And then, on iOS, it will use Grand Central Dispatch. So that’s pretty cool. Let’s take a quick example of what JobDispatcher looks like when you’re performing background activity. So this is a quick example of creating a simple job service that encapsulates a code you need to perform in the background. This is the, whatever it is that your application needs to do, in the background, you put in that doWork function. And then, again, very simple, create a job using the Job Builder from the Dispatcher.

Give it the service that you just created that’s wrapping around all the activity. And then, in this case, I’m just giving it a constraint that I want it to happen on an Unmetered network. And then, that’s it. Then schedule. So pretty simple, very easy to use to perform any kind of background activity. So Ashish, we’ve been talking a lot about very cool platform features, a lot of APIs that we’ve introduced. And these sound like they’re going to have a huge impact. But how can we be sure that they’re going to make any difference? ASHISH SHARMA: That’s right, Meghan. It’s not an easy problem, something that I have personally suffered with, or struggled with, for a while, and that is, how do you really make sure that your app is behaving the way that you intend it to be when it comes to all of these battery optimizations? Or worse, what if your app is draining more battery than you think it should? How do you diagnose that? So let me take a quick poll.

How many of you have tried diagnosing battery problems on your applications? MEGHAN DESAI: OK. Quite a few. ASHISH SHARMA: Some. Now, for the others who did not raise their hands, was that because you found it too hard to diagnose battery problems? Because I’ve been in that same place. Well, you can be honest, but, so diagnosing of battery problems can be really tricky [INAUDIBLE]. And good thing we have a tool. And we have some logs on the device that can help us do that in an easier fashion and not have to struggle through all of the pain. Let’s look at some of the logs, or the types of logs, that are present on the device. Now, Android maintains data structure in memory on all devices. And this log is called Batterystats. Now, what Batterystats is is it is a set of cumulative counters that go on incrementing while your device is on battery. So since it’s in memory, and these are cumulative counters that go on increasing, they need to get reset at some point. And that point is when you’ve fully charged your device, and you’ve just unplugged it.

So say, for example, you charge your device overnight. And you unplugged it at 7 AM in the morning. And maybe it’s about 10 and a half hours since then. If you take a bug report on your device now, then it would contain the whole 10 and a half hours’ worth of Batterystats and counters about various things happening on your device that we think are relevant with respect to battery life. So things like how long was the partial Wakelock held on the device across all applications and on an application basis? Or how much data was transferred over the mobile network or the Wi-Fi network? And what you can see here is there’s also a StartClock time which tells you exactly when the stats were reset.

So this is really useful when you’re trying to look at what all happened on your device that may have caused the battery to drain faster than what you would expect. The other type of log that is present on the device is something that we call Battery History. And what this is, it is an event log of all of the state transitions for components on your device, or for actions like scheduling a wakelock, or an application scheduling a job, or the device going into suspend, coming out of suspend, or maybe it’s the network radio that got turned on. So there’s a lot of information here. And this would contain an event log of a millisecond level granularity of everything that happened on your device since the stats were reset. MEGHAN DESAI: A millisecond level granularity? You’re telling me that I have to look at this to figure out what’s going on with the battery life on my device? ASHISH SHARMA: Yes.

MEGHAN DESAI: There’s going to be hundreds of thousands of lines of this. ASHISH SHARMA: Well, but it’s fairly obvious. You can just make out what the problem is. MEGHAN DESAI: Well, can I? ASHISH SHARMA: No, I’m just kidding. We have a tool that helps us make sense of this entire thing. And that’s called Battery Historian. Many of you might be aware of this. And what this tool would do is it would take all of those logs that are present, the two logs that I just mentioned that are present in the bug report, and it would help you look at them in a very intuitive and interactive UI that makes clear what the problem is on the device. So Meghan– MEGHAN DESAI: Wow. That’s pretty cool. I like this. I like this a lot. So where do I see this though? Is this on my device and setting somewhere? ASHISH SHARMA: No. I know you have a very cool and powerful device, but going through these hundreds of thousands of transitions on your small little screen may not be a very pleasant experience, especially when you’re trying to diagnose battery problems with your apps.

So what this is is, let me walk you through the workflow of how this tool works. It is an open source tool available on GitHub, ready for you to download. And you can look at the source code, modify it any which way you want. What you do is, you install it on your computer. Now, you have your development device on which you, for the stats to be recent, because you want to have a good starting point, you can either charge the device up to 100% when the stats would get reset, or there is an ADB command to actually manually reset the start so you have a good initiation point. You can run your experiment, which might last a few minutes, or maybe a couple of hours. And at the end of it, you take a bug report. And then, you upload that bug report on your computer that you have the Battery Historian tool to go back to this interactive, visual interpretation of all the state transitions. MEGHAN DESAI: Cool.

ASHISH SHARMA: So now that we’re clear on how the workflow works for Battery Historian, I’d like you to come with me on a slight tour of what are the features of this tool. Let’s zoom into one of the rows, or a few of these rows. What you’re seeing is the top line, which is CPU running. And what this indicates is it indicates is whether your device was in suspend, or was it out of suspend? So the solid black bars are when your device was actually out of suspend and doing some activity. Similarly, you can see things like when was a Userspace Wakelock held or when the screen was on. And the information about any of your jobs or syncs will also appear here. And in this UI, you can zoom in to every little event that you see, no matter how long. And if you take your cursor over that, it will show you a nice tutor. So say, for example, we are at this point in the UI.

We have zoomed in. And it tells me exactly what the current time was at this instance. And the red highlighted portion now shows you the battery level drop from 73 to 72 and how long it took for the device to discharge from 73 to 72, giving you an indication of what the average discharge rate was during that time. And you can see all of the events lined up nicely. So you can actually figure out when your device was discharging rather fast, what were the events that were happening on the device? Let me take you through another example.

So say you have adopted or migrated your app to start using JobScheduler now. How do you figure out when your jobs are getting scheduled? So in the JobScheduler row, you go on any one of those events. And if you are in a zoomed out view, it might collapse a bunch of these little jobs that didn’t last as long. But it will give you information about how many jobs were run in that particular small box and for how long each of those jobs ran. And you can zoom in if you like. So it’s a very interactive and fun tool. I have a lot of fun playing with it and diagnosing all the battery problems. What I want you to do is look at an example of Doze in action. So we’ve been talking about the Doze mode in Marshmallow that was introduced and the lighter version of Doze that was introduced in the N-release.

So what I’m showing you here is a bug report that I uploaded to the Battery Historian tool. And the black line that you see going down that’s not exactly horizontal, that’s your instantaneous battery level. So typically, it would start off with something high if you started with 100%. In this case, I manually reset the stats. It starts somewhere around 50%. And then, what you can see is, let’s zoom into this little area. When your screen was on, you can see that the frequency of your jobs and syncs was fairly high. All of the jobs and syncs were getting scheduled fairly periodically. But then, after the screen has been turned off for a while, what you see in the Doze line, or the Doze row, in orange, that’s the lighter version of Doze kicking in. So some applications would lose network access. And you start to see that now your jobs and your syncs are beginning to get less and less frequent. And they’re getting batched together. And further out, after the device has had its screen off for a while, and it has been stationary, you see the device entering this deeper Doze mode, which is shown in the blue row here.

And when that happens, now, we know that the device is not being touched by the user, is not being used. And that’s an opportunity for the JobScheduler API to start throttling and batching together a lot of the activity. So you see that under the blue bars, the JobScheduler and the SyncManager frequency is fairly infrequent. And they get scheduled during the maintenance windows. Now, what’s really interesting is– and this slide will help you get a perspective on what uses the most power on your phones– initially, when the screen was on, my battery level was discharging really fast.

So you see the slope of the line? That’s my battery level going from 50 to maybe 30 very quickly. And after the screen has been turned off and the Doze mode has kicked in, that’s when you start to see that now my battery is not declining as fast. And it might have even lasted me a couple of hours in that state without discharging a whole lot of battery. And then, towards the end, as soon as the screen is turned back on, we see that the device exited the Doze mode. And you go back to that steep discharge of when I’m actually playing a game or watching a video. MEGHAN DESAI: That’s pretty cool, Ashish. So all that stuff we were talking about, coalescing, and deferring background activity during Doze actually works. ASHISH SHARMA: That is living proof. MEGHAN DESAI: That’s pretty cool. ASHISH SHARMA: OK. So the next thing I want to show you is, I talked about these accumulated stats. So the same tool, what it would help you do is, once you’ve uploaded the bug report, it will now show you all of this information that was collected on the device, so which jobs were run, for how long they were run, which application required Wakelocks, and for how long they did.

And in general, for the entire device, there’s a whole bunch of information here, such as the mobile radio activity, which application used the most amount of mobile traffic or Wi-Fi, number of Wi-Fi scans. And it helps you get a good overview in a very quick fashion on what exactly happened with your device. MEGHAN DESAI: So hold on. This has all been pretty cool. But I thought you said that this was going to help me figure out issues with my application. ASHISH SHARMA: Yes. MEGHAN DESAI: Can I do that with this? ASHISH SHARMA: Yes, Meghan. That leads me to my very next slide, which is, there is an App Selection bar there. So you can actually search for your app and pick your app. And the moment you’ve done that, you get taken to this App Stats view, which tells you all of this same information just for your app. So you can look at all the jobs that got fired, what all processes you were running, how much mobile data, or Wi-Fi data, sensors, all the good stuff just there for your app. And the very cool thing that I don’t have it here in the slides is once you’ve picked your application, if you go back and look to the UI of the timeline of events, you will see that in the job row, or the JobScheduler row, or the Sync row, only the jobs and syncs for your applications will appear.

And all else will disappear. So that can really get you a visibility into how frequently your application was scheduling all of these tasks. So we found this tool to be very useful. But there is one case that has been especially painful for me. And that is, when you are developing an app, or say you made a change in your app, and suddenly your device is discharging very fast. Now, I write perfect code. I never make mistakes. But then, my device is discharging fast.

What did I do? And I’m in this position more than I would like to admit. And I’m sure a lot of us have been in this situation for one, or the other, time. And so for that, what we have is an A/B Comparison mode in the same tool. So what you can do is you can upload two bug reports. And if you have a good case and you have a bad case, then what the tool will let you do is it will highlight all the biggest differences that it sees between these two bug reports.

So say, for example, it’s comparing now file 1 versus file 2. And it’s telling me that in file 1, it has used times more Wi-Fi data than the others. And the screen off discharge rate on, let’s say, the first one, was less than times, and a whole lot of other good stuff. I haven’t shown you all of the detail. But if you upload two bug reports, it will automatically normalize those two bug reports. So say, if you have one bug report that was taken for four hours, and the other that was at two, it will automatically normalize all of that and show you a good comparison, which can give you a very good starting point as to what actually changed on the device, whether it was really my app, or some other app started doing something that may have accounted for this difference. So that’s an interesting mode. And to wrap up, I’d like you to look at one last feature on this tool, which is my personal favorite.

And this is for the true geeks out there. So if you have a phone, and if you were able to modify your phone to connect it to a power monitor, and say you were recording the instantaneous current values when the device was actually running. What you can do is you can upload a bug report, and you can upload these power readings, these instantaneous current values, to the Battery Historian tool. And it will show you a nice overlay of what your instantaneous current draw was and what the device was actually doing at the time. So here’s, you know, this is where for me, at least, all of it comes together.

So you see when the CPA was running, indicated in the black bars in the top row, that’s when your instantaneous current draw was close to 800 milliamperes. But when the device was in suspend, it was hardly anything. You can’t even see it there. Because it’s close to about 4-5 milliamps. So there’s several orders of magnitude difference in the amount of power that’s discharged from your phone when you’re actively doing stuff. And when you do this, when you use the JobScheduler API and start batching together a lot of the activity, well, it’s not hard to see that your phone will now last much longer and really take away the pain from having a device that doesn’t last as long.

MEGHAN DESAI: That’s really cool, Ashish. I’d love to have an amp meter to look at what’s going on my phone. ASHISH SHARMA: Yeah. There are detailed instructions of this on the GitHub website on how to actually hook it up. So try it out if you like. MEGHAN DESAI: Cool. So what’s next? Well, you saw how these simple design principles that Ashish talked about, Reduce, Defer, and Coalesce, go a long way in improving battery life and performance of the device. So here’s what we want you to do.

We want you to reduce all the background activity in your applications. What you can’t reduce, defer it to when the device is charging. And what you can’t defer to when the device is charging, at least help us coalesce it with other activity that’s going on in the background. So go out there and figure out how to use JobScheduler and JobDispatcher instead of using background services. We actually have a code lab up to walk you through some key use cases around migrating from services to JobScheduler. Check out Battery Historian, as Ashish mentioned. We also want you to start removing your dependencies in your applications on statically declared implicit broadcast receivers, as well as on any background services, again.

And send us any feedback as you’re doing that on where you are unable to do that using JobScheduler or JobDispatcher. We would love to hear from you. We want to get there together. So with that, if you have any questions, you can join us at office hours right after this, at 6 o’clock on stage 9, as well as tomorrow and Friday. Thank you so much for being here this late. ASHISH SHARMA: Thank you for coming. [APPLAUSE] [MUSIC PLAYING].

As found on Youtube