Disable development settings when the switch bar turns off.

Change-Id: Icc9953c95ed4d131231bb6ba95d60b43092a3833
Fix: 29274149
Test: make RunSettingsRoboTests
diff --git a/src/com/android/settings/development/DevelopmentSettings.java b/src/com/android/settings/development/DevelopmentSettings.java
index 2a4a231..0a3351a 100644
--- a/src/com/android/settings/development/DevelopmentSettings.java
+++ b/src/com/android/settings/development/DevelopmentSettings.java
@@ -23,7 +23,6 @@
 import android.app.AppOpsManager;
 import android.app.AppOpsManager.PackageOps;
 import android.app.Dialog;
-import android.app.admin.DevicePolicyManager;
 import android.app.backup.IBackupManager;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
@@ -246,17 +245,15 @@
     private IWindowManager mWindowManager;
     private IBackupManager mBackupManager;
     private IWebViewUpdateService mWebViewUpdateService;
-    private DevicePolicyManager mDpm;
     private UserManager mUm;
     private WifiManager mWifiManager;
     private PersistentDataBlockManager mOemUnlockManager;
     private TelephonyManager mTelephonyManager;
 
     private SwitchBar mSwitchBar;
-    private boolean mLastEnabledState;
+
     private boolean mHaveDebugSettings;
     private boolean mDontPokeProperties;
-
     private SwitchPreference mEnableAdb;
     private Preference mClearAdbKeys;
     private SwitchPreference mEnableTerminal;
@@ -350,6 +347,7 @@
     private boolean mLogpersistCleared;
     private Dialog mLogpersistClearDialog;
     private DashboardFeatureProvider mDashboardFeatureProvider;
+    private DevelopmentSettingsEnabler mSettingsEnabler;
     private BugReportPreferenceController mBugReportController;
     private BugReportInPowerPreferenceController mBugReportInPowerController;
     private TelephonyMonitorPreferenceController mTelephonyMonitorController;
@@ -366,6 +364,7 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
+        mSettingsEnabler = new DevelopmentSettingsEnabler(context, getLifecycle());
         mDashboardFeatureProvider = FeatureFactory.getFactory(context)
                 .getDashboardFeatureProvider(context);
     }
@@ -382,7 +381,6 @@
                 .getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
         mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
 
-        mDpm = (DevicePolicyManager) getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
         mUm = (UserManager) getSystemService(Context.USER_SERVICE);
 
         mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
@@ -671,22 +669,18 @@
             mDisabledPrefs.add(mKeepScreenOn);
         }
 
-        final ContentResolver cr = getActivity().getContentResolver();
-        mLastEnabledState = Settings.Global.getInt(cr,
-                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
-        mSwitchBar.setChecked(mLastEnabledState);
-        setPrefsEnabledState(mLastEnabledState);
+        final boolean lastEnabledState = mSettingsEnabler.getLastEnabledState();
+        mSwitchBar.setChecked(lastEnabledState);
+        setPrefsEnabledState(lastEnabledState);
 
-        if (mHaveDebugSettings && !mLastEnabledState) {
+        if (mHaveDebugSettings && !lastEnabledState) {
             // Overall debugging is disabled, but there are some debug
             // settings that are enabled.  This is an invalid state.  Switch
             // to debug settings being enabled, so the user knows there is
             // stuff enabled and can turn it all off if they want.
-            Settings.Global.putInt(getActivity().getContentResolver(),
-                    Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
-            mLastEnabledState = true;
-            mSwitchBar.setChecked(mLastEnabledState);
-            setPrefsEnabledState(mLastEnabledState);
+            mSettingsEnabler.enableDevelopmentSettings();
+            mSwitchBar.setChecked(lastEnabledState);
+            setPrefsEnabledState(lastEnabledState);
         }
         mSwitchBar.show();
 
@@ -1560,7 +1554,7 @@
                         || currentValue.equals(SELECT_LOGD_OFF_SIZE_MARKER_VALUE)) {
                     writeLogpersistOption(null, true);
                     mLogpersist.setEnabled(false);
-                } else if (mLastEnabledState) {
+                } else if (mSettingsEnabler.getLastEnabledState()) {
                     mLogpersist.setEnabled(true);
                 }
             }
@@ -1848,8 +1842,9 @@
                 }
             }
         }
