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

Commit 41407833 authored by Patrick Baumann's avatar Patrick Baumann
Browse files

Makes non-system app deletion fail-safe

This is the second in a series of app delete refactors that moves
detection of all failure cases outside of the actual delete action for
non-system apps (system apps still require a subsequent install of the
disabled app that can still fail).

Bug: 109941548
Test: install, uninstall still work
Change-Id: I8ee470fdb02f2ae9cea1da0f23f484242c47173b
parent 82b6b06f
Loading
Loading
Loading
Loading
+190 −124
Original line number Original line Diff line number Diff line
@@ -53,7 +53,6 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
@@ -15191,8 +15190,11 @@ public class PackageManagerService extends IPackageManager.Stub
        }
        }
    }
    }
    private static class ReconcileFailure extends PackageManagerException {
    private static class ReconcileFailure extends PackageManagerException {
        public ReconcileFailure(String message) {
        ReconcileFailure(String message) {
            super("Invalid reconcile request: " + message);
            super("Reconcile failed: " + message);
        }
        ReconcileFailure(int reason, String message) {
            super(reason, "Reconcile failed: " + message);
        }
        }
    }
    }
@@ -15211,10 +15213,12 @@ public class PackageManagerService extends IPackageManager.Stub
        @PackageManager.InstallFlags
        @PackageManager.InstallFlags
        public final int installFlags;
        public final int installFlags;
        public final InstallArgs installArgs;
        public final InstallArgs installArgs;
        public final DeletePackageAction deletePackageAction;
        private ReconciledPackage(InstallArgs installArgs, PackageSetting pkgSetting,
        private ReconciledPackage(InstallArgs installArgs, PackageSetting pkgSetting,
                UserHandle installForUser, PackageInstalledInfo installResult, int installFlags,
                UserHandle installForUser, PackageInstalledInfo installResult, int installFlags,
                String volumeUuid, PrepareResult prepareResult, ScanResult scanResult) {
                String volumeUuid, PrepareResult prepareResult, ScanResult scanResult,
                DeletePackageAction deletePackageAction) {
            this.installArgs = installArgs;
            this.installArgs = installArgs;
            this.pkgSetting = pkgSetting;
            this.pkgSetting = pkgSetting;
            this.installForUser = installForUser;
            this.installForUser = installForUser;
@@ -15223,6 +15227,7 @@ public class PackageManagerService extends IPackageManager.Stub
            this.volumeUuid = volumeUuid;
            this.volumeUuid = volumeUuid;
            this.prepareResult = prepareResult;
            this.prepareResult = prepareResult;
            this.scanResult = scanResult;
            this.scanResult = scanResult;
            this.deletePackageAction = deletePackageAction;
        }
        }
    }
    }
@@ -15235,14 +15240,29 @@ public class PackageManagerService extends IPackageManager.Stub
            final ScanResult scanResult = request.scannedPackages.get(installPackageName);
            final ScanResult scanResult = request.scannedPackages.get(installPackageName);
            final InstallArgs installArgs = request.installArgs.get(installPackageName);
            final InstallArgs installArgs = request.installArgs.get(installPackageName);
            final PackageInstalledInfo res = request.installResults.get(installPackageName);
            final PackageInstalledInfo res = request.installResults.get(installPackageName);
            final PrepareResult prepareResult = request.preparedPackages.get(installPackageName);
            if (scanResult == null || installArgs == null || res == null) {
            if (scanResult == null || installArgs == null || res == null) {
                throw new ReconcileFailure(
                throw new ReconcileFailure(
                        "inputs not balanced; missing argument for " + installPackageName);
                        "inputs not balanced; missing argument for " + installPackageName);
            }
            }
            final DeletePackageAction deletePackageAction;
            if (prepareResult.replace) {
                deletePackageAction = mayDeletePackageLocked(res.removedInfo,
                        prepareResult.originalPs, prepareResult.disabledPs,
                        prepareResult.childPackageSettings);
                if (deletePackageAction == null) {
                    throw new ReconcileFailure(
                            PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
                            "May not delete " + installPackageName + " to replace");
                }
            } else {
                deletePackageAction = null;
            }
            result.put(installPackageName,
            result.put(installPackageName,
                    new ReconciledPackage(installArgs, scanResult.pkgSetting, installArgs.getUser(),
                    new ReconciledPackage(installArgs, scanResult.pkgSetting, installArgs.getUser(),
                            res, installArgs.installFlags, installArgs.volumeUuid,
                            res, installArgs.installFlags, installArgs.volumeUuid,
                            request.preparedPackages.get(installPackageName), scanResult));
                            request.preparedPackages.get(installPackageName), scanResult,
                            deletePackageAction));
        }
        }
        return result;
        return result;
    }
    }
