1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.accessibility;
18 
19 import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
20 import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_TILE_COMPONENT_NAME;
21 import static com.android.settings.accessibility.AccessibilityStatsLogUtils.logAccessibilityServiceEnabled;
22 import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
23 import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
24 
25 import android.app.settings.SettingsEnums;
26 import android.content.ComponentName;
27 import android.content.Context;
28 import android.content.res.Resources;
29 import android.os.Bundle;
30 import android.provider.Settings;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.ViewGroup;
34 
35 import androidx.annotation.VisibleForTesting;
36 import androidx.preference.Preference;
37 
38 import com.android.settings.R;
39 import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
40 import com.android.settings.search.BaseSearchIndexProvider;
41 import com.android.settings.widget.SettingsMainSwitchPreference;
42 import com.android.settingslib.core.AbstractPreferenceController;
43 import com.android.settingslib.core.lifecycle.Lifecycle;
44 import com.android.settingslib.search.SearchIndexable;
45 
46 import java.util.ArrayList;
47 import java.util.List;
48 
49 /** Settings for daltonizer. */
50 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
51 public class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceFragment
52         implements DaltonizerRadioButtonPreferenceController.OnChangeListener {
53 
54     private static final String TAG = "ToggleDaltonizerPreferenceFragment";
55     private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED;
56     private static final String KEY_PREVIEW = "daltonizer_preview";
57     @VisibleForTesting
58     static final String KEY_DEUTERANOMALY = "daltonizer_mode_deuteranomaly";
59     @VisibleForTesting
60     static final String KEY_PROTANOMALY = "daltonizer_mode_protanomaly";
61     @VisibleForTesting
62     static final String KEY_TRITANOMEALY = "daltonizer_mode_tritanomaly";
63     @VisibleForTesting
64     static final String KEY_GRAYSCALE = "daltonizer_mode_grayscale";
65     @VisibleForTesting
66     static final String KEY_SATURATION = "daltonizer_saturation";
67 
68     private static final List<AbstractPreferenceController> sControllers = new ArrayList<>();
69 
buildPreferenceControllers(Context context, Lifecycle lifecycle)70     private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
71             Lifecycle lifecycle) {
72         if (sControllers.size() == 0) {
73             final Resources resources = context.getResources();
74             final String[] daltonizerKeys = resources.getStringArray(
75                     R.array.daltonizer_mode_keys);
76 
77             for (String daltonizerKey : daltonizerKeys) {
78                 sControllers.add(new DaltonizerRadioButtonPreferenceController(
79                         context, lifecycle, daltonizerKey));
80             }
81         }
82         return sControllers;
83     }
84 
85     @Override
registerKeysToObserverCallback( AccessibilitySettingsContentObserver contentObserver)86     protected void registerKeysToObserverCallback(
87             AccessibilitySettingsContentObserver contentObserver) {
88         super.registerKeysToObserverCallback(contentObserver);
89 
90         final List<String> enableServiceFeatureKeys = new ArrayList<>(/* initialCapacity= */ 1);
91         enableServiceFeatureKeys.add(ENABLED);
92         contentObserver.registerKeysToObserverCallback(enableServiceFeatureKeys,
93                 key -> updateSwitchBarToggleSwitch());
94     }
95 
96     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)97     public View onCreateView(LayoutInflater inflater, ViewGroup container,
98             Bundle savedInstanceState) {
99         mComponentName = DALTONIZER_COMPONENT_NAME;
100         mPackageName = getText(com.android.settingslib.R
101                 .string.accessibility_display_daltonizer_preference_title);
102         mHtmlDescription = getText(com.android.settingslib.R
103                 .string.accessibility_display_daltonizer_preference_subtitle);
104         mTopIntroTitle = getText(R.string.accessibility_daltonizer_about_intro_text);
105         final View view = super.onCreateView(inflater, container, savedInstanceState);
106         updateFooterPreference();
107         return view;
108     }
109 
110     @Override
onViewCreated(View view, Bundle savedInstanceState)111     public void onViewCreated(View view, Bundle savedInstanceState) {
112         super.onViewCreated(view, savedInstanceState);
113         final View rootView = getActivity().getWindow().peekDecorView();
114         if (rootView != null) {
115             rootView.setAccessibilityPaneTitle(getString(com.android.settingslib.R
116                     .string.accessibility_display_daltonizer_preference_title));
117         }
118     }
119 
120     @Override
onCheckedChanged(Preference preference)121     public void onCheckedChanged(Preference preference) {
122         for (AbstractPreferenceController controller : sControllers) {
123             controller.updateState(preference);
124         }
125     }
126 
updateFooterPreference()127     private void updateFooterPreference() {
128         final String title = getPrefContext()
129                 .getString(R.string.accessibility_daltonizer_about_title);
130         final String learnMoreText = getPrefContext()
131                 .getString(R.string.accessibility_daltonizer_footer_learn_more_content_description);
132         mFooterPreferenceController.setIntroductionTitle(title);
133         mFooterPreferenceController.setupHelpLink(getHelpResource(), learnMoreText);
134         mFooterPreferenceController.displayPreference(getPreferenceScreen());
135     }
136 
137     /** Customizes the order by preference key. */
getPreferenceOrderList()138     protected List<String> getPreferenceOrderList() {
139         final List<String> lists = new ArrayList<>();
140         lists.add(KEY_TOP_INTRO_PREFERENCE);
141         lists.add(KEY_PREVIEW);
142         lists.add(KEY_USE_SERVICE_PREFERENCE);
143         // Putting saturation level close to the preview so users can see what is changing.
144         lists.add(KEY_SATURATION);
145         lists.add(KEY_DEUTERANOMALY);
146         lists.add(KEY_PROTANOMALY);
147         lists.add(KEY_TRITANOMEALY);
148         lists.add(KEY_GRAYSCALE);
149         lists.add(KEY_GENERAL_CATEGORY);
150         lists.add(KEY_HTML_DESCRIPTION_PREFERENCE);
151         return lists;
152     }
153 
154     @Override
onResume()155     public void onResume() {
156         super.onResume();
157         updateSwitchBarToggleSwitch();
158         for (AbstractPreferenceController controller :
159                 buildPreferenceControllers(getPrefContext(), getSettingsLifecycle())) {
160             ((DaltonizerRadioButtonPreferenceController) controller).setOnChangeListener(this);
161             ((DaltonizerRadioButtonPreferenceController) controller).displayPreference(
162                     getPreferenceScreen());
163         }
164     }
165 
166     @Override
onPause()167     public void onPause() {
168         for (AbstractPreferenceController controller :
169                 buildPreferenceControllers(getPrefContext(), getSettingsLifecycle())) {
170             ((DaltonizerRadioButtonPreferenceController) controller).setOnChangeListener(null);
171         }
172         super.onPause();
173     }
174 
175     @Override
getMetricsCategory()176     public int getMetricsCategory() {
177         return SettingsEnums.ACCESSIBILITY_TOGGLE_DALTONIZER;
178     }
179 
180     @Override
getHelpResource()181     public int getHelpResource() {
182         return R.string.help_url_color_correction;
183     }
184 
185     @Override
getPreferenceScreenResId()186     protected int getPreferenceScreenResId() {
187         return R.xml.accessibility_daltonizer_settings;
188     }
189 
190     @Override
getLogTag()191     protected String getLogTag() {
192         return TAG;
193     }
194 
195     @Override
onPreferenceToggled(String preferenceKey, boolean enabled)196     protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
197         final boolean isEnabled = Settings.Secure.getInt(getContentResolver(), ENABLED, OFF) == ON;
198         if (enabled == isEnabled) {
199             return;
200         }
201 
202         if (enabled) {
203             showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
204         }
205         logAccessibilityServiceEnabled(mComponentName, enabled);
206         Settings.Secure.putInt(getContentResolver(), ENABLED, enabled ? ON : OFF);
207     }
208 
209     @Override
onRemoveSwitchPreferenceToggleSwitch()210     protected void onRemoveSwitchPreferenceToggleSwitch() {
211         super.onRemoveSwitchPreferenceToggleSwitch();
212         mToggleServiceSwitchPreference.setOnPreferenceClickListener(null);
213     }
214 
215     @Override
updateToggleServiceTitle(SettingsMainSwitchPreference switchPreference)216     protected void updateToggleServiceTitle(SettingsMainSwitchPreference switchPreference) {
217         switchPreference.setTitle(R.string.accessibility_daltonizer_primary_switch_title);
218     }
219 
220     @Override
getShortcutTitle()221     protected CharSequence getShortcutTitle() {
222         return getText(R.string.accessibility_daltonizer_shortcut_title);
223     }
224 
225     @Override
getUserShortcutTypes()226     int getUserShortcutTypes() {
227         return AccessibilityUtil.getUserShortcutTypesFromSettings(getPrefContext(),
228                 mComponentName);
229     }
230 
231     @Override
getTileComponentName()232     ComponentName getTileComponentName() {
233         return DALTONIZER_TILE_COMPONENT_NAME;
234     }
235 
236     @Override
getTileTooltipContent(@uickSettingsTooltipType int type)237     CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
238         return getText(type == QuickSettingsTooltipType.GUIDE_TO_EDIT
239                 ? R.string.accessibility_color_correction_qs_tooltip_content
240                 : R.string.accessibility_color_correction_auto_added_qs_tooltip_content);
241     }
242 
243     @Override
updateSwitchBarToggleSwitch()244     protected void updateSwitchBarToggleSwitch() {
245         final boolean checked = Settings.Secure.getInt(getContentResolver(), ENABLED, OFF) == ON;
246         if (mToggleServiceSwitchPreference.isChecked() == checked) {
247             return;
248         }
249         mToggleServiceSwitchPreference.setChecked(checked);
250     }
251 
252     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
253             new BaseSearchIndexProvider(R.xml.accessibility_daltonizer_settings);
254 }
255