• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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