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 51 public AppPermissions(Context context, PackageInfo packageInfo, String[] permissions, 52 boolean sortGroups, Runnable onErrorCallback) { 53 mContext = context; 54 mPackageInfo = packageInfo; 55 mFilterPermissions = permissions; 56 mAppLabel = BidiFormatter.getInstance().unicodeWrap( 57 packageInfo.applicationInfo.loadSafeLabel( 58 context.getPackageManager()).toString()); 59 mSortGroups = sortGroups; 60 mOnErrorCallback = onErrorCallback; 61 loadPermissionGroups(); 62 } 63 64 public PackageInfo getPackageInfo() { 65 return mPackageInfo; 66 } 67 68 public void refresh() { 69 loadPackageInfo(); 70 loadPermissionGroups(); 71 } 72 73 public CharSequence getAppLabel() { 74 return mAppLabel; 75 } 76 77 public AppPermissionGroup getPermissionGroup(String name) { 78 return mNameToGroupMap.get(name); 79 } 80 81 public List<AppPermissionGroup> getPermissionGroups() { 82 return mGroups; 83 } 84 85 public boolean isReviewRequired() { 86 if (!Build.PERMISSIONS_REVIEW_REQUIRED) { 87 return false; 88 } 89 final int groupCount = mGroups.size(); 90 for (int i = 0; i < groupCount; i++) { 91 AppPermissionGroup group = mGroups.get(i); 92 if (group.isReviewRequired()) { 93 return true; 94 } 95 } 96 return false; 97 } 98 99 private void loadPackageInfo() { 100 try { 101 mPackageInfo = mContext.getPackageManager().getPackageInfo( 102 mPackageInfo.packageName, PackageManager.GET_PERMISSIONS); 103 } catch (PackageManager.NameNotFoundException e) { 104 if (mOnErrorCallback != null) { 105 mOnErrorCallback.run(); 106 } 107 } 108 } 109 110 private void loadPermissionGroups() { 111 mGroups.clear(); 112 113 if (mPackageInfo.requestedPermissions == null) { 114 return; 115 } 116 117 if (mFilterPermissions != null) { 118 for (String filterPermission : mFilterPermissions) { 119 for (String requestedPerm : mPackageInfo.requestedPermissions) { 120 if (!filterPermission.equals(requestedPerm)) { 121 continue; 122 } 123 124 if (hasGroupForPermission(requestedPerm)) { 125 break; 126 } 127 128 AppPermissionGroup group = AppPermissionGroup.create(mContext, 129 mPackageInfo, requestedPerm); 130 if (group == null) { 131 break; 132 } 133 134 mGroups.add(group); 135 break; 136 } 137 } 138 } else { 139 for (String requestedPerm : mPackageInfo.requestedPermissions) { 140 if (hasGroupForPermission(requestedPerm)) { 141 continue; 142 } 143 144 AppPermissionGroup group = AppPermissionGroup.create(mContext, 145 mPackageInfo, requestedPerm); 146 if (group == null) { 147 continue; 148 } 149 150 mGroups.add(group); 151 } 152 } 153 154 if (mSortGroups) { 155 Collections.sort(mGroups); 156 } 157 158 mNameToGroupMap.clear(); 159 for (AppPermissionGroup group : mGroups) { 160 mNameToGroupMap.put(group.getName(), group); 161 } 162 } 163 164 private boolean hasGroupForPermission(String permission) { 165 for (AppPermissionGroup group : mGroups) { 166 if (group.hasPermission(permission)) { 167 return true; 168 } 169 } 170 return false; 171 } 172 } 173