Merge "[DO NOT MERGE] Check caller's uid in backupAgentCreated callback" into tm-dev
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index a6edb0f..2e04cda 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -3101,6 +3101,15 @@
             return settingsState.getSettingLocked(name);
         }
 
+        private boolean shouldExcludeSettingFromReset(Setting setting, String prefix) {
+            // If a prefix was specified, exclude settings whose names don't start with it.
+            if (prefix != null && !setting.getName().startsWith(prefix)) {
+                return true;
+            }
+            // Never reset SECURE_FRP_MODE, as it could be abused to bypass FRP via RescueParty.
+            return Secure.SECURE_FRP_MODE.equals(setting.getName());
+        }
+
         public void resetSettingsLocked(int type, int userId, String packageName, int mode,
                 String tag) {
             resetSettingsLocked(type, userId, packageName, mode, tag, /*prefix=*/
@@ -3123,7 +3132,7 @@
                         Setting setting = settingsState.getSettingLocked(name);
                         if (packageName.equals(setting.getPackageName())) {
                             if ((tag != null && !tag.equals(setting.getTag()))
-                                    || (prefix != null && !setting.getName().startsWith(prefix))) {
+                                    || shouldExcludeSettingFromReset(setting, prefix)) {
                                 continue;
                             }
                             if (settingsState.resetSettingLocked(name)) {
@@ -3143,7 +3152,7 @@
                         Setting setting = settingsState.getSettingLocked(name);
                         if (!SettingsState.isSystemPackage(getContext(),
                                 setting.getPackageName())) {
-                            if (prefix != null && !setting.getName().startsWith(prefix)) {
+                            if (shouldExcludeSettingFromReset(setting, prefix)) {
                                 continue;
                             }
                             if (settingsState.resetSettingLocked(name)) {
@@ -3163,7 +3172,7 @@
                         Setting setting = settingsState.getSettingLocked(name);
                         if (!SettingsState.isSystemPackage(getContext(),
                                 setting.getPackageName())) {
-                            if (prefix != null && !setting.getName().startsWith(prefix)) {
+                            if (shouldExcludeSettingFromReset(setting, prefix)) {
                                 continue;
                             }
                             if (setting.isDefaultFromSystem()) {
@@ -3186,7 +3195,7 @@
                     for (String name : settingsState.getSettingNamesLocked()) {
                         Setting setting = settingsState.getSettingLocked(name);
                         boolean someSettingChanged = false;
-                        if (prefix != null && !setting.getName().startsWith(prefix)) {
+                        if (shouldExcludeSettingFromReset(setting, prefix)) {
                             continue;
                         }
                         if (setting.isDefaultFromSystem()) {
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
index eaf0dcb..1c6d2b0 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
@@ -464,6 +464,31 @@
         }
     }
 
+    // To prevent FRP bypasses, the SECURE_FRP_MODE setting should not be reset when all other
+    // settings are reset.  But it should still be possible to explicitly set its value.
+    @Test
+    public void testSecureFrpModeSettingCannotBeReset() throws Exception {
+        final String name = Settings.Secure.SECURE_FRP_MODE;
+        final String origValue = getSetting(SETTING_TYPE_GLOBAL, name);
+        setSettingViaShell(SETTING_TYPE_GLOBAL, name, "1", false);
+        try {
+            assertEquals("1", getSetting(SETTING_TYPE_GLOBAL, name));
+            for (int type : new int[] { SETTING_TYPE_GLOBAL, SETTING_TYPE_SECURE }) {
+                resetSettingsViaShell(type, Settings.RESET_MODE_UNTRUSTED_DEFAULTS);
+                resetSettingsViaShell(type, Settings.RESET_MODE_UNTRUSTED_CHANGES);
+                resetSettingsViaShell(type, Settings.RESET_MODE_TRUSTED_DEFAULTS);
+            }
+            // The value should still be "1".  It should not have been reset to null.
+            assertEquals("1", getSetting(SETTING_TYPE_GLOBAL, name));
+            // It should still be possible to explicitly set the value to "0".
+            setSettingViaShell(SETTING_TYPE_GLOBAL, name, "0", false);
+            assertEquals("0", getSetting(SETTING_TYPE_GLOBAL, name));
+        } finally {
+            setSettingViaShell(SETTING_TYPE_GLOBAL, name, origValue, false);
+            assertEquals(origValue, getSetting(SETTING_TYPE_GLOBAL, name));
+        }
+    }
+
     private void doTestQueryStringInBracketsViaProviderApiForType(int type) {
         // Make sure we have a clean slate.
         deleteStringViaProviderApi(type, FAKE_SETTING_NAME);