@@ -15314,14 +15334,15 @@ public class PackageManagerService extends IPackageManager.Stub
                    final boolean killApp = (scanRequest.scanFlags & SCAN_DONT_KILL_APP) == 0;
                    final boolean killApp = (scanRequest.scanFlags & SCAN_DONT_KILL_APP) == 0;
                    final int deleteFlags = PackageManager.DELETE_KEEP_DATA
                    final int deleteFlags = PackageManager.DELETE_KEEP_DATA
                            | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
                            | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
                    // First delete the existing package while retaining the data directory
                    try {
                    if (!deletePackageLIF(packageName, null, true, request.mAllUsers, deleteFlags,
                        executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
                            res.removedInfo, true, pkg)) {
                                null, true, request.mAllUsers, deleteFlags, true, pkg);
                        // If the existing package wasn't successfully deleted
                    } catch (SystemDeleteException e) {
                        res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
                        if (Build.IS_ENG) {
                                "replaceNonSystemPackageLI");
                            throw new RuntimeException("Unexpected failure", e);
                        return false;
                            // ignore; not possible for non-system app
                    } else {
                        }
                    }
                    // Successfully deleted the old package; proceed with replace.
                    // Successfully deleted the old package; proceed with replace.
                    // If deleted package lived in a container, give users a chance to
                    // If deleted package lived in a container, give users a chance to
@@ -15336,7 +15357,6 @@ public class PackageManagerService extends IPackageManager.Stub
                        pkgList.add(oldPackage.applicationInfo.packageName);
                        pkgList.add(oldPackage.applicationInfo.packageName);
                        sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
                        sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
                    }
                    }
                    }
                    // Update the in-memory copy of the previous code paths.
                    // Update the in-memory copy of the previous code paths.
                    PackageSetting ps1 = mSettings.mPackages.get(
                    PackageSetting ps1 = mSettings.mPackages.get(
@@ -15744,13 +15764,16 @@ public class PackageManagerService extends IPackageManager.Stub
        @Nullable
        @Nullable
        public final String renamedPackage;
        public final String renamedPackage;
        public final PackageFreezer freezer;
        public final PackageFreezer freezer;
        public final PackageSetting originalPs;
        public final PackageSetting disabledPs;
        public final PackageSetting[] childPackageSettings;
        private PrepareResult(int installReason, String volumeUuid,
        private PrepareResult(int installReason, String volumeUuid,
                String installerPackageName, UserHandle user, boolean replace, int scanFlags,
                String installerPackageName, UserHandle user, boolean replace, int scanFlags,
                int parseFlags, PackageParser.Package existingPackage,
                int parseFlags, PackageParser.Package existingPackage,
                PackageParser.Package packageToScan, boolean clearCodeCache, boolean system,
                PackageParser.Package packageToScan, boolean clearCodeCache, boolean system,
                String renamedPackage,
                String renamedPackage, PackageFreezer freezer, PackageSetting originalPs,
                PackageFreezer freezer) {
                PackageSetting disabledPs, PackageSetting[] childPackageSettings) {
            this.installReason = installReason;
            this.installReason = installReason;
            this.volumeUuid = volumeUuid;
            this.volumeUuid = volumeUuid;
            this.installerPackageName = installerPackageName;
            this.installerPackageName = installerPackageName;
@@ -15764,6 +15787,9 @@ public class PackageManagerService extends IPackageManager.Stub
            this.system = system;
            this.system = system;
            this.renamedPackage = renamedPackage;
            this.renamedPackage = renamedPackage;
            this.freezer = freezer;
            this.freezer = freezer;
            this.originalPs = originalPs;
            this.disabledPs = disabledPs;
            this.childPackageSettings = childPackageSettings;
        }
        }
    }
    }
