Merge "Catch IAE from unbind onServiceDisconnected()" into pi-dev
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index e85058d..aa0bd84 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -590,26 +590,33 @@
     public static final int PRIVATE_FLAG_VIRTUAL_PRELOAD = 1 << 16;
 
     /**
-     * Value for {@linl #privateFlags}: whether this app is pre-installed on the
+     * Value for {@link #privateFlags}: whether this app is pre-installed on the
      * OEM partition of the system image.
      * @hide
      */
     public static final int PRIVATE_FLAG_OEM = 1 << 17;
 
     /**
-     * Value for {@linl #privateFlags}: whether this app is pre-installed on the
+     * Value for {@link #privateFlags}: whether this app is pre-installed on the
      * vendor partition of the system image.
      * @hide
      */
     public static final int PRIVATE_FLAG_VENDOR = 1 << 18;
 
     /**
-     * Value for {@linl #privateFlags}: whether this app is pre-installed on the
+     * Value for {@link #privateFlags}: whether this app is pre-installed on the
      * product partition of the system image.
      * @hide
      */
     public static final int PRIVATE_FLAG_PRODUCT = 1 << 19;
 
+    /**
+     * Value for {@link #privateFlags}: whether this app is signed with the
+     * platform key.
+     * @hide
+     */
+    public static final int PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY = 1 << 20;
+
     /** @hide */
     @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = {
             PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE,
@@ -629,6 +636,7 @@
             PRIVATE_FLAG_PRIVILEGED,
             PRIVATE_FLAG_PRODUCT,
             PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER,
+            PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY,
             PRIVATE_FLAG_STATIC_SHARED_LIBRARY,
             PRIVATE_FLAG_VENDOR,
             PRIVATE_FLAG_VIRTUAL_PRELOAD,
@@ -1658,6 +1666,11 @@
         return SystemConfig.getInstance().getHiddenApiWhitelistedApps().contains(packageName);
     }
 
+    private boolean isAllowedToUseHiddenApis() {
+        return isSignedWithPlatformKey()
+            || (isPackageWhitelistedForHiddenApis() && (isSystemApp() || isUpdatedSystemApp()));
+    }
+
     /**
      * @hide
      */
@@ -1665,7 +1678,7 @@
         if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) {
             return mHiddenApiPolicy;
         }
-        if (isPackageWhitelistedForHiddenApis() && (isSystemApp() || isUpdatedSystemApp())) {
+        if (isAllowedToUseHiddenApis()) {
             return HIDDEN_API_ENFORCEMENT_NONE;
         }
         return HIDDEN_API_ENFORCEMENT_BLACK;
@@ -1758,6 +1771,11 @@
     }
 
     /** @hide */
