DebugSettingsFragment.java revision ac88f3d8459e17236654aa38debea749ecb631d1
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.Intent;
21import android.content.SharedPreferences;
22import android.content.res.Resources;
23import android.os.Bundle;
24import android.os.Process;
25import android.preference.Preference;
26import android.preference.Preference.OnPreferenceClickListener;
27import android.preference.PreferenceGroup;
28import android.preference.TwoStatePreference;
29
30import com.android.inputmethod.latin.DictionaryDumpBroadcastReceiver;
31import com.android.inputmethod.latin.DictionaryFacilitator;
32import com.android.inputmethod.latin.R;
33import com.android.inputmethod.latin.debug.ExternalDictionaryGetterForDebug;
34import com.android.inputmethod.latin.utils.ApplicationUtils;
35import com.android.inputmethod.latin.utils.ResourceUtils;
36
37import java.util.Locale;
38
39/**
40 * "Debug mode" settings sub screen.
41 *
42 * This settings sub screen handles a several preference options for debugging.
43 */
44public final class DebugSettingsFragment extends SubScreenFragment
45        implements OnPreferenceClickListener {
46    private static final String PREF_READ_EXTERNAL_DICTIONARY = "read_external_dictionary";
47    private static final String PREF_KEY_DUMP_DICTS = "pref_key_dump_dictionaries";
48    private static final String PREF_KEY_DUMP_DICT_PREFIX = "pref_key_dump_dictionaries";
49
50    private boolean mServiceNeedsRestart = false;
51    private Preference mReadExternalDictionaryPref;
52    private TwoStatePreference mDebugMode;
53
54    @Override
55    public void onCreate(Bundle icicle) {
56        super.onCreate(icicle);
57        addPreferencesFromResource(R.xml.prefs_screen_debug);
58
59        if (!Settings.HAS_UI_TO_ACCEPT_TYPED_WORD) {
60            removePreference(DebugSettings.PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD);
61        }
62
63        mReadExternalDictionaryPref = findPreference(PREF_READ_EXTERNAL_DICTIONARY);
64        if (mReadExternalDictionaryPref != null) {
65            mReadExternalDictionaryPref.setOnPreferenceClickListener(this);
66        }
67
68        final PreferenceGroup dictDumpPreferenceGroup =
69                (PreferenceGroup)findPreference(PREF_KEY_DUMP_DICTS);
70        for (final String dictName : DictionaryFacilitator.DICT_TYPE_TO_CLASS.keySet()) {
71            final Preference pref = new DictDumpPreference(getActivity(), dictName);
72            pref.setOnPreferenceClickListener(this);
73            dictDumpPreferenceGroup.addPreference(pref);
74        }
75        final Resources res = getResources();
76        setupKeyLongpressTimeoutSettings();
77        setupKeyPreviewAnimationDuration(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
78                res.getInteger(R.integer.config_key_preview_show_up_duration));
79        setupKeyPreviewAnimationDuration(DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
80                res.getInteger(R.integer.config_key_preview_dismiss_duration));
81        final float defaultKeyPreviewShowUpStartScale = ResourceUtils.getFloatFromFraction(
82                res, R.fraction.config_key_preview_show_up_start_scale);
83        final float defaultKeyPreviewDismissEndScale = ResourceUtils.getFloatFromFraction(
84                res, R.fraction.config_key_preview_dismiss_end_scale);
85        setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE,
86                defaultKeyPreviewShowUpStartScale);
87        setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE,
88                defaultKeyPreviewShowUpStartScale);
89        setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
90                defaultKeyPreviewDismissEndScale);
91        setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
92                defaultKeyPreviewDismissEndScale);
93
94        mServiceNeedsRestart = false;
95        mDebugMode = (TwoStatePreference) findPreference(DebugSettings.PREF_DEBUG_MODE);
96        updateDebugMode();
97    }
98
99    private static class DictDumpPreference extends Preference {
100        public final String mDictName;
101
102        public DictDumpPreference(final Context context, final String dictName) {
103            super(context);
104            setKey(PREF_KEY_DUMP_DICT_PREFIX + dictName);
105            setTitle("Dump " + dictName + " dictionary");
106            mDictName = dictName;
107        }
108    }
109
110    @Override
111    public boolean onPreferenceClick(final Preference pref) {
112        final Context context = getActivity();
113        if (pref == mReadExternalDictionaryPref) {
114            ExternalDictionaryGetterForDebug.chooseAndInstallDictionary(context);
115            mServiceNeedsRestart = true;
116            return true;
117        }
118        if (pref instanceof DictDumpPreference) {
119            final DictDumpPreference dictDumpPref = (DictDumpPreference)pref;
120            final String dictName = dictDumpPref.mDictName;
121            final Intent intent = new Intent(
122                    DictionaryDumpBroadcastReceiver.DICTIONARY_DUMP_INTENT_ACTION);
123            intent.putExtra(DictionaryDumpBroadcastReceiver.DICTIONARY_NAME_KEY, dictName);
124            context.sendBroadcast(intent);
125            return true;
126        }
127        return true;
128    }
129
130    @Override
131    public void onStop() {
132        super.onStop();
133        if (mServiceNeedsRestart) {
134            Process.killProcess(Process.myPid());
135        }
136    }
137
138    @Override
139    public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
140        if (key.equals(DebugSettings.PREF_DEBUG_MODE) && mDebugMode != null) {
141            mDebugMode.setChecked(prefs.getBoolean(DebugSettings.PREF_DEBUG_MODE, false));
142            updateDebugMode();
143            mServiceNeedsRestart = true;
144            return;
145        }
146        if (key.equals(DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH)
147                || key.equals(DebugSettings.PREF_FORCE_PHYSICAL_KEYBOARD_SPECIAL_KEY)) {
148            mServiceNeedsRestart = true;
149            return;
150        }
151    }
152
153    private void updateDebugMode() {
154        boolean isDebugMode = mDebugMode.isChecked();
155        final String version = getString(
156                R.string.version_text, ApplicationUtils.getVersionName(getActivity()));
157        if (!isDebugMode) {
158            mDebugMode.setTitle(version);
159            mDebugMode.setSummary(null);
160        } else {
161            mDebugMode.setTitle(getString(R.string.prefs_debug_mode));
162            mDebugMode.setSummary(version);
163        }
164    }
165
166    private void setupKeyLongpressTimeoutSettings() {
167        final SharedPreferences prefs = getSharedPreferences();
168        final Resources res = getResources();
169        final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
170                DebugSettings.PREF_KEY_LONGPRESS_TIMEOUT);
171        if (pref == null) {
172            return;
173        }
174        pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
175            @Override
176            public void writeValue(final int value, final String key) {
177                prefs.edit().putInt(key, value).apply();
178            }
179
180            @Override
181            public void writeDefaultValue(final String key) {
182                prefs.edit().remove(key).apply();
183            }
184
185            @Override
186            public int readValue(final String key) {
187                return Settings.readKeyLongpressTimeout(prefs, res);
188            }
189
190            @Override
191            public int readDefaultValue(final String key) {
192                return Settings.readDefaultKeyLongpressTimeout(res);
193            }
194
195            @Override
196            public String getValueText(final int value) {
197                return res.getString(R.string.abbreviation_unit_milliseconds, value);
198            }
199
200            @Override
201            public void feedbackValue(final int value) {}
202        });
203    }
204
205    private void setupKeyPreviewAnimationScale(final String prefKey, final float defaultValue) {
206        final SharedPreferences prefs = getSharedPreferences();
207        final Resources res = getResources();
208        final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(prefKey);
209        if (pref == null) {
210            return;
211        }
212        pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
213            private static final float PERCENTAGE_FLOAT = 100.0f;
214
215            private float getValueFromPercentage(final int percentage) {
216                return percentage / PERCENTAGE_FLOAT;
217            }
218
219            private int getPercentageFromValue(final float floatValue) {
220                return (int)(floatValue * PERCENTAGE_FLOAT);
221            }
222
223            @Override
224            public void writeValue(final int value, final String key) {
225                prefs.edit().putFloat(key, getValueFromPercentage(value)).apply();
226            }
227
228            @Override
229            public void writeDefaultValue(final String key) {
230                prefs.edit().remove(key).apply();
231            }
232
233            @Override
234            public int readValue(final String key) {
235                return getPercentageFromValue(
236                        Settings.readKeyPreviewAnimationScale(prefs, key, defaultValue));
237            }
238
239            @Override
240            public int readDefaultValue(final String key) {
241                return getPercentageFromValue(defaultValue);
242            }
243
244            @Override
245            public String getValueText(final int value) {
246                if (value < 0) {
247                    return res.getString(R.string.settings_system_default);
248                }
249                return String.format(Locale.ROOT, "%d%%", value);
250            }
251
252            @Override
253            public void feedbackValue(final int value) {}
254        });
255    }
256
257    private void setupKeyPreviewAnimationDuration(final String prefKey, final int defaultValue) {
258        final SharedPreferences prefs = getSharedPreferences();
259        final Resources res = getResources();
260        final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(prefKey);
261        if (pref == null) {
262            return;
263        }
264        pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
265            @Override
266            public void writeValue(final int value, final String key) {
267                prefs.edit().putInt(key, value).apply();
268            }
269
270            @Override
271            public void writeDefaultValue(final String key) {
272                prefs.edit().remove(key).apply();
273            }
274
275            @Override
276            public int readValue(final String key) {
277                return Settings.readKeyPreviewAnimationDuration(prefs, key, defaultValue);
278            }
279
280            @Override
281            public int readDefaultValue(final String key) {
282                return defaultValue;
283            }
284
285            @Override
286            public String getValueText(final int value) {
287                return res.getString(R.string.abbreviation_unit_milliseconds, value);
288            }
289
290            @Override
291            public void feedbackValue(final int value) {}
292        });
293    }
294}
295