Merge "Add annotations and finals to PermissionGroupInfo"
diff --git a/api/current.txt b/api/current.txt
index 9fad6ca..5f447d3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11825,15 +11825,15 @@
   }
 
   public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
-    ctor public PermissionGroupInfo();
-    ctor public PermissionGroupInfo(android.content.pm.PermissionGroupInfo);
+    ctor @Deprecated public PermissionGroupInfo();
+    ctor @Deprecated public PermissionGroupInfo(@NonNull android.content.pm.PermissionGroupInfo);
     method public int describeContents();
-    method public CharSequence loadDescription(android.content.pm.PackageManager);
+    method @Nullable public CharSequence loadDescription(@NonNull android.content.pm.PackageManager);
     field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.PermissionGroupInfo> CREATOR;
     field public static final int FLAG_PERSONAL_INFO = 1; // 0x1
-    field public int descriptionRes;
+    field @StringRes public int descriptionRes;
     field public int flags;
-    field public CharSequence nonLocalizedDescription;
+    field @Nullable public CharSequence nonLocalizedDescription;
     field public int priority;
   }
 
diff --git a/api/system-current.txt b/api/system-current.txt
index ae06706..7cd8c14 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1709,9 +1709,9 @@
   }
 
   public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
-    field @StringRes public int backgroundRequestDetailResourceId;
-    field @StringRes public int backgroundRequestResourceId;
-    field @StringRes public int requestDetailResourceId;
+    field @StringRes public final int backgroundRequestDetailResourceId;
+    field @StringRes public final int backgroundRequestResourceId;
+    field @StringRes public final int requestDetailResourceId;
     field @StringRes public int requestRes;
   }
 
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a006f23..e516ed6 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -45,6 +45,7 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityTaskManager;
@@ -3260,10 +3261,21 @@
     private boolean parsePermissionGroup(Package owner, int flags, Resources res,
             XmlResourceParser parser, String[] outError)
             throws XmlPullParserException, IOException {
-        PermissionGroup perm = new PermissionGroup(owner);
-
         TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestPermissionGroup);
