1 /*
2  * Copyright (C) 2019 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 android.content.ContentResolver;
20 import android.content.Context;
21 import android.content.res.Resources;
22 import android.provider.Settings;
23 import android.view.View;
24 import android.view.accessibility.AccessibilityManager;
25 
26 import androidx.lifecycle.LifecycleObserver;
27 import androidx.preference.Preference;
28 import androidx.preference.PreferenceScreen;
29 
30 import com.android.settings.R;
31 import com.android.settings.core.BasePreferenceController;
32 import com.android.settingslib.core.lifecycle.Lifecycle;
33 import com.android.settingslib.widget.RadioButtonPreference;
34 
35 import com.google.common.primitives.Ints;
36 
37 import java.util.HashMap;
38 import java.util.Map;
39 
40 /** Controller class that control radio button of accessibility daltonizer settings. */
41 public class DaltonizerRadioButtonPreferenceController extends BasePreferenceController implements
42         LifecycleObserver, RadioButtonPreference.OnClickListener {
43     private static final String TYPE = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER;
44 
45     // pair the preference key and daltonizer value.
46     private final Map<String, Integer> mAccessibilityDaltonizerKeyToValueMap = new HashMap<>();
47 
48     // RadioButtonPreference key, each preference represent a daltonizer value.
49     private final ContentResolver mContentResolver;
50     private final Resources mResources;
51     private DaltonizerRadioButtonPreferenceController.OnChangeListener mOnChangeListener;
52     private RadioButtonPreference mPreference;
53     private int mAccessibilityDaltonizerValue;
54 
DaltonizerRadioButtonPreferenceController(Context context, String preferenceKey)55     public DaltonizerRadioButtonPreferenceController(Context context, String preferenceKey) {
56         super(context, preferenceKey);
57 
58         mContentResolver = context.getContentResolver();
59         mResources = context.getResources();
60     }
61 
DaltonizerRadioButtonPreferenceController(Context context, Lifecycle lifecycle, String preferenceKey)62     public DaltonizerRadioButtonPreferenceController(Context context, Lifecycle lifecycle,
63             String preferenceKey) {
64         super(context, preferenceKey);
65 
66         mContentResolver = context.getContentResolver();
67         mResources = context.getResources();
68 
69         if (lifecycle != null) {
70             lifecycle.addObserver(this);
71         }
72     }
73 
getSecureAccessibilityDaltonizerValue(ContentResolver resolver, String name)74     protected static int getSecureAccessibilityDaltonizerValue(ContentResolver resolver,
75             String name) {
76         final String daltonizerStringValue = Settings.Secure.getString(resolver, name);
77         if (daltonizerStringValue == null) {
78             return AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY;
79         }
80         final Integer daltonizerIntValue = Ints.tryParse(daltonizerStringValue);
81         return daltonizerIntValue == null ? AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY
82                 : daltonizerIntValue;
83     }
84 
setOnChangeListener( DaltonizerRadioButtonPreferenceController.OnChangeListener listener)85     public void setOnChangeListener(
86             DaltonizerRadioButtonPreferenceController.OnChangeListener listener) {
87         mOnChangeListener = listener;
88     }
89 
getDaltonizerValueToKeyMap()90     private Map<String, Integer> getDaltonizerValueToKeyMap() {
91         if (mAccessibilityDaltonizerKeyToValueMap.size() == 0) {
92 
93             final String[] daltonizerKeys = mResources.getStringArray(
94                     R.array.daltonizer_mode_keys);
95 
96             final int[] daltonizerValues = mResources.getIntArray(
97                     R.array.daltonizer_type_values);
98 
99             final int daltonizerValueCount = daltonizerValues.length;
100             for (int i = 0; i < daltonizerValueCount; i++) {
101                 mAccessibilityDaltonizerKeyToValueMap.put(daltonizerKeys[i], daltonizerValues[i]);
102             }
103         }
104         return mAccessibilityDaltonizerKeyToValueMap;
105     }
106 
putSecureString(String name, String value)107     private void putSecureString(String name, String value) {
108         Settings.Secure.putString(mContentResolver, name, value);
109     }
110 
handlePreferenceChange(String value)111     private void handlePreferenceChange(String value) {
112         putSecureString(TYPE, value);
113     }
114 
115     @Override
getAvailabilityStatus()116     public int getAvailabilityStatus() {
117         return AVAILABLE;
118     }
119 
120     @Override
displayPreference(PreferenceScreen screen)121     public void displayPreference(PreferenceScreen screen) {
122         super.displayPreference(screen);
123         mPreference = (RadioButtonPreference)
124                 screen.findPreference(getPreferenceKey());
125         mPreference.setOnClickListener(this);
126         mPreference.setAppendixVisibility(View.GONE);
127         updateState(mPreference);
128     }
129 
130     @Override
onRadioButtonClicked(RadioButtonPreference preference)131     public void onRadioButtonClicked(RadioButtonPreference preference) {
132         final int value = getDaltonizerValueToKeyMap().get(mPreferenceKey);
133         handlePreferenceChange(String.valueOf(value));
134         if (mOnChangeListener != null) {
135             mOnChangeListener.onCheckedChanged(mPreference);
136         }
137     }
138 
getAccessibilityDaltonizerValue()139     private int getAccessibilityDaltonizerValue() {
140         final int daltonizerValue = getSecureAccessibilityDaltonizerValue(mContentResolver,
141                 TYPE);
142         return daltonizerValue;
143     }
144 
updatePreferenceCheckedState(int value)145     protected void updatePreferenceCheckedState(int value) {
146         if (mAccessibilityDaltonizerValue == value) {
147             mPreference.setChecked(true);
148         }
149     }
150 
151     @Override
updateState(Preference preference)152     public void updateState(Preference preference) {
153         super.updateState(preference);
154         mAccessibilityDaltonizerValue = getAccessibilityDaltonizerValue();
155 
156         // reset RadioButton
157         mPreference.setChecked(false);
158         final int preferenceValue = getDaltonizerValueToKeyMap().get(mPreference.getKey());
159         updatePreferenceCheckedState(preferenceValue);
160     }
161 
162     /** Listener interface handles checked event. */
163     public interface OnChangeListener {
164         /** A hook that is called when preference checked. */
onCheckedChanged(Preference preference)165         void onCheckedChanged(Preference preference);
166     }
167 }
168