summaryrefslogtreecommitdiffstats
path: root/src/com/android/packageinstaller/permission/model
diff options
context:
space:
mode:
authorJason Monk <jmonk@google.com>2015-05-20 16:43:42 -0400
committerJason Monk <jmonk@google.com>2015-05-26 11:10:21 -0400
commit93568c580d730911a6e2734e79fbe6dc27c1bca1 (patch)
treefce9e658e4e118792f07b725426ecd29083d9c03 /src/com/android/packageinstaller/permission/model
parent0b085665998b69aa9543d50ecca1a5bc62d6bb77 (diff)
downloadandroid_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.java276
-rw-r--r--src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java93
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;
+ }
+}