Settings.java revision d7491e6e817e8954d15aa91300d209fb7e8bf384
1/* 2 * Copyright (C) 2013 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.pm.ApplicationInfo; 22import android.content.res.Resources; 23import android.preference.PreferenceManager; 24import android.util.Log; 25 26import com.android.inputmethod.latin.AudioAndHapticFeedbackManager; 27import com.android.inputmethod.latin.InputAttributes; 28import com.android.inputmethod.latin.R; 29import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; 30import com.android.inputmethod.latin.utils.LocaleUtils; 31import com.android.inputmethod.latin.utils.ResourceUtils; 32import com.android.inputmethod.latin.utils.RunInLocale; 33 34import java.util.HashMap; 35import java.util.Locale; 36 37public final class Settings implements SharedPreferences.OnSharedPreferenceChangeListener { 38 private static final String TAG = Settings.class.getSimpleName(); 39 // In the same order as xml/prefs.xml 40 public static final String PREF_GENERAL_SETTINGS = "general_settings"; 41 public static final String PREF_AUTO_CAP = "auto_cap"; 42 public static final String PREF_VIBRATE_ON = "vibrate_on"; 43 public static final String PREF_SOUND_ON = "sound_on"; 44 public static final String PREF_POPUP_ON = "popup_on"; 45 public static final String PREF_VOICE_MODE = "voice_mode"; 46 public static final String PREF_CORRECTION_SETTINGS = "correction_settings"; 47 public static final String PREF_EDIT_PERSONAL_DICTIONARY = "edit_personal_dictionary"; 48 public static final String PREF_CONFIGURE_DICTIONARIES_KEY = "configure_dictionaries_key"; 49 public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold"; 50 public static final String PREF_SHOW_SUGGESTIONS_SETTING = "show_suggestions_setting"; 51 public static final String PREF_MISC_SETTINGS = "misc_settings"; 52 public static final String PREF_LAST_USER_DICTIONARY_WRITE_TIME = 53 "last_user_dictionary_write_time"; 54 public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings"; 55 public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict"; 56 public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD = 57 "pref_key_use_double_space_period"; 58 public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE = 59 "pref_key_block_potentially_offensive"; 60 public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY = 61 "pref_show_language_switch_key"; 62 public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST = 63 "pref_include_other_imes_in_language_switch_list"; 64 public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles"; 65 public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY = 66 "pref_key_preview_popup_dismiss_delay"; 67 public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction"; 68 public static final String PREF_GESTURE_SETTINGS = "gesture_typing_settings"; 69 public static final String PREF_GESTURE_INPUT = "gesture_input"; 70 public static final String PREF_SLIDING_KEY_INPUT_PREVIEW = "pref_sliding_key_input_preview"; 71 public static final String PREF_KEY_LONGPRESS_TIMEOUT = "pref_key_longpress_timeout"; 72 public static final String PREF_VIBRATION_DURATION_SETTINGS = 73 "pref_vibration_duration_settings"; 74 public static final String PREF_KEYPRESS_SOUND_VOLUME = 75 "pref_keypress_sound_volume"; 76 public static final String PREF_GESTURE_PREVIEW_TRAIL = "pref_gesture_preview_trail"; 77 public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT = 78 "pref_gesture_floating_preview_text"; 79 public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon"; 80 81 public static final String PREF_INPUT_LANGUAGE = "input_language"; 82 public static final String PREF_SELECTED_LANGUAGES = "selected_languages"; 83 public static final String PREF_DEBUG_SETTINGS = "debug_settings"; 84 public static final String PREF_KEY_IS_INTERNAL = "pref_key_is_internal"; 85 86 // This preference key is deprecated. Use {@link #PREF_SHOW_LANGUAGE_SWITCH_KEY} instead. 87 // This is being used only for the backward compatibility. 88 private static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY = 89 "pref_suppress_language_switch_key"; 90 91 public static final String PREF_SEND_FEEDBACK = "send_feedback"; 92 public static final String PREF_ABOUT_KEYBOARD = "about_keyboard"; 93 94 private Resources mRes; 95 private SharedPreferences mPrefs; 96 private SettingsValues mSettingsValues; 97 98 private static final Settings sInstance = new Settings(); 99 100 public static Settings getInstance() { 101 return sInstance; 102 } 103 104 public static void init(final Context context) { 105 sInstance.onCreate(context); 106 } 107 108 private Settings() { 109 // Intentional empty constructor for singleton. 110 } 111 112 private void onCreate(final Context context) { 113 mRes = context.getResources(); 114 mPrefs = PreferenceManager.getDefaultSharedPreferences(context); 115 mPrefs.registerOnSharedPreferenceChangeListener(this); 116 } 117 118 public void onDestroy() { 119 mPrefs.unregisterOnSharedPreferenceChangeListener(this); 120 } 121 122 @Override 123 public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) { 124 if (mSettingsValues == null) { 125 // TODO: Introduce a static function to register this class and ensure that 126 // loadSettings must be called before "onSharedPreferenceChanged" is called. 127 Log.w(TAG, "onSharedPreferenceChanged called before loadSettings."); 128 return; 129 } 130 loadSettings(mSettingsValues.mLocale, mSettingsValues.mInputAttributes); 131 } 132 133 public void loadSettings(final Locale locale, final InputAttributes inputAttributes) { 134 final SharedPreferences prefs = mPrefs; 135 final RunInLocale<SettingsValues> job = new RunInLocale<SettingsValues>() { 136 @Override 137 protected SettingsValues job(final Resources res) { 138 return new SettingsValues(prefs, locale, res, inputAttributes); 139 } 140 }; 141 mSettingsValues = job.runInLocale(mRes, locale); 142 } 143 144 // TODO: Remove this method and add proxy method to SettingsValues. 145 public SettingsValues getCurrent() { 146 return mSettingsValues; 147 } 148 149 public boolean isInternal() { 150 return mSettingsValues.mIsInternal; 151 } 152 153 public String getWordSeparators() { 154 return mSettingsValues.mWordSeparators; 155 } 156 157 public boolean isWordSeparator(final int code) { 158 return mSettingsValues.isWordSeparator(code); 159 } 160 161 public boolean getBlockPotentiallyOffensive() { 162 return mSettingsValues.mBlockPotentiallyOffensive; 163 } 164 165 // Accessed from the settings interface, hence public 166 public static boolean readKeypressSoundEnabled(final SharedPreferences prefs, 167 final Resources res) { 168 return prefs.getBoolean(Settings.PREF_SOUND_ON, 169 res.getBoolean(R.bool.config_default_sound_enabled)); 170 } 171 172 public static boolean readVibrationEnabled(final SharedPreferences prefs, 173 final Resources res) { 174 final boolean hasVibrator = AudioAndHapticFeedbackManager.getInstance().hasVibrator(); 175 return hasVibrator && prefs.getBoolean(PREF_VIBRATE_ON, 176 res.getBoolean(R.bool.config_default_vibration_enabled)); 177 } 178 179 public static boolean readAutoCorrectEnabled(final String currentAutoCorrectionSetting, 180 final Resources res) { 181 final String autoCorrectionOff = res.getString( 182 R.string.auto_correction_threshold_mode_index_off); 183 return !currentAutoCorrectionSetting.equals(autoCorrectionOff); 184 } 185 186 public static boolean readBlockPotentiallyOffensive(final SharedPreferences prefs, 187 final Resources res) { 188 return prefs.getBoolean(Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE, 189 res.getBoolean(R.bool.config_block_potentially_offensive)); 190 } 191 192 public static boolean readFromBuildConfigIfGestureInputEnabled(final Resources res) { 193 return res.getBoolean(R.bool.config_gesture_input_enabled_by_build_config); 194 } 195 196 public static boolean readGestureInputEnabled(final SharedPreferences prefs, 197 final Resources res) { 198 return readFromBuildConfigIfGestureInputEnabled(res) 199 && prefs.getBoolean(Settings.PREF_GESTURE_INPUT, true); 200 } 201 202 public static boolean readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption( 203 final Resources res) { 204 return res.getBoolean(R.bool.config_enable_show_option_of_key_preview_popup); 205 } 206 207 public static boolean readKeyPreviewPopupEnabled(final SharedPreferences prefs, 208 final Resources res) { 209 final boolean defaultKeyPreviewPopup = res.getBoolean( 210 R.bool.config_default_key_preview_popup); 211 if (!readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(res)) { 212 return defaultKeyPreviewPopup; 213 } 214 return prefs.getBoolean(PREF_POPUP_ON, defaultKeyPreviewPopup); 215 } 216 217 public static int readKeyPreviewPopupDismissDelay(final SharedPreferences prefs, 218 final Resources res) { 219 return Integer.parseInt(prefs.getString(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, 220 Integer.toString(res.getInteger( 221 R.integer.config_key_preview_linger_timeout)))); 222 } 223 224 public static boolean readShowsLanguageSwitchKey(final SharedPreferences prefs) { 225 if (prefs.contains(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY)) { 226 final boolean suppressLanguageSwitchKey = prefs.getBoolean( 227 PREF_SUPPRESS_LANGUAGE_SWITCH_KEY, false); 228 final SharedPreferences.Editor editor = prefs.edit(); 229 editor.remove(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY); 230 editor.putBoolean(PREF_SHOW_LANGUAGE_SWITCH_KEY, !suppressLanguageSwitchKey); 231 editor.apply(); 232 } 233 return prefs.getBoolean(PREF_SHOW_LANGUAGE_SWITCH_KEY, true); 234 } 235 236 public static String readPrefAdditionalSubtypes(final SharedPreferences prefs, 237 final Resources res) { 238 final String predefinedPrefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes( 239 res.getStringArray(R.array.predefined_subtypes)); 240 return prefs.getString(PREF_CUSTOM_INPUT_STYLES, predefinedPrefSubtypes); 241 } 242 243 public static void writePrefAdditionalSubtypes(final SharedPreferences prefs, 244 final String prefSubtypes) { 245 prefs.edit().putString(Settings.PREF_CUSTOM_INPUT_STYLES, prefSubtypes).apply(); 246 } 247 248 public static float readKeypressSoundVolume(final SharedPreferences prefs, 249 final Resources res) { 250 final float volume = prefs.getFloat(PREF_KEYPRESS_SOUND_VOLUME, -1.0f); 251 return (volume >= 0) ? volume : readDefaultKeypressSoundVolume(res); 252 } 253 254 public static float readDefaultKeypressSoundVolume(final Resources res) { 255 return Float.parseFloat( 256 ResourceUtils.getDeviceOverrideValue(res, R.array.keypress_volumes)); 257 } 258 259 public static int readKeyLongpressTimeout(final SharedPreferences prefs, 260 final Resources res) { 261 final int ms = prefs.getInt(PREF_KEY_LONGPRESS_TIMEOUT, -1); 262 return (ms >= 0) ? ms : readDefaultKeyLongpressTimeout(res); 263 } 264 265 public static int readDefaultKeyLongpressTimeout(final Resources res) { 266 return res.getInteger(R.integer.config_default_longpress_key_timeout); 267 } 268 269 public static int readKeypressVibrationDuration(final SharedPreferences prefs, 270 final Resources res) { 271 final int ms = prefs.getInt(PREF_VIBRATION_DURATION_SETTINGS, -1); 272 return (ms >= 0) ? ms : readDefaultKeypressVibrationDuration(res); 273 } 274 275 public static int readDefaultKeypressVibrationDuration(final Resources res) { 276 return Integer.parseInt( 277 ResourceUtils.getDeviceOverrideValue(res, R.array.keypress_vibration_durations)); 278 } 279 280 public static boolean readUsabilityStudyMode(final SharedPreferences prefs) { 281 return prefs.getBoolean(DebugSettings.PREF_USABILITY_STUDY_MODE, true); 282 } 283 284 public static long readLastUserHistoryWriteTime(final SharedPreferences prefs, 285 final String locale) { 286 final String str = prefs.getString(PREF_LAST_USER_DICTIONARY_WRITE_TIME, ""); 287 final HashMap<String, Long> map = LocaleUtils.localeAndTimeStrToHashMap(str); 288 if (map.containsKey(locale)) { 289 return map.get(locale); 290 } 291 return 0; 292 } 293 294 public static void writeLastUserHistoryWriteTime(final SharedPreferences prefs, 295 final String locale) { 296 final String oldStr = prefs.getString(PREF_LAST_USER_DICTIONARY_WRITE_TIME, ""); 297 final HashMap<String, Long> map = LocaleUtils.localeAndTimeStrToHashMap(oldStr); 298 map.put(locale, System.currentTimeMillis()); 299 final String newStr = LocaleUtils.localeAndTimeHashMapToStr(map); 300 prefs.edit().putString(PREF_LAST_USER_DICTIONARY_WRITE_TIME, newStr).apply(); 301 } 302 303 public static boolean readUseFullscreenMode(final Resources res) { 304 return res.getBoolean(R.bool.config_use_fullscreen_mode); 305 } 306 307 public static boolean readShowSetupWizardIcon(final SharedPreferences prefs, 308 final Context context) { 309 final boolean enableSetupWizardByConfig = context.getResources().getBoolean( 310 R.bool.config_setup_wizard_available); 311 if (!enableSetupWizardByConfig) { 312 return false; 313 } 314 if (!prefs.contains(Settings.PREF_SHOW_SETUP_WIZARD_ICON)) { 315 final ApplicationInfo appInfo = context.getApplicationInfo(); 316 final boolean isApplicationInSystemImage = 317 (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 318 // Default value 319 return !isApplicationInSystemImage; 320 } 321 return prefs.getBoolean(Settings.PREF_SHOW_SETUP_WIZARD_ICON, false); 322 } 323 324 public static boolean isInternal(final SharedPreferences prefs) { 325 return prefs.getBoolean(Settings.PREF_KEY_IS_INTERNAL, false); 326 } 327 328 public static boolean readUseOnlyPersonalizationDictionaryForDebug( 329 final SharedPreferences prefs) { 330 return prefs.getBoolean( 331 DebugSettings.PREF_USE_ONLY_PERSONALIZATION_DICTIONARY_FOR_DEBUG, false); 332 } 333} 334