+    public boolean isSignedWithPlatformKey() {
+        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY) != 0;
+    }
+
+    /** @hide */
     @TestApi
     public boolean isPrivilegedApp() {
         return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
index 95aff9a..4e09c69 100644
--- a/data/etc/hiddenapi-package-whitelist.xml
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -17,66 +17,28 @@
 
 <!--
 This XML file declares which system apps should be exempted from the hidden API blacklisting, i.e.
-which apps should be allowed to access the entire private API.
+which apps should be allowed to access the entire private API. Only apps NOT signed with the
+platform cert need to be included, as apps signed with the platform cert are exempted by default.
 -->
 
 <config>
-  <hidden-api-whitelisted-app package="android.car.cluster.loggingrenderer" />
-  <hidden-api-whitelisted-app package="android.car.input.service" />
-  <hidden-api-whitelisted-app package="android.car.usb.handler" />
   <hidden-api-whitelisted-app package="android.ext.services" />
   <hidden-api-whitelisted-app package="com.android.apps.tag" />
-  <hidden-api-whitelisted-app package="com.android.backupconfirm" />
   <hidden-api-whitelisted-app package="com.android.basicsmsreceiver" />
-  <hidden-api-whitelisted-app package="com.android.bluetooth" />
-  <hidden-api-whitelisted-app package="com.android.bluetoothdebug" />
-  <hidden-api-whitelisted-app package="com.android.bluetoothmidiservice" />
   <hidden-api-whitelisted-app package="com.android.bookmarkprovider" />
   <hidden-api-whitelisted-app package="com.android.calllogbackup" />
   <hidden-api-whitelisted-app package="com.android.camera" />
-  <hidden-api-whitelisted-app package="com.android.captiveportallogin" />
-  <hidden-api-whitelisted-app package="com.android.car" />
   <hidden-api-whitelisted-app package="com.android.car.dialer" />
-  <hidden-api-whitelisted-app package="com.android.car.hvac" />
-  <hidden-api-whitelisted-app package="com.android.car.mapsplaceholder" />
-  <hidden-api-whitelisted-app package="com.android.car.media" />
-  <hidden-api-whitelisted-app package="com.android.car.media.localmediaplayer" />
   <hidden-api-whitelisted-app package="com.android.car.messenger" />
   <hidden-api-whitelisted-app package="com.android.car.overview" />
-  <hidden-api-whitelisted-app package="com.android.car.radio" />
-  <hidden-api-whitelisted-app package="com.android.car.settings" />
   <hidden-api-whitelisted-app package="com.android.car.stream" />
-  <hidden-api-whitelisted-app package="com.android.car.systemupdater" />
-  <hidden-api-whitelisted-app package="com.android.car.trust" />
-  <hidden-api-whitelisted-app package="com.android.carrierconfig" />
-  <hidden-api-whitelisted-app package="com.android.carrierdefaultapp" />
-  <hidden-api-whitelisted-app package="com.android.cellbroadcastreceiver" />
-  <hidden-api-whitelisted-app package="com.android.certinstaller" />
   <hidden-api-whitelisted-app package="com.android.companiondevicemanager" />
-  <hidden-api-whitelisted-app package="com.android.customlocale2" />
-  <hidden-api-whitelisted-app package="com.android.defcontainer" />
-  <hidden-api-whitelisted-app package="com.android.development" />
-  <hidden-api-whitelisted-app package="com.android.documentsui" />
   <hidden-api-whitelisted-app package="com.android.dreams.basic" />
-  <hidden-api-whitelisted-app package="com.android.egg" />
-  <hidden-api-whitelisted-app package="com.android.emergency" />
-  <hidden-api-whitelisted-app package="com.android.externalstorage" />
-  <hidden-api-whitelisted-app package="com.android.fakeoemfeatures" />
   <hidden-api-whitelisted-app package="com.android.gallery" />
-  <hidden-api-whitelisted-app package="com.android.hotspot2" />
-  <hidden-api-whitelisted-app package="com.android.keychain" />
   <hidden-api-whitelisted-app package="com.android.launcher3" />
-  <hidden-api-whitelisted-app package="com.android.location.fused" />
-  <hidden-api-whitelisted-app package="com.android.managedprovisioning" />
-  <hidden-api-whitelisted-app package="com.android.mms.service" />
   <hidden-api-whitelisted-app package="com.android.mtp" />
   <hidden-api-whitelisted-app package="com.android.musicfx" />
-  <hidden-api-whitelisted-app package="com.android.nfc" />
-  <hidden-api-whitelisted-app package="com.android.osu" />
   <hidden-api-whitelisted-app package="com.android.packageinstaller" />
-  <hidden-api-whitelisted-app package="com.android.pacprocessor" />
-  <hidden-api-whitelisted-app package="com.android.phone" />
-  <hidden-api-whitelisted-app package="com.android.pmc" />
   <hidden-api-whitelisted-app package="com.android.printservice.recommendation" />
   <hidden-api-whitelisted-app package="com.android.printspooler" />
   <hidden-api-whitelisted-app package="com.android.providers.blockednumber" />
@@ -85,36 +47,13 @@
   <hidden-api-whitelisted-app package="com.android.providers.downloads" />
   <hidden-api-whitelisted-app package="com.android.providers.downloads.ui" />
   <hidden-api-whitelisted-app package="com.android.providers.media" />
-  <hidden-api-whitelisted-app package="com.android.providers.settings" />
-  <hidden-api-whitelisted-app package="com.android.providers.telephony" />
   <hidden-api-whitelisted-app package="com.android.providers.tv" />
   <hidden-api-whitelisted-app package="com.android.providers.userdictionary" />
-  <hidden-api-whitelisted-app package="com.android.provision" />
-  <hidden-api-whitelisted-app package="com.android.proxyhandler" />
-  <hidden-api-whitelisted-app package="com.android.sdksetup" />
-  <hidden-api-whitelisted-app package="com.android.se" />
-  <hidden-api-whitelisted-app package="com.android.server.telecom" />
-  <hidden-api-whitelisted-app package="com.android.service.ims" />
-  <hidden-api-whitelisted-app package="com.android.service.ims.presence" />
-  <hidden-api-whitelisted-app package="com.android.settings" />
-  <hidden-api-whitelisted-app package="com.android.sharedstoragebackup" />
-  <hidden-api-whitelisted-app package="com.android.shell" />
   <hidden-api-whitelisted-app package="com.android.smspush" />
   <hidden-api-whitelisted-app package="com.android.spare_parts" />
   <hidden-api-whitelisted-app package="com.android.statementservice" />
-  <hidden-api-whitelisted-app package="com.android.stk" />
   <hidden-api-whitelisted-app package="com.android.storagemanager" />
-  <hidden-api-whitelisted-app package="com.android.support.car.lenspicker" />
-  <hidden-api-whitelisted-app package="com.android.systemui" />
   <hidden-api-whitelisted-app package="com.android.systemui.plugins" />
   <hidden-api-whitelisted-app package="com.android.terminal" />
-  <hidden-api-whitelisted-app package="com.android.timezone.updater" />
-  <hidden-api-whitelisted-app package="com.android.traceur" />
-  <hidden-api-whitelisted-app package="com.android.tv.settings" />
-  <hidden-api-whitelisted-app package="com.android.vpndialogs" />
-  <hidden-api-whitelisted-app package="com.android.wallpaper.livepicker" />
-  <hidden-api-whitelisted-app package="com.android.wallpaperbackup" />
-  <hidden-api-whitelisted-app package="com.android.wallpapercropper" />
-  <hidden-api-whitelisted-app package="com.googlecode.android_scripting" />
   <hidden-api-whitelisted-app package="jp.co.omronsoft.openwnn" />
 </config>
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a26581b..712392e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8700,7 +8700,7 @@
                             disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
                             null /* originalPkgSetting */, null, parseFlags, scanFlags,
                             (pkg == mPlatformPackage), user);
