Add self update permission

This permission is a subset of INSTALL_PACKAGES that only allows a
package to update itself. Many of the users of INSTALL_PACKAGE claim to
be using it solely for self updating but INSTALL_PACKAGES gives a lot
more power than is needed. This limits those priv apps to what they
intend to do.

Test: manual
Change-Id: I3442ad1a285df660b8c2635e3db59d7bc0662324
diff --git a/api/system-current.txt b/api/system-current.txt
index 61216fc..5bd84f1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -127,6 +127,7 @@
     field public static final java.lang.String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS";
     field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
     field public static final java.lang.String INSTALL_PACKAGES = "android.permission.INSTALL_PACKAGES";
+    field public static final java.lang.String INSTALL_SELF_UPDATES = "android.permission.INSTALL_SELF_UPDATES";
     field public static final java.lang.String INSTALL_SHORTCUT = "com.android.launcher.permission.INSTALL_SHORTCUT";
     field public static final java.lang.String INSTANT_APP_FOREGROUND_SERVICE = "android.permission.INSTANT_APP_FOREGROUND_SERVICE";
     field public static final java.lang.String INTENT_FILTER_VERIFICATION_AGENT = "android.permission.INTENT_FILTER_VERIFICATION_AGENT";
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8573e1d..39046d2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2776,6 +2776,14 @@
     <!-- @SystemApi Allows an application to install packages.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.INSTALL_PACKAGES"
+      android:protectionLevel="signature|privileged" />
+
+    <!-- @SystemApi Allows an application to install self updates. This is a limited version
+         of {@link android.Manifest.permission#INSTALL_PACKAGES}.
+        <p>Not for use by third-party applications.
+        @hide
+    -->
+    <permission android:name="android.permission.INSTALL_SELF_UPDATES"
         android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to clear user data.
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 0ecb4e1..648586e 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -312,9 +312,15 @@
             return false;
         }
 
-        final boolean isPermissionGranted =
+        final boolean isInstallPermissionGranted =
                 (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES,
                         mInstallerUid) == PackageManager.PERMISSION_GRANTED);
+        final boolean isSelfUpdatePermissionGranted =
+                (mPm.checkUidPermission(android.Manifest.permission.INSTALL_SELF_UPDATES,
+                        mInstallerUid) == PackageManager.PERMISSION_GRANTED);
+        final boolean isPermissionGranted = isInstallPermissionGranted
+                || (isSelfUpdatePermissionGranted
+                    && mPm.getPackageUid(mPackageName, 0, userId) == mInstallerUid);
         final boolean isInstallerRoot = (mInstallerUid == Process.ROOT_UID);
         final boolean forcePermissionPrompt =
                 (params.installFlags & PackageManager.INSTALL_FORCE_PERMISSION_PROMPT) != 0;