Enforce REQUEST_DELETE_PACKAGES for PackageInstaller.uninstall()

Fixes: 64576642
Test: Uninstalled apps
Change-Id: Ia7f3c047bb9c725228ca45e4c34e51a2d9177120
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index dd729a3..bad452c 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1728,6 +1728,9 @@
      * <p>
      * Output: If {@link #EXTRA_RETURN_RESULT}, returns whether the install
      * succeeded.
+     * <p>
+     * Requires {@link android.Manifest.permission#REQUEST_DELETE_PACKAGES}
+     * since {@link Build.VERSION_CODES#P}.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE";
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 5673361..86288396 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -444,6 +444,9 @@
      * @param packageName The package to uninstall.
      * @param statusReceiver Where to deliver the result.
      */
+    @RequiresPermission(anyOf = {
+            Manifest.permission.DELETE_PACKAGES,
+            Manifest.permission.REQUEST_DELETE_PACKAGES})
     public void uninstall(@NonNull String packageName, @NonNull IntentSender statusReceiver) {
         uninstall(packageName, 0 /*flags*/, statusReceiver);
     }
@@ -476,6 +479,9 @@
      * @param versionedPackage The versioned package to uninstall.
      * @param statusReceiver Where to deliver the result.
      */
+    @RequiresPermission(anyOf = {
+            Manifest.permission.DELETE_PACKAGES,
+            Manifest.permission.REQUEST_DELETE_PACKAGES})
     public void uninstall(@NonNull VersionedPackage versionedPackage,
             @NonNull IntentSender statusReceiver) {
         uninstall(versionedPackage, 0 /*flags*/, statusReceiver);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index fd17dcb..1b56c28 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2776,8 +2776,9 @@
         android:protectionLevel="signature|appop" />
 
     <!-- Allows an application to request deleting packages. Apps
-         targeting APIs greater than 25 must hold this permission in
-         order to use {@link android.content.Intent#ACTION_UNINSTALL_PACKAGE}.
+         targeting APIs {@link android.os.Build.VERSION_CODES#P} or greater must hold this
+         permission in order to use {@link android.content.Intent#ACTION_UNINSTALL_PACKAGE} or
+         {@link android.content.pm.PackageInstaller#uninstall}.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.REQUEST_DELETE_PACKAGES"
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 09f9cb8..be9b2f3 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -32,6 +32,7 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.IntentSender.SendIntentException;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageInstallerCallback;
 import android.content.pm.IPackageInstallerSession;
@@ -45,6 +46,7 @@
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
@@ -724,6 +726,12 @@
                 Binder.restoreCallingIdentity(ident);
             }
         } else {
+            ApplicationInfo appInfo = mPm.getApplicationInfo(callerPackageName, 0, userId);
+            if (appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
+                mContext.enforceCallingOrSelfPermission(Manifest.permission.REQUEST_DELETE_PACKAGES,
+                        null);
+            }
+
             // Take a short detour to confirm with user
             final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
             intent.setData(Uri.fromParts("package", versionedPackage.getPackageName(), null));