From b7306044c930242c73a8bc7a41ab9d9190972813 Mon Sep 17 00:00:00 2001 From: menghanli Date: Mon, 23 Dec 2019 17:08:49 +0800 Subject: [PATCH] Create settings for color inversion (2/n) Provide a setting for new color inversion design. Bug: 146019226 Test: make RunSettingsRoboTests ROBOTEST_FILTER=ColorInversionPreferenceControllerTest Test: make RunSettingsRoboTests2 Change-Id: I1d081c6321ee96d48e8f52304893e4a5fb59333a --- .../accessibility_color_inversion_preview.png | Bin 0 -> 15263 bytes res/layout/color_inversion_preview.xml | 29 +++ res/values/strings.xml | 6 +- ...accessibility_color_inversion_settings.xml | 42 ++++ res/xml/accessibility_settings.xml | 4 +- .../accessibility/AccessibilitySettings.java | 5 +- .../ColorInversionPreferenceController.java | 23 +- ...oggleColorInversionPreferenceFragment.java | 199 ++++++++++++++++++ .../ToggleDaltonizerPreferenceFragment.java | 5 +- ...olorInversionPreferenceControllerTest.java | 65 ++---- 10 files changed, 309 insertions(+), 69 deletions(-) create mode 100644 res/drawable/accessibility_color_inversion_preview.png create mode 100644 res/layout/color_inversion_preview.xml create mode 100644 res/xml/accessibility_color_inversion_settings.xml create mode 100644 src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java diff --git a/res/drawable/accessibility_color_inversion_preview.png b/res/drawable/accessibility_color_inversion_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..5c9f3ea10a1533ee5110683635b24397281b10a4 GIT binary patch literal 15263 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 b68WWNmeG(ty + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index cd473a296ba..cb3dae9ba23 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4903,8 +4903,10 @@ Touch & hold delay Color inversion + + Invert colors - May affect performance + Turn light screens dark so people who are sensitive to bright light can have a better viewing experience.\n\nNote: dark colors will turn light. Images will also be inverted. Dwell timing @@ -4919,7 +4921,7 @@ Ring vibration Touch feedback - + Use %1$s Use color correction diff --git a/res/xml/accessibility_color_inversion_settings.xml b/res/xml/accessibility_color_inversion_settings.xml new file mode 100644 index 00000000000..de1511fbc81 --- /dev/null +++ b/res/xml/accessibility_color_inversion_settings.xml @@ -0,0 +1,42 @@ + + + + + + + + + diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml index a7b602cfb0f..d83fa595fb8 100644 --- a/res/xml/accessibility_settings.xml +++ b/res/xml/accessibility_settings.xml @@ -209,11 +209,11 @@ android:title="@string/accessibility_display_daltonizer_preference_title" settings:controller="com.android.settings.accessibility.DaltonizerPreferenceController"/> - diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java index ee73e6fe02e..f184b982c96 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettings.java +++ b/src/com/android/settings/accessibility/AccessibilitySettings.java @@ -172,7 +172,7 @@ public class AccessibilitySettings extends DashboardFragment { private SwitchPreference mToggleDisableAnimationsPreference; private Preference mDisplayMagnificationPreferenceScreen; private Preference mDisplayDaltonizerPreferenceScreen; - private SwitchPreference mToggleInversionPreference; + private Preference mToggleInversionPreference; private DevicePolicyManager mDpm; @@ -502,7 +502,8 @@ public class AccessibilitySettings extends DashboardFragment { mToggleInversionPreference.getOrder() + 1); mToggleDisableAnimationsPreference.setOrder( mToggleLargePointerIconPreference.getOrder() + 1); - mToggleInversionPreference.setSummary(R.string.summary_empty); + mToggleInversionPreference.setSummary(AccessibilityUtil.getSummary( + getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED)); displayCategory.addPreference(mToggleInversionPreference); displayCategory.addPreference(mDisplayDaltonizerPreferenceScreen); } diff --git a/src/com/android/settings/accessibility/ColorInversionPreferenceController.java b/src/com/android/settings/accessibility/ColorInversionPreferenceController.java index 4e4c17b17a7..926bc0d0080 100644 --- a/src/com/android/settings/accessibility/ColorInversionPreferenceController.java +++ b/src/com/android/settings/accessibility/ColorInversionPreferenceController.java @@ -19,30 +19,21 @@ package com.android.settings.accessibility; import android.content.Context; import android.provider.Settings; -import androidx.annotation.VisibleForTesting; +import com.android.settings.core.BasePreferenceController; -import com.android.settings.core.TogglePreferenceController; +/** Controller that shows the color inversion summary. */ +public class ColorInversionPreferenceController extends BasePreferenceController { -public class ColorInversionPreferenceController extends TogglePreferenceController { - @VisibleForTesting - static final int ON = 1; - @VisibleForTesting - static final int OFF = 0; + private static final String DISPLAY_INVERSION_ENABLED = + Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED; public ColorInversionPreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); } @Override - public boolean isChecked() { - return Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, OFF) == ON; - } - - @Override - public boolean setChecked(boolean isChecked) { - return Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, (isChecked ? ON : OFF)); + public CharSequence getSummary() { + return AccessibilityUtil.getSummary(mContext, DISPLAY_INVERSION_ENABLED); } @Override diff --git a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java new file mode 100644 index 00000000000..880efb6d135 --- /dev/null +++ b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2019 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.accessibility; + +import android.app.Dialog; +import android.app.settings.SettingsEnums; +import android.content.DialogInterface; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.provider.Settings; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Switch; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.widget.SwitchBar; +import com.android.settingslib.search.SearchIndexable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; + +/** Settings page for color inversion. */ +@SearchIndexable +public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePreferenceFragment + implements SwitchBar.OnSwitchChangeListener, ShortcutPreference.OnClickListener { + + private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED; + private static final String PREVIEW_PREFERENCE_KEY = "color_inversion_preview"; + private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference"; + private static final int DIALOG_ID_EDIT_SHORTCUT = 1; + private static final String DISPLAY_INVERSION_ENABLED = + Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED; + private final DialogInterface.OnClickListener mDialogListener = + (DialogInterface dialog, int id) -> { + if (id == DialogInterface.BUTTON_POSITIVE) { + // TODO(b/142531156): Save the shortcut type preference. + } + }; + private final Handler mHandler = new Handler(); + private Dialog mDialog; + private SettingsContentObserver mSettingsContentObserver; + + @Override + public void onStart() { + super.onStart(); + mSettingsContentObserver.register(getContentResolver()); + } + + @Override + public void onStop() { + mSettingsContentObserver.unregister(getContentResolver()); + super.onStop(); + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.ACCESSIBILITY_COLOR_INVERSION_SETTINGS; + } + + @Override + protected void onPreferenceToggled(String preferenceKey, boolean enabled) { + Settings.Secure.putInt(getContentResolver(), ENABLED, enabled ? State.OFF : State.ON); + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.accessibility_color_inversion_settings; + } + + @Override + protected void onRemoveSwitchBarToggleSwitch() { + super.onRemoveSwitchBarToggleSwitch(); + mSwitchBar.removeOnSwitchChangeListener(this); + } + + @Override + protected void updateSwitchBarText(SwitchBar switchBar) { + final String switchBarText = getString( + R.string.accessibility_display_inversion_switch_title, + getString(R.string.accessibility_display_inversion_switch_title)); + switchBar.setSwitchBarText(switchBarText, switchBarText); + } + + @Override + public void onSwitchChanged(Switch switchView, boolean isChecked) { + Settings.Secure.putInt(getContentResolver(), ENABLED, isChecked ? State.ON : State.OFF); + } + + @Override + protected void onInstallSwitchBarToggleSwitch() { + super.onInstallSwitchBarToggleSwitch(); + mSwitchBar.setCheckedInternal( + Settings.Secure.getInt(getContentResolver(), ENABLED, State.OFF) == State.ON); + mSwitchBar.addOnSwitchChangeListener(this); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + initShortcutPreference(); + final List shortcutFeatureKeys = new ArrayList<>(1); + shortcutFeatureKeys.add(DISPLAY_INVERSION_ENABLED); + mSettingsContentObserver = new SettingsContentObserver(mHandler, shortcutFeatureKeys) { + @Override + public void onChange(boolean selfChange, Uri uri) { + mSwitchBar.setCheckedInternal( + Settings.Secure.getInt(getContentResolver(), ENABLED, State.OFF) + == State.ON); + } + }; + return super.onCreateView(inflater, container, savedInstanceState); + } + + @Override + public Dialog onCreateDialog(int dialogId) { + if (dialogId == DIALOG_ID_EDIT_SHORTCUT) { + final CharSequence dialogTitle = getActivity().getString( + R.string.accessibility_shortcut_edit_dialog_title_daltonizer); + mDialog = AccessibilityEditDialogUtils.showEditShortcutDialog(getActivity(), + dialogTitle, mDialogListener); + } + + return mDialog; + } + + @Override + public int getDialogMetricsCategory(int dialogId) { + if (dialogId == DIALOG_ID_EDIT_SHORTCUT) { + return SettingsEnums.DIALOG_COLOR_INVERSION_EDIT_SHORTCUT; + } + return 0; + } + + private void initShortcutPreference() { + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + final ShortcutPreference shortcutPreference = new ShortcutPreference( + preferenceScreen.getContext(), null); + final Preference previewPreference = findPreference(PREVIEW_PREFERENCE_KEY); + // Put the shortcutPreference before radioButtonPreference. + shortcutPreference.setPersistent(false); + shortcutPreference.setKey(getShortcutPreferenceKey()); + shortcutPreference.setOrder(previewPreference.getOrder() - 1); + shortcutPreference.setTitle(R.string.accessibility_shortcut_title); + shortcutPreference.setOnClickListener(this); + // TODO(b/142530063): Check the new setting key to decide which summary should be shown. + // TODO(b/142530063): Check if gesture mode is on to decide which summary should be shown. + // TODO(b/142530063): Check the new key to decide whether checkbox should be checked. + preferenceScreen.addPreference(shortcutPreference); + } + + public String getShortcutPreferenceKey() { + return KEY_SHORTCUT_PREFERENCE; + } + + @Override + public void onCheckboxClicked(ShortcutPreference preference) { + if (preference.getChecked()) { + // TODO(b/142530063): Enable shortcut when checkbox is checked. + } else { + // TODO(b/142530063): Disable shortcut when checkbox is unchecked. + } + } + + @Override + public void onSettingsClicked(ShortcutPreference preference) { + showDialog(DIALOG_ID_EDIT_SHORTCUT); + } + + @Retention(RetentionPolicy.SOURCE) + private @interface State { + int OFF = 0; + int ON = 1; + } + + public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider(R.xml.accessibility_color_inversion_settings); +} diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java index 9fb93efd9cd..a4f3e62a987 100644 --- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java @@ -47,8 +47,6 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe implements DaltonizerRadioButtonPreferenceController.OnChangeListener, SwitchBar.OnSwitchChangeListener, ShortcutPreference.OnClickListener { - public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.accessibility_daltonizer_settings); private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED; private static final String RADIOPREFERENCE_KEY = "daltonizer_mode_deuteranomaly"; private static final int DIALOG_ID_EDIT_SHORTCUT = 1; @@ -206,4 +204,7 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe shortcutPreference.setOnClickListener(this); preferenceScreen.addPreference(shortcutPreference); } + + public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider(R.xml.accessibility_daltonizer_settings); } diff --git a/tests/robotests/src/com/android/settings/accessibility/ColorInversionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/ColorInversionPreferenceControllerTest.java index 6b46652e30f..e03449887d3 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ColorInversionPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ColorInversionPreferenceControllerTest.java @@ -16,82 +16,57 @@ package com.android.settings.accessibility; -import static com.android.settings.accessibility.ColorInversionPreferenceController.OFF; -import static com.android.settings.accessibility.ColorInversionPreferenceController.ON; - import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.provider.Settings; -import androidx.preference.SwitchPreference; - -import com.android.settings.core.BasePreferenceController; +import com.android.settings.R; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + @RunWith(RobolectricTestRunner.class) public class ColorInversionPreferenceControllerTest { - private static final int UNKNOWN = -1; + private static final String PREF_KEY = "toggle_inversion_preference"; + private static final String DISPLAY_INVERSION_ENABLED = + Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED; private Context mContext; private ColorInversionPreferenceController mController; - private SwitchPreference mPreference; @Before public void setUp() { - MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; - mController = new ColorInversionPreferenceController(mContext, "pref_key"); - mPreference = new SwitchPreference(mContext); - mController.updateState(mPreference); + mController = new ColorInversionPreferenceController(mContext, PREF_KEY); } @Test - public void getAvailabilityStatus_available() { - assertThat(mController.getAvailabilityStatus()).isEqualTo( - BasePreferenceController.AVAILABLE); - } - - @Test - public void isChecked_enabled() { + public void getSummary_enabledColorInversion_shouldReturnOnSummary() { Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, ON); + DISPLAY_INVERSION_ENABLED, State.ON); - mController.updateState(mPreference); - - assertThat(mController.isChecked()).isTrue(); - assertThat(mPreference.isChecked()).isTrue(); + assertThat(mController.getSummary().toString().contains( + mContext.getText(R.string.accessibility_feature_state_on))).isTrue(); } @Test - public void isChecked_disabled() { + public void getSummary_disabledColorInversion_shouldReturnOffSummary() { Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, OFF); + DISPLAY_INVERSION_ENABLED, State.OFF); - mController.updateState(mPreference); - - assertThat(mController.isChecked()).isFalse(); - assertThat(mPreference.isChecked()).isFalse(); + assertThat(mController.getSummary().toString().contains( + mContext.getText(R.string.accessibility_feature_state_off))).isTrue(); } - @Test - public void setChecked_enabled() { - mController.setChecked(true); - - assertThat(Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, UNKNOWN)).isEqualTo(ON); - } - - @Test - public void setChecked_disabled() { - mController.setChecked(false); - - assertThat(Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, UNKNOWN)).isEqualTo(OFF); + @Retention(RetentionPolicy.SOURCE) + private @interface State { + int OFF = 0; + int ON = 1; } }