package com.test.getPermisson;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class GetPermissonActivity extends Activity {
/** Called when the activity is first created. */
private Button btn1,btn2;
private TextView tv;
// private ScrollView sv;
private LinearLayout linear;
private Context mContext;
private String mDivider = "-------------------------------------------";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mContext = this;
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
tv = (TextView) findViewById(R.id.tv);
// sv = (ScrollView) findViewById(R.id.sv);
linear = (LinearLayout) findViewById(R.id.linear);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
linear.removeAllViews();
tv.setText("");
getPermisson(GetPermissonActivity.this);
}
});
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
linear.removeAllViews();
tv.setText("");
View v = getPerView();
linear.addView(v);
}
});
}
private void getPermisson(Context context){
try {
PackageManager pm = context.getPackageManager();
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
//得到自己的包名
String pkgName = pi.packageName;
PermissionGroupInfo pgi;
PackageInfo pkgInfo = pm.getPackageInfo(pkgName, PackageManager.GET_PERMISSIONS);
String sharedPkgList[] = pkgInfo.requestedPermissions;
for(int i=0;i
package com.test.getPermisson;
import android.content.Context;
import android.content.res.Resources;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
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;
public class AppSecurityPermissions implements View.OnClickListener {
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 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;
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;
mPermsList = permList;
}
public AppSecurityPermissions(Context context, String packageName) {
mContext = context;
mPm = mContext.getPackageManager();
mPermsList = new ArrayList();
Set permSet = new HashSet();
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);
}
}
private void getAllUsedPermissions(int sharedUid, Set 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 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) && (pkgInfo.requestedPermissions != null)) {
extractPerms(pkgInfo.requestedPermissions, permSet);
}
}
private void extractPerms(String strList[], Set 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);
mShowMoreText = (TextView) mShowMore.findViewById(R.id.show_more_text);
mDangerousList = (LinearLayout) mPermsView.findViewById(R.id.dangerous_perms_list);
mNonDangerousList = (LinearLayout) mPermsView.findViewById(R.id.non_dangerous_perms_list);
mNoPermsView = mPermsView.findViewById(R.id.no_permissions);
// Set up the LinearLayout that acts like a list item.
mShowMore.setClickable(true);
mShowMore.setOnClickListener(this);
mShowMore.setFocusable(true);
mShowMore.setBackgroundResource(android.R.drawable.list_selector_background);
// Pick up from framework resources instead.
mDefaultGrpLabel = "default_permission_group";
mPermFormat = "string.permissions_format";
mNormalIcon = mContext.getResources().getDrawable(R.drawable.ic_text_dot);
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);
// Set permissions view
setPermissions(mPermsList);
return mPermsView;
}
/**
* Canonicalizes the group description before it is displayed to the user.
*
* TODO check for internationalization issues remove trailing '.' in str1
*/
private String canonicalizeGroupDesc(String groupDesc) {
if ((groupDesc == null) || (groupDesc.length() == 0)) {
return null;
}
// Both str1 and str2 are non-null and are non-zero in size.
int len = groupDesc.length();
if(groupDesc.charAt(len-1) == '.') {
groupDesc = groupDesc.substring(0, len-1);
}
return groupDesc;
}
/**
* Utility method that concatenates two strings defined by mPermFormat.
* a null value is returned if both str1 and str2 are null, if one of the strings
* is null the other non null value is returned without formatting
* this is to placate initial error checks
*/
private String formatPermissions(String groupDesc, CharSequence permDesc) {
if(groupDesc == null) {
if(permDesc == null) {
return null;
}
return permDesc.toString();
}
groupDesc = canonicalizeGroupDesc(groupDesc);
if(permDesc == null) {
return groupDesc;
}
// groupDesc and permDesc are non null
return String.format(mPermFormat, groupDesc, permDesc.toString());
}
private CharSequence getGroupLabel(String grpName) {
if (grpName == null) {
//return default label
return mDefaultGrpLabel;
}
CharSequence cachedLabel = mGroupLabelCache.get(grpName);
if (cachedLabel != null) {
return cachedLabel;
}
PermissionGroupInfo pgi;
try {
pgi = mPm.getPermissionGroupInfo(grpName, 0);
} catch (NameNotFoundException e) {
Log.i(TAG, "Invalid group name:" + grpName);
return null;
}
CharSequence label = pgi.loadLabel(mPm).toString();
mGroupLabelCache.put(grpName, label);
return label;
}
private void displayPermissions(boolean dangerous) {
Map permInfoMap = dangerous ? mDangerousMap : mNormalMap;
LinearLayout permListView = dangerous ? mDangerousList : mNonDangerousList;
permListView.removeAllViews();
Set 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("#####eeee", "Adding view group:" + grpLabel + ", desc:"
+ permInfoMap.get(loopPermGrpInfoStr));
permListView.addView(getPermissionItemView(grpLabel,
permInfoMap.get(loopPermGrpInfoStr), dangerous));
}
}
private void displayNoPermissions() {
mNoPermsView.setVisibility(View.VISIBLE);
}
private View getPermissionItemView(CharSequence grpName, String permList,
boolean dangerous) {
View permView = mInflater.inflate(R.layout.app_permission_item, null);
Drawable icon = dangerous ? mDangerousIcon : mNormalIcon;
TextView permGrpView = (TextView) permView.findViewById(R.id.permission_group);
TextView permDescView = (TextView) permView.findViewById(R.id.permission_list);
if (dangerous) {
final Resources resources = mContext.getResources();
permGrpView.setTextColor(Color.GREEN);//R.color.perms_dangerous_grp_color
permDescView.setTextColor(Color.RED);//R.color.perms_dangerous_perm_color
}
ImageView imgView = (ImageView)permView.findViewById(R.id.perm_icon);
imgView.setImageDrawable(icon);
if(grpName != null) {
permGrpView.setText(grpName);
permDescView.setText(permList);
} else {
permGrpView.setText(permList);
permDescView.setVisibility(View.GONE);
}
return permView;
}
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("perms_hide");
mNonDangerousList.setVisibility(View.VISIBLE);
} else {
mShowMoreIcon.setImageDrawable(mShowMinIcon);
mShowMoreText.setText("perms_show_all");
mNonDangerousList.setVisibility(View.GONE);
}
mShowMore.setVisibility(View.VISIBLE);
break;
}
}
private boolean isDisplayablePermission(PermissionInfo pInfo) {
if(pInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS ||
pInfo.protectionLevel == PermissionInfo.PROTECTION_NORMAL) {
return true;
}
return false;
}
/*
* 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;
}
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;
}
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 static class PermissionInfoComparator implements Comparator {
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 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 (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;
}
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);
}
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();
}
}
1