Home | History | Annotate | Download | only in inputmethod
      1 /*
      2  * Copyright (C) 2008 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.settings.inputmethod;
     18 
     19 import com.android.settings.R;
     20 import com.android.settings.Settings.KeyboardLayoutPickerActivity;
     21 import com.android.settings.Settings.SpellCheckersSettingsActivity;
     22 import com.android.settings.SettingsPreferenceFragment;
     23 import com.android.settings.Utils;
     24 import com.android.settings.VoiceInputOutputSettings;
     25 
     26 import android.app.Activity;
     27 import android.content.ContentResolver;
     28 import android.content.Context;
     29 import android.content.Intent;
     30 import android.content.pm.PackageManager;
     31 import android.content.res.Configuration;
     32 import android.content.res.Resources;
     33 import android.database.ContentObserver;
     34 import android.hardware.input.InputManager;
     35 import android.hardware.input.KeyboardLayout;
     36 import android.os.Bundle;
     37 import android.os.Handler;
     38 import android.preference.CheckBoxPreference;
     39 import android.preference.ListPreference;
     40 import android.preference.Preference;
     41 import android.preference.PreferenceCategory;
     42 import android.preference.PreferenceScreen;
     43 import android.provider.Settings;
     44 import android.provider.Settings.System;
     45 import android.text.TextUtils;
     46 import android.view.InputDevice;
     47 import android.view.inputmethod.InputMethodInfo;
     48 import android.view.inputmethod.InputMethodManager;
     49 
     50 import java.util.ArrayList;
     51 import java.util.Collections;
     52 import java.util.List;
     53 import java.util.TreeSet;
     54 
     55 public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
     56         implements Preference.OnPreferenceChangeListener, InputManager.InputDeviceListener,
     57         KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener {
     58 
     59     private static final String KEY_PHONE_LANGUAGE = "phone_language";
     60     private static final String KEY_CURRENT_INPUT_METHOD = "current_input_method";
     61     private static final String KEY_INPUT_METHOD_SELECTOR = "input_method_selector";
     62     private static final String KEY_USER_DICTIONARY_SETTINGS = "key_user_dictionary_settings";
     63     // false: on ICS or later
     64     private static final boolean SHOW_INPUT_METHOD_SWITCHER_SETTINGS = false;
     65 
     66     private static final String[] sSystemSettingNames = {
     67         System.TEXT_AUTO_REPLACE, System.TEXT_AUTO_CAPS, System.TEXT_AUTO_PUNCTUATE,
     68     };
     69 
     70     private static final String[] sHardKeyboardKeys = {
     71         "auto_replace", "auto_caps", "auto_punctuate",
     72     };
     73 
     74     private int mDefaultInputMethodSelectorVisibility = 0;
     75     private ListPreference mShowInputMethodSelectorPref;
     76     private PreferenceCategory mKeyboardSettingsCategory;
     77     private PreferenceCategory mHardKeyboardCategory;
     78     private PreferenceCategory mGameControllerCategory;
     79     private Preference mLanguagePref;
     80     private final ArrayList<InputMethodPreference> mInputMethodPreferenceList =
     81             new ArrayList<InputMethodPreference>();
     82     private final ArrayList<PreferenceScreen> mHardKeyboardPreferenceList =
     83             new ArrayList<PreferenceScreen>();
     84     private InputManager mIm;
     85     private InputMethodManager mImm;
     86     private List<InputMethodInfo> mImis;
     87     private boolean mIsOnlyImeSettings;
     88     private Handler mHandler;
     89     @SuppressWarnings("unused")
     90     private SettingsObserver mSettingsObserver;
     91     private Intent mIntentWaitingForResult;
     92 
     93     @Override
     94     public void onCreate(Bundle icicle) {
     95         super.onCreate(icicle);
     96 
     97         addPreferencesFromResource(R.xml.language_settings);
     98 
     99         try {
    100             mDefaultInputMethodSelectorVisibility = Integer.valueOf(
    101                     getString(R.string.input_method_selector_visibility_default_value));
    102         } catch (NumberFormatException e) {
    103         }
    104 
    105         if (getActivity().getAssets().getLocales().length == 1) {
    106             // No "Select language" pref if there's only one system locale available.
    107             getPreferenceScreen().removePreference(findPreference(KEY_PHONE_LANGUAGE));
    108         } else {
    109             mLanguagePref = findPreference(KEY_PHONE_LANGUAGE);
    110         }
    111         if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
    112             mShowInputMethodSelectorPref = (ListPreference)findPreference(
    113                     KEY_INPUT_METHOD_SELECTOR);
    114             mShowInputMethodSelectorPref.setOnPreferenceChangeListener(this);
    115             // TODO: Update current input method name on summary
    116             updateInputMethodSelectorSummary(loadInputMethodSelectorVisibility());
    117         }
    118 
    119         new VoiceInputOutputSettings(this).onCreate();
    120 
    121         // Get references to dynamically constructed categories.
    122         mHardKeyboardCategory = (PreferenceCategory)findPreference("hard_keyboard");
    123         mKeyboardSettingsCategory = (PreferenceCategory)findPreference(
    124                 "keyboard_settings_category");
    125         mGameControllerCategory = (PreferenceCategory)findPreference(
    126                 "game_controller_settings_category");
    127 
    128         // Filter out irrelevant features if invoked from IME settings button.
    129         mIsOnlyImeSettings = Settings.ACTION_INPUT_METHOD_SETTINGS.equals(
    130                 getActivity().getIntent().getAction());
    131         getActivity().getIntent().setAction(null);
    132         if (mIsOnlyImeSettings) {
    133             getPreferenceScreen().removeAll();
    134             getPreferenceScreen().addPreference(mHardKeyboardCategory);
    135             if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
    136                 getPreferenceScreen().addPreference(mShowInputMethodSelectorPref);
    137             }
    138             getPreferenceScreen().addPreference(mKeyboardSettingsCategory);
    139         }
    140 
    141         // Build IME preference category.
    142         mImm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    143         mImis = mImm.getInputMethodList();
    144 
    145         mKeyboardSettingsCategory.removeAll();
    146         if (!mIsOnlyImeSettings) {
    147             final PreferenceScreen currentIme = new PreferenceScreen(getActivity(), null);
    148             currentIme.setKey(KEY_CURRENT_INPUT_METHOD);
    149             currentIme.setTitle(getResources().getString(R.string.current_input_method));
    150             mKeyboardSettingsCategory.addPreference(currentIme);
    151         }
    152 
    153         mInputMethodPreferenceList.clear();
    154         final int N = (mImis == null ? 0 : mImis.size());
    155         for (int i = 0; i < N; ++i) {
    156             final InputMethodInfo imi = mImis.get(i);
    157             final InputMethodPreference pref = getInputMethodPreference(imi, N);
    158             mInputMethodPreferenceList.add(pref);
    159         }
    160 
    161         if (!mInputMethodPreferenceList.isEmpty()) {
    162             Collections.sort(mInputMethodPreferenceList);
    163             for (int i = 0; i < N; ++i) {
    164                 mKeyboardSettingsCategory.addPreference(mInputMethodPreferenceList.get(i));
    165             }
    166         }
    167 
    168         // Build hard keyboard and game controller preference categories.
    169         mIm = (InputManager)getActivity().getSystemService(Context.INPUT_SERVICE);
    170         updateInputDevices();
    171 
    172         // Spell Checker
    173         final Intent intent = new Intent(Intent.ACTION_MAIN);
    174         intent.setClass(getActivity(), SpellCheckersSettingsActivity.class);
    175         final SpellCheckersPreference scp = ((SpellCheckersPreference)findPreference(
    176                 "spellcheckers_settings"));
    177         if (scp != null) {
    178             scp.setFragmentIntent(this, intent);
    179         }
    180 
    181         mHandler = new Handler();
    182         mSettingsObserver = new SettingsObserver(mHandler, getActivity());
    183     }
    184 
    185     private void updateInputMethodSelectorSummary(int value) {
    186         String[] inputMethodSelectorTitles = getResources().getStringArray(
    187                 R.array.input_method_selector_titles);
    188         if (inputMethodSelectorTitles.length > value) {
    189             mShowInputMethodSelectorPref.setSummary(inputMethodSelectorTitles[value]);
    190             mShowInputMethodSelectorPref.setValue(String.valueOf(value));
    191         }
    192     }
    193 
    194     private void updateUserDictionaryPreference(Preference userDictionaryPreference) {
    195         final Activity activity = getActivity();
    196         final TreeSet<String> localeList = UserDictionaryList.getUserDictionaryLocalesSet(activity);
    197         if (null == localeList) {
    198             // The locale list is null if and only if the user dictionary service is
    199             // not present or disabled. In this case we need to remove the preference.
    200             getPreferenceScreen().removePreference(userDictionaryPreference);
    201         } else if (localeList.size() <= 1) {
    202             final Intent intent =
    203                     new Intent(UserDictionaryList.USER_DICTIONARY_SETTINGS_INTENT_ACTION);
    204             userDictionaryPreference.setTitle(R.string.user_dict_single_settings_title);
    205             userDictionaryPreference.setIntent(intent);
    206             userDictionaryPreference.setFragment(
    207                     com.android.settings.UserDictionarySettings.class.getName());
    208             // If the size of localeList is 0, we don't set the locale parameter in the
    209             // extras. This will be interpreted by the UserDictionarySettings class as
    210             // meaning "the current locale".
    211             // Note that with the current code for UserDictionaryList#getUserDictionaryLocalesSet()
    212             // the locale list always has at least one element, since it always includes the current
    213             // locale explicitly. @see UserDictionaryList.getUserDictionaryLocalesSet().
    214             if (localeList.size() == 1) {
    215                 final String locale = (String)localeList.toArray()[0];
    216                 userDictionaryPreference.getExtras().putString("locale", locale);
    217             }
    218         } else {
    219             userDictionaryPreference.setTitle(R.string.user_dict_multiple_settings_title);
    220             userDictionaryPreference.setFragment(UserDictionaryList.class.getName());
    221         }
    222     }
    223 
    224     @Override
    225     public void onResume() {
    226         super.onResume();
    227 
    228         mSettingsObserver.resume();
    229         mIm.registerInputDeviceListener(this, null);
    230 
    231         if (!mIsOnlyImeSettings) {
    232             if (mLanguagePref != null) {
    233                 Configuration conf = getResources().getConfiguration();
    234                 String language = conf.locale.getLanguage();
    235                 String localeString;
    236                 // TODO: This is not an accurate way to display the locale, as it is
    237                 // just working around the fact that we support limited dialects
    238                 // and want to pretend that the language is valid for all locales.
    239                 // We need a way to support languages that aren't tied to a particular
    240                 // locale instead of hiding the locale qualifier.
    241                 if (language.equals("zz")) {
    242                     String country = conf.locale.getCountry();
    243                     if (country.equals("ZZ")) {
    244                         localeString = "[Developer] Accented English (zz_ZZ)";
    245                     } else if (country.equals("ZY")) {
    246                         localeString = "[Developer] Fake Bi-Directional (zz_ZY)";
    247                     } else {
    248                         localeString = "";
    249                     }
    250                 } else if (hasOnlyOneLanguageInstance(language,
    251                         Resources.getSystem().getAssets().getLocales())) {
    252                     localeString = conf.locale.getDisplayLanguage(conf.locale);
    253                 } else {
    254                     localeString = conf.locale.getDisplayName(conf.locale);
    255                 }
    256                 if (localeString.length() > 1) {
    257                     localeString = Character.toUpperCase(localeString.charAt(0))
    258                             + localeString.substring(1);
    259                     mLanguagePref.setSummary(localeString);
    260                 }
    261             }
    262 
    263             updateUserDictionaryPreference(findPreference(KEY_USER_DICTIONARY_SETTINGS));
    264             if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
    265                 mShowInputMethodSelectorPref.setOnPreferenceChangeListener(this);
    266             }
    267         }
    268 
    269         // Hard keyboard
    270         if (!mHardKeyboardPreferenceList.isEmpty()) {
    271             for (int i = 0; i < sHardKeyboardKeys.length; ++i) {
    272                 CheckBoxPreference chkPref = (CheckBoxPreference)
    273                         mHardKeyboardCategory.findPreference(sHardKeyboardKeys[i]);
    274                 chkPref.setChecked(
    275                         System.getInt(getContentResolver(), sSystemSettingNames[i], 1) > 0);
    276             }
    277         }
    278 
    279         updateInputDevices();
    280 
    281         // IME
    282         InputMethodAndSubtypeUtil.loadInputMethodSubtypeList(
    283                 this, getContentResolver(), mImis, null);
    284         updateActiveInputMethodsSummary();
    285     }
    286 
    287     @Override
    288     public void onPause() {
    289         super.onPause();
    290 
    291         mIm.unregisterInputDeviceListener(this);
    292         mSettingsObserver.pause();
    293 
    294         if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
    295             mShowInputMethodSelectorPref.setOnPreferenceChangeListener(null);
    296         }
    297         InputMethodAndSubtypeUtil.saveInputMethodSubtypeList(
    298                 this, getContentResolver(), mImis, !mHardKeyboardPreferenceList.isEmpty());
    299     }
    300 
    301     @Override
    302     public void onInputDeviceAdded(int deviceId) {
    303         updateInputDevices();
    304     }
    305 
    306     @Override
    307     public void onInputDeviceChanged(int deviceId) {
    308         updateInputDevices();
    309     }
    310 
    311     @Override
    312     public void onInputDeviceRemoved(int deviceId) {
    313         updateInputDevices();
    314     }
    315 
    316     @Override
    317     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
    318         // Input Method stuff
    319         if (Utils.isMonkeyRunning()) {
    320             return false;
    321         }
    322         if (preference instanceof PreferenceScreen) {
    323             if (preference.getFragment() != null) {
    324                 // Fragment will be handled correctly by the super class.
    325             } else if (KEY_CURRENT_INPUT_METHOD.equals(preference.getKey())) {
    326                 final InputMethodManager imm = (InputMethodManager)
    327                         getSystemService(Context.INPUT_METHOD_SERVICE);
    328                 imm.showInputMethodPicker();
    329             }
    330         } else if (preference instanceof CheckBoxPreference) {
    331             final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
    332             if (!mHardKeyboardPreferenceList.isEmpty()) {
    333                 for (int i = 0; i < sHardKeyboardKeys.length; ++i) {
    334                     if (chkPref == mHardKeyboardCategory.findPreference(sHardKeyboardKeys[i])) {
    335                         System.putInt(getContentResolver(), sSystemSettingNames[i],
    336                                 chkPref.isChecked() ? 1 : 0);
    337                         return true;
    338                     }
    339                 }
    340             }
    341             if (chkPref == mGameControllerCategory.findPreference("vibrate_input_devices")) {
    342                 System.putInt(getContentResolver(), Settings.System.VIBRATE_INPUT_DEVICES,
    343                         chkPref.isChecked() ? 1 : 0);
    344                 return true;
    345             }
    346         }
    347         return super.onPreferenceTreeClick(preferenceScreen, preference);
    348     }
    349 
    350     private boolean hasOnlyOneLanguageInstance(String languageCode, String[] locales) {
    351         int count = 0;
    352         for (String localeCode : locales) {
    353             if (localeCode.length() > 2
    354                     && localeCode.startsWith(languageCode)) {
    355                 count++;
    356                 if (count > 1) {
    357                     return false;
    358                 }
    359             }
    360         }
    361         return count == 1;
    362     }
    363 
    364     private void saveInputMethodSelectorVisibility(String value) {
    365         try {
    366             int intValue = Integer.valueOf(value);
    367             Settings.Secure.putInt(getContentResolver(),
    368                     Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY, intValue);
    369             updateInputMethodSelectorSummary(intValue);
    370         } catch(NumberFormatException e) {
    371         }
    372     }
    373 
    374     private int loadInputMethodSelectorVisibility() {
    375         return Settings.Secure.getInt(getContentResolver(),
    376                 Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY,
    377                 mDefaultInputMethodSelectorVisibility);
    378     }
    379 
    380     @Override
    381     public boolean onPreferenceChange(Preference preference, Object value) {
    382         if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
    383             if (preference == mShowInputMethodSelectorPref) {
    384                 if (value instanceof String) {
    385                     saveInputMethodSelectorVisibility((String)value);
    386                 }
    387             }
    388         }
    389         return false;
    390     }
    391 
    392     private void updateActiveInputMethodsSummary() {
    393         for (Preference pref : mInputMethodPreferenceList) {
    394             if (pref instanceof InputMethodPreference) {
    395                 ((InputMethodPreference)pref).updateSummary();
    396             }
    397         }
    398         updateCurrentImeName();
    399     }
    400 
    401     private void updateCurrentImeName() {
    402         final Context context = getActivity();
    403         if (context == null || mImm == null) return;
    404         final Preference curPref = getPreferenceScreen().findPreference(KEY_CURRENT_INPUT_METHOD);
    405         if (curPref != null) {
    406             final CharSequence curIme = InputMethodAndSubtypeUtil.getCurrentInputMethodName(
    407                     context, getContentResolver(), mImm, mImis, getPackageManager());
    408             if (!TextUtils.isEmpty(curIme)) {
    409                 synchronized(this) {
    410                     curPref.setSummary(curIme);
    411                 }
    412             }
    413         }
    414     }
    415 
    416     private InputMethodPreference getInputMethodPreference(InputMethodInfo imi, int imiSize) {
    417         final PackageManager pm = getPackageManager();
    418         final CharSequence label = imi.loadLabel(pm);
    419         // IME settings
    420         final Intent intent;
    421         final String settingsActivity = imi.getSettingsActivity();
    422         if (!TextUtils.isEmpty(settingsActivity)) {
    423             intent = new Intent(Intent.ACTION_MAIN);
    424             intent.setClassName(imi.getPackageName(), settingsActivity);
    425         } else {
    426             intent = null;
    427         }
    428 
    429         // Add a check box for enabling/disabling IME
    430         InputMethodPreference pref = new InputMethodPreference(this, intent, mImm, imi, imiSize);
    431         pref.setKey(imi.getId());
    432         pref.setTitle(label);
    433         return pref;
    434     }
    435 
    436     private void updateInputDevices() {
    437         updateHardKeyboards();
    438         updateGameControllers();
    439     }
    440 
    441     private void updateHardKeyboards() {
    442         mHardKeyboardPreferenceList.clear();
    443         if (getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY) {
    444             final int[] devices = InputDevice.getDeviceIds();
    445             for (int i = 0; i < devices.length; i++) {
    446                 InputDevice device = InputDevice.getDevice(devices[i]);
    447                 if (device != null
    448                         && !device.isVirtual()
    449                         && device.isFullKeyboard()) {
    450                     final String inputDeviceDescriptor = device.getDescriptor();
    451                     final String keyboardLayoutDescriptor =
    452                             mIm.getCurrentKeyboardLayoutForInputDevice(inputDeviceDescriptor);
    453                     final KeyboardLayout keyboardLayout = keyboardLayoutDescriptor != null ?
    454                             mIm.getKeyboardLayout(keyboardLayoutDescriptor) : null;
    455 
    456                     final PreferenceScreen pref = new PreferenceScreen(getActivity(), null);
    457                     pref.setTitle(device.getName());
    458                     if (keyboardLayout != null) {
    459                         pref.setSummary(keyboardLayout.toString());
    460                     } else {
    461                         pref.setSummary(R.string.keyboard_layout_default_label);
    462                     }
    463                     pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
    464                         @Override
    465                         public boolean onPreferenceClick(Preference preference) {
    466                             showKeyboardLayoutDialog(inputDeviceDescriptor);
    467                             return true;
    468                         }
    469                     });
    470                     mHardKeyboardPreferenceList.add(pref);
    471                 }
    472             }
    473         }
    474 
    475         if (!mHardKeyboardPreferenceList.isEmpty()) {
    476             for (int i = mHardKeyboardCategory.getPreferenceCount(); i-- > 0; ) {
    477                 final Preference pref = mHardKeyboardCategory.getPreference(i);
    478                 if (pref.getOrder() < 1000) {
    479                     mHardKeyboardCategory.removePreference(pref);
    480                 }
    481             }
    482 
    483             Collections.sort(mHardKeyboardPreferenceList);
    484             final int count = mHardKeyboardPreferenceList.size();
    485             for (int i = 0; i < count; i++) {
    486                 final Preference pref = mHardKeyboardPreferenceList.get(i);
    487                 pref.setOrder(i);
    488                 mHardKeyboardCategory.addPreference(pref);
    489             }
    490 
    491             getPreferenceScreen().addPreference(mHardKeyboardCategory);
    492         } else {
    493             getPreferenceScreen().removePreference(mHardKeyboardCategory);
    494         }
    495     }
    496 
    497     private void showKeyboardLayoutDialog(String inputDeviceDescriptor) {
    498         KeyboardLayoutDialogFragment fragment =
    499                 new KeyboardLayoutDialogFragment(inputDeviceDescriptor);
    500         fragment.setTargetFragment(this, 0);
    501         fragment.show(getActivity().getFragmentManager(), "keyboardLayout");
    502     }
    503 
    504     @Override
    505     public void onSetupKeyboardLayouts(String inputDeviceDescriptor) {
    506         final Intent intent = new Intent(Intent.ACTION_MAIN);
    507         intent.setClass(getActivity(), KeyboardLayoutPickerActivity.class);
    508         intent.putExtra(KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_DESCRIPTOR,
    509                 inputDeviceDescriptor);
    510         mIntentWaitingForResult = intent;
    511         startActivityForResult(intent, 0);
    512     }
    513 
    514     @Override
    515     public void onActivityResult(int requestCode, int resultCode, Intent data) {
    516         super.onActivityResult(requestCode, resultCode, data);
    517 
    518         if (mIntentWaitingForResult != null) {
    519             String inputDeviceDescriptor = mIntentWaitingForResult.getStringExtra(
    520                     KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_DESCRIPTOR);
    521             mIntentWaitingForResult = null;
    522             showKeyboardLayoutDialog(inputDeviceDescriptor);
    523         }
    524     }
    525 
    526     private void updateGameControllers() {
    527         if (haveInputDeviceWithVibrator()) {
    528             getPreferenceScreen().addPreference(mGameControllerCategory);
    529 
    530             CheckBoxPreference chkPref = (CheckBoxPreference)
    531                     mGameControllerCategory.findPreference("vibrate_input_devices");
    532             chkPref.setChecked(System.getInt(getContentResolver(),
    533                     Settings.System.VIBRATE_INPUT_DEVICES, 1) > 0);
    534         } else {
    535             getPreferenceScreen().removePreference(mGameControllerCategory);
    536         }
    537     }
    538 
    539     private boolean haveInputDeviceWithVibrator() {
    540         final int[] devices = InputDevice.getDeviceIds();
    541         for (int i = 0; i < devices.length; i++) {
    542             InputDevice device = InputDevice.getDevice(devices[i]);
    543             if (device != null && !device.isVirtual() && device.getVibrator().hasVibrator()) {
    544                 return true;
    545             }
    546         }
    547         return false;
    548     }
    549 
    550     private class SettingsObserver extends ContentObserver {
    551         private Context mContext;
    552 
    553         public SettingsObserver(Handler handler, Context context) {
    554             super(handler);
    555             mContext = context;
    556         }
    557 
    558         @Override public void onChange(boolean selfChange) {
    559             updateCurrentImeName();
    560         }
    561 
    562         public void resume() {
    563             final ContentResolver cr = mContext.getContentResolver();
    564             cr.registerContentObserver(
    565                     Settings.Secure.getUriFor(Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
    566             cr.registerContentObserver(Settings.Secure.getUriFor(
    567                     Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, this);
    568         }
    569 
    570         public void pause() {
    571             mContext.getContentResolver().unregisterContentObserver(this);
    572         }
    573     }
    574 }
    575