diff --git a/api/16.txt b/api/16.txt
index b8aeb392ae834..8a7ac008672da 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -754,7 +754,6 @@ package android {
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 = 16843688; // 0x10103a8
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
@@ -6596,11 +6595,8 @@ package android.content.pm {
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/api/current.txt b/api/current.txt
index b8aeb392ae834..8a7ac008672da 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -754,7 +754,6 @@ package android {
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 = 16843688; // 0x10103a8
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
@@ -6596,11 +6595,8 @@ package android.content.pm {
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 e180df435de06..679a8aceb54c4 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1464,8 +1464,7 @@ public class PackageParser {
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.flags = 0;
perm.info.priority = sa.getInt(
com.android.internal.R.styleable.AndroidManifestPermissionGroup_priority, 0);
if (perm.info.priority > 0 && (flags&PARSE_IS_SYSTEM) == 0) {
diff --git a/core/java/android/content/pm/PermissionGroupInfo.java b/core/java/android/content/pm/PermissionGroupInfo.java
index 452bf0d2b6a10..96d30d4113b1e 100644
--- a/core/java/android/content/pm/PermissionGroupInfo.java
+++ b/core/java/android/content/pm/PermissionGroupInfo.java
@@ -44,17 +44,20 @@ public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
/**
* Flag for {@link #flags}, corresponding to personalInfo
* value of {@link android.R.attr#permissionGroupFlags}.
+ * @hide
*/
public static final int FLAG_PERSONAL_INFO = 1<<0;
/**
* Additional flags about this group as given by
* {@link android.R.attr#permissionGroupFlags}.
+ * @hide
*/
public int flags;
/**
* Prioritization of this group, for visually sorting with other groups.
+ * @hide
*/
public int priority;
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 64f6c07f87a6a..988760db7028d 100755
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -18,9 +18,7 @@ package android.widget;
import com.android.internal.R;
-import android.app.AlertDialog;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -28,14 +26,9 @@ import android.content.pm.PackageParser;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.graphics.drawable.Drawable;
-import android.os.Parcel;
-import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
-import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import java.text.Collator;
import java.util.ArrayList;
@@ -43,6 +36,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -58,200 +52,52 @@ import java.util.Set;
*
* {@hide}
*/
-public class AppSecurityPermissions {
+public class AppSecurityPermissions implements View.OnClickListener {
- public static final int WHICH_PERSONAL = 1<<0;
- public static final int WHICH_DEVICE = 1<<1;
- public static final int WHICH_NEW = 1<<2;
- public static final int WHICH_ALL = 0xffff;
+ private enum State {
+ NO_PERMS,
+ DANGEROUS_ONLY,
+ NORMAL_ONLY,
+ BOTH
+ }
private final static String TAG = "AppSecurityPermissions";
private boolean localLOGV = false;
private Context mContext;
private LayoutInflater mInflater;
private PackageManager mPm;
- private PackageInfo mInstalledPackageInfo;
- private final Map mPermGroups
- = new HashMap();
- private final List mPermGroupsList
- = new ArrayList();
- private final PermissionGroupInfoComparator mPermGroupComparator;
- private final PermissionInfoComparator mPermComparator;
- private List mPermsList;
- private CharSequence mNewPermPrefix;
+ private LinearLayout mPermsView;
+ private Map mDangerousMap;
+ private Map mNormalMap;
+ private List mPermsList;
+ private String mDefaultGrpLabel;
+ private String mDefaultGrpName="DefaultGrp";
+ private String mPermFormat;
private Drawable mNormalIcon;
private Drawable mDangerousIcon;
-
- static class MyPermissionGroupInfo extends PermissionGroupInfo {
- CharSequence mLabel;
-
- final ArrayList mNewPermissions = new ArrayList();
- final ArrayList mPersonalPermissions = new ArrayList();
- final ArrayList mDevicePermissions = new ArrayList();
- final ArrayList mAllPermissions = new ArrayList();
-
- MyPermissionGroupInfo(PermissionInfo perm) {
- name = perm.packageName;
- packageName = perm.packageName;
- }
-
- MyPermissionGroupInfo(PermissionGroupInfo info) {
- super(info);
- }
-
- public Drawable loadGroupIcon(PackageManager pm) {
- if (icon != 0) {
- return loadIcon(pm);
- } else {
- ApplicationInfo appInfo;
- try {
- appInfo = pm.getApplicationInfo(packageName, 0);
- return appInfo.loadIcon(pm);
- } catch (NameNotFoundException e) {
- }
- }
- return null;
- }
- }
-
- static class MyPermissionInfo extends PermissionInfo {
- CharSequence mLabel;
-
- /**
- * PackageInfo.requestedPermissionsFlags for the new package being installed.
- */
- int mNewReqFlags;
-
- /**
- * PackageInfo.requestedPermissionsFlags for the currently installed
- * package, if it is installed.
- */
- int mExistingReqFlags;
-
- /**
- * True if this should be considered a new permission.
- */
- boolean mNew;
-
- MyPermissionInfo() {
- }
-
- MyPermissionInfo(PermissionInfo info) {
- super(info);
- }
-
- MyPermissionInfo(MyPermissionInfo info) {
- super(info);
- mNewReqFlags = info.mNewReqFlags;
- mExistingReqFlags = info.mExistingReqFlags;
- mNew = info.mNew;
- }
- }
-
- public static class PermissionItemView extends LinearLayout implements View.OnClickListener {
- MyPermissionGroupInfo mGroup;
- MyPermissionInfo mPerm;
- AlertDialog mDialog;
-
- public PermissionItemView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setClickable(true);
- }
-
- public void setPermission(MyPermissionGroupInfo grp, MyPermissionInfo perm,
- boolean first, CharSequence newPermPrefix) {
- mGroup = grp;
- mPerm = perm;
-
- ImageView permGrpIcon = (ImageView) findViewById(R.id.perm_icon);
- TextView permNameView = (TextView) findViewById(R.id.perm_name);
-
- PackageManager pm = getContext().getPackageManager();
- Drawable icon = null;
- if (first) {
- icon = grp.loadGroupIcon(pm);
- }
- CharSequence label = perm.mLabel;
- if (perm.mNew && newPermPrefix != null) {
- // If this is a new permission, format it appropriately.
- SpannableStringBuilder builder = new SpannableStringBuilder();
- Parcel parcel = Parcel.obtain();
- TextUtils.writeToParcel(newPermPrefix, parcel, 0);
- parcel.setDataPosition(0);
- CharSequence newStr = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
- parcel.recycle();
- builder.append(newStr);
- builder.append(label);
- label = builder;
- }
-
- permGrpIcon.setImageDrawable(icon);
- permNameView.setText(label);
- setOnClickListener(this);
- }
-
- @Override
- public void onClick(View v) {
- if (mGroup != null && mPerm != null) {
- if (mDialog != null) {
- mDialog.dismiss();
- }
- PackageManager pm = getContext().getPackageManager();
- AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
- builder.setTitle(mGroup.mLabel);
- if (mPerm.descriptionRes != 0) {
- builder.setMessage(mPerm.loadDescription(pm));
- } else {
- CharSequence appName;
- try {
- ApplicationInfo app = pm.getApplicationInfo(mPerm.packageName, 0);
- appName = app.loadLabel(pm);
- } catch (NameNotFoundException e) {
- appName = mPerm.packageName;
- }
- StringBuilder sbuilder = new StringBuilder(128);
- sbuilder.append(getContext().getString(
- R.string.perms_description_app, appName));
- sbuilder.append("\n\n");
- sbuilder.append(mPerm.name);
- builder.setMessage(sbuilder.toString());
- }
- builder.setCancelable(true);
- builder.setIcon(mGroup.loadGroupIcon(pm));
- mDialog = builder.show();
- mDialog.setCanceledOnTouchOutside(true);
- }
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- if (mDialog != null) {
- mDialog.dismiss();
- }
- }
- }
-
+ private boolean mExpanded;
+ private Drawable mShowMaxIcon;
+ private Drawable mShowMinIcon;
+ private View mShowMore;
+ private TextView mShowMoreText;
+ private ImageView mShowMoreIcon;
+ private State mCurrentState;
+ private LinearLayout mNonDangerousList;
+ private LinearLayout mDangerousList;
+ private HashMap mGroupLabelCache;
+ private View mNoPermsView;
+
public AppSecurityPermissions(Context context, List permList) {
mContext = context;
mPm = mContext.getPackageManager();
- loadResources();
- mPermComparator = new PermissionInfoComparator();
- mPermGroupComparator = new PermissionGroupInfoComparator();
- for (PermissionInfo pi : permList) {
- mPermsList.add(new MyPermissionInfo(pi));
- }
- setPermissions(mPermsList);
+ mPermsList = permList;
}
public AppSecurityPermissions(Context context, String packageName) {
mContext = context;
mPm = mContext.getPackageManager();
- loadResources();
- mPermComparator = new PermissionInfoComparator();
- mPermGroupComparator = new PermissionGroupInfoComparator();
- mPermsList = new ArrayList();
- Set permSet = new HashSet();
+ mPermsList = new ArrayList();
+ Set permSet = new HashSet();
PackageInfo pkgInfo;
try {
pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
@@ -263,39 +109,29 @@ public class AppSecurityPermissions {
if((pkgInfo.applicationInfo != null) && (pkgInfo.applicationInfo.uid != -1)) {
getAllUsedPermissions(pkgInfo.applicationInfo.uid, permSet);
}
- for(MyPermissionInfo tmpInfo : permSet) {
+ for(PermissionInfo tmpInfo : permSet) {
mPermsList.add(tmpInfo);
}
- setPermissions(mPermsList);
}
-
+
public AppSecurityPermissions(Context context, PackageParser.Package pkg) {
mContext = context;
mPm = mContext.getPackageManager();
- loadResources();
- mPermComparator = new PermissionInfoComparator();
- mPermGroupComparator = new PermissionGroupInfoComparator();
- mPermsList = new ArrayList();
- Set permSet = new HashSet();
+ mPermsList = new ArrayList();
+ Set permSet = new HashSet();
if(pkg == null) {
return;
}
-
- // Convert to a PackageInfo
- PackageInfo info = PackageParser.generatePackageInfo(pkg, null,
- PackageManager.GET_PERMISSIONS, 0, 0, null);
- PackageInfo installedPkgInfo = null;
// Get requested permissions
- if (info.requestedPermissions != null) {
- try {
- installedPkgInfo = mPm.getPackageInfo(info.packageName,
- PackageManager.GET_PERMISSIONS);
- } catch (NameNotFoundException e) {
+ if (pkg.requestedPermissions != null) {
+ ArrayList strList = pkg.requestedPermissions;
+ int size = strList.size();
+ if (size > 0) {
+ extractPerms(strList.toArray(new String[size]), permSet);
}
- extractPerms(info, permSet, installedPkgInfo);
}
// Get permissions related to shared user if any
- if (pkg.mSharedUserId != null) {
+ if(pkg.mSharedUserId != null) {
int sharedUid;
try {
sharedUid = mPm.getUidForSharedUser(pkg.mSharedUserId);
@@ -305,23 +141,13 @@ public class AppSecurityPermissions {
}
}
// Retrieve list of permissions
- for (MyPermissionInfo tmpInfo : permSet) {
+ for(PermissionInfo tmpInfo : permSet) {
mPermsList.add(tmpInfo);
}
- setPermissions(mPermsList);
}
-
- private void loadResources() {
- // Pick up from framework resources instead.
- mNewPermPrefix = mContext.getText(R.string.perms_new_perm_prefix);
- mNormalIcon = mContext.getResources().getDrawable(R.drawable.ic_text_dot);
- mDangerousIcon = mContext.getResources().getDrawable(R.drawable.ic_bullet_key_permission);
- }
-
+
/**
- * Utility to retrieve a view displaying a single permission. This provides
- * the old UI layout for permissions; it is only here for the device admin
- * settings to continue to use.
+ * Utility to retrieve a view displaying a single permission.
*/
public static View getPermissionItemView(Context context,
CharSequence grpName, CharSequence description, boolean dangerous) {
@@ -329,15 +155,11 @@ public class AppSecurityPermissions {
Context.LAYOUT_INFLATER_SERVICE);
Drawable icon = context.getResources().getDrawable(dangerous
? R.drawable.ic_bullet_key_permission : R.drawable.ic_text_dot);
- return getPermissionItemViewOld(context, inflater, grpName,
+ return getPermissionItemView(context, inflater, grpName,
description, dangerous, icon);
}
- public PackageInfo getInstalledPackageInfo() {
- return mInstalledPackageInfo;
- }
-
- private void getAllUsedPermissions(int sharedUid, Set permSet) {
+ private void getAllUsedPermissions(int sharedUid, Set permSet) {
String sharedPkgList[] = mPm.getPackagesForUid(sharedUid);
if(sharedPkgList == null || (sharedPkgList.length == 0)) {
return;
@@ -348,95 +170,29 @@ public class AppSecurityPermissions {
}
private void getPermissionsForPackage(String packageName,
- Set permSet) {
+ Set permSet) {
PackageInfo pkgInfo;
try {
pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
} catch (NameNotFoundException e) {
- Log.w(TAG, "Couldn't retrieve permissions for package:"+packageName);
+ Log.w(TAG, "Could'nt retrieve permissions for package:"+packageName);
return;
}
if ((pkgInfo != null) && (pkgInfo.requestedPermissions != null)) {
- extractPerms(pkgInfo, permSet, pkgInfo);
+ extractPerms(pkgInfo.requestedPermissions, permSet);
}
}
-
- private void extractPerms(PackageInfo info, Set permSet,
- PackageInfo installedPkgInfo) {
- String[] strList = info.requestedPermissions;
- int[] flagsList = info.requestedPermissionsFlags;
- if ((strList == null) || (strList.length == 0)) {
+
+ private void extractPerms(String strList[], Set permSet) {
+ if((strList == null) || (strList.length == 0)) {
return;
}
- mInstalledPackageInfo = installedPkgInfo;
- for (int i=0; i= 0 ?
- installedPkgInfo.requestedPermissionsFlags[existingIndex] : 0;
- if (!isDisplayablePermission(tmpPermInfo, flagsList[i], existingFlags)) {
- // This is not a permission that is interesting for the user
- // to see, so skip it.
- continue;
- }
- final String origGroupName = tmpPermInfo.group;
- String groupName = origGroupName;
- if (groupName == null) {
- groupName = tmpPermInfo.packageName;
- tmpPermInfo.group = groupName;
- }
- MyPermissionGroupInfo group = mPermGroups.get(groupName);
- if (group == null) {
- PermissionGroupInfo grp = null;
- if (origGroupName != null) {
- grp = mPm.getPermissionGroupInfo(origGroupName, 0);
- }
- if (grp != null) {
- group = new MyPermissionGroupInfo(grp);
- } else {
- // We could be here either because the permission
- // didn't originally specify a group or the group it
- // gave couldn't be found. In either case, we consider
- // its group to be the permission's package name.
- tmpPermInfo.group = tmpPermInfo.packageName;
- group = mPermGroups.get(tmpPermInfo.group);
- if (group == null) {
- group = new MyPermissionGroupInfo(tmpPermInfo);
- }
- group = new MyPermissionGroupInfo(tmpPermInfo);
- }
- mPermGroups.put(tmpPermInfo.group, group);
- }
- final boolean newPerm = installedPkgInfo != null
- && (existingFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0;
- MyPermissionInfo myPerm = new MyPermissionInfo(tmpPermInfo);
- myPerm.mNewReqFlags = flagsList[i];
- myPerm.mExistingReqFlags = existingFlags;
- // This is a new permission if the app is already installed and
- // doesn't currently hold this permission.
- myPerm.mNew = newPerm;
- permSet.add(myPerm);
} catch (NameNotFoundException e) {
Log.i(TAG, "Ignoring unknown permission:"+permName);
}
@@ -444,99 +200,131 @@ public class AppSecurityPermissions {
}
public int getPermissionCount() {
- return getPermissionCount(WHICH_ALL);
- }
-
- private List getPermissionList(MyPermissionGroupInfo grp, int which) {
- if (which == WHICH_NEW) {
- return grp.mNewPermissions;
- } else if (which == WHICH_PERSONAL) {
- return grp.mPersonalPermissions;
- } else if (which == WHICH_DEVICE) {
- return grp.mDevicePermissions;
- } else {
- return grp.mAllPermissions;
- }
- }
-
- public int getPermissionCount(int which) {
- int N = 0;
- for (int i=0; i groups,
- LinearLayout permListView, int which) {
+ private void displayPermissions(boolean dangerous) {
+ Map permInfoMap = dangerous ? mDangerousMap : mNormalMap;
+ LinearLayout permListView = dangerous ? mDangerousList : mNonDangerousList;
permListView.removeAllViews();
- int spacing = (int)(8*mContext.getResources().getDisplayMetrics().density);
-
- for (int i=0; i perms = getPermissionList(grp, which);
- for (int j=0; j permInfoStrSet = permInfoMap.keySet();
+ for (String loopPermGrpInfoStr : permInfoStrSet) {
+ CharSequence grpLabel = getGroupLabel(loopPermGrpInfoStr);
+ //guaranteed that grpLabel wont be null since permissions without groups
+ //will belong to the default group
+ if(localLOGV) Log.i(TAG, "Adding view group:" + grpLabel + ", desc:"
+ + permInfoMap.get(loopPermGrpInfoStr));
+ permListView.addView(getPermissionItemView(grpLabel,
+ permInfoMap.get(loopPermGrpInfoStr), dangerous));
}
}
- private PermissionItemView getPermissionItemView(MyPermissionGroupInfo grp,
- MyPermissionInfo perm, boolean first, CharSequence newPermPrefix) {
- return getPermissionItemView(mContext, mInflater, grp, perm, first, newPermPrefix);
+ private void displayNoPermissions() {
+ mNoPermsView.setVisibility(View.VISIBLE);
}
- private static PermissionItemView getPermissionItemView(Context context, LayoutInflater inflater,
- MyPermissionGroupInfo grp, MyPermissionInfo perm, boolean first,
- CharSequence newPermPrefix) {
- PermissionItemView permView = (PermissionItemView)inflater.inflate(
- R.layout.app_permission_item, null);
- permView.setPermission(grp, perm, first, newPermPrefix);
- return permView;
+ private View getPermissionItemView(CharSequence grpName, CharSequence permList,
+ boolean dangerous) {
+ return getPermissionItemView(mContext, mInflater, grpName, permList,
+ dangerous, dangerous ? mDangerousIcon : mNormalIcon);
}
- private static View getPermissionItemViewOld(Context context, LayoutInflater inflater,
+ private static View getPermissionItemView(Context context, LayoutInflater inflater,
CharSequence grpName, CharSequence permList, boolean dangerous, Drawable icon) {
- View permView = inflater.inflate(R.layout.app_permission_item_old, null);
+ View permView = inflater.inflate(R.layout.app_permission_item, null);
TextView permGrpView = (TextView) permView.findViewById(R.id.permission_group);
TextView permDescView = (TextView) permView.findViewById(R.id.permission_list);
@@ -553,107 +341,159 @@ public class AppSecurityPermissions {
return permView;
}
- private boolean isDisplayablePermission(PermissionInfo pInfo, int newReqFlags,
- int existingReqFlags) {
- final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
- // Dangerous and normal permissions are always shown to the user.
- if (base == PermissionInfo.PROTECTION_DANGEROUS ||
- base == PermissionInfo.PROTECTION_NORMAL) {
- return true;
+ private void showPermissions() {
+
+ switch(mCurrentState) {
+ case NO_PERMS:
+ displayNoPermissions();
+ break;
+
+ case DANGEROUS_ONLY:
+ displayPermissions(true);
+ break;
+
+ case NORMAL_ONLY:
+ displayPermissions(false);
+ break;
+
+ case BOTH:
+ displayPermissions(true);
+ if (mExpanded) {
+ displayPermissions(false);
+ mShowMoreIcon.setImageDrawable(mShowMaxIcon);
+ mShowMoreText.setText(R.string.perms_hide);
+ mNonDangerousList.setVisibility(View.VISIBLE);
+ } else {
+ mShowMoreIcon.setImageDrawable(mShowMinIcon);
+ mShowMoreText.setText(R.string.perms_show_all);
+ mNonDangerousList.setVisibility(View.GONE);
+ }
+ mShowMore.setVisibility(View.VISIBLE);
+ break;
}
- // Development permissions are only shown to the user if they are already
- // granted to the app -- if we are installing an app and they are not
- // already granted, they will not be granted as part of the install.
- if ((existingReqFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0
- && (pInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
+ }
+
+ private boolean isDisplayablePermission(PermissionInfo pInfo) {
+ if(pInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS ||
+ pInfo.protectionLevel == PermissionInfo.PROTECTION_NORMAL) {
return true;
}
return false;
}
- private static class PermissionGroupInfoComparator implements Comparator {
- private final Collator sCollator = Collator.getInstance();
- PermissionGroupInfoComparator() {
+ /*
+ * Utility method that aggregates all permission descriptions categorized by group
+ * Say group1 has perm11, perm12, perm13, the group description will be
+ * perm11_Desc, perm12_Desc, perm13_Desc
+ */
+ private void aggregateGroupDescs(
+ Map > map, Map retMap) {
+ if(map == null) {
+ return;
}
- public final int compare(MyPermissionGroupInfo a, MyPermissionGroupInfo b) {
- if (((a.flags^b.flags)&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) {
- return ((a.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) ? -1 : 1;
+ if(retMap == null) {
+ return;
+ }
+ Set grpNames = map.keySet();
+ Iterator grpNamesIter = grpNames.iterator();
+ while(grpNamesIter.hasNext()) {
+ String grpDesc = null;
+ String grpNameKey = grpNamesIter.next();
+ List grpPermsList = map.get(grpNameKey);
+ if(grpPermsList == null) {
+ continue;
}
- if (a.priority != b.priority) {
- return a.priority > b.priority ? -1 : 1;
+ for(PermissionInfo permInfo: grpPermsList) {
+ CharSequence permDesc = permInfo.loadLabel(mPm);
+ grpDesc = formatPermissions(grpDesc, permDesc);
+ }
+ // Insert grpDesc into map
+ if(grpDesc != null) {
+ if(localLOGV) Log.i(TAG, "Group:"+grpNameKey+" description:"+grpDesc.toString());
+ retMap.put(grpNameKey, grpDesc.toString());
}
- return sCollator.compare(a.mLabel, b.mLabel);
}
}
- private static class PermissionInfoComparator implements Comparator {
+ private static class PermissionInfoComparator implements Comparator {
+ private PackageManager mPm;
private final Collator sCollator = Collator.getInstance();
- PermissionInfoComparator() {
+ PermissionInfoComparator(PackageManager pm) {
+ mPm = pm;
}
- public final int compare(MyPermissionInfo a, MyPermissionInfo b) {
- return sCollator.compare(a.mLabel, b.mLabel);
+ public final int compare(PermissionInfo a, PermissionInfo b) {
+ CharSequence sa = a.loadLabel(mPm);
+ CharSequence sb = b.loadLabel(mPm);
+ return sCollator.compare(sa, sb);
}
}
-
- private void addPermToList(List permList,
- MyPermissionInfo pInfo) {
- if (pInfo.mLabel == null) {
- pInfo.mLabel = pInfo.loadLabel(mPm);
- }
- int idx = Collections.binarySearch(permList, pInfo, mPermComparator);
- if(localLOGV) Log.i(TAG, "idx="+idx+", list.size="+permList.size());
- if (idx < 0) {
- idx = -idx-1;
- permList.add(idx, pInfo);
- }
- }
-
- private void setPermissions(List permList) {
+
+ private void setPermissions(List permList) {
+ mGroupLabelCache = new HashMap();
+ //add the default label so that uncategorized permissions can go here
+ mGroupLabelCache.put(mDefaultGrpName, mDefaultGrpLabel);
+
+ // Map containing group names and a list of permissions under that group
+ // categorized as dangerous
+ mDangerousMap = new HashMap();
+ // Map containing group names and a list of permissions under that group
+ // categorized as normal
+ mNormalMap = new HashMap();
+
+ // Additional structures needed to ensure that permissions are unique under
+ // each group
+ Map> dangerousMap =
+ new HashMap>();
+ Map > normalMap =
+ new HashMap>();
+ PermissionInfoComparator permComparator = new PermissionInfoComparator(mPm);
+
if (permList != null) {
// First pass to group permissions
- for (MyPermissionInfo pInfo : permList) {
+ for (PermissionInfo pInfo : permList) {
if(localLOGV) Log.i(TAG, "Processing permission:"+pInfo.name);
- if(!isDisplayablePermission(pInfo, pInfo.mNewReqFlags, pInfo.mExistingReqFlags)) {
+ if(!isDisplayablePermission(pInfo)) {
if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" is not displayable");
continue;
}
- MyPermissionGroupInfo group = mPermGroups.get(pInfo.group);
- if (group != null) {
- pInfo.mLabel = pInfo.loadLabel(mPm);
- addPermToList(group.mAllPermissions, pInfo);
- if (pInfo.mNew) {
- addPermToList(group.mNewPermissions, pInfo);
- }
- if ((group.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) {
- addPermToList(group.mPersonalPermissions, pInfo);
- } else {
- addPermToList(group.mDevicePermissions, pInfo);
+ Map > permInfoMap =
+ (pInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) ?
+ dangerousMap : normalMap;
+ String grpName = (pInfo.group == null) ? mDefaultGrpName : pInfo.group;
+ if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" belongs to group:"+grpName);
+ List grpPermsList = permInfoMap.get(grpName);
+ if(grpPermsList == null) {
+ grpPermsList = new ArrayList();
+ permInfoMap.put(grpName, grpPermsList);
+ grpPermsList.add(pInfo);
+ } else {
+ int idx = Collections.binarySearch(grpPermsList, pInfo, permComparator);
+ if(localLOGV) Log.i(TAG, "idx="+idx+", list.size="+grpPermsList.size());
+ if (idx < 0) {
+ idx = -idx-1;
+ grpPermsList.add(idx, pInfo);
}
}
}
+ // Second pass to actually form the descriptions
+ // Look at dangerous permissions first
+ aggregateGroupDescs(dangerousMap, mDangerousMap);
+ aggregateGroupDescs(normalMap, mNormalMap);
}
- for (MyPermissionGroupInfo pgrp : mPermGroups.values()) {
- if (pgrp.labelRes != 0 || pgrp.nonLocalizedLabel != null) {
- pgrp.mLabel = pgrp.loadLabel(mPm);
- } else {
- ApplicationInfo app;
- try {
- app = mPm.getApplicationInfo(pgrp.packageName, 0);
- pgrp.mLabel = app.loadLabel(mPm);
- } catch (NameNotFoundException e) {
- pgrp.mLabel = pgrp.loadLabel(mPm);
- }
- }
- mPermGroupsList.add(pgrp);
- }
- Collections.sort(mPermGroupsList, mPermGroupComparator);
- if (false) {
- for (MyPermissionGroupInfo grp : mPermGroupsList) {
- Log.i("foo", "Group " + grp.name + " personal="
- + ((grp.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0)
- + " priority=" + grp.priority);
- }
+ mCurrentState = State.NO_PERMS;
+ if(mDangerousMap.size() > 0) {
+ mCurrentState = (mNormalMap.size() > 0) ? State.BOTH : State.DANGEROUS_ONLY;
+ } else if(mNormalMap.size() > 0) {
+ mCurrentState = State.NORMAL_ONLY;
}
+ if(localLOGV) Log.i(TAG, "mCurrentState=" + mCurrentState);
+ showPermissions();
+ }
+
+ public void onClick(View v) {
+ if(localLOGV) Log.i(TAG, "mExpanded="+mExpanded);
+ mExpanded = !mExpanded;
+ showPermissions();
}
}
diff --git a/core/res/res/layout/app_permission_item.xml b/core/res/res/layout/app_permission_item.xml
index c448bd1dbaef5..1bd267f43cb43 100644
--- a/core/res/res/layout/app_permission_item.xml
+++ b/core/res/res/layout/app_permission_item.xml
@@ -19,33 +19,37 @@
Contains the group name and a list of permission labels under the group.
-->
-
+ android:layout_height="wrap_content">
-
+ android:layout_height="wrap_content" />
-
+
+
+
diff --git a/core/res/res/layout/app_perms_summary.xml b/core/res/res/layout/app_perms_summary.xml
index 509c502770f79..3f99dde59397c 100755
--- a/core/res/res/layout/app_perms_summary.xml
+++ b/core/res/res/layout/app_perms_summary.xml
@@ -26,17 +26,79 @@
android:id="@+id/no_permissions"
android:text="@string/no_permissions"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
+ android:paddingLeft="16dip"
+ android:paddingRight="12dip"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f24733cb3ebd6..f971d390719db 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -199,7 +199,7 @@
-
+
Done
-
+
+
+ Default
+
+ %1$s, %2$s
+
+ No permissions required
+
+ Hide
+
+ Show all
+
+
NEW:
Provided by %1$s.
-
- No permissions required