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

Commit abf224e8 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fixes incorrect app id cleanup on failure" into qt-dev

parents 9b2b4f55 b22e916a
Loading
Loading
Loading
Loading
+28 −18
Original line number Diff line number Diff line
@@ -9334,6 +9334,7 @@ public class PackageManagerService extends IPackageManager.Stub
                | SCAN_UPDATE_SIGNATURE, currentTime, user);
        if (scanResult.success) {
            synchronized (mPackages) {
                boolean appIdCreated = false;
                try {
                    final String pkgName = scanResult.pkgSetting.name;
                    final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked(
@@ -9346,11 +9347,12 @@ public class PackageManagerService extends IPackageManager.Stub
                                    Collections.singletonMap(pkgName,
                                            getSharedLibLatestVersionSetting(scanResult))),
                            mSettings.mKeySetManagerService);
                    prepareScanResultLocked(scanResult);
                    commitReconciledScanResultLocked(
                            reconcileResult.get(pkgName));
                    appIdCreated = optimisticallyRegisterAppId(scanResult);
                    commitReconciledScanResultLocked(reconcileResult.get(pkgName));
                } catch (PackageManagerException e) {
                    unprepareScanResultLocked(scanResult);
                    if (appIdCreated) {
                        cleanUpAppIdCreation(scanResult);
                    }
                    throw e;
                }
            }
@@ -10837,29 +10839,34 @@ public class PackageManagerService extends IPackageManager.Stub
    }
    /** Prepares the system to commit a {@link ScanResult} in a way that will not fail. */
    private void prepareScanResultLocked(@NonNull ScanResult result)
    /**
     * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering
     * the app ID required for reconcile.
     * @return {@code true} if a new app ID was registered and will need to be cleaned up on
     *         failure.
     */
    private boolean optimisticallyRegisterAppId(@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);
            return mSettings.registerAppIdLPw(result.pkgSetting);
        }
        return false;
    }
    /**
     * Reverts any changes to the system that were made by
     * {@link #prepareScanResultLocked(ScanResult)}
     * Reverts any app ID creation that were made by
     * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the
     * referenced method returned true.
     */
    private void unprepareScanResultLocked(@NonNull ScanResult result) {
        if (!result.existingSettingCopied) {
    private void cleanUpAppIdCreation(@NonNull ScanResult result) {
        // 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);
        }
    }
    }
    /**
     * Commits the package scan and modifies system state.
@@ -16701,6 +16708,7 @@ public class PackageManagerService extends IPackageManager.Stub
        final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size());
        final Map<String, PackageSetting> lastStaticSharedLibSettings =
                new ArrayMap<>(requests.size());
        final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
        boolean success = false;
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
@@ -16740,7 +16748,7 @@ public class PackageManagerService extends IPackageManager.Stub
                                            + " in multi-package install request.");
                            return;
                        }
                        prepareScanResultLocked(result);
                        createdAppId.put(packageName, optimisticallyRegisterAppId(result));
                        versionInfos.put(result.pkgSetting.pkg.packageName,
                                getSettingsVersionForPackage(result.pkgSetting.pkg));
                        if (result.staticSharedLibraryInfo != null) {
@@ -16797,7 +16805,9 @@ public class PackageManagerService extends IPackageManager.Stub
        } finally {
            if (!success) {
                for (ScanResult result : preparedScans.values()) {
                    unprepareScanResultLocked(result);
                    if (createdAppId.getOrDefault(result.request.pkg.packageName, false)) {
                        cleanUpAppIdCreation(result);
                    }
                }
            }
            for (PrepareResult result : prepareResults.values()) {
+8 −2
Original line number Diff line number Diff line
@@ -810,15 +810,20 @@ public final class Settings {

    /**
     * Registers a user ID with the system. Potentially allocates a new user ID.
     * @return {@code true} if a new app ID was created in the process. {@code false} can be
     *         returned in the case that a shared user ID already exists or the explicit app ID is
     *         already registered.
     * @throws PackageManagerException If a user ID could not be allocated.
     */
    void registerAppIdLPw(PackageSetting p) throws PackageManagerException {
    boolean registerAppIdLPw(PackageSetting p) throws PackageManagerException {
        final boolean createdNew;
        if (p.appId == 0) {
            // Assign new user ID
            p.appId = acquireAndRegisterNewAppIdLPw(p);
            createdNew = true;
        } else {
            // Add new setting to list of user IDs
            registerExistingAppIdLPw(p.appId, p, p.name);
            createdNew = registerExistingAppIdLPw(p.appId, p, p.name);
        }
        if (p.appId < 0) {
            PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -826,6 +831,7 @@ public final class Settings {
            throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
                    "Package " + p.name + " could not be assigned a valid UID");
        }
        return createdNew;
    }

    /**