Understanding & testing Android M+ Doze Mode - android-6.0-marshmallow

I am working on making my Android app a good citizen of the post Android M world which imposes severe constraints on what an app can/cannot do when the device goes into doze. My understanding of the issues involved is still rather fragmentary so I am hoping that someone here can fill the gaps.
The duration of doze
My own empirical findings here
Doze first starts within about half an hour of stationary, screen-off, inactivity
The first maintenance window happens within 30 minutes
The next one happens in about an hour
The ones after than in ca 2, 4 and 6 h. I have not tested beyond that
Are these the official Android doze periods or is it just one empirical observation.
All of the above on an Android N device.
Testing Apps in Doze Mode
Connect the device to a computer with ADB
Bring the app to the foreground
Turn off the device screen
From the command line issue adb shell dumpsys battery unplug
Now cycle through the commands `adb shell dumpsys deviceidle step light OR deep
finally issue adb shell dumpsys battery reset
Entering/Exiting Doze
Happens when the screen is off and the device is not being subjected to movement
Presumably this uses the motion sensor in the phone so a phone sitting quietly on a remarkably smoothly moving train will still enter doze?
If I pick up a dozing phone and start walking around with it without otherwise interacting with it will it automatically exit doze?
Suppose my app is not in the foreground when its host device enters doze. Then I start using the device again but without visiting that app. Will it automatically start "working" again, i.e.
Its broadcast receivers will become functional?
Its handlers will start working?
Its scheduled jobs with setRequiresDeviceIdle(true) will stop being called?
The various modes of Doze & Job Scheduling
From what I have understood there are two doze modes LIGHT & DEEP. They both have sub-modes
LIGHT:Active, Idle, Idle_Maintenance,Override. I do not understand what the various modes do. From ADB I have issued step light with the screen on and seen the return value ACTIVE. With the screen off step light returns IDLE.
DEEP: Active,IDLE_PENDING,SENSING,LOCATING,IDLE,IDLE_MAINTENANCE with the screen on too returns ACTIVE but with the screen off it returns IDLE_PENDING. So when exactly do the other sub modes, IDLE, SENSING... happen?
I assume that IDLE_MAINTENANCE happens when the device enters a maintenance window from DOZE and attempts to run pending Job requests from various apps.
But if that is the case why is it that PowerManager.isDeviceIdleMode() and PowerManger.isPowerSaveMode() ALWAYS return false when I check them when a schedule job in my app runs?
JobInfo.Builder very kindly allows you to set criteria such as setMinimumLatency and setOverrideDeadline but as far as I can tell the OS hen goes and blithely ignores them - at times I have had jobs running withtin seconds of each other and at other times as far as two hours apart.
Why is there no API function to test for Doze and its sub modes? I would expect to find it in PowerManager but all I find there are isDeviceIdleMode and isPowerSaveMode which consistently return false whenever tested
The App in Doze Mode
Will have all its background services destroyed?
Will not get normal priority push messages?
Will not respond to alarms - but is that with the exception of setAndAllowWhenIdle?
Will get no comms from any of its broadcast receivers?
Will not be able to connect to the outside world on sockets - so push messaging, pub/sub etc will not work?
Will immediately destroy any broadcast receivers declared in the Android manifest. This has been my own finding - receivers that I create from Java code stay put, though they do not work during doze.
My own app watches for geo location changes by setting up a broadcast receiver and calling .FusedLocationApi.requestLocationUpdates. This receiver survives the doze/wakeup cycle. However, is there a guarantee my LocationUpdates request still being honored after wake up?
I have run into a rather peculiar bug. I found that my scheduled jobs in doze ran too close to one another on occassion even though I have given them a latency of 900,000 ms (15 minutes) and a deadline of 1,000,000 ms. I thought I would get round this by testing for the last time the job was run by keeping track of the last run time which I did thus
private static Boolean shortInstantGap()
{
Long instantNow = Instant.now().getEpochSecond();
if (300 > (instantNow - this.lastInstant)) return true;
//ignore the job opportunity if the last one was
//less than 300s (5 minutes) ago
this.lastInstant = instantNow;
return false;
}
and then aborting the job slot
private static Runnable timeRunner = new Runnable()
{
#Override
public void run()
{
if (shortInstantGap()) return;
callMyHandlerCode();
}
};
However, I found that this code causes the OS to abruptly terminate my app if it is on screen when I go through a screen-off screen-on cycle. Why was that happening?
Finally, is there not an API call I can use to test that the device has just returned from doze so I get an opportunity to do some post doze housekeeping?

I think good post and questions on this thread, thanks.
Really hope Android OS will improve push notification delays. Sometimes it doesnt get notification for an hour if you dont touch the screen. It may be good for some users due to battery saving but optimising push notification along with battery optimisation can be win win for everyone.
Anyway, here my 2 cents, are a few little tips my for those who want to analyse dozing stuff and those not aware of these already:
Wireless debugging feature can be used to connect device with computer/adb tools. So no need a usb cable and charging the phone while connected doing tests. I think since Android 11 most devices has wireless debugging option under developer options, this works natively without a usb cable setup. If no wifi debugging available(Android versions before 11) then usb cable can be used to setup it.
"adb shell dumpsys deviceidle" this command summarize some info like status of doze and sub states, can be used to check current status during doze/app testings.
You can check other adb doze commands and their effects like forcing doze, enable/disable it etc. online.

Related

NRF BLE chip, with bonding - bt-agent in NoInputNoOutput mode can't "forget" device

First little project at a new place and I'm having some trouble - hoping I can get some ideas. We have a BLE device using an NRF chip one which we've just enabled security and bonding. We're hoping to get our linux test fixtures set up so that the devices can be paired and bonded without the operator needing to accept the bonding request for every device. In the field, the end user will need to bond a device to a smartphone at least once.
I set up an agent using bt-agent --compatibility=NoInputNoOutput as described here:
https://www.kynetics.com/docs/2018/pairing_agents_bluez/
The bonding worked wonderfully without user interaction on my linux desktop (Ubuntu 20.10). Problem is, when I remove the agent, I had hoped that the bonding process would return to normal. It does not - it still doesn't require user interaction to establish the bonding. A similar operation completed from my Android phone works as expected after I "forget" the device.
I'm looking for more ideas as to how to reset the bonding/pairing of this device on my linux computer such that I can easily trade back and forth between needing user input and not (for testing and demonstration purposes). I've tried the following:
Remove the cache entry for my device in /var/lib/bluetooth//cache
Remove the device using bluetoothctl => remove aa:bb:cc:dd:ee:ff
Remove all agents using bluetoothctl => agent off (until no more agents remain)
probably some other things that aren't coming to mind right now
Regardless, the device automatically bonds when I click it in my Bluetooth list (or choose to connect in bluetoothctl). Any other thoughts on how I can return my linux box to a state where it's requiring user interaction for the bonding process?
thanks a million
I would expect Remove the device using bluetoothctl => remove aa:bb:cc:dd:ee:ff to have removed the device and the bond information.
Which leads me to suspect that your agent is still running in the background and being triggered on the request to do the pairing/bonding. My assumptions is that the agent registered by bt-agent would be unregistered when bt-agent exits. Could the bt-agent script still running in the background? Is the agent not unregistered on exit?
I don't have bt-agent on my system as it doesn't seem to be part of the standard BlueZ offering so I can't reproduce the issue. To get more debug information when pairing and exiting bt-agent, have separate terminals open with the following running to get more visibility of what is happening:
bluetootctl
journalctl -f -u bluetooth
sudo busctl monitor org.bluez
sudo btmon

Raspberry Pi 3 Model B (Android things OS) Error: Failed to open /dev/ttyAMA0: No such file or directory

I am a beginner in Android and testing Android code in which I am receiving and sending data through UART communication.
Hardware for communication- MAX232 device which is connected to Raspberry Pi3 Model B and the other part of MAX232 is connected to Vending Machine Port(Rx,Tx,Gnd to communicate my android app with the Vending Machine). My communication breaks SPORADICALLY and then starts communicating.
I do not know what the reason is
If anyone can help me in this, please suggest. Or any other information will be needed,I will share
private static final String UART_DEVICE_NAME = "UART0"; // define in my code.
**
I have to use ttyAMA0(PL011 UART) port because baudrate does not
change with the core frequency like with ttyS0(MIniUART)
**
For example: If I send 100 commands one by one, I get 2-5 times this
error.
**
> ERROR: Failed to open /dev/ttyAMA0: No such file or directory
**
Same thing happens to me reading data. I do not talk to the device (particle photon) connected to it, just listen. Since i'm expecting a response frequently, anything more than a couple seconds means things have gone south on one side or the other. It didn't seem likely though that my photon code was bad, as I had done many day-long tests with other things reading the data (arduino IDE, whatever).
Anyway, I created a runnable that fires every few seconds and checks when the last received response was. If it exceeds 60 seconds (things are most certainly wrecked and not going to get any better), I'll attempt to start up the connection again (Periperhal manager's openUartDevice). The main code waits another 60 seconds before trying again if it still has not received a response.
I also added code in 'onUartDeviceError' to trigger a callback the second that goes bad (not really sure if that's ever been the culprit in this), which will attempt the same restart logic but with a much smaller wait (like 5 seconds).
Lastly I made the Pi reboot itself (and thus the attached photon) so everything starts fresh, every morning at 6am. This has solved the issue for my purposes and its been in service for somewhere in the neighborhood of two years. Due to this reliability issue I don't do anything important with the pi, it simply exists to aggregate data from a few places and provide JSON. The photon is much more reliable even if the pi stops listening to it, so it controls the important/dangerous stuff (heaters, lithium batteries). Hopes this helps a little, but maybe some reconnect logic would solve the problem.

How to set the duration of Alexa wake time?

I am not seeing anything in the docs (Alexa Skills Kit or Alexa Voice Service) about adjusting the time that the device waits for a command after the "wake word" (default: "Alexa") has been uttered. I was wondering if I could adjust it and how to do so, preferably programmatically.
Is it possible? How so?
This is part of the hardware device behavior. So it cannot be done via the SDKs.
The underlying service, Alexa, doesn't support the concept of a wake word. In fact, it is against the terms and conditions of people using AVS to enable hardware devices to use a wake word without explicit permission from Amazon. So it isn't the sort of thing you would expect to see available programmatically.
The same goes for the other constants that govern how the hardware reacts such as the timeout in waiting for the service to respond, how long it waits for the user to say something before a reprompt, or how long it waits after the reprompt before hanging up.

isn't so called push really pull?

Ever since the introduction of push services in IOS I wonder how it works.
From what I found out the push function is basically an open connection that does not close serverside.
But mobiles are connecting at different points of the internet, the only way for a server to know where the mobile is connected is when the mobile tells the server where that it has changed location.
I read something about polling a connection so it stays open.
What advantage is there to manage and keep a changing open connection alive vs just checking if something is to pull?
Internally yes, push is implemented by having your phone poll for new data. The thing that makes push notifications attractive is that they are routed over Apple's service and that has many advantages.
From the phone's point of view, it only has to poll from one service, which means it can conserve bandwidth and piggyback on the normal operations of keeping a cellphone online. That means a lot less battery is used, and you can do things like set your phone to only receive push notifications every half hour, which means that 29 minutes out of every half hour you can turn off the data connection.
From the server's point of view, you no longer need to cache messages or provide quality-of-service guarantees. If you want to send a push notification to a phone that's out of range of a cell-tower for a few minutes, you may need to store the message for a considerable amount of time until the phone comes back online. Apple handles all this for you, and lets your server just be in charge of creating notifications, not storing and relaying them.

PUSH notifications via GPRS/3G. How stable are they?

I do an application design for a soft real-time software application now.
The application will probably need to notify its mobile users about some events in the system. An event can happen during a 15-minute time frame which starts after the user's first interaction with the system. The event notification should be done in soft real-time: if a user notified later than 15-20 seconds he was supposed to be notified, then it is critical. Basically, I need to notify a mobile user about an event no later than 15-20 seconds after that event happens during a 15-minutes time frame.
I plan to do that with some kind of PUSH technology (XMPP/Jabber, native app with Comet connection or maybe PUSH email).
Unfortunately, the most obvious solution which is to have mobile web-site (example: http://www.lightstreamer.com/) with real-time push notifications is not suitable, because in that case the user will have to stare at the screen during all the 15-minute time frame. Notifying a user with a sound or a vibration would be a much more pleasant user experience (connect to the system via smartphone -> start interaction with the system -> put the smartphone back into the pocket or a bag -> get notified).
I have done a simple experiment by sending Jabber chat messages between my laptop (WiFi/100Mbit) and my Android smartphone (GPRS/3G). The thing is that some of the messages sent to the smartphone are late (it takes about 1 minute until they arrive at the smartphone) or just lost (they never arrive at the smartphone). Moreover, I have noticed that the Jabber client at the smartphone goes offline regularly for a few seconds. I do not know if it is because I have a very cheap Android smartphone or because the 3G connection is not very good, but this behaviour is not acceptable for the software application that I design.
Thus, I am interested in the following:
is there any technology standard that can guarantee pushed message delivery to mobile (GPRS/3G) consumers in soft real-time? I.e. a technology standard which guarantees that a mobile client will be notified no later than N seconds from now;
do you know any examples of mobile apps which have soft real-time push notifications?
what are the ways to address the issue of delivering/pushing soft real-time messages to mobile devices in soft real-time? (e.g. keep sending the same message until the mobile device confirms the receipt of the message)
P.S. The intended use of the software application is with any smartphone, be it iPhone, Android, WP or any other internet-connected smartphone.
Note: This question is similar to one of my previous questions, but this one is about on a completely different use-case with strong focus on soft real-time requirements.
I know that this question is 3 years old but it doesn't have any answer.
A PUSH notification is always Best Effort. It means that the server will do it's best to deliver it but can not guarantee that it will be done on time or if it will be delivered at all.
Never rely on PUSH notifications to achieve a critical job.

Resources