e-mission / e-mission-docs

Repository for docs and issues. If you need help, please file an issue here. Public conversations are better for open source projects than private email.
https://e-mission.readthedocs.io/en/latest
BSD 3-Clause "New" or "Revised" License
15 stars 34 forks source link

Dealing with background restrictions on non-stock android phones #535

Open shankari opened 4 years ago

shankari commented 4 years ago

Since e-mission started as a research project, all the initial development was on stock android, primarily running on Nexus phones. Since I wrote the code to be light on background usage, it doesn't use a wakelock. Instead, it uses an intent service that receives messages from the location APIs.

After API 28, the intent service is registered as a foreground service so it is allowed to receive fine grained updates.

As e-mission becomes more widely adopted, though, we need to deal with non-stock android phones. There are many known issues with non-stock phones and background operation (https://dontkillmyapp.com/) and all of them require manual user intervention to allow the app to work properly.

This issue tracks the question of how to let the users know what they need to know.

shankari commented 4 years ago

So far, I have had issues reported on Huawei by @PatGendre, Samsung by @asiripanich, and Redmi by numerous people in India.

shankari commented 4 years ago

My original plan was to integrate directly with https://dontkillmyapp.com/ and display the steps outlined there through their API. But after spending some time looking at it, I am not sure that is the right approach.

Several of their issues appear to be related to the use of wake locks, which is not a concern for e-mission. For example, consider their page on stock android, which says:

There’s a special option in Settings > Apps > Your app > Advanced > Battery > Background restrictions. If users accidentally enable this option it will break their apps. And users do enable that option!

but that is not actually true for e-mission since we use a foreground service for our location tracking. And @stephhuerre's team tested on android P recently and confirmed this.

Similarly, for Huawei, they list 4 steps but @PatGendre figured out that only the second one was needed.

EMUI 6+ devices (and some EMUI 5 devices)

    Phone settings > Advanced Settings > Battery manager > Power plan set to Performance
    Phone Settings > Advanced Settings > Battery Manager > Protected apps – set your app as Protected
    Phone Settings > Apps > Your app > Battery > Power-intensive prompt [uncheck] and Keep running after screen off [check]
    Phone settings > Apps > Advanced (At the bottom) > Ignore optimisations > Press Allowed > All apps > Find your app on the list and set to Allow

So I am concerned that blindly using https://dontkillmyapp.com/ will just confuse users and make them less likely to use the app. I am not sure that we want them to turn off OS-wide power saving measures (like setting the power plan to "performance") unless we have to.

So I'm thinking that we might want to look at the issues that others have reported on https://dontkillmyapp.com/, try to reproduce them ourselves and crowdsource an e-mission specific set of instructions instead.

@PatGendre @stephhuerre @kafitz @asiripanich @xubowenhaoren what do you think?

xubowenhaoren commented 4 years ago

Aware (FYI another data collection framework) uses a global foreground service. See an example here.

It also prompts the user to ignore doze mode (see here).

Lastly, it uses the accessibility service to monitor and restart the foreground service (see here). However, if you use this, then your app won't be allowed to publish in Play Store.

shankari commented 4 years ago

@xubowenhaoren thank you for your feedback on what AWARE does.

However, this just reiterates my point about having an e-mission specific workaround list since e-mission has been engineered to not have many of those issues apply to it.

Concretely, we do not need to ask the user for permission to ignore doze mode because e-mission does not use wake locks. We do not need to use an accessibility based hack to restart the foreground service since we use an intent based foreground service that is automatically triggered by the OS.

So we don't need to follow the same restrictions as other apps. We need to test the situations where the OS restrictions are affecting e-mission, and either rewrite the code to avoid them (preferred option) or to document the minimal set of user actions required for e-mission to work on non standard android phones.

PatGendre commented 4 years ago

Hi @shankari , I agree:

stephhuerre commented 4 years ago

Hi @shankari https://github.com/shankari ,

I agree with @PatGendre https://github.com/PatGendre , I think using an extra layer of complexity will confuse users. It is best to simplify and make custom instructions.

All the best!

On Mon, May 11, 2020 at 8:12 AM Patrick GENDRE notifications@github.com wrote:

Hi @shankari https://github.com/shankari , I agree:

  • using https://dontkillmyapp.com/ will just confuse end-users
  • we'd better have our e-mission specific set of instructions instead (which should be easy to find and understand for end-users)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/e-mission/e-mission-docs/issues/535#issuecomment-626492508, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIMDTWPXX6XSARP45Z7VAMLRQ6JMLANCNFSM4M5JIBKQ .

shankari commented 4 years ago

Aha! I actually found a programmatic way to check this, but don't have the appropriate phones to test. @kafitz does Itinerum have some test phones where we can experiment with this for the next release? @PatGendre @stephhuerre which phones do you have access to? :)

https://stackoverflow.com/a/49110392/4040267

kafitz commented 4 years ago

I have just a Pixel 3a which is pretty vanilla, but I can test here. Unfortunately our mobile development happened elsewhere and any test phones here were already ancient technology when we got them 4 years ago, but I will look around to see what is available.

shankari commented 4 years ago

@kafitz Yeah Pixel is pretty vanilla. I need to see if I can buy some cheap OEM phones, at least from the most prominent vendors.

shankari commented 4 years ago

Initial version of text at https://github.com/e-mission/e-mission-phone/pull/672 Comments on the wording and other test results welcome!

shankari commented 3 years ago

This has come up again as part of the CEO ebike full pilot. One of the testers has an Samsung Galaxy S6 Edge, which appears to turn the location services off and on by itself. This happens even after they have turned off the power saving features for the app.

This may be due to weird Verizon restrictions - e.g. https://community.verizon.com/t5/Samsung-Galaxy-Note/Location-Services-Turn-Off-Automatically-on-my-Note-8/td-p/1009105 or https://community.verizon.com/t5/Moto-Z-Droid/Location-services-and-NFC-turns-off/td-p/1070001 or https://community.verizon.com/t5/Android-General/Location-keeps-turning-off-automatically/td-p/1132800

A workaround would be to turn on continuous location sensing. That would avoid the current problems, in which the phone is turning location services on/off, the app is turning location tracking on/off and the two are unable to communicate since we don't get callbacks on location services availability if we are not tracking location.

https://developers.google.com/android/reference/com/google/android/gms/location/LocationCallback

The methods are called if the LocationCallback has been registered with the location client using the FusedLocationProviderApi.requestLocationUpdates(GoogleApiClient, LocationRequest, LocationCallback, Looper) method

Turning on continuous tracking would allow the location services availability to control the sensing and fix this mismatch.

I have verified in the emulator that if we have continuous location sensing turned on, turning location services off stops location intent delivery to the app.

But with continuous location tracking, we don't generate filtered_location objects on the phone. This means that we need to re-enable the feared and dreaded filter_accuracy step in the pipeline. Let's track that in https://github.com/e-mission/e-mission-docs/issues/637

shankari commented 3 years ago

Actually, the problem is not just the mismatch. Looking at her logs, we see that we typically get location points only every 5 minutes.

Reported by user: Sunday, 25th Apr 2021

Home – AS left ~ 8 am AS – to S area around 11-ish am S – Home – left around noon The walk at 5:16 is correct.

From the logs:

Geofence exit

102175,1619359547.2979999,2021-04-25T08:05:47.298000-06:00,GeofenceExitIntentService : onCreate called
102199,1619359547.4870002,2021-04-25T08:05:47.487000-06:00,ActivityRecognitionHandler : Starting activity recognition with interval = 30000
102202,1619359547.5,2021-04-25T08:05:47.500000-06:00,"TripDiaryStateMachineService : handleAction(local.state.waiting_for_trip_start, local.transition.exited_geofence) completed, waiting for async operations to complete"
102206,1619359547.5839999,2021-04-25T08:05:47.584000-06:00,TripDiaryStateMachineService : newState saved in prefManager is local.state.ongoing_trip

Bunch of locations, every ~ 5 minutes (Home -> AS, 8am)

102222,1619359547.6460001,2021-04-25T08:05:47.646000-06:00,"LocationChangeIntentService : Read locations from intent"
102243,1619359547.715,2021-04-25T08:05:47.715000-06:00,LocationChangeIntentService : Read locations from intent
102255,1619359874.855,2021-04-25T08:11:14.855000-06:00,"LocationChangeIntentService : Read locations from intent"
102286,1619360094.494,2021-04-25T08:14:54.494000-06:00,"LocationChangeIntentService : Read locations from intent"
102310,1619360128.234,2021-04-25T08:15:28.234000-06:00,"LocationChangeIntentService : Read locations from intent"
102329,1619360154.91,2021-04-25T08:15:54.910000-06:00,"LocationChangeIntentService : Read locations from intent"
102357,1619360474.7610002,2021-04-25T08:21:14.761000-06:00,"LocationChangeIntentService : Read locations from intent"
102669,1619360548.096,2021-04-25T08:22:28.096000-06:00,"LocationChangeIntentService : Read locations from intent"
102766,1619360577.754,2021-04-25T08:22:57.754000-06:00,"LocationChangeIntentService : Read locations from intent"
102795,1619360607.5089998,2021-04-25T08:23:27.509000-06:00,"LocationChangeIntentService : Read locations from intent"

Phone was rebooted

102825,1619370884.911,2021-04-25T11:14:44.911000-06:00,BootReceiver : BootReceiver.onReceive called
102826,1619370885.111,2021-04-25T11:14:45.111000-06:00,BuiltinUserCache : Added value for key statemachine/transition at time 1.61937088508E9

Reinitialize tracking

102828,1619370927.899,2021-04-25T11:15:27.899000-06:00,TransitionNotificationReceiver : Received platform-specification notification local.transition.initialize
102837,1619370928.014,2021-04-25T11:15:28.014000-06:00,"TripDiaryStateMachineService : after reading from the prefs, the current state is local.state.ongoing_trip"
102851,1619370928.351,2021-04-25T11:15:28.351000-06:00,TripDiaryStateMachineService : newState after handling action is local.state.waiting_for_trip_start

Exit geofence again (AS -> S area, 11-ish am)

102877,1619371221.5679998,2021-04-25T11:20:21.568000-06:00,TransitionNotificationReceiver : Received platform-specification notification local.transition.exited_geofence
102913,1619371222.2529998,2021-04-25T11:20:22.253000-06:00,"LocationChangeIntentService : Read locations from intent"
102937,1619371222.322,2021-04-25T11:20:22.322000-06:00,LocationChangeIntentService : Read locations from intent
102949,1619371533.044,2021-04-25T11:25:33.044000-06:00,"LocationChangeIntentService : Read locations from intent"
...
103293,1619373432.2710001,2021-04-25T11:57:12.271000-06:00,"LocationChangeIntentService : Read locations from intent"
...
103521,1619375886.188,2021-04-25T12:38:06.188000-06:00,"LocationChangeIntentService : Read locations from intent"
103541,1619375886.262,2021-04-25T12:38:06.262000-06:00,LocationChangeIntentService : stoppedMoving: stoppedMoving = true
103542,1619375886.264,2021-04-25T12:38:06.264000-06:00,LocationChangeIntentService : isTripEnded: stoppedMoving = false

Updates paused for ~ 20 mins (location turned off? around noon?)

103543,1619375886.2670002,2021-04-25T12:38:06.267000-06:00,LocationChangeIntentService : onDestroy called
103544,1619376860.1360002,2021-04-25T12:54:20.136000-06:00,LocationChangeIntentService : onCreate called
103963,1619380525.242,2021-04-25T13:55:25.242000-06:00,"LocationChangeIntentService : Read locations from intent"
103989,1619380525.385,2021-04-25T13:55:25.385000-06:00,TransitionNotificationReceiver : Received platform-specification notification local.transition.stopped_moving
104012,1619380525.742,2021-04-25T13:55:25.742000-06:00,TripDiaryStateMachineService : newState saved in prefManager is local.state.waiting_for_trip_start

Exited at 17:28 (walk is correct)

104052,1619393287.3979998,2021-04-25T17:28:07.398000-06:00,TransitionNotificationReceiver : Received platform-specification notification local.transition.exited_geofence
shankari commented 3 years ago

I have now acquired a samsung galaxy s6 edge from eBay and have installed the CanBikeCO app on it. I noticed that the foreground service disappeared soon after app install. On further investigation, this is because the android version (Settings -> About Device -> Software Info -> Android version) is 7.0. That's also what the tester has.

Let's go and take some trips now.

shankari commented 3 years ago

Trips seemed to work fine. Got a notification about an app that is draining battery. As expected, this was CanBikeCO. Was recommended to put app to sleep, which apparently restricts background operation and notifications. Can't figure out how to remove it from the list; the instructions are here https://www.samsung.com/us/support/answer/ANS00088422/ but I don't have a Background usage limits section

Warning about app usage Putting it to sleep Here's how to remove it later Is that the same as optimized
Screenshot_20210523-225141 Screenshot_20210523-230139 Screenshot_20210523-231346 Screenshot_20210523-230452

There's also a separate section on "optimized apps" that is accessed from the Apps entry. For now, the app is both optimized and sleeping, let's see what that does.

May need to reinstall the app/reset the phone to get the warning back.

shankari commented 3 years ago

wrt "Trips seem to work fine".

The points are definitely more frequent than 5 mins.

0    2021-05-23T20:39:18.984000-02:30
1    2021-05-23T20:39:25.796000-02:30
2    2021-05-23T20:39:56.160000-02:30
3    2021-05-23T20:39:58.396000-02:30
4    2021-05-23T20:40:27.120000-02:30
5    2021-05-23T20:40:32.659000-02:30
6    2021-05-23T20:41:02.114000-02:30
7    2021-05-23T20:41:06.903000-02:30
8    2021-05-23T20:41:35.122000-02:30
9    2021-05-23T20:41:52.124000-02:30
Screen Shot 2021-05-23 at 8 47 36 PM
shankari commented 3 years ago

So this is weird.

wrt my question "There's also a separate section on "optimized apps" that is accessed from the Apps entry.". The F-droid app is currently optimized but is not sleeping. I speculate that optimized apps are those for which samsung generates sleeping recommendations.

Processed trips Nothing on the 24th Notification Rules for sleeping apps F-droid is also optimized
Screenshot_20210524-015037 Screenshot_20210524-014955 Screenshot_20210524-014605 Screenshot_20210524-014728 Screenshot_20210524-021401
shankari commented 3 years ago

Although CanBikeCo was sleeping all night, it has been making GET calls the entire time. The GET calls are also extremely regular, roughly even hour. And they continue regularly through the time when the phone was unplugged (from around 10am). So the "sleep mode" doesn't seem to actually affect app operation.

0     2021-05-24T00:28:35.354171-07:00
2     2021-05-24T01:33:17.529982-07:00
4     2021-05-24T02:29:19.494450-07:00
6     2021-05-24T03:29:20.268457-07:00
8     2021-05-24T04:29:20.328079-07:00
10    2021-05-24T05:31:26.157468-07:00
12    2021-05-24T06:33:17.479962-07:00
14    2021-05-24T07:28:18.939388-07:00
16    2021-05-24T08:30:56.643318-07:00
18    2021-05-24T09:28:18.209212-07:00
20    2021-05-24T10:28:24.862274-07:00
22    2021-05-24T11:31:38.185676-07:00
26    2021-05-24T13:45:14.255243-07:00
46    2021-05-24T14:44:42.299872-07:00

Location points sometimes have a gap of a minute but nothing like what we saw with the other Edge phone.

0    2021-05-24T16:04:40.518000-02:30
1    2021-05-24T16:04:40.518000-02:30
2    2021-05-24T16:04:47.830000-02:30
3    2021-05-24T16:05:14.479000-02:30
4    2021-05-24T16:05:24.015000-02:30
5    2021-05-24T16:05:59.438000-02:30
6    2021-05-24T16:07:40.658000-02:30
7    2021-05-24T16:07:46.658000-02:30
8    2021-05-24T16:07:51.999000-02:30
9    2021-05-24T16:07:57.999000-02:30

Here's the raw data.

Screen Shot 2021-05-24 at 4 02 09 PM
I will note that the raw data quality appears to be somewhat poor - e.g. Weird points that don't match routes Noisy data at destination
Screen Shot 2021-05-24 at 5 42 29 PM Screen Shot 2021-05-24 at 5 43 15 PM

Also, there was no foreground notification after either trip. Need to see if the push notification shows up.

shankari commented 3 years ago

At around 4:30pm, switched to MID power saving mode, which lowers CPU speeds and reduced background network usage. https://www.samsung.com/in/support/mobile-devices/how-to-enable-power-saving-mode-in-samsung-galaxy/

Let's see if that changes anything.

Took a carpool trip right after that and a bike trip at around 6:15pm.

shankari commented 3 years ago

ok! Neither of the trips after the switch to MID power was recorded. Let's take a look at the logs.

Notification Trips in the afternoon Nothing after that
Screenshot_20210525-003422 Screenshot_20210525-003531 Screenshot_20210525-003558
shankari commented 3 years ago

The push notification was received and displayed correctly, and then kept reappearing roughly every few minutes.

Over and over and over
Screenshot_20210525-003750 Screenshot_20210524-201247 Screenshot_20210524-202459

Ah the second issue is because of the crontab entry

* 3 * * * ./e-mission-py.bash bin/push/push_to_users.py -t "Trip labels requested" "Please label your trips for the day" -a  >> /var/log/push_trip_reminder.stdinout 2>&1

Fixed by changing to

0 3 * * * ./e-mission-py.bash bin/push/push_to_users.py -t "Trip labels requested" "Please label your trips for the day" -a  >> /var/log/push_trip_reminder.stdinout 2>&1
shankari commented 3 years ago

So from the logs, the problem is that the broadcast receiver doesn't seem to work when MID power saving is on.

For the trip around 1pm, we get an exited_geofence callback to the broadcast receiver.

5793,1621885864.9720001,2021-05-24T12:51:04.972000-07:00,"TripDiaryStateMachineRcvr : TripDiaryStateMachineReciever onReceive(android.app.ReceiverRestrictedContext@1fdc82a, Intent { act=local.transition.exited_geofence flg=0x10 pkg=gov.colorado.energyoffice.emission cmp=gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.TripDiaryStateMachineReceiver launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } bqHint=1 }) called"
9444,1621889380.6320002,2021-05-24T13:49:40.632000-07:00,"TripDiaryStateMachineRcvr : TripDiaryStateMachineReciever onReceive(android.app.ReceiverRestrictedContext@1fdc82a, Intent { act=local.transition.stopped_moving flg=0x10 pkg=gov.colorado.energyoffice.emission cmp=gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.TripDiaryStateMachineReceiver launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } bqHint=1 }) called"

But for the later trips, although we get geofence exits, the receiver doesn't seem to be triggered, so we don't turn on the location tracking.

5780,1621885864.8520002,2021-05-24T12:51:04.852000-07:00,GeofenceExitIntentService : onStartCommand called with intent Intent { cmp=gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.GeofenceExitIntentService launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } (has extras) } flags 0 startId 1
5781,1621885864.8579998,2021-05-24T12:51:04.858000-07:00,GeofenceExitIntentService : onStart called with startId 1
5782,1621885864.86,2021-05-24T12:51:04.860000-07:00,GeofenceExitIntentService : geofence exit intent action = null
5783,1621885864.87,2021-05-24T12:51:04.870000-07:00,GeofenceExitIntentService : parsedEvent = com.google.android.gms.location.GeofencingEvent@6ab03bd
5784,1621885864.877,2021-05-24T12:51:04.877000-07:00,"GeofenceExitIntentService : got geofence intent callback with type 2 and location Location[fused ... acc=44 et=+8d2h46m27s657ms alt=-46.58838114754745 {Bundle[mParcelledData.dataSize=52]}]"
5785,1621885864.88,2021-05-24T12:51:04.880000-07:00,GeofenceExitIntentService : Geofence exited! Intent = Intent { cmp=gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.GeofenceExitIntentService launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } (has extras) } Starting ongoing monitoring...
5792,1621885864.96,2021-05-24T12:51:04.960000-07:00,GeofenceExitIntentService : onDestroy called

