package com.android.settings;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import android.app.Dialog;
import android.app.ExpandableListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;
public class Permissions extends ExpandableListActivity implements Runnable {
private static final String TAG = "Permissions";
private static final String NAME = "Name";
private static final String DESCRIPTION = "Description";
private static final String PACKAGENAME = "PackageName";
private static final String SECURITYLEVEL = "Securitylevel";
private static final int OPTIONS_REFRESH = 1;
private int mDangerousColor;
private int mDefaultTextColor;
private static final int PROGRESS_DIALOG = 0;
private ProgressDialog mProgressDialog;
private List<Map<String, String>> mGroupData;
private List<List<Map<String, String>>> mChildData;
private PackageManager mPm;
@Override
protected void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPm = getPackageManager();
mDangerousColor = getResources().getColor(
com.android.internal.R.color.perms_dangerous_grp_color);
mGroupData = new ArrayList<Map<String, String>>();
mChildData = new ArrayList<List<Map<String, String>>>();
mDefaultTextColor = Color.WHITE;
showDialog(PROGRESS_DIALOG);
};
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setClass(this, InstalledAppDetails.class);
intent.putExtra(ManageApplications.APP_PKG_NAME, (String)v.getTag());
startActivity(intent);
return super.onChildClick(parent, v, groupPosition, childPosition, id);
}
@Override
protected Dialog onCreateDialog(int id) {
switch(id) {
case PROGRESS_DIALOG:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setMessage(getText(R.string.permission_settings_loading));
mProgressDialog.setCancelable(false);
Thread thread = new Thread(this);
thread.start();
return mProgressDialog;
default:
return super.onCreateDialog(id, null);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, OPTIONS_REFRESH, Menu.NONE, R.string.permission_settings_refresh)
.setIcon(com.android.internal.R.drawable.ic_menu_refresh);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case OPTIONS_REFRESH:
showDialog(PROGRESS_DIALOG);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private final Handler handler = new Handler() {
public void handleMessage(Message msg) {
removeDialog(PROGRESS_DIALOG);
PermissionAdapter mAdapter = new PermissionAdapter(
Permissions.this,
mGroupData,
R.layout.permissions_expandable_list_item,
new String[] { NAME, DESCRIPTION },
new int[] { android.R.id.text1, android.R.id.text2 },
mChildData,
R.layout.permissions_expandable_list_item_child,
new String[] { NAME, DESCRIPTION },
new int[] { android.R.id.text1, android.R.id.text2 }
);
setListAdapter(mAdapter);
}
};
private class PermissionAdapter extends SimpleExpandableListAdapter {
public PermissionAdapter(Context context, List<? extends Map<String, ?>> groupData,
int groupLayout, String[] groupFrom, int[] groupTo,
List<? extends List<? extends Map<String, ?>>> childData, int childLayout,
String[] childFrom, int[] childTo) {
super(context, groupData, groupLayout, groupFrom, groupTo, childData,
childLayout, childFrom, childTo);
}
@Override
@SuppressWarnings("unchecked")
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
final View v = super.getGroupView(groupPosition, isExpanded, convertView, parent);
Map<String, String> group = (Map<String, String>) getGroup(groupPosition);
int secLevel = Integer.parseInt(group.get(SECURITYLEVEL));
TextView textView = (TextView) v.findViewById(android.R.id.text1);
if (PermissionInfo.PROTECTION_DANGEROUS == secLevel) {
textView.setTextColor(mDangerousColor);
} else {
textView.setTextColor(mDefaultTextColor);
}
return v;
}
@Override
@SuppressWarnings("unchecked")
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
final View v = super.getChildView(groupPosition, childPosition, isLastChild,
convertView, parent);
ImageView imageView = (ImageView) v.findViewById(android.R.id.icon);
Map<String, String> child =
(Map<String, String>)getChild(groupPosition, childPosition);
Drawable icon;
String packageName = (String)child.get(PACKAGENAME);
try {
icon = mPm.getApplicationIcon(packageName);
} catch (NameNotFoundException e) {
icon = mPm.getDefaultActivityIcon();
}
imageView.setImageDrawable(icon);
v.setTag(packageName);
return v;
}
}
public void run() {
mChildData.clear();
mGroupData.clear();
List<PackageInfo> appList =
mPm.getInstalledPackages(PackageManager.GET_PERMISSIONS);
Map<String, List<PackageInfo>> permList = new TreeMap<String, List<PackageInfo>>();
// Loop through all installed packaged to get a list of used permissions and PackageInfos
for (PackageInfo pi : appList) {
// Do not add System Packages
if (pi.requestedPermissions == null || pi.packageName.equals("android")) {
continue;
}
for (String perms : pi.requestedPermissions) {
if (!permList.containsKey(perms)) {
// First time we get this permission so add it and create a new List
permList.put(perms, new ArrayList<PackageInfo>());
}
permList.get(perms).add(pi);
}
}
appList.clear();
Set<String> keys = permList.keySet();
for (String key : keys) {
Map<String, String> curGroupMap = new HashMap<String, String>();
try {
PermissionInfo pinfo =
mPm.getPermissionInfo(key, PackageManager.GET_META_DATA);
CharSequence label = pinfo.loadLabel(mPm);
CharSequence desc = pinfo.loadDescription(mPm);
curGroupMap.put(NAME, (label == null) ? pinfo.name : label.toString());
curGroupMap.put(DESCRIPTION, (desc == null) ? "" : desc.toString());
curGroupMap.put(SECURITYLEVEL, String.valueOf(pinfo.protectionLevel));
} catch (NameNotFoundException e) {
Log.i(TAG, "Ignoring unknown permission " + key);
continue;
}
mGroupData.add(curGroupMap);
List<Map<String, String>> children = new ArrayList<Map<String, String>>();
List<PackageInfo> infos = permList.get(key);
for (PackageInfo child : infos) {
Map<String, String> curChildMap = new HashMap<String, String>();
String appName = (child.applicationInfo == null) ?
child.packageName : child.applicationInfo.loadLabel(mPm).toString();
curChildMap.put(NAME, appName);
curChildMap.put(DESCRIPTION, child.versionName);
curChildMap.put(PACKAGENAME, child.packageName);
children.add(curChildMap);
}
mChildData.add(children);
}
permList.clear();
handler.sendEmptyMessage(0);
}
}