From 305f900bfa42a4ecc3a7b8d1454331d8ad8d76a9 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Mon, 5 Jun 2017 18:44:47 -0700 Subject: [PATCH] Add saturation boost setting Bug: 62238038 62377592 38225028 Test: make RunSettingsRoboTests -j40 ROBOTEST_FILTER=com.android.settings.display.ColorModePreferenceControllerTest Change-Id: Iae8f4b25966ff28fde127e6103b2c03c67862cf0 --- res/values/strings.xml | 2 + res/xml/development_prefs.xml | 2 +- res/xml/display_settings.xml | 4 + src/com/android/settings/DisplaySettings.java | 2 + .../development/DevelopmentSettings.java | 5 +- .../ColorModePreferenceController.java | 118 ++++++++++++++++++ .../ColorModePreferenceControllerTest.java | 113 +++++++++++++++++ .../search/DatabaseIndexingManagerTest.java | 4 +- 8 files changed, 245 insertions(+), 5 deletions(-) create mode 100644 src/com/android/settings/display/ColorModePreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/display/ColorModePreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 3c248256025..c3c950d856f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2328,6 +2328,8 @@ Display Auto-rotate screen + + Vivid colors Switch orientation automatically when rotating tablet diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml index d6f9dcc6f64..e443027075b 100644 --- a/res/xml/development_prefs.xml +++ b/res/xml/development_prefs.xml @@ -71,7 +71,7 @@ android:fragment="com.android.settings.applications.ConvertToFbe" /> diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml index 11b26769551..0462e94b1ec 100644 --- a/res/xml/display_settings.xml +++ b/res/xml/display_settings.xml @@ -62,6 +62,10 @@ android:key="auto_rotate" android:title="@string/accelerometer_title" /> + + 1.0f); + } + + @Override + public boolean isAvailable() { + return mConfigWrapper.isScreenWideColorGamut(); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + float saturation = (boolean) newValue + ? COLOR_SATURATION_VIVID : COLOR_SATURATION_DEFAULT; + + SystemProperties.set(PERSISTENT_PROPERTY_SATURATION, Float.toString(saturation)); + applySaturation(saturation); + + return true; + } + + /** + * Propagates the provided saturation to the SurfaceFlinger. + */ + private void applySaturation(float saturation) { + if (mSurfaceFlinger != null) { + final Parcel data = Parcel.obtain(); + data.writeInterfaceToken("android.ui.ISurfaceComposer"); + data.writeFloat(saturation); + try { + mSurfaceFlinger.transact(SURFACE_FLINGER_TRANSACTION_SATURATION, data, null, 0); + } catch (RemoteException ex) { + Log.e(TAG, "Failed to set saturation", ex); + } finally { + data.recycle(); + } + } + } + + private static float getSaturationValue() { + try { + return Float.parseFloat(SystemProperties.get( + PERSISTENT_PROPERTY_SATURATION, Float.toString(COLOR_SATURATION_DEFAULT))); + } catch (NumberFormatException e) { + return COLOR_SATURATION_DEFAULT; + } + } + + @VisibleForTesting + static class ConfigurationWrapper { + private final Context mContext; + + ConfigurationWrapper(Context context) { + mContext = context; + } + + boolean isScreenWideColorGamut() { + return mContext.getResources().getConfiguration().isScreenWideColorGamut(); + } + } +} diff --git a/tests/robotests/src/com/android/settings/display/ColorModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/ColorModePreferenceControllerTest.java new file mode 100644 index 00000000000..f93e1a735a5 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/ColorModePreferenceControllerTest.java @@ -0,0 +1,113 @@ +/* + * 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 android.content.Context; +import android.os.IBinder; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.PreferenceScreen; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.testutils.shadow.SettingsShadowSystemProperties; +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; +import org.robolectric.util.ReflectionHelpers; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class ColorModePreferenceControllerTest { + @Mock + private ColorModePreferenceController.ConfigurationWrapper mConfigWrapper; + @Mock + private SwitchPreference mPreference; + @Mock + private PreferenceScreen mScreen; + @Mock + private Context mContext; + @Mock + private IBinder mSurfaceFlinger; + + private ColorModePreferenceController mController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + SettingsShadowSystemProperties.clear(); + + mController = new ColorModePreferenceController(mContext); + ReflectionHelpers.setField(mController, "mSurfaceFlinger", mSurfaceFlinger); + ReflectionHelpers.setField(mController, "mConfigWrapper", mConfigWrapper); + + when(mConfigWrapper.isScreenWideColorGamut()).thenReturn(true); + + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); + } + + @Config(shadows = {SettingsShadowSystemProperties.class}) + @Test + public void shouldCheckPreference() { + SettingsShadowSystemProperties.set( + ColorModePreferenceController.PERSISTENT_PROPERTY_SATURATION, + Float.toString(ColorModePreferenceController.COLOR_SATURATION_VIVID)); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(true); + } + + @Config(shadows = {SettingsShadowSystemProperties.class}) + @Test + public void shouldUncheckPreference() { + SettingsShadowSystemProperties.set( + ColorModePreferenceController.PERSISTENT_PROPERTY_SATURATION, + Float.toString(ColorModePreferenceController.COLOR_SATURATION_DEFAULT)); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(false); + } + + @Config(shadows = {SettingsShadowSystemProperties.class}) + @Test + public void shouldBoostSaturationOnCheck() { + mController.onPreferenceChange(mPreference, true); + + String saturation = SettingsShadowSystemProperties + .get(ColorModePreferenceController.PERSISTENT_PROPERTY_SATURATION); + assertThat(saturation) + .isEqualTo(Float.toString(ColorModePreferenceController.COLOR_SATURATION_VIVID)); + } + + @Config(shadows = {SettingsShadowSystemProperties.class}) + @Test + public void shouldResetSaturationOnUncheck() { + mController.onPreferenceChange(mPreference, false); + + String saturation = SettingsShadowSystemProperties + .get(ColorModePreferenceController.PERSISTENT_PROPERTY_SATURATION); + assertThat(saturation) + .isEqualTo(Float.toString(ColorModePreferenceController.COLOR_SATURATION_DEFAULT)); + } +} diff --git a/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java b/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java index f06f0036bda..87171aeba65 100644 --- a/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java +++ b/tests/robotests/src/com/android/settings/search/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(16); + assertThat(cursor.getCount()).isEqualTo(17); } @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(14); + assertThat(cursor.getCount()).isEqualTo(15); } @Test