Merge "Disable user control of color mode depending on Accessibility" into pi-dev
diff --git a/src/com/android/settings/display/ColorModePreferenceFragment.java b/src/com/android/settings/display/ColorModePreferenceFragment.java
index 5f5445b..6e4bd1f 100644
--- a/src/com/android/settings/display/ColorModePreferenceFragment.java
+++ b/src/com/android/settings/display/ColorModePreferenceFragment.java
@@ -16,6 +16,7 @@
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.internal.app.ColorDisplayController;
@@ -24,13 +25,15 @@
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.R;
 import com.android.settings.widget.RadioButtonPickerFragment;
+import com.android.settings.widget.RadioButtonPreference;
 import com.android.settingslib.widget.CandidateInfo;
 
 import java.util.Arrays;
 import java.util.List;
 
 @SuppressWarnings("WeakerAccess")
-public class ColorModePreferenceFragment extends RadioButtonPickerFragment {
+public class ColorModePreferenceFragment extends RadioButtonPickerFragment
+        implements ColorDisplayController.Callback {
 
     @VisibleForTesting
     static final String KEY_COLOR_MODE_NATURAL = "color_mode_natural";
@@ -48,6 +51,16 @@
     public void onAttach(Context context) {
         super.onAttach(context);
         mController = new ColorDisplayController(context);
+        mController.setListener(this);
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+        if (mController != null) {
+            mController.setListener(null);
+            mController = null;
+        }
     }
 
     @Override
@@ -71,15 +84,16 @@
     @Override
     protected List<? extends CandidateInfo> getCandidates() {
         Context c = getContext();
+        final boolean enabled = !mController.getAccessibilityTransformActivated();
         return Arrays.asList(
-            new ColorModeCandidateInfo(c.getString(R.string.color_mode_option_natural),
-                    KEY_COLOR_MODE_NATURAL),
-            new ColorModeCandidateInfo(c.getString(R.string.color_mode_option_boosted),
-                    KEY_COLOR_MODE_BOOSTED),
-            new ColorModeCandidateInfo(c.getString(R.string.color_mode_option_saturated),
-                    KEY_COLOR_MODE_SATURATED),
-            new ColorModeCandidateInfo(c.getString(R.string.color_mode_option_automatic),
-                    KEY_COLOR_MODE_AUTOMATIC)
+            new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_natural),
+                    KEY_COLOR_MODE_NATURAL, enabled),
+            new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_boosted),
+                    KEY_COLOR_MODE_BOOSTED, enabled),
+            new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_saturated),
+                    KEY_COLOR_MODE_SATURATED, enabled),
+            new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_automatic),
+                    KEY_COLOR_MODE_AUTOMATIC, enabled)
         );
     }
 
@@ -120,8 +134,8 @@
         private final CharSequence mLabel;
         private final String mKey;
 
-        ColorModeCandidateInfo(CharSequence label, String key) {
-            super(true);
+        ColorModeCandidateInfo(CharSequence label, String key, boolean enabled) {
+            super(enabled);
             mLabel = label;
             mKey = key;
         }
@@ -142,4 +156,18 @@
         }
     }
 
