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