1 /*
2  * Copyright (C) 2015 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.res.Resources;
20 import android.os.Bundle;
21 import android.provider.Settings;
22 import android.support.v7.preference.Preference;
23 import android.view.View;
24 import android.view.accessibility.AccessibilityManager;
25 import android.widget.Switch;
26 
27 import com.android.internal.logging.MetricsProto.MetricsEvent;
28 import com.android.settings.R;
29 import com.android.settings.SeekBarPreference;
30 import com.android.settings.widget.SwitchBar;
31 
32 
33 /**
34  * Fragment for preference screen for settings related to Automatically click after mouse stops
35  * feature.
36  */
37 public class ToggleAutoclickPreferenceFragment extends ToggleFeaturePreferenceFragment
38         implements SwitchBar.OnSwitchChangeListener, Preference.OnPreferenceChangeListener {
39 
40     /** Min allowed autoclick delay value. */
41     private static final int MIN_AUTOCLICK_DELAY = 200;
42     /** Max allowed autoclick delay value. */
43     private static final int MAX_AUTOCLICK_DELAY = 1000;
44     /**
45      * Allowed autoclick delay values are discrete. This is the difference between two allowed
46      * values.
47      */
48     private static final int AUTOCLICK_DELAY_STEP = 100;
49 
50     /**
51      * Resource ids from which autoclick preference summaries should be derived. The strings have
52      * placeholder for integer delay value.
53      */
54     private static final int[] mAutoclickPreferenceSummaries = {
55             R.plurals.accessibilty_autoclick_preference_subtitle_extremely_short_delay,
56             R.plurals.accessibilty_autoclick_preference_subtitle_very_short_delay,
57             R.plurals.accessibilty_autoclick_preference_subtitle_short_delay,
58             R.plurals.accessibilty_autoclick_preference_subtitle_long_delay,
59             R.plurals.accessibilty_autoclick_preference_subtitle_very_long_delay
60     };
61 
62     /**
63      * Seek bar preference for autoclick delay value. The seek bar has values between 0 and
64      * number of possible discrete autoclick delay values. These will have to be converted to actual
65      * delay values before saving them in settings.
66      */
67     private SeekBarPreference mDelay;
68 
69     /**
70      * Gets string that should be used as a autoclick preference summary for provided autoclick
71      * delay.
72      * @param resources Resources from which string should be retrieved.
73      * @param delay Delay for whose value summary should be retrieved.
74      */
getAutoclickPreferenceSummary(Resources resources, int delay)75     static CharSequence getAutoclickPreferenceSummary(Resources resources, int delay) {
76         int summaryIndex = getAutoclickPreferenceSummaryIndex(delay);
77         return resources.getQuantityString(
78                 mAutoclickPreferenceSummaries[summaryIndex], delay, delay);
79     }
80 
81     /**
82      * Finds index of the summary that should be used for the provided autoclick delay.
83      */
getAutoclickPreferenceSummaryIndex(int delay)84     private static int getAutoclickPreferenceSummaryIndex(int delay) {
85         if (delay <= MIN_AUTOCLICK_DELAY) {
86             return 0;
87         }
88         if (delay >= MAX_AUTOCLICK_DELAY) {
89             return mAutoclickPreferenceSummaries.length - 1;
90         }
91         int rangeSize = (MAX_AUTOCLICK_DELAY - MIN_AUTOCLICK_DELAY) /
92                 (mAutoclickPreferenceSummaries.length - 1);
93         return (delay - MIN_AUTOCLICK_DELAY) / rangeSize;
94     }
95 
96     @Override
onPreferenceToggled(String preferenceKey, boolean enabled)97     protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
98         Settings.Secure.putInt(getContentResolver(), preferenceKey, enabled ? 1 : 0);
99         mDelay.setEnabled(enabled);
100     }
101 
102     @Override
getMetricsCategory()103     protected int getMetricsCategory() {
104         return MetricsEvent.ACCESSIBILITY_TOGGLE_AUTOCLICK;
105     }
106 
107     @Override
onCreate(Bundle savedInstanceState)108     public void onCreate(Bundle savedInstanceState) {
109         super.onCreate(savedInstanceState);
110 
111         addPreferencesFromResource(R.xml.accessibility_autoclick_settings);
112 
113         int delay = Settings.Secure.getInt(
114                 getContentResolver(), Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
115                 AccessibilityManager.AUTOCLICK_DELAY_DEFAULT);
116 
117         // Initialize seek bar preference. Sets seek bar size to the number of possible delay
118         // values.
119         mDelay = (SeekBarPreference) findPreference("autoclick_delay");
120         mDelay.setMax(delayToSeekBarProgress(MAX_AUTOCLICK_DELAY));
121         mDelay.setProgress(delayToSeekBarProgress(delay));
122         mDelay.setOnPreferenceChangeListener(this);
123     }
124 
125     @Override
onInstallSwitchBarToggleSwitch()126     protected void onInstallSwitchBarToggleSwitch() {
127         super.onInstallSwitchBarToggleSwitch();
128 
129         int value = Settings.Secure.getInt(getContentResolver(),
130                 Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, 0);
131         mSwitchBar.setCheckedInternal(value == 1);
132         mSwitchBar.addOnSwitchChangeListener(this);
133         mDelay.setEnabled(value == 1);
134     }
135 
136     @Override
onRemoveSwitchBarToggleSwitch()137     protected void onRemoveSwitchBarToggleSwitch() {
138         super.onRemoveSwitchBarToggleSwitch();
139         mSwitchBar.removeOnSwitchChangeListener(this);
140     }
141 
142     @Override
onSwitchChanged(Switch switchView, boolean isChecked)143     public void onSwitchChanged(Switch switchView, boolean isChecked) {
144         onPreferenceToggled(Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, isChecked);
145     }
146 
147     @Override
onViewCreated(View view, Bundle savedInstanceState)148     public void onViewCreated(View view, Bundle savedInstanceState) {
149         super.onViewCreated(view, savedInstanceState);
150 
151         setTitle(getString(R.string.accessibility_autoclick_preference_title));
152     }
153 
154     @Override
onPreferenceChange(Preference preference, Object newValue)155     public boolean onPreferenceChange(Preference preference, Object newValue) {
156         if (preference == mDelay && newValue instanceof Integer) {
157             Settings.Secure.putInt(getContentResolver(),
158                    Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
159                    seekBarProgressToDelay((int)newValue));
160             return true;
161          }
162          return false;
163     }
164 
165     /**
166      * Converts seek bar preference progress value to autoclick delay associated with it.
167      */
seekBarProgressToDelay(int progress)168     private int seekBarProgressToDelay(int progress) {
169         return progress * AUTOCLICK_DELAY_STEP + MIN_AUTOCLICK_DELAY;
170     }
171 
172     /**
173      * Converts autoclick delay value to seek bar preference progress values that represents said
174      * delay.
175      */
delayToSeekBarProgress(int delay)176     private int delayToSeekBarProgress(int delay) {
177         return (delay - MIN_AUTOCLICK_DELAY) / AUTOCLICK_DELAY_STEP;
178     }
179 }
180