Move hidden ApplicationInfo flags into a separate field.

The public API field android.content.pm.ApplicationInfo.flags can
support only 32 flags. This limit has been reached. As a short term
workaround to enable new public flags to be added, this CL moves flags
which are not public API into a separate new field privateFlags and
renames the affected flags constants accordingly (e.g., FLAG_PRIVILEGED
is now PRIVATE_FLAG_PRIVILEGED).

The new privateFlags field is not public API and should not be used
for flags that are public API.

The flags that are moved out of ApplicationInfo.flags are:
* FLAG_HIDDEN,
* FLAG_CANT_SAVE_STATE,
* FLAG_FORWARD_LOCK, and
* FLAG_PRIVILEGED.

NOTE: This changes the format of packages.xml. Prior to this CL flags
were stored in the "flags" attribute. With this CL, the public flags
are stored in a new "publicFlags" attribute and private flags are
stored in a new "privateFlags" attribute. The old "flags" attribute
is interpreted by using the old values of hidden/private flags.

Change-Id: Ie23eb8ddd5129de3c6e008c5261b639e22182ee5
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index e07edba..e822708 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -334,44 +334,6 @@
     public static final int FLAG_FULL_BACKUP_ONLY = 1<<26;
 
     /**
-     * Value for {@link #flags}: true if the application is hidden via restrictions and for
-     * most purposes is considered as not installed.
-     * {@hide}
-     */
-    public static final int FLAG_HIDDEN = 1<<27;
-
-    /**
-     * Value for {@link #flags}: set to <code>true</code> if the application
-     * has reported that it is heavy-weight, and thus can not participate in
-     * the normal application lifecycle.
-     *
-     * <p>Comes from the
-     * android.R.styleable#AndroidManifestApplication_cantSaveState
-     * attribute of the &lt;application&gt; tag.
-     *
-     * {@hide}
-     */
-    public static final int FLAG_CANT_SAVE_STATE = 1<<28;
-
-    /**
-     * Value for {@link #flags}: Set to true if the application has been
-     * installed using the forward lock option.
-     *
-     * NOTE: DO NOT CHANGE THIS VALUE!  It is saved in packages.xml.
-     * 
-     * {@hide}
-     */
-    public static final int FLAG_FORWARD_LOCK = 1<<29;
-
-    /**
-     * Value for {@link #flags}: set to {@code true} if the application
-     * is permitted to hold privileged permissions.
-     *
-     * {@hide}
-     */
-    public static final int FLAG_PRIVILEGED = 1<<30;
-
-    /**
      * Value for {@link #flags}: true if code from this application will need to be
      * loaded into other applications' processes. On devices that support multiple
      * instruction sets, this implies the code might be loaded into a process that's
@@ -395,11 +357,60 @@
      * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_SUPPORTS_XLARGE_SCREENS},
      * {@link #FLAG_RESIZEABLE_FOR_SCREENS},
      * {@link #FLAG_SUPPORTS_SCREEN_DENSITIES}, {@link #FLAG_VM_SAFE_MODE},
-     * {@link #FLAG_INSTALLED}, {@link #FLAG_IS_GAME}.
+     * {@link #FLAG_ALLOW_BACKUP}, {@link #FLAG_KILL_AFTER_RESTORE},
+     * {@link #FLAG_RESTORE_ANY_VERSION}, {@link #FLAG_EXTERNAL_STORAGE},
+     * {@link #FLAG_LARGE_HEAP}, {@link #FLAG_STOPPED},
+     * {@link #FLAG_SUPPORTS_RTL}, {@link #FLAG_INSTALLED},
+     * {@link #FLAG_IS_DATA_ONLY}, {@link #FLAG_IS_GAME},
+     * {@link #FLAG_FULL_BACKUP_ONLY}, {@link #FLAG_MULTIARCH}.
      */
     public int flags = 0;
 
     /**
+     * Value for {@link #privateFlags}: true if the application is hidden via restrictions and for
+     * most purposes is considered as not installed.
+     * {@hide}
+     */
+    public static final int PRIVATE_FLAG_HIDDEN = 1<<0;
+
+    /**
+     * Value for {@link #privateFlags}: set to <code>true</code> if the application
+     * has reported that it is heavy-weight, and thus can not participate in
+     * the normal application lifecycle.
+     *
+     * <p>Comes from the
+     * android.R.styleable#AndroidManifestApplication_cantSaveState
+     * attribute of the &lt;application&gt; tag.
+     *
+     * {@hide}
+     */
+    public static final int PRIVATE_FLAG_CANT_SAVE_STATE = 1<<1;
+
+    /**
+     * Value for {@link #privateFlags}: Set to true if the application has been
+     * installed using the forward lock option.
+     *
+     * NOTE: DO NOT CHANGE THIS VALUE!  It is saved in packages.xml.
+     *
+     * {@hide}
+     */
+    public static final int PRIVATE_FLAG_FORWARD_LOCK = 1<<2;
+
+    /**
+     * Value for {@link #privateFlags}: set to {@code true} if the application
+     * is permitted to hold privileged permissions.
+     *
+     * {@hide}
+     */
+    public static final int PRIVATE_FLAG_PRIVILEGED = 1<<3;
+
+    /**
+     * Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
+     * {@hide}
+     */
+    public int privateFlags;
+
+    /**
      * The required smallest screen width the application can run on.  If 0,
      * nothing has been specified.  Comes from
      * {@link android.R.styleable#AndroidManifestSupportsScreens_requiresSmallestWidthDp
@@ -598,6 +609,7 @@
         pw.println(prefix + "processName=" + processName);
         pw.println(prefix + "taskAffinity=" + taskAffinity);
         pw.println(prefix + "uid=" + uid + " flags=0x" + Integer.toHexString(flags)
+                + " privateFlags=0x" + Integer.toHexString(privateFlags)
                 + " theme=0x" + Integer.toHexString(theme));
         pw.println(prefix + "requiresSmallestWidthDp=" + requiresSmallestWidthDp
                 + " compatibleWidthLimitDp=" + compatibleWidthLimitDp
@@ -680,6 +692,7 @@
         className = orig.className;
         theme = orig.theme;
         flags = orig.flags;
+        privateFlags = orig.privateFlags;
         requiresSmallestWidthDp = orig.requiresSmallestWidthDp;
         compatibleWidthLimitDp = orig.compatibleWidthLimitDp;
         largestWidthLimitDp = orig.largestWidthLimitDp;
@@ -730,6 +743,7 @@
         dest.writeString(className);
         dest.writeInt(theme);
         dest.writeInt(flags);
+        dest.writeInt(privateFlags);
         dest.writeInt(requiresSmallestWidthDp);
         dest.writeInt(compatibleWidthLimitDp);
         dest.writeInt(largestWidthLimitDp);
@@ -779,6 +793,7 @@
         className = source.readString();
         theme = source.readInt();
         flags = source.readInt();
+        privateFlags = source.readInt();
         requiresSmallestWidthDp = source.readInt();
         compatibleWidthLimitDp = source.readInt();
         largestWidthLimitDp = source.readInt();
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c37534a..b37713a 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -111,6 +111,8 @@
 
     int getFlagsForUid(int uid);
 
+    int getPrivateFlagsForUid(int uid);
+
     boolean isUidPrivileged(int uid);
 
     String[] getAppOpPermissionPackages(String permissionName);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ca4ff6a..131ca39 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -784,6 +784,7 @@
                 pkg.splitNames = lite.splitNames;
                 pkg.splitCodePaths = lite.splitCodePaths;
                 pkg.splitFlags = new int[num];
+                pkg.splitPrivateFlags = new int[num];
 
                 for (int i = 0; i < num; i++) {
                     parseSplitApk(pkg, i, assets, flags);
@@ -1391,7 +1392,7 @@
 
         /* Set the global "forward lock" flag */
         if ((flags & PARSE_FORWARD_LOCK) != 0) {
-            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FORWARD_LOCK;
+            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK;
         }
 
         /* Set the global "on SD card" flag */