There is really no difference in the Geofence exit between the code above (which succeeded without power savings) and the code below, which failed with power savings.

9720,1621899324.645,2021-05-24T16:35:24.645000-07:00,GeofenceExitIntentService : onCreate called
9721,1621899324.65,2021-05-24T16:35:24.650000-07:00,GeofenceExitIntentService : onStartCommand called with intent Intent { cmp=gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.GeofenceExitIntentService launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } (has extras) } flags 0 startId 1
9722,1621899324.6560001,2021-05-24T16:35:24.656000-07:00,GeofenceExitIntentService : onStart called with startId 1
9723,1621899324.659,2021-05-24T16:35:24.659000-07:00,GeofenceExitIntentService : geofence exit intent action = null
9724,1621899324.676,2021-05-24T16:35:24.676000-07:00,GeofenceExitIntentService : parsedEvent = com.google.android.gms.location.GeofencingEvent@cd30a09
9725,1621899324.685,2021-05-24T16:35:24.685000-07:00,"GeofenceExitIntentService : got geofence intent callback with type 2 and location Location[fused 37.382832,-122.115519 acc=1200 et=+8d6h30m46s292ms alt=3.4001871636678587 {Bundle[mParcelledData.dataSize=52]}]"
9726,1621899324.687,2021-05-24T16:35:24.687000-07:00,GeofenceExitIntentService : Geofence exited! Intent = Intent { cmp=gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.GeofenceExitIntentService launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } (has extras) } Starting ongoing monitoring...
9728,1621899324.79,2021-05-24T16:35:24.790000-07:00,GeofenceExitIntentService : onDestroy called

