opentrace-community / opentrace-android

OpenTrace Android app. Reference implementation of the BlueTrace protocol.
https://bluetrace.io
GNU General Public License v3.0
577 stars 223 forks source link

How does this solve scanning while the device is asleep? #3

Closed simekadam closed 4 years ago

simekadam commented 4 years ago

Hi, I'm struggling to understand how your implementation manages scanning while in background. There is no wakelock and the repeated scan scheduling is implemented via simple handler messages. To my understanding this won't work when the device goes into sleep. I now work on a similar app and we solve theses problems by keeping the device awake as we really want to make sure the scanning works continuously and reliably. Obviously it comes with some extra battery drain. That's why I'm trying to understand how you cope with this and if perhaps continuous scanning proved itself as not necessary.

slxe6 commented 4 years ago

Hi simekadam, we are using a foreground service to keep it running even when the app is in the background or killed. This is why you see a banner displayed on the notification bar when you run the app.

simekadam commented 4 years ago

But foreground service alone doesn't keep the device awake. It only lets your process stay running even if there are no visible activities. If the user turns of their screen the CPU goes to sleep after some time of inactivity and code execution stops until next wake up.

There are several mechanisms in Android that lets developers manage this behavior:

I don't see any of this being used

slxe6 commented 4 years ago

I misinterpreted your question. We are using AlarmManager to schedule intents to fire to our service at regular intervals. We have tried different ways to get the scanning and advertisement to work consistently during doze but we have yet to find a reliable way to do so.

Presently, TraceTogether is still affected by doze behavior and in our trials and testing we do note gaps of a few minutes during user's inactivity period. This gap is sometimes longer when the phone goes into deep doze usually when the user does not touch the phone for an extended period of time such as sleeping etc. Battery usage is a key concern for us and we strive to keep it to the minimum. Doze is both a friend and a foe.

After TraceTogether launched, different phone manufacturers have reached out to us and they offered to whitelist TraceTogether from doze but I am not sure if this is applicable for other applications. Hope this answers your question.

simekadam commented 4 years ago

Aw, I see the alarms now. 🤦 I was misled by this scheduling which uses a simple handler. https://github.com/opentrace-community/opentrace-android/blob/e8b68321d1c567f45898744c7210323c1660df6f/app/src/main/java/io/bluetrace/opentrace/services/BluetoothMonitoringService.kt#L441

I see that you also request the user to whitelist the app from battery optimizations. Shouldn't this solve the doze problem for you? To my understanding that should remove restrictions on when alarms can be fired. Albeit I guess that various manufactures might have different measure here.

There are still some places where I don't really understand the logic behind how this works..I see alarms scheduled to rotate the broadcasted id, but as I mentioned above, scanning seems to use just a normal handler. The there is some other alarm for scheduling health check. Didn't really dig into that, but I suppose that's unrelated to scanning. There's actually also this method which would do the scanning scheduling, but it is unused? https://github.com/opentrace-community/opentrace-android/blob/e8b68321d1c567f45898744c7210323c1660df6f/app/src/main/java/io/bluetrace/opentrace/Utils.kt#L146

Anyways, thanks a lot for your help and comments and if you were curious below is a link to our repo. https://github.com/covid19cz/erouska-android

slxe6 commented 4 years ago

We whitelisted the app from battery optimisations but our app was still subjected to doze. AlarmManager setExact and setWindows are deferred to the next maintenance window during doze and battery optimisations does not overcome this unfortunately so the doze effect still kicks in.

Yes the alarms are scheduled to rotate the TempIDs and perform health checks. The scanning cycle itself is done with just a Handler. You are correct the Utils.scheduleNextScan is not in use. We will clean this up to avoid confusion. Thank you for the feedback!

Thanks for sharing the link to your repo, we hope to learn from other teams building the same functionality. Cheers!