Merge "Add new APIs for permission group flags and priorities." into jb-dev
diff --git a/api/current.txt b/api/current.txt
index 81abd5f..419a977 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -88,6 +88,7 @@
     field public static final java.lang.String READ_SOCIAL_STREAM = "android.permission.READ_SOCIAL_STREAM";
     field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
     field public static final java.lang.String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS";
+    field public static final java.lang.String READ_USER_DICTIONARY = "android.permission.READ_USER_DICTIONARY";
     field public static final java.lang.String REBOOT = "android.permission.REBOOT";
     field public static final java.lang.String RECEIVE_BOOT_COMPLETED = "android.permission.RECEIVE_BOOT_COMPLETED";
     field public static final java.lang.String RECEIVE_MMS = "android.permission.RECEIVE_MMS";
@@ -134,6 +135,7 @@
     field public static final java.lang.String WRITE_SMS = "android.permission.WRITE_SMS";
     field public static final java.lang.String WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM";
     field public static final java.lang.String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS";
+    field public static final java.lang.String WRITE_USER_DICTIONARY = "android.permission.WRITE_USER_DICTIONARY";
   }
 
   public static final class Manifest.permission_group {
@@ -738,6 +740,7 @@
     field public static final int pathPrefix = 16842795; // 0x101002b
     field public static final int permission = 16842758; // 0x1010006
     field public static final int permissionGroup = 16842762; // 0x101000a
+    field public static final int permissionGroupFlags = 16843700; // 0x10103b4
     field public static final int persistent = 16842765; // 0x101000d
     field public static final int persistentDrawingCache = 16842990; // 0x10100ee
     field public static final deprecated int phoneNumber = 16843111; // 0x1010167
@@ -6577,8 +6580,11 @@
     method public int describeContents();
     method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
     field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int FLAG_PERSONAL_INFO = 1; // 0x1
     field public int descriptionRes;
+    field public int flags;
     field public java.lang.CharSequence nonLocalizedDescription;
+    field public int priority;
   }
 
   public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 185fcb9..98b40eb 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -970,7 +970,7 @@
                     return null;
                 }
             } else if (tagName.equals("permission-group")) {
-                if (parsePermissionGroup(pkg, res, parser, attrs, outError) == null) {
+                if (parsePermissionGroup(pkg, flags, res, parser, attrs, outError) == null) {
                     return null;
                 }
             } else if (tagName.equals("permission")) {
@@ -1432,7 +1432,7 @@
         return buildCompoundName(pkg, procSeq, "taskAffinity", outError);
     }
     
-    private PermissionGroup parsePermissionGroup(Package owner, Resources res,
+    private PermissionGroup parsePermissionGroup(Package owner, int flags, Resources res,
             XmlPullParser parser, AttributeSet attrs, String[] outError)
         throws XmlPullParserException, IOException {
         PermissionGroup perm = new PermissionGroup(owner);
@@ -1454,6 +1454,13 @@
         perm.info.descriptionRes = sa.getResourceId(
                 com.android.internal.R.styleable.AndroidManifestPermissionGroup_description,
                 0);
+        perm.info.flags = sa.getInt(
+                com.android.internal.R.styleable.AndroidManifestPermissionGroup_permissionGroupFlags, 0);
+        perm.info.priority = sa.getInt(
+                com.android.internal.R.styleable.AndroidManifestPermissionGroup_priority, 0);
+        if (perm.info.priority > 0 && (flags&PARSE_IS_SYSTEM) != 0) {
+            perm.info.priority = 0;
+        }
 
         sa.recycle();
         
diff --git a/core/java/android/content/pm/PermissionGroupInfo.java b/core/java/android/content/pm/PermissionGroupInfo.java
index 02eb816..452bf0d 100644
--- a/core/java/android/content/pm/PermissionGroupInfo.java
+++ b/core/java/android/content/pm/PermissionGroupInfo.java
@@ -41,6 +41,23 @@
      */
     public CharSequence nonLocalizedDescription;
 
+    /**
+     * Flag for {@link #flags}, corresponding to <code>personalInfo</code>
+     * value of {@link android.R.attr#permissionGroupFlags}.
+     */
+    public static final int FLAG_PERSONAL_INFO = 1<<0;
+
+    /**
+     * Additional flags about this group as given by
+     * {@link android.R.attr#permissionGroupFlags}.
+     */
+    public int flags;
+
+    /**
+     * Prioritization of this group, for visually sorting with other groups.
+     */
+    public int priority;
+
     public PermissionGroupInfo() {
     }
 
@@ -48,6 +65,8 @@
         super(orig);
         descriptionRes = orig.descriptionRes;
         nonLocalizedDescription = orig.nonLocalizedDescription;
+        flags = orig.flags;
+        priority = orig.priority;
     }
 
     /**
@@ -77,7 +96,7 @@
     public String toString() {
         return "PermissionGroupInfo{"
             + Integer.toHexString(System.identityHashCode(this))
-            + " " + name + "}";
+            + " " + name + " flgs=0x" + Integer.toHexString(flags) + "}";
     }
 
     public int describeContents() {
@@ -88,6 +107,8 @@
         super.writeToParcel(dest, parcelableFlags);
         dest.writeInt(descriptionRes);
         TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags);
+        dest.writeInt(flags);
+        dest.writeInt(priority);
     }
 
     public static final Creator<PermissionGroupInfo> CREATOR =
@@ -104,5 +125,7 @@
         super(source);
         descriptionRes = source.readInt();
         nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+        flags = source.readInt();
+        priority = source.readInt();
     }
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 471a496..e1eaf41 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -258,7 +258,8 @@
          expressed as two distinct permissions). -->
     <permission-group android:name="android.permission-group.PERSONAL_INFO"
         android:label="@string/permgrouplab_personalInfo"
-        android:description="@string/permgroupdesc_personalInfo" />
+        android:description="@string/permgroupdesc_personalInfo"
+        android:permissionGroupFlags="personalInfo" />
 
     <!-- Allows an application to read the user's contacts data. -->
     <permission android:name="android.permission.READ_CONTACTS"
@@ -338,16 +339,14 @@
 
     <!-- Allows an application to read the user dictionary. This should
          really only be required by an IME, or a dictionary editor like
-         the Settings app.
-         @hide Pending API council approval -->
+         the Settings app. -->
     <permission android:name="android.permission.READ_USER_DICTIONARY"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
         android:protectionLevel="dangerous"
         android:label="@string/permlab_readDictionary"
         android:description="@string/permdesc_readDictionary" />
 
-    <!-- Allows an application to write to the user dictionary.
-         @hide Pending API council approval -->
+    <!-- Allows an application to write to the user dictionary. -->
     <permission android:name="android.permission.WRITE_USER_DICTIONARY"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
         android:protectionLevel="normal"
@@ -793,7 +792,7 @@
          as locale. -->
     <permission android:name="android.permission.CHANGE_CONFIGURATION"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-        android:protectionLevel="dangerous"
+        android:protectionLevel="signature|system|development"
         android:label="@string/permlab_changeConfiguration"
         android:description="@string/permdesc_changeConfiguration" />
 
@@ -844,7 +843,7 @@
     <!-- Modify the global animation scaling factor. -->
     <permission android:name="android.permission.SET_ANIMATION_SCALE"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-        android:protectionLevel="dangerous"
+        android:protectionLevel="signature|system|development"
         android:label="@string/permlab_setAnimationScale"
         android:description="@string/permdesc_setAnimationScale" />
 
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 0ac2ad74..b677513 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -198,7 +198,15 @@
              (optionally) be granted to development applications. -->
         <flag name="development" value="0x20" />
     </attr>
-    
+
+    <!-- Flags indicating more context for a permission group. -->
+    <attr name="permissionGroupFlags">
+        <!-- Set to indicate that this permission group contains permissions
+             protecting access to some information that is considered
+             personal to the user (such as contacts, e-mails, etc). -->
+        <flag name="personalInfo" value="0x0001" />
+    </attr>
+
     <!-- Specified the name of a group that this permission is associated
          with.  The group must have been defined with the
          {@link android.R.styleable#AndroidManifestPermissionGroup permission-group} tag. -->
@@ -895,6 +903,8 @@
         <attr name="icon" />
         <attr name="logo" />
         <attr name="description" />
+        <attr name="permissionGroupFlags" />
+        <attr name="priority" />
     </declare-styleable>
     
     <!-- The <code>permission-tree</code> tag declares the base of a tree of
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 14584df..2d29d06 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3611,4 +3611,6 @@
   <public type="attr" name="importantForAccessibility"/>
   <public type="attr" name="canHandleGestures"/>
 
+  <public type="attr" name="permissionGroupFlags"/>
+
 </resources>