In fact, there were literally no logs between the geofence exit at 16:35 (id 9728) and the one at 18:28 (id 9729)

9729,1621906090.244,2021-05-24T18:28:10.244000-07:00,GeofenceExitIntentService : onCreate called
9730,1621906090.2529998,2021-05-24T18:28:10.253000-07:00,GeofenceExitIntentService : onStartCommand called with intent Intent { cmp=gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.GeofenceExitIntentService launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } (has extras) } flags 0 startId 1
9731,1621906090.256,2021-05-24T18:28:10.256000-07:00,GeofenceExitIntentService : onStart called with startId 1
9732,1621906090.262,2021-05-24T18:28:10.262000-07:00,GeofenceExitIntentService : geofence exit intent action = null
9733,1621906090.276,2021-05-24T18:28:10.276000-07:00,GeofenceExitIntentService : parsedEvent = com.google.android.gms.location.GeofencingEvent@cd30a09
9734,1621906090.2870002,2021-05-24T18:28:10.287000-07:00,"GeofenceExitIntentService : got geofence intent callback with type 2 and location Location[... acc=48 et=+8d8h23m32s949ms alt=-12.073251402735451 vel=4.6222234 bear=31.475302]"
9735,1621906090.292,2021-05-24T18:28:10.292000-07:00,GeofenceExitIntentService : Geofence exited! Intent = Intent { cmp=gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.GeofenceExitIntentService launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } (has extras) } Starting ongoing monitoring...
9737,1621906090.3779998,2021-05-24T18:28:10.378000-07:00,GeofenceExitIntentService : onDestroy called
shankari commented 3 years ago

