diff --git a/src/com/android/settings/development/DevelopmentSettings.java b/src/com/android/settings/development/DevelopmentSettings.java index 2a4a2312668..0a3351aad7d 100644 --- a/src/com/android/settings/development/DevelopmentSettings.java +++ b/src/com/android/settings/development/DevelopmentSettings.java @@ -23,7 +23,6 @@ import android.app.AlertDialog; 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 @@ public class DevelopmentSettings extends RestrictedSettingsFragment 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 @@ public class DevelopmentSettings extends RestrictedSettingsFragment 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 @@ public class DevelopmentSettings extends RestrictedSettingsFragment @Override public void onAttach(Context context) { super.onAttach(context); + mSettingsEnabler = new DevelopmentSettingsEnabler(context, getLifecycle()); mDashboardFeatureProvider = FeatureFactory.getFactory(context) .getDashboardFeatureProvider(context); } @@ -382,7 +381,6 @@ public class DevelopmentSettings extends RestrictedSettingsFragment .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 @@ public class DevelopmentSettings extends RestrictedSettingsFragment 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 @@ public class DevelopmentSettings extends RestrictedSettingsFragment || 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 @@ public class DevelopmentSettings extends RestrictedSettingsFragment } } } - if (codecConfig == null) + if (codecConfig == null) { return; + } try { resources = getResources(); @@ -2329,7 +2324,8 @@ public class DevelopmentSettings extends RestrictedSettingsFragment 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 @@ public class DevelopmentSettings extends RestrictedSettingsFragment 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 @@ public class DevelopmentSettings extends RestrictedSettingsFragment } 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 00000000000..e97997e7910 --- /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 4062be8045a..f174e10bd7c 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.Lifecycle; 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 @@ public class BuildNumberPreferenceController extends PreferenceController 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 00000000000..87905aa8b15 --- /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); + } +}