@@ -2594,7 +2595,7 @@
                 if (sa.getBoolean(
                         com.android.internal.R.styleable.AndroidManifestApplication_cantSaveState,
                         false)) {
-                    ai.flags |= ApplicationInfo.FLAG_CANT_SAVE_STATE;
+                    ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;
 
                     // A heavy-weight application can not be in a custom process.
                     // We can do direct compare because we intern all strings.
@@ -3149,7 +3150,8 @@
 
         sa.recycle();
 
-        if (receiver && (owner.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
+        if (receiver && (owner.applicationInfo.privateFlags
+                &ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
             // A heavy-weight application can not have receives in its main process
             // We can do direct compare because we intern all strings.
             if (a.info.processName == owner.packageName) {
@@ -3502,7 +3504,8 @@
 
         sa.recycle();
 
-        if ((owner.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
+        if ((owner.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
+                != 0) {
             // A heavy-weight application can not have providers in its main process
             // We can do direct compare because we intern all strings.
             if (p.info.processName == owner.packageName) {
@@ -3777,7 +3780,8 @@
 
         sa.recycle();
 
-        if ((owner.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
+        if ((owner.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
+                != 0) {
             // A heavy-weight application can not have services in its main process
             // We can do direct compare because we intern all strings.
             if (s.info.processName == owner.packageName) {
@@ -4189,6 +4193,13 @@
         /** Flags of any split APKs; ordered by parsed splitName */
         public int[] splitFlags;
 
+        /**
+         * Private flags of any split APKs; ordered by parsed splitName.
+         *
+         * {@hide}
+         */
+        public int[] splitPrivateFlags;
+
         public boolean baseHardwareAccelerated;
 
         // For now we only support one application per package.
@@ -4624,9 +4635,9 @@
             ai.flags &= ~ApplicationInfo.FLAG_INSTALLED;
         }
         if (state.hidden) {
-            ai.flags |= ApplicationInfo.FLAG_HIDDEN;
+            ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
         } else {
-            ai.flags &= ~ApplicationInfo.FLAG_HIDDEN;
+            ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_HIDDEN;
         }
         if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
             ai.enabled = true;
diff --git a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
index 518a874..cc018e9 100644
--- a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
+++ b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
@@ -104,7 +104,7 @@
             try {
                 ai = pm.getApplicationInfo(
                         ri.activityInfo.packageName, PackageManager.GET_META_DATA);
-                if ((ai.flags & ApplicationInfo.FLAG_PRIVILEGED) == 0) {
+                if ((ai.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) == 0) {
                     // The application isn't privileged (/system/priv-app).
                     // The enrollment application needs to be a privileged system app.
                     Slog.w(TAG, ai.packageName + "is not a privileged system app");
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 3a80309..1530bb2 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -419,7 +419,7 @@
             if (rLoc == INSTALL_LOC_INT) {
                 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
                     assertTrue("The application should be installed forward locked",
-                            (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
+                            (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
                     assertStartsWith("The APK path should point to the ASEC",
                             SECURE_CONTAINERS_PREFIX, srcPath);
                     assertStartsWith("The public APK path should point to the ASEC",
@@ -435,7 +435,8 @@
                         fail("compat check: Can't read " + info.dataDir + "/lib");
                     }
                 } else {
-                    assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
+                    assertFalse(
+                            (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
                     assertEquals(srcPath, appInstallPath);
                     assertEquals(publicSrcPath, appInstallPath);
                     assertStartsWith("Native library should point to shared lib directory",
@@ -462,16 +463,16 @@
             } else if (rLoc == INSTALL_LOC_SD) {
                 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
                     assertTrue("The application should be installed forward locked",
-                            (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
+                            (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
                 } else {
                     assertFalse("The application should not be installed forward locked",
-                            (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
+                            (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
                 }
                 assertTrue("Application flags (" + info.flags
                         + ") should contain FLAG_EXTERNAL_STORAGE",
                         (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
                 // Might need to check:
-                // ((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0)
+                // ((info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0)
                 assertStartsWith("The APK path should point to the ASEC",
                         SECURE_CONTAINERS_PREFIX, srcPath);
                 assertStartsWith("The public APK path should point to the ASEC",