The background restrictions seem to only apply to when the phone is not plugged in

We start with calls roughly every hour

4965,1621877304.94,2021-05-24T10:28:24.940000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
5009,1621881102.518,2021-05-24T11:31:42.518000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
9065,1621889111.1620002,2021-05-24T13:45:11.162000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
9620,1621892677.9,2021-05-24T14:44:37.900000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY

Stop syncing after 4pm when switching to MID and start up again at 8pm

9677,1621898346.562,2021-05-24T16:19:06.562000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
9741,1621911736.5879998,2021-05-24T20:02:16.588000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY

And then we have every hour overnight while the phone was plugged in.

10119,1621917300.849,2021-05-24T21:35:00.849000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10165,1621920795.911,2021-05-24T22:33:15.911000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10211,1621924395.7229998,2021-05-24T23:33:15.723000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10257,1621927802.539,2021-05-25T00:30:02.539000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10303,1621931580.24,2021-05-25T01:33:00.240000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10349,1621935195.349,2021-05-25T02:33:15.349000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10395,1621938602.408,2021-05-25T03:30:02.408000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10441,1621942202.316,2021-05-25T04:30:02.316000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10487,1621945868.9229999,2021-05-25T05:31:08.923000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10533,1621949595.3439999,2021-05-25T06:33:15.344000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10579,1621953195.504,2021-05-25T07:33:15.504000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
10625,1621957369.095,2021-05-25T08:42:49.095000-07:00,TripDiaryStateMachineRcvr : START PERIODIC ACTIVITY
shankari commented 3 years ago

This indicates that resolving the issue with the broadcast notification, or switching to a different event handling mechanism would resolve the problem. The advantage of broadcast notifications is the decoupling between different android modules. I double checked and we do use explicit intents. As we can see from the fact that the events are received without the restrictions.

Before digging too much deeper into this, I want to see what the locations look like under these restrictions. Turning off duty cycling = Turning on continuous tracking and taking a walk around the block.

shankari commented 3 years ago

Aha! Bingo! When I turned on continuous tracking, the location symbol on the notification bar turned on. But when I came back from the trip, and then after lunch, the location icon stayed stubbornly off. It came back again when I launched the app to upload logs. This is with ongoing tracking, no duty cycling, so it can't be due to any geofence issues. Need to look at the logs

Before leaving After coming back After lunch Launched app
Screenshot_20210525-120840 Screenshot_20210525-122648 Screenshot_20210525-132604 Screenshot_20210525-132649

Note also that the "Launched app" screenshot has a black location icon as well, which I assume is the foreground service notification.

shankari commented 3 years ago

Yes, this trip quality is pretty bad as well.

