diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:43 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:43 -0800 |
commit | f013e1afd1e68af5e3b868c26a653bbfb39538f8 (patch) | |
tree | 7ad6c8fd9c7b55f4b4017171dec1cb760bbd26bf /core/java/android/widget/AppSecurityPermissions.java | |
parent | e70cfafe580c6f2994c4827cd8a534aabf3eb05c (diff) | |
download | frameworks_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-x | core/java/android/widget/AppSecurityPermissions.java | 347 |
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; |