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

Commit 0a3524a1 authored by Patrick Baumann's avatar Patrick Baumann Committed by android-build-merger
Browse files

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

am: abf224e8

Change-Id: If0f5922696b2030642209efa777ad4582445ff90
parents 61886126 abf224e8
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;
    }

    /**