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

Commit 7d24318f authored by Chris Tate's avatar Chris Tate Committed by Android (Google) Code Review
Browse files

Merge "Implement demotion of an app's FGses"

parents f0009e41 7efefc63
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -517,6 +517,11 @@ public abstract class ActivityManagerInternal {
    public abstract void onForegroundServiceNotificationUpdate(boolean shown,
            Notification notification, int id, String pkg, @UserIdInt int userId);

    /**
     * Un-foreground all foreground services in the given app.
     */
    public abstract void makeServicesNonForeground(String pkg, @UserIdInt int userId);

    /**
     * If the given app has any FGSs whose notifications are in the given channel,
     * stop them.
+1 −0
Original line number Diff line number Diff line
@@ -278,6 +278,7 @@ interface IActivityManager {
    List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState();
    boolean clearApplicationUserData(in String packageName, boolean keepState,
            in IPackageDataObserver observer, int userId);
    void makeServicesNonForeground(in String packageName, int userId);
    @UnsupportedAppUsage
    void forceStopPackage(in String packageName, int userId);
    boolean killPids(in int[] pids, in String reason, boolean secure);
+23 −0
Original line number Diff line number Diff line
@@ -5110,6 +5110,29 @@ public final class ActiveServices {
        return didSomething;
    }

    void makeServicesNonForegroundLocked(final String pkg, final @UserIdInt int userId) {
        final ServiceMap smap = mServiceMap.get(userId);
        if (smap != null) {
            ArrayList<ServiceRecord> fgsList = new ArrayList<>();
            for (int i = 0; i < smap.mServicesByInstanceName.size(); i++) {
                final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i);
                if (sr.appInfo.packageName.equals(pkg) && sr.isForeground) {
                    fgsList.add(sr);
                }
            }

            final int numServices = fgsList.size();
            if (DEBUG_FOREGROUND_SERVICE) {
                Slog.i(TAG_SERVICE, "Forcing " + numServices + " services out of foreground in u"
                        + userId + "/" + pkg);
            }
            for (int i = 0; i < numServices; i++) {
                final ServiceRecord sr = fgsList.get(i);
                setServiceForegroundInnerLocked(sr, 0, null, Service.STOP_FOREGROUND_REMOVE, 0);
            }
        }
    }

    void forceStopPackageLocked(String packageName, int userId) {
        ServiceMap smap = mServiceMap.get(userId);
        if (smap != null && smap.mActiveForegroundApps.size() > 0) {
+35 −0
Original line number Diff line number Diff line
@@ -3750,6 +3750,29 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    @Override
    public void makeServicesNonForeground(final String packageName, int userId) {
        if (checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
                != PackageManager.PERMISSION_GRANTED) {
            String msg = "Permission Denial: makeServicesNonForeground() from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid()
                    + " requires " + android.Manifest.permission.MANAGE_ACTIVITY_TASKS;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
        final int callingPid = Binder.getCallingPid();
        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
                userId, true, ALLOW_FULL_ONLY, "makeServicesNonForeground", null);
        final long callingId = Binder.clearCallingIdentity();
        try {
            makeServicesNonForegroundUnchecked(packageName, userId);
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }
    @Override
    public void forceStopPackage(final String packageName, int userId) {
        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
@@ -4058,6 +4081,13 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    private void makeServicesNonForegroundUnchecked(final String packageName,
            final @UserIdInt int userId) {
        synchronized (this) {
            mServices.makeServicesNonForegroundLocked(packageName, userId);
        }
    }
    @GuardedBy("this")
    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
@@ -16398,6 +16428,11 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
        }
        @Override
        public void makeServicesNonForeground(String pkg, int userId) {
            ActivityManagerService.this.makeServicesNonForegroundUnchecked(pkg, userId);
        }
        @Override
        public void stopForegroundServicesForChannel(String pkg, int userId,
                String channelId) {
+18 −0
Original line number Diff line number Diff line
@@ -229,6 +229,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    return runBugReport(pw);
                case "force-stop":
                    return runForceStop(pw);
                case "stop-fgs":
                    return runStopForegroundServices(pw);
                case "fgs-notification-rate-limit":
                    return runFgsNotificationRateLimit(pw);
                case "crash":
@@ -1105,6 +1107,22 @@ final class ActivityManagerShellCommand extends ShellCommand {
        return 0;
    }

    int runStopForegroundServices(PrintWriter pw) throws RemoteException {
        int userId = UserHandle.USER_SYSTEM;

        String opt;
        while ((opt = getNextOption()) != null) {
            if (opt.equals("--user")) {
                userId = UserHandle.parseUserArg(getNextArgRequired());
            } else {
                getErrPrintWriter().println("Error: Unknown option: " + opt);
                return -1;
            }
        }
        mInterface.makeServicesNonForeground(getNextArgRequired(), userId);
        return 0;
    }

    int runFgsNotificationRateLimit(PrintWriter pw) throws RemoteException {
        final String toggleValue = getNextArgRequired();
        final boolean enable;