+    @Override
+    public void onAccessibilityTransformChanged(boolean state) {
+        // Disable controls when a11y transforms are enabled, and vice versa
+        final PreferenceScreen screen = getPreferenceScreen();
+        if (screen != null) {
+            final int count = screen.getPreferenceCount();
+            for (int i = 0; i < count; i++) {
+                final Preference pref = screen.getPreference(i);
+                if (pref instanceof RadioButtonPreference) {
+                    pref.setEnabled(!state);
+                }
+            }
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
index e962441..6df0c04 100644
--- a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
@@ -16,8 +16,10 @@
 package com.android.settings.display;
 
 import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -32,6 +34,7 @@
 import com.android.settings.R;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.widget.RadioButtonPreference;
 import com.android.settingslib.widget.CandidateInfo;
 
 import org.junit.Before;
@@ -39,11 +42,11 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.util.ReflectionHelpers;
 
+import java.util.ArrayList;
 import java.util.List;
 
 @RunWith(SettingsRobolectricTestRunner.class)
@@ -54,11 +57,14 @@
     @Mock
     private ColorDisplayController mController;
 
+    @Mock
+    private PreferenceScreen mScreen;
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
 
-        mFragment = spy(new ColorModePreferenceFragment());
+        mFragment = spy(new ColorModePreferenceFragmentTestable(mScreen));
         ReflectionHelpers.setField(mFragment, "mController", mController);
     }
 
@@ -86,7 +92,7 @@
 
     @Test
     public void getKey_natural() {
-        Mockito.when(mController.getColorMode())
+        when(mController.getColorMode())
             .thenReturn(ColorDisplayController.COLOR_MODE_NATURAL);
 
         assertThat(mFragment.getDefaultKey())
@@ -95,7 +101,7 @@
 
     @Test
     public void getKey_boosted() {
-        Mockito.when(mController.getColorMode())
+        when(mController.getColorMode())
             .thenReturn(ColorDisplayController.COLOR_MODE_BOOSTED);
 
         assertThat(mFragment.getDefaultKey())
@@ -104,7 +110,7 @@
 
     @Test
     public void getKey_saturated() {
-        Mockito.when(mController.getColorMode())
+        when(mController.getColorMode())
             .thenReturn(ColorDisplayController.COLOR_MODE_SATURATED);
 
         assertThat(mFragment.getDefaultKey())
@@ -141,15 +147,64 @@
 
     @Test
     public void addStaticPreferences_shouldAddPreviewImage() {
-        PreferenceScreen mockPreferenceScreen = Mockito.mock(PreferenceScreen.class);
-        LayoutPreference mockPreview = Mockito.mock(LayoutPreference.class);
+        PreferenceScreen mockPreferenceScreen = mock(PreferenceScreen.class);
+        LayoutPreference mockPreview = mock(LayoutPreference.class);
 
         ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass(Preference.class);
 
         mFragment.configureAndInstallPreview(mockPreview, mockPreferenceScreen);
-        Mockito.verify(mockPreview, times(1)).setSelectable(false);
-        Mockito.verify(mockPreferenceScreen, times(1)).addPreference(preferenceCaptor.capture());
+        verify(mockPreview, times(1)).setSelectable(false);
+        verify(mockPreferenceScreen, times(1)).addPreference(preferenceCaptor.capture());
 
         assertThat(preferenceCaptor.getValue()).isEqualTo(mockPreview);
     }
+
+    @Test
+    public void onAccessibilityTransformChanged_toggles() {
+        final int radioPrefsCount = 3;
+        List<RadioButtonPreference> radioPrefs = new ArrayList<>();
+        for (int i = 0; i < radioPrefsCount; i++) {
+            radioPrefs.add(mock(RadioButtonPreference.class));
+        }
+
+        when(mScreen.getPreferenceCount()).thenReturn(radioPrefs.size());
+        when(mScreen.getPreference(anyInt())).thenAnswer(invocation -> {
+            final Object[] args = invocation.getArguments();
+            return radioPrefs.get((int) args[0]);
+        });
+
+        mFragment.onAccessibilityTransformChanged(true /* state */);
+        for (int i = 0; i < radioPrefsCount; i++) {
+            verify(radioPrefs.get(i)).setEnabled(false);
+        }
+
+        mFragment.onAccessibilityTransformChanged(false /* state */);
+        for (int i = 0; i < radioPrefsCount; i++) {
+            verify(radioPrefs.get(i)).setEnabled(true);
+        }
+    }
+
+    private static class ColorModePreferenceFragmentTestable
+            extends ColorModePreferenceFragment {
+
+        private final PreferenceScreen mPreferenceScreen;
+
+        private ColorModePreferenceFragmentTestable(PreferenceScreen screen) {
+            mPreferenceScreen = screen;
+        }
+
+        /**
+         * A method to return a mock PreferenceScreen.
+         * A real ColorModePreferenceFragment calls super.getPreferenceScreen() to get its
+         * PreferenceScreen handle, which internally dereferenced a PreferenceManager. But in this
+         * test scenario, the PreferenceManager object is uninitialized, so we need to supply the
+         * PreferenceScreen directly.
+         *
+         * @return a mock PreferenceScreen
+         */
+        @Override
+        public PreferenceScreen getPreferenceScreen() {
+            return mPreferenceScreen;
+        }
+    }
 }