@@ -16267,7 +16293,9 @@ public class PackageManagerService extends IPackageManager.Stub
            String targetVolumeUuid = volumeUuid;
            String targetVolumeUuid = volumeUuid;
            int targetScanFlags = scanFlags;
            int targetScanFlags = scanFlags;
            int targetParseFlags = parseFlags;
            int targetParseFlags = parseFlags;
            final PackageSetting ps;
            final PackageSetting disabledPs;
            final PackageSetting[] childPackages;
            if (replace) {
            if (replace) {
                targetVolumeUuid = null;
                targetVolumeUuid = null;
                if (pkg.applicationInfo.isStaticSharedLibrary()) {
                if (pkg.applicationInfo.isStaticSharedLibrary()) {
@@ -16287,7 +16315,6 @@ public class PackageManagerService extends IPackageManager.Stub
                final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
                final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
                final PackageParser.Package oldPackage;
                final PackageParser.Package oldPackage;
                final PackageSetting ps;
                final String pkgName11 = pkg.packageName;
                final String pkgName11 = pkg.packageName;
                final int[] allUsers;
                final int[] allUsers;
                final int[] installedUsers;
                final int[] installedUsers;
@@ -16314,6 +16341,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    }
                    }
                    ps = mSettings.mPackages.get(pkgName11);
                    ps = mSettings.mPackages.get(pkgName11);
                    disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
                    // verify signatures are valid
                    // verify signatures are valid
                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
@@ -16410,12 +16438,11 @@ public class PackageManagerService extends IPackageManager.Stub
                    res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
                    res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
                }
                }
                final int childCount = (oldPackage.childPackages != null)
                childPackages = mSettings.getChildSettingsLPr(ps);
                        ? oldPackage.childPackages.size() : 0;
                if (childPackages != null) {
                for (int i = 0; i < childCount; i++) {
                    for (PackageSetting childPs : childPackages) {
                        boolean childPackageUpdated = false;
                        boolean childPackageUpdated = false;
                    PackageParser.Package childPkg = oldPackage.childPackages.get(i);
                        PackageParser.Package childPkg = (childPs == null) ? null : childPs.pkg;
                    final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
                        if (res.addedChildPackages != null) {
                        if (res.addedChildPackages != null) {
                            PackageInstalledInfo childRes = res.addedChildPackages.get(
                            PackageInstalledInfo childRes = res.addedChildPackages.get(
                                    childPkg.packageName);
                                    childPkg.packageName);
@@ -16427,7 +16454,8 @@ public class PackageManagerService extends IPackageManager.Stub
                                            childPs.installerPackageName;
                                            childPs.installerPackageName;
                                }
                                }
                                childRes.removedInfo.isUpdate = true;
                                childRes.removedInfo.isUpdate = true;
                            childRes.removedInfo.installReasons = res.removedInfo.installReasons;
                                childRes.removedInfo.installReasons =
                                        res.removedInfo.installReasons;
                                childPackageUpdated = true;
                                childPackageUpdated = true;
                            }
                            }
                        }
                        }
