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