diff options
author | Dianne Hackborn <hackbod@google.com> | 2014-07-21 15:35:45 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2014-07-21 20:15:59 -0700 |
commit | 33f5ddd1bea21296938f2cba196f95d223aa247c (patch) | |
tree | 272be16f506e0f220ab12e3d4d76226eea139d17 | |
parent | 66e207ec54e2085c0eb70d5189562effafa2c9c5 (diff) | |
download | frameworks_base-33f5ddd1bea21296938f2cba196f95d223aa247c.zip frameworks_base-33f5ddd1bea21296938f2cba196f95d223aa247c.tar.gz frameworks_base-33f5ddd1bea21296938f2cba196f95d223aa247c.tar.bz2 |
Add permissions associated with app ops.
Change-Id: I575ad7a3ceea59486ca601f69760b14f6269511d
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | core/java/android/app/AppOpsManager.java | 9 | ||||
-rw-r--r-- | core/java/android/content/pm/IPackageManager.aidl | 2 | ||||
-rw-r--r-- | core/java/android/content/pm/PermissionInfo.java | 10 | ||||
-rw-r--r-- | core/res/AndroidManifest.xml | 4 | ||||
-rw-r--r-- | core/res/res/values/attrs_manifest.xml | 3 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 68 | ||||
-rw-r--r-- | tests/VoiceInteraction/AndroidManifest.xml | 2 |
8 files changed, 96 insertions, 4 deletions
diff --git a/api/current.txt b/api/current.txt index e736d78..1263186 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3820,6 +3820,7 @@ package android.app { method public void startWatchingMode(java.lang.String, java.lang.String, android.app.AppOpsManager.OnOpChangedListener); method public void stopWatchingMode(android.app.AppOpsManager.OnOpChangedListener); field public static final int MODE_ALLOWED = 0; // 0x0 + field public static final int MODE_DEFAULT = 3; // 0x3 field public static final int MODE_ERRORED = 2; // 0x2 field public static final int MODE_IGNORED = 1; // 0x1 field public static final java.lang.String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -8877,6 +8878,7 @@ package android.content.pm { field public static final android.os.Parcelable.Creator CREATOR; field public static final int FLAG_COSTS_MONEY = 1; // 0x1 field public static final int PROTECTION_DANGEROUS = 1; // 0x1 + field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40 field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20 field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10 field public static final int PROTECTION_MASK_BASE = 15; // 0xf diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 990ea85..caadecb 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -94,6 +94,13 @@ public class AppOpsManager { */ public static final int MODE_ERRORED = 2; + /** + * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should + * use its default security check. This mode is not normally used; it should only be used + * with appop permissions, and callers must explicitly check for it and deal with it. + */ + public static final int MODE_DEFAULT = 3; + // when adding one of these: // - increment _NUM_OP // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpPerms, sOpDefaultMode @@ -588,7 +595,7 @@ public class AppOpsManager { AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_IGNORED, // OP_GET_USAGE_STATS + AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 5e55ba7..4b339a1 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -110,6 +110,8 @@ interface IPackageManager { int getFlagsForUid(int uid); + String[] getAppOpPermissionPackages(String permissionName); + ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags, int userId); boolean canForwardTo(in Intent intent, String resolvedType, int sourceUserId, int targetUserId); diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index 5a63e5f..af574db 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -69,6 +69,13 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20; /** + * Additional flag for {@link #protectionLevel}, corresponding + * to the <code>development</code> value of + * {@link android.R.attr#protectionLevel}. + */ + public static final int PROTECTION_FLAG_APPOP = 0x40; + + /** * Mask for {@link #protectionLevel}: the basic protection type. */ public static final int PROTECTION_MASK_BASE = 0xf; @@ -153,6 +160,9 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { if ((level&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { protLevel += "|development"; } + if ((level&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { + protLevel += "|appop"; + } return protLevel; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index a2afb44..7f97726 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2461,7 +2461,7 @@ <permission android:name="android.permission.PACKAGE_USAGE_STATS" android:label="@string/permlab_pkgUsageStats" android:description="@string/permdesc_pkgUsageStats" - android:protectionLevel="signature|system" /> + android:protectionLevel="signature|system|development|appop" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> <!-- @SystemApi Allows an application to collect battery statistics --> @@ -2469,7 +2469,7 @@ android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:label="@string/permlab_batteryStats" android:description="@string/permdesc_batteryStats" - android:protectionLevel="signature|system" /> + android:protectionLevel="signature|system|development" /> <!-- @SystemApi Allows an application to control the backup and restore process. <p>Not for use by third-party applications. diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 3026514..7311a60 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -212,6 +212,9 @@ <!-- Additional flag from base permission type: this permission can also (optionally) be granted to development applications. --> <flag name="development" value="0x20" /> + <!-- Additional flag from base permission type: this permission is closely + associated with an app op for controlling access. --> + <flag name="appop" value="0x40" /> </attr> <!-- Flags indicating more context for a permission group. --> diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 6de8a8b..69f2f32 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -474,6 +474,9 @@ public class PackageManagerService extends IPackageManager.Stub { final SparseArray<PackageVerificationState> mPendingVerification = new SparseArray<PackageVerificationState>(); + /** Set of packages associated with each app op permission. */ + final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); + final PackageInstallerService mInstallerService; HashSet<PackageParser.Package> mDeferredDexOpt = null; @@ -2917,6 +2920,17 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override + public String[] getAppOpPermissionPackages(String permissionName) { + synchronized (mPackages) { + ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); + if (pkgs == null) { + return null; + } + return pkgs.toArray(new String[pkgs.size()]); + } + } + + @Override public ResolveInfo resolveIntent(Intent intent, String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return null; @@ -6591,6 +6605,31 @@ public class PackageManagerService extends IPackageManager.Stub { r.append(p.info.name); } } + if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { + ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name); + if (appOpPerms != null) { + appOpPerms.remove(pkg.packageName); + } + } + } + if (r != null) { + if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); + } + + N = pkg.requestedPermissions.size(); + r = null; + for (i=0; i<N; i++) { + String perm = pkg.requestedPermissions.get(i); + BasePermission bp = mSettings.mPermissions.get(perm); + if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { + ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm); + if (appOpPerms != null) { + appOpPerms.remove(pkg.packageName); + if (appOpPerms.isEmpty()) { + mAppOpPermissionPackages.remove(perm); + } + } + } } if (r != null) { if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); @@ -6775,6 +6814,15 @@ public class PackageManagerService extends IPackageManager.Stub { final String perm = bp.name; boolean allowed; boolean allowedSig = false; + if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { + // Keep track of app op permissions. + ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); + if (pkgs == null) { + pkgs = new ArraySet<>(); + mAppOpPermissionPackages.put(bp.name, pkgs); + } + pkgs.add(pkg.packageName); + } final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; if (level == PermissionInfo.PROTECTION_NORMAL || level == PermissionInfo.PROTECTION_DANGEROUS) { @@ -6837,7 +6885,9 @@ public class PackageManagerService extends IPackageManager.Stub { + " (protectionLevel=" + bp.protectionLevel + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) + ")"); - } else { + } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { + // Don't print warning for app op permissions, since it is fine for them + // not to be granted, there is a UI for the user to decide. Slog.w(TAG, "Not granting permission " + perm + " to package " + pkg.packageName + " (protectionLevel=" + bp.protectionLevel @@ -12426,6 +12476,22 @@ public class PackageManagerService extends IPackageManager.Stub { if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { mSettings.dumpPermissionsLPr(pw, packageName, dumpState); + if (packageName == null) { + for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { + if (iperm == 0) { + if (dumpState.onTitlePrinted()) + pw.println(); + pw.println("AppOp Permissions:"); + } + pw.print(" AppOp Permission "); + pw.print(mAppOpPermissionPackages.keyAt(iperm)); + pw.println(":"); + ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); + for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { + pw.print(" "); pw.println(pkgs.valueAt(ipkg)); + } + } + } } if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml index 33f000d..c328b3c 100644 --- a/tests/VoiceInteraction/AndroidManifest.xml +++ b/tests/VoiceInteraction/AndroidManifest.xml @@ -1,6 +1,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.test.voiceinteraction"> + <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> + <application> <activity android:name="VoiceInteractionMain" android:label="Voice Interaction" android:theme="@android:style/Theme.Material"> |