AppStateAppOpsBridge.java revision 3d9c7fc9982ddd513bc1bebdce76a12eecb61c88
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.Manifest; 197f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.app.AppGlobals; 207f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.app.AppOpsManager; 217f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.app.AppOpsManager.PackageOps; 227f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.content.Context; 237f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.content.pm.IPackageManager; 247f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.content.pm.PackageInfo; 257f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.content.pm.PackageManager; 267f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.os.RemoteException; 277f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.os.UserHandle; 287f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.os.UserManager; 297f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.util.ArrayMap; 307f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.util.Log; 317f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport android.util.SparseArray; 327f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 337f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport com.android.settingslib.applications.ApplicationsState; 347f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport com.android.settingslib.applications.ApplicationsState.AppEntry; 357f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport com.android.settingslib.applications.ApplicationsState.AppFilter; 367f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 373d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lauimport java.util.Arrays; 387f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport java.util.Collection; 393d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lauimport java.util.HashSet; 407f70ba18e6760c2539704c16cf3865bf49953d50Billy Lauimport java.util.List; 413d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lauimport java.util.Set; 427f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 437f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau/* 447f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * Connects app ops info to the ApplicationsState. Makes use of AppOpsManager to 457f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * determine further permission level. 467f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 477f70ba18e6760c2539704c16cf3865bf49953d50Billy Laupublic abstract class AppStateAppOpsBridge extends AppStateBaseBridge { 487f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 497f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private static final String TAG = "AppStateAppOpsBridge"; 507f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 517f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final IPackageManager mIPackageManager; 527f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final UserManager mUserManager; 537f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final List<UserHandle> mProfiles; 547f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final AppOpsManager mAppOpsManager; 557f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final Context mContext; 567f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final int[] mAppOpsOpCodes; 577f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private final String[] mPermissions; 587f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 597f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public AppStateAppOpsBridge(Context context, ApplicationsState appState, Callback callback, 603d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau int appOpsOpCode, String[] permissions) { 617f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau super(appState, callback); 627f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mContext = context; 637f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mIPackageManager = AppGlobals.getPackageManager(); 647f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mUserManager = UserManager.get(context); 657f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mProfiles = mUserManager.getUserProfiles(); 667f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); 677f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mAppOpsOpCodes = new int[] {appOpsOpCode}; 683d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau mPermissions = permissions; 697f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 707f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 717f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private boolean isThisUserAProfileOfCurrentUser(final int userId) { 727f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int profilesMax = mProfiles.size(); 737f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (int i = 0; i < profilesMax; i++) { 747f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (mProfiles.get(i).getIdentifier() == userId) { 757f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return true; 767f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 777f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 787f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return false; 797f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 807f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 817f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau protected abstract void updateExtraInfo(AppEntry app, String pkg, int uid); 827f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 833d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau private boolean doesAnyPermissionMatch(String permissionToMatch, String[] permissions) { 843d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau for (String permission : permissions) { 853d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau if (permissionToMatch.equals(permission)) { 863d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau return true; 873d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau } 883d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau } 893d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau return false; 903d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau } 913d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau 927f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public PermissionState getPermissionInfo(String pkg, int uid) { 937f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau PermissionState permissionState = new PermissionState(pkg, new UserHandle(UserHandle 947f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau .getUserId(uid))); 957f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau try { 967f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau permissionState.packageInfo = mIPackageManager.getPackageInfo(pkg, 977f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau PackageManager.GET_PERMISSIONS, permissionState.userHandle.getIdentifier()); 987f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Check static permission state (whatever that is declared in package manifest) 997f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau String[] requestedPermissions = permissionState.packageInfo.requestedPermissions; 1007f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau int[] permissionFlags = permissionState.packageInfo.requestedPermissionsFlags; 1017f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (requestedPermissions != null) { 1027f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (int i = 0; i < requestedPermissions.length; i++) { 1033d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau if (doesAnyPermissionMatch(requestedPermissions[i], mPermissions)) { 1047f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau permissionState.permissionDeclared = true; 105fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau if ((permissionFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) { 106fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau permissionState.staticPermissionGranted = true; 107fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau break; 108fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau } 1097f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1107f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1117f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1127f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Check app op state. 1137f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau List<PackageOps> ops = mAppOpsManager.getOpsForPackage(uid, pkg, mAppOpsOpCodes); 1147f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (ops != null && ops.size() > 0 && ops.get(0).getOps().size() > 0) { 1157f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau permissionState.appOpMode = ops.get(0).getOps().get(0).getMode(); 1167f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1177f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } catch (RemoteException e) { 1187f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Log.w(TAG, "PackageManager is dead. Can't get package info " + pkg, e); 1197f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1207f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return permissionState; 1217f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1227f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1237f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau @Override 1247f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau protected void loadAllExtraInfo() { 1257f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau SparseArray<ArrayMap<String, PermissionState>> entries = getEntries(); 1267f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1277f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Load state info. 1287f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau loadPermissionsStates(entries); 1297f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau loadAppOpsStates(entries); 1307f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1317f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Map states to application info. 1327f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau List<AppEntry> apps = mAppSession.getAllApps(); 1337f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int N = apps.size(); 1347f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (int i = 0; i < N; i++) { 1357f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau AppEntry app = apps.get(i); 1367f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau int userId = UserHandle.getUserId(app.info.uid); 1377f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau ArrayMap<String, PermissionState> userMap = entries.get(userId); 1387f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau app.extraInfo = userMap != null ? userMap.get(app.info.packageName) : null; 1397f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1407f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1417f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1427f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau /* 1437f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * Gets a sparse array that describes every user on the device and all the associated packages 1447f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * of each user, together with the packages available for that user. 1457f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 1467f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private SparseArray<ArrayMap<String, PermissionState>> getEntries() { 1477f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau try { 1483d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau Set<String> packagesSet = new HashSet<>(); 1493d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau for (String permission : mPermissions) { 1503d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau String[] pkgs = mIPackageManager.getAppOpPermissionPackages(permission); 1513d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau if (pkgs != null) { 1523d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau packagesSet.addAll(Arrays.asList(pkgs)); 1533d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau } 1543d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau } 1557f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1563d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau if (packagesSet.isEmpty()) { 1577f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // No packages are requesting permission as specified by mPermissions. 1587f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return null; 1597f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1607f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1617f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Create a sparse array that maps profileIds to an ArrayMap that maps package names to 1627f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // an associated PermissionState object 1637f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau SparseArray<ArrayMap<String, PermissionState>> entries = new SparseArray<>(); 1647f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (final UserHandle profile : mProfiles) { 1657f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final ArrayMap<String, PermissionState> entriesForProfile = new ArrayMap<>(); 1667f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int profileId = profile.getIdentifier(); 1677f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau entries.put(profileId, entriesForProfile); 1683d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau for (final String packageName : packagesSet) { 1697f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final boolean isAvailable = mIPackageManager.isPackageAvailable(packageName, 1707f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau profileId); 1717f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (!shouldIgnorePackage(packageName) && isAvailable) { 1727f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final PermissionState newEntry = new PermissionState(packageName, profile); 1737f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau entriesForProfile.put(packageName, newEntry); 1747f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1757f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1767f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1777f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1787f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return entries; 1797f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } catch (RemoteException e) { 1807f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Log.w(TAG, "PackageManager is dead. Can't get list of packages requesting " 1817f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau + mPermissions[0], e); 1827f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return null; 1837f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1847f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1857f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 1867f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau /* 187fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau * This method will set the packageInfo and staticPermissionGranted field of the associated 1887f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * PermissionState, which describes a particular package. 1897f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 1907f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private void loadPermissionsStates(SparseArray<ArrayMap<String, PermissionState>> entries) { 1917f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Load the packages that have been granted the permission specified in mPermission. 1927f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau try { 1937f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (final UserHandle profile : mProfiles) { 1947f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int profileId = profile.getIdentifier(); 1957f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final ArrayMap<String, PermissionState> entriesForProfile = entries.get(profileId); 1967f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entriesForProfile == null) { 1977f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau continue; 1987f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 1997f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau @SuppressWarnings("unchecked") 2007f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final List<PackageInfo> packageInfos = mIPackageManager 2017f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau .getPackagesHoldingPermissions(mPermissions, 0, profileId).getList(); 2027f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int packageInfoCount = packageInfos != null ? packageInfos.size() : 0; 2037f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (int i = 0; i < packageInfoCount; i++) { 2047f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final PackageInfo packageInfo = packageInfos.get(i); 2057f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final PermissionState pe = entriesForProfile.get(packageInfo.packageName); 2067f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (pe != null) { 2077f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau pe.packageInfo = packageInfo; 208fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau pe.staticPermissionGranted = true; 2097f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2107f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2117f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2127f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } catch (RemoteException e) { 2137f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Log.w(TAG, "PackageManager is dead. Can't get list of packages granted " 2143d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau + mPermissions, e); 2157f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return; 2167f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2177f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2187f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2197f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau /* 2207f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * This method will set the appOpMode field of the associated PermissionState, which describes 2217f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * a particular package. 2227f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 2237f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private void loadAppOpsStates(SparseArray<ArrayMap<String, PermissionState>> entries) { 2247f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // Find out which packages have been granted permission from AppOps. 2257f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final List<AppOpsManager.PackageOps> packageOps = mAppOpsManager.getPackagesForOps( 2267f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau mAppOpsOpCodes); 2277f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int packageOpsCount = packageOps != null ? packageOps.size() : 0; 2287f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (int i = 0; i < packageOpsCount; i++) { 2297f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final AppOpsManager.PackageOps packageOp = packageOps.get(i); 2307f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final int userId = UserHandle.getUserId(packageOp.getUid()); 2317f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (!isThisUserAProfileOfCurrentUser(userId)) { 2327f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // This AppOp does not belong to any of this user's profiles. 2337f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau continue; 2347f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2357f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2367f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final ArrayMap<String, PermissionState> entriesForProfile = entries.get(userId); 2377f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entriesForProfile == null) { 2387f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau continue; 2397f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2407f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final PermissionState pe = entriesForProfile.get(packageOp.getPackageName()); 2417f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (pe == null) { 2427f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Log.w(TAG, "AppOp permission exists for package " + packageOp.getPackageName() 2437f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau + " of user " + userId + " but package doesn't exist or did not request " 2443d9c7fc9982ddd513bc1bebdce76a12eecb61c88Billy Lau + mPermissions + " access"); 2457f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau continue; 2467f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2477f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2487f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (packageOp.getOps().size() < 1) { 2497f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Log.w(TAG, "No AppOps permission exists for package " + packageOp.getPackageName()); 2507f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau continue; 2517f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2527f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau pe.appOpMode = packageOp.getOps().get(0).getMode(); 2537f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2547f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2557f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2567f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau /* 2577f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau * Check for packages that should be ignored for further processing 2587f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau */ 2597f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau private boolean shouldIgnorePackage(String packageName) { 2607f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return packageName.equals("android") || packageName.equals(mContext.getPackageName()); 2617f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2627f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2637f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public int getNumPackagesDeclaredPermission() { 2647f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau SparseArray<ArrayMap<String, PermissionState>> entries = getEntries(); 2657f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entries == null) { 2667f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return 0; 2677f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2687f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final ArrayMap<String, PermissionState> entriesForProfile = entries.get(mUserManager 2697f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau .getUserHandle()); 2707f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entriesForProfile == null) { 2717f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return 0; 2727f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2737f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return entriesForProfile.size(); 2747f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2757f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2767f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public int getNumPackagesAllowedByAppOps() { 2777f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau SparseArray<ArrayMap<String, PermissionState>> entries = getEntries(); 2787f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entries == null) { 2797f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return 0; 2807f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2817f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau loadPermissionsStates(entries); 2827f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau loadAppOpsStates(entries); 2837f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau final ArrayMap<String, PermissionState> entriesForProfile = entries.get(mUserManager 2847f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau .getUserHandle()); 2857f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (entriesForProfile == null) { 2867f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return 0; 2877f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2887f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau Collection<PermissionState> permStates = entriesForProfile.values(); 2897f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau int result = 0; 2907f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau for (PermissionState permState : permStates) { 2917f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (permState.isPermissible()) { 2927f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau result++; 2937f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2947f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2957f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return result; 2967f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 2977f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 2987f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public static class PermissionState { 2997f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public final String packageName; 3007f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public final UserHandle userHandle; 3017f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public PackageInfo packageInfo; 302fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau public boolean staticPermissionGranted; 3037f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public boolean permissionDeclared; 3047f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public int appOpMode; 3057f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 3067f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public PermissionState(String packageName, UserHandle userHandle) { 3077f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau this.packageName = packageName; 3087f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau this.appOpMode = AppOpsManager.MODE_DEFAULT; 3097f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau this.userHandle = userHandle; 3107f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3117f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau 3127f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau public boolean isPermissible() { 3137f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // defining the default behavior as permissible as long as the package requested this 3147f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // permission (this means pre-M gets approval during install time; M apps gets approval 3157f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau // during runtime. 3167f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau if (appOpMode == AppOpsManager.MODE_DEFAULT) { 317fee785645b57c519a31ed403e60e8f76dcc8abbbBilly Lau return staticPermissionGranted; 3187f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3197f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau return appOpMode == AppOpsManager.MODE_ALLOWED; 3207f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3217f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau } 3227f70ba18e6760c2539704c16cf3865bf49953d50Billy Lau} 323