Home | History | Annotate | Download | only in applications
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
      5  * except in compliance with the License. You may obtain a copy of the License at
      6  *
      7  *      http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software distributed under the
     10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     11  * KIND, either express or implied. See the License for the specific language governing
     12  * permissions and limitations under the License.
     13  */
     14 package com.android.settings.applications;
     15 
     16 import android.content.Context;
     17 import android.content.pm.PackageInfo;
     18 import android.content.pm.PackageManager;
     19 import android.content.pm.PackageManager.NameNotFoundException;
     20 import android.content.pm.PermissionGroupInfo;
     21 import android.content.pm.PermissionInfo;
     22 import android.text.TextUtils;
     23 import android.util.ArraySet;
     24 import android.util.Log;
     25 
     26 import com.android.settings.R;
     27 import com.android.settings.core.BasePreferenceController;
     28 
     29 import java.util.List;
     30 import java.util.Set;
     31 
     32 public class AppPermissionsPreferenceController extends BasePreferenceController {
     33 
     34     private static final String TAG = "AppPermissionPrefCtrl";
     35     private static final String KEY_APP_PERMISSION_GROUPS = "manage_perms";
     36     private static final String[] PERMISSION_GROUPS = new String[] {
     37             "android.permission-group.LOCATION",
     38             "android.permission-group.MICROPHONE",
     39             "android.permission-group.CAMERA",
     40             "android.permission-group.SMS",
     41             "android.permission-group.CONTACTS",
     42             "android.permission-group.PHONE"};
     43 
     44     private static final int NUM_PERMISSION_TO_USE = 3;
     45 
     46     private final PackageManager mPackageManager;
     47 
     48     public AppPermissionsPreferenceController(Context context) {
     49         super(context, KEY_APP_PERMISSION_GROUPS);
     50         mPackageManager = context.getPackageManager();
     51     }
     52 
     53     @Override
     54     public int getAvailabilityStatus() {
     55         return AVAILABLE;
     56     }
     57 
     58     /*
     59        Summary text looks like: Apps using Permission1, Permission2, Permission3
     60        The 3 permissions are the first three from the list which any app has granted:
     61        Location, Microphone, Camera, Sms, Contacts, and Phone
     62      */
     63     @Override
     64     public CharSequence getSummary() {
     65         final Set<String> permissions = getAllPermissionsInGroups();
     66         Set<String> grantedPermissionGroups = getGrantedPermissionGroups(permissions);
     67         CharSequence summary = null;
     68         int count = 0;
     69         for (String group : PERMISSION_GROUPS) {
     70             if (!grantedPermissionGroups.contains(group)) {
     71                 continue;
     72             }
     73             summary = concatSummaryText(summary, group);
     74             if (++count >= NUM_PERMISSION_TO_USE) {
     75                 break;
     76             }
     77         }
     78         return count > 0 ? mContext.getString(R.string.app_permissions_summary, summary) : null;
     79     }
     80 
     81     private Set<String> getGrantedPermissionGroups(Set<String> permissions) {
     82         ArraySet<String> grantedPermissionGroups = new ArraySet<>();
     83         List<PackageInfo> installedPackages =
     84                 mPackageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS);
     85         for (PackageInfo installedPackage : installedPackages) {
     86             if (installedPackage.permissions == null) {
     87                 continue;
     88             }
     89             for (PermissionInfo permissionInfo : installedPackage.permissions) {
     90                 if (permissions.contains(permissionInfo.name)
     91                         && !grantedPermissionGroups.contains(permissionInfo.group)) {
     92                     grantedPermissionGroups.add(permissionInfo.group);
     93                 }
     94             }
     95         }
     96         return grantedPermissionGroups;
     97     }
     98 
     99     private CharSequence concatSummaryText(CharSequence currentSummary, String permission) {
    100         final String label = getPermissionGroupLabel(permission).toString().toLowerCase();
    101         if (TextUtils.isEmpty(currentSummary)) {
    102             return label;
    103         }
    104         return mContext.getString(R.string.join_many_items_middle, currentSummary, label);
    105     }
    106 
    107     private CharSequence getPermissionGroupLabel(String group) {
    108         try {
    109             final PermissionGroupInfo groupInfo = mPackageManager.getPermissionGroupInfo(group, 0);
    110             return groupInfo.loadLabel(mPackageManager);
    111         } catch (NameNotFoundException e) {
    112             Log.e(TAG, "Error getting permissions label.", e);
    113         }
    114         return group;
    115     }
    116 
    117     private Set<String> getAllPermissionsInGroups() {
    118         ArraySet<String> result = new ArraySet<>();
    119         for (String group : PERMISSION_GROUPS) {
    120             try {
    121                 final List<PermissionInfo> permissions =
    122                         mPackageManager.queryPermissionsByGroup(group, 0);
    123                 for (PermissionInfo permissionInfo : permissions) {
    124                     result.add(permissionInfo.name);
    125                 }
    126             } catch (NameNotFoundException e) {
    127                 Log.e(TAG, "Error getting permissions in group " + group, e);
    128             }
    129         }
    130         return result;
    131     }
    132 }
    133