diff options
author | Jason Monk <jmonk@google.com> | 2015-05-20 16:43:42 -0400 |
---|---|---|
committer | Jason Monk <jmonk@google.com> | 2015-05-26 11:10:21 -0400 |
commit | 93568c580d730911a6e2734e79fbe6dc27c1bca1 (patch) | |
tree | fce9e658e4e118792f07b725426ecd29083d9c03 /src/com/android/packageinstaller/permission/model | |
parent | 0b085665998b69aa9543d50ecca1a5bc62d6bb77 (diff) | |
download | android_packages_apps_PackageInstaller-93568c580d730911a6e2734e79fbe6dc27c1bca1.tar.gz android_packages_apps_PackageInstaller-93568c580d730911a6e2734e79fbe6dc27c1bca1.tar.bz2 android_packages_apps_PackageInstaller-93568c580d730911a6e2734e79fbe6dc27c1bca1.zip |
Add permission summaries back
- Add summaries to manage permissions screen
- Add some shortcuts to skip loading unneeded labels/icons
for summary info
- Add way for Settings to broadcast request for info about
granted permissions.
Bug: 21078474
Change-Id: I28582129971385203f4e4316addf73e07ee53940
Diffstat (limited to 'src/com/android/packageinstaller/permission/model')
-rw-r--r-- | src/com/android/packageinstaller/permission/model/PermissionApps.java | 276 | ||||
-rw-r--r-- | src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java | 93 |
2 files changed, 271 insertions, 98 deletions
diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java index 7191381d..06ef7981 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionApps.java +++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java @@ -29,6 +29,9 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; import android.util.Log; +import android.util.SparseArray; + +import com.android.packageinstaller.permission.utils.Utils; import java.util.ArrayList; import java.util.Collection; @@ -43,25 +46,63 @@ public class PermissionApps { private final PackageManager mPm; private final Callback mCallback; + private final PmCache mCache; + private CharSequence mLabel; private Drawable mIcon; private List<PermissionApp> mPermApps; // Map (pkg|uid) -> AppPermission private ArrayMap<String, PermissionApp> mAppLookup; + private boolean mSkipUi; + public PermissionApps(Context context, String groupName, Callback callback) { + this(context, groupName, callback, null); + } + + public PermissionApps(Context context, String groupName, Callback callback, PmCache cache) { + mCache = cache; mContext = context; mPm = mContext.getPackageManager(); mGroupName = groupName; mCallback = callback; loadGroupInfo(); - new PermissionAppsLoader().execute(); } - public void refresh() { + public void loadNowWithoutUi() { + mSkipUi = true; + createMap(loadPermissionApps()); + } + + public void refresh(boolean getUiInfo) { + mSkipUi = !getUiInfo; new PermissionAppsLoader().execute(); } + public int getGrantedCount() { + int count = 0; + for (PermissionApp app : mPermApps) { + if (!Utils.shouldShowPermission(app)) { + continue; + } + if (app.areRuntimePermissionsGranted()) { + count++; + } + } + return count; + } + + public int getTotalCount() { + int count = 0; + for (PermissionApp app : mPermApps) { + if (!Utils.shouldShowPermission(app)) { + continue; + } + count++; + } + return count; + } + public Collection<PermissionApp> getApps() { return mPermApps; } @@ -78,6 +119,114 @@ public class PermissionApps { return mIcon; } + private List<PermissionApp> loadPermissionApps() { + PackageItemInfo groupInfo = getGroupInfo(mGroupName); + if (groupInfo == null) { + return Collections.emptyList(); + } + + List<PermissionInfo> groupPermInfos = getGroupPermissionInfos(mGroupName); + if (groupPermInfos == null) { + return Collections.emptyList(); + } + + ArrayList<PermissionApp> permApps = new ArrayList<>(); + + for (UserHandle user : UserManager.get(mContext).getUserProfiles()) { + List<PackageInfo> apps = mCache != null ? mCache.getPackages(user.getIdentifier()) + : mPm.getInstalledPackages(PackageManager.GET_PERMISSIONS, + user.getIdentifier()); + + final int N = apps.size(); + for (int i = 0; i < N; i++) { + PackageInfo app = apps.get(i); + if (app.requestedPermissions == null) { + continue; + } + + for (int j = 0; j < app.requestedPermissions.length; j++) { + String requestedPerm = app.requestedPermissions[j]; + + boolean requestsPermissionInGroup = false; + + for (PermissionInfo groupPermInfo : groupPermInfos) { + if (groupPermInfo.name.equals(requestedPerm)) { + requestsPermissionInGroup = true; + break; + } + } + + if (!requestsPermissionInGroup) { + continue; + } + + AppPermissionGroup group = AppPermissionGroup.create(mContext, + app, groupInfo, groupPermInfos); + + String label = mSkipUi ? app.packageName + : app.applicationInfo.loadLabel(mPm).toString(); + PermissionApp permApp = new PermissionApp(app.packageName, + group, label, getBadgedIcon(app.applicationInfo)); + + permApps.add(permApp); + } + } + } + + Collections.sort(permApps); + + return permApps; + } + + private void createMap(List<PermissionApp> result) { + mAppLookup = new ArrayMap<>(); + for (PermissionApp app : result) { + mAppLookup.put(app.getKey(), app); + } + mPermApps = result; + } + + private PackageItemInfo getGroupInfo(String groupName) { + try { + return mContext.getPackageManager().getPermissionGroupInfo(groupName, 0); + } catch (NameNotFoundException e) { + /* ignore */ + } + try { + return mContext.getPackageManager().getPermissionInfo(groupName, 0); + } catch (NameNotFoundException e2) { + /* ignore */ + } + return null; + } + + private List<PermissionInfo> getGroupPermissionInfos(String groupName) { + try { + return mContext.getPackageManager().queryPermissionsByGroup(groupName, 0); + } catch (NameNotFoundException e) { + /* ignore */ + } + try { + PermissionInfo permissionInfo = mContext.getPackageManager() + .getPermissionInfo(groupName, 0); + List<PermissionInfo> permissions = new ArrayList<>(); + permissions.add(permissionInfo); + return permissions; + } catch (NameNotFoundException e2) { + /* ignore */ + } + return null; + } + + private Drawable getBadgedIcon(ApplicationInfo appInfo) { + if (mSkipUi) { + return null; + } + Drawable unbadged = appInfo.loadUnbadgedIcon(mPm); + return mPm.getUserBadgedIcon(unbadged, + new UserHandle(UserHandle.getUserId(appInfo.uid))); + } + private void loadGroupInfo() { PackageItemInfo info; try { @@ -177,120 +326,51 @@ public class PermissionApps { return result; } - private int getUid() { + public int getUid() { return mAppPermissionGroup.getApp().applicationInfo.uid; } } private class PermissionAppsLoader extends AsyncTask<Void, Void, List<PermissionApp>> { + @Override protected List<PermissionApp> doInBackground(Void... args) { - PackageItemInfo groupInfo = getGroupInfo(mGroupName); - if (groupInfo == null) { - return Collections.emptyList(); - } - - List<PermissionInfo> groupPermInfos = getGroupPermissionInfos(mGroupName); - if (groupPermInfos == null) { - return Collections.emptyList(); - } - - ArrayList<PermissionApp> permApps = new ArrayList<>(); - - for (UserHandle user : UserManager.get(mContext).getUserProfiles()) { - List<PackageInfo> apps = mPm.getInstalledPackages( - PackageManager.GET_PERMISSIONS, user.getIdentifier()); - - final int N = apps.size(); - for (int i = 0; i < N; i++) { - PackageInfo app = apps.get(i); - if (app.requestedPermissions == null) { - continue; - } - - for (int j = 0; j < app.requestedPermissions.length; j++) { - String requestedPerm = app.requestedPermissions[j]; - - boolean requestsPermissionInGroup = false; - - for (PermissionInfo groupPermInfo : groupPermInfos) { - if (groupPermInfo.name.equals(requestedPerm)) { - requestsPermissionInGroup = true; - break; - } - } - - if (!requestsPermissionInGroup) { - continue; - } - - AppPermissionGroup group = AppPermissionGroup.create(mContext, - app, groupInfo, groupPermInfos); - - PermissionApp permApp = new PermissionApp(app.packageName, - group, app.applicationInfo.loadLabel(mPm).toString(), - getBadgedIcon(app.applicationInfo)); - - permApps.add(permApp); - } - } - } - - Collections.sort(permApps); - - return permApps; + return loadPermissionApps(); } - private PackageItemInfo getGroupInfo(String groupName) { - try { - return mContext.getPackageManager().getPermissionGroupInfo(groupName, 0); - } catch (NameNotFoundException e) { - /* ignore */ - } - try { - return mContext.getPackageManager().getPermissionInfo(groupName, 0); - } catch (NameNotFoundException e2) { - /* ignore */ - } - return null; - } - - private List<PermissionInfo> getGroupPermissionInfos(String groupName) { - try { - return mContext.getPackageManager().queryPermissionsByGroup(groupName, 0); - } catch (NameNotFoundException e) { - /* ignore */ - } - try { - PermissionInfo permissionInfo = mContext.getPackageManager() - .getPermissionInfo(groupName, 0); - List<PermissionInfo> permissions = new ArrayList<>(); - permissions.add(permissionInfo); - return permissions; - } catch (NameNotFoundException e2) { - /* ignore */ + @Override + protected void onPostExecute(List<PermissionApp> result) { + createMap(result); + if (mCallback != null) { + mCallback.onPermissionsLoaded(PermissionApps.this); } - return null; } + } - private Drawable getBadgedIcon(ApplicationInfo appInfo) { - Drawable unbadged = appInfo.loadUnbadgedIcon(mPm); - return mPm.getUserBadgedIcon(unbadged, - new UserHandle(UserHandle.getUserId(appInfo.uid))); + /** + * Class used to reduce the number of calls to the package manager. + * This caches app information so it should only be used across parallel PermissionApps + * instances, and should not be retained across UI refresh. + */ + public static class PmCache { + private final SparseArray<List<PackageInfo>> mPackageInfoCache = new SparseArray<>(); + private final PackageManager mPm; + + public PmCache(PackageManager pm) { + mPm = pm; } - @Override - protected void onPostExecute(List<PermissionApp> result) { - mAppLookup = new ArrayMap<>(); - for (PermissionApp app : result) { - mAppLookup.put(app.getKey(), app); + public synchronized List<PackageInfo> getPackages(int userId) { + List<PackageInfo> ret = mPackageInfoCache.get(userId); + if (ret == null) { + ret = mPm.getInstalledPackages(PackageManager.GET_PERMISSIONS, userId); + mPackageInfoCache.put(userId, ret); } - mPermApps = result; - mCallback.onPermissionsLoaded(); + return ret; } } public interface Callback { - void onPermissionsLoaded(); + void onPermissionsLoaded(PermissionApps permissionApps); } } diff --git a/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java b/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java new file mode 100644 index 00000000..f84a0757 --- /dev/null +++ b/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.packageinstaller.permission.model; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.util.SparseArray; + +import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; +import com.android.packageinstaller.permission.utils.Utils; + +public class PermissionStatusReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + int[] result = new int[2]; + boolean succeeded = false; + Intent responseIntent = new Intent(intent.getStringExtra( + Intent.EXTRA_GET_PERMISSIONS_RESPONSE_INTENT)); + responseIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); + if (intent.hasExtra(Intent.EXTRA_PACKAGE_NAME)) { + String pkg = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); + succeeded = getPermissionsCount(context, pkg, result); + } else { + succeeded = getAppsWithPermissionsCount(context, result); + } + responseIntent.putExtra(Intent.EXTRA_GET_PERMISSIONS_COUNT_RESULT, + succeeded ? result : null); + context.sendBroadcast(responseIntent); + } + + public boolean getPermissionsCount(Context context, String pkg, int[] counts) { + try { + PackageInfo packageInfo = + context.getPackageManager().getPackageInfo(pkg, PackageManager.GET_PERMISSIONS); + AppPermissions appPermissions = + new AppPermissions(context, packageInfo, null, null); + int grantedCount = 0; + int totalCount = 0; + for (AppPermissionGroup group : appPermissions.getPermissionGroups()) { + if (Utils.shouldShowPermission(group, false)) { + totalCount++; + if (group.areRuntimePermissionsGranted()) { + grantedCount++; + } + } + } + counts[0] = grantedCount; + counts[1] = totalCount; + return true; + } catch (NameNotFoundException e) { + return false; + } + } + + public boolean getAppsWithPermissionsCount(Context context, int[] counts) { + // Indexed by uid. + SparseArray<Boolean> grantedApps = new SparseArray<>(); + SparseArray<Boolean> allApps = new SparseArray<>(); + for (String group : Utils.MODERN_PERMISSION_GROUPS) { + PermissionApps permissionApps = new PermissionApps(context, + group, null); + permissionApps.loadNowWithoutUi(); + for (PermissionApp app : permissionApps.getApps()) { + int uid = app.getUid(); + if (app.areRuntimePermissionsGranted()) { + grantedApps.put(uid, true); + } + allApps.put(uid, true); + } + } + counts[0] = grantedApps.size(); + counts[1] = allApps.size(); + return true; + } +} |