• 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;
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.provider.Settings;
33 import android.support.v7.preference.Preference;
34 import android.support.v7.preference.Preference.OnPreferenceClickListener;
35 import android.support.v7.preference.PreferenceCategory;
36 import android.support.v7.preference.PreferenceGroup;
37 import android.util.Log;
38 import android.view.MenuItem;
39 
40 import com.android.packageinstaller.R;
41 import com.android.packageinstaller.permission.utils.Utils;
42 
43 import java.util.ArrayList;
44 import java.util.Collections;
45 import java.util.Comparator;
46 
47 public final class AllAppPermissionsFragment extends SettingsWithHeader {
48 
49     private static final String LOG_TAG = "AllAppPermissionsFragment";
50 
51     private static final String KEY_OTHER = "other_perms";
52 
newInstance(String packageName)53     public static AllAppPermissionsFragment newInstance(String packageName) {
54         AllAppPermissionsFragment instance = new AllAppPermissionsFragment();
55         Bundle arguments = new Bundle();
56         arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
57         instance.setArguments(arguments);
58         return instance;
59     }
60 
61     @Override
onCreate(Bundle savedInstanceState)62     public void onCreate(Bundle savedInstanceState) {
63         super.onCreate(savedInstanceState);
64         setHasOptionsMenu(true);
65         final ActionBar ab = getActivity().getActionBar();
66         if (ab != null) {
67             ab.setTitle(R.string.all_permissions);
68             ab.setDisplayHomeAsUpEnabled(true);
69         }
70     }
71 
72     @Override
onResume()73     public void onResume() {
74         super.onResume();
75         updateUi();
76     }
77 
78     @Override
onOptionsItemSelected(MenuItem item)79     public boolean onOptionsItemSelected(MenuItem item) {
80         switch (item.getItemId()) {
81             case android.R.id.home: {
82                 getFragmentManager().popBackStack();
83                 return true;
84             }
85         }
86         return super.onOptionsItemSelected(item);
87     }
88 
updateUi()89     private void updateUi() {
90         if (getPreferenceScreen() != null) {
91             getPreferenceScreen().removeAll();
92         }
93         addPreferencesFromResource(R.xml.all_permissions);
94         PreferenceGroup otherGroup = (PreferenceGroup) findPreference(KEY_OTHER);
95         ArrayList<Preference> prefs = new ArrayList<>(); // Used for sorting.
96         prefs.add(otherGroup);
97         String pkg = getArguments().getString(Intent.EXTRA_PACKAGE_NAME);
98         otherGroup.removeAll();
99         PackageManager pm = getContext().getPackageManager();
100 
101         try {
102             PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_PERMISSIONS);
103 
104             ApplicationInfo appInfo = info.applicationInfo;
105             final Drawable icon = appInfo.loadIcon(pm);
106             final CharSequence label = appInfo.loadLabel(pm);
107             Intent infoIntent = null;
108             if (!getActivity().getIntent().getBooleanExtra(
109                     AppPermissionsFragment.EXTRA_HIDE_INFO_BUTTON, false)) {
110                 infoIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
111                         .setData(Uri.fromParts("package", pkg, null));
112             }
113             setHeader(icon, label, infoIntent);
114 
115             if (info.requestedPermissions != null) {
116                 for (int i = 0; i < info.requestedPermissions.length; i++) {
117                     PermissionInfo perm;
118                     try {
119                         perm = pm.getPermissionInfo(info.requestedPermissions[i], 0);
120                     } catch (NameNotFoundException e) {
121                         Log.e(LOG_TAG,
122                                 "Can't get permission info for " + info.requestedPermissions[i], e);
123                         continue;
124                     }
125 
126                     if ((perm.flags & PermissionInfo.FLAG_INSTALLED) == 0
127                             || (perm.flags & PermissionInfo.FLAG_HIDDEN) != 0) {
128                         continue;
129                     }
130 
131                     if (perm.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
132                         PermissionGroupInfo group = getGroup(perm.group, pm);
133                         PreferenceGroup pref =
134                                 findOrCreate(group != null ? group : perm, pm, prefs);
135                         pref.addPreference(getPreference(perm, group, pm));
136                     } else if (perm.protectionLevel == PermissionInfo.PROTECTION_NORMAL) {
137                         PermissionGroupInfo group = getGroup(perm.group, pm);
138                         otherGroup.addPreference(getPreference(perm, group, pm));
139                     }
140                 }
141             }
142         } catch (NameNotFoundException e) {
143             Log.e(LOG_TAG, "Problem getting package info for " + pkg, e);
144         }
145         // Sort an ArrayList of the groups and then set the order from the sorting.
146         Collections.sort(prefs, new Comparator<Preference>() {
147             @Override
148             public int compare(Preference lhs, Preference rhs) {
149                 String lKey = lhs.getKey();
150                 String rKey = rhs.getKey();
151                 if (lKey.equals(KEY_OTHER)) {
152                     return 1;
153                 } else if (rKey.equals(KEY_OTHER)) {
154                     return -1;
155                 } else if (Utils.isModernPermissionGroup(lKey)
156                         != Utils.isModernPermissionGroup(rKey)) {
157                     return Utils.isModernPermissionGroup(lKey) ? -1 : 1;
158                 }
159                 return lhs.getTitle().toString().compareTo(rhs.getTitle().toString());
160             }
161         });
162         for (int i = 0; i < prefs.size(); i++) {
163             prefs.get(i).setOrder(i);
164         }
165     }
166 
getGroup(String group, PackageManager pm)167     private PermissionGroupInfo getGroup(String group, PackageManager pm) {
168         try {
169             return pm.getPermissionGroupInfo(group, 0);
170         } catch (NameNotFoundException e) {
171             return null;
172         }
173     }
174 
findOrCreate(PackageItemInfo group, PackageManager pm, ArrayList<Preference> prefs)175     private PreferenceGroup findOrCreate(PackageItemInfo group, PackageManager pm,
176             ArrayList<Preference> prefs) {
177         PreferenceGroup pref = (PreferenceGroup) findPreference(group.name);
178         if (pref == null) {
179             pref = new PreferenceCategory(getContext());
180             pref.setKey(group.name);
181             pref.setLayoutResource(R.layout.preference_category_material);
182             pref.setTitle(group.loadLabel(pm));
183             prefs.add(pref);
184             getPreferenceScreen().addPreference(pref);
185         }
186         return pref;
187     }
188 
getPreference(PermissionInfo perm, PermissionGroupInfo group, PackageManager pm)189     private Preference getPreference(PermissionInfo perm, PermissionGroupInfo group,
190             PackageManager pm) {
191         Preference pref = new Preference(getContext());
192         pref.setLayoutResource(R.layout.preference_permissions);
193         Drawable icon = null;
194         if (perm.icon != 0) {
195             icon = perm.loadIcon(pm);
196         } else if (group != null && group.icon != 0) {
197             icon = group.loadIcon(pm);
198         } else {
199             icon = getContext().getDrawable(R.drawable.ic_perm_device_info);
200         }
201         pref.setIcon(Utils.applyTint(getContext(), icon, android.R.attr.colorControlNormal));
202         pref.setTitle(perm.loadLabel(pm));
203         final CharSequence desc = perm.loadDescription(pm);
204         pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
205             @Override
206             public boolean onPreferenceClick(Preference preference) {
207                 new AlertDialog.Builder(getContext())
208                         .setMessage(desc)
209                         .setPositiveButton(android.R.string.ok, null)
210                         .show();
211                 return true;
212             }
213         });
214 
215         return pref;
216     }
217 }