@@ -16441,7 +16469,8 @@ public class PackageManagerService extends IPackageManager.Stub
                            childRemovedRes.dataRemoved = true;
                            childRemovedRes.dataRemoved = true;
                            synchronized (mPackages) {
                            synchronized (mPackages) {
                                if (childPs != null) {
                                if (childPs != null) {
                                childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers,
                                    childRemovedRes.origUsers = childPs.queryInstalledUsers(
                                            allUsers,
                                            true);
                                            true);
                                }
                                }
                            }
                            }
@@ -16452,6 +16481,8 @@ public class PackageManagerService extends IPackageManager.Stub
                                    childRemovedRes);
                                    childRemovedRes);
                        }
                        }
                    }
                    }
                }
                sysPkg = (isSystemApp(oldPackage));
                sysPkg = (isSystemApp(oldPackage));
                if (sysPkg) {
                if (sysPkg) {
@@ -16495,6 +16526,9 @@ public class PackageManagerService extends IPackageManager.Stub
                }
                }
            } else { // new package install
            } else { // new package install
                ps = null;
                childPackages = null;
                disabledPs = null;
                replace = false;
                replace = false;
                existingPackage = null;
                existingPackage = null;
                // Remember this for later, in case we need to rollback this install
                // Remember this for later, in case we need to rollback this install
@@ -16525,9 +16559,11 @@ public class PackageManagerService extends IPackageManager.Stub
            }
            }
            // we're passing the freezer back to be closed in a later phase of install
            // we're passing the freezer back to be closed in a later phase of install
            shouldCloseFreezerBeforeReturn = false;
            shouldCloseFreezerBeforeReturn = false;
            return new PrepareResult(args.installReason, targetVolumeUuid, installerPackageName,
            return new PrepareResult(args.installReason, targetVolumeUuid, installerPackageName,
                    args.user, replace, targetScanFlags, targetParseFlags, existingPackage, pkg,
                    args.user, replace, targetScanFlags, targetParseFlags, existingPackage, pkg,
                    replace /* clearCodeCache */, sysPkg, renamedPackage, freezer);
                    replace /* clearCodeCache */, sysPkg, renamedPackage, freezer,
                    ps, disabledPs, childPackages);
        } finally {
        } finally {
            if (shouldCloseFreezerBeforeReturn) {
            if (shouldCloseFreezerBeforeReturn) {
                freezer.close();
                freezer.close();
@@ -17477,34 +17513,20 @@ public class PackageManagerService extends IPackageManager.Stub
    /*
    /*
     * Tries to delete system package.
     * Tries to delete system package.
     */
     */
    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
    private void deleteSystemPackageLIF(DeletePackageAction action,
            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
            PackageParser.Package deletedPkg, PackageSetting deletedPs, int[] allUserHandles,
            boolean writeSettings) {
            int flags, PackageRemovedInfo outInfo, boolean writeSettings)
        if (deletedPs.parentPackageName != null) {
            throws SystemDeleteException {
            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
            return false;
        }
        final boolean applyUserRestrictions
        final boolean applyUserRestrictions
                = (allUserHandles != null) && (outInfo.origUsers != null);
                = (allUserHandles != null) && (outInfo.origUsers != null);
        final PackageSetting disabledPs;
        // Confirm if the system package has been updated
        // Confirm if the system package has been updated
        // An updated system app can be deleted. This will also have to restore
        // An updated system app can be deleted. This will also have to restore
        // the system pkg from system partition
        // the system pkg from system partition
        // reader
        // reader
        synchronized (mPackages) {
        final PackageSetting disabledPs = action.disabledPs;
            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
        }
        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
                + " disabledPs=" + disabledPs);
                + " disabledPs=" + disabledPs);
        if (disabledPs == null) {
            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
            return false;
        } else if (DEBUG_REMOVE) {
        Slog.d(TAG, "Deleting system pkg from data partition");
        Slog.d(TAG, "Deleting system pkg from data partition");
        }
        if (DEBUG_REMOVE) {
        if (DEBUG_REMOVE) {
            if (applyUserRestrictions) {
            if (applyUserRestrictions) {
@@ -17542,11 +17564,8 @@ public class PackageManagerService extends IPackageManager.Stub
            flags |= PackageManager.DELETE_KEEP_DATA;
            flags |= PackageManager.DELETE_KEEP_DATA;
        }
        }
        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
        deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
                outInfo, writeSettings, disabledPs.pkg);
                outInfo, writeSettings, disabledPs.pkg);
        if (!ret) {
            return false;
        }
        // writer
        // writer
        synchronized (mPackages) {
        synchronized (mPackages) {
@@ -17563,25 +17582,25 @@ public class PackageManagerService extends IPackageManager.Stub
        // Install the system package
        // Install the system package
        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
        try {
        try {
            installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
            installPackageFromSystemLIF(disabledPs.codePathString, allUserHandles,
                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
        } catch (PackageManagerException e) {
        } catch (PackageManagerException e) {
            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
                    + e.getMessage());
                    + e.getMessage());
            return false;
            // TODO(patb): can we avoid this; throw would come from scan...
            throw new SystemDeleteException(e);
        } finally {
        } finally {
            if (disabledPs.pkg.isStub) {
            if (disabledPs.pkg.isStub) {
                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
            }
            }
        }
        }
        return true;
    }
    }
    /**
    /**
     * Installs a package that's already on the system partition.
     * Installs a package that's already on the system partition.
     */
     */
    private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
    private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
            @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
            @Nullable PermissionsState origPermissionState, boolean writeSettings)
            @Nullable PermissionsState origPermissionState, boolean writeSettings)
                    throws PackageManagerException {
                    throws PackageManagerException {
        @ParseFlags int parseFlags =
        @ParseFlags int parseFlags =
@@ -17589,7 +17608,7 @@ public class PackageManagerService extends IPackageManager.Stub
                | PackageParser.PARSE_MUST_BE_APK
                | PackageParser.PARSE_MUST_BE_APK
                | PackageParser.PARSE_IS_SYSTEM_DIR;
                | PackageParser.PARSE_IS_SYSTEM_DIR;
        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
        if (isPrivileged || locationIsPrivileged(codePathString)) {
        if (locationIsPrivileged(codePathString)) {
            scanFlags |= SCAN_AS_PRIVILEGED;
            scanFlags |= SCAN_AS_PRIVILEGED;
        }
        }
        if (locationIsOem(codePathString)) {
        if (locationIsOem(codePathString)) {
@@ -17665,7 +17684,7 @@ public class PackageManagerService extends IPackageManager.Stub
        return pkg;
        return pkg;
    }
    }
    private boolean deleteInstalledPackageLIF(PackageSetting ps,
    private void deleteInstalledPackageLIF(PackageSetting ps,
            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
            PackageRemovedInfo outInfo, boolean writeSettings,
            PackageRemovedInfo outInfo, boolean writeSettings,
            PackageParser.Package replacingPackage) {
            PackageParser.Package replacingPackage) {
@@ -17680,9 +17699,6 @@ public class PackageManagerService extends IPackageManager.Stub
                for (int i = 0; i < childCount; i++) {
                for (int i = 0; i < childCount; i++) {
                    String childPackageName = ps.childPackageNames.get(i);
                    String childPackageName = ps.childPackageNames.get(i);
                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
                    if (childPs == null) {
                        return false;
                    }
                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
                            childPackageName);
                            childPackageName);
                    if (childInfo != null) {
                    if (childInfo != null) {
@@ -17723,8 +17739,6 @@ public class PackageManagerService extends IPackageManager.Stub
                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
            }
            }
        }
        }
        return true;
    }
    }
    @Override
    @Override
