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

Commit 649a8574 authored by Patrick Baumann's avatar Patrick Baumann
Browse files

Moves appID registration outside of scan commit

This refactoring moves us closer to an error-free call to commit
by allowing app ID to be acquired (and returned on failure) outside
of the actual commit call.

Bug: 109941548
Test: install still works
Change-Id: I6bbd50b9ce8aaf665abd6dd89172b667a1c9ee44
parent 30968d9d
Loading
Loading
Loading
Loading
+53 −19
Original line number Diff line number Diff line
@@ -5407,7 +5407,7 @@ public class PackageManagerService extends IPackageManager.Stub
        synchronized (mPackages) {
            Signature[] s1;
            Signature[] s2;
            Object obj = mSettings.getUserIdLPr(uid1);
            Object obj = mSettings.getSettingLPr(uid1);
            if (obj != null) {
                if (obj instanceof SharedUserSetting) {
                    if (isCallerInstantApp) {
@@ -5426,7 +5426,7 @@ public class PackageManagerService extends IPackageManager.Stub
            } else {
                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
            }
            obj = mSettings.getUserIdLPr(uid2);
            obj = mSettings.getSettingLPr(uid2);
            if (obj != null) {
                if (obj instanceof SharedUserSetting) {
                    if (isCallerInstantApp) {
@@ -5485,7 +5485,7 @@ public class PackageManagerService extends IPackageManager.Stub
        // reader
        synchronized (mPackages) {
            final PackageParser.SigningDetails signingDetails;
            final Object obj = mSettings.getUserIdLPr(uid);
            final Object obj = mSettings.getSettingLPr(uid);
            if (obj != null) {
                if (obj instanceof SharedUserSetting) {
                    final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
@@ -5598,7 +5598,7 @@ public class PackageManagerService extends IPackageManager.Stub
        uid = UserHandle.getAppId(uid);
        // reader
        synchronized (mPackages) {
            Object obj = mSettings.getUserIdLPr(uid);
            Object obj = mSettings.getSettingLPr(uid);
            if (obj instanceof SharedUserSetting) {
                if (isCallerInstantApp) {
                    return null;
@@ -5634,7 +5634,7 @@ public class PackageManagerService extends IPackageManager.Stub
            return null;
        }
        synchronized (mPackages) {
            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
            Object obj = mSettings.getSettingLPr(UserHandle.getAppId(uid));
            if (obj instanceof SharedUserSetting) {
                final SharedUserSetting sus = (SharedUserSetting) obj;
                return sus.name + ":" + sus.userId;
@@ -5662,7 +5662,7 @@ public class PackageManagerService extends IPackageManager.Stub
        synchronized (mPackages) {
            for (int i = uids.length - 1; i >= 0; i--) {
                final int uid = uids[i];
                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
                Object obj = mSettings.getSettingLPr(UserHandle.getAppId(uid));
                if (obj instanceof SharedUserSetting) {
                    final SharedUserSetting sus = (SharedUserSetting) obj;
                    names[i] = "shared:" + sus.name;
@@ -5711,7 +5711,7 @@ public class PackageManagerService extends IPackageManager.Stub
            return 0;
        }
        synchronized (mPackages) {
            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
            Object obj = mSettings.getSettingLPr(UserHandle.getAppId(uid));
            if (obj instanceof SharedUserSetting) {
                final SharedUserSetting sus = (SharedUserSetting) obj;
                return sus.pkgFlags;
@@ -5733,7 +5733,7 @@ public class PackageManagerService extends IPackageManager.Stub
            return 0;
        }
        synchronized (mPackages) {
            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
            Object obj = mSettings.getSettingLPr(UserHandle.getAppId(uid));
            if (obj instanceof SharedUserSetting) {
                final SharedUserSetting sus = (SharedUserSetting) obj;
                return sus.pkgPrivateFlags;
@@ -5756,7 +5756,7 @@ public class PackageManagerService extends IPackageManager.Stub
        uid = UserHandle.getAppId(uid);
        // reader
        synchronized (mPackages) {
            Object obj = mSettings.getUserIdLPr(uid);
            Object obj = mSettings.getSettingLPr(uid);
            if (obj instanceof SharedUserSetting) {
                final SharedUserSetting sus = (SharedUserSetting) obj;
                final Iterator<PackageSetting> it = sus.packages.iterator();
@@ -6396,7 +6396,7 @@ public class PackageManagerService extends IPackageManager.Stub
                callingUid = mIsolatedOwners.get(callingUid);
            }
            final int appId = UserHandle.getAppId(callingUid);
            final Object obj = mSettings.getUserIdLPr(appId);
            final Object obj = mSettings.getSettingLPr(appId);
            if (obj instanceof PackageSetting) {
                final PackageSetting ps = (PackageSetting) obj;
                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
@@ -8726,7 +8726,13 @@ public class PackageManagerService extends IPackageManager.Stub
                | SCAN_UPDATE_SIGNATURE, currentTime, user);
        if (scanResult.success) {
            synchronized (mPackages) {
                try {
                    prepareScanResultLocked(scanResult);
                    commitScanResultLocked(scanResult);
                } catch (PackageManagerException e) {
                    unprepareScanResultLocked(scanResult);
                    throw e;
                }
            }
        }
@@ -10125,7 +10131,37 @@ public class PackageManagerService extends IPackageManager.Stub
                }
            }
            for (ScanResult result : results) {
                try {
                    prepareScanResultLocked(result);
                    commitScanResultLocked(result);
                } catch (PackageManagerException e) {
                    unprepareScanResultLocked(result);
                    throw e;
                }
            }
        }
    }
    /** Prepares the system to commit a {@link ScanResult} in a way that will not fail. */
    private void prepareScanResultLocked(@NonNull ScanResult result)
            throws PackageManagerException {
        if (!result.existingSettingCopied) {
            // THROWS: when we can't allocate a user id. add call to check if there's
            // enough space to ensure we won't throw; otherwise, don't modify state
            mSettings.registerAppIdLPw(result.pkgSetting);
        }
    }
    /**
     * Reverts any changes to the system that were made by
     * {@link #prepareScanResultLocked(ScanResult)}
     */
    private void unprepareScanResultLocked(@NonNull ScanResult result) {
        if (!result.existingSettingCopied) {
            // iff we've acquired an app ID for a new package setting, remove it so that it can be
            // acquired by another request.
            if (result.pkgSetting.appId > 0) {
                mSettings.removeAppIdLPw(result.pkgSetting.appId);
            }
        }
    }
@@ -10164,10 +10200,6 @@ public class PackageManagerService extends IPackageManager.Stub
            if (originalPkgSetting != null) {
                mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
            }
            // THROWS: when we can't allocate a user id. add call to check if there's
            // enough space to ensure we won't throw; otherwise, don't modify state
            mSettings.addUserToSettingLPw(pkgSetting);
            if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
                mTransferedPackages.add(originalPkgSetting.name);
            }
@@ -13496,7 +13528,7 @@ public class PackageManagerService extends IPackageManager.Stub
            }
            Signature[] callerSignature;
            Object obj = mSettings.getUserIdLPr(callingUid);
            Object obj = mSettings.getSettingLPr(callingUid);
            if (obj != null) {
                if (obj instanceof SharedUserSetting) {
                    callerSignature =
@@ -15414,8 +15446,10 @@ public class PackageManagerService extends IPackageManager.Stub
            try {
                prepareScanResultLocked(scanResult);
                commitScanResultLocked(scanResult);
            } catch (PackageManagerException e) {
                unprepareScanResultLocked(scanResult);
                res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
                res.setError("Package couldn't be installed in " + pkg.codePath, e);
                return false;
@@ -18477,7 +18511,7 @@ public class PackageManagerService extends IPackageManager.Stub
    @GuardedBy("mPackages")
    private int getUidTargetSdkVersionLockedLPr(int uid) {
        Object obj = mSettings.getUserIdLPr(uid);
        Object obj = mSettings.getSettingLPr(uid);
        if (obj instanceof SharedUserSetting) {
            final SharedUserSetting sus = (SharedUserSetting) obj;
            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
@@ -22588,7 +22622,7 @@ public class PackageManagerService extends IPackageManager.Stub
        private SigningDetails getSigningDetails(int uid) {
            synchronized (mPackages) {
                final int appId = UserHandle.getAppId(uid);
                final Object obj = mSettings.getUserIdLPr(appId);
                final Object obj = mSettings.getSettingLPr(appId);
                if (obj != null) {
                    if (obj instanceof SharedUserSetting) {
                        return ((SharedUserSetting) obj).signatures.mSigningDetails;
+62 −60
Original line number Diff line number Diff line
@@ -381,11 +381,9 @@ public final class Settings {
    final SparseArray<CrossProfileIntentResolver> mCrossProfileIntentResolvers =
            new SparseArray<CrossProfileIntentResolver>();

    final ArrayMap<String, SharedUserSetting> mSharedUsers =
            new ArrayMap<String, SharedUserSetting>();
    private final ArrayList<Object> mUserIds = new ArrayList<Object>();
    private final SparseArray<Object> mOtherUserIds =
            new SparseArray<Object>();
    final ArrayMap<String, SharedUserSetting> mSharedUsers = new ArrayMap<>();
    private final ArrayList<SettingBase> mAppIds = new ArrayList<>();
    private final SparseArray<SettingBase> mOtherAppIds = new SparseArray<>();

    // For reading/writing settings file.
    private final ArrayList<Signature> mPastSignatures =
@@ -519,7 +517,7 @@ public final class Settings {
        SharedUserSetting s = mSharedUsers.get(name);
        if (s == null && create) {
            s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
            s.userId = newUserIdLPw(s);
            s.userId = acquireAndRegisterNewAppIdLPw(s);
            if (s.userId < 0) {
                // < 0 means we couldn't assign a userid; throw exception
                throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
@@ -612,7 +610,7 @@ public final class Settings {
                cpuAbiOverrideString, vc, pkgFlags, pkgPrivateFlags, parentPackageName,
                childPackageNames, 0 /*userId*/, usesStaticLibraries, usesStaticLibraryNames);
        p.appId = uid;
        if (addUserIdLPw(uid, p, name)) {
        if (registerExistingAppIdLPw(uid, p, name)) {
            mPackages.put(name, p);
            return p;
        }
@@ -635,7 +633,7 @@ public final class Settings {
        }
        s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
        s.userId = uid;
        if (addUserIdLPw(uid, s, name)) {
        if (registerExistingAppIdLPw(uid, s, name)) {
            mSharedUsers.put(name, s);
            return s;
        }
@@ -885,13 +883,13 @@ public final class Settings {
     * Registers a user ID with the system. Potentially allocates a new user ID.
     * @throws PackageManagerException If a user ID could not be allocated.
     */
    void addUserToSettingLPw(PackageSetting p) throws PackageManagerException {
    void registerAppIdLPw(PackageSetting p) throws PackageManagerException {
        if (p.appId == 0) {
            // Assign new user ID
            p.appId = newUserIdLPw(p);
            p.appId = acquireAndRegisterNewAppIdLPw(p);
        } else {
            // Add new setting to list of user IDs
            addUserIdLPw(p.appId, p, p.name);
            registerExistingAppIdLPw(p.appId, p, p.name);
        }
        if (p.appId < 0) {
            PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -972,14 +970,14 @@ public final class Settings {

        // If the we know about this user id, we have to update it as it
        // has to point to the same PackageSetting instance as the package.
        Object userIdPs = getUserIdLPr(p.appId);
        Object userIdPs = getSettingLPr(p.appId);
        if (sharedUser == null) {
            if (userIdPs != null && userIdPs != p) {
                replaceUserIdLPw(p.appId, p);
                replaceAppIdLPw(p.appId, p);
            }
        } else {
            if (userIdPs != null && userIdPs != sharedUser) {
                replaceUserIdLPw(p.appId, sharedUser);
                replaceAppIdLPw(p.appId, sharedUser);
            }
        }

@@ -1083,11 +1081,11 @@ public final class Settings {
                p.sharedUser.removePackage(p);
                if (p.sharedUser.packages.size() == 0) {
                    mSharedUsers.remove(p.sharedUser.name);
                    removeUserIdLPw(p.sharedUser.userId);
                    removeAppIdLPw(p.sharedUser.userId);
                    return p.sharedUser.userId;
                }
            } else {
                removeUserIdLPw(p.appId);
                removeAppIdLPw(p.appId);
                return p.appId;
            }
        }
@@ -1115,65 +1113,69 @@ public final class Settings {
        mInstallerPackages.remove(packageName);
    }

    private boolean addUserIdLPw(int uid, Object obj, Object name) {
        if (uid > Process.LAST_APPLICATION_UID) {
    /** Returns true if the requested AppID was valid and not already registered. */
    private boolean registerExistingAppIdLPw(int appId, SettingBase obj, Object name) {
        if (appId > Process.LAST_APPLICATION_UID) {
            return false;
        }

        if (uid >= Process.FIRST_APPLICATION_UID) {
            int N = mUserIds.size();
            final int index = uid - Process.FIRST_APPLICATION_UID;
            while (index >= N) {
                mUserIds.add(null);
                N++;
        if (appId >= Process.FIRST_APPLICATION_UID) {
            int size = mAppIds.size();
            final int index = appId - Process.FIRST_APPLICATION_UID;
            // fill the array until our index becomes valid
            while (index >= size) {
                mAppIds.add(null);
                size++;
            }
            if (mUserIds.get(index) != null) {
            if (mAppIds.get(index) != null) {
                PackageManagerService.reportSettingsProblem(Log.ERROR,
                        "Adding duplicate user id: " + uid
                        "Adding duplicate app id: " + appId
                        + " name=" + name);
                return false;
            }
            mUserIds.set(index, obj);
            mAppIds.set(index, obj);
        } else {
            if (mOtherUserIds.get(uid) != null) {
            if (mOtherAppIds.get(appId) != null) {
                PackageManagerService.reportSettingsProblem(Log.ERROR,
                        "Adding duplicate shared id: " + uid
                        "Adding duplicate shared id: " + appId
                                + " name=" + name);
                return false;
            }
            mOtherUserIds.put(uid, obj);
            mOtherAppIds.put(appId, obj);
        }
        return true;
    }

    public Object getUserIdLPr(int uid) {
        if (uid >= Process.FIRST_APPLICATION_UID) {
            final int N = mUserIds.size();
            final int index = uid - Process.FIRST_APPLICATION_UID;
            return index < N ? mUserIds.get(index) : null;
    /** Gets the setting associated with the provided App ID */
    public SettingBase getSettingLPr(int appId) {
        if (appId >= Process.FIRST_APPLICATION_UID) {
            final int size = mAppIds.size();
            final int index = appId - Process.FIRST_APPLICATION_UID;
            return index < size ? mAppIds.get(index) : null;
        } else {
            return mOtherUserIds.get(uid);
            return mOtherAppIds.get(appId);
        }
    }

    private void removeUserIdLPw(int uid) {
        if (uid >= Process.FIRST_APPLICATION_UID) {
            final int N = mUserIds.size();
            final int index = uid - Process.FIRST_APPLICATION_UID;
            if (index < N) mUserIds.set(index, null);
    /** Unregisters the provided app ID. */
    void removeAppIdLPw(int appId) {
        if (appId >= Process.FIRST_APPLICATION_UID) {
            final int size = mAppIds.size();
            final int index = appId - Process.FIRST_APPLICATION_UID;
            if (index < size) mAppIds.set(index, null);
        } else {
            mOtherUserIds.remove(uid);
            mOtherAppIds.remove(appId);
        }
        setFirstAvailableUid(uid+1);
        setFirstAvailableUid(appId + 1);
    }

    private void replaceUserIdLPw(int uid, Object obj) {
        if (uid >= Process.FIRST_APPLICATION_UID) {
            final int N = mUserIds.size();
            final int index = uid - Process.FIRST_APPLICATION_UID;
            if (index < N) mUserIds.set(index, obj);
    private void replaceAppIdLPw(int appId, SettingBase obj) {
        if (appId >= Process.FIRST_APPLICATION_UID) {
            final int size = mAppIds.size();
            final int index = appId - Process.FIRST_APPLICATION_UID;
            if (index < size) mAppIds.set(index, obj);
        } else {
            mOtherUserIds.put(uid, obj);
            mOtherAppIds.put(appId, obj);
        }
    }

@@ -3157,7 +3159,7 @@ public final class Settings {
        for (int i = 0; i < N; i++) {
            final PackageSetting p = mPendingPackages.get(i);
            final int sharedUserId = p.getSharedUserId();
            final Object idObj = getUserIdLPr(sharedUserId);
            final Object idObj = getSettingLPr(sharedUserId);
            if (idObj instanceof SharedUserSetting) {
                final SharedUserSetting sharedUser = (SharedUserSetting) idObj;
                p.sharedUser = sharedUser;
@@ -3202,7 +3204,7 @@ public final class Settings {
        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
        while (disabledIt.hasNext()) {
            final PackageSetting disabledPs = disabledIt.next();
            final Object id = getUserIdLPr(disabledPs.appId);
            final Object id = getSettingLPr(disabledPs.appId);
            if (id != null && id instanceof SharedUserSetting) {
                disabledPs.sharedUser = (SharedUserSetting) id;
            }
@@ -4206,24 +4208,24 @@ public final class Settings {
        }
    }

    // Returns -1 if we could not find an available UserId to assign
    private int newUserIdLPw(Object obj) {
    /** Returns a new AppID or -1 if we could not find an available AppID to assign */
    private int acquireAndRegisterNewAppIdLPw(SettingBase obj) {
        // Let's be stupidly inefficient for now...
        final int N = mUserIds.size();
        for (int i = mFirstAvailableUid; i < N; i++) {
            if (mUserIds.get(i) == null) {
                mUserIds.set(i, obj);
        final int size = mAppIds.size();
        for (int i = mFirstAvailableUid; i < size; i++) {
            if (mAppIds.get(i) == null) {
                mAppIds.set(i, obj);
                return Process.FIRST_APPLICATION_UID + i;
            }
        }

        // None left?
        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
        if (size > (Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID)) {
            return -1;
        }

        mUserIds.add(obj);
        return Process.FIRST_APPLICATION_UID + N;
        mAppIds.add(obj);
        return Process.FIRST_APPLICATION_UID + size;
    }

    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {