summaryrefslogtreecommitdiffstats
path: root/src/com/android/packageinstaller/permission/model
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/packageinstaller/permission/model')
-rw-r--r--src/com/android/packageinstaller/permission/model/AppPermissionGroup.java177
-rw-r--r--src/com/android/packageinstaller/permission/model/AppPermissions.java40
-rw-r--r--src/com/android/packageinstaller/permission/model/Permission.java17
-rw-r--r--src/com/android/packageinstaller/permission/model/PermissionApps.java48
-rw-r--r--src/com/android/packageinstaller/permission/model/PermissionGroups.java2
-rw-r--r--src/com/android/packageinstaller/permission/model/PermissionStatusReceiver.java116
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);