Home | History | Annotate | Download | only in handheld
      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 }