Merge "Introduce StayAwakePreferenceController"
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 919dc3a..5768299 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -32,8 +32,10 @@
import com.android.settings.search.Indexable;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -116,7 +118,7 @@
@Override
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
- return buildPreferenceControllers(context);
+ return buildPreferenceControllers(context, getLifecycle());
}
void onEnableDevelopmentOptionsConfirmed() {
@@ -129,8 +131,12 @@
mSwitchBar.setChecked(false);
}
- private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
- return null;
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+ Lifecycle lifecycle) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new StayAwakePreferenceController(context, lifecycle));
+
+ return controllers;
}
/**
@@ -156,7 +162,7 @@
@Override
public List<AbstractPreferenceController> getPreferenceControllers(Context
context) {
- return buildPreferenceControllers(context);
+ return buildPreferenceControllers(context, null /* lifecycle */);
}
};
}
diff --git a/src/com/android/settings/development/StayAwakePreferenceController.java b/src/com/android/settings/development/StayAwakePreferenceController.java
new file mode 100644
index 0000000..ebba9e5
--- /dev/null
+++ b/src/com/android/settings/development/StayAwakePreferenceController.java
@@ -0,0 +1,139 @@
+package com.android.settings.development;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+
+
+public class StayAwakePreferenceController extends AbstractPreferenceController implements
+ PreferenceControllerMixin, Preference.OnPreferenceChangeListener, LifecycleObserver,
+ OnResume, OnPause {
+
+ private static final String TAG = "StayAwakeCtrl";
+ private static final String PREFERENCE_KEY = "keep_screen_on";
+ @VisibleForTesting
+ static final int SETTING_VALUE_OFF = 0;
+ @VisibleForTesting
+ static final int SETTING_VALUE_ON =
+ BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS;
+ @VisibleForTesting
+ SettingsObserver mSettingsObserver;
+
+ private RestrictedSwitchPreference mPreference;
+
+ public StayAwakePreferenceController(Context context, Lifecycle lifecycle) {
+ super(context);
+ mSettingsObserver = new SettingsObserver();
+
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return PREFERENCE_KEY;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = (RestrictedSwitchPreference) screen.findPreference(getPreferenceKey());
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean stayAwake = (Boolean) newValue;
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
+ stayAwake ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ final RestrictedLockUtils.EnforcedAdmin admin = checkIfMaximumTimeToLockSetByAdmin();
+ if (admin != null) {
+ mPreference.setDisabledByAdmin(admin);
+ return;
+ }
+
+ final int stayAwakeMode = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
+ SETTING_VALUE_OFF);
+ mPreference.setChecked(stayAwakeMode != SETTING_VALUE_OFF);
+ }
+
+ @Override
+ public void onResume() {
+ if (mPreference != null) {
+ mSettingsObserver.register(true /* register */);
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (mPreference != null) {
+ mSettingsObserver.register(false /* unregister */);
+ }
+ }
+
+ @VisibleForTesting
+ RestrictedLockUtils.EnforcedAdmin checkIfMaximumTimeToLockSetByAdmin() {
+ // A DeviceAdmin has specified a maximum time until the device
+ // will lock... in this case we can't allow the user to turn
+ // on "stay awake when plugged in" because that would defeat the
+ // restriction.
+ return RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext);
+ }
+
+ @VisibleForTesting
+ class SettingsObserver extends ContentObserver {
+ private final Uri mStayAwakeUri = Settings.Global.getUriFor(
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
+
+ public SettingsObserver() {
+ super(new Handler());
+ }
+
+ public void register(boolean register) {
+ final ContentResolver cr = mContext.getContentResolver();
+ if (register) {
+ cr.registerContentObserver(
+ mStayAwakeUri, false, this);
+ } else {
+ cr.unregisterContentObserver(this);
+ }
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ if (mStayAwakeUri.equals(uri)) {
+ updateState(mPreference);
+ }
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/development/StayAwakePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/StayAwakePreferenceControllerTest.java
new file mode 100644
index 0000000..cbef531
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/StayAwakePreferenceControllerTest.java
@@ -0,0 +1,117 @@
+package com.android.settings.development;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class StayAwakePreferenceControllerTest {
+
+ @Mock
+ private Context mContext;
+ @Mock
+ private RestrictedSwitchPreference mPreference;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ @Mock
+ private Lifecycle mLifecycle;
+ private ContentResolver mContentResolver;
+ private StayAwakePreferenceController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ mController = new StayAwakePreferenceController(mContext, mLifecycle);
+ when(mContext.getContentResolver()).thenReturn(mContentResolver);
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mPreference);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void onPreferenceChanged_turnOnStayAwake() {
+ mController.onPreferenceChange(null, true);
+
+ final int mode = Settings.System.getInt(mContentResolver,
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN, -1);
+ assertThat(mode).isEqualTo(StayAwakePreferenceController.SETTING_VALUE_ON);
+ }
+
+ @Test
+ public void onPreferenceChanged_turnOffStayAwake() {
+ mController.onPreferenceChange(null, false);
+
+ final int mode = Settings.System.getInt(mContentResolver,
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN, -1);
+ assertThat(mode).isEqualTo(StayAwakePreferenceController.SETTING_VALUE_OFF);
+ }
+
+ @Test
+ public void updateState_preferenceShouldBeChecked() {
+ Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
+ StayAwakePreferenceController.SETTING_VALUE_ON);
+ mController.updateState(mPreference);
+ verify(mPreference).setChecked(true);
+ }
+
+ @Test
+ public void updateState_preferenceShouldNotBeChecked() {
+ Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
+ StayAwakePreferenceController.SETTING_VALUE_OFF);
+ mController.updateState(mPreference);
+ verify(mPreference).setChecked(false);
+ }
+
+ @Test
+ public void displayPreference_expectSetDisabledByAdminToBeCalled() {
+ mController = spy(mController);
+ RestrictedLockUtils.EnforcedAdmin admin = Mockito.mock(
+ RestrictedLockUtils.EnforcedAdmin.class);
+ doReturn(admin).when(mController).checkIfMaximumTimeToLockSetByAdmin();
+ mController.updateState(mPreference);
+ verify(mPreference).setDisabledByAdmin(admin);
+ }
+
+ @Test
+ public void observerOnChangeCalledWithSameUri_preferenceShouldBeUpdated() {
+ Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
+ StayAwakePreferenceController.SETTING_VALUE_ON);
+ mController.mSettingsObserver.onChange(false,
+ Settings.Global.getUriFor(Settings.Global.STAY_ON_WHILE_PLUGGED_IN));
+ verify(mPreference).setChecked(true);
+ }
+
+ @Test
+ public void observerOnChangeCalledWithDifferentUri_preferenceShouldNotBeUpdated() {
+ Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
+ StayAwakePreferenceController.SETTING_VALUE_ON);
+ mController.mSettingsObserver.onChange(false, null);
+ verify(mPreference, never()).setChecked(true);
+ }
+}