@@ -17780,26 +17794,59 @@ public class PackageManagerService extends IPackageManager.Stub
    private static class DeletePackageAction {
    private static class DeletePackageAction {
        public final PackageSetting deletingPs;
        public final PackageSetting deletingPs;
        public final PackageSetting disabledPs;
        public final PackageRemovedInfo outInfo;
        private DeletePackageAction(PackageSetting deletingPs) {
        private DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs,
                PackageRemovedInfo outInfo) {
            this.deletingPs = deletingPs;
            this.deletingPs = deletingPs;
            this.disabledPs = disabledPs;
            this.outInfo = outInfo;
        }
        }
    }
    }
    /**
    /**
     * @return a {@link DeletePackageAction} if the provided package may be deleted, {@code null}
     * @return a {@link DeletePackageAction} if the provided package and related state may be
     * otherwise.
     * deleted, {@code null} otherwise.
     */
     */
    @Nullable
    @Nullable
    private DeletePackageAction mayDeletePackageLIF(@NonNull String packageName) {
    @GuardedBy("mPackages")
        synchronized (mPackages) {
    private static DeletePackageAction mayDeletePackageLocked(
            final PackageSetting ps;
            PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs,
            ps = mSettings.mPackages.get(packageName);
            @Nullable PackageSetting[] children) {
        if (ps == null) {
        if (ps == null) {
            return null;
            return null;
        }
        }
            return new DeletePackageAction(ps);
        if (isSystemApp(ps)) {
            if (ps.parentPackageName == null) {
                Slog.w(TAG, "Attempt to delete child system package " + ps.pkg.packageName);
                return null;
            }
            // Confirm if the system package has been updated
            // An updated system app can be deleted. This will also have to restore
            // the system pkg from system partition
            // reader
            if (disabledPs == null) {
                Slog.w(TAG,
                        "Attempt to delete unknown system package " + ps.pkg.packageName);
                return null;
            }
        }
        final int parentReferenceCount =
                (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
        final int childCount = children != null ? children.length : 0;
        if (childCount != parentReferenceCount) {
            return null;
        }
        if (childCount != 0 && outInfo != null && outInfo.removedChildPackages != null) {
            for (PackageSetting child : children) {
                if (child == null || !ps.childPackageNames.contains(child.name)) {
                    return null;
                }
            }
        }
        }
        return new DeletePackageAction(ps, disabledPs, outInfo);
    }
    }
    /*
    /*
@@ -17809,22 +17856,43 @@ public class PackageManagerService extends IPackageManager.Stub
            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
            PackageRemovedInfo outInfo, boolean writeSettings,
            PackageRemovedInfo outInfo, boolean writeSettings,
            PackageParser.Package replacingPackage) {
            PackageParser.Package replacingPackage) {
        final DeletePackageAction action = mayDeletePackageLIF(packageName);
        final DeletePackageAction action;
        synchronized (mPackages) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
            PackageSetting[] children = mSettings.getChildSettingsLPr(ps);
            action = mayDeletePackageLocked(outInfo, ps, disabledPs, children);
        }
        if (null == action) {
        if (null == action) {
            return false;
            return false;
        }
        }
        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
        return executeDeletePackageLIF(action, packageName, user, deleteCodeAndResources,
        try {
                allUserHandles, flags, outInfo, writeSettings, replacingPackage);
            executeDeletePackageLIF(action, packageName, user, deleteCodeAndResources,
                    allUserHandles, flags, writeSettings, replacingPackage);
        } catch (SystemDeleteException e) {
            return false;
        }
        return true;
    }
    }
    private boolean executeDeletePackageLIF(DeletePackageAction action,
    private static class SystemDeleteException extends Exception {
        public final PackageManagerException reason;
        private SystemDeleteException(PackageManagerException reason) {
            this.reason = reason;
        }
    }
    /** Deletes a package. Only throws when install of a disabled package fails. */
    private void executeDeletePackageLIF(DeletePackageAction action,
            String packageName, UserHandle user, boolean deleteCodeAndResources,
            String packageName, UserHandle user, boolean deleteCodeAndResources,
            int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
            int[] allUserHandles, int flags, boolean writeSettings,
            boolean writeSettings, PackageParser.Package replacingPackage) {
            PackageParser.Package replacingPackage) throws SystemDeleteException {
        final PackageSetting ps = action.deletingPs;
        final PackageSetting ps = action.deletingPs;
        final PackageRemovedInfo outInfo = action.outInfo;
        final boolean systemApp = isSystemApp(ps);
        final boolean systemApp = isSystemApp(ps);
        synchronized (mPackages) {
        synchronized (mPackages) {
@@ -17840,7 +17908,7 @@ public class PackageManagerService extends IPackageManager.Stub
                clearPackageStateForUserLIF(ps, removedUserId, outInfo);
                clearPackageStateForUserLIF(ps, removedUserId, outInfo);
                markPackageUninstalledForUserLPw(ps, user);
                markPackageUninstalledForUserLPw(ps, user);
                scheduleWritePackageRestrictionsLocked(user);
                scheduleWritePackageRestrictionsLocked(user);
                return true;
                return;
            }
            }
        }
        }
