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