-                    applyPolicy(pkg, parseFlags, scanFlags);
+                    applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
                     scanPackageOnlyLI(request, mFactoryTest, -1L);
                 }
             }
@@ -10019,7 +10019,7 @@
 
         scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg);
         synchronized (mPackages) {
-            applyPolicy(pkg, parseFlags, scanFlags);
+            applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
             assertPackageIsValid(pkg, parseFlags, scanFlags);
 
             SharedUserSetting sharedUserSetting = null;
@@ -10699,7 +10699,7 @@
      * ideally be static, but, it requires locks to read system state.
      */
     private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
-            final @ScanFlags int scanFlags) {
+            final @ScanFlags int scanFlags, PackageParser.Package platformPkg) {
         if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
             if (pkg.applicationInfo.isDirectBootAware()) {
@@ -10785,6 +10785,15 @@
             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
         }
 
+        // Check if the package is signed with the same key as the platform package.
+        if (PLATFORM_PACKAGE_NAME.equals(pkg.packageName) ||
+                (platformPkg != null && compareSignatures(
+                        platformPkg.mSigningDetails.signatures,
+                        pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH)) {
+            pkg.applicationInfo.privateFlags |=
+                ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY;
+        }
+
         if (!isSystemApp(pkg)) {
             // Only system apps can use these features.
             pkg.mOriginalPackages = null;