1/*
2 * Copyright (C) 2014 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.inputmethod.latin.settings;
18
19import android.content.Context;
20import android.content.SharedPreferences;
21import android.content.res.Resources;
22import android.media.AudioManager;
23import android.os.Bundle;
24import android.preference.ListPreference;
25import android.preference.Preference;
26
27import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
28import com.android.inputmethod.latin.R;
29import com.android.inputmethod.latin.SystemBroadcastReceiver;
30import com.android.inputmethod.latin.define.ProductionFlags;
31
32/**
33 * "Advanced" settings sub screen.
34 *
35 * This settings sub screen handles the following advanced preferences.
36 * - Key popup dismiss delay
37 * - Keypress vibration duration
38 * - Keypress sound volume
39 * - Show app icon
40 * - Improve keyboard
41 * - Debug settings
42 */
43public final class AdvancedSettingsFragment extends SubScreenFragment {
44    @Override
45    public void onCreate(final Bundle icicle) {
46        super.onCreate(icicle);
47        addPreferencesFromResource(R.xml.prefs_screen_advanced);
48
49        final Resources res = getResources();
50        final Context context = getActivity();
51
52        // When we are called from the Settings application but we are not already running, some
53        // singleton and utility classes may not have been initialized.  We have to call
54        // initialization method of these classes here. See {@link LatinIME#onCreate()}.
55        AudioAndHapticFeedbackManager.init(context);
56
57        final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
58
59        if (!Settings.isInternal(prefs)) {
60            removePreference(Settings.SCREEN_DEBUG);
61        }
62
63        if (!AudioAndHapticFeedbackManager.getInstance().hasVibrator()) {
64            removePreference(Settings.PREF_VIBRATION_DURATION_SETTINGS);
65        }
66
67        // TODO: consolidate key preview dismiss delay with the key preview animation parameters.
68        if (!Settings.readFromBuildConfigIfToShowKeyPreviewPopupOption(res)) {
69            removePreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
70        } else {
71            // TODO: Cleanup this setup.
72            final ListPreference keyPreviewPopupDismissDelay =
73                    (ListPreference) findPreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
74            final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger(
75                    R.integer.config_key_preview_linger_timeout));
76            keyPreviewPopupDismissDelay.setEntries(new String[] {
77                    res.getString(R.string.key_preview_popup_dismiss_no_delay),
78                    res.getString(R.string.key_preview_popup_dismiss_default_delay),
79            });
80            keyPreviewPopupDismissDelay.setEntryValues(new String[] {
81                    "0",
82                    popupDismissDelayDefaultValue
83            });
84            if (null == keyPreviewPopupDismissDelay.getValue()) {
85                keyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue);
86            }
87            keyPreviewPopupDismissDelay.setEnabled(
88                    Settings.readKeyPreviewPopupEnabled(prefs, res));
89        }
90
91        setupKeypressVibrationDurationSettings();
92        setupKeypressSoundVolumeSettings();
93        setupKeyLongpressTimeoutSettings();
94        refreshEnablingsOfKeypressSoundAndVibrationSettings();
95    }
96
97    @Override
98    public void onResume() {
99        super.onResume();
100        final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
101        updateListPreferenceSummaryToCurrentValue(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
102    }
103
104    @Override
105    public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
106        final Resources res = getResources();
107        if (key.equals(Settings.PREF_POPUP_ON)) {
108            setPreferenceEnabled(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
109                    Settings.readKeyPreviewPopupEnabled(prefs, res));
110        } else if (key.equals(Settings.PREF_SHOW_SETUP_WIZARD_ICON)) {
111            SystemBroadcastReceiver.toggleAppIcon(getActivity());
112        }
113        updateListPreferenceSummaryToCurrentValue(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
114        refreshEnablingsOfKeypressSoundAndVibrationSettings();
115    }
116
117    private void refreshEnablingsOfKeypressSoundAndVibrationSettings() {
118        final SharedPreferences prefs = getSharedPreferences();
119        final Resources res = getResources();
120        setPreferenceEnabled(Settings.PREF_VIBRATION_DURATION_SETTINGS,
121                Settings.readVibrationEnabled(prefs, res));
122        setPreferenceEnabled(Settings.PREF_KEYPRESS_SOUND_VOLUME,
123                Settings.readKeypressSoundEnabled(prefs, res));
124    }
125
126    private void setupKeypressVibrationDurationSettings() {
127        final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
128                Settings.PREF_VIBRATION_DURATION_SETTINGS);
129        if (pref == null) {
130            return;
131        }
132        final SharedPreferences prefs = getSharedPreferences();
133        final Resources res = getResources();
134        pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
135            @Override
136            public void writeValue(final int value, final String key) {
137                prefs.edit().putInt(key, value).apply();
138            }
139
140            @Override
141            public void writeDefaultValue(final String key) {
142                prefs.edit().remove(key).apply();
143            }
144
145            @Override
146            public int readValue(final String key) {
147                return Settings.readKeypressVibrationDuration(prefs, res);
148            }
149
150            @Override
151            public int readDefaultValue(final String key) {
152                return Settings.readDefaultKeypressVibrationDuration(res);
153            }
154
155            @Override
156            public void feedbackValue(final int value) {
157                AudioAndHapticFeedbackManager.getInstance().vibrate(value);
158            }
159
160            @Override
161            public String getValueText(final int value) {
162                if (value < 0) {
163                    return res.getString(R.string.settings_system_default);
164                }
165                return res.getString(R.string.abbreviation_unit_milliseconds, value);
166            }
167        });
168    }
169
170    private void setupKeypressSoundVolumeSettings() {
171        final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
172                Settings.PREF_KEYPRESS_SOUND_VOLUME);
173        if (pref == null) {
174            return;
175        }
176        final SharedPreferences prefs = getSharedPreferences();
177        final Resources res = getResources();
178        final AudioManager am = (AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE);
179        pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
180            private static final float PERCENTAGE_FLOAT = 100.0f;
181
182            private float getValueFromPercentage(final int percentage) {
183                return percentage / PERCENTAGE_FLOAT;
184            }
185
186            private int getPercentageFromValue(final float floatValue) {
187                return (int)(floatValue * PERCENTAGE_FLOAT);
188            }
189
190            @Override
191            public void writeValue(final int value, final String key) {
192                prefs.edit().putFloat(key, getValueFromPercentage(value)).apply();
193            }
194
195            @Override
196            public void writeDefaultValue(final String key) {
197                prefs.edit().remove(key).apply();
198            }
199
200            @Override
201            public int readValue(final String key) {
202                return getPercentageFromValue(Settings.readKeypressSoundVolume(prefs, res));
203            }
204
205            @Override
206            public int readDefaultValue(final String key) {
207                return getPercentageFromValue(Settings.readDefaultKeypressSoundVolume(res));
208            }
209
210            @Override
211            public String getValueText(final int value) {
212                if (value < 0) {
213                    return res.getString(R.string.settings_system_default);
214                }
215                return Integer.toString(value);
216            }
217
218            @Override
219            public void feedbackValue(final int value) {
220                am.playSoundEffect(
221                        AudioManager.FX_KEYPRESS_STANDARD, getValueFromPercentage(value));
222            }
223        });
224    }
225
226    private void setupKeyLongpressTimeoutSettings() {
227        final SharedPreferences prefs = getSharedPreferences();
228        final Resources res = getResources();
229        final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
230                Settings.PREF_KEY_LONGPRESS_TIMEOUT);
231        if (pref == null) {
232            return;
233        }
234        pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
235            @Override
236            public void writeValue(final int value, final String key) {
237                prefs.edit().putInt(key, value).apply();
238            }
239
240            @Override
241            public void writeDefaultValue(final String key) {
242                prefs.edit().remove(key).apply();
243            }
244
245            @Override
246            public int readValue(final String key) {
247                return Settings.readKeyLongpressTimeout(prefs, res);
248            }
249
250            @Override
251            public int readDefaultValue(final String key) {
252                return Settings.readDefaultKeyLongpressTimeout(res);
253            }
254
255            @Override
256            public String getValueText(final int value) {
257                return res.getString(R.string.abbreviation_unit_milliseconds, value);
258            }
259
260            @Override
261            public void feedbackValue(final int value) {}
262        });
263    }
264}
265