• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 android.content.Context.MODE_PRIVATE;
20 
21 import android.content.ContentResolver;
22 import android.content.Context;
23 import android.content.SharedPreferences;
24 import android.content.res.Resources;
25 import android.provider.Settings;
26 import android.util.ArrayMap;
27 
28 import androidx.annotation.VisibleForTesting;
29 import androidx.lifecycle.LifecycleObserver;
30 import androidx.preference.Preference;
31 import androidx.preference.PreferenceScreen;
32 
33 import com.android.settings.R;
34 import com.android.settings.core.BasePreferenceController;
35 import com.android.settings.core.PreferenceControllerMixin;
36 import com.android.settingslib.core.lifecycle.Lifecycle;
37 import com.android.settingslib.widget.LayoutPreference;
38 import com.android.settingslib.widget.RadioButtonPreference;
39 
40 import java.util.Map;
41 
42 /**
43  * Controller class that controls accessibility autoclick settings.
44  */
45 public class ToggleAutoclickPreferenceController extends BasePreferenceController implements
46         LifecycleObserver, RadioButtonPreference.OnClickListener, PreferenceControllerMixin {
47 
48     @VisibleForTesting
49     static final String CONTROL_AUTOCLICK_DELAY_SECURE =
50             Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY;
51 
52     @VisibleForTesting
53     static final String KEY_AUTOCLICK_CUSTOM_SEEKBAR = "autoclick_custom_seekbar";
54     static final String KEY_DELAY_MODE = "delay_mode";
55 
56     @VisibleForTesting
57     static final int AUTOCLICK_OFF_MODE = 0;
58 
59     @VisibleForTesting
60     static final int AUTOCLICK_CUSTOM_MODE = 2000;
61 
62     // Pair the preference key and autoclick mode value.
63     @VisibleForTesting
64     Map<String, Integer> mAccessibilityAutoclickKeyToValueMap = new ArrayMap<>();
65 
66     private SharedPreferences mSharedPreferences;
67     private final ContentResolver mContentResolver;
68     private final Resources mResources;
69     private OnChangeListener mOnChangeListener;
70     private RadioButtonPreference mDelayModePref;
71 
72     /**
73      * Seek bar preference for autoclick delay value. The seek bar has values between 0 and
74      * number of possible discrete autoclick delay values. These will have to be converted to actual
75      * delay values before saving them in settings.
76      */
77     private LayoutPreference mSeekBerPreference;
78     private int mCurrentUiAutoClickMode;
79 
ToggleAutoclickPreferenceController(Context context, String preferenceKey)80     public ToggleAutoclickPreferenceController(Context context, String preferenceKey) {
81         this(context, /* lifecycle= */ null, preferenceKey);
82     }
83 
ToggleAutoclickPreferenceController(Context context, Lifecycle lifecycle, String preferenceKey)84     public ToggleAutoclickPreferenceController(Context context, Lifecycle lifecycle,
85             String preferenceKey) {
86         super(context, preferenceKey);
87 
88         mSharedPreferences = context.getSharedPreferences(context.getPackageName(), MODE_PRIVATE);
89         mContentResolver = context.getContentResolver();
90         mResources = context.getResources();
91 
92         setAutoclickModeToKeyMap();
93 
94         if (lifecycle != null) {
95             lifecycle.addObserver(this);
96         }
97     }
98 
setOnChangeListener(OnChangeListener listener)99     public void setOnChangeListener(OnChangeListener listener) {
100         mOnChangeListener = listener;
101     }
102 
103     @Override
getAvailabilityStatus()104     public int getAvailabilityStatus() {
105         return AVAILABLE;
106     }
107 
108     @Override
displayPreference(PreferenceScreen screen)109     public void displayPreference(PreferenceScreen screen) {
110         super.displayPreference(screen);
111 
112         mDelayModePref = (RadioButtonPreference)
113                 screen.findPreference(getPreferenceKey());
114         mDelayModePref.setOnClickListener(this);
115         mSeekBerPreference = (LayoutPreference) screen.findPreference(KEY_AUTOCLICK_CUSTOM_SEEKBAR);
116         updateState((Preference) mDelayModePref);
117     }
118 
119     @Override
onRadioButtonClicked(RadioButtonPreference preference)120     public void onRadioButtonClicked(RadioButtonPreference preference) {
121         final int value = mAccessibilityAutoclickKeyToValueMap.get(mPreferenceKey);
122         handleRadioButtonPreferenceChange(value);
123         if (mOnChangeListener != null) {
124             mOnChangeListener.onCheckedChanged(mDelayModePref);
125         }
126     }
127 
updatePreferenceCheckedState(int mode)128     private void updatePreferenceCheckedState(int mode) {
129         if (mCurrentUiAutoClickMode == mode) {
130             mDelayModePref.setChecked(true);
131         }
132     }
133 
updatePreferenceVisibleState(int mode)134     private void updatePreferenceVisibleState(int mode) {
135         mSeekBerPreference.setVisible(mCurrentUiAutoClickMode == mode);
136     }
137 
138     @Override
updateState(Preference preference)139     public void updateState(Preference preference) {
140         super.updateState(preference);
141 
142         final boolean enabled = Settings.Secure.getInt(mContext.getContentResolver(),
143                 Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, 0) == 1;
144 
145         mCurrentUiAutoClickMode =
146                 enabled ? getSharedPreferenceForAutoClickMode() : AUTOCLICK_OFF_MODE;
147 
148         // Reset RadioButton.
149         mDelayModePref.setChecked(false);
150         final int mode = mAccessibilityAutoclickKeyToValueMap.get(mDelayModePref.getKey());
151         updatePreferenceCheckedState(mode);
152         updatePreferenceVisibleState(mode);
153     }
154 
155     /** Listener interface handles checked event. */
156     public interface OnChangeListener {
157         /**
158          * A hook that is called when preference checked.
159          */
onCheckedChanged(Preference preference)160         void onCheckedChanged(Preference preference);
161     }
162 
setAutoclickModeToKeyMap()163     private void setAutoclickModeToKeyMap() {
164         final String[] autoclickKeys = mResources.getStringArray(
165                 R.array.accessibility_autoclick_control_selector_keys);
166 
167         final int[] autoclickValues = mResources.getIntArray(
168                 R.array.accessibility_autoclick_selector_values);
169 
170         final int autoclickValueCount = autoclickValues.length;
171         for (int i = 0; i < autoclickValueCount; i++) {
172             mAccessibilityAutoclickKeyToValueMap.put(autoclickKeys[i], autoclickValues[i]);
173         }
174     }
175 
handleRadioButtonPreferenceChange(int preference)176     private void handleRadioButtonPreferenceChange(int preference) {
177         putSecureInt(Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED,
178                 (preference != AUTOCLICK_OFF_MODE) ? /* enabled */ 1 : /* disabled */ 0);
179 
180         mSharedPreferences.edit().putInt(KEY_DELAY_MODE, preference).apply();
181 
182         if (preference != AUTOCLICK_CUSTOM_MODE) {
183             putSecureInt(CONTROL_AUTOCLICK_DELAY_SECURE, preference);
184         }
185     }
186 
putSecureInt(String name, int value)187     private void putSecureInt(String name, int value) {
188         Settings.Secure.putInt(mContentResolver, name, value);
189     }
190 
getSharedPreferenceForAutoClickMode()191     private int getSharedPreferenceForAutoClickMode() {
192         return mSharedPreferences.getInt(KEY_DELAY_MODE, AUTOCLICK_CUSTOM_MODE);
193     }
194 }
195