AppPermissions.java revision 03dc824d37099b29acb5a0aa28e881d5b05cce0e
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 17package com.android.packageinstaller.permission.model; 18 19import android.content.Context; 20import android.content.pm.PackageInfo; 21import android.content.pm.PackageManager; 22import android.text.BidiFormatter; 23import android.text.TextPaint; 24import android.text.TextUtils; 25 26import com.android.packageinstaller.DeviceUtils; 27 28import java.util.ArrayList; 29import java.util.Collections; 30import java.util.LinkedHashMap; 31import java.util.List; 32 33public final class AppPermissions { 34 private static final float MAX_APP_LABEL_LENGTH_PIXELS = 500; 35 36 private static final TextPaint sAppLabelEllipsizePaint = new TextPaint(); 37 static { 38 sAppLabelEllipsizePaint.setAntiAlias(true); 39 // Both text size and width are given in absolute pixels, for consistent truncation 40 // across devices; this value corresponds to the default 14dip size on an xdhpi device. 41 sAppLabelEllipsizePaint.setTextSize(42); 42 } 43 44 private final ArrayList<AppPermissionGroup> mGroups = new ArrayList<>(); 45 46 private final LinkedHashMap<String, AppPermissionGroup> mNameToGroupMap = new LinkedHashMap<>(); 47 48 private final Context mContext; 49 50 private final String[] mFilterPermissions; 51 52 private final CharSequence mAppLabel; 53 54 private final Runnable mOnErrorCallback; 55 56 private final boolean mSortGroups; 57 58 private PackageInfo mPackageInfo; 59 60 public AppPermissions(Context context, PackageInfo packageInfo, String[] permissions, 61 boolean sortGroups, Runnable onErrorCallback) { 62 mContext = context; 63 mPackageInfo = packageInfo; 64 mFilterPermissions = permissions; 65 mAppLabel = loadEllipsizedAppLabel(context, packageInfo); 66 mSortGroups = sortGroups; 67 mOnErrorCallback = onErrorCallback; 68 loadPermissionGroups(); 69 } 70 71 public PackageInfo getPackageInfo() { 72 return mPackageInfo; 73 } 74 75 public void refresh() { 76 loadPackageInfo(); 77 loadPermissionGroups(); 78 } 79 80 public CharSequence getAppLabel() { 81 return mAppLabel; 82 } 83 84 public AppPermissionGroup getPermissionGroup(String name) { 85 return mNameToGroupMap.get(name); 86 } 87 88 public List<AppPermissionGroup> getPermissionGroups() { 89 return mGroups; 90 } 91 92 93 private void loadPackageInfo() { 94 try { 95 mPackageInfo = mContext.getPackageManager().getPackageInfo( 96 mPackageInfo.packageName, PackageManager.GET_PERMISSIONS); 97 } catch (PackageManager.NameNotFoundException e) { 98 if (mOnErrorCallback != null) { 99 mOnErrorCallback.run(); 100 } 101 } 102 } 103 104 private void loadPermissionGroups() { 105 mGroups.clear(); 106 107 if (mPackageInfo.requestedPermissions == null) { 108 return; 109 } 110 111 if (mFilterPermissions != null) { 112 for (String filterPermission : mFilterPermissions) { 113 for (String requestedPerm : mPackageInfo.requestedPermissions) { 114 if (!filterPermission.equals(requestedPerm)) { 115 continue; 116 } 117 118 if (hasGroupForPermission(requestedPerm)) { 119 break; 120 } 121 122 AppPermissionGroup group = AppPermissionGroup.create(mContext, 123 mPackageInfo, requestedPerm); 124 if (group == null) { 125 break; 126 } 127 128 mGroups.add(group); 129 break; 130 } 131 } 132 } else { 133 for (String requestedPerm : mPackageInfo.requestedPermissions) { 134 if (hasGroupForPermission(requestedPerm)) { 135 continue; 136 } 137 138 AppPermissionGroup group = AppPermissionGroup.create(mContext, 139 mPackageInfo, requestedPerm); 140 if (group == null) { 141 continue; 142 } 143 144 mGroups.add(group); 145 } 146 } 147 148 if (mSortGroups) { 149 Collections.sort(mGroups); 150 } 151 152 mNameToGroupMap.clear(); 153 for (AppPermissionGroup group : mGroups) { 154 mNameToGroupMap.put(group.getName(), group); 155 } 156 } 157 158 private boolean hasGroupForPermission(String permission) { 159 for (AppPermissionGroup group : mGroups) { 160 if (group.hasPermission(permission)) { 161 return true; 162 } 163 } 164 return false; 165 } 166 167 private static CharSequence loadEllipsizedAppLabel(Context context, PackageInfo packageInfo) { 168 String label = packageInfo.applicationInfo.loadLabel( 169 context.getPackageManager()).toString(); 170 String ellipsizedLabel = label.replace("\n", " "); 171 if (!DeviceUtils.isWear(context)) { 172 // Only ellipsize for non-Wear devices. 173 ellipsizedLabel = TextUtils.ellipsize(ellipsizedLabel, sAppLabelEllipsizePaint, 174 MAX_APP_LABEL_LENGTH_PIXELS, TextUtils.TruncateAt.END).toString(); 175 } 176 return BidiFormatter.getInstance().unicodeWrap(ellipsizedLabel); 177 } 178} 179