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

Commit 29e092bf authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Notify all packages is uid-mode is changed

Multiple packages might share a UID, but appOpsService might not have
cached the uid->package mapping for those yet. Hence the only way to
list all packages for a uid is to ask package manager.

setUidMode already handled this correctly, hence factor out the code
into notifyOpChangedForAllPkgsInUid and reuse it from
commitUidStatePendingLocked.

Bug: 148180766
Test: (on master) atest CtsAppOpsTestCases:android.app.appops.cts.ForegroundModeTest
Change-Id: I99a8f255a60d3523da7eb36a8f2c9426af1a1fea
Merged-In: I2d5d6c7aa38d201707349a137c9c29b7987775be
parent c866e0c5
Loading
Loading
Loading
Loading
+38 −16
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE_LOCATION;
import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED;
import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
import static android.app.AppOpsManager.UID_STATE_TOP;
import static android.app.AppOpsManager.WATCH_FOREGROUND_CHANGES;
import static android.app.AppOpsManager.modeToName;
import static android.app.AppOpsManager.opToName;
import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState;
@@ -1288,6 +1289,18 @@ public class AppOpsService extends IAppOpsService.Stub {
            uidState.evalForegroundOps(mOpModeWatchers);
        }

        notifyOpChangedForAllPkgsInUid(code, uid, false);
        notifyOpChangedSync(code, uid, null, mode);
    }

    /**
     * Notify that an op changed for all packages in an uid.
     *
     * @param code The op that changed
     * @param uid The uid the op was changed for
     * @param onlyForeground Only notify watchers that watch for foreground changes
     */
    private void notifyOpChangedForAllPkgsInUid(int code, int uid, boolean onlyForeground) {
        String[] uidPackageNames = getPackagesForUid(uid);
        ArrayMap<ModeCallback, ArraySet<String>> callbackSpecs = null;

@@ -1297,6 +1310,10 @@ public class AppOpsService extends IAppOpsService.Stub {
                final int callbackCount = callbacks.size();
                for (int i = 0; i < callbackCount; i++) {
                    ModeCallback callback = callbacks.valueAt(i);
                    if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) {
                        continue;
                    }

                    ArraySet<String> changedPackages = new ArraySet<>();
                    Collections.addAll(changedPackages, uidPackageNames);
                    if (callbackSpecs == null) {
@@ -1315,6 +1332,10 @@ public class AppOpsService extends IAppOpsService.Stub {
                    final int callbackCount = callbacks.size();
                    for (int i = 0; i < callbackCount; i++) {
                        ModeCallback callback = callbacks.valueAt(i);
                        if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) {
                            continue;
                        }

                        ArraySet<String> changedPackages = callbackSpecs.get(callback);
                        if (changedPackages == null) {
                            changedPackages = new ArraySet<>();
@@ -1327,7 +1348,6 @@ public class AppOpsService extends IAppOpsService.Stub {
        }

        if (callbackSpecs == null) {
            notifyOpChangedSync(code, uid, null, mode);
            return;
        }

@@ -1349,8 +1369,6 @@ public class AppOpsService extends IAppOpsService.Stub {
                }
            }
        }

        notifyOpChangedSync(code, uid, null, mode);
    }

    private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) {
@@ -2496,6 +2514,14 @@ public class AppOpsService extends IAppOpsService.Stub {
                if (resolvedLastFg == resolvedNowFg) {
                    continue;
                }

                if (uidState.opModes != null
                        && uidState.opModes.indexOfKey(code) >= 0
                        && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND) {
                    mHandler.sendMessage(PooledLambda.obtainMessage(
                            AppOpsService::notifyOpChangedForAllPkgsInUid,
                            this, code, uidState.uid, true));
                } else {
                    final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code);
                    if (callbacks != null) {
                        for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) {
@@ -2504,16 +2530,12 @@ public class AppOpsService extends IAppOpsService.Stub {
                                    || !callback.isWatchingUid(uidState.uid)) {
                                continue;
                            }
                        boolean doAllPackages = uidState.opModes != null
                                && uidState.opModes.indexOfKey(code) >= 0
                                && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND;
                        if (uidState.pkgOps != null) {
                            for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) {
                                final Op op = uidState.pkgOps.valueAt(pkgi).get(code);
                                if (op == null) {
                                    continue;
                                }
                                if (doAllPackages || op.mode == AppOpsManager.MODE_FOREGROUND) {
                                if (op.mode == AppOpsManager.MODE_FOREGROUND) {
                                    mHandler.sendMessage(PooledLambda.obtainMessage(
                                            AppOpsService::notifyOpChanged,
                                            this, callback, code, uidState.uid,