• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
newInstance(String packageName)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
onCreate(Bundle savedInstanceState)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
onResume()72     public void onResume() {
73         super.onResume();
74         updateUi();
75     }
76 
77     @Override
onOptionsItemSelected(MenuItem item)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 
updateUi()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 
getGroup(String group, PackageManager pm)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 
findOrCreate(PackageItemInfo group, PackageManager pm, ArrayList<Preference> prefs)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 
getPreference(PermissionInfo perm, PermissionGroupInfo group, PackageManager pm)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 }