At 2:30 after some more time
Screen Shot 2021-05-25 at 2 30 13 PM Screen Shot 2021-05-25 at 8 21 35 PM
0    2021-05-25T12:07:58.915000-07:00
1    2021-05-25T12:08:17.573000-07:00
2    2021-05-25T12:08:40.039000-07:00
3    2021-05-25T12:08:50.774000-07:00
4    2021-05-25T12:09:04.965000-07:00
5    2021-05-25T12:09:40.848000-07:00
6    2021-05-25T12:10:10.880000-07:00
7    2021-05-25T12:10:41.036000-07:00
8    2021-05-25T12:11:10.917000-07:00
9    2021-05-25T12:11:40.986000-07:00
Name: fmt_time, dtype: object

This is where we switched to the continuous data collection

10994,1621969689.129,2021-05-25T12:08:09.129000-07:00,TripDiaryStateMachineService : TripDiaryStateMachineReceiver handleTrackingStopped(local.transition.start_tracking) called
10995,1621969689.1320002,2021-05-25T12:08:09.132000-07:00,LocationHandler : default request is Request[PRIORITY_BALANCED_POWER_ACCURACY requested=3600000ms fastest=600000ms]
10996,1621969689.1339998,2021-05-25T12:08:09.134000-07:00,"LocationHandler : after applying config, value is Request[PRIORITY_HIGH_ACCURACY requested=30000ms fastest=5000ms]"
10997,1621969689.1379998,2021-05-25T12:08:09.138000-07:00,ActivityRecognitionHandler : Starting activity recognition with interval = 30000
10999,1621969689.175,2021-05-25T12:08:09.175000-07:00,TripDiaryStateMachineService : newState after handling action is local.state.ongoing_trip

Initially, all was well, and we were getting points every 30 seconds, or even less!

11013,1621969689.28,2021-05-25T12:08:09.280000-07:00,LocationChangeIntentService : Read locations null from intent
11020,1621969689.4429998,2021-05-25T12:08:09.443000-07:00,"LocationChangeIntentService : Read locations [Location[fused 37.391043,-122.086459 acc=12 et=+9d2h3m22s42ms alt=-4.123652705050885 {Bundle[mParcelledData.dataSize=52]}]] from intent"
11027,1621969696.4120002,2021-05-25T12:08:16.412000-07:00,"LocationChangeIntentService : Read locations [Location[fused 37.391089,-122.086496 acc=24 et=+9d2h3m39s463ms alt=-4.0498009835022 vel=0.106007636 bear=339.0 {Bundle[mParcelledData.dataSize=52]}]] from intent"
11034,1621969720.096,2021-05-25T12:08:40.096000-07:00,"LocationChangeIntentService : Read locations [Location[fused 37.391044,-122.086451 acc=15 et=+9d2h4m3s166ms alt=-4.506273702311313 {Bundle[mParcelledData.dataSize=52]}]] from intent"

Until 10 minutes after the start. At that point, all updates stop until the app is launched again after lunch.

11224,1621970326.355,2021-05-25T12:18:46.355000-07:00,"LocationChangeIntentService : Read locations [Location[fused 37.395915,-122.081581 acc=437 et=+9d2h14m8s271ms alt=-5.372534582514927 {Bundle[mParcelledData.dataSize=52]}]] from intent"
11231,1621970356.518,2021-05-25T12:19:16.518000-07:00,"LocationChangeIntentService : Read locations [Location[fused 37.399428,-122.077531 acc=900 et=+9d2h14m38s423ms alt=-8.201757912975607 {Bundle[mParcelledData.dataSize=52]}]] from intent"
...
11310,1621974388.303,2021-05-25T13:26:28.303000-07:00,LocationChangeIntentService : Read locations null from intent
11332,1621974389.175,2021-05-25T13:26:29.175000-07:00,"LocationChangeIntentService : Read locations [Location[fused 37.391041,-122.086456 acc=17 et=+9d3h21m52s178ms alt=-4.227138359505194 {Bundle[mParcelledData.dataSize=52]}]] from intent"

The last recorded point is partway through the trip (beyond the overpass) and not at the actual trip end.

shankari commented 3 years ago

Let's reproduce this again with a walk trip, and then switch to extreme power saving mode to see if we can reproduce the problem with the points only being recorded every 5 mins. Then, we can figure out how to avoid that.

shankari commented 3 years ago

Ok so this is super weird. I went on a walk trip, leaving between 4:30 and 5pm. When I checked the phone at around 5pm, this time the location was on. And it stayed on for the entire hour from 5pm to 6pm. Then it turned off, and would not turn on again even when I launched the app. wtf are you doing, samsung?

Location on (end of walk) Location on (entering house) Location on (on desk)
Screenshot_20210525-171005 Screenshot_20210525-171206 Screenshot_20210525-174526
Location off (is this the witching hour?) Location off (not a fluke) Location off (even when app is in foreground and ongoing trip state)
Screenshot_20210525-180155 Screenshot_20210525-181755 Screenshot_20210525-181927
shankari commented 3 years ago

so the raw location points are consistent with the behavior on the phone.

There was a giant gap between 15:25 and 16:54

13393,1621981551.615,2021-05-25T15:25:51.615000-07:00,"LocationChangeIntentService : Read locations [Location[fused redacted acc=17 et=+9d5h21m14s631ms alt=-4.097496459035437 {Bundle[mParcelledData.dataSize=52]}]] from intent"
13409,1621984535.696,2021-05-25T16:15:35.696000-07:00,LocationChangeIntentService : Read locations null from intent
13417,1621986842.5879998,2021-05-25T16:54:02.588000-07:00,"LocationChangeIntentService : Read locations [Location[fused redacted acc=14 et=+9d6h49m25s491ms alt=-4.333269289703798 {Bundle[mParcelledData.dataSize=52]}]] from intent"

Then there were location points consistently for an hour

13435,1621986872.975,2021-05-25T16:54:32.975000-07:00,"LocationChangeIntentService : Read locations [Location[fused redacted acc=16 et=+9d6h49m55s997ms alt=-4.253440284648558 {Bundle[mParcelledData.dataSize=52]}]] from intent"
14506,1621990865.438,2021-05-25T18:01:05.438000-07:00,"LocationChangeIntentService : Read locations [Location[fused redacted acc=15 et=+9d7h56m28s462ms alt=-4.168450834470828 {Bundle[mParcelledData.dataSize=52]}]] from intent"

when they abruptly stopped

Looking at the detailed logs around the start, both the false start and the real one, there seem to be messages around the Activity Recognition code, but the location is not available.

