summaryrefslogtreecommitdiffstats
path: root/core/java/android/widget/AppSecurityPermissions.java
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:43 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:43 -0800
commitf013e1afd1e68af5e3b868c26a653bbfb39538f8 (patch)
tree7ad6c8fd9c7b55f4b4017171dec1cb760bbd26bf /core/java/android/widget/AppSecurityPermissions.java
parente70cfafe580c6f2994c4827cd8a534aabf3eb05c (diff)
downloadframeworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.zip
frameworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.tar.gz
frameworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'core/java/android/widget/AppSecurityPermissions.java')
-rwxr-xr-xcore/java/android/widget/AppSecurityPermissions.java347
1 files changed, 234 insertions, 113 deletions
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 582117f..5fa00e7 100755
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -18,7 +18,6 @@ package android.widget;
import com.android.internal.R;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
@@ -31,9 +30,17 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
+
import java.io.File;
+import java.text.Collator;
import java.util.ArrayList;
+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;
/**
@@ -56,15 +63,15 @@ public class AppSecurityPermissions implements View.OnClickListener {
BOTH
}
- private final String TAG = "AppSecurityPermissions";
+ private final static String TAG = "AppSecurityPermissions";
private boolean localLOGV = false;
private Context mContext;
private LayoutInflater mInflater;
private PackageManager mPm;
private LinearLayout mPermsView;
- private HashMap<String, String> mDangerousMap;
- private HashMap<String, String> mNormalMap;
- private ArrayList<PermissionInfo> mPermsList;
+ private Map<String, String> mDangerousMap;
+ private Map<String, String> mNormalMap;
+ private List<PermissionInfo> mPermsList;
private String mDefaultGrpLabel;
private String mDefaultGrpName="DefaultGrp";
private String mPermFormat;
@@ -79,18 +86,129 @@ public class AppSecurityPermissions implements View.OnClickListener {
private State mCurrentState;
private LinearLayout mNonDangerousList;
private LinearLayout mDangerousList;
- private HashMap<String, String> mGroupLabelCache;
+ private HashMap<String, CharSequence> mGroupLabelCache;
private View mNoPermsView;
-
- public AppSecurityPermissions(Context context) {
- this(context, null);
- }
-
- public AppSecurityPermissions(Context context, ArrayList<PermissionInfo> permList) {
+
+ public AppSecurityPermissions(Context context, List<PermissionInfo> permList) {
mContext = context;
- mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mPm = context.getPackageManager();
+ mPm = mContext.getPackageManager();
mPermsList = permList;
+ }
+
+ public AppSecurityPermissions(Context context, String packageName) {
+ mContext = context;
+ mPm = mContext.getPackageManager();
+ mPermsList = new ArrayList<PermissionInfo>();
+ Set<PermissionInfo> permSet = new HashSet<PermissionInfo>();
+ PackageInfo pkgInfo;
+ try {
+ pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Could'nt retrieve permissions for package:"+packageName);
+ return;
+ }
+ // Extract all user permissions
+ if((pkgInfo.applicationInfo != null) && (pkgInfo.applicationInfo.uid != -1)) {
+ getAllUsedPermissions(pkgInfo.applicationInfo.uid, permSet);
+ }
+ for(PermissionInfo tmpInfo : permSet) {
+ mPermsList.add(tmpInfo);
+ }
+ }
+
+ public AppSecurityPermissions(Context context, PackageParser.Package pkg) {
+ mContext = context;
+ mPm = mContext.getPackageManager();
+ mPermsList = new ArrayList<PermissionInfo>();
+ Set<PermissionInfo> permSet = new HashSet<PermissionInfo>();
+ if(pkg == null) {
+ return;
+ }
+ // Extract shared user permissions if any
+ if(pkg.mSharedUserId != null) {
+ int sharedUid;
+ try {
+ sharedUid = mPm.getUidForSharedUser(pkg.mSharedUserId);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Could'nt retrieve shared user id for:"+pkg.packageName);
+ return;
+ }
+ getAllUsedPermissions(sharedUid, permSet);
+ } else {
+ ArrayList<String> strList = pkg.requestedPermissions;
+ int size;
+ if((strList == null) || ((size = strList.size()) == 0)) {
+ return;
+ }
+ // Extract permissions defined in current package
+ extractPerms(strList.toArray(new String[size]), permSet);
+ }
+ for(PermissionInfo tmpInfo : permSet) {
+ mPermsList.add(tmpInfo);
+ }
+ }
+
+ public PackageParser.Package getPackageInfo(Uri packageURI) {
+ final String archiveFilePath = packageURI.getPath();
+ PackageParser packageParser = new PackageParser(archiveFilePath);
+ File sourceFile = new File(archiveFilePath);
+ DisplayMetrics metrics = new DisplayMetrics();
+ metrics.setToDefaults();
+ return packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);
+ }
+
+ private void getAllUsedPermissions(int sharedUid, Set<PermissionInfo> permSet) {
+ String sharedPkgList[] = mPm.getPackagesForUid(sharedUid);
+ if(sharedPkgList == null || (sharedPkgList.length == 0)) {
+ return;
+ }
+ for(String sharedPkg : sharedPkgList) {
+ getPermissionsForPackage(sharedPkg, permSet);
+ }
+ }
+
+ private void getPermissionsForPackage(String packageName,
+ Set<PermissionInfo> permSet) {
+ PackageInfo pkgInfo;
+ try {
+ pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Could'nt retrieve permissions for package:"+packageName);
+ return;
+ }
+ if(pkgInfo == null) {
+ return;
+ }
+ String strList[] = pkgInfo.requestedPermissions;
+ if(strList == null) {
+ return;
+ }
+ extractPerms(strList, permSet);
+ }
+
+ private void extractPerms(String strList[], Set<PermissionInfo> permSet) {
+ if((strList == null) || (strList.length == 0)) {
+ return;
+ }
+ for(String permName:strList) {
+ try {
+ PermissionInfo tmpPermInfo = mPm.getPermissionInfo(permName, 0);
+ if(tmpPermInfo != null) {
+ permSet.add(tmpPermInfo);
+ }
+ } catch (NameNotFoundException e) {
+ Log.i(TAG, "Ignoring unknown permission:"+permName);
+ }
+ }
+ }
+
+ public int getPermissionCount() {
+ return mPermsList.size();
+ }
+
+ public View getPermissionsView() {
+
+ mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mPermsView = (LinearLayout) mInflater.inflate(R.layout.app_perms_summary, null);
mShowMore = mPermsView.findViewById(R.id.show_more);
mShowMoreIcon = (ImageView) mShowMore.findViewById(R.id.show_more_icon);
@@ -112,32 +230,9 @@ public class AppSecurityPermissions implements View.OnClickListener {
mDangerousIcon = mContext.getResources().getDrawable(R.drawable.ic_bullet_key_permission);
mShowMaxIcon = mContext.getResources().getDrawable(R.drawable.expander_ic_maximized);
mShowMinIcon = mContext.getResources().getDrawable(R.drawable.expander_ic_minimized);
- }
-
- public void setSecurityPermissionsView() {
- setPermissions(mPermsList);
- }
-
- public void setSecurityPermissionsView(Uri pkgURI) {
- final String archiveFilePath = pkgURI.getPath();
- PackageParser packageParser = new PackageParser(archiveFilePath);
- File sourceFile = new File(archiveFilePath);
- DisplayMetrics metrics = new DisplayMetrics();
- metrics.setToDefaults();
- PackageParser.Package pkgInfo = packageParser.parsePackage(sourceFile,
- archiveFilePath, metrics, 0);
- mPermsList = generatePermissionsInfo(pkgInfo.requestedPermissions);
- //For packages that havent been installed we need the application info object
- //to load the labels and other resources.
- setPermissions(mPermsList, pkgInfo.applicationInfo);
- }
-
- public void setSecurityPermissionsView(PackageInfo pInfo) {
- mPermsList = generatePermissionsInfo(pInfo.requestedPermissions);
+
+ // Set permissions view
setPermissions(mPermsList);
- }
-
- public View getPermissionsView() {
return mPermsView;
}
@@ -164,74 +259,30 @@ public class AppSecurityPermissions implements View.OnClickListener {
* is null the other non null value is returned without formatting
* this is to placate initial error checks
*/
- private String formatPermissions(String groupDesc, String permDesc) {
+ private String formatPermissions(String groupDesc, CharSequence permDesc) {
if(groupDesc == null) {
- return permDesc;
- }
- groupDesc = canonicalizeGroupDesc(groupDesc);
- if(permDesc == null) {
- return groupDesc;
+ if(permDesc == null) {
+ return null;
+ }
+ return permDesc.toString();
}
- return String.format(mPermFormat, groupDesc, permDesc);
- }
-
- /**
- * Utility method that concatenates two strings defined by mPermFormat.
- */
- private String formatPermissions(String groupDesc, CharSequence permDesc) {
groupDesc = canonicalizeGroupDesc(groupDesc);
if(permDesc == null) {
return groupDesc;
}
- // Format only if str1 and str2 are not null.
- return formatPermissions(groupDesc, permDesc.toString());
+ // groupDesc and permDesc are non null
+ return String.format(mPermFormat, groupDesc, permDesc.toString());
}
- private ArrayList<PermissionInfo> generatePermissionsInfo(String[] strList) {
- ArrayList<PermissionInfo> permInfoList = new ArrayList<PermissionInfo>();
- if(strList == null) {
- return permInfoList;
- }
- PermissionInfo tmpPermInfo = null;
- for(int i = 0; i < strList.length; i++) {
- try {
- tmpPermInfo = mPm.getPermissionInfo(strList[i], 0);
- permInfoList.add(tmpPermInfo);
- } catch (NameNotFoundException e) {
- Log.i(TAG, "Ignoring unknown permisison:"+strList[i]);
- continue;
- }
- }
- return permInfoList;
- }
-
- private ArrayList<PermissionInfo> generatePermissionsInfo(ArrayList<String> strList) {
- ArrayList<PermissionInfo> permInfoList = new ArrayList<PermissionInfo>();
- if(strList != null) {
- PermissionInfo tmpPermInfo = null;
- for(String permName:strList) {
- try {
- tmpPermInfo = mPm.getPermissionInfo(permName, 0);
- permInfoList.add(tmpPermInfo);
- } catch (NameNotFoundException e) {
- Log.i(TAG, "Ignoring unknown permisison:"+permName);
- continue;
- }
- }
- }
- return permInfoList;
- }
-
- private String getGroupLabel(String grpName) {
+ private CharSequence getGroupLabel(String grpName) {
if (grpName == null) {
//return default label
return mDefaultGrpLabel;
}
- String cachedLabel = mGroupLabelCache.get(grpName);
+ CharSequence cachedLabel = mGroupLabelCache.get(grpName);
if (cachedLabel != null) {
return cachedLabel;
}
-
PermissionGroupInfo pgi;
try {
pgi = mPm.getPermissionGroupInfo(grpName, 0);
@@ -239,7 +290,7 @@ public class AppSecurityPermissions implements View.OnClickListener {
Log.i(TAG, "Invalid group name:" + grpName);
return null;
}
- String label = pgi.loadLabel(mPm).toString();
+ CharSequence label = pgi.loadLabel(mPm).toString();
mGroupLabelCache.put(grpName, label);
return label;
}
@@ -249,13 +300,13 @@ public class AppSecurityPermissions implements View.OnClickListener {
* list of permission descriptions.
*/
private void displayPermissions(boolean dangerous) {
- HashMap<String, String> permInfoMap = dangerous ? mDangerousMap : mNormalMap;
+ Map<String, String> permInfoMap = dangerous ? mDangerousMap : mNormalMap;
LinearLayout permListView = dangerous ? mDangerousList : mNonDangerousList;
permListView.removeAllViews();
Set<String> permInfoStrSet = permInfoMap.keySet();
for (String loopPermGrpInfoStr : permInfoStrSet) {
- String grpLabel = getGroupLabel(loopPermGrpInfoStr);
+ 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:"
@@ -269,7 +320,7 @@ public class AppSecurityPermissions implements View.OnClickListener {
mNoPermsView.setVisibility(View.VISIBLE);
}
- private View getPermissionItemView(String grpName, String permList,
+ private View getPermissionItemView(CharSequence grpName, String permList,
boolean dangerous) {
View permView = mInflater.inflate(R.layout.app_permission_item, null);
Drawable icon = dangerous ? mDangerousIcon : mNormalIcon;
@@ -334,35 +385,105 @@ public class AppSecurityPermissions implements View.OnClickListener {
}
return false;
}
-
- private void setPermissions(ArrayList<PermissionInfo> permList) {
- setPermissions(permList, null);
+
+ /*
+ * 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<String, List<PermissionInfo> > map, Map<String, String> retMap) {
+ if(map == null) {
+ return;
+ }
+ if(retMap == null) {
+ return;
+ }
+ Set<String> grpNames = map.keySet();
+ Iterator<String> grpNamesIter = grpNames.iterator();
+ while(grpNamesIter.hasNext()) {
+ String grpDesc = null;
+ String grpNameKey = grpNamesIter.next();
+ List<PermissionInfo> grpPermsList = map.get(grpNameKey);
+ if(grpPermsList == null) {
+ continue;
+ }
+ 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());
+ }
+ }
}
- private void setPermissions(ArrayList<PermissionInfo> permList, ApplicationInfo appInfo) {
- mDangerousMap = new HashMap<String, String>();
- mNormalMap = new HashMap<String, String>();
- mGroupLabelCache = new HashMap<String, String>();
+ private static class PermissionInfoComparator implements Comparator<PermissionInfo> {
+ private PackageManager mPm;
+ private final Collator sCollator = Collator.getInstance();
+ PermissionInfoComparator(PackageManager pm) {
+ mPm = pm;
+ }
+ 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 setPermissions(List<PermissionInfo> permList) {
+ mGroupLabelCache = new HashMap<String, CharSequence>();
//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<String, String>();
+ // Map containing group names and a list of permissions under that group
+ // categorized as normal
+ mNormalMap = new HashMap<String, String>();
+
+ // Additional structures needed to ensure that permissions are unique under
+ // each group
+ Map<String, List<PermissionInfo>> dangerousMap =
+ new HashMap<String, List<PermissionInfo>>();
+ Map<String, List<PermissionInfo> > normalMap =
+ new HashMap<String, List<PermissionInfo>>();
+ PermissionInfoComparator permComparator = new PermissionInfoComparator(mPm);
+
if (permList != null) {
+ // First pass to group permissions
for (PermissionInfo pInfo : permList) {
+ if(localLOGV) Log.i(TAG, "Processing permission:"+pInfo.name);
if(!isDisplayablePermission(pInfo)) {
+ if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" is not displayable");
continue;
}
- String grpName = (pInfo.group == null) ? mDefaultGrpName : pInfo.group;
- HashMap<String, String> permInfoMap =
+ Map<String, List<PermissionInfo> > permInfoMap =
(pInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) ?
- mDangerousMap : mNormalMap;
- // Check to make sure we have a label for the group
- if (getGroupLabel(grpName) == null) {
- continue;
+ dangerousMap : normalMap;
+ String grpName = (pInfo.group == null) ? mDefaultGrpName : pInfo.group;
+ if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" belongs to group:"+grpName);
+ List<PermissionInfo> grpPermsList = permInfoMap.get(grpName);
+ if(grpPermsList == null) {
+ grpPermsList = new ArrayList<PermissionInfo>();
+ 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);
+ }
}
- CharSequence permDesc = pInfo.loadLabel(mPm);
- String grpDesc = permInfoMap.get(grpName);
- permInfoMap.put(grpName, formatPermissions(grpDesc, permDesc));
- if(localLOGV) Log.i(TAG, pInfo.name + " : " + permDesc+" : " + grpName);
}
+ // Second pass to actually form the descriptions
+ // Look at dangerous permissions first
+ aggregateGroupDescs(dangerousMap, mDangerousMap);
+ aggregateGroupDescs(normalMap, mNormalMap);
}
mCurrentState = State.NO_PERMS;