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