diff options
author | Svet Ganov <svetoslavganov@google.com> | 2015-05-16 22:45:19 -0700 |
---|---|---|
committer | Svet Ganov <svetoslavganov@google.com> | 2015-05-17 00:01:15 -0700 |
commit | 267c2bd39c248eea2679c0a8efa334d3155e262c (patch) | |
tree | 74a752ae544c45fb8f4a6e0b1003c76703f68104 /src/com/android/packageinstaller/permission/model/PermissionGroups.java | |
parent | d7f8200201563ca300572e2b56100acfd010140d (diff) | |
download | android_packages_apps_PackageInstaller-267c2bd39c248eea2679c0a8efa334d3155e262c.tar.gz android_packages_apps_PackageInstaller-267c2bd39c248eea2679c0a8efa334d3155e262c.tar.bz2 android_packages_apps_PackageInstaller-267c2bd39c248eea2679c0a8efa334d3155e262c.zip |
Hide platform platform legacy permissions behind a menu option - package installer.
bug:21195624
Change-Id: If6de516d76969c3627316d091893da58f81af832
Diffstat (limited to 'src/com/android/packageinstaller/permission/model/PermissionGroups.java')
-rw-r--r-- | src/com/android/packageinstaller/permission/model/PermissionGroups.java | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroups.java b/src/com/android/packageinstaller/permission/model/PermissionGroups.java new file mode 100644 index 00000000..62477b88 --- /dev/null +++ b/src/com/android/packageinstaller/permission/model/PermissionGroups.java @@ -0,0 +1,222 @@ +/* + * 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.app.LoaderManager; +import android.app.LoaderManager.LoaderCallbacks; +import android.content.AsyncTaskLoader; +import android.content.Context; +import android.content.Loader; +import android.content.pm.PackageInfo; +import android.content.pm.PackageItemInfo; +import android.content.pm.PackageManager; +import android.content.pm.PermissionGroupInfo; +import android.content.pm.PermissionInfo; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.util.ArraySet; + +import com.android.packageinstaller.R; +import com.android.packageinstaller.permission.utils.Utils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public final class PermissionGroups implements LoaderCallbacks<List<PermissionGroup>> { + private final ArrayList<PermissionGroup> mGroups = new ArrayList<>(); + private final Context mContext; + private final LoaderManager mLoaderManager; + private final PermissionsGroupsChangeCallback mCallback; + + public interface PermissionsGroupsChangeCallback { + public void onPermissionGroupsChanged(); + } + + public PermissionGroups(Context context, LoaderManager loaderManager, + PermissionsGroupsChangeCallback callback) { + mContext = context; + mLoaderManager = loaderManager; + mCallback = callback; + } + + @Override + public Loader<List<PermissionGroup>> onCreateLoader(int id, Bundle args) { + return new PermissionsLoader(mContext); + } + + @Override + public void onLoadFinished(Loader<List<PermissionGroup>> loader, + List<PermissionGroup> groups) { + if (mGroups.equals(groups)) { + return; + } + mGroups.clear(); + mGroups.addAll(groups); + mCallback.onPermissionGroupsChanged(); + } + + @Override + public void onLoaderReset(Loader<List<PermissionGroup>> loader) { + mGroups.clear(); + mCallback.onPermissionGroupsChanged(); + } + + public void refresh() { + mLoaderManager.restartLoader(0, null, this); + mLoaderManager.getLoader(0).forceLoad(); + } + + public List<PermissionGroup> getGroups() { + return mGroups; + } + + public PermissionGroup getGroup(String name) { + for (PermissionGroup group : mGroups) { + if (group.getName().equals(name)) { + return group; + } + } + return null; + } + + private static final class PermissionsLoader extends AsyncTaskLoader<List<PermissionGroup>> { + + public PermissionsLoader(Context context) { + super(context); + } + + @Override + public List<PermissionGroup> loadInBackground() { + List<PermissionGroup> groups = new ArrayList<>(); + Set<String> seenPermissions = new ArraySet<>(); + + + PackageManager packageManager = getContext().getPackageManager(); + List<PermissionGroupInfo> groupInfos = packageManager.getAllPermissionGroups(0); + + for (PermissionGroupInfo groupInfo : groupInfos) { + // Mare sure we respond to cancellation. + if (isLoadInBackgroundCanceled()) { + return Collections.emptyList(); + } + + // Get the permissions in this group. + final List<PermissionInfo> groupPermissions; + try { + groupPermissions = packageManager.queryPermissionsByGroup(groupInfo.name, 0); + } catch (PackageManager.NameNotFoundException e) { + continue; + } + + boolean hasRuntimePermissions = false; + + // Cache seen permissions and see if group has runtime permissions. + for (PermissionInfo groupPermission : groupPermissions) { + seenPermissions.add(groupPermission.name); + if (groupPermission.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) { + hasRuntimePermissions = true; + } + } + + // No runtime permissions - not interesting for us. + if (!hasRuntimePermissions) { + continue; + } + + CharSequence label = loadItemInfoLabel(groupInfo); + Drawable icon = loadItemInfoIcon(groupInfo); + + // Create the group and add to the list. + PermissionGroup group = new PermissionGroup(groupInfo.name, + groupInfo.packageName, label, icon); + groups.add(group); + } + + + // Make sure we add groups for lone runtime permissions. + List<PackageInfo> installedPackages = getContext().getPackageManager() + .getInstalledPackages(PackageManager.GET_PERMISSIONS); + + + // We will filter out permissions that no package requests. + Set<String> requestedPermissions = new ArraySet<>(); + for (PackageInfo installedPackage : installedPackages) { + if (installedPackage.requestedPermissions == null) { + break; + } + for (String requestedPermission : installedPackage.requestedPermissions) { + requestedPermissions.add(requestedPermission); + } + } + + for (PackageInfo installedPackage : installedPackages) { + if (installedPackage.permissions == null) { + continue; + } + + for (PermissionInfo permissionInfo : installedPackage.permissions) { + // If we have handled this permission, no more work to do. + if (!seenPermissions.add(permissionInfo.name)) { + continue; + } + + // We care only about runtime permissions. + if (permissionInfo.protectionLevel != PermissionInfo.PROTECTION_DANGEROUS) { + continue; + } + + // If no app uses this permission, + if (!requestedPermissions.contains(permissionInfo.name)) { + continue; + } + + CharSequence label = loadItemInfoLabel(permissionInfo); + Drawable icon = loadItemInfoIcon(permissionInfo); + + // Create the group and add to the list. + PermissionGroup group = new PermissionGroup(permissionInfo.name, + permissionInfo.packageName, label, icon); + groups.add(group); + } + } + + Collections.sort(groups); + return groups; + } + + private CharSequence loadItemInfoLabel(PackageItemInfo itemInfo) { + CharSequence label = itemInfo.loadLabel(getContext().getPackageManager()); + if (label == null) { + label = itemInfo.name; + } + return label; + } + + private Drawable loadItemInfoIcon(PackageItemInfo itemInfo) { + final Drawable icon; + if (itemInfo.icon > 0) { + icon = Utils.loadDrawable(getContext().getPackageManager(), + itemInfo.packageName, itemInfo.icon); + } else { + icon = getContext().getDrawable(R.drawable.ic_perm_device_info); + } + return icon; + } + } +} |