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

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

Fixes unupdated system app deletion

A recent refactor of delete resulted in an incorrect test for the
existence of a disabled setting for all system apps regardless of
the isUpdated state. This change ensures that we only execute this check
in the case that the caller has not requested delete of the system
version as well.

This change also removes a few redundant variables from
executeDeletePackageLIF and instead encapsulates them in the
DeletePackageAction.

Test: Delete of an unupdated app is successful.
Test: QR-based setup completes (b/120189588)
Change-Id: I6e789f1c04b82580b4b46178cc69dfd95b50b621
Fixes: 120189588
parent eb458627
Loading
Loading
Loading
Loading
+38 −22
Original line number Diff line number Diff line
@@ -15269,9 +15269,12 @@ public class PackageManagerService extends IPackageManager.Stub
            final DeletePackageAction deletePackageAction;
            // we only want to try to delete for non system apps
            if (prepareResult.replace && !prepareResult.system) {
                final boolean killApp = (scanResult.request.scanFlags & SCAN_DONT_KILL_APP) == 0;
                final int deleteFlags = PackageManager.DELETE_KEEP_DATA
                        | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
                deletePackageAction = mayDeletePackageLocked(res.removedInfo,
                        prepareResult.originalPs, prepareResult.disabledPs,
                        prepareResult.childPackageSettings);
                        prepareResult.childPackageSettings, deleteFlags, installArgs.user);
                if (deletePackageAction == null) {
                    throw new ReconcileFailure(
                            PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
@@ -15353,12 +15356,9 @@ public class PackageManagerService extends IPackageManager.Stub
                        }
                    }
                } else {
                    final boolean killApp = (scanRequest.scanFlags & SCAN_DONT_KILL_APP) == 0;
                    final int deleteFlags = PackageManager.DELETE_KEEP_DATA
                            | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
                    try {
                        executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
                                null, true, request.mAllUsers, deleteFlags, true, pkg);
                                true, request.mAllUsers, true, pkg);
                    } catch (SystemDeleteException e) {
                        if (Build.IS_ENG) {
                            throw new RuntimeException("Unexpected failure", e);
@@ -17818,12 +17818,23 @@ public class PackageManagerService extends IPackageManager.Stub
        public final PackageSetting deletingPs;
        public final PackageSetting disabledPs;
        public final PackageRemovedInfo outInfo;
        public final int flags;
        public final UserHandle user;
        /**
         * True if this package is an unupdated system app that may be deleted by the system.
         * When true, disabledPs will be null.
         */
        public final boolean mayDeleteUnupdatedSystemApp;
        private DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs,
                PackageRemovedInfo outInfo) {
                PackageRemovedInfo outInfo, int flags, UserHandle user,
                boolean mayDeleteUnupdatedSystemApp) {
            this.deletingPs = deletingPs;
            this.disabledPs = disabledPs;
            this.outInfo = outInfo;
            this.flags = flags;
            this.user = user;
            this.mayDeleteUnupdatedSystemApp = mayDeleteUnupdatedSystemApp;
        }
    }
@@ -17835,23 +17846,26 @@ public class PackageManagerService extends IPackageManager.Stub
    @GuardedBy("mPackages")
    private static DeletePackageAction mayDeletePackageLocked(
            PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs,
            @Nullable PackageSetting[] children) {
            @Nullable PackageSetting[] children, int flags, UserHandle user) {
        if (ps == null) {
            return null;
        }
        boolean mayDeleteUnupdatedSystemApp = false;
        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
            if (((flags & PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
                    && user.getIdentifier() != UserHandle.USER_ALL) {
                mayDeleteUnupdatedSystemApp = true;
            } else if (disabledPs == null) {
                // Confirmed 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);
                Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.packageName);
                return null;
            }
        }
@@ -17868,7 +17882,8 @@ public class PackageManagerService extends IPackageManager.Stub
                }
            }
        }
        return new DeletePackageAction(ps, disabledPs, outInfo);
        return new DeletePackageAction(ps, disabledPs, outInfo, flags, user,
                mayDeleteUnupdatedSystemApp);
    }
    /*
@@ -17883,7 +17898,7 @@ public class PackageManagerService extends IPackageManager.Stub
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
            PackageSetting[] children = mSettings.getChildSettingsLPr(ps);
            action = mayDeletePackageLocked(outInfo, ps, disabledPs, children);
            action = mayDeletePackageLocked(outInfo, ps, disabledPs, children, flags, user);
        }
        if (null == action) {
            return false;
@@ -17892,8 +17907,8 @@ public class PackageManagerService extends IPackageManager.Stub
        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
        try {
            executeDeletePackageLIF(action, packageName, user, deleteCodeAndResources,
                    allUserHandles, flags, writeSettings, replacingPackage);
            executeDeletePackageLIF(action, packageName, deleteCodeAndResources,
                    allUserHandles, writeSettings, replacingPackage);
        } catch (SystemDeleteException e) {
            return false;
        }
@@ -17910,11 +17925,13 @@ public class PackageManagerService extends IPackageManager.Stub
    /** Deletes a package. Only throws when install of a disabled package fails. */
    private void executeDeletePackageLIF(DeletePackageAction action,
            String packageName, UserHandle user, boolean deleteCodeAndResources,
            int[] allUserHandles, int flags, boolean writeSettings,
            String packageName, boolean deleteCodeAndResources,
            int[] allUserHandles, boolean writeSettings,
            PackageParser.Package replacingPackage) throws SystemDeleteException {
        final PackageSetting ps = action.deletingPs;
        final PackageRemovedInfo outInfo = action.outInfo;
        final UserHandle user = action.user;
        final int flags = action.flags;
        final boolean systemApp = isSystemApp(ps);
        synchronized (mPackages) {
@@ -17940,8 +17957,7 @@ public class PackageManagerService extends IPackageManager.Stub
        }
        if (((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
                && user.getIdentifier() != UserHandle.USER_ALL)) {
        if (!systemApp || action.mayDeleteUnupdatedSystemApp) {
            // The caller is asking that the package only be deleted for a single
            // user.  To do this, we just mark its uninstalled state and delete
            // its data. If this is a system app, we only allow this to happen if