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

Commit ba33a165 authored by Evan Severson's avatar Evan Severson
Browse files

[AppOps] Make some corrections towards UidState initialization

We don't need to create UidStates for apex or create sandbox uids for
any uid less than application uid. We should also clean up uid states
that have been persisted but shouldn't exist.

Bug: 320850079
Test: Successful boot and improved performance with child CL observed
Change-Id: I641bb381eee8962f4432254029c93d505d327980
parent c8a73723
Loading
Loading
Loading
Loading
+40 −11
Original line number Diff line number Diff line
@@ -1034,7 +1034,7 @@ public class AppOpsService extends IAppOpsService.Stub {
                                new Ops(pkgName, uidState));
                    }

                    createSandboxUidStateIfNotExistsForAppLocked(uid);
                    createSandboxUidStateIfNotExistsForAppLocked(uid, null);
                }
            } else if (action.equals(ACTION_PACKAGE_REMOVED) && !intent.hasExtra(EXTRA_REPLACING)) {
                synchronized (AppOpsService.this) {
@@ -1253,19 +1253,33 @@ public class AppOpsService extends IAppOpsService.Stub {
    void initializeUidStates() {
        UserManagerInternal umi = getUserManagerInternal();
        synchronized (this) {
            SparseBooleanArray knownUids = new SparseBooleanArray();

            for (int uid : NON_PACKAGE_UIDS) {
                if (!mUidStates.contains(uid)) {
                    mUidStates.put(uid, new UidState(uid));
                }
                knownUids.put(uid, true);
            }

            int[] userIds = umi.getUserIds();
            try (PackageManagerLocal.UnfilteredSnapshot snapshot =
                         getPackageManagerLocal().withUnfilteredSnapshot()) {
                Map<String, PackageState> packageStates = snapshot.getPackageStates();
                for (int i = 0; i < userIds.length; i++) {
                    int userId = userIds[i];
                    initializeUserUidStatesLocked(userId, packageStates);
                    initializeUserUidStatesLocked(userId, packageStates, knownUids);
                }
            }

            for (int uid : NON_PACKAGE_UIDS) {
                mUidStates.put(uid, new UidState(uid));
            // Remove what may have been added during persistence parsing
            for (int i = mUidStates.size() - 1; i >= 0; i--) {
                int uid = mUidStates.keyAt(i);
                if (!knownUids.get(uid, false)) {
                    mUidStates.removeAt(i);
                }
            }

            mUidStatesInitialized = true;
        }
    }
@@ -1274,26 +1288,34 @@ public class AppOpsService extends IAppOpsService.Stub {
        synchronized (this) {
            try (PackageManagerLocal.UnfilteredSnapshot snapshot =
                    getPackageManagerLocal().withUnfilteredSnapshot()) {
                initializeUserUidStatesLocked(userId, snapshot.getPackageStates());
                initializeUserUidStatesLocked(userId, snapshot.getPackageStates(), null);
            }
        }
    }

    private void initializeUserUidStatesLocked(int userId, Map<String,
            PackageState> packageStates) {
            PackageState> packageStates, SparseBooleanArray knownUids) {
        for (Map.Entry<String, PackageState> entry : packageStates.entrySet()) {
            int appId = entry.getValue().getAppId();
            PackageState packageState = entry.getValue();
            if (packageState.isApex()) {
                continue;
            }
            int appId = packageState.getAppId();
            String packageName = entry.getKey();

            initializePackageUidStateLocked(userId, appId, packageName);
            initializePackageUidStateLocked(userId, appId, packageName, knownUids);
        }
    }

    /*
      Be careful not to clear any existing data; only want to add objects that don't already exist.
     */
    private void initializePackageUidStateLocked(int userId, int appId, String packageName) {
    private void initializePackageUidStateLocked(int userId, int appId, String packageName,
            SparseBooleanArray knownUids) {
        int uid = UserHandle.getUid(userId, appId);
        if (knownUids != null) {
            knownUids.put(uid, true);
        }
        UidState uidState = getUidStateLocked(uid, true);
        Ops ops = uidState.pkgOps.get(packageName);
        if (ops == null) {
@@ -1311,7 +1333,7 @@ public class AppOpsService extends IAppOpsService.Stub {
            }
        }

        createSandboxUidStateIfNotExistsForAppLocked(uid);
        createSandboxUidStateIfNotExistsForAppLocked(uid, knownUids);
    }

    /**
@@ -4246,8 +4268,15 @@ public class AppOpsService extends IAppOpsService.Stub {
        return uidState;
    }

    private void createSandboxUidStateIfNotExistsForAppLocked(int uid) {
    private void createSandboxUidStateIfNotExistsForAppLocked(int uid,
            SparseBooleanArray knownUids) {
        if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) {
            return;
        }
        final int sandboxUid = Process.toSdkSandboxUid(uid);
        if (knownUids != null) {
            knownUids.put(sandboxUid, true);
        }
        getUidStateLocked(sandboxUid, true);
    }