@@ -17869,7 +17937,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
                    clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo);
                    clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo);
                    scheduleWritePackageRestrictionsLocked(user);
                    scheduleWritePackageRestrictionsLocked(user);
                    return true;
                    return;
                } else {
                } else {
                    // We need to set it back to 'installed' so the uninstall
                    // We need to set it back to 'installed' so the uninstall
                    // broadcasts will be sent correctly.
                    // broadcasts will be sent correctly.
@@ -17885,7 +17953,7 @@ public class PackageManagerService extends IPackageManager.Stub
                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
                clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo);
                clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo);
                scheduleWritePackageRestrictionsLocked(user);
                scheduleWritePackageRestrictionsLocked(user);
                return true;
                return;
            }
            }
        }
        }
@@ -17910,15 +17978,15 @@ public class PackageManagerService extends IPackageManager.Stub
        }
        }
        // TODO(b/109941548): break reasons for ret = false out into mayDelete method
        // TODO(b/109941548): break reasons for ret = false out into mayDelete method
        final boolean ret;
        if (systemApp) {
        if (systemApp) {
            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
            // When an updated system application is deleted we delete the existing resources
            // When an updated system application is deleted we delete the existing resources
            // as well and fall back to existing code in system partition
            // as well and fall back to existing code in system partition
            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
            deleteSystemPackageLIF(
                    action, ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
        } else {
        } else {
            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
            deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
                    outInfo, writeSettings, replacingPackage);
                    outInfo, writeSettings, replacingPackage);
        }
        }
@@ -17967,8 +18035,6 @@ public class PackageManagerService extends IPackageManager.Stub
                }
                }
            }
            }
        }
        }
        return ret;
    }
    }
    @GuardedBy("mPackages")
    @GuardedBy("mPackages")
@@ -19694,7 +19760,7 @@ public class PackageManagerService extends IPackageManager.Stub
                                enableSystemPackageLPw(deletedPkg);
                                enableSystemPackageLPw(deletedPkg);
                            }
                            }
                            installPackageFromSystemLIF(deletedPkg.codePath,
                            installPackageFromSystemLIF(deletedPkg.codePath,
                                    false /*isPrivileged*/, null /*allUserHandles*/,
                                    /*isPrivileged*/ null /*allUserHandles*/,
                                    null /*origUserHandles*/, null /*origPermissionsState*/,
                                    null /*origUserHandles*/, null /*origPermissionsState*/,
                                    true /*writeSettings*/);
                                    true /*writeSettings*/);
                        } catch (PackageManagerException pme) {
                        } catch (PackageManagerException pme) {
+37 −0

File changed.

Preview size limit exceeded, changes collapsed.