blob: 803b3bdffbc92596bb253d7e4e718c84bba84ffd [file] [log] [blame]
The Android Open Source Project923bf412009-03-13 15:11:42 -07001/*
Tadashi G. Takaokacbee8a32013-01-08 15:41:46 +09002 * Copyright (C) 2013 The Android Open Source Project
Jean Chalard89764ad2011-01-19 17:44:39 +09003 *
Tadashi G. Takaoka8aa99632013-01-21 21:52:57 +09004 * 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
Doug Zongkera16ff1b2010-01-28 10:09:44 -08007 *
Tadashi G. Takaoka8aa99632013-01-21 21:52:57 +09008 * http://www.apache.org/licenses/LICENSE-2.0
Doug Zongkera16ff1b2010-01-28 10:09:44 -08009 *
The Android Open Source Project923bf412009-03-13 15:11:42 -070010 * Unless required by applicable law or agreed to in writing, software
Tadashi G. Takaoka8aa99632013-01-21 21:52:57 +090011 * 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.
The Android Open Source Project923bf412009-03-13 15:11:42 -070015 */
16
Ken Wakasaa7d2fc62013-07-22 12:43:37 +090017package com.android.inputmethod.latin.settings;
The Android Open Source Project923bf412009-03-13 15:11:42 -070018
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +090019import android.content.Context;
20import android.content.SharedPreferences;
Chieu Nguyena2376cd2015-04-22 14:41:45 -070021import android.content.pm.ApplicationInfo;
Jean Chalard6bb6d302014-09-03 19:36:35 +090022import android.content.res.Configuration;
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +090023import android.content.res.Resources;
Tadashi G. Takaoka7ed40a12014-05-24 00:41:11 +090024import android.os.Build;
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +090025import android.preference.PreferenceManager;
Satoshi Kataoka6f9c6f22013-06-06 10:57:47 +090026import android.util.Log;
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +090027
Tadashi G. Takaoka78cff102014-08-12 23:13:18 +090028import com.android.inputmethod.compat.BuildCompatUtils;
Ken Wakasaa7d2fc62013-07-22 12:43:37 +090029import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
Ken Wakasaa7d2fc62013-07-22 12:43:37 +090030import com.android.inputmethod.latin.InputAttributes;
31import com.android.inputmethod.latin.R;
Jean Chalard4beeb922014-10-28 21:31:09 +090032import com.android.inputmethod.latin.common.StringUtils;
Tadashi G. Takaokaa410cb42013-07-24 10:37:07 +090033import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
Steve Kondik0b495922013-12-06 19:21:08 +010034import com.android.inputmethod.latin.utils.JniUtils;
Ken Wakasae28eba52013-06-24 01:11:32 +090035import com.android.inputmethod.latin.utils.ResourceUtils;
Tadashi G. Takaoka0c3a9b52013-07-24 15:58:11 +090036import com.android.inputmethod.latin.utils.RunInLocale;
Jatin Matanicc7e44e2014-09-30 17:09:00 -070037import com.android.inputmethod.latin.utils.StatsUtils;
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +090038
Keisuke Kuroyanagieb28bac2014-01-10 20:28:30 +090039import java.util.Collections;
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +090040import java.util.Locale;
Keisuke Kuroyanagieb28bac2014-01-10 20:28:30 +090041import java.util.Set;
Jean Chalard10d66662013-08-02 20:22:00 +090042import java.util.concurrent.locks.ReentrantLock;
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +090043
Tadashi G. Takaokad3a4c512014-10-22 14:04:07 +090044import javax.annotation.Nonnull;
45
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +090046public final class Settings implements SharedPreferences.OnSharedPreferenceChangeListener {
Satoshi Kataoka6f9c6f22013-06-06 10:57:47 +090047 private static final String TAG = Settings.class.getSimpleName();
Tadashi G. Takaoka058c6c62014-06-19 17:47:11 -070048 // Settings screens
Sandeep Siddharthaa4e0b6e2014-09-16 14:56:34 -070049 public static final String SCREEN_ACCOUNTS = "screen_accounts";
Tadashi G. Takaokaa715d7f2014-07-29 15:33:40 +090050 public static final String SCREEN_THEME = "screen_theme";
Tadashi G. Takaoka058c6c62014-06-19 17:47:11 -070051 public static final String SCREEN_DEBUG = "screen_debug";
Steve Kondik0b495922013-12-06 19:21:08 +010052 public static final String SCREEN_GESTURE = "screen_gesture";
Jean Chalard837b1092011-12-09 16:41:05 +090053 // In the same order as xml/prefs.xml
Jean Chalard837b1092011-12-09 16:41:05 +090054 public static final String PREF_AUTO_CAP = "auto_cap";
Tadashi G. Takaoka9502cc12010-12-09 21:06:26 +090055 public static final String PREF_VIBRATE_ON = "vibrate_on";
56 public static final String PREF_SOUND_ON = "sound_on";
Jean Chalardba93dda2011-12-09 17:58:51 +090057 public static final String PREF_POPUP_ON = "popup_on";
Satoshi Kataoka21a89c12013-09-05 15:46:04 +090058 // PREF_VOICE_MODE_OBSOLETE is obsolete. Use PREF_VOICE_INPUT_KEY instead.
59 public static final String PREF_VOICE_MODE_OBSOLETE = "voice_mode";
60 public static final String PREF_VOICE_INPUT_KEY = "pref_voice_input_key";
Dan Zivkovic764a18c2015-06-16 18:26:02 -070061 public static final String PREF_EDIT_PERSONAL_DICTIONARY = "edit_personal_dictionary";
Jean Chalard837b1092011-12-09 16:41:05 +090062 public static final String PREF_CONFIGURE_DICTIONARIES_KEY = "configure_dictionaries_key";
Chieu Nguyen116e58c2015-03-12 19:39:06 -070063 // PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE is obsolete. Use PREF_AUTO_CORRECTION instead.
64 public static final String PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE =
65 "auto_correction_threshold";
66 public static final String PREF_AUTO_CORRECTION = "pref_key_auto_correction";
Tadashi G. Takaokaab661e32014-07-22 10:18:38 -070067 // PREF_SHOW_SUGGESTIONS_SETTING_OBSOLETE is obsolete. Use PREF_SHOW_SUGGESTIONS instead.
68 public static final String PREF_SHOW_SUGGESTIONS_SETTING_OBSOLETE = "show_suggestions_setting";
69 public static final String PREF_SHOW_SUGGESTIONS = "show_suggestions";
Tadashi G. Takaoka47e2bf32012-07-27 15:32:29 +090070 public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
Tadashi G. Takaokac2ba73a2014-02-20 06:02:26 +000071 public static final String PREF_KEY_USE_PERSONALIZED_DICTS = "pref_key_use_personalized_dicts";
Ken Wakasa139bd83f2012-12-04 15:24:55 +090072 public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD =
73 "pref_key_use_double_space_period";
Jean Chalardbb612932013-04-23 12:19:31 +090074 public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE =
75 "pref_key_block_potentially_offensive";
Tadashi G. Takaoka7ed40a12014-05-24 00:41:11 +090076 public static final boolean ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS =
Tadashi G. Takaoka78cff102014-08-12 23:13:18 +090077 BuildCompatUtils.EFFECTIVE_SDK_INT <= Build.VERSION_CODES.KITKAT;
Tadashi G. Takaoka6fb586a2014-10-06 17:20:10 +090078 public static final boolean SHOULD_SHOW_LXX_SUGGESTION_UI =
Yohei Yukawa66d30a42014-10-22 00:07:23 +090079 BuildCompatUtils.EFFECTIVE_SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
Tadashi G. Takaoka1a4aa7e2012-09-20 10:32:56 +090080 public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY =
81 "pref_show_language_switch_key";
Tadashi G. Takaoka81d4e3c2012-02-17 17:46:01 -080082 public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
83 "pref_include_other_imes_in_language_switch_list";
Tadashi G. Takaokaf5a0bd22012-04-18 22:13:29 +090084 public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
Jatin Matania5d4cb72014-09-10 10:25:43 +090085 public static final String PREF_ENABLE_SPLIT_KEYBOARD = "pref_split_keyboard";
Tadashi G. Takaokac9072dc2014-02-17 12:10:09 +090086 // TODO: consolidate key preview dismiss delay with the key preview animation parameters.
Jean Chalard240297d2011-05-11 20:51:07 +090087 public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
88 "pref_key_preview_popup_dismiss_delay";
Dan Zivkovic54551792015-03-13 14:50:54 -070089 public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction";
Tadashi G. Takaoka62b8ddd2012-07-20 17:49:06 +090090 public static final String PREF_GESTURE_INPUT = "gesture_input";
Jean Chalardba93dda2011-12-09 17:58:51 +090091 public static final String PREF_VIBRATION_DURATION_SETTINGS =
satok43396572011-09-28 20:11:05 +090092 "pref_vibration_duration_settings";
Tadashi G. Takaokaad2f6952014-10-17 16:07:50 +090093 public static final String PREF_KEYPRESS_SOUND_VOLUME = "pref_keypress_sound_volume";
94 public static final String PREF_KEY_LONGPRESS_TIMEOUT = "pref_key_longpress_timeout";
Tadashi G. Takaokaf7e01e82014-10-27 11:59:57 +090095 public static final String PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY =
96 "pref_enable_emoji_alt_physical_key";
Tadashi G. Takaoka47e2bf32012-07-27 15:32:29 +090097 public static final String PREF_GESTURE_PREVIEW_TRAIL = "pref_gesture_preview_trail";
Tadashi G. Takaoka15281ad2012-10-02 10:30:03 +090098 public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT =
99 "pref_gesture_floating_preview_text";
Chieu Nguyena2376cd2015-04-22 14:41:45 -0700100 public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon";
Jean Chalard837b1092011-12-09 16:41:05 +0900101
Satoshi Kataoka756791e2013-03-13 13:08:34 +0900102 public static final String PREF_KEY_IS_INTERNAL = "pref_key_is_internal";
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +0900103
Yohei Yukawa9aa7f662014-05-14 14:26:29 +0900104 public static final String PREF_ENABLE_METRICS_LOGGING = "pref_enable_metrics_logging";
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900105 // This preference key is deprecated. Use {@link #PREF_SHOW_LANGUAGE_SWITCH_KEY} instead.
106 // This is being used only for the backward compatibility.
107 private static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY =
108 "pref_suppress_language_switch_key";
109
Satoshi Kataoka283cf9c2013-08-16 14:35:56 +0900110 private static final String PREF_LAST_USED_PERSONALIZATION_TOKEN =
111 "pref_last_used_personalization_token";
Keisuke Kuroyanagiba07df72014-01-10 16:30:59 +0900112 private static final String PREF_LAST_PERSONALIZATION_DICT_WIPED_TIME =
113 "pref_last_used_personalization_dict_wiped_time";
Keisuke Kuroyanagieb28bac2014-01-10 20:28:30 +0900114 private static final String PREF_CORPUS_HANDLES_FOR_PERSONALIZATION =
115 "pref_corpus_handles_for_personalization";
Satoshi Kataokaa462cd82013-03-19 16:49:19 +0900116
Satoshi Kataokaf3f00002013-09-16 17:13:41 +0900117 // Emoji
118 public static final String PREF_EMOJI_RECENT_KEYS = "emoji_recent_keys";
119 public static final String PREF_EMOJI_CATEGORY_LAST_TYPED_ID = "emoji_category_last_typed_id";
Satoshi Kataoka6dc99dc2013-10-11 14:54:26 +0900120 public static final String PREF_LAST_SHOWN_EMOJI_CATEGORY_ID = "last_shown_emoji_category_id";
Satoshi Kataokaf3f00002013-09-16 17:13:41 +0900121
Tadashi G. Takaoka276b1a22014-02-07 15:25:50 +0900122 private static final float UNDEFINED_PREFERENCE_VALUE_FLOAT = -1.0f;
123 private static final int UNDEFINED_PREFERENCE_VALUE_INT = -1;
124
Jean Chalard1404c1a2013-12-20 15:00:44 +0900125 private Context mContext;
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +0900126 private Resources mRes;
127 private SharedPreferences mPrefs;
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +0900128 private SettingsValues mSettingsValues;
Jean Chalard10d66662013-08-02 20:22:00 +0900129 private final ReentrantLock mSettingsValuesLock = new ReentrantLock();
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +0900130
131 private static final Settings sInstance = new Settings();
132
133 public static Settings getInstance() {
134 return sInstance;
135 }
136
137 public static void init(final Context context) {
138 sInstance.onCreate(context);
139 }
140
141 private Settings() {
142 // Intentional empty constructor for singleton.
143 }
144
145 private void onCreate(final Context context) {
Jean Chalard1404c1a2013-12-20 15:00:44 +0900146 mContext = context;
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +0900147 mRes = context.getResources();
148 mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
149 mPrefs.registerOnSharedPreferenceChangeListener(this);
Chieu Nguyen116e58c2015-03-12 19:39:06 -0700150 upgradeAutocorrectionSettings(mPrefs, mRes);
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +0900151 }
152
153 public void onDestroy() {
154 mPrefs.unregisterOnSharedPreferenceChangeListener(this);
155 }
156
157 @Override
158 public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
Jean Chalard10d66662013-08-02 20:22:00 +0900159 mSettingsValuesLock.lock();
160 try {
161 if (mSettingsValues == null) {
162 // TODO: Introduce a static function to register this class and ensure that
163 // loadSettings must be called before "onSharedPreferenceChanged" is called.
164 Log.w(TAG, "onSharedPreferenceChanged called before loadSettings.");
165 return;
166 }
Jean Chalard1404c1a2013-12-20 15:00:44 +0900167 loadSettings(mContext, mSettingsValues.mLocale, mSettingsValues.mInputAttributes);
Jatin Matanicc7e44e2014-09-30 17:09:00 -0700168 StatsUtils.onLoadSettings(mSettingsValues);
Jean Chalard10d66662013-08-02 20:22:00 +0900169 } finally {
170 mSettingsValuesLock.unlock();
Satoshi Kataoka6f9c6f22013-06-06 10:57:47 +0900171 }
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +0900172 }
173
Jean Chalard1404c1a2013-12-20 15:00:44 +0900174 public void loadSettings(final Context context, final Locale locale,
Tadashi G. Takaokad3a4c512014-10-22 14:04:07 +0900175 @Nonnull final InputAttributes inputAttributes) {
Jean Chalard10d66662013-08-02 20:22:00 +0900176 mSettingsValuesLock.lock();
Jean Chalard1404c1a2013-12-20 15:00:44 +0900177 mContext = context;
Jean Chalard10d66662013-08-02 20:22:00 +0900178 try {
179 final SharedPreferences prefs = mPrefs;
180 final RunInLocale<SettingsValues> job = new RunInLocale<SettingsValues>() {
181 @Override
182 protected SettingsValues job(final Resources res) {
Tadashi G. Takaoka860c3b82014-01-09 16:59:23 +0900183 return new SettingsValues(context, prefs, res, inputAttributes);
Jean Chalard10d66662013-08-02 20:22:00 +0900184 }
185 };
186 mSettingsValues = job.runInLocale(mRes, locale);
187 } finally {
188 mSettingsValuesLock.unlock();
189 }
Tadashi G. Takaokaff0735a2013-01-08 16:35:21 +0900190 }
191
192 // TODO: Remove this method and add proxy method to SettingsValues.
193 public SettingsValues getCurrent() {
194 return mSettingsValues;
195 }
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900196
Satoshi Kataoka756791e2013-03-13 13:08:34 +0900197 public boolean isInternal() {
198 return mSettingsValues.mIsInternal;
199 }
200
Tadashi G. Takaoka395009c2014-10-28 14:40:06 +0900201 public static int readScreenMetrics(final Resources res) {
202 return res.getInteger(R.integer.config_screen_metrics);
203 }
204
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900205 // Accessed from the settings interface, hence public
Tadashi G. Takaokace875662013-01-22 13:29:30 +0900206 public static boolean readKeypressSoundEnabled(final SharedPreferences prefs,
207 final Resources res) {
Tadashi G. Takaokaa3920c72014-04-25 11:49:33 -0700208 return prefs.getBoolean(PREF_SOUND_ON,
Tadashi G. Takaokace875662013-01-22 13:29:30 +0900209 res.getBoolean(R.bool.config_default_sound_enabled));
210 }
211
212 public static boolean readVibrationEnabled(final SharedPreferences prefs,
213 final Resources res) {
214 final boolean hasVibrator = AudioAndHapticFeedbackManager.getInstance().hasVibrator();
215 return hasVibrator && prefs.getBoolean(PREF_VIBRATE_ON,
216 res.getBoolean(R.bool.config_default_vibration_enabled));
217 }
218
Chieu Nguyen116e58c2015-03-12 19:39:06 -0700219 public static boolean readAutoCorrectEnabled(final SharedPreferences prefs,
Tadashi G. Takaokace875662013-01-22 13:29:30 +0900220 final Resources res) {
Chieu Nguyen116e58c2015-03-12 19:39:06 -0700221 return prefs.getBoolean(PREF_AUTO_CORRECTION, true);
Tadashi G. Takaokace875662013-01-22 13:29:30 +0900222 }
223
Jean Chalard56577462014-11-21 22:49:50 +0900224 public static float readPlausibilityThreshold(final Resources res) {
225 return Float.parseFloat(res.getString(R.string.plausibility_threshold));
226 }
227
Jean Chalardbb612932013-04-23 12:19:31 +0900228 public static boolean readBlockPotentiallyOffensive(final SharedPreferences prefs,
229 final Resources res) {
Tadashi G. Takaokaa3920c72014-04-25 11:49:33 -0700230 return prefs.getBoolean(PREF_BLOCK_POTENTIALLY_OFFENSIVE,
Jean Chalardbb612932013-04-23 12:19:31 +0900231 res.getBoolean(R.bool.config_block_potentially_offensive));
232 }
233
Tadashi G. Takaokace875662013-01-22 13:29:30 +0900234 public static boolean readFromBuildConfigIfGestureInputEnabled(final Resources res) {
Steve Kondik0b495922013-12-06 19:21:08 +0100235 if (!JniUtils.sHaveGestureLib) {
236 return false;
237 }
Tadashi G. Takaokace875662013-01-22 13:29:30 +0900238 return res.getBoolean(R.bool.config_gesture_input_enabled_by_build_config);
239 }
240
241 public static boolean readGestureInputEnabled(final SharedPreferences prefs,
242 final Resources res) {
243 return readFromBuildConfigIfGestureInputEnabled(res)
Tadashi G. Takaokaa3920c72014-04-25 11:49:33 -0700244 && prefs.getBoolean(PREF_GESTURE_INPUT, true);
Tadashi G. Takaokace875662013-01-22 13:29:30 +0900245 }
246
Ken Wakasa2fa36932013-12-13 17:09:16 +0900247 public static boolean readFromBuildConfigIfToShowKeyPreviewPopupOption(final Resources res) {
248 return res.getBoolean(R.bool.config_enable_show_key_preview_popup_option);
Tadashi G. Takaokace875662013-01-22 13:29:30 +0900249 }
250
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900251 public static boolean readKeyPreviewPopupEnabled(final SharedPreferences prefs,
252 final Resources res) {
Tadashi G. Takaokace875662013-01-22 13:29:30 +0900253 final boolean defaultKeyPreviewPopup = res.getBoolean(
254 R.bool.config_default_key_preview_popup);
Ken Wakasa2fa36932013-12-13 17:09:16 +0900255 if (!readFromBuildConfigIfToShowKeyPreviewPopupOption(res)) {
Tadashi G. Takaokace875662013-01-22 13:29:30 +0900256 return defaultKeyPreviewPopup;
257 }
258 return prefs.getBoolean(PREF_POPUP_ON, defaultKeyPreviewPopup);
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900259 }
260
261 public static int readKeyPreviewPopupDismissDelay(final SharedPreferences prefs,
262 final Resources res) {
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900263 return Integer.parseInt(prefs.getString(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
264 Integer.toString(res.getInteger(
265 R.integer.config_key_preview_linger_timeout))));
266 }
267
268 public static boolean readShowsLanguageSwitchKey(final SharedPreferences prefs) {
269 if (prefs.contains(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY)) {
270 final boolean suppressLanguageSwitchKey = prefs.getBoolean(
271 PREF_SUPPRESS_LANGUAGE_SWITCH_KEY, false);
272 final SharedPreferences.Editor editor = prefs.edit();
273 editor.remove(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY);
274 editor.putBoolean(PREF_SHOW_LANGUAGE_SWITCH_KEY, !suppressLanguageSwitchKey);
275 editor.apply();
276 }
277 return prefs.getBoolean(PREF_SHOW_LANGUAGE_SWITCH_KEY, true);
278 }
279
280 public static String readPrefAdditionalSubtypes(final SharedPreferences prefs,
281 final Resources res) {
Tadashi G. Takaokaa410cb42013-07-24 10:37:07 +0900282 final String predefinedPrefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes(
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900283 res.getStringArray(R.array.predefined_subtypes));
284 return prefs.getString(PREF_CUSTOM_INPUT_STYLES, predefinedPrefSubtypes);
285 }
286
287 public static void writePrefAdditionalSubtypes(final SharedPreferences prefs,
288 final String prefSubtypes) {
Tadashi G. Takaokaa3920c72014-04-25 11:49:33 -0700289 prefs.edit().putString(PREF_CUSTOM_INPUT_STYLES, prefSubtypes).apply();
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900290 }
291
292 public static float readKeypressSoundVolume(final SharedPreferences prefs,
293 final Resources res) {
Tadashi G. Takaoka276b1a22014-02-07 15:25:50 +0900294 final float volume = prefs.getFloat(
295 PREF_KEYPRESS_SOUND_VOLUME, UNDEFINED_PREFERENCE_VALUE_FLOAT);
296 return (volume != UNDEFINED_PREFERENCE_VALUE_FLOAT) ? volume
297 : readDefaultKeypressSoundVolume(res);
Tadashi G. Takaokaa7a7f4e2013-01-10 12:06:00 +0900298 }
299
Tadashi G. Takaokabd9887a2014-02-10 12:54:45 +0900300 // Default keypress sound volume for unknown devices.
301 // The negative value means system default.
302 private static final String DEFAULT_KEYPRESS_SOUND_VOLUME = Float.toString(-1.0f);
303
Tadashi G. Takaokaa7a7f4e2013-01-10 12:06:00 +0900304 public static float readDefaultKeypressSoundVolume(final Resources res) {
Tadashi G. Takaokabd9887a2014-02-10 12:54:45 +0900305 return Float.parseFloat(ResourceUtils.getDeviceOverrideValue(res,
306 R.array.keypress_volumes, DEFAULT_KEYPRESS_SOUND_VOLUME));
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900307 }
308
Tadashi G. Takaokacc5e4a42013-01-18 12:19:59 +0900309 public static int readKeyLongpressTimeout(final SharedPreferences prefs,
310 final Resources res) {
Tadashi G. Takaoka276b1a22014-02-07 15:25:50 +0900311 final int milliseconds = prefs.getInt(
Tadashi G. Takaokaad2f6952014-10-17 16:07:50 +0900312 PREF_KEY_LONGPRESS_TIMEOUT, UNDEFINED_PREFERENCE_VALUE_INT);
Tadashi G. Takaoka276b1a22014-02-07 15:25:50 +0900313 return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds
314 : readDefaultKeyLongpressTimeout(res);
Tadashi G. Takaokacc5e4a42013-01-18 12:19:59 +0900315 }
316
317 public static int readDefaultKeyLongpressTimeout(final Resources res) {
318 return res.getInteger(R.integer.config_default_longpress_key_timeout);
319 }
320
Tadashi G. Takaokaa7a7f4e2013-01-10 12:06:00 +0900321 public static int readKeypressVibrationDuration(final SharedPreferences prefs,
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900322 final Resources res) {
Tadashi G. Takaoka276b1a22014-02-07 15:25:50 +0900323 final int milliseconds = prefs.getInt(
324 PREF_VIBRATION_DURATION_SETTINGS, UNDEFINED_PREFERENCE_VALUE_INT);
325 return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds
326 : readDefaultKeypressVibrationDuration(res);
Tadashi G. Takaokaa7a7f4e2013-01-10 12:06:00 +0900327 }
328
Tadashi G. Takaokabd9887a2014-02-10 12:54:45 +0900329 // Default keypress vibration duration for unknown devices.
330 // The negative value means system default.
331 private static final String DEFAULT_KEYPRESS_VIBRATION_DURATION = Integer.toString(-1);
332
Tadashi G. Takaokaa7a7f4e2013-01-10 12:06:00 +0900333 public static int readDefaultKeypressVibrationDuration(final Resources res) {
Tadashi G. Takaokabd9887a2014-02-10 12:54:45 +0900334 return Integer.parseInt(ResourceUtils.getDeviceOverrideValue(res,
335 R.array.keypress_vibration_durations, DEFAULT_KEYPRESS_VIBRATION_DURATION));
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900336 }
337
Tadashi G. Takaoka276b1a22014-02-07 15:25:50 +0900338 public static float readKeyPreviewAnimationScale(final SharedPreferences prefs,
339 final String prefKey, final float defaultValue) {
340 final float fraction = prefs.getFloat(prefKey, UNDEFINED_PREFERENCE_VALUE_FLOAT);
341 return (fraction != UNDEFINED_PREFERENCE_VALUE_FLOAT) ? fraction : defaultValue;
342 }
343
344 public static int readKeyPreviewAnimationDuration(final SharedPreferences prefs,
345 final String prefKey, final int defaultValue) {
346 final int milliseconds = prefs.getInt(prefKey, UNDEFINED_PREFERENCE_VALUE_INT);
347 return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds : defaultValue;
348 }
349
Tadashi G. Takaokabe819db2014-12-09 17:53:24 +0900350 public static float readKeyboardHeight(final SharedPreferences prefs,
351 final float defaultValue) {
352 final float percentage = prefs.getFloat(
353 DebugSettings.PREF_KEYBOARD_HEIGHT_SCALE, UNDEFINED_PREFERENCE_VALUE_FLOAT);
Andy Wangbb9400a2014-10-21 17:03:05 +0900354 return (percentage != UNDEFINED_PREFERENCE_VALUE_FLOAT) ? percentage : defaultValue;
355 }
356
Tadashi G. Takaokad3b0ece2013-01-08 18:20:31 +0900357 public static boolean readUseFullscreenMode(final Resources res) {
358 return res.getBoolean(R.bool.config_use_fullscreen_mode);
359 }
Tadashi G. Takaoka2e1b55f2013-03-05 12:54:13 +0900360
Chieu Nguyena2376cd2015-04-22 14:41:45 -0700361 public static boolean readShowSetupWizardIcon(final SharedPreferences prefs,
362 final Context context) {
363 if (!prefs.contains(PREF_SHOW_SETUP_WIZARD_ICON)) {
364 final ApplicationInfo appInfo = context.getApplicationInfo();
365 final boolean isApplicationInSystemImage =
366 (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
367 // Default value
368 return !isApplicationInSystemImage;
369 }
370 return prefs.getBoolean(PREF_SHOW_SETUP_WIZARD_ICON, false);
371 }
372
Jean Chalard6bb6d302014-09-03 19:36:35 +0900373 public static boolean readHasHardwareKeyboard(final Configuration conf) {
374 // The standard way of finding out whether we have a hardware keyboard. This code is taken
375 // from InputMethodService#onEvaluateInputShown, which canonically determines this.
376 // In a nutshell, we have a keyboard if the configuration says the type of hardware keyboard
377 // is NOKEYS and if it's not hidden (e.g. folded inside the device).
378 return conf.keyboard != Configuration.KEYBOARD_NOKEYS
379 && conf.hardKeyboardHidden != Configuration.HARDKEYBOARDHIDDEN_YES;
380 }
381
Satoshi Kataoka756791e2013-03-13 13:08:34 +0900382 public static boolean isInternal(final SharedPreferences prefs) {
Tadashi G. Takaokaa3920c72014-04-25 11:49:33 -0700383 return prefs.getBoolean(PREF_KEY_IS_INTERNAL, false);
Satoshi Kataoka756791e2013-03-13 13:08:34 +0900384 }
Satoshi Kataokad7491e62013-08-02 15:22:17 +0900385
Satoshi Kataoka283cf9c2013-08-16 14:35:56 +0900386 public void writeLastUsedPersonalizationToken(byte[] token) {
Keisuke Kuroyanagif1457e72013-12-25 11:44:16 +0900387 if (token == null) {
388 mPrefs.edit().remove(PREF_LAST_USED_PERSONALIZATION_TOKEN).apply();
389 } else {
390 final String tokenStr = StringUtils.byteArrayToHexString(token);
391 mPrefs.edit().putString(PREF_LAST_USED_PERSONALIZATION_TOKEN, tokenStr).apply();
392 }
Satoshi Kataoka283cf9c2013-08-16 14:35:56 +0900393 }
394
395 public byte[] readLastUsedPersonalizationToken() {
396 final String tokenStr = mPrefs.getString(PREF_LAST_USED_PERSONALIZATION_TOKEN, null);
397 return StringUtils.hexStringToByteArray(tokenStr);
398 }
Satoshi Kataokaf3f00002013-09-16 17:13:41 +0900399
Keisuke Kuroyanagiba07df72014-01-10 16:30:59 +0900400 public void writeLastPersonalizationDictWipedTime(final long timestamp) {
401 mPrefs.edit().putLong(PREF_LAST_PERSONALIZATION_DICT_WIPED_TIME, timestamp).apply();
402 }
403
404 public long readLastPersonalizationDictGeneratedTime() {
405 return mPrefs.getLong(PREF_LAST_PERSONALIZATION_DICT_WIPED_TIME, 0);
406 }
407
Keisuke Kuroyanagieb28bac2014-01-10 20:28:30 +0900408 public void writeCorpusHandlesForPersonalization(final Set<String> corpusHandles) {
409 mPrefs.edit().putStringSet(PREF_CORPUS_HANDLES_FOR_PERSONALIZATION, corpusHandles).apply();
410 }
411
412 public Set<String> readCorpusHandlesForPersonalization() {
413 final Set<String> emptySet = Collections.emptySet();
414 return mPrefs.getStringSet(PREF_CORPUS_HANDLES_FOR_PERSONALIZATION, emptySet);
415 }
416
Satoshi Kataokaf3f00002013-09-16 17:13:41 +0900417 public static void writeEmojiRecentKeys(final SharedPreferences prefs, String str) {
418 prefs.edit().putString(PREF_EMOJI_RECENT_KEYS, str).apply();
419 }
420
421 public static String readEmojiRecentKeys(final SharedPreferences prefs) {
422 return prefs.getString(PREF_EMOJI_RECENT_KEYS, "");
423 }
424
Satoshi Kataoka6dc99dc2013-10-11 14:54:26 +0900425 public static void writeLastTypedEmojiCategoryPageId(
426 final SharedPreferences prefs, final int categoryId, final int categoryPageId) {
427 final String key = PREF_EMOJI_CATEGORY_LAST_TYPED_ID + categoryId;
428 prefs.edit().putInt(key, categoryPageId).apply();
Satoshi Kataokaf3f00002013-09-16 17:13:41 +0900429 }
430
Satoshi Kataoka6dc99dc2013-10-11 14:54:26 +0900431 public static int readLastTypedEmojiCategoryPageId(
432 final SharedPreferences prefs, final int categoryId) {
433 final String key = PREF_EMOJI_CATEGORY_LAST_TYPED_ID + categoryId;
Satoshi Kataokaf3f00002013-09-16 17:13:41 +0900434 return prefs.getInt(key, 0);
435 }
Satoshi Kataoka6dc99dc2013-10-11 14:54:26 +0900436
437 public static void writeLastShownEmojiCategoryId(
438 final SharedPreferences prefs, final int categoryId) {
439 prefs.edit().putInt(PREF_LAST_SHOWN_EMOJI_CATEGORY_ID, categoryId).apply();
440 }
441
442 public static int readLastShownEmojiCategoryId(
443 final SharedPreferences prefs, final int defValue) {
444 return prefs.getInt(PREF_LAST_SHOWN_EMOJI_CATEGORY_ID, defValue);
445 }
Chieu Nguyen116e58c2015-03-12 19:39:06 -0700446
447 private void upgradeAutocorrectionSettings(final SharedPreferences prefs, final Resources res) {
448 final String thresholdSetting =
449 prefs.getString(PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE, null);
450 if (thresholdSetting != null) {
451 SharedPreferences.Editor editor = prefs.edit();
452 editor.remove(PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE);
453 final String autoCorrectionOff =
454 res.getString(R.string.auto_correction_threshold_mode_index_off);
455 if (thresholdSetting.equals(autoCorrectionOff)) {
456 editor.putBoolean(PREF_AUTO_CORRECTION, false);
457 } else {
458 editor.putBoolean(PREF_AUTO_CORRECTION, true);
459 }
460 editor.commit();
461 }
462 }
Ken Wakasa644d33d2011-10-28 00:33:15 +0900463}