Home | History | Annotate | Download | only in model
      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