diff --git a/src/com/android/settings/development/ColorModePreference.java b/src/com/android/settings/development/ColorModePreference.java index e0b0837d800..20af2c62ac8 100644 --- a/src/com/android/settings/development/ColorModePreference.java +++ b/src/com/android/settings/development/ColorModePreference.java @@ -28,6 +28,7 @@ import android.view.Display; import com.android.settings.R; import java.util.ArrayList; +import java.util.List; public class ColorModePreference extends SwitchPreference implements DisplayListener { @@ -35,7 +36,28 @@ public class ColorModePreference extends SwitchPreference implements DisplayList private Display mDisplay; private int mCurrentIndex; - private ArrayList mDescriptions; + private List mDescriptions; + + public static List getColorModeDescriptions(Context context) { + + List colorModeDescriptions = new ArrayList<>(); + Resources resources = context.getResources(); + int[] colorModes = resources.getIntArray(R.array.color_mode_ids); + String[] titles = resources.getStringArray(R.array.color_mode_names); + String[] descriptions = resources.getStringArray(R.array.color_mode_descriptions); + // Map the resource information describing color modes. + for (int i = 0; i < colorModes.length; i++) { + if (colorModes[i] != -1 && i != 1 /* Skip Natural for now. */) { + ColorModeDescription desc = new ColorModeDescription(); + desc.colorMode = colorModes[i]; + desc.title = titles[i]; + desc.summary = descriptions[i]; + colorModeDescriptions.add(desc); + } + } + + return colorModeDescriptions; + } public ColorModePreference(Context context, AttributeSet attrs) { super(context, attrs); @@ -75,22 +97,7 @@ public class ColorModePreference extends SwitchPreference implements DisplayList public void updateCurrentAndSupported() { mDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY); - mDescriptions = new ArrayList<>(); - - Resources resources = getContext().getResources(); - int[] colorModes = resources.getIntArray(R.array.color_mode_ids); - String[] titles = resources.getStringArray(R.array.color_mode_names); - String[] descriptions = resources.getStringArray(R.array.color_mode_descriptions); - // Map the resource information describing color modes. - for (int i = 0; i < colorModes.length; i++) { - if (colorModes[i] != -1 && i != 1 /* Skip Natural for now. */) { - ColorModeDescription desc = new ColorModeDescription(); - desc.colorMode = colorModes[i]; - desc.title = titles[i]; - desc.summary = descriptions[i]; - mDescriptions.add(desc); - } - } + mDescriptions = getColorModeDescriptions(getContext()); int currentColorMode = mDisplay.getColorMode(); mCurrentIndex = -1; diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 06623086b25..d334bd05185 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -181,7 +181,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new OemUnlockPreferenceController(context, activity, fragment)); // running services // convert to file encryption - // picture color mode + controllers.add(new PictureColorModePreferenceController(context, lifecycle)); // webview implementation // cool color temperature // automatic system updates diff --git a/src/com/android/settings/development/PictureColorModePreferenceController.java b/src/com/android/settings/development/PictureColorModePreferenceController.java new file mode 100644 index 00000000000..fe4755ff409 --- /dev/null +++ b/src/com/android/settings/development/PictureColorModePreferenceController.java @@ -0,0 +1,99 @@ +/* + * 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.support.annotation.VisibleForTesting; +import android.support.v7.preference.PreferenceScreen; + +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 PictureColorModePreferenceController extends + DeveloperOptionsPreferenceController implements + LifecycleObserver, OnResume, OnPause { + + private static final String KEY_COLOR_MODE = "picture_color_mode"; + + private ColorModePreference mPreference; + + public PictureColorModePreferenceController(Context context, Lifecycle lifecycle) { + super(context); + + if (lifecycle != null) { + lifecycle.addObserver(this); + } + } + + @Override + public boolean isAvailable() { + return getColorModeDescriptionsSize() > 1 && !isWideColorGamut(); + } + + @Override + public String getPreferenceKey() { + return KEY_COLOR_MODE; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = (ColorModePreference) screen.findPreference(getPreferenceKey()); + if (mPreference != null) { + mPreference.updateCurrentAndSupported(); + } + } + + @Override + public void onResume() { + if (mPreference == null) { + return; + } + mPreference.startListening(); + mPreference.updateCurrentAndSupported(); + } + + @Override + public void onPause() { + if (mPreference == null) { + return; + } + mPreference.stopListening(); + } + + @Override + protected void onDeveloperOptionsSwitchEnabled() { + mPreference.setEnabled(true); + } + + @Override + protected void onDeveloperOptionsSwitchDisabled() { + mPreference.setEnabled(false); + } + + @VisibleForTesting + boolean isWideColorGamut() { + return mContext.getDisplay().isWideColorGamut(); + } + + @VisibleForTesting + int getColorModeDescriptionsSize() { + return ColorModePreference.getColorModeDescriptions(mContext).size(); + } +} diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java index c8748deeac3..13f73742d65 100644 --- a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java @@ -112,6 +112,9 @@ public class DevelopmentSettingsDashboardFragmentTest { } @Test + @Config(shadows = { + ShadowPictureColorModePreferenceController.class + }) public void searchIndex_pageEnabled_shouldNotAddKeysToNonIndexable() { final Context appContext = RuntimeEnvironment.application; DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(appContext, true); @@ -198,4 +201,13 @@ public class DevelopmentSettingsDashboardFragmentTest { mShown = true; } } + + @Implements(PictureColorModePreferenceController.class) + public static class ShadowPictureColorModePreferenceController { + + @Implementation + public boolean isAvailable() { + return true; + } + } } diff --git a/tests/robotests/src/com/android/settings/development/PictureColorModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/PictureColorModePreferenceControllerTest.java new file mode 100644 index 00000000000..5cf4e10a4f2 --- /dev/null +++ b/tests/robotests/src/com/android/settings/development/PictureColorModePreferenceControllerTest.java @@ -0,0 +1,137 @@ +/* + * 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 static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.res.Resources; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +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.MockitoAnnotations; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class PictureColorModePreferenceControllerTest { + + @Mock + private ColorModePreference mPreference; + @Mock + private Context mContext; + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private Resources mResources; + + private Lifecycle mLifecycle; + private PictureColorModePreferenceController mController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mLifecycle = new Lifecycle(); + mController = new PictureColorModePreferenceController(mContext, mLifecycle); + when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn( + mPreference); + when(mContext.getResources()).thenReturn(mResources); + when(mResources.getIntArray(R.array.color_mode_ids)).thenReturn(new int[0]); + mController.displayPreference(mPreferenceScreen); + } + + @Test + public void isAvailable_shouldReturnFalseWhenWideColorGambit() { + mController = spy(mController); + doReturn(2).when(mController).getColorModeDescriptionsSize(); + doReturn(true).when(mController).isWideColorGamut(); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void isAvailable_shouldReturnTrueWhenNotWideColorGambit() { + mController = spy(mController); + doReturn(2).when(mController).getColorModeDescriptionsSize(); + doReturn(false).when(mController).isWideColorGamut(); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_shouldReturnFalseWhenColorCountIsOne() { + mController = spy(mController); + doReturn(1).when(mController).getColorModeDescriptionsSize(); + doReturn(true).when(mController).isWideColorGamut(); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void isAvailable_shouldReturnTrueWhenColorCountIsTwo() { + mController = spy(mController); + doReturn(2).when(mController).getColorModeDescriptionsSize(); + doReturn(false).when(mController).isWideColorGamut(); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void onDeveloperOptionEnabled_shouldEnablePreference() { + mController = spy(mController); + doReturn(true).when(mController).isAvailable(); + mController.onDeveloperOptionsEnabled(); + + verify(mPreference).setEnabled(true); + } + + @Test + public void onDeveloperOptionDisabled_shouldDisablePreference() { + mController = spy(mController); + doReturn(true).when(mController).isAvailable(); + mController.onDeveloperOptionsDisabled(); + + verify(mPreference).setEnabled(false); + } + + @Test + public void onResume_shouldStartListening() { + mLifecycle.onResume(); + + verify(mPreference).startListening(); + } + + @Test + public void onPause_shouldStopListening() { + mLifecycle.onPause(); + + verify(mPreference).stopListening(); + } +}