Closed Bug 1407046 Opened 8 years ago Closed 7 years ago

Abide by Android Oreo background execution limits

Categories

(Firefox for Android Graveyard :: General, enhancement, P3)

All
Android
enhancement

Tracking

(firefox63 fixed)

RESOLVED FIXED
Firefox 63
Tracking Status
firefox63 --- fixed

People

(Reporter: mcomella, Assigned: petru)

References

Details

(Whiteboard: --do_not_change--[priority:high])

Attachments

(13 files, 6 obsolete files)

59 bytes, text/x-review-board-request
JanH
: review+
Details
59 bytes, text/x-review-board-request
JanH
: review+
Details
59 bytes, text/x-review-board-request
jchen
: review+
Details
59 bytes, text/x-review-board-request
JanH
: review+
Details
59 bytes, text/x-review-board-request
JanH
: review+
Details
59 bytes, text/x-review-board-request
jchen
: review+
Details
59 bytes, text/x-review-board-request
Details
59 bytes, text/x-review-board-request
Details
59 bytes, text/x-review-board-request
Details
59 bytes, text/x-review-board-request
Details
59 bytes, text/x-review-board-request
Details
59 bytes, text/x-review-board-request
Details
59 bytes, text/x-review-board-request
Details
Oreo introduced new execution background limits [1]. Roughly, if your app targets O, your app can run only run background services when it’s active, for several minutes after being backgrounded, or for several minutes after receiving an important push/broadcast/event (e.g. Firebase cloud message). You can still run foreground services without limitations and JobScheduler will still intelligently schedule your jobs so you can use that to replace previous background service work. Caveat: while its enforced when your app targets O, users on Android O can enable the restrictions on any app if they choose too. Wrappers: - JobIntentService was introduced to run IntentServices on JobScheduler where available, or IntentService otherwise - Evernote’s Android-job library [2] wraps JobScheduler and pre-JobScheduler implementations and directs to the appropriate one as necessary --- We should look at our background services (e.g. go through the manifest) to identify which will need to change to adapt to the new format. Right now, it looks like we have at least 11 classes that extend `IntentService` [3]. Consider changing this bug to a meta to change the code incrementally. [1]: https://developer.android.com/about/versions/oreo/background.html [2]: https://github.com/evernote/android-job [3]: http://searchfox.org/mozilla-central/search?q=path%3Amobile%2Fandroid+extends+intentservice&path=
NI Grisha as an FYI for Sync services; no action needed.
Flags: needinfo?(gkruglov)
[triage] Blocked on targeting Android O.
Priority: -- → P3
See Also: → 1384866
Whiteboard: --do_not_change--[priority:high]
Depends on: 1385464
JobIntentService was added in 26.1.0 so we first need the Android support library used to be at at least that same version.
Depends on: 1384866
See Also: 1384866
Assignee: nobody → petru.lingurar
I wanted to migrate FxAccountDeletedService and FxAccountProfileService which are now IntentServices to JobIntentService, but I see thay both are in /mobile/android/services/... and the ReadMe of this module says "These files are managed in the android-sync repo. Do not modify directly, or your changes will be lost." [1] How should I proceed?
Another big issue is with Stumbler. I understand it was supposed to always run in the background, collect data and upload it. It was supposed to even start at boot, irrespective of app's state. This will not be possible anymore unless it will be a foreground service (with a notification visible to the user). I also heard about talks to remove it. NI'ing Susheel to help choosing between this two options.
Flags: needinfo?(sdaswani)
Andreas, do you still use the Stumbler data for anything? I think we have to shut it off if we want to support Oreo.
Flags: needinfo?(sdaswani) → needinfo?(abovens)
Recent thread on mozilla.dev.geolocation "Status of Mozilla Stumbler?" - https://groups.google.com/forum/#!topic/mozilla.dev.geolocation/lx09zGU8dKM Dropping some NI to people who own(ish) the data. See comment 7 & 8
Flags: needinfo?(vng)
Flags: needinfo?(chris.lonnen)
Attachment #8983763 - Flags: review?(sdaswani) → review?(jh+bugzilla)
Attachment #8983768 - Flags: review?(sdaswani) → review?(jh+bugzilla)
Attachment #8983766 - Flags: review?(sdaswani) → review?(jh+bugzilla)
Attachment #8983764 - Flags: review?(sdaswani) → review?(jh+bugzilla)
Attachment #8983769 - Flags: review?(sdaswani) → review?(jh+bugzilla)
Attachment #8983767 - Flags: review?(sdaswani) → review?(jh+bugzilla)
Attachment #8983765 - Flags: review?(sdaswani) → review?(jh+bugzilla)
Blocks: 1467461
Comment on attachment 8983765 [details] Bug 1407046 - Migrate FxAccountProfileService to JobIntentService; https://reviewboard.mozilla.org/r/249596/#review256656
Attachment #8983765 - Flags: review?(jh+bugzilla) → review+
Comment on attachment 8983766 [details] Bug 1407046 - Migrate FxAccountDeletedService to JobIntentService; https://reviewboard.mozilla.org/r/249598/#review256672 ::: mobile/android/services/src/main/java/org/mozilla/gecko/fxa/receivers/FxAccountDeletedService.java:52 (Diff revision 2) > - public FxAccountDeletedService() { > - super(LOG_TAG); > + public static void enqueueWork(@NonNull final Context context, @NonNull final Intent workIntent) { > + enqueueWork(context, FxAccountDeletedService.class, JobIdsConstants.JOB_ID_PROFILE_DELETE, workIntent); > } > > @Override > - protected void onHandleIntent(final Intent intent) { > + protected void onHandleWork(Intent intent) { Recent framework code now explicitly have the Intent in the IntentService's `onHandleIntent(@Nullable final Intent intent)` as `@Nullable`, whereas for the JobIntentService on the other hand the Intent is declared to be `@NonNull`. I've also tried looking at the source for the JobIntentService (e.g. [here](http://androidxref.com/8.0.0_r4/xref/frameworks/support/compat/java/android/support/v4/app/JobIntentService.java#365)) and by my reading it, unlike presumably the IntentService implementation does, it doesn't leave delivery of the Intent to the system, where apparently under some circumstances it can get lost. Instead, it keeps its own list of work items and when it runs, the Intent is retrieved from that work item and then directly passed to `onHandleWork`. So in summary I think you can preserve the original function signature and mark this `@NonNull` as well.
Attachment #8983766 - Flags: review?(jh+bugzilla)
Comment on attachment 8983767 [details] Bug 1407046 - Migrate TelemetryUploadService to JobIntentService; https://reviewboard.mozilla.org/r/249600/#review256688 Whether and how to abort all queued uploads if we encountered a failure needs some more thinking about (see below), but on the other hand for the presumably most common case (no network connection available) we already return early beforehand without aborting other queued work, so I guess we can just land this and think about that problem when there's some more spare time. ::: mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryUploadService.java:89 (Diff revision 2) > if (!wereAllUploadsSuccessful) { > // If we had an upload failure, we should stop the IntentService and drop any > // pending Intents in the queue so we don't waste resources (e.g. battery) > // trying to upload when there's likely to be another connection failure. > Log.d(LOGTAG, "Clearing Intent queue due to connection failures"); > stopSelf(); I have a suspicion that this trick might not longer work on Android O and above, where we're running as a `JobService`, which, given the entry for `onBind` in the documentation ("Returns the IBinder for the JobServiceEngine when running as a JobService on O and later platforms.") might run as a bound service, where calling stopSelf() won't have any effect. Plus I think in that `JobService` mode the list of Jobs still to be executed might no longer even be held by ther service itself, so even if we could destroy it that wouldn't help in that regard. Unfortunately I've got no idea how necessary this is , i.e. how hard we should try finding an alternative design for Android O and above... At the very least, leave a follow-up bug for this.
Attachment #8983767 - Flags: review?(jh+bugzilla) → review+
Comment on attachment 8983768 [details] Bug 1407046 - Migrate FileCleanupService to JobIntentService; https://reviewboard.mozilla.org/r/249602/#review256696
Attachment #8983768 - Flags: review?(jh+bugzilla) → review+
Comment on attachment 8983764 [details] Bug 1407046 - Migrate TabReceivedService to JobIntentService; https://reviewboard.mozilla.org/r/249594/#review256700 ::: mobile/android/base/java/org/mozilla/gecko/tabqueue/TabReceivedService.java:89 (Diff revision 2) > prefs.edit().putInt(PREF_NOTIFICATION_ID, notificationId).apply(); > } > > + @Override > + public boolean onStopCurrentWork() { > + // Reschedule the work it it has been stopped before completing (shouldn't) Nit: "Reschedule the work it it has [...]" -> if it
Attachment #8983764 - Flags: review?(jh+bugzilla) → review+
:kbrosnan We can't easily remove the Stumbler from Firefox as MLS is still an ongoing concern at this point. The majority of our data collection is because of the passive stumbler in Firefox Android. We're trying to schedule some meetings to figure out what to do about Stumbler and MLS during the allhands coming up in SF.
Flags: needinfo?(vng)
Flags: needinfo?(chris.lonnen)
No longer depends on: 1384866
See Also: → 1384866
(In reply to Jan Henning [:JanH] from comment #30) > (In reply to Petru-Mugurel Lingurar[:petru] from comment #7) > > Another big issue is with Stumbler. > > I understand it was supposed to always run in the background, collect data > > and upload it. It was supposed to even start at boot, irrespective of app's > > state. > > This will not be possible anymore unless it will be a foreground service > > (with a notification visible to the user). > > > > I also heard about talks to remove it. > > > > NI'ing Susheel to help choosing between this two options. > > There also a third option - only start the service when Firefox is in > foreground, at least when running on Oreo or higher... Forget what I said there - background services will be stopped by the OS some time after the app goes into the background.
Just noticed that this is actually only required "if your app targets O", so needs to block that bug as well.
Comment on attachment 8983763 [details] Bug 1407046 - Migrate DownloadContentService to JobIntentService; https://reviewboard.mozilla.org/r/249592/#review256864 The DLC changes themselves look absolutely fine, but JobIdsConstants.java needs some more work because of our shared UID problem, hence the r-. ::: mobile/android/services/src/main/java/org/mozilla/gecko/background/JobIdsConstants.java:5 (Diff revision 2) > +package org.mozilla.gecko.background; > + > +/** > + * Repository for all the IDs used to differentiate between different Android Jobs.<br> > + * They should be unique across both the app’s own code and the code from any library that the app uses.<br> Hmm, the documentation says that > This ID must be unique across all clients of the same uid (not just the same package). and unfortunately Firefox and Firefox Beta *do* use a shared UID (see bug 1437871), as did org.mozilla.fennec and org.mozilla.fennec_aurora, although the latter case is less relevant since the "fennec" builds have now been discontinued. So I fear that this could lead to unintended behaviour for users who have installed both Release and Beta, since one app could unintentionally mess up the other app's jobs. So maybe we should add (or subtract, since you're using negative IDs) a constant coming out of our build config, so we can specify differing offsets for Release and Beta. Ping nalexander if you need any help there.
Attachment #8983763 - Flags: review?(jh+bugzilla) → review-
Comment on attachment 8983763 [details] Bug 1407046 - Migrate DownloadContentService to JobIntentService; https://reviewboard.mozilla.org/r/249592/#review256864 > Hmm, the documentation says that > > This ID must be unique across all clients of the same uid (not just the same package). > > and unfortunately Firefox and Firefox Beta *do* use a shared UID (see bug 1437871), as did org.mozilla.fennec and org.mozilla.fennec_aurora, although the latter case is less relevant since the "fennec" builds have now been discontinued. > > So I fear that this could lead to unintended behaviour for users who have installed both Release and Beta, since one app could unintentionally mess up the other app's jobs. > > So maybe we should add (or subtract, since you're using negative IDs) a constant coming out of our build config, so we can specify differing offsets for Release and Beta. Ping nalexander if you need any help there. Thanks! Didn't know about this shared UID issue. Will be using an offset set in `JobIdsConstants` to provide an offsetted id for Beta.
Comment on attachment 8983767 [details] Bug 1407046 - Migrate TelemetryUploadService to JobIntentService; https://reviewboard.mozilla.org/r/249600/#review256688 > I have a suspicion that this trick might not longer work on Android O and above, where we're running as a `JobService`, which, given the entry for `onBind` in the documentation ("Returns the IBinder for the JobServiceEngine when running as a JobService on O and later platforms.") might run as a bound service, where calling stopSelf() won't have any effect. > > Plus I think in that `JobService` mode the list of Jobs still to be executed might no longer even be held by ther service itself, so even if we could destroy it that wouldn't help in that regard. > > Unfortunately I've got no idea how necessary this is , i.e. how hard we should try finding an alternative design for Android O and above... > > At the very least, leave a follow-up bug for this. Thanks for looking into this. How I viewed this situation: When running on pre Oreo the JobIntentService will be a normal IntentService so that stopSelf() should still work as before. When running on >= Oreo the JobServiceEngine will indeed bind to the JobIntentService (that's why the bind permission is needed in manifest). Even if stopSelf() wouldn't have any effect here it is the last code executing in the `onHandleWork()` block. But I don't know if after this the service will be unbinded and destroyed. Created bug 1468284 to investigate.
Updated the patches to support different Job Ids for Release / Beta builds.
Status: NEW → ASSIGNED
Attachment #8983763 - Flags: review?(jh+bugzilla) → review?(nchen)
Attachment #8983763 - Flags: review?(nchen) → review?(s.kaspari)
Comment on attachment 8983766 [details] Bug 1407046 - Migrate FxAccountDeletedService to JobIntentService; https://reviewboard.mozilla.org/r/249598/#review258502
Attachment #8983766 - Flags: review+
Comment on attachment 8983769 [details] Bug 1407046 - Migrate UpdateService to JobIntentService; https://reviewboard.mozilla.org/r/249604/#review258504 We don't actually use the updater service anymore. I think it's okay if we don't make this change. (We should remove the service eventually)
(In reply to Jim Chen [:jchen] [:darchons] from comment #45) > Comment on attachment 8983769 [details] > Bug 1407046 - Migrate UpdateService to JobIntentService; > > https://reviewboard.mozilla.org/r/249604/#review258504 > > We don't actually use the updater service anymore. Don't we? It's still working in practice, is AFAIK the only update mechanism for single-locale builds (which aren't on Google Play, are they?), plus it also provides updates for anybody else who can't or doesn't want to use the Play Store?
Hm you're right. We do still use the updater service for these edge cases.
Comment on attachment 8983769 [details] Bug 1407046 - Migrate UpdateService to JobIntentService; https://reviewboard.mozilla.org/r/249604/#review258750 Looks okay, assuming it's been thoroughly tested ::: mobile/android/base/java/org/mozilla/gecko/updater/PackageVerifier.java:14 (Diff revision 3) > +import java.io.FileInputStream; > +import java.io.InputStream; > +import java.security.MessageDigest; > + > +public class PackageVerifier { > + private static final String LOGTAG = "PackageVerifier"; "GeckoPackageVerifier" ::: mobile/android/base/java/org/mozilla/gecko/updater/UpdateServiceReceiver.java:14 (Diff revision 3) > + * Receiver only used in local notifications posted by an {@link UpdaterService} after which it finishes.<br> > + * Used to start another variant of {@link UpdaterService}. > + */ > +public class UpdateServiceReceiver extends BroadcastReceiver { > + private static final String LOGTAG = "UpdateServiceReceiver"; > + Add "Gecko" prefix to `LOGTAG` here and elsewhere. ::: mobile/android/base/java/org/mozilla/gecko/updater/UpdateServiceReceiver.java:22 (Diff revision 3) > + > + @Override > + public void onReceive(Context context, Intent intent) { > + final String action = intent.getAction(); > + > + Log.d(LOGTAG, String.format("Will enqueue \"%s\" work", action)); Put logging inside `if (DEBUG) { ... }` here and elsewhere. ::: mobile/android/base/java/org/mozilla/gecko/updater/UpdaterService.java:16 (Diff revision 3) > + protected Updater updater; > + protected UpdatesPrefs prefs; > + > + @Override > + public void onCreate() { > + crashHandler = CrashHandler.createDefaultCrashHandler(getApplicationContext()); We will end up creating multiple crash handlers for the different services. We should only create one
Attachment #8983769 - Flags: review+
Comment on attachment 8983763 [details] Bug 1407046 - Migrate DownloadContentService to JobIntentService; https://reviewboard.mozilla.org/r/249592/#review259194 ::: mobile/android/services/src/main/java/org/mozilla/gecko/background/JobIdsConstants.java:20 (Diff revision 3) > + * @see <a href="https://developer.android.com/reference/android/app/job/JobInfo.Builder#JobInfo.Builder(int, android.content.ComponentName)"> > + * JobId importance</a> > + */ > +public class JobIdsConstants { > + // Offset to differentiate the ids for Release/Beta versions of the app > + private static final int BETA_OFFSET = -1000; I think we are going to need different offsets for Nightly <-> Beta <-> Release?
Attachment #8983763 - Flags: review?(s.kaspari) → review-
- moved `JobIdsConstants()` to "mobile/android/base/java/org/mozilla/gecko" and started the Ids from 1000 as Jim suggested in bug 1467461 comment 24 - added a second offset for Nightly - implemented the changes Jim suggested - rebased the patches
Comment on attachment 8983763 [details] Bug 1407046 - Migrate DownloadContentService to JobIntentService; https://reviewboard.mozilla.org/r/249592/#review259194 > I think we are going to need different offsets for Nightly <-> Beta <-> Release? Nightly doesn't share an UID with our other APKs, so it doesn't actually need a separate offset, does it?
(In reply to Jan Henning (on vacation in June) [:JanH] from comment #58) > Comment on attachment 8983763 [details] > Bug 1407046 - Migrate DownloadContentService to JobIntentService; > > https://reviewboard.mozilla.org/r/249592/#review259194 > > > I think we are going to need different offsets for Nightly <-> Beta <-> Release? > > Nightly doesn't share an UID with our other APKs, so it doesn't actually > need a separate offset, does it? Ah, that's right. I assumed we would set sharedUserId to the same value on all our builds. But they Nightly seems to use a different value AND is signed with a different key too. Sorry!
Attachment #8983763 - Flags: review?(s.kaspari)
- removed the nightly offset - added missing MPL licenses
Attachment #8983763 - Flags: review?(sdaswani) → review?(snorp)
Comment on attachment 8983763 [details] Bug 1407046 - Migrate DownloadContentService to JobIntentService; https://reviewboard.mozilla.org/r/249592/#review260032
Attachment #8983763 - Flags: review?(snorp) → review+
Keywords: checkin-needed
Flags: needinfo?(abovens)
Attachment #8983764 - Attachment is obsolete: true
Attachment #8983765 - Attachment is obsolete: true
Attachment #8983766 - Attachment is obsolete: true
Attachment #8983767 - Attachment is obsolete: true
Attachment #8983768 - Attachment is obsolete: true
Attachment #8983769 - Attachment is obsolete: true
Attachment #8983763 - Attachment is obsolete: true
Attachment #8983763 - Flags: review?(sdaswani)
Attachment #8992018 - Attachment is obsolete: true
Attachment #8992018 - Flags: review?(jh+bugzilla)
Attachment #8992019 - Attachment is obsolete: true
Attachment #8992019 - Flags: review?(jh+bugzilla)
Attachment #8992020 - Attachment is obsolete: true
Attachment #8992020 - Flags: review?(nchen)
Attachment #8992022 - Attachment is obsolete: true
Attachment #8992022 - Flags: review?(jh+bugzilla)
Attachment #8992024 - Attachment is obsolete: true
Attachment #8992024 - Flags: review?(jh+bugzilla)
Attachment #8983764 - Attachment is obsolete: false
Attachment #8992025 - Attachment is obsolete: true
Attachment #8992025 - Flags: review?(nchen)
Attachment #8992268 - Attachment is obsolete: true
Attachment #8992268 - Flags: review?(sdaswani)
Attachment #8992269 - Attachment is obsolete: true
Attachment #8992269 - Flags: review?(jh+bugzilla)
Attachment #8992270 - Attachment is obsolete: true
Attachment #8992270 - Flags: review?(jh+bugzilla)
Attachment #8992271 - Attachment is obsolete: true
Attachment #8992271 - Flags: review?(nchen)
Attachment #8992272 - Attachment is obsolete: true
Attachment #8992272 - Flags: review?(jh+bugzilla)
Attachment #8992273 - Attachment is obsolete: true
Attachment #8992273 - Flags: review?(jh+bugzilla)
Attachment #8983765 - Attachment is obsolete: false
Attachment #8983766 - Attachment is obsolete: false
Attachment #8983767 - Attachment is obsolete: false
Attachment #8983768 - Attachment is obsolete: false
Attachment #8983769 - Attachment is obsolete: false
Attachment #8992268 - Flags: review?(sdaswani)
Attachment #8992269 - Flags: review?(jh+bugzilla)
Attachment #8992270 - Flags: review?(jh+bugzilla)
Attachment #8992271 - Flags: review?(nchen)
Attachment #8992272 - Flags: review?(jh+bugzilla)
Attachment #8992273 - Flags: review?(jh+bugzilla)
Attachment #8992025 - Flags: review?(nchen)
Pushed by cbrindusan@mozilla.com: https://hg.mozilla.org/integration/mozilla-inbound/rev/e224f2f4c44a Migrate DownloadContentService to JobIntentService. r=snorp https://hg.mozilla.org/integration/mozilla-inbound/rev/69fd84bee441 Migrate TabReceivedService to JobIntentService. r=JanH https://hg.mozilla.org/integration/mozilla-inbound/rev/162d4eb92cdb Migrate FxAccountProfileService to JobIntentService. r=JanH https://hg.mozilla.org/integration/mozilla-inbound/rev/b2b84b2e18b5 Migrate FxAccountDeletedService to JobIntentService. r=jchen https://hg.mozilla.org/integration/mozilla-inbound/rev/2c81eca09564 Migrate TelemetryUploadService to JobIntentService. r=JanH https://hg.mozilla.org/integration/mozilla-inbound/rev/16424a7c3866 Migrate FileCleanupService to JobIntentService. r=JanH https://hg.mozilla.org/integration/mozilla-inbound/rev/2c647187c1a2 Migrate UpdateService to JobIntentService. r=jchen
Pushed by archaeopteryx@coole-files.de: https://hg.mozilla.org/integration/mozilla-inbound/rev/ddd3a8daeb33 Migrate FileCleanupService to JobIntentService: Follow-up to for android-test. r=test-fix
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Depends on: 1474961, 1476237
Flags: needinfo?(petru.lingurar)
Will fix the tests failing in Bug 1476237
Status: REOPENED → RESOLVED
Closed: 7 years ago7 years ago
Resolution: --- → FIXED
Depends on: 1476681
Depends on: 1489634
Product: Firefox for Android → Firefox for Android Graveyard
Flags: needinfo?(gkruglov)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: