diff options
Diffstat (limited to 'src/com/android/packageinstaller/permission/model')
6 files changed, 276 insertions, 124 deletions
diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index e54b7029..a6601165 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -25,10 +25,12 @@ import android.content.pm.PackageManager; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.os.Build; +import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; import com.android.packageinstaller.R; +import com.android.packageinstaller.permission.utils.ArrayUtils; import com.android.packageinstaller.permission.utils.LocationUtils; import java.util.ArrayList; @@ -67,7 +69,7 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup> if (permissionInfo.protectionLevel != PermissionInfo.PROTECTION_DANGEROUS || (permissionInfo.flags & PermissionInfo.FLAG_INSTALLED) == 0 - || (permissionInfo.flags & PermissionInfo.FLAG_HIDDEN) != 0) { + || (permissionInfo.flags & PermissionInfo.FLAG_REMOVED) != 0) { return null; } @@ -92,7 +94,7 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup> } return create(context, packageInfo, groupInfo, permissionInfos, - new UserHandle(context.getUserId())); + Process.myUserHandle()); } public static AppPermissionGroup create(Context context, PackageInfo packageInfo, @@ -135,21 +137,20 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup> continue; } - // Don't allow toggle of non platform defined permissions for legacy apps via app ops. + // Don't allow toggling non-platform permission groups for legacy apps via app ops. if (packageInfo.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1 - && !PLATFORM_PACKAGE_NAME.equals(requestedPermissionInfo.packageName)) { + && !PLATFORM_PACKAGE_NAME.equals(groupInfo.packageName)) { continue; } final boolean granted = (packageInfo.requestedPermissionsFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0; - final int appOp = PLATFORM_PACKAGE_NAME.equals(requestedPermissionInfo.packageName) - ? AppOpsManager.permissionToOpCode(requestedPermissionInfo.name) - : AppOpsManager.OP_NONE; + final String appOp = PLATFORM_PACKAGE_NAME.equals(requestedPermissionInfo.packageName) + ? AppOpsManager.permissionToOp(requestedPermissionInfo.name) : null; - final boolean appOpAllowed = appOp != AppOpsManager.OP_NONE - && context.getSystemService(AppOpsManager.class).checkOp(appOp, + final boolean appOpAllowed = appOp != null + && context.getSystemService(AppOpsManager.class).checkOpNoThrow(appOp, packageInfo.applicationInfo.uid, packageInfo.packageName) == AppOpsManager.MODE_ALLOWED; @@ -209,23 +210,39 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup> return mAppSupportsRuntimePermissions; } - - public boolean hasGrantedByDefaultPermission() { + public boolean isReviewRequired() { + if (mAppSupportsRuntimePermissions) { + return false; + } final int permissionCount = mPermissions.size(); for (int i = 0; i < permissionCount; i++) { Permission permission = mPermissions.valueAt(i); - if (permission.isGrantedByDefault()) { + if (permission.isReviewRequired()) { return true; } } return false; } - public boolean hasAppOpPermission() { + public void resetReviewRequired() { + final int permissionCount = mPermissions.size(); + for (int i = 0; i < permissionCount; i++) { + Permission permission = mPermissions.valueAt(i); + if (permission.isReviewRequired()) { + permission.resetReviewRequired(); + mPackageManager.updatePermissionFlags(permission.getName(), + mPackageInfo.packageName, + PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, + 0, mUserHandle); + } + } + } + + public boolean hasGrantedByDefaultPermission() { final int permissionCount = mPermissions.size(); for (int i = 0; i < permissionCount; i++) { Permission permission = mPermissions.valueAt(i); - if (permission.getAppOp() != AppOpsManager.OP_NONE) { + if (permission.isGrantedByDefault()) { return true; } } @@ -260,24 +277,35 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup> return mDescription; } + public int getUserId() { + return mUserHandle.getIdentifier(); + } + public boolean hasPermission(String permission) { return mPermissions.get(permission) != null; } public boolean areRuntimePermissionsGranted() { + return areRuntimePermissionsGranted(null); + } + + public boolean areRuntimePermissionsGranted(String[] filterPermissions) { if (LocationUtils.isLocationGroupAndProvider(mName, mPackageInfo.packageName)) { return LocationUtils.isLocationEnabled(mContext); } final int permissionCount = mPermissions.size(); for (int i = 0; i < permissionCount; i++) { Permission permission = mPermissions.valueAt(i); + if (filterPermissions != null + && !ArrayUtils.contains(filterPermissions, permission.getName())) { + continue; + } if (mAppSupportsRuntimePermissions) { if (permission.isGranted()) { return true; } - } else if (permission.isGranted() && ((permission.getAppOp() - != AppOpsManager.OP_NONE && permission.isAppOpAllowed()) - || permission.getAppOp() == AppOpsManager.OP_NONE)) { + } else if (permission.isGranted() && (permission.getAppOp() == null + || permission.isAppOpAllowed())) { return true; } } @@ -285,13 +313,21 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup> } public boolean grantRuntimePermissions(boolean fixedByTheUser) { - final boolean isSharedUser = mPackageInfo.sharedUserId != null; + return grantRuntimePermissions(fixedByTheUser, null); + } + + public boolean grantRuntimePermissions(boolean fixedByTheUser, String[] filterPermissions) { final int uid = mPackageInfo.applicationInfo.uid; // We toggle permissions only to apps that support runtime // permissions, otherwise we toggle the app op corresponding // to the permission if the permission is granted to the app. for (Permission permission : mPermissions.values()) { + if (filterPermissions != null + && !ArrayUtils.contains(filterPermissions, permission.getName())) { + continue; + } + if (mAppSupportsRuntimePermissions) { // Do not touch permissions fixed by the system. if (permission.isSystemFixed()) { @@ -327,43 +363,42 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup> } } else { // Legacy apps cannot have a not granted permission but just in case. - // Also if the permissions has no corresponding app op, then it is a - // third-party one and we do not offer toggling of such permissions. - if (!permission.isGranted() || !permission.hasAppOp()) { + if (!permission.isGranted()) { continue; } - if (!permission.isAppOpAllowed()) { - permission.setAppOpAllowed(true); - // It this is a shared user we want to enable the app op for all - // packages in the shared user to match the behavior of this - // shared user having a runtime permission. - if (isSharedUser) { - // Enable the app op. - String[] packageNames = mPackageManager.getPackagesForUid(uid); - for (String packageName : packageNames) { - mAppOps.setUidMode(permission.getAppOp(), uid, - AppOpsManager.MODE_ALLOWED); - } - } else { + int killUid = -1; + int mask = 0; + + // If the permissions has no corresponding app op, then it is a + // third-party one and we do not offer toggling of such permissions. + if (permission.hasAppOp()) { + if (!permission.isAppOpAllowed()) { + permission.setAppOpAllowed(true); // Enable the app op. mAppOps.setUidMode(permission.getAppOp(), uid, AppOpsManager.MODE_ALLOWED); + + // Legacy apps do not know that they have to retry access to a + // resource due to changes in runtime permissions (app ops in this + // case). Therefore, we restart them on app op change, so they + // can pick up the change. + killUid = uid; } // Mark that the permission should not be be granted on upgrade // when the app begins supporting runtime permissions. if (permission.shouldRevokeOnUpgrade()) { permission.setRevokeOnUpgrade(false); - mPackageManager.updatePermissionFlags(permission.getName(), - mPackageInfo.packageName, - PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, - 0, mUserHandle); + mask |= PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; } + } + + if (mask != 0) { + mPackageManager.updatePermissionFlags(permission.getName(), + mPackageInfo.packageName, mask, 0, mUserHandle); + } - // Legacy apps do not know that they have to retry access to a - // resource due to changes in runtime permissions (app ops in this - // case). Therefore, we restart them on app op change, so they - // can pick up the change. + if (killUid != -1) { mActivityManager.killUid(uid, KILL_REASON_APP_OP_CHANGE); } } @@ -373,13 +408,21 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup> } public boolean revokeRuntimePermissions(boolean fixedByTheUser) { - final boolean isSharedUser = mPackageInfo.sharedUserId != null; + return revokeRuntimePermissions(fixedByTheUser, null); + } + + public boolean revokeRuntimePermissions(boolean fixedByTheUser, String[] filterPermissions) { final int uid = mPackageInfo.applicationInfo.uid; // We toggle permissions only to apps that support runtime // permissions, otherwise we toggle the app op corresponding // to the permission if the permission is granted to the app. for (Permission permission : mPermissions.values()) { + if (filterPermissions != null + && !ArrayUtils.contains(filterPermissions, permission.getName())) { + continue; + } + if (mAppSupportsRuntimePermissions) { // Do not touch permissions fixed by the system. if (permission.isSystemFixed()) { @@ -419,43 +462,43 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup> } } else { // Legacy apps cannot have a non-granted permission but just in case. - // Also if the permission has no corresponding app op, then it is a - // third-party one and we do not offer toggling of such permissions. - if (!permission.isGranted() || !permission.hasAppOp()) { + if (!permission.isGranted()) { continue; } - if (permission.isAppOpAllowed()) { - permission.setAppOpAllowed(false); - // It this is a shared user we want to enable the app op for all - // packages the the shared user to match the behavior of this - // shared user having a runtime permission. - if (isSharedUser) { - String[] packageNames = mPackageManager.getPackagesForUid(uid); - for (String packageName : packageNames) { - // Disable the app op. - mAppOps.setUidMode(permission.getAppOp(), uid, - AppOpsManager.MODE_IGNORED); - } - } else { + int mask = 0; + int flags = 0; + int killUid = -1; + + // If the permission has no corresponding app op, then it is a + // third-party one and we do not offer toggling of such permissions. + if (permission.hasAppOp()) { + if (permission.isAppOpAllowed()) { + permission.setAppOpAllowed(false); // Disable the app op. mAppOps.setUidMode(permission.getAppOp(), uid, AppOpsManager.MODE_IGNORED); + + // Disabling an app op may put the app in a situation in which it + // has a handle to state it shouldn't have, so we have to kill the + // app. This matches the revoke runtime permission behavior. + killUid = uid; } // Mark that the permission should not be granted on upgrade // when the app begins supporting runtime permissions. if (!permission.shouldRevokeOnUpgrade()) { permission.setRevokeOnUpgrade(true); - mPackageManager.updatePermissionFlags(permission.getName(), - mPackageInfo.packageName, - PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, - PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, - mUserHandle); + mask |= PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; + flags |= PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; } + } + + if (mask != 0) { + mPackageManager.updatePermissionFlags(permission.getName(), + mPackageInfo.packageName, mask, flags, mUserHandle); + } - // Disabling an app op may put the app in a situation in which it - // has a handle to state it shouldn't have, so we have to kill the - // app. This matches the revoke runtime permission behavior. + if (killUid != -1) { mActivityManager.killUid(uid, KILL_REASON_APP_OP_CHANGE); } } diff --git a/src/com/android/packageinstaller/permission/model/AppPermissions.java b/src/com/android/packageinstaller/permission/model/AppPermissions.java index a0f23d64..e455ef13 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissions.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissions.java @@ -19,6 +19,7 @@ package com.android.packageinstaller.permission.model; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.os.Build; import android.text.BidiFormatter; import android.text.TextPaint; import android.text.TextUtils; @@ -31,16 +32,6 @@ import java.util.LinkedHashMap; import java.util.List; public final class AppPermissions { - private static final float MAX_APP_LABEL_LENGTH_PIXELS = 500; - - private static final TextPaint sAppLabelEllipsizePaint = new TextPaint(); - static { - sAppLabelEllipsizePaint.setAntiAlias(true); - // Both text size and width are given in absolute pixels, for consistent truncation - // across devices; this value corresponds to the default 14dip size on an xdhpi device. - sAppLabelEllipsizePaint.setTextSize(42); - } - private final ArrayList<AppPermissionGroup> mGroups = new ArrayList<>(); private final LinkedHashMap<String, AppPermissionGroup> mNameToGroupMap = new LinkedHashMap<>(); @@ -62,7 +53,9 @@ public final class AppPermissions { mContext = context; mPackageInfo = packageInfo; mFilterPermissions = permissions; - mAppLabel = loadEllipsizedAppLabel(context, packageInfo); + mAppLabel = BidiFormatter.getInstance().unicodeWrap( + packageInfo.applicationInfo.loadSafeLabel( + context.getPackageManager()).toString()); mSortGroups = sortGroups; mOnErrorCallback = onErrorCallback; loadPermissionGroups(); @@ -89,6 +82,19 @@ public final class AppPermissions { return mGroups; } + public boolean isReviewRequired() { + if (!Build.PERMISSIONS_REVIEW_REQUIRED) { + return false; + } + final int groupCount = mGroups.size(); + for (int i = 0; i < groupCount; i++) { + AppPermissionGroup group = mGroups.get(i); + if (group.isReviewRequired()) { + return true; + } + } + return false; + } private void loadPackageInfo() { try { @@ -163,16 +169,4 @@ public final class AppPermissions { } return false; } - - private static CharSequence loadEllipsizedAppLabel(Context context, PackageInfo packageInfo) { - String label = packageInfo.applicationInfo.loadLabel( - context.getPackageManager()).toString(); - String ellipsizedLabel = label.replace("\n", " "); - if (!DeviceUtils.isWear(context)) { - // Only ellipsize for non-Wear devices. - ellipsizedLabel = TextUtils.ellipsize(ellipsizedLabel, sAppLabelEllipsizePaint, - MAX_APP_LABEL_LENGTH_PIXELS, TextUtils.TruncateAt.END).toString(); - } - return BidiFormatter.getInstance().unicodeWrap(ellipsizedLabel); - } } diff --git a/src/com/android/packageinstaller/permission/model/Permission.java b/src/com/android/packageinstaller/permission/model/Permission.java index 1be4e75b..f9dc6e8e 100644 --- a/src/com/android/packageinstaller/permission/model/Permission.java +++ b/src/com/android/packageinstaller/permission/model/Permission.java @@ -16,19 +16,18 @@ package com.android.packageinstaller.permission.model; -import android.app.AppOpsManager; import android.content.pm.PackageManager; public final class Permission { private final String mName; - private final int mAppOp; + private final String mAppOp; private boolean mGranted; private boolean mAppOpAllowed; private int mFlags; public Permission(String name, boolean granted, - int appOp, boolean appOpAllowed, int flags) { + String appOp, boolean appOpAllowed, int flags) { mName = name; mGranted = granted; mAppOp = appOp; @@ -40,7 +39,7 @@ public final class Permission { return mName; } - public int getAppOp() { + public String getAppOp() { return mAppOp; } @@ -49,13 +48,21 @@ public final class Permission { } public boolean hasAppOp() { - return mAppOp != AppOpsManager.OP_NONE; + return mAppOp != null; } public boolean isGranted() { return mGranted; } + public boolean isReviewRequired() { + return (mFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0; + } + + public void resetReviewRequired() { + mFlags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; + } + public void setGranted(boolean mGranted) { this.mGranted = mGranted; } diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java index e5d96d55..be32f2ac 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionApps.java +++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java @@ -24,6 +24,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PermissionInfo; import android.graphics.drawable.Drawable; import android.os.AsyncTask; +import android.os.Process; import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; @@ -35,7 +36,6 @@ import com.android.packageinstaller.R; import com.android.packageinstaller.permission.utils.Utils; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; @@ -120,7 +120,7 @@ public class PermissionApps { return count; } - public Collection<PermissionApp> getApps() { + public List<PermissionApp> getApps() { return mPermApps; } @@ -149,9 +149,10 @@ public class PermissionApps { ArrayList<PermissionApp> permApps = new ArrayList<>(); - for (UserHandle user : UserManager.get(mContext).getUserProfiles()) { + UserManager userManager = mContext.getSystemService(UserManager.class); + for (UserHandle user : userManager.getUserProfiles()) { List<PackageInfo> apps = mCache != null ? mCache.getPackages(user.getIdentifier()) - : mPm.getInstalledPackages(PackageManager.GET_PERMISSIONS, + : mPm.getInstalledPackagesAsUser(PackageManager.GET_PERMISSIONS, user.getIdentifier()); final int N = apps.size(); @@ -182,17 +183,31 @@ public class PermissionApps { || (requestedPermissionInfo.flags & PermissionInfo.FLAG_INSTALLED) == 0 || (requestedPermissionInfo.flags - & PermissionInfo.FLAG_HIDDEN) != 0) { + & PermissionInfo.FLAG_REMOVED) != 0) { continue; } AppPermissionGroup group = AppPermissionGroup.create(mContext, app, groupInfo, groupPermInfos, user); + if (group == null) { + continue; + } + String label = mSkipUi ? app.packageName : app.applicationInfo.loadLabel(mPm).toString(); - PermissionApp permApp = new PermissionApp(app.packageName, - group, label, getBadgedIcon(app.applicationInfo), + + Drawable icon = null; + if (!mSkipUi) { + UserHandle userHandle = new UserHandle( + UserHandle.getUserId(group.getApp().applicationInfo.uid)); + + icon = mPm.getUserBadgedIcon( + mPm.loadUnbadgedItemIcon(app.applicationInfo, app.applicationInfo), + userHandle); + } + + PermissionApp permApp = new PermissionApp(app.packageName, group, label, icon, app.applicationInfo); permApps.add(permApp); @@ -246,15 +261,6 @@ public class PermissionApps { 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 { @@ -317,6 +323,10 @@ public class PermissionApps { return mAppPermissionGroup.areRuntimePermissionsGranted(); } + public boolean isReviewRequired() { + return mAppPermissionGroup.isReviewRequired(); + } + public void grantRuntimePermissions() { mAppPermissionGroup.grantRuntimePermissions(false); } @@ -341,8 +351,8 @@ public class PermissionApps { return mAppPermissionGroup.hasRuntimePermission(); } - public boolean hasAppOpPermissions() { - return mAppPermissionGroup.hasAppOpPermission(); + public int getUserId() { + return mAppPermissionGroup.getUserId(); } public String getPackageName() { @@ -401,7 +411,7 @@ public class PermissionApps { public synchronized List<PackageInfo> getPackages(int userId) { List<PackageInfo> ret = mPackageInfoCache.get(userId); if (ret == null) { - ret = mPm.getInstalledPackages(PackageManager.GET_PERMISSIONS, userId); + ret = mPm.getInstalledPackagesAsUser(PackageManager.GET_PERMISSIONS, userId); mPackageInfoCache.put(userId, ret); } return ret; diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroups.java b/src/com/android/packageinstaller/permission/model/PermissionGroups.java index c496e898..8ca69f24 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionGroups.java +++ b/src/com/android/packageinstaller/permission/model/PermissionGroups.java @@ -131,7 +131,7 @@ public final class PermissionGroups implements LoaderCallbacks<List<PermissionGr seenPermissions.add(groupPermission.name); if (groupPermission.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && (groupPermission.flags & PermissionInfo.FLAG_INSTALLED) != 0 - && (groupPermission.flags & PermissionInfo.FLAG_HIDDEN) == 0) { + && (groupPermission.flags & PermissionInfo.FLAG_REMOVED) == 0) { hasRuntimePermissions = true; } } diff --git a/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java b/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java index 810ae8ec..a87976a6 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java +++ b/src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java @@ -33,12 +33,110 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +/** + * This class handles backwards compatibility for M. Don't remove + * until we decide to drop M support altogether. + */ public class PermissionStatusReceiver extends BroadcastReceiver { + + /** + * Broadcast action that requests current permission granted information. It will respond + * to the request by sending a broadcast with action defined by + * {@link #EXTRA_GET_PERMISSIONS_RESPONSE_INTENT}. The response will contain + * {@link #EXTRA_GET_PERMISSIONS_COUNT_RESULT}, as well as + * {@link #EXTRA_GET_PERMISSIONS_GROUP_LIST_RESULT}, with contents described below or + * a null upon failure. + * + * <p>If {@link Intent#EXTRA_PACKAGE_NAME} is included then the number of permissions granted, the + * number of permissions requested and the number of granted additional permissions + * by that package will be calculated and included as the first + * and second elements respectively of an int[] in the response as + * {@link #EXTRA_GET_PERMISSIONS_COUNT_RESULT}. The response will also deliver the list + * of localized permission group names that are granted in + * {@link #EXTRA_GET_PERMISSIONS_GROUP_LIST_RESULT}. + * + * <p>If {@link #EXTRA_PACKAGE_NAME} is not included then the number of apps granted any runtime + * permissions and the total number of apps requesting runtime permissions will be the first + * and second elements respectively of an int[] in the response as + * {@link #EXTRA_GET_PERMISSIONS_COUNT_RESULT}. + * + * @hide + */ + public static final String ACTION_GET_PERMISSIONS_COUNT + = "android.intent.action.GET_PERMISSIONS_COUNT"; + + /** + * Broadcast action that requests list of all apps that have runtime permissions. It will + * respond to the request by sending a broadcast with action defined by + * {@link #EXTRA_GET_PERMISSIONS_PACKAGES_RESPONSE_INTENT}. The response will contain + * {@link #EXTRA_GET_PERMISSIONS_APP_LIST_RESULT}, as well as + * {@link #EXTRA_GET_PERMISSIONS_APP_LABEL_LIST_RESULT}, with contents described below or + * a null upon failure. + * + * <p>{@link #EXTRA_GET_PERMISSIONS_APP_LIST_RESULT} will contain a list of package names of + * apps that have runtime permissions. {@link #EXTRA_GET_PERMISSIONS_APP_LABEL_LIST_RESULT} + * will contain the list of app labels corresponding ot the apps in the first list. + * + * @hide + */ + public static final String ACTION_GET_PERMISSIONS_PACKAGES + = "android.intent.action.GET_PERMISSIONS_PACKAGES"; + + /** + * Extra included in response to {@link #ACTION_GET_PERMISSIONS_COUNT}. + * @hide + */ + public static final String EXTRA_GET_PERMISSIONS_COUNT_RESULT + = "android.intent.extra.GET_PERMISSIONS_COUNT_RESULT"; + + /** + * List of CharSequence of localized permission group labels. + * @hide + */ + public static final String EXTRA_GET_PERMISSIONS_GROUP_LIST_RESULT + = "android.intent.extra.GET_PERMISSIONS_GROUP_LIST_RESULT"; + + /** + * String list of apps that have one or more runtime permissions. + * @hide + */ + public static final String EXTRA_GET_PERMISSIONS_APP_LIST_RESULT + = "android.intent.extra.GET_PERMISSIONS_APP_LIST_RESULT"; + + /** + * String list of app labels for apps that have one or more runtime permissions. + * @hide + */ + public static final String EXTRA_GET_PERMISSIONS_APP_LABEL_LIST_RESULT + = "android.intent.extra.GET_PERMISSIONS_APP_LABEL_LIST_RESULT"; + + /** + * Boolean list describing if the app is a system app for apps that have one or more runtime + * permissions. + * @hide + */ + public static final String EXTRA_GET_PERMISSIONS_IS_SYSTEM_APP_LIST_RESULT + = "android.intent.extra.GET_PERMISSIONS_IS_SYSTEM_APP_LIST_RESULT"; + + /** + * Required extra to be sent with {@link #ACTION_GET_PERMISSIONS_COUNT} broadcasts. + * @hide + */ + public static final String EXTRA_GET_PERMISSIONS_RESPONSE_INTENT + = "android.intent.extra.GET_PERMISSIONS_RESONSE_INTENT"; + + /** + * Required extra to be sent with {@link #ACTION_GET_PERMISSIONS_PACKAGES} broadcasts. + * @hide + */ + public static final String EXTRA_GET_PERMISSIONS_PACKAGES_RESPONSE_INTENT + = "android.intent.extra.GET_PERMISSIONS_PACKAGES_RESONSE_INTENT"; + @Override public void onReceive(Context context, Intent intent) { - if (Intent.ACTION_GET_PERMISSIONS_COUNT.equals(intent.getAction())) { + if (ACTION_GET_PERMISSIONS_COUNT.equals(intent.getAction())) { Intent responseIntent = new Intent(intent.getStringExtra( - Intent.EXTRA_GET_PERMISSIONS_RESPONSE_INTENT)); + EXTRA_GET_PERMISSIONS_RESPONSE_INTENT)); responseIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); int[] counts = new int[3]; @@ -54,28 +152,28 @@ public class PermissionStatusReceiver extends BroadcastReceiver { succeeded = getAppsWithPermissionsCount(context, counts); } if (succeeded) { - responseIntent.putExtra(Intent.EXTRA_GET_PERMISSIONS_COUNT_RESULT, counts); + responseIntent.putExtra(EXTRA_GET_PERMISSIONS_COUNT_RESULT, counts); if (isForPackage) { - responseIntent.putExtra(Intent.EXTRA_GET_PERMISSIONS_GROUP_LIST_RESULT, + responseIntent.putExtra(EXTRA_GET_PERMISSIONS_GROUP_LIST_RESULT, grantedGroups.toArray(new CharSequence[grantedGroups.size()])); } } context.sendBroadcast(responseIntent); - } else if (Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(intent.getAction())) { + } else if (ACTION_GET_PERMISSIONS_PACKAGES.equals(intent.getAction())) { Intent responseIntent = new Intent(intent.getStringExtra( - Intent.EXTRA_GET_PERMISSIONS_PACKAGES_RESPONSE_INTENT)); + EXTRA_GET_PERMISSIONS_PACKAGES_RESPONSE_INTENT)); responseIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); List<String> appsList = new ArrayList<>(); List<CharSequence> appLabelsList = new ArrayList<>(); List<Boolean> isSystemAppList = new ArrayList<>(); if (getAppsWithRuntimePermissions(context, appsList, appLabelsList, isSystemAppList)) { - responseIntent.putExtra(Intent.EXTRA_GET_PERMISSIONS_APP_LIST_RESULT, + responseIntent.putExtra(EXTRA_GET_PERMISSIONS_APP_LIST_RESULT, appsList.toArray(new String[appsList.size()])); - responseIntent.putExtra(Intent.EXTRA_GET_PERMISSIONS_APP_LABEL_LIST_RESULT, + responseIntent.putExtra(EXTRA_GET_PERMISSIONS_APP_LABEL_LIST_RESULT, appLabelsList.toArray(new String[appLabelsList.size()])); - responseIntent.putExtra(Intent.EXTRA_GET_PERMISSIONS_IS_SYSTEM_APP_LIST_RESULT, + responseIntent.putExtra(EXTRA_GET_PERMISSIONS_IS_SYSTEM_APP_LIST_RESULT, toPrimitiveBoolArray(isSystemAppList)); } context.sendBroadcast(responseIntent); |