13399,1621984513.6360002,2021-05-25T16:15:13.636000-07:00,"ActivityRecognitionChangeIntentService : Detected new activity DetectedActivity [type=TILTING, confidence=100]"
...
13409,1621984535.696,2021-05-25T16:15:35.696000-07:00,LocationChangeIntentService : Read locations null from intent
13410,1621984535.698,2021-05-25T16:15:35.698000-07:00,LocationChangeIntentService : availability = false
13417,1621986842.5879998,2021-05-25T16:54:02.588000-07:00,"LocationChangeIntentService : Read locations [Location[fused redacted acc=14 et=+9d6h49m25s491ms alt=-4.333269289703798 {Bundle[mParcelledData.dataSize=52]}]] from intent"
...
13427,1621986853.294,2021-05-25T16:54:13.294000-07:00,"ActivityRecognitionChangeIntentService : Detected new activity DetectedActivity [type=UNKNOWN, confidence=40]"

But we also detected a bunch of STILL activity around 5:23 and the location access didn't stop then

13765,1621987910.43,2021-05-25T17:11:50.430000-07:00,"ActivityRecognitionChangeIntentService : Detected new activity DetectedActivity [type=ON_FOOT, confidence=97]"
13798,1621988004.189,2021-05-25T17:13:24.189000-07:00,"ActivityRecognitionChangeIntentService : Detected new activity DetectedActivity [type=TILTING, confidence=100]"
13803,1621988004.2389998,2021-05-25T17:13:24.239000-07:00,"ActivityRecognitionChangeIntentService : Detected new activity DetectedActivity [type=STILL, confidence=100]"
13885,1621988333.502,2021-05-25T17:18:53.502000-07:00,"ActivityRecognitionChangeIntentService : Detected new activity DetectedActivity [type=STILL, confidence=100]"
13953,1621988582.8779998,2021-05-25T17:23:02.878000-07:00,"ActivityRecognitionChangeIntentService : Detected new activity DetectedActivity [type=STILL, confidence=100]"

At the time that we actually stopped tracking, there's nothing. Samsung just cut off location access to the app.

14507,1621990865.447,2021-05-25T18:01:05.447000-07:00,BuiltinUserCache : Added value for key background/location at time 1.621990865442E9
14508,1621990865.454,2021-05-25T18:01:05.454000-07:00,LocationChangeIntentService : onDestroy called
14509,1621991886.0970001,2021-05-25T18:18:06.097000-07:00,BuiltinUserCache : Added value for key stats/client_nav_event at time 1.621991886084E9
14510,1621991886.106,2021-05-25T18:18:06.106000-07:00,BuiltinUserCache : Added value for key background/battery at time 1.621991886104E9
14511,1621991886.1179998,2021-05-25T18:18:06.118000-07:00,"ServerSyncAdapter : introDoneResult = {""intro_done"":""2021-05-23T19:49:10-02:30""}"

The map looks like:

Screen Shot 2021-05-25 at 8 19 56 PM
shankari commented 3 years ago

Got push notification at 8pm PT, location is now on again.

shankari commented 3 years ago

Switching to max power savings now. Location is off. But WiFi is also off. Screenshots are stuck in the Outbox. Manually turned on WiFi, now taking a trip.

Location on after push Turning on Maximum power savings Weird new screen, with only selected apps
Screenshot_20210525-202346 Screenshot_20210525-202517 Screenshot_20210525-202543
shankari commented 3 years ago

It also has a weird screen that can only run some apps, CanBikeCO is apparently not one of them, and location is turned completely off by default. This seems like an excessively conservative mode.

Weird home screen CanBikeCO not visible as an app No location
Screenshot_20210525-204506 Screenshot_20210525-204353 Screenshot_20210525-204439
shankari commented 3 years ago

Sent a push notification to this phone at around 10:15pm. Still not received. Will plug in at around 10:45 and see what is going on.

shankari commented 3 years ago

Plugged in the phone at 10:45 and left it plugged in overnight. Saw a notification from Google Play in the middle of the night, clicking on it revealed that Google Play Services appeared to be disabled (!!), but it wasn't clear if we could even enable it.

Switched to mid mode today morning, got all notifications from last night and location turned on. Read up on max mode some more and it is pretty clear that:

Turned on power saving mode Was providing location to the app But turned off very soon
Screenshot_20210526-074016 Screenshot_20210526-074153 Screenshot_20210526-075711

And then never actually came back on, even when I took a walk.

Leaving en-route back
Screenshot_20210526-090749 Screenshot_20210526-091826 Screenshot_20210526-092202
shankari commented 3 years ago

Now that we have established the capricious nature of enabling location for the app, I am going to see how to mitigate that.

But in the interim, I also want to do an intellectual experiment on whether the location is enabled more often after the app is launched.

Trying again....

It almost seems like the phone checks every 30 mins and turns off if there hasn't been any motion. But it doesn't turn on automatically when we start moving, which is the big bottleneck for our work. There does not appear to be any way to handle this gracefully in the code. If the OS turns off location access to the app (pretends that the location is not available), at arbitrary times, there is not much we can do.

shankari commented 3 years ago

Looking the system logs for that time to understand the mechanism better, there are no messages from the app.

./bugreport-2021-05-26-09-32-54.txt:05-26 07:54:40.252 32276  4364 D LocationChangeIntentService: FINALLY! Got location update, intent is Intent { cmp=gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.LocationChangeIntentService launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } (has extras) }
./bugreport-2021-05-26-09-32-54.txt:05-26 07:55:10.272 25774 25774 D CatchNotificationsView: Inflate item  - gov.colorado.energyoffice.emission, postTime : 1622040087718
./bugreport-2021-05-26-09-32-54.txt:05-26 07:55:10.276 25774 25774 D CatchNotificationsView: Inflate item  - gov.colorado.energyoffice.emission, postTime : 1622040087718
./bugreport-2021-05-26-09-32-54.txt:05-26 08:27:03.993 26268 26354 D BadgeCache: 1. updateBadgeCounts: gov.colorado.energyoffice.emission = 0

But I do see

05-26 07:55:10.123  3642 13640 D LocationManagerService: provider request: gps ProviderRequest[OFF]

in the middle.

there are a bunch of similar messages at around the right times

05-26 07:55:10.123  3642 13640 D LocationManagerService: provider request: gps ProviderRequest[OFF]

05-26 08:47:08.496  3642  3642 D LocationManagerService: provider request: fused ProviderRequest[ON interval=0]
05-26 08:47:08.505  3642  3642 D LocationManagerService: provider request: gps ProviderRequest[ON interval=+1s0ms]
05-26 08:47:08.566  3642  4735 D LocationManagerService: provider request: gps ProviderRequest[ON interval=0]

