diff --git a/res/values/strings.xml b/res/values/strings.xml index ccd73fc1e20..4f3f1f3f0b4 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2387,6 +2387,10 @@ Ambient display Wake screen when you receive notifications + + Always on + + Show time, notification icons, and other info Font size diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml index 655243f16eb..b1241443d23 100644 --- a/res/xml/display_settings.xml +++ b/res/xml/display_settings.xml @@ -110,6 +110,11 @@ android:title="@string/doze_title" android:summary="@string/doze_summary" /> + + buildPreferenceControllers( Context context, Lifecycle lifecycle) { final List controllers = new ArrayList<>(); + final AmbientDisplayConfiguration ambientDisplayConfig = new AmbientDisplayConfiguration(context); controllers.add(new AutoBrightnessPreferenceController(context, KEY_AUTO_BRIGHTNESS)); controllers.add(new AutoRotatePreferenceController(context, lifecycle)); controllers.add(new CameraGesturePreferenceController(context)); - controllers.add(new DozePreferenceController(context)); + controllers.add(new DozePreferenceController(context, ambientDisplayConfig, + FeatureFactory.getFactory(context).getMetricsFeatureProvider())); + controllers.add(new DozeAlwaysOnPreferenceController(context, ambientDisplayConfig)); controllers.add(new FontSizePreferenceController(context)); controllers.add(new LiftToWakePreferenceController(context)); controllers.add(new NightDisplayPreferenceController(context)); controllers.add(new NightModePreferenceController(context)); controllers.add(new ScreenSaverPreferenceController(context)); - AmbientDisplayConfiguration ambientDisplayConfig = new AmbientDisplayConfiguration(context); controllers.add(new PickupGesturePreferenceController( context, lifecycle, ambientDisplayConfig, UserHandle.myUserId())); controllers.add(new DoubleTapScreenPreferenceController( diff --git a/src/com/android/settings/display/DozeAlwaysOnPreferenceController.java b/src/com/android/settings/display/DozeAlwaysOnPreferenceController.java new file mode 100644 index 00000000000..e3e2e2d4e63 --- /dev/null +++ b/src/com/android/settings/display/DozeAlwaysOnPreferenceController.java @@ -0,0 +1,64 @@ +/* + * 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.display; + +import static android.provider.Settings.Secure.DOZE_ALWAYS_ON; + + +import android.content.Context; +import android.os.UserHandle; +import android.provider.Settings; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.Preference; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.settings.core.PreferenceController; + +public class DozeAlwaysOnPreferenceController extends PreferenceController implements + Preference.OnPreferenceChangeListener { + + private static final String KEY_DOZE_ALWAYS_ON = "doze_always_on"; + private static final int MY_USER = UserHandle.myUserId(); + + private final AmbientDisplayConfiguration mConfig; + + public DozeAlwaysOnPreferenceController(Context context, AmbientDisplayConfiguration config) { + super(context); + mConfig = config; + } + + @Override + public String getPreferenceKey() { + return KEY_DOZE_ALWAYS_ON; + } + + @Override + public void updateState(Preference preference) { + ((SwitchPreference) preference).setChecked(mConfig.alwaysOnEnabled(MY_USER)); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + int enabled = (boolean) newValue ? 1 : 0; + Settings.Secure.putInt(mContext.getContentResolver(), DOZE_ALWAYS_ON, enabled); + return true; + } + + @Override + public boolean isAvailable() { + return mConfig.alwaysOnAvailable(); + } +} diff --git a/src/com/android/settings/display/DozePreferenceController.java b/src/com/android/settings/display/DozePreferenceController.java index ad72053bf38..36c850ea948 100644 --- a/src/com/android/settings/display/DozePreferenceController.java +++ b/src/com/android/settings/display/DozePreferenceController.java @@ -14,16 +14,15 @@ package com.android.settings.display; import android.content.Context; -import android.os.Build; -import android.os.SystemProperties; +import android.os.UserHandle; import android.provider.Settings; +import android.support.annotation.VisibleForTesting; import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.Preference; -import android.text.TextUtils; +import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.settings.core.PreferenceController; import com.android.settings.core.instrumentation.MetricsFeatureProvider; -import com.android.settings.overlay.FeatureFactory; import static android.provider.Settings.Secure.DOZE_ENABLED; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_AMBIENT_DISPLAY; @@ -31,13 +30,18 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION public class DozePreferenceController extends PreferenceController implements Preference.OnPreferenceChangeListener { - private static final String KEY_DOZE = "doze"; + @VisibleForTesting + static final String KEY_DOZE = "doze"; + private static final int MY_USER = UserHandle.myUserId(); private final MetricsFeatureProvider mMetricsFeatureProvider; + private final AmbientDisplayConfiguration mConfig; - public DozePreferenceController(Context context) { + public DozePreferenceController(Context context, AmbientDisplayConfiguration config, + MetricsFeatureProvider metricsFeatureProvider) { super(context); - mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); + mMetricsFeatureProvider = metricsFeatureProvider; + mConfig = config; } @Override @@ -55,8 +59,7 @@ public class DozePreferenceController extends PreferenceController implements @Override public void updateState(Preference preference) { - int value = Settings.Secure.getInt(mContext.getContentResolver(), DOZE_ENABLED, 1); - ((SwitchPreference) preference).setChecked(value != 0); + ((SwitchPreference) preference).setChecked(mConfig.pulseOnNotificationEnabled(MY_USER)); } @Override @@ -68,11 +71,6 @@ public class DozePreferenceController extends PreferenceController implements @Override public boolean isAvailable() { - String name = Build.IS_DEBUGGABLE ? SystemProperties.get("debug.doze.component") : null; - if (TextUtils.isEmpty(name)) { - name = mContext.getResources().getString( - com.android.internal.R.string.config_dozeComponent); - } - return !TextUtils.isEmpty(name); + return mConfig.pulseOnNotificationAvailable(); } } diff --git a/tests/robotests/src/com/android/internal/hardware/AmbientDisplayConfiguration.java b/tests/robotests/src/com/android/internal/hardware/AmbientDisplayConfiguration.java index ffa6d96f6ac..9ac077dbde1 100644 --- a/tests/robotests/src/com/android/internal/hardware/AmbientDisplayConfiguration.java +++ b/tests/robotests/src/com/android/internal/hardware/AmbientDisplayConfiguration.java @@ -16,7 +16,6 @@ package com.android.internal.hardware; -import android.provider.Settings; import android.content.Context; /** @@ -42,4 +41,20 @@ public class AmbientDisplayConfiguration { public boolean pulseOnDoubleTapEnabled(int user) { return true; } + + public boolean pulseOnNotificationEnabled(int user) { + return true; + } + + public boolean pulseOnNotificationAvailable() { + return true; + } + + public boolean alwaysOnEnabled(int user) { + return true; + } + + public boolean alwaysOnAvailable() { + return true; + } } diff --git a/tests/robotests/src/com/android/settings/display/DozeAlwaysOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/DozeAlwaysOnPreferenceControllerTest.java new file mode 100644 index 00000000000..fc299c04972 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/DozeAlwaysOnPreferenceControllerTest.java @@ -0,0 +1,109 @@ +/* + * 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.display; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.provider.Settings; +import android.support.v14.preference.SwitchPreference; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.testutils.shadow.ShadowSecureSettings; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = {ShadowSecureSettings.class}) +public class DozeAlwaysOnPreferenceControllerTest { + + @Mock Context mContext; + @Mock AmbientDisplayConfiguration mConfig; + @Mock SwitchPreference mSwitchPreference; + + DozeAlwaysOnPreferenceController mController; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mController = new DozeAlwaysOnPreferenceController(mContext, mConfig); + } + + @Test + public void updateState_enabled() throws Exception { + when(mConfig.alwaysOnEnabled(anyInt())) + .thenReturn(true); + + mController.updateState(mSwitchPreference); + + verify(mSwitchPreference).setChecked(true); + } + + @Test + public void updateState_disabled() throws Exception { + when(mConfig.alwaysOnEnabled(anyInt())) + .thenReturn(false); + + mController.updateState(mSwitchPreference); + + verify(mSwitchPreference).setChecked(false); + } + + @Test + public void onPreferenceChange_enable() throws Exception { + mController.onPreferenceChange(mSwitchPreference, true); + + assertThat(Settings.Secure.getInt(null, Settings.Secure.DOZE_ALWAYS_ON, -1)) + .isEqualTo(1); + } + + @Test + public void onPreferenceChange_disable() throws Exception { + mController.onPreferenceChange(mSwitchPreference, false); + + assertThat(Settings.Secure.getInt(null, Settings.Secure.DOZE_ALWAYS_ON, -1)) + .isEqualTo(0); + } + + @Test + public void isAvailable_available() throws Exception { + when(mConfig.alwaysOnAvailable()) + .thenReturn(true); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_unavailable() throws Exception { + when(mConfig.alwaysOnAvailable()) + .thenReturn(false); + + assertThat(mController.isAvailable()).isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/display/DozePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/DozePreferenceControllerTest.java new file mode 100644 index 00000000000..a956945e254 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/DozePreferenceControllerTest.java @@ -0,0 +1,134 @@ +/* + * 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.display; + +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_AMBIENT_DISPLAY; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.provider.Settings; +import android.support.v14.preference.SwitchPreference; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.core.instrumentation.MetricsFeatureProvider; +import com.android.settings.testutils.shadow.ShadowSecureSettings; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = {ShadowSecureSettings.class}) +public class DozePreferenceControllerTest { + + @Mock Context mContext; + @Mock AmbientDisplayConfiguration mConfig; + @Mock SwitchPreference mSwitchPreference; + @Mock MetricsFeatureProvider mMetricsFeatureProvider; + + DozePreferenceController mController; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mController = new DozePreferenceController(mContext, mConfig, mMetricsFeatureProvider); + } + + @Test + public void updateState_enabled() throws Exception { + when(mConfig.pulseOnNotificationEnabled(anyInt())) + .thenReturn(true); + + mController.updateState(mSwitchPreference); + + verify(mSwitchPreference).setChecked(true); + } + + @Test + public void updateState_disabled() throws Exception { + when(mConfig.pulseOnNotificationEnabled(anyInt())) + .thenReturn(false); + + mController.updateState(mSwitchPreference); + + verify(mSwitchPreference).setChecked(false); + } + + @Test + public void onPreferenceChange_enable() throws Exception { + mController.onPreferenceChange(mSwitchPreference, true); + + assertThat(Settings.Secure.getInt(null, Settings.Secure.DOZE_ENABLED, -1)) + .isEqualTo(1); + } + + @Test + public void onPreferenceChange_disable() throws Exception { + mController.onPreferenceChange(mSwitchPreference, false); + + assertThat(Settings.Secure.getInt(null, Settings.Secure.DOZE_ENABLED, -1)) + .isEqualTo(0); + } + + @Test + public void isAvailable_available() throws Exception { + when(mConfig.pulseOnNotificationAvailable()) + .thenReturn(true); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_unavailable() throws Exception { + when(mConfig.pulseOnNotificationAvailable()) + .thenReturn(false); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void handlePreferenceTreeClick_reportsEventForItsPreference() throws Exception { + when(mSwitchPreference.getKey()).thenReturn(DozePreferenceController.KEY_DOZE); + + mController.handlePreferenceTreeClick(mSwitchPreference); + + verify(mMetricsFeatureProvider).action(any(), eq(ACTION_AMBIENT_DISPLAY)); + } + + @Test + public void handlePreferenceTreeClick_doesntReportEventForOtherPreferences() throws Exception { + when(mSwitchPreference.getKey()).thenReturn("some_other_key"); + + mController.handlePreferenceTreeClick(mSwitchPreference); + + verifyNoMoreInteractions(mMetricsFeatureProvider); + } +} diff --git a/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java b/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java index 47e677a84f6..dc30028dc9c 100644 --- a/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java +++ b/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java @@ -258,7 +258,7 @@ public class DatabaseIndexingManagerTest { SearchIndexableResource resource = getFakeResource(R.xml.display_settings); mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); - assertThat(cursor.getCount()).isEqualTo(18); + assertThat(cursor.getCount()).isEqualTo(19); } @Test @@ -273,7 +273,7 @@ public class DatabaseIndexingManagerTest { Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 0", null); assertThat(cursor.getCount()).isEqualTo(2); cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 1", null); - assertThat(cursor.getCount()).isEqualTo(16); + assertThat(cursor.getCount()).isEqualTo(17); } @Test