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
17package com.android.settings.accessibility;
18
19import android.content.res.Resources;
20import android.os.Bundle;
21import android.provider.Settings;
22import android.support.v7.preference.Preference;
23import android.view.View;
24import android.view.accessibility.AccessibilityManager;
25import android.widget.Switch;
26
27import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
28import com.android.settings.R;
29import com.android.settings.SeekBarPreference;
30import 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 */
37public 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     */
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     */
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
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
103    public int getMetricsCategory() {
104        return MetricsEvent.ACCESSIBILITY_TOGGLE_AUTOCLICK;
105    }
106
107    @Override
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
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
137    protected void onRemoveSwitchBarToggleSwitch() {
138        super.onRemoveSwitchBarToggleSwitch();
139        mSwitchBar.removeOnSwitchChangeListener(this);
140    }
141
142    @Override
143    public void onSwitchChanged(Switch switchView, boolean isChecked) {
144        onPreferenceToggled(Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, isChecked);
145    }
146
147    @Override
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
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     */
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     */
176    private int delayToSeekBarProgress(int delay) {
177        return (delay - MIN_AUTOCLICK_DELAY) / AUTOCLICK_DELAY_STEP;
178    }
179}
180