Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6aab623a authored by Christopher Tate's avatar Christopher Tate
Browse files

Top apps may start fg services even when under bg restriction

We now apply bg restriction policy (appop) on being able to enter a
foreground service lifecycle only when the app is not in a "top" i.e.
directly user-facing state.  This avoids breaking existing supported
lifecycle guarantees involving the order of calls to startService(),
startForeground(), and startForegroundService().  Briefly:  there is a
designed behavior in the following sequence:

  1. startService(intent);
  2. startForeground() on that service; then
  3. startForegroundService(intent)

The intentional behavior is that after step 3, the app is not required
to call startForeground() *again,* redundantly; because that service is
already in a fg lifecycle.

However, new-in-Q code broke this pattern in the case where the user had
imposed bg service restrictions on the app.  For this and for
semantic/model reasons, we now do not apply fg service start
restrictions to the user-facing app, even if the at app is under bg
execution restrictions.  The app is not background at that time, so
should not be expected to face a different execution environment.

Bug: 130048629
Test: Foreground use of GPM under bg restrictions
Change-Id: I0e8c308ac26211082a90c165a64d66b31ab804df
parent 5ad5cdc3
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -828,6 +828,13 @@ public final class ActiveServices {
                        sb.append(compName);
                        Slog.w(TAG, sb.toString());
                        stopping.add(service);

                        // If the app is under bg restrictions, also make sure that
                        // any notification is dismissed
                        if (appRestrictedAnyInBackground(
                                service.appInfo.uid, service.packageName)) {
                            cancelForegroundNotificationLocked(service);
                        }
                    }
                }
            }
@@ -1232,6 +1239,10 @@ public final class ActiveServices {
        }
    }

    private boolean appIsTopLocked(int uid) {
        return mAm.getUidState(uid) <= ActivityManager.PROCESS_STATE_TOP;
    }

    /**
     * @param id Notification ID.  Zero === exit foreground state for the given service.
     */
@@ -1318,8 +1329,11 @@ public final class ActiveServices {
                        throw new SecurityException("Foreground not allowed as per app op");
                }

                if (!ignoreForeground &&
                        appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
                // Apps that are TOP or effectively similar may call startForeground() on
                // their services even if they are restricted from doing that while in bg.
                if (!ignoreForeground
                        && !appIsTopLocked(r.appInfo.uid)
                        && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
                    Slog.w(TAG,
                            "Service.startForeground() not allowed due to bg restriction: service "
                            + r.shortInstanceName);