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.model; 18 19 import android.content.Context; 20 import android.content.pm.PackageInfo; 21 import android.content.pm.PackageManager; 22 import android.os.Build; 23 import android.text.BidiFormatter; 24 import android.text.TextPaint; 25 import android.text.TextUtils; 26 27 import com.android.packageinstaller.DeviceUtils; 28 29 import java.util.ArrayList; 30 import java.util.Collections; 31 import java.util.LinkedHashMap; 32 import java.util.List; 33 34 public final class AppPermissions { 35 private final ArrayList<AppPermissionGroup> mGroups = new ArrayList<>(); 36 37 private final LinkedHashMap<String, AppPermissionGroup> mNameToGroupMap = new LinkedHashMap<>(); 38 39 private final Context mContext; 40 41 private final String[] mFilterPermissions; 42 43 private final CharSequence mAppLabel; 44 45 private final Runnable mOnErrorCallback; 46 47 private final boolean mSortGroups; 48 49 private PackageInfo mPackageInfo; 50 AppPermissions(Context context, PackageInfo packageInfo, String[] filterPermissions, boolean sortGroups, Runnable onErrorCallback)51 public AppPermissions(Context context, PackageInfo packageInfo, String[] filterPermissions, 52 boolean sortGroups, Runnable onErrorCallback) { 53 mContext = context; 54 mPackageInfo = packageInfo; 55 mFilterPermissions = filterPermissions; 56 mAppLabel = BidiFormatter.getInstance().unicodeWrap( 57 packageInfo.applicationInfo.loadSafeLabel( 58 context.getPackageManager()).toString()); 59 mSortGroups = sortGroups; 60 mOnErrorCallback = onErrorCallback; 61 loadPermissionGroups(); 62 } 63 getPackageInfo()64 public PackageInfo getPackageInfo() { 65 return mPackageInfo; 66 } 67 refresh()68 public void refresh() { 69 loadPackageInfo(); 70 loadPermissionGroups(); 71 } 72 getAppLabel()73 public CharSequence getAppLabel() { 74 return mAppLabel; 75 } 76 getPermissionGroup(String name)77 public AppPermissionGroup getPermissionGroup(String name) { 78 return mNameToGroupMap.get(name); 79 } 80 getPermissionGroups()81 public List<AppPermissionGroup> getPermissionGroups() { 82 return mGroups; 83 } 84 isReviewRequired()85 public boolean isReviewRequired() { 86 if (!mContext.getResources().getBoolean( 87 com.android.internal.R.bool.config_permissionReviewRequired) 88 && !Build.PERMISSIONS_REVIEW_REQUIRED) { 89 return false; 90 } 91 final int groupCount = mGroups.size(); 92 for (int i = 0; i < groupCount; i++) { 93 AppPermissionGroup group = mGroups.get(i); 94 if (group.isReviewRequired()) { 95 return true; 96 } 97 } 98 return false; 99 } 100 loadPackageInfo()101 private void loadPackageInfo() { 102 try { 103 mPackageInfo = mContext.getPackageManager().getPackageInfo( 104 mPackageInfo.packageName, PackageManager.GET_PERMISSIONS); 105 } catch (PackageManager.NameNotFoundException e) { 106 if (mOnErrorCallback != null) { 107 mOnErrorCallback.run(); 108 } 109 } 110 } 111 loadPermissionGroups()112 private void loadPermissionGroups() { 113 mGroups.clear(); 114 115 if (mPackageInfo.requestedPermissions == null) { 116 return; 117 } 118 119 if (mFilterPermissions != null) { 120 for (String filterPermission : mFilterPermissions) { 121 for (String requestedPerm : mPackageInfo.requestedPermissions) { 122 if (!filterPermission.equals(requestedPerm)) { 123 continue; 124 } 125 addPermissionGroupIfNeeded(requestedPerm); 126 break; 127 } 128 } 129 } else { 130 for (String requestedPerm : mPackageInfo.requestedPermissions) { 131 addPermissionGroupIfNeeded(requestedPerm); 132 } 133 } 134 135 if (mSortGroups) { 136 Collections.sort(mGroups); 137 } 138 139 mNameToGroupMap.clear(); 140 for (AppPermissionGroup group : mGroups) { 141 mNameToGroupMap.put(group.getName(), group); 142 } 143 } 144 addPermissionGroupIfNeeded(String permission)145 private void addPermissionGroupIfNeeded(String permission) { 146 if (hasGroupForPermission(permission)) { 147 return; 148 } 149 150 AppPermissionGroup group = AppPermissionGroup.create(mContext, 151 mPackageInfo, permission); 152 if (group == null) { 153 return; 154 } 155 156 mGroups.add(group); 157 } 158 hasGroupForPermission(String permission)159 private boolean hasGroupForPermission(String permission) { 160 for (AppPermissionGroup group : mGroups) { 161 if (group.hasPermission(permission)) { 162 return true; 163 } 164 } 165 return false; 166 } 167 } 168