1 /* 2 * Copyright 2019 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.car.settings.applications; 18 19 import android.car.drivingstate.CarUxRestrictions; 20 import android.content.Context; 21 import android.content.pm.PackageInfo; 22 import android.content.pm.PackageManager; 23 import android.content.pm.PermissionGroupInfo; 24 import android.content.pm.PermissionInfo; 25 import android.icu.text.ListFormatter; 26 import android.util.ArraySet; 27 28 import androidx.preference.Preference; 29 30 import com.android.car.settings.R; 31 import com.android.car.settings.common.FragmentController; 32 import com.android.car.settings.common.Logger; 33 import com.android.car.settings.common.PreferenceController; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 import java.util.Set; 38 39 /** 40 * Updates the summary of the entry preference for app permissions to show up to a fixed number of 41 * permission groups currently permitted. 42 */ 43 public class AppPermissionsEntryPreferenceController extends PreferenceController<Preference> { 44 45 private static final Logger LOG = new Logger(AppPermissionsEntryPreferenceController.class); 46 47 private static final String[] PERMISSION_GROUPS = new String[]{ 48 "android.permission-group.LOCATION", 49 "android.permission-group.MICROPHONE", 50 "android.permission-group.CAMERA", 51 "android.permission-group.SMS", 52 "android.permission-group.CONTACTS", 53 "android.permission-group.PHONE"}; 54 55 private static final int NUM_PERMISSION_TO_USE = 3; 56 57 private PackageManager mPackageManager; 58 AppPermissionsEntryPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)59 public AppPermissionsEntryPreferenceController(Context context, String preferenceKey, 60 FragmentController fragmentController, CarUxRestrictions uxRestrictions) { 61 super(context, preferenceKey, fragmentController, uxRestrictions); 62 mPackageManager = context.getPackageManager(); 63 } 64 65 @Override getPreferenceType()66 protected Class<Preference> getPreferenceType() { 67 return Preference.class; 68 } 69 70 @Override updateState(Preference preference)71 protected void updateState(Preference preference) { 72 Set<String> permissions = getAllPermissionsInGroups(); 73 Set<String> grantedPermissionGroups = getGrantedPermissionGroups(permissions); 74 int count = 0; 75 final List<String> summaries = new ArrayList<>(); 76 77 // Iterate over array instead of set to show sensitive permissions first. 78 for (String group : PERMISSION_GROUPS) { 79 if (!grantedPermissionGroups.contains(group)) { 80 continue; 81 } 82 summaries.add(getPermissionGroupLabel(group).toString().toLowerCase()); 83 if (++count >= NUM_PERMISSION_TO_USE) { 84 break; 85 } 86 } 87 String summary = (count > 0) ? getContext().getString(R.string.app_permissions_summary, 88 ListFormatter.getInstance().format(summaries)) : null; 89 90 preference.setSummary(summary); 91 } 92 getAllPermissionsInGroups()93 private Set<String> getAllPermissionsInGroups() { 94 Set<String> result = new ArraySet<>(); 95 for (String group : PERMISSION_GROUPS) { 96 try { 97 List<PermissionInfo> permissions = mPackageManager.queryPermissionsByGroup( 98 group, /* flags= */ 0); 99 for (PermissionInfo permissionInfo : permissions) { 100 result.add(permissionInfo.name); 101 } 102 } catch (PackageManager.NameNotFoundException e) { 103 LOG.e("Error getting permissions in group " + group, e); 104 } 105 } 106 return result; 107 } 108 getGrantedPermissionGroups(Set<String> permissions)109 private Set<String> getGrantedPermissionGroups(Set<String> permissions) { 110 Set<String> grantedPermissionGroups = new ArraySet<>(); 111 List<PackageInfo> installedPackages = 112 mPackageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS); 113 for (PackageInfo installedPackage : installedPackages) { 114 if (installedPackage.permissions == null) { 115 continue; 116 } 117 for (PermissionInfo permissionInfo : installedPackage.permissions) { 118 if (permissions.contains(permissionInfo.name)) { 119 grantedPermissionGroups.add(permissionInfo.group); 120 } 121 } 122 } 123 return grantedPermissionGroups; 124 } 125 getPermissionGroupLabel(String group)126 private CharSequence getPermissionGroupLabel(String group) { 127 try { 128 PermissionGroupInfo groupInfo = mPackageManager.getPermissionGroupInfo( 129 group, /* flags= */ 0); 130 return groupInfo.loadLabel(mPackageManager); 131 } catch (PackageManager.NameNotFoundException e) { 132 LOG.e("Error getting permissions label.", e); 133 } 134 return group; 135 } 136 } 137