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

Commit d336f843 authored by Robert Horvath's avatar Robert Horvath
Browse files

Add PackageInstaller#uninstallExistingPackage

This new API allows an app to be uninstalled silently by any app holding
the DELETE_PACKAGES permission, as long as the app is installed in
another user so won't be fully removed from the device.

Bug: 149601842
Test: atest UninstallExistingPackageTest
Change-Id: I69fe4d1dd4e9da83574b431257f7be6d1ac8b2bb
parent 61bea7ba
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -11801,6 +11801,7 @@ package android.content.pm {
    method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback, @NonNull android.os.Handler);
    method @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void uninstall(@NonNull String, @NonNull android.content.IntentSender);
    method @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void uninstall(@NonNull android.content.pm.VersionedPackage, @NonNull android.content.IntentSender);
    method @RequiresPermission(android.Manifest.permission.DELETE_PACKAGES) public void uninstallExistingPackage(@NonNull String, @Nullable android.content.IntentSender);
    method public void unregisterSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback);
    method public void updateSessionAppIcon(int, @Nullable android.graphics.Bitmap);
    method public void updateSessionAppLabel(int, @Nullable CharSequence);
+3 −0
Original line number Diff line number Diff line
@@ -52,6 +52,9 @@ interface IPackageInstaller {
    void uninstall(in VersionedPackage versionedPackage, String callerPackageName, int flags,
            in IntentSender statusReceiver, int userId);

    void uninstallExistingPackage(in VersionedPackage versionedPackage, String callerPackageName,
            in IntentSender statusReceiver, int userId);

    void installExistingPackage(String packageName, int installFlags, int installReason,
            in IntentSender statusReceiver, int userId, in List<String> whiteListedPermissions);

+10 −0
Original line number Diff line number Diff line
@@ -235,6 +235,16 @@ interface IPackageManager {
    void deletePackageVersioned(in VersionedPackage versionedPackage,
            IPackageDeleteObserver2 observer, int userId, int flags);

    /**
     * Delete a package for a specific user.
     *
     * @param versionedPackage The package to delete.
     * @param observer a callback to use to notify when the package deletion in finished.
     * @param userId the id of the user for whom to delete the package
     */
    void deleteExistingPackageAsUser(in VersionedPackage versionedPackage,
            IPackageDeleteObserver2 observer, int userId);

    @UnsupportedAppUsage
    String getInstallerPackageName(in String packageName);

+19 −0
Original line number Diff line number Diff line
@@ -723,6 +723,25 @@ public class PackageInstaller {
        }
    }

    /**
     * Uninstall the given package for the user for which this installer was created if the package
     * will still exist for other users on the device.
     *
     * @param packageName The package to install.
     * @param statusReceiver Where to deliver the result.
     */
    @RequiresPermission(Manifest.permission.DELETE_PACKAGES)
    public void uninstallExistingPackage(@NonNull String packageName,
            @Nullable IntentSender statusReceiver) {
        Objects.requireNonNull(packageName, "packageName cannot be null");
        try {
            mInstaller.uninstallExistingPackage(
                    new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
                    mInstallerPackageName, statusReceiver, mUserId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** {@hide} */
    @SystemApi
+15 −0
Original line number Diff line number Diff line
@@ -936,6 +936,21 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        }
    }

    @Override
    public void uninstallExistingPackage(VersionedPackage versionedPackage,
            String callerPackageName, IntentSender statusReceiver, int userId) {
        final int callingUid = Binder.getCallingUid();
        mContext.enforceCallingOrSelfPermission(Manifest.permission.DELETE_PACKAGES, null);
        mPermissionManager.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
        if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
            mAppOps.checkPackage(callingUid, callerPackageName);
        }

        final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
                statusReceiver, versionedPackage.getPackageName(), false, userId);
        mPm.deleteExistingPackageAsUser(versionedPackage, adapter.getBinder(), userId);
    }

    @Override
    public void installExistingPackage(String packageName, int installFlags, int installReason,
            IntentSender statusReceiver, int userId, List<String> whiteListedPermissions) {
Loading