Should a device behave as if nothing happened during Battery tests? - android

I need to test whether an app behaves correctly after restoring from Doze / App standby. The thing is that when I use commands from the Android Developers site, nothing happens with either the app nor with the device itself. The command prompt seems to respond correctly though.
Commands for Doze:
adb shell dumpsys deviceidle unforce
adb shell dumpsys battery reset
Commands for App Standby:
adb shell dumpsys battery unplug
adb shell am set-inactive <packageName> true
Wake up from App Standby:
adb shell am set-inactive <packageName> false
adb shell am get-inactive <packageName>
https://developer.android.com/training/monitoring-device-state/doze-standby.html#testing_doze_and_app_standby
Do you think that if nothing bad happens to the app, it means that it is behaving correctly? Or have I made some mistakes during the tests? I'm asking because from what I've read on the internet, the Doze should trigger with at least locked screen, so it all looks suspicious to me. I don't have any other ideas how to confirm whether these commands actually work.

With the Doze test, make sure you force the system into idle mode by running the following command first:
adb shell dumpsys deviceidle force-idle
But otherwise the commands you are running look correct.
You primarily want to test that the app returns to a good state after being in Doze or App Standby mode, and that any restrictions in place during that mode are lifted. The restrictions Doze and App Standby may impose on apps include limited or no network access, suspended background tasks, suspended Notifications, ignored wake requests, and alarms.
If your app can send notifications or trigger alarms, you can test that those are blocked during this mode.
According to the Android docs:
Observe the behavior of your app when it is woken. Make sure it
recovers gracefully from standby mode. In particular, you should check
if your app's Notifications and background jobs continue to function
as expected.

Related

Android - Disable Forced DozeMode or AppStandByMode

I have an application that uses a ForegroundService to send location updates to a server. Basically a tracker.
This ForegroundService has a Handler that periodically (using postDelayed) executes a block of code to send the location.
This works perfectly fine, when the app is in the foreground and even in the background, but I started to notice a delay when the phone is locked, with the screen off for about 15minutes. I mean, 15 minutes of no user activity and no charger plugged.
This is happening on a Android Q (v10) device. I'm assuming this would also happen on any device running Oreo onwards.
Let's make it clear... My app send the location every 30sec, but when entering what I suppose is the DozeMode or AppStandByMode, it continues sending the location, but every 2 minutes (more or less). If I turn the screen on, or plug-in the charger it inmediately come back to the 30sec pace. That's what makes me thing about the DozeMode or AppStandByMode. Moreover, if I leave the phone untouched, but with the charger plugged in, then this never happens.
As said, I'm pretty sure the DozeMode or AppStandByMode is kicking in, and I know I can whitelist my app to prevent that. But before going further I would like to reproduce this without the need to wait those 15minutes every time I want to test the behavior of my app.
So I "googled" how I can force this and here's what I've found:
For DozeMode (see source)
adb shell dumpsys battery unplug
adb shell dumpsys deviceidle step deep
And continue to execute the last command until reaching IDLE state.
For AppStandByeMode (see source)
adb shell dumpsys battery unplug
adb shell am set-inactive packageName true
And query the state with this other command:
adb shell am get-inactive packageName
which I confirm it returns Idle=true
I also even do as this other blog suggest, issuing:
adb shell dumpsys deviceidle force-idle
I though I was not getting in this mode, but now it seems I am and I can not get out of it... See the update
UPDATE
At first I thought I was not entering the DozeMode... Now I can confirm I'm in, but it always triggers inmediately. (no more waiting those 15min)
Whenever I lock the phone and screen goes off, it automatically enters the doze mode and begin spacing the location updates. I plug the charger and then again sends them at 30sec.
I've try:
adb shell dumpsys deviceidle unforce
adb shell dumpsys deviceidle disable
adb shell dumpsys battery reset
and still the same.
Also:
power-down and power back up the phone
uninstall the app
change battery optimization to NOT OPTIMZE inside the app settings
Did I miss a step?
Except for Doze mode, Android 9 extended the concept of AppStandby with App Standby Buckets.
Along with network restrictions, an app that is in a low priority bucket will be affected in the frequency of running Jobs, triggering Alarms, and receiving FCM messages.
You can get your app's current bucket using this command:
adb shell am get-standby-bucket your.package.name
You can set the bucket and see how your app behaves using this command:
adb shell am set-standby-bucket your.package.name <never/rare>
I wrote an article that summarizes all changes regarding background process limitations over the years: https://rotemmatityahu.medium.com/workmanager-does-it-always-manage-to-work-fd8518655052

