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

Commit eda93a2c authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Fix cleanup when an app with SUSPEND_APPS is deleted

If an app with SUSPEND_APPS happened to be a system app, downgrade would
happen simultaneously on all users it was installed on. The system
should clean up suspensions on all such users in this case.
Also cleaning up the "distracting restrictions" that were being left
around earlier.

Added a new shell command to uninstall-system-updates for a specific
package.

Test: Manual.
1. Install a system app <app1> with SUSPEND_APPS and suspend another
app, <app2> with it in user 0.
2. Create another user and install an update to app1.
3. Run `adb shell pm uninstall --user all <app1>`
Verify that app2 got unsuspended in user 0.
4. Repeat 1 and then run `adb shell pm uninstall-system-updates <app1>`
Verify that app2 got unsuspended in user 0.

Bug: 139950940
Change-Id: I007b248ed522c6658d3cb48d286768c3cb3db0a1
parent fdcdfb95
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -19147,9 +19147,7 @@ public class PackageManagerService extends IPackageManager.Stub
        final boolean systemApp = isSystemApp(ps);
        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
        if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) {
            unsuspendForSuspendingPackage(packageName, userId);
        }
        if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
                && userId != UserHandle.USER_ALL) {
            // The caller is asking that the package only be deleted for a single
@@ -19207,6 +19205,20 @@ public class PackageManagerService extends IPackageManager.Stub
                    outInfo, writeSettings);
        }
        // If the package removed had SUSPEND_APPS, unset any restrictions that might have been in
        // place for all affected users.
        int[] affectedUserIds = (outInfo != null) ? outInfo.removedUsers : null;
        if (affectedUserIds == null) {
            affectedUserIds = resolveUserIds(userId);
        }
        for (final int affectedUserId : affectedUserIds) {
            if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS,
                    affectedUserId)) {
                unsuspendForSuspendingPackage(packageName, affectedUserId);
                removeAllDistractingPackageRestrictions(affectedUserId);
            }
        }
        // Take a note whether we deleted the package for all users
        if (outInfo != null) {
            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
+22 −16
Original line number Diff line number Diff line
@@ -125,7 +125,6 @@ import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -291,7 +290,8 @@ class PackageManagerShellCommand extends ShellCommand {
                case "get-stagedsessions":
                    return runListStagedSessions();
                case "uninstall-system-updates":
                    return uninstallSystemUpdates();
                    String packageName = getNextArg();
                    return uninstallSystemUpdates(packageName);
                case "rollback-app":
                    return runRollbackApp();
                case "get-moduleinfo":
@@ -409,15 +409,22 @@ class PackageManagerShellCommand extends ShellCommand {
        }
    }

    private int uninstallSystemUpdates() {
    private int uninstallSystemUpdates(String packageName) {
        final PrintWriter pw = getOutPrintWriter();
        List<String> failedUninstalls = new LinkedList<>();
        boolean failedUninstalls = false;
        try {
            final IPackageInstaller installer = mInterface.getPackageInstaller();
            final List<ApplicationInfo> list;
            if (packageName == null) {
                final ParceledListSlice<ApplicationInfo> packages =
                        mInterface.getInstalledApplications(
                                PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
            final IPackageInstaller installer = mInterface.getPackageInstaller();
            List<ApplicationInfo> list = packages.getList();
                list = packages.getList();
            } else {
                list = new ArrayList<>(1);
                list.add(mInterface.getApplicationInfo(packageName,
                        PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM));
            }
            for (ApplicationInfo info : list) {
                if (info.isUpdatedSystemApp()) {
                    pw.println("Uninstalling updates to " + info.packageName + "...");
@@ -430,7 +437,8 @@ class PackageManagerShellCommand extends ShellCommand {
                    final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
                            PackageInstaller.STATUS_FAILURE);
                    if (status != PackageInstaller.STATUS_SUCCESS) {
                        failedUninstalls.add(info.packageName);
                        failedUninstalls = true;
                        pw.println("Couldn't uninstall package: " + info.packageName);
                    }
                }
            }
@@ -440,10 +448,7 @@ class PackageManagerShellCommand extends ShellCommand {
                    + e.getMessage() + "]");
            return 0;
        }
        if (!failedUninstalls.isEmpty()) {
            pw.println("Failure [Couldn't uninstall packages: "
                    + TextUtils.join(", ", failedUninstalls)
                    + "]");
        if (failedUninstalls) {
            return 0;
        }
        pw.println("Success");
@@ -3824,9 +3829,10 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("  get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
        pw.println("    Return the harmful app warning message for the given app, if present");
        pw.println();
        pw.println("  uninstall-system-updates");
        pw.println("    Remove updates to all system applications and fall back to their /system " +
                "version.");
        pw.println("  uninstall-system-updates [<PACKAGE>]");
        pw.println("    Removes updates to the given system application and falls back to its");
        pw.println("    /system version. Does nothing if the given package is not a system app.");
        pw.println("    If no package is specified, removes updates to all system applications.");
        pw.println("");
        pw.println("  get-moduleinfo [--all | --installed] [module-name]");
        pw.println("    Displays module info. If module-name is specified only that info is shown");