05-26 08:47:14.536  3642  3658 D LocationManagerService: provider request: fused ProviderRequest[OFF]
05-26 08:47:14.549  3642  3658 D LocationManagerService: provider request: gps ProviderRequest[ON interval=0]
05-26 08:47:14.555  3642  4820 D LocationManagerService: provider request: gps ProviderRequest[OFF]

Let's get some more system logs and see what we can find.

shankari commented 3 years ago

Here are additional logs that cover the time period in https://github.com/e-mission/e-mission-docs/issues/535#issuecomment-849011947

05-26 11:19:00.500  3642  9487 D LocationManagerService: provider request: gps ProviderRequest[ON interval=+30s0ms]
05-26 11:30:35.366  3642  3654 D LocationManagerService: provider request: gps ProviderRequest[OFF]
05-26 11:50:37.094  3642  3653 D LocationManagerService: provider request: gps ProviderRequest[ON interval=+30s0ms]
05-26 12:39:22.715  3642  3911 D LocationManagerService: provider request: gps ProviderRequest[OFF]

And it matches exactly. Basically, the GPS is getting turned off, which is causing all location to be turned off because we are looking for high accuracy data collection.

But is it cause or effect? is the GPS turned off because the requesting app has been killed, or is the app killed because the GPS is turned off?

shankari commented 3 years ago

Doesn't seem to be super consistent.

1: Instance 1 at 11:30

We got a location

05-26 11:30:06.237 20841 22441 D LocationChangeIntentService: Read locations [Location[fused 37.391010,-122.086462 acc=16 et=+10d1h25m29s201ms alt=-4.064562022362958 {Bundle[mParcelledData.dataSize=52]}]] from intent
05-26 11:30:06.249 20841 22441 D BuiltinUserCache: Added value for key background/location at time 1.622053806241E9
05-26 11:30:06.267 20841 20841 D LocationChangeIntentService: onDestroy called

Location services state was changed

05-26 11:30:35.358  3959  4351 D LocationControllerImpl: onReceive   android.location.HIGH_POWER_REQUEST_CHANGE
05-26 11:30:35.360  3959  4351 D LocationControllerImpl: refreshViews mAreActiveLocationRequests  false isPaused false
05-26 11:30:35.361  3642  3654 I LocationManagerService: remove 1d23211
05-26 11:30:35.366  3642  3654 D LocationManagerService: provider request: gps ProviderRequest[OFF]

A long time later, we launch the app

05-26 11:49:59.662 23184 23184 I SELinux : SELinux: seapp_context_lookup: seinfo=untrusted, level=s0:c512,c768, pkgname=gov.colorado.energyoffice.emission
05-26 11:50:00.554  3642  3667 I ActivityManager: Displayed gov.colorado.energyoffice.emission/.MainActivity: +907ms

2: Instance 2 at 12:39

we get a location

05-26 12:38:53.479 23184 30889 D LocationChangeIntentService: Read locations [Location[fused 37.391043,-122.086463 acc=13 et=+10d2h34m16s475ms alt=-4.2659448259381225 {Bundle[mParcelledData.dataSize=52]}]] from intent
05-26 12:38:53.487 23184 30889 D BuiltinUserCache: Added value for key background/location at time 1.622057933482E9

App is killed

05-26 12:39:22.613  3642  3659 V MARsPolicyManager: executePolicy policy = applocker(1), reason = App Locker First -- 10Min
05-26 12:39:22.620  3642  3659 I ActivityManager: Force stopping gov.colorado.energyoffice.emission appid=10197 user=0: MARs-Kill-SkipAdj-applocker(1)
05-26 12:39:22.622  3642  3659 I ActivityManager: Killing 23184:gov.colorado.energyoffice.emission/u0a197 (adj 700): stop gov.colorado.energyoffice.emission cause MARs-Kill-SkipAdj-applocker(1)

Restarting and then re-killing the foreground service

05-26 12:39:22.628  3642  3659 W ActivityManager: Scheduling restart of crashed service gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.TripDiaryStateMachineForegroundService in 1000ms
05-26 12:39:22.640  3642  3659 I ActivityManager:   Force stopping service ServiceRecord{805c0be u0 gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.TripDiaryStateMachineForegroundService}
05-26 12:39:22.648  3642  3659 I WindowManager_SurfaceController: Destroying surface Surface(name=gov.colorado.energyoffice.emission/gov.colorado.energyoffice.emission.MainActivity) called by com.android.server.wm.WindowStateAnimator.destroySurface:2907 com.android.server.wm.WindowStateAnimator.destroySurfaceLocked:1120 com.android.server.wm.WindowState.removeLocked:1867 com.android.server.wm.WindowManagerService.removeWindowInnerLocked:2934 com.android.server.wm.WindowManagerService.removeWindowLocked:2865 com.android.server.wm.WindowManagerService.removeWindowLocked:2689 com.android.server.wm.AppWindowToken.removeAllWindows:608 com.android.server.wm.AppWindowToken.removeAppFromTaskLocked:370

And then turned off the location

05-26 12:39:22.706  3959  4351 D LocationControllerImpl: onReceive   android.location.HIGH_POWER_REQUEST_CHANGE
05-26 12:39:22.708  3959  3959 D TextClock: TextClock received ACTION_TIME_TICK : start
05-26 12:39:22.709  3959  3959 D TextClock: TextClock received ACTION_TIME_TICK : end
05-26 12:39:22.712  3959  4351 D LocationControllerImpl: refreshViews mAreActiveLocationRequests  false isPaused false
05-26 12:39:22.714  3642  3911 I LocationManagerService: remove fe08970
05-26 12:39:22.715  3642  3911 D LocationManagerService: provider request: gps ProviderRequest[OFF]

In fact, around 11:30, the app was not even killed

$ grep "Force stopping" /tmp/bugreport/bugreport-2021-05-26-12-47-49.txt
05-26 12:39:22.620  3642  3659 I ActivityManager: Force stopping gov.colorado.energyoffice.emission appid=10197 user=0: MARs-Kill-SkipAdj-applocker(1)
05-26 12:39:22.640  3642  3659 I ActivityManager:   Force stopping service ServiceRecord{805c0be u0 gov.colorado.energyoffice.emission/edu.berkeley.eecs.emission.cordova.tracker.location.TripDiaryStateMachineForegroundService}
shankari commented 3 years ago

Given this, not sure if we can make it work with any app-level exception. But let's try anyway.

Try 1

At this point, it seems pretty clear that preventing app sleeping seems to work at least for continuous data collection. Switching to duty cycled now...

shankari commented 3 years ago

