1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.packageinstaller.permission.ui.handheld; 18 19 import android.app.ActionBar; 20 import android.app.AlertDialog; 21 import android.content.Intent; 22 import android.content.pm.ApplicationInfo; 23 import android.content.pm.PackageInfo; 24 import android.content.pm.PackageItemInfo; 25 import android.content.pm.PackageManager; 26 import android.content.pm.PackageManager.NameNotFoundException; 27 import android.content.pm.PermissionGroupInfo; 28 import android.content.pm.PermissionInfo; 29 import android.graphics.drawable.Drawable; 30 import android.net.Uri; 31 import android.os.Bundle; 32 import android.preference.Preference; 33 import android.preference.Preference.OnPreferenceClickListener; 34 import android.preference.PreferenceCategory; 35 import android.preference.PreferenceGroup; 36 import android.provider.Settings; 37 import android.util.Log; 38 import android.view.MenuItem; 39 import com.android.packageinstaller.R; 40 import com.android.packageinstaller.permission.utils.Utils; 41 42 import java.util.ArrayList; 43 import java.util.Collections; 44 import java.util.Comparator; 45 46 public final class AllAppPermissionsFragment extends SettingsWithHeader { 47 48 private static final String LOG_TAG = "AllAppPermissionsFragment"; 49 50 private static final String KEY_OTHER = "other_perms"; 51 52 public static AllAppPermissionsFragment newInstance(String packageName) { 53 AllAppPermissionsFragment instance = new AllAppPermissionsFragment(); 54 Bundle arguments = new Bundle(); 55 arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 56 instance.setArguments(arguments); 57 return instance; 58 } 59 60 @Override 61 public void onCreate(Bundle savedInstanceState) { 62 super.onCreate(savedInstanceState); 63 setHasOptionsMenu(true); 64 final ActionBar ab = getActivity().getActionBar(); 65 if (ab != null) { 66 ab.setTitle(R.string.all_permissions); 67 ab.setDisplayHomeAsUpEnabled(true); 68 } 69 } 70 71 @Override 72 public void onResume() { 73 super.onResume(); 74 updateUi(); 75 } 76 77 @Override 78 public boolean onOptionsItemSelected(MenuItem item) { 79 switch (item.getItemId()) { 80 case android.R.id.home: { 81 getFragmentManager().popBackStack(); 82 return true; 83 } 84 } 85 return super.onOptionsItemSelected(item); 86 } 87 88 private void updateUi() { 89 if (getPreferenceScreen() != null) { 90 getPreferenceScreen().removeAll(); 91 } 92 addPreferencesFromResource(R.xml.all_permissions); 93 PreferenceGroup otherGroup = (PreferenceGroup) findPreference(KEY_OTHER); 94 ArrayList<Preference> prefs = new ArrayList<>(); // Used for sorting. 95 prefs.add(otherGroup); 96 String pkg = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); 97 otherGroup.removeAll(); 98 PackageManager pm = getContext().getPackageManager(); 99 100 try { 101 PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_PERMISSIONS); 102 103 ApplicationInfo appInfo = info.applicationInfo; 104 final Drawable icon = appInfo.loadIcon(pm); 105 final CharSequence label = appInfo.loadLabel(pm); 106 Intent infoIntent = null; 107 if (!getActivity().getIntent().getBooleanExtra( 108 AppPermissionsFragment.EXTRA_HIDE_INFO_BUTTON, false)) { 109 infoIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) 110 .setData(Uri.fromParts("package", pkg, null)); 111 } 112 setHeader(icon, label, infoIntent); 113 114 if (info.requestedPermissions != null) { 115 for (int i = 0; i < info.requestedPermissions.length; i++) { 116 PermissionInfo perm; 117 try { 118 perm = pm.getPermissionInfo(info.requestedPermissions[i], 0); 119 } catch (NameNotFoundException e) { 120 Log.e(LOG_TAG, 121 "Can't get permission info for " + info.requestedPermissions[i], e); 122 continue; 123 } 124 125 if ((perm.flags & PermissionInfo.FLAG_INSTALLED) == 0 126 || (perm.flags & PermissionInfo.FLAG_REMOVED) != 0) { 127 continue; 128 } 129 130 if (perm.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) { 131 PermissionGroupInfo group = getGroup(perm.group, pm); 132 PreferenceGroup pref = 133 findOrCreate(group != null ? group : perm, pm, prefs); 134 pref.addPreference(getPreference(perm, group, pm)); 135 } else if (perm.protectionLevel == PermissionInfo.PROTECTION_NORMAL) { 136 PermissionGroupInfo group = getGroup(perm.group, pm); 137 otherGroup.addPreference(getPreference(perm, group, pm)); 138 } 139 } 140 } 141 } catch (NameNotFoundException e) { 142 Log.e(LOG_TAG, "Problem getting package info for " + pkg, e); 143 } 144 // Sort an ArrayList of the groups and then set the order from the sorting. 145 Collections.sort(prefs, new Comparator<Preference>() { 146 @Override 147 public int compare(Preference lhs, Preference rhs) { 148 String lKey = lhs.getKey(); 149 String rKey = rhs.getKey(); 150 if (lKey.equals(KEY_OTHER)) { 151 return 1; 152 } else if (rKey.equals(KEY_OTHER)) { 153 return -1; 154 } else if (Utils.isModernPermissionGroup(lKey) 155 != Utils.isModernPermissionGroup(rKey)) { 156 return Utils.isModernPermissionGroup(lKey) ? -1 : 1; 157 } 158 return lhs.getTitle().toString().compareTo(rhs.getTitle().toString()); 159 } 160 }); 161 for (int i = 0; i < prefs.size(); i++) { 162 prefs.get(i).setOrder(i); 163 } 164 } 165 166 private PermissionGroupInfo getGroup(String group, PackageManager pm) { 167 try { 168 return pm.getPermissionGroupInfo(group, 0); 169 } catch (NameNotFoundException e) { 170 return null; 171 } 172 } 173 174 private PreferenceGroup findOrCreate(PackageItemInfo group, PackageManager pm, 175 ArrayList<Preference> prefs) { 176 PreferenceGroup pref = (PreferenceGroup) findPreference(group.name); 177 if (pref == null) { 178 pref = new PreferenceCategory(getContext()); 179 pref.setKey(group.name); 180 pref.setTitle(group.loadLabel(pm)); 181 prefs.add(pref); 182 getPreferenceScreen().addPreference(pref); 183 } 184 return pref; 185 } 186 187 private Preference getPreference(PermissionInfo perm, PermissionGroupInfo group, 188 PackageManager pm) { 189 Preference pref = new Preference(getContext()); 190 Drawable icon = null; 191 if (perm.icon != 0) { 192 icon = perm.loadIcon(pm); 193 } else if (group != null && group.icon != 0) { 194 icon = group.loadIcon(pm); 195 } else { 196 icon = getContext().getDrawable(R.drawable.ic_perm_device_info); 197 } 198 pref.setIcon(Utils.applyTint(getContext(), icon, android.R.attr.colorControlNormal)); 199 pref.setTitle(perm.loadLabel(pm)); 200 final CharSequence desc = perm.loadDescription(pm); 201 pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { 202 @Override 203 public boolean onPreferenceClick(Preference preference) { 204 new AlertDialog.Builder(getContext()) 205 .setMessage(desc) 206 .setPositiveButton(android.R.string.ok, null) 207 .show(); 208 return true; 209 } 210 }); 211 212 return pref; 213 } 214 }