Automated tests with Doze mode on android

I am trying to write some automated tests for how my app functions when the device enters and exits Doze mode. I know that you can use dumpsys deviceidle force-idle to force the device into idle mode when doing manual testing.
Is there a way to run that command from within a test app, or (better yet) an Android API to request Doze mode? If there isn't, does anyone have a recommendation for documentation regarding a good way to run adb commands at fixed points in an integration test?

Behaviour in Android Doze when using different Scheduler

I'm trying to optimize our app for Doze and AppStandBy and have implemented a
test application to understand the behaviour of the system when using different background schedulers.
However I'm very confused about the behaviour when using AlarmManager and Observable.intervall().
AlarmManager
I have registered an alarm through an Activity and then brought the device via adb in Doze.
The system behaves as expected, the alarm is not fired.
Rx-Observable.intervall
I have started a Service through an Activity and then brought the device via adb in Doze. The Service is NOT a foreground service.
The system does not behave as expected in my eyes and the ticks are continuous delivered to the app.
To veryfy that the device was really in Doze I also reviewed the battery statistics with adb bugreport, and the historian tells me that the device was in Doze in that timespan.
Is there any documentation how the different schedulers work in Doze or AppStandBy?
Thanks for any advice.
The problem seems to be that adb keeps the CPU running (if the device is connected via usb) even if the device brought to doze by adb with the commands
$ adb shell dumpsys battery unplug
$ adb shell input keyevent KEYCODE_POWER
adb shell dumpsys deviceidle step
The interval timer scheduled by ScheduledThreadPoolExecutor (used by rxjava) seems not to be restricted in doze mode but alarms via AlarmManager do.

How long does an App need to be idle for App Standby to kick in (Android Marshmallow)

I've looked all over the internet to find specifics about App Standby mode in Android Marshmallow, but I've not found any specific data for when it happens, other than some listed conditions that might cause it to happen. I also see a nebulous "If the device is idle for long periods of time, the system allows idle apps network access around once a day" without any specifics about how long this window would be.
Doze mode seems pretty well researched (This gist was particularly helpful and consistent with my findings), but I haven't been able to see App Standby in action. I created a test app that sends data to a server every 5 minutes via an Alarm and ran it for a week, and it continued to hit the server every 5 minutes unless the phone went into Doze mode and only hit the server in maintenance periods, then go back to every 5 minutes when the phone was awoken, so it did not appear that Android ever put it in "App Standby" state even though I didn't directly interact with the app.
Is there any specific data on how App Standby works?
You can force the device to enter this mode using the code below:
adb shell dumpsys deviceidle enable
adb shell dumpsys battery unplug
adb shell dumpsys deviceidle step
adb shell dumpsys deviceidle force-idle

Doze mode and foreground service

Checking my app's behavior on M Preview device, it seems that its foreground (with active notification) service playing music is not affected by Doze mode.
But reading docs it seems that foreground services are exempt only from AppStandby.
What is the real rule?
In this post's comments on Sep 17 Dianne Hackborn writes:
Apps that have been running foreground services (with the associated notification) are not restricted by doze.
So yes, your findings seem to be the intended behavior.
Attention, Foreground service can prevent your app never into app standby, but not doze.
Here use adb cmd to test
$ adb shell dumpsys battery unplug
$ adb shell am set-inactive <packageName> true

Categories

Resources