I will note, though, that the F-Droid app is now "sleeping". I didn't click on "Save power" for it, and it is not in "Always sleeping". Re launching it wakes it up. So part of the problem might be that, if users don't launch the app frequently, it goes to sleep automatically.

Not sleeping Sleeping Not sleeping (after launch)
Screenshot_20210526-201922 Screenshot_20210527-030603 Screenshot_20210527-090440
shankari commented 3 years ago

Adding this to "unmonitored apps" to avoid inadvertently being put to sleep. I will then return to duty cycling, and take a few trips to confirm that everything works.

shankari commented 3 years ago

Took a trip, location was on during the trip and the app was in "ongoing_trip" state. Some time after coming back, went to the "waiting_for_trip_start" state correctly. Note no location icon when waiting for trip start.

During trip Right after coming back After 10 mins
Screenshot_20210527-112503 Screenshot_20210527-113253 Screenshot_20210527-114754
shankari commented 3 years ago

Took another trip, this time by bike. Location icon came on just over a block away. Still on at trip end. App in ongoing_trip state. Location icon turned off some time after trip end. Everything seems to be working fine.

shankari commented 3 years ago

what I want to do over the weekend, is to not launch the app manually at all, and take a bunch of trips and then check on Tuesday to see if everything is correct. Because what i noticed with F-Droid is that if an app has not been manually launched for a while, the phone puts it into sleep mode. But if you launch the app UI then it wakes it up (https://github.com/e-mission/e-mission-docs/issues/535#issuecomment-849760428)

shankari commented 3 years ago

Argh, this is not working as well as I had hoped.

Trip checks over the weekend:
- Sat: Walk at 9:35, works
- Sat: Bike at 8pm, works
- Sun: All day hiking trip, worked, just did not upload until the phone was plugged in at night
shankari commented 3 years ago

Hey, wait a minute, although there was clearly an all day hiking trip on Sun in the transitions, it doesn't show up in the cleaned trips. And I didn't notice it until I launched the app right now.

These are the transitions:

2021-05-31T17:10:32.216000-07:00
2021-05-31T16:55:22.947000-07:00
2021-05-31T12:08:40.251000-07:00
2021-05-31T10:51:23.091000-07:00
2021-05-30T15:12:40.636000-07:00
2021-05-30T08:26:59.260000-07:00

But these are the trips:

2021-05-31T16:48:58.988788-07:00 2021-05-31T17:07:30.911000-07:00
2021-05-30T08:21:18.411084-07:00 2021-05-30T08:27:31.193000-07:00

The 10-12 trip on the 31st has disappeared completely; the 8-15 trip on the 30th has been truncated to 5 minutes

shankari commented 3 years ago

Tried to turn off optimizations for the app right after noticing that behavior. The app has been in the "not optimized" list for the past week, but the trips have still been very poor quality. This continued until Fri evening.

Then, I turned off all power optimizations for the phone. All trips since Saturday, including hiking trips in the mountains, have seem to have been recorded correctly, with the exception of trip to REI on Sunday. I have turned on power savings again on Saturday night; let's see what the impact is tomorrow.

PatGendre commented 3 years ago

Hi @shankari , we have similar problems of background restrictions on Android phones : Romain, the project manager of the la Rochelle self data experimentation, has a Xiaomi on Android10 and the app is often killed. For one trip, ha had the Xiaomi and an Iphone with the app installed, and the trip was recorded on iOS but not on Android. I can send you his logs if you're interested to have a look?
Do you maintain a list of model specific issue with e-mission background restrictions somewhere in a FAQ ?
We suggested to Romain to check on https://dontkillmyapp.com/xiaomi if he can solve the problem by modifying certain xiaomi parameters (he will have a look, I'll tell you if this works).

Also, an intern is currently testing e-mission at the IT department of the Lyon urban area county, and they have similar problems. They are concerned that the problems may worsen as each new version of Android seems to restrict even more third party apps wrt location and background execution. What's your point of view on this, on the mid term? Could this imply to redesign part of the e-mission data collection layer?

shankari commented 3 years ago

@PatGendre I want to distinguish between stock android and the manufacturer-specific variations.

stock android: It is absolutely true that each new version of Android adds additional restrictions on background location tracking. However, there are documented APIs that developers can use to request permissions, and more crucially, to check whether the permissions have been given. The e-mission platform will fully support stock android going forward.

android variants: as you can see from https://dontkillmyapp.com/, the android variants have additional restrictions that cannot be queried or modified by app developers. We apparently have to tell users how to modify their settings manually. My current plan for addressing that is two-fold:

  1. I want to create the status screen, so users can more easily troubleshoot what is wrong (we didn't get any locations, the background sync was never called,....)
  2. I have been purchasing problematic phones so that I can directly see what is happening with the data collection and whether it is possible to introduce workarounds. So far, the Samsung Edge results have not been promising. As far as I can tell, if we allow Samsung to "sleep" the app, Samsung turns off location to the app after ~ 30 mins (https://github.com/e-mission/e-mission-docs/issues/535#issuecomment-848390001). No location => e-mission fundamentally can't work. I don't see how any amount of tweaking can overcome that, although I am all ears for any out-of-the-box solution.
  3. I will be creating a device-specific, e-mission-specific set of instructions based on (2) and any reports from the community, similar to dontkillmyapp. It will be very hard to maintain these instructions without community support. As you might imagine, I cannot purchase phones of every possible android make and model. For example, Xiaomi phones are not widely available in the US, and I am not allowed to purchase Huawei phones with NREL funds (https://www.theverge.com/2020/6/30/21308477/fcc-huawei-zte-ban-universal-service-fund-national-security-threat-risk).

Unfortunately, unless the android OEMs remove their custom hacks, or support programmatic access to them, that is the best that I can think of doing.

PatGendre commented 3 years ago

@shankari thanks for your clear post, which I will forward to my partners in la Rochelle and Lyon, we can certainly provide you with device specific issues we encounter in the coming months.
Currently the usual users just see that "the app doesn't work" and provide initially little useful info, so only "special users" like Romain are aware that the problems may be due to the Phone model not the app, but the support team will insist on this kind of issues during the onboarding from now on.

shankari commented 3 years ago

@PatGendre I really hope that the status screen will help with "app doesn't work" issues by empowering users to understand more clearly why it doesn't work. I've wanted to build it for a long time, but keep getting sidetracked with papers/proposals/other higher priority features.

For example, an upcoming feature is to allow users to designate custom polygons and have all trips within the polygon have the same label. This is critical for the eBike pilot because several users work in huge warehouses and are walking around for work all day. Having users label ~ 20 trips a day is too much.