Fix issue #10919261: Don't clear OP_WRITE_SMS when resetting app prefs

Add a new array indicating whether each op allows itself to
be reset, and use it.

Change-Id: I494f630bda170e061196a380563512e9e77b51a8
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 055044b..dce8cab 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -453,27 +453,84 @@
             AppOpsManager.MODE_ALLOWED,
     };
 
+    /**
+     * This specifies whether each option is allowed to be reset
+     * when resetting all app preferences.  Disable reset for
+     * app ops that are under strong control of some part of the
+     * system (such as OP_WRITE_SMS, which should be allowed only
+     * for whichever app is selected as the current SMS app).
+     */
+    private static boolean[] sOpDisableReset = new boolean[] {
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            true,      // OP_WRITE_SMS
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+            false,
+    };
+
     private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>();
 
     static {
         if (sOpToSwitch.length != _NUM_OP) {
-            throw new IllegalStateException("sOpStringLength " + sOpToSwitch.length
+            throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
                     + " should be " + _NUM_OP);
         }
         if (sOpToString.length != _NUM_OP) {
-            throw new IllegalStateException("sOpStringLength " + sOpToString.length
+            throw new IllegalStateException("sOpToString length " + sOpToString.length
                     + " should be " + _NUM_OP);
         }
         if (sOpNames.length != _NUM_OP) {
-            throw new IllegalStateException("sOpStringLength " + sOpNames.length
+            throw new IllegalStateException("sOpNames length " + sOpNames.length
                     + " should be " + _NUM_OP);
         }
         if (sOpPerms.length != _NUM_OP) {
-            throw new IllegalStateException("sOpStringLength " + sOpPerms.length
+            throw new IllegalStateException("sOpPerms length " + sOpPerms.length
                     + " should be " + _NUM_OP);
         }
         if (sOpDefaultMode.length != _NUM_OP) {
-            throw new IllegalStateException("sOpStringLength " + sOpDefaultMode.length
+            throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
+                    + " should be " + _NUM_OP);
+        }
+        if (sOpDisableReset.length != _NUM_OP) {
+            throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
                     + " should be " + _NUM_OP);
         }
         for (int i=0; i<_NUM_OP; i++) {
@@ -517,6 +574,14 @@
     }
 
     /**
+     * Retrieve whether the op allows itself to be reset.
+     * @hide
+     */
+    public static boolean opAllowsReset(int op) {
+        return !sOpDisableReset[op];
+    }
+
+    /**
      * Class holding all of the operation information associated with an app.
      * @hide
      */
diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java
index 67b2307..a1a0d47 100644
--- a/services/java/com/android/server/AppOpsService.java
+++ b/services/java/com/android/server/AppOpsService.java
@@ -435,7 +435,8 @@
                     Ops pkgOps = ent.getValue();
                     for (int j=pkgOps.size()-1; j>=0; j--) {
                         Op curOp = pkgOps.valueAt(j);
-                        if (curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) {
+                        if (AppOpsManager.opAllowsReset(curOp.op)
+                                && curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) {
                             curOp.mode = AppOpsManager.opToDefaultMode(curOp.op);
                             changed = true;
                             callbacks = addCallbacks(callbacks, packageName, curOp.op,