summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Mortimer <sam@mortimer.me.uk>2013-10-20 23:48:45 -0700
committerSteve Kondik <shade@chemlab.org>2014-01-02 21:22:19 +0000
commit77c4a66e19c0de10bf3de2b2f57f900876bd01b8 (patch)
tree3917862bba3961046b5f698b71372473ec2d8890
parentd36835874e9e1d22464d26bbd51dcd2acf12597f (diff)
downloadandroid_frameworks_base-77c4a66e19c0de10bf3de2b2f57f900876bd01b8.tar.gz
android_frameworks_base-77c4a66e19c0de10bf3de2b2f57f900876bd01b8.tar.bz2
android_frameworks_base-77c4a66e19c0de10bf3de2b2f57f900876bd01b8.zip
AppOps: track op persistence by name instead of id
On XML write, include the op name. On XML read, map the name back to op id (if it exists). Persistent AppOp state now follows the op name instead numeric id. This allows upgrades between versions of android that have different code<>name mappings. Change-Id: Iffc02095b6838a34ff999f8db51c2c6739dd0db8
-rw-r--r--core/java/android/app/AppOpsManager.java14
-rw-r--r--services/java/com/android/server/AppOpsService.java15
2 files changed, 28 insertions, 1 deletions
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 9fa23a13acc..2985dabd622 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -508,6 +508,8 @@ public class AppOpsManager {
private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>();
+ private static HashMap<String, Integer> sNameToOp = new HashMap<String, Integer>();
+
static {
if (sOpToSwitch.length != _NUM_OP) {
throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
@@ -538,6 +540,9 @@ public class AppOpsManager {
sOpStrToOp.put(sOpToString[i], i);
}
}
+ for (int i=0; i<_NUM_OP; i++) {
+ sNameToOp.put(sOpNames[i], i);
+ }
}
/**
@@ -558,6 +563,15 @@ public class AppOpsManager {
}
/**
+ * Map a non-localized name for the operation back to the Op number
+ * @hide
+ */
+ public static int nameToOp(String name) {
+ Integer val = sNameToOp.get(name);
+ return val != null ? val : OP_NONE;
+ }
+
+ /**
* Retrieve the permission associated with an operation, or null if there is not one.
* @hide
*/
diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java
index 3d65a6a825c..bef508dd859 100644
--- a/services/java/com/android/server/AppOpsService.java
+++ b/services/java/com/android/server/AppOpsService.java
@@ -883,7 +883,19 @@ public class AppOpsService extends IAppOpsService.Stub {
String tagName = parser.getName();
if (tagName.equals("op")) {
- Op op = new Op(uid, pkgName, Integer.parseInt(parser.getAttributeValue(null, "n")));
+ int code = Integer.parseInt(parser.getAttributeValue(null, "n"));
+ // use op name string if it exists
+ String codeNameStr = parser.getAttributeValue(null, "ns");
+ if (codeNameStr != null) {
+ // returns OP_NONE if it could not be mapped
+ code = AppOpsManager.nameToOp(codeNameStr);
+ }
+ // skip op codes that are out of bounds
+ if (code == AppOpsManager.OP_NONE
+ || code >= AppOpsManager._NUM_OP) {
+ continue;
+ }
+ Op op = new Op(uid, pkgName, code);
String mode = parser.getAttributeValue(null, "m");
if (mode != null) {
op.mode = Integer.parseInt(mode);
@@ -956,6 +968,7 @@ public class AppOpsService extends IAppOpsService.Stub {
AppOpsManager.OpEntry op = ops.get(j);
out.startTag(null, "op");
out.attribute(null, "n", Integer.toString(op.getOp()));
+ out.attribute(null, "ns", AppOpsManager.opToName(op.getOp()));
if (op.getMode() != AppOpsManager.opToDefaultMode(op.getOp())) {
out.attribute(null, "m", Integer.toString(op.getMode()));
}