-        if (codecConfig == null)
+        if (codecConfig == null) {
             return;
+        }
 
         try {
             resources = getResources();
@@ -2329,7 +2324,8 @@
         if (switchView != mSwitchBar.getSwitch()) {
             return;
         }
-        if (isChecked != mLastEnabledState) {
+        final boolean lastEnabledState = mSettingsEnabler.getLastEnabledState();
+        if (isChecked != lastEnabledState) {
             if (isChecked) {
                 mDialogClicked = false;
                 if (mEnableDialog != null) dismissDialogs();
@@ -2343,10 +2339,8 @@
                 mEnableDialog.setOnDismissListener(this);
             } else {
                 resetDangerousOptions();
-                Settings.Global.putInt(getActivity().getContentResolver(),
-                        Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
-                mLastEnabledState = isChecked;
-                setPrefsEnabledState(mLastEnabledState);
+                mSettingsEnabler.disableDevelopmentSettings();
+                setPrefsEnabledState(false);
             }
         }
     }
@@ -2629,10 +2623,8 @@
         } else if (dialog == mEnableDialog) {
             if (which == DialogInterface.BUTTON_POSITIVE) {
                 mDialogClicked = true;
-                Settings.Global.putInt(getActivity().getContentResolver(),
-                        Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
-                mLastEnabledState = true;
-                setPrefsEnabledState(mLastEnabledState);
+                mSettingsEnabler.enableDevelopmentSettings();
+                setPrefsEnabledState(true);
             } else {
                 // Reset the toggle
                 mSwitchBar.setChecked(false);
diff --git a/src/com/android/settings/development/DevelopmentSettingsEnabler.java b/src/com/android/settings/development/DevelopmentSettingsEnabler.java
new file mode 100644
index 0000000..e97997e
--- /dev/null
+++ b/src/com/android/settings/development/DevelopmentSettingsEnabler.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.provider.Settings;
+
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnResume;
+
+public class DevelopmentSettingsEnabler implements LifecycleObserver, OnResume {
+
+    private final Context mContext;
+    private final SharedPreferences mDevelopmentPreferences;
+    private boolean mLastEnabledState;
+
+    public DevelopmentSettingsEnabler(Context context, Lifecycle lifecycle) {
+        mContext = context;
+        mDevelopmentPreferences = context.getSharedPreferences(DevelopmentSettings.PREF_FILE,
+                Context.MODE_PRIVATE);
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        mLastEnabledState = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
+    }
+
+    public static boolean enableDevelopmentSettings(Context context, SharedPreferences prefs) {
+        prefs.edit()
+                .putBoolean(DevelopmentSettings.PREF_SHOW, true)
+                .commit();
+        return Settings.Global.putInt(context.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
+    }
+
+    public boolean getLastEnabledState() {
+        return mLastEnabledState;
+    }
+
+    public void enableDevelopmentSettings() {
+        mLastEnabledState = enableDevelopmentSettings(mContext, mDevelopmentPreferences);
+    }
+
+    public void disableDevelopmentSettings() {
+        mDevelopmentPreferences.edit()
+                .putBoolean(DevelopmentSettings.PREF_SHOW, false)
+                .commit();
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
+        mLastEnabledState = false;
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
index 4062be8..f174e10 100644
--- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
@@ -39,8 +39,8 @@
 import com.android.settings.core.lifecycle.LifecycleObserver;
 import com.android.settings.core.lifecycle.events.OnResume;
 import com.android.settings.development.DevelopmentSettings;
+import com.android.settings.development.DevelopmentSettingsEnabler;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.search2.SearchFeatureProvider;
 import com.android.settingslib.RestrictedLockUtils;
 
 public class BuildNumberPreferenceController extends PreferenceController
@@ -210,10 +210,9 @@
     private void enableDevelopmentSettings() {
         mDevHitCountdown = 0;
         mProcessingLastDevHit = false;
-        mContext.getSharedPreferences(DevelopmentSettings.PREF_FILE,
-                Context.MODE_PRIVATE).edit()
-                .putBoolean(DevelopmentSettings.PREF_SHOW, true)
-                .apply();
+        DevelopmentSettingsEnabler.enableDevelopmentSettings(mContext,
+                mContext.getSharedPreferences(DevelopmentSettings.PREF_FILE,
+                        Context.MODE_PRIVATE));
         if (mDevHitToast != null) {
             mDevHitToast.cancel();
         }
diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsEnablerTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsEnablerTest.java
new file mode 100644
index 0000000..87905aa
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsEnablerTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.provider.Settings;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class DevelopmentSettingsEnablerTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private SharedPreferences mDevelopmentPreferences;
+    private Context mContext;
+    private DevelopmentSettingsEnabler mEnabler;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mEnabler = new DevelopmentSettingsEnabler(mContext, null);
+        ReflectionHelpers.setField(mEnabler, "mDevelopmentPreferences", mDevelopmentPreferences);
+    }
+
+    @Test
+    public void onResume_shouldReadStateFromSettingProvider() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
+
+        mEnabler.onResume();
+
+        assertThat(mEnabler.getLastEnabledState()).isTrue();
+
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
+
+        mEnabler.onResume();
+
+        assertThat(mEnabler.getLastEnabledState()).isFalse();
+    }
+
+    @Test
+    public void disable_shouldChangeSettingProviderValue() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
+
+        mEnabler.disableDevelopmentSettings();
+
+        assertThat(mEnabler.getLastEnabledState()).isFalse();
+        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1)).isEqualTo(0);
+    }
+
+    @Test
+    public void enable_shouldChangeSettingProviderValue() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
+
+        mEnabler.enableDevelopmentSettings();
+
+        assertThat(mEnabler.getLastEnabledState()).isTrue();
+        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0)).isEqualTo(1);
+    }
+}