17f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau/* 27f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * Copyright (C) 2015 The Android Open Source Project 37f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * 47f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * Licensed under the Apache License, Version 2.0 (the "License"); 57f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * you may not use this file except in compliance with the License. 67f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * You may obtain a copy of the License at 77f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * 87f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * http://www.apache.org/licenses/LICENSE-2.0 97f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * 107f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * Unless required by applicable law or agreed to in writing, software 117f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * distributed under the License is distributed on an "AS IS" BASIS, 127f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * See the License for the specific language governing permissions and 147f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * limitations under the License. 157f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 167f70ba18e6760c2539704c16cf3865bf49953d50Billy Laupackage com.android.settings.applications; 177f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 187f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.app.AppGlobals; 197f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.app.AppOpsManager; 207f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.app.AppOpsManager.PackageOps; 217f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.content.Context; 227f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.content.pm.PackageInfo; 237f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.content.pm.PackageManager; 247f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.os.RemoteException; 257f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.os.UserHandle; 267f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.os.UserManager; 27cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Lingimport android.support.annotation.VisibleForTesting; 287f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.util.ArrayMap; 297f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.util.Log; 307f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.util.SparseArray; 317f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 327f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport com.android.settingslib.applications.ApplicationsState; 337f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport com.android.settingslib.applications.ApplicationsState.AppEntry; 347f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 353d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lauimport java.util.Arrays; 367f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport java.util.Collection; 373d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lauimport java.util.HashSet; 387f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport java.util.List; 393d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lauimport java.util.Set; 407f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 417f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau/* 427f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * Connects app ops info to the ApplicationsState. Makes use of AppOpsManager to 437f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * determine further permission level. 447f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 457f70ba18e6760c2539704c16cf3865bf49953d50Billy Laupublic abstract class AppStateAppOpsBridge extends AppStateBaseBridge { 467f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 477f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private static final String TAG = "AppStateAppOpsBridge"; 487f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 49cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling private final IPackageManagerWrapper mIPackageManager; 507f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final UserManager mUserManager; 517f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final List<UserHandle> mProfiles; 527f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final AppOpsManager mAppOpsManager; 537f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final Context mContext; 547f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final int[] mAppOpsOpCodes; 557f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final String[] mPermissions; 567f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 577f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public AppStateAppOpsBridge(Context context, ApplicationsState appState, Callback callback, 583d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau int appOpsOpCode, String[] permissions) { 59cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling this(context, appState, callback, appOpsOpCode, permissions, 60cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling new IPackageManagerWrapperImpl(AppGlobals.getPackageManager())); 61cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling } 62cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling 63cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling @VisibleForTesting(otherwise = VisibleForTesting.NONE) 64cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling AppStateAppOpsBridge(Context context, ApplicationsState appState, Callback callback, 65cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling int appOpsOpCode, String[] permissions, IPackageManagerWrapper packageManager) { 667f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau super(appState, callback); 677f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mContext = context; 68cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling mIPackageManager = packageManager; 697f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mUserManager = UserManager.get(context); 707f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mProfiles = mUserManager.getUserProfiles(); 717f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); 727f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mAppOpsOpCodes = new int[] {appOpsOpCode}; 733d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau mPermissions = permissions; 747f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 757f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 767f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private boolean isThisUserAProfileOfCurrentUser(final int userId) { 777f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int profilesMax = mProfiles.size(); 787f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (int i = 0; i < profilesMax; i++) { 797f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (mProfiles.get(i).getIdentifier() == userId) { 807f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return true; 817f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 827f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 837f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return false; 847f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 857f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 867f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau protected abstract void updateExtraInfo(AppEntry app, String pkg, int uid); 877f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 883d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau private boolean doesAnyPermissionMatch(String permissionToMatch, String[] permissions) { 893d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau for (String permission : permissions) { 903d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau if (permissionToMatch.equals(permission)) { 913d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau return true; 923d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau } 933d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau } 943d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau return false; 953d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau } 963d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau 977f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public PermissionState getPermissionInfo(String pkg, int uid) { 987f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau PermissionState permissionState = new PermissionState(pkg, new UserHandle(UserHandle 997f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau .getUserId(uid))); 1007f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau try { 1017f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau permissionState.packageInfo = mIPackageManager.getPackageInfo(pkg, 102cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling PackageManager.GET_PERMISSIONS | PackageManager.MATCH_ANY_USER, 103bde1a7cfb13736ad52ba838e0b21117b7da6dafbJason Monk permissionState.userHandle.getIdentifier()); 104cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling if (permissionState.packageInfo != null) { 105cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling // Check static permission state (whatever that is declared in package manifest) 106cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling String[] requestedPermissions = permissionState.packageInfo.requestedPermissions; 107cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling int[] permissionFlags = permissionState.packageInfo.requestedPermissionsFlags; 108cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling if (requestedPermissions != null) { 109cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling for (int i = 0; i < requestedPermissions.length; i++) { 110cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling if (doesAnyPermissionMatch(requestedPermissions[i], mPermissions)) { 111cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling permissionState.permissionDeclared = true; 112cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling if ((permissionFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) 113cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling != 0) { 114cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling permissionState.staticPermissionGranted = true; 115cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling break; 116cc28cb372da331e75330d4544d5ae90b7cf34f65Doris Ling } 117fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau } 1187f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1197f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1207f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1217f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Check app op state. 1227f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau List<PackageOps> ops = mAppOpsManager.getOpsForPackage(uid, pkg, mAppOpsOpCodes); 1237f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (ops != null && ops.size() > 0 && ops.get(0).getOps().size() > 0) { 1247f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau permissionState.appOpMode = ops.get(0).getOps().get(0).getMode(); 1257f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1267f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } catch (RemoteException e) { 1277f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Log.w(TAG, "PackageManager is dead. Can't get package info " + pkg, e); 1287f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1297f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return permissionState; 1307f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1317f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1327f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau @Override 1337f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau protected void loadAllExtraInfo() { 1347f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau SparseArray<ArrayMap<String, PermissionState>> entries = getEntries(); 1357f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1367f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Load state info. 1377f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau loadPermissionsStates(entries); 1387f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau loadAppOpsStates(entries); 1397f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1407f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Map states to application info. 1417f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau List<AppEntry> apps = mAppSession.getAllApps(); 1427f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int N = apps.size(); 1437f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (int i = 0; i < N; i++) { 1447f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau AppEntry app = apps.get(i); 1457f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau int userId = UserHandle.getUserId(app.info.uid); 1467f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau ArrayMap<String, PermissionState> userMap = entries.get(userId); 1477f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau app.extraInfo = userMap != null ? userMap.get(app.info.packageName) : null; 1487f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1497f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1507f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1517f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau /* 1527f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * Gets a sparse array that describes every user on the device and all the associated packages 1537f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * of each user, together with the packages available for that user. 1547f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 1557f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private SparseArray<ArrayMap<String, PermissionState>> getEntries() { 1567f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau try { 1573d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau Set<String> packagesSet = new HashSet<>(); 1583d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau for (String permission : mPermissions) { 1593d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau String[] pkgs = mIPackageManager.getAppOpPermissionPackages(permission); 1603d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau if (pkgs != null) { 1613d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau packagesSet.addAll(Arrays.asList(pkgs)); 1623d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau } 1633d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau } 1647f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1653d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau if (packagesSet.isEmpty()) { 1667f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // No packages are requesting permission as specified by mPermissions. 1677f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return null; 1687f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1697f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1707f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Create a sparse array that maps profileIds to an ArrayMap that maps package names to 1717f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // an associated PermissionState object 1727f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau SparseArray<ArrayMap<String, PermissionState>> entries = new SparseArray<>(); 1737f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (final UserHandle profile : mProfiles) { 1747f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final ArrayMap<String, PermissionState> entriesForProfile = new ArrayMap<>(); 1757f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int profileId = profile.getIdentifier(); 1767f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau entries.put(profileId, entriesForProfile); 1773d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau for (final String packageName : packagesSet) { 1787f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final boolean isAvailable = mIPackageManager.isPackageAvailable(packageName, 1797f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau profileId); 1807f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (!shouldIgnorePackage(packageName) && isAvailable) { 1817f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final PermissionState newEntry = new PermissionState(packageName, profile); 1827f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau entriesForProfile.put(packageName, newEntry); 1837f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1847f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1857f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1867f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1877f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return entries; 1887f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } catch (RemoteException e) { 1897f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Log.w(TAG, "PackageManager is dead. Can't get list of packages requesting " 1907f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau + mPermissions[0], e); 1917f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return null; 1927f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1937f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1947f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1957f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau /* 196fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau * This method will set the packageInfo and staticPermissionGranted field of the associated 1977f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * PermissionState, which describes a particular package. 1987f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 1997f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private void loadPermissionsStates(SparseArray<ArrayMap<String, PermissionState>> entries) { 2007f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Load the packages that have been granted the permission specified in mPermission. 2017f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau try { 2027f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (final UserHandle profile : mProfiles) { 2037f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int profileId = profile.getIdentifier(); 2047f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final ArrayMap<String, PermissionState> entriesForProfile = entries.get(profileId); 2057f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entriesForProfile == null) { 2067f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau continue; 2077f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2087f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau @SuppressWarnings("unchecked") 2097f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final List<PackageInfo> packageInfos = mIPackageManager 2107f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau .getPackagesHoldingPermissions(mPermissions, 0, profileId).getList(); 2117f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int packageInfoCount = packageInfos != null ? packageInfos.size() : 0; 2127f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (int i = 0; i < packageInfoCount; i++) { 2137f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final PackageInfo packageInfo = packageInfos.get(i); 2147f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final PermissionState pe = entriesForProfile.get(packageInfo.packageName); 2157f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (pe != null) { 2167f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau pe.packageInfo = packageInfo; 217fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau pe.staticPermissionGranted = true; 2187f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2197f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2207f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2217f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } catch (RemoteException e) { 2227f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Log.w(TAG, "PackageManager is dead. Can't get list of packages granted " 2233d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau + mPermissions, e); 2247f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return; 2257f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2267f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2277f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2287f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau /* 2297f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * This method will set the appOpMode field of the associated PermissionState, which describes 2307f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * a particular package. 2317f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 2327f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private void loadAppOpsStates(SparseArray<ArrayMap<String, PermissionState>> entries) { 2337f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Find out which packages have been granted permission from AppOps. 2347f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final List<AppOpsManager.PackageOps> packageOps = mAppOpsManager.getPackagesForOps( 2357f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mAppOpsOpCodes); 2367f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int packageOpsCount = packageOps != null ? packageOps.size() : 0; 2377f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (int i = 0; i < packageOpsCount; i++) { 2387f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final AppOpsManager.PackageOps packageOp = packageOps.get(i); 2397f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int userId = UserHandle.getUserId(packageOp.getUid()); 2407f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (!isThisUserAProfileOfCurrentUser(userId)) { 2417f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // This AppOp does not belong to any of this user's profiles. 2427f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau continue; 2437f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2447f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2457f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final ArrayMap<String, PermissionState> entriesForProfile = entries.get(userId); 2467f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entriesForProfile == null) { 2477f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau continue; 2487f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2497f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final PermissionState pe = entriesForProfile.get(packageOp.getPackageName()); 2507f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (pe == null) { 2517f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Log.w(TAG, "AppOp permission exists for package " + packageOp.getPackageName() 2527f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau + " of user " + userId + " but package doesn't exist or did not request " 2533d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau + mPermissions + " access"); 2547f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau continue; 2557f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2567f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2577f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (packageOp.getOps().size() < 1) { 2587f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Log.w(TAG, "No AppOps permission exists for package " + packageOp.getPackageName()); 2597f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau continue; 2607f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2617f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau pe.appOpMode = packageOp.getOps().get(0).getMode(); 2627f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2637f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2647f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2657f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau /* 2667f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * Check for packages that should be ignored for further processing 2677f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 2687f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private boolean shouldIgnorePackage(String packageName) { 2697f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return packageName.equals("android") || packageName.equals(mContext.getPackageName()); 2707f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2717f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2727f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public int getNumPackagesDeclaredPermission() { 2737f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau SparseArray<ArrayMap<String, PermissionState>> entries = getEntries(); 2747f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entries == null) { 2757f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return 0; 2767f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2777f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final ArrayMap<String, PermissionState> entriesForProfile = entries.get(mUserManager 2787f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau .getUserHandle()); 2797f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entriesForProfile == null) { 2807f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return 0; 2817f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2827f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return entriesForProfile.size(); 2837f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2847f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2857f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public int getNumPackagesAllowedByAppOps() { 2867f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau SparseArray<ArrayMap<String, PermissionState>> entries = getEntries(); 2877f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entries == null) { 2887f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return 0; 2897f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2907f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau loadPermissionsStates(entries); 2917f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau loadAppOpsStates(entries); 2927f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final ArrayMap<String, PermissionState> entriesForProfile = entries.get(mUserManager 2937f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau .getUserHandle()); 2947f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entriesForProfile == null) { 2957f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return 0; 2967f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2977f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Collection<PermissionState> permStates = entriesForProfile.values(); 2987f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau int result = 0; 2997f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (PermissionState permState : permStates) { 3007f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (permState.isPermissible()) { 3017f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau result++; 3027f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3037f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3047f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return result; 3057f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3067f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 3077f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public static class PermissionState { 3087f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public final String packageName; 3097f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public final UserHandle userHandle; 3107f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public PackageInfo packageInfo; 311fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau public boolean staticPermissionGranted; 3127f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public boolean permissionDeclared; 3137f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public int appOpMode; 3147f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 3157f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public PermissionState(String packageName, UserHandle userHandle) { 3167f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau this.packageName = packageName; 3177f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau this.appOpMode = AppOpsManager.MODE_DEFAULT; 3187f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau this.userHandle = userHandle; 3197f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3207f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 3217f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public boolean isPermissible() { 3227f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // defining the default behavior as permissible as long as the package requested this 3237f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // permission (this means pre-M gets approval during install time; M apps gets approval 3247f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // during runtime. 3257f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (appOpMode == AppOpsManager.MODE_DEFAULT) { 326fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau return staticPermissionGranted; 3277f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3287f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return appOpMode == AppOpsManager.MODE_ALLOWED; 3297f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3307f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3317f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau} 332