diff options
author | Sam Mortimer <sam@mortimer.me.uk> | 2013-10-20 23:48:45 -0700 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2014-01-02 21:22:19 +0000 |
commit | 77c4a66e19c0de10bf3de2b2f57f900876bd01b8 (patch) | |
tree | 3917862bba3961046b5f698b71372473ec2d8890 | |
parent | d36835874e9e1d22464d26bbd51dcd2acf12597f (diff) | |
download | android_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.java | 14 | ||||
-rw-r--r-- | services/java/com/android/server/AppOpsService.java | 15 |
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())); } |