+
+        int requestDetailResourceId = sa.getResourceId(
+                com.android.internal.R.styleable.AndroidManifestPermissionGroup_requestDetail, 0);
+        int backgroundRequestResourceId = sa.getResourceId(
+                com.android.internal.R.styleable.AndroidManifestPermissionGroup_backgroundRequest,
+                0);
+        int backgroundRequestDetailResourceId = sa.getResourceId(
+                com.android.internal.R.styleable
+                        .AndroidManifestPermissionGroup_backgroundRequestDetail, 0);
+
+        PermissionGroup perm = new PermissionGroup(owner, requestDetailResourceId,
+                backgroundRequestResourceId, backgroundRequestDetailResourceId);
+
         if (!parsePackageItemInfo(owner, perm.info, outError,
                 "<permission-group>", sa, true /*nameRequired*/,
                 com.android.internal.R.styleable.AndroidManifestPermissionGroup_name,
@@ -3282,14 +3294,6 @@
                 0);
         perm.info.requestRes = sa.getResourceId(
                 com.android.internal.R.styleable.AndroidManifestPermissionGroup_request, 0);
-        perm.info.requestDetailResourceId = sa.getResourceId(
-                com.android.internal.R.styleable.AndroidManifestPermissionGroup_requestDetail, 0);
-        perm.info.backgroundRequestResourceId = sa.getResourceId(
-                com.android.internal.R.styleable.AndroidManifestPermissionGroup_backgroundRequest,
-                0);
-        perm.info.backgroundRequestDetailResourceId = sa.getResourceId(
-                com.android.internal.R.styleable
-                        .AndroidManifestPermissionGroup_backgroundRequestDetail, 0);
         perm.info.flags = sa.getInt(
                 com.android.internal.R.styleable.AndroidManifestPermissionGroup_permissionGroupFlags, 0);
         perm.info.priority = sa.getInt(
@@ -7676,9 +7680,12 @@
         @UnsupportedAppUsage
         public final PermissionGroupInfo info;
 
-        public PermissionGroup(Package _owner) {
-            super(_owner);
-            info = new PermissionGroupInfo();
+        public PermissionGroup(Package owner, @StringRes int requestDetailResourceId,
+                @StringRes int backgroundRequestResourceId,
+                @StringRes int backgroundRequestDetailResourceId) {
+            super(owner);
+            info = new PermissionGroupInfo(requestDetailResourceId, backgroundRequestResourceId,
+                    backgroundRequestDetailResourceId);
         }
 
         public PermissionGroup(Package _owner, PermissionGroupInfo _info) {
diff --git a/core/java/android/content/pm/PermissionGroupInfo.java b/core/java/android/content/pm/PermissionGroupInfo.java
index 3a87eca..e65e742 100644
--- a/core/java/android/content/pm/PermissionGroupInfo.java
+++ b/core/java/android/content/pm/PermissionGroupInfo.java
@@ -16,12 +16,20 @@
 
 package android.content.pm;
 
+import static android.content.res.Resources.ID_NULL;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Information you can retrieve about a particular security permission
  * group known to the system.  This corresponds to information collected from the
@@ -33,7 +41,7 @@
      * permission's description.  From the "description" attribute or,
      * if not set, 0.
      */
-    public int descriptionRes;
+    public @StringRes int descriptionRes;
 
     /**
      * A string resource identifier (in the package's resources) used to request the permissions.
@@ -54,7 +62,7 @@
      * @hide
      */
     @SystemApi
-    public @StringRes int requestDetailResourceId;
+    public final @StringRes int requestDetailResourceId;
 
     /**
      * A string resource identifier (in the package's resources) used when requesting background
@@ -66,7 +74,7 @@
      * @hide
      */
     @SystemApi
-    public @StringRes int backgroundRequestResourceId;
+    public final @StringRes int backgroundRequestResourceId;
 
     /**
      * A string resource identifier (in the package's resources) used as subtitle when requesting
@@ -78,7 +86,7 @@
      * @hide
      */
     @SystemApi
-    public @StringRes int backgroundRequestDetailResourceId;
+    public final @StringRes int backgroundRequestDetailResourceId;
 
     /**
      * The description string provided in the AndroidManifest file, if any.  You
@@ -86,7 +94,7 @@
      * is in a resource.  You probably want
      * {@link PermissionInfo#loadDescription} instead.
      */
-    public CharSequence nonLocalizedDescription;
+    public @Nullable CharSequence nonLocalizedDescription;
 
     /**
      * Flag for {@link #flags}, corresponding to <code>personalInfo</code>
@@ -94,21 +102,48 @@
      */
     public static final int FLAG_PERSONAL_INFO = 1<<0;
 
+    /** @hide */
+    @IntDef(flag = true, prefix = { "FLAG_" }, value = {
+            FLAG_PERSONAL_INFO,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Flags {}
+
     /**
      * Additional flags about this group as given by
      * {@link android.R.attr#permissionGroupFlags}.
      */
-    public int flags;
+    public @Flags int flags;
 
     /**
      * Prioritization of this group, for visually sorting with other groups.
      */
     public int priority;
 
-    public PermissionGroupInfo() {
+    /**
+     * @hide
+     */
+    public PermissionGroupInfo(@StringRes int requestDetailResourceId,
+            @StringRes int backgroundRequestResourceId,
+            @StringRes int backgroundRequestDetailResourceId) {
+        this.requestDetailResourceId = requestDetailResourceId;
+        this.backgroundRequestResourceId = backgroundRequestResourceId;
+        this.backgroundRequestDetailResourceId = backgroundRequestDetailResourceId;
     }
 
-    public PermissionGroupInfo(PermissionGroupInfo orig) {
+    /**
+     * @deprecated Should only be created by the system.
+     */
+    @Deprecated
+    public PermissionGroupInfo() {
+        this(ID_NULL, ID_NULL, ID_NULL);
+    }
+
+    /**
+     * @deprecated Should only be created by the system.
+     */
+    @Deprecated
+    public PermissionGroupInfo(@NonNull PermissionGroupInfo orig) {
         super(orig);
         descriptionRes = orig.descriptionRes;
         requestRes = orig.requestRes;
@@ -131,7 +166,7 @@
      * @return Returns a CharSequence containing the permission's description.
      * If there is no description, null is returned.
      */
-    public CharSequence loadDescription(PackageManager pm) {
+    public @Nullable CharSequence loadDescription(@NonNull PackageManager pm) {
         if (nonLocalizedDescription != null) {
             return nonLocalizedDescription;
         }
@@ -166,7 +201,7 @@
         dest.writeInt(priority);
     }
 
-    public static final @android.annotation.NonNull Creator<PermissionGroupInfo> CREATOR =
+    public static final @NonNull Creator<PermissionGroupInfo> CREATOR =
             new Creator<PermissionGroupInfo>() {
         public PermissionGroupInfo createFromParcel(Parcel source) {
             return new PermissionGroupInfo(source);
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 72357ce..133e9f8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.pm;
 
+import static android.content.res.Resources.ID_NULL;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
@@ -454,7 +456,7 @@
         pkg.applicationInfo = new ApplicationInfo();
 
         pkg.permissions.add(new PackageParser.Permission(pkg));
-        pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg));
+        pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg, ID_NULL, ID_NULL, ID_NULL));
 
         final PackageParser.ParseComponentArgs dummy = new PackageParser.ParseComponentArgs(
                 pkg, new String[1], 0, 0, 0, 0, 0, 0, null, 0, 0, 0);