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
This commit is contained in:
menghanli
2019-12-23 17:08:49 +08:00
committed by Raff Tsai
parent b2c2f9d5e3
commit b7306044c9
10 changed files with 309 additions and 69 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="@dimen/color_mode_preview_height"
android:contentDescription="@null"
android:scaleType="fitCenter"
android:src="@drawable/accessibility_color_inversion_preview"/>
</FrameLayout>

View File

@@ -4903,8 +4903,10 @@
<string name="accessibility_long_press_timeout_preference_title">Touch &amp; hold delay</string>
<!-- Title for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
<string name="accessibility_display_inversion_preference_title">Color inversion</string>
<!-- Used in the accessibility service settings to control turning display color inversion on/off entirely. [CHAR LIMIT=NONE] -->
<string name="accessibility_display_inversion_switch_title">Invert colors</string>
<!-- Subtitle for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
<string name="accessibility_display_inversion_preference_subtitle">May affect performance</string>
<string name="accessibility_display_inversion_preference_subtitle">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.</string>
<!-- Title for accessibility preference for configuring feature that performs click action soon after mouse/trackpad pointer stops moving. [CHAR LIMIT=NONE] -->
<string name="accessibility_autoclick_preference_title">Dwell timing</string>
<!-- Footer text to explain what autoclick does -->
@@ -4919,7 +4921,7 @@
<string name="accessibility_ring_vibration_title">Ring vibration</string>
<!-- Title for accessibility preference for configuring touch feedback vibrations. -->
<string name="accessibility_touch_vibration_title">Touch feedback</string>
<!-- Used in the acessibilty service settings to control turning on/off the service entirely -->
<!-- Used in the accessibility service settings to control turning on/off the service entirely -->
<string name="accessibility_service_master_switch_title">Use <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g></string>
<!-- Used in the Color correction settings screen to control turning on/off the feature entirely -->
<string name="accessibility_daltonizer_master_switch_title">Use color correction</string>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="color_inversion_preference_screen"
android:persistent="false"
android:title="@string/accessibility_display_inversion_preference_title">
<com.android.settingslib.widget.LayoutPreference
android:key="color_inversion_preview"
android:layout="@layout/color_inversion_preview"
android:persistent="false"
android:selectable="false"
android:title="@string/summary_placeholder"
settings:allowDividerAbove="true"
settings:allowDividerBelow="true"
settings:searchable="false" />
<com.android.settingslib.widget.FooterPreference
android:key="color_inversion_footer"
android:persistent="false"
android:selectable="false"
android:title="@string/accessibility_display_inversion_preference_subtitle"
settings:allowDividerAbove="true"
settings:searchable="false" />
</PreferenceScreen>

View File

@@ -209,11 +209,11 @@
android:title="@string/accessibility_display_daltonizer_preference_title"
settings:controller="com.android.settings.accessibility.DaltonizerPreferenceController"/>
<SwitchPreference
<Preference
android:fragment="com.android.settings.accessibility.ToggleColorInversionPreferenceFragment"
android:icon="@drawable/ic_color_inversion"
android:key="toggle_inversion_preference"
android:persistent="false"
android:summary="@string/accessibility_display_inversion_preference_subtitle"
android:title="@string/accessibility_display_inversion_preference_title"
settings:controller="com.android.settings.accessibility.ColorInversionPreferenceController"/>
</PreferenceCategory>

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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<String> 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);
}

View File

@@ -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);
}

View File

@@ -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;
}
}