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

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

Merge "Add support for uninstalling apex to PackageManagerShellCommand"

parents b62f541a f012a22a
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.PackageManager.ComponentInfoFlags;
import android.content.pm.PackageManager.PackageInfoFlags;
@@ -925,4 +926,21 @@ public abstract class PackageManagerInternal {
     * @param provider the provider
     */
    public abstract void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider);

    /**
     * Returns {@code true} if given {@code packageName} is an apex package.
     */
    public abstract boolean isApexPackage(String packageName);

    /**
     * Uninstalls given {@code packageName}.
     *
     * @param packageName apex package to uninstall.
     * @param versionCode version of a package to uninstall.
     * @param userId user to uninstall apex package for. Must be
     *               {@link android.os.UserHandle#USER_ALL}, otherwise failure will be reported.
     * @param intentSender a {@link IntentSender} to send result of an uninstall to.
     */
    public abstract void uninstallApex(String packageName, long versionCode, int userId,
            IntentSender intentSender);
}
+29 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import java.io.File;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -134,6 +135,17 @@ class ApexManager {
        return mActivePackagesCache.values();
    }

    /**
     * Checks if {@code packageName} is an apex package.
     *
     * @param packageName package to check.
     * @return {@code true} if {@code packageName} is an apex package.
     */
    boolean isApexPackage(String packageName) {
        populateActivePackagesCacheIfNeeded();
        return mActivePackagesCache.containsKey(packageName);
    }

    /**
     * Retrieves information about an apexd staged session i.e. the internal state used by apexd to
     * track the different states of a session.
@@ -245,6 +257,23 @@ class ApexManager {
        }
    }

    /**
     * Uninstalls given {@code apexPackage}.
     *
     * <p>NOTE. Device must be rebooted in order for uninstall to take effect.
     *
     * @param apexPackagePath package to uninstall.
     * @return {@code true} upon successful uninstall, {@code false} otherwise.
     */
    boolean uninstallApex(String apexPackagePath) {
        try {
            mApexService.unstagePackages(Collections.singletonList(apexPackagePath));
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * Dumps various state information to the provided {@link PrintWriter} object.
     *
+44 −0
Original line number Diff line number Diff line
@@ -23902,6 +23902,50 @@ public class PackageManagerService extends IPackageManager.Stub
                mDefaultHomeProvider = provider;
            }
        }
        @Override
        public boolean isApexPackage(String packageName) {
            return PackageManagerService.this.mApexManager.isApexPackage(packageName);
        }
        @Override
        public void uninstallApex(String packageName, long versionCode, int userId,
                IntentSender intentSender) {
            final int callerUid = Binder.getCallingUid();
            if (callerUid != Process.ROOT_UID && callerUid != Process.SHELL_UID) {
                throw new SecurityException("Not allowed to uninstall apexes");
            }
            PackageInstallerService.PackageDeleteObserverAdapter adapter =
                    new PackageInstallerService.PackageDeleteObserverAdapter(
                            PackageManagerService.this.mContext, intentSender, packageName,
                            false, userId);
            if (userId != UserHandle.USER_ALL) {
                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
                        "Can't uninstall an apex for a single user");
                return;
            }
            final ApexManager am = PackageManagerService.this.mApexManager;
            PackageInfo activePackage = am.getActivePackage(packageName);
            if (activePackage == null) {
                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
                        packageName + " is not an apex package");
                return;
            }
            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
                    && activePackage.getLongVersionCode() != versionCode) {
                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
                        "Active version " + activePackage.getLongVersionCode()
                                + " is not equal to " + versionCode + "]");
                return;
            }
            if (!am.uninstallApex(activePackage.applicationInfo.sourceDir)) {
                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
                        "Failed to uninstall apex " + packageName);
            } else {
                adapter.onPackageDeleted(packageName, PackageManager.DELETE_SUCCEEDED,
                        null);
            }
        }
    }
    @GuardedBy("mPackages")
+27 −21
Original line number Diff line number Diff line
@@ -1619,6 +1619,12 @@ class PackageManagerShellCommand extends ShellCommand {
        }

        userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
        final LocalIntentReceiver receiver = new LocalIntentReceiver();
        PackageManagerInternal internal = LocalServices.getService(PackageManagerInternal.class);

        if (internal.isApexPackage(packageName)) {
            internal.uninstallApex(packageName, versionCode, userId, receiver.getIntentSender());
        } else {
            if (userId == UserHandle.USER_ALL) {
                userId = UserHandle.USER_SYSTEM;
                flags |= PackageManager.DELETE_ALL_USERS;
@@ -1639,10 +1645,10 @@ class PackageManagerShellCommand extends ShellCommand {
                }
            }

        final LocalIntentReceiver receiver = new LocalIntentReceiver();
            mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
                            versionCode), null /*callerPackageName*/, flags,
                    receiver.getIntentSender(), userId);
        }

        final Intent result = receiver.getResult();
        final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,