1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/*
2afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
4afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * you may not use this file except in compliance with the License.
6afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * You may obtain a copy of the License at
7afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
8afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
10afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * See the License for the specific language governing permissions and
14afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * limitations under the License.
15afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
16afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
170417e4094713c5f4dac700b645000d0959bf62fasatokpackage com.android.settings.inputmethod;
180417e4094713c5f4dac700b645000d0959bf62fasatok
190417e4094713c5f4dac700b645000d0959bf62fasatokimport com.android.settings.R;
20e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brownimport com.android.settings.Settings.KeyboardLayoutPickerActivity;
21e077d2b607032fb66a4a046aa4b46945d32d281esatokimport com.android.settings.Settings.SpellCheckersSettingsActivity;
220417e4094713c5f4dac700b645000d0959bf62fasatokimport com.android.settings.SettingsPreferenceFragment;
230417e4094713c5f4dac700b645000d0959bf62fasatokimport com.android.settings.Utils;
24b44161f3ed9b91f39086247d8efbdac42656b93bAmith Yamasaniimport com.android.settings.VoiceInputOutputSettings;
25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
26c087e35d7f9a968ea035e931aa318cf36a3e1b90Jean Chalardimport android.app.Activity;
27b9509d046c911b7b334aa45f693c49a7182ef470satokimport android.content.ContentResolver;
28afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Context;
293fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.content.Intent;
303fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.content.pm.PackageManager;
31afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.res.Configuration;
32140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasaniimport android.content.res.Resources;
33b9509d046c911b7b334aa45f693c49a7182ef470satokimport android.database.ContentObserver;
34e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brownimport android.hardware.input.InputManager;
354397f406a3c9e09ca2d5174ba46328345faa504eJeff Brownimport android.hardware.input.KeyboardLayout;
36afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Bundle;
37b9509d046c911b7b334aa45f693c49a7182ef470satokimport android.os.Handler;
383fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.preference.CheckBoxPreference;
39c88a7ff1efd10374974e45768bde1658cc1d8483satokimport android.preference.ListPreference;
40afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.preference.Preference;
413fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.preference.PreferenceCategory;
42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.preference.PreferenceScreen;
43c88a7ff1efd10374974e45768bde1658cc1d8483satokimport android.provider.Settings;
443fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.provider.Settings.System;
453fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.text.TextUtils;
46e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brownimport android.view.InputDevice;
473fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.view.inputmethod.InputMethodInfo;
48afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.inputmethod.InputMethodManager;
49c087e35d7f9a968ea035e931aa318cf36a3e1b90Jean Chalard
503fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport java.util.ArrayList;
513fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport java.util.Collections;
523fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport java.util.List;
53f54622e46c9164e4ab46c09c9c3ff173828d5940Jean Chalardimport java.util.TreeSet;
54afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
55c88a7ff1efd10374974e45768bde1658cc1d8483satokpublic class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
56766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        implements Preference.OnPreferenceChangeListener, InputManager.InputDeviceListener,
57766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener {
580cc35e444bd71f117b6aed97e40ea4f3d82cd8faDaisuke Miyakawa
590f2e6dec7c8dc136783eacb5b62c9d3248c4845aAmith Yamasani    private static final String KEY_PHONE_LANGUAGE = "phone_language";
60c88a7ff1efd10374974e45768bde1658cc1d8483satok    private static final String KEY_CURRENT_INPUT_METHOD = "current_input_method";
61c88a7ff1efd10374974e45768bde1658cc1d8483satok    private static final String KEY_INPUT_METHOD_SELECTOR = "input_method_selector";
6271ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard    private static final String KEY_USER_DICTIONARY_SETTINGS = "key_user_dictionary_settings";
633fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    // false: on ICS or later
643fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private static final boolean SHOW_INPUT_METHOD_SWITCHER_SETTINGS = false;
6571ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard
663fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private static final String[] sSystemSettingNames = {
673fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        System.TEXT_AUTO_REPLACE, System.TEXT_AUTO_CAPS, System.TEXT_AUTO_PUNCTUATE,
683fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    };
693fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
703fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private static final String[] sHardKeyboardKeys = {
713fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        "auto_replace", "auto_caps", "auto_punctuate",
723fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    };
7386997beac8ccd3d9e1deedb4a7afe6ddeb3a0bd7The Android Open Source Project
74c88a7ff1efd10374974e45768bde1658cc1d8483satok    private int mDefaultInputMethodSelectorVisibility = 0;
75c88a7ff1efd10374974e45768bde1658cc1d8483satok    private ListPreference mShowInputMethodSelectorPref;
76e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown    private PreferenceCategory mKeyboardSettingsCategory;
77e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown    private PreferenceCategory mHardKeyboardCategory;
78f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown    private PreferenceCategory mGameControllerCategory;
790f2e6dec7c8dc136783eacb5b62c9d3248c4845aAmith Yamasani    private Preference mLanguagePref;
80e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown    private final ArrayList<InputMethodPreference> mInputMethodPreferenceList =
813fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            new ArrayList<InputMethodPreference>();
82e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown    private final ArrayList<PreferenceScreen> mHardKeyboardPreferenceList =
83e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            new ArrayList<PreferenceScreen>();
8496cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown    private InputManager mIm;
853fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private InputMethodManager mImm;
863fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private List<InputMethodInfo> mImis;
873fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private boolean mIsOnlyImeSettings;
88b9509d046c911b7b334aa45f693c49a7182ef470satok    private Handler mHandler;
89b9509d046c911b7b334aa45f693c49a7182ef470satok    @SuppressWarnings("unused")
90b9509d046c911b7b334aa45f693c49a7182ef470satok    private SettingsObserver mSettingsObserver;
91766b286187d02b3da6e0142376a4478072f30a16Jeff Brown    private Intent mIntentWaitingForResult;
92afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
93afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
94d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public void onCreate(Bundle icicle) {
95afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onCreate(icicle);
96afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
97afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        addPreferencesFromResource(R.xml.language_settings);
98afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
99c88a7ff1efd10374974e45768bde1658cc1d8483satok        try {
100c88a7ff1efd10374974e45768bde1658cc1d8483satok            mDefaultInputMethodSelectorVisibility = Integer.valueOf(
101c88a7ff1efd10374974e45768bde1658cc1d8483satok                    getString(R.string.input_method_selector_visibility_default_value));
102c88a7ff1efd10374974e45768bde1658cc1d8483satok        } catch (NumberFormatException e) {
103afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
10486997beac8ccd3d9e1deedb4a7afe6ddeb3a0bd7The Android Open Source Project
105c88a7ff1efd10374974e45768bde1658cc1d8483satok        if (getActivity().getAssets().getLocales().length == 1) {
106c88a7ff1efd10374974e45768bde1658cc1d8483satok            // No "Select language" pref if there's only one system locale available.
107c88a7ff1efd10374974e45768bde1658cc1d8483satok            getPreferenceScreen().removePreference(findPreference(KEY_PHONE_LANGUAGE));
108afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
109c88a7ff1efd10374974e45768bde1658cc1d8483satok            mLanguagePref = findPreference(KEY_PHONE_LANGUAGE);
110afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
1113fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
1123fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            mShowInputMethodSelectorPref = (ListPreference)findPreference(
1133fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                    KEY_INPUT_METHOD_SELECTOR);
1143fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            mShowInputMethodSelectorPref.setOnPreferenceChangeListener(this);
1153fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            // TODO: Update current input method name on summary
1163fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            updateInputMethodSelectorSummary(loadInputMethodSelectorVisibility());
1173fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
118b44161f3ed9b91f39086247d8efbdac42656b93bAmith Yamasani
119b44161f3ed9b91f39086247d8efbdac42656b93bAmith Yamasani        new VoiceInputOutputSettings(this).onCreate();
1203fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
121e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        // Get references to dynamically constructed categories.
122e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        mHardKeyboardCategory = (PreferenceCategory)findPreference("hard_keyboard");
123e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        mKeyboardSettingsCategory = (PreferenceCategory)findPreference(
124e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                "keyboard_settings_category");
125f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        mGameControllerCategory = (PreferenceCategory)findPreference(
126f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown                "game_controller_settings_category");
1273fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
128e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        // Filter out irrelevant features if invoked from IME settings button.
1293fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        mIsOnlyImeSettings = Settings.ACTION_INPUT_METHOD_SETTINGS.equals(
1303fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                getActivity().getIntent().getAction());
1318ff6222a9136cdbaeea9191869b90abd179efc85satok        getActivity().getIntent().setAction(null);
132e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        if (mIsOnlyImeSettings) {
133e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            getPreferenceScreen().removeAll();
134e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            getPreferenceScreen().addPreference(mHardKeyboardCategory);
135e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
136e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                getPreferenceScreen().addPreference(mShowInputMethodSelectorPref);
137e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            }
138e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            getPreferenceScreen().addPreference(mKeyboardSettingsCategory);
139e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        }
140e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown
141e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        // Build IME preference category.
1423fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        mImm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
1433fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        mImis = mImm.getInputMethodList();
144e077d2b607032fb66a4a046aa4b46945d32d281esatok
145e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        mKeyboardSettingsCategory.removeAll();
146e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        if (!mIsOnlyImeSettings) {
147e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            final PreferenceScreen currentIme = new PreferenceScreen(getActivity(), null);
148e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            currentIme.setKey(KEY_CURRENT_INPUT_METHOD);
149e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            currentIme.setTitle(getResources().getString(R.string.current_input_method));
150e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            mKeyboardSettingsCategory.addPreference(currentIme);
151e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        }
152e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown
153e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        mInputMethodPreferenceList.clear();
154e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        final int N = (mImis == null ? 0 : mImis.size());
155e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        for (int i = 0; i < N; ++i) {
156e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            final InputMethodInfo imi = mImis.get(i);
157e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            final InputMethodPreference pref = getInputMethodPreference(imi, N);
158e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            mInputMethodPreferenceList.add(pref);
159e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        }
160e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown
161e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        if (!mInputMethodPreferenceList.isEmpty()) {
162e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            Collections.sort(mInputMethodPreferenceList);
163e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            for (int i = 0; i < N; ++i) {
164e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                mKeyboardSettingsCategory.addPreference(mInputMethodPreferenceList.get(i));
165e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            }
166e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        }
167e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown
168f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        // Build hard keyboard and game controller preference categories.
16996cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown        mIm = (InputManager)getActivity().getSystemService(Context.INPUT_SERVICE);
170f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        updateInputDevices();
171e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown
172e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        // Spell Checker
173e077d2b607032fb66a4a046aa4b46945d32d281esatok        final Intent intent = new Intent(Intent.ACTION_MAIN);
174e077d2b607032fb66a4a046aa4b46945d32d281esatok        intent.setClass(getActivity(), SpellCheckersSettingsActivity.class);
175c0b569c317fad96abbf0ea23d07eb6d19f634ccfsatok        final SpellCheckersPreference scp = ((SpellCheckersPreference)findPreference(
176c0b569c317fad96abbf0ea23d07eb6d19f634ccfsatok                "spellcheckers_settings"));
177c0b569c317fad96abbf0ea23d07eb6d19f634ccfsatok        if (scp != null) {
178c0b569c317fad96abbf0ea23d07eb6d19f634ccfsatok            scp.setFragmentIntent(this, intent);
179c0b569c317fad96abbf0ea23d07eb6d19f634ccfsatok        }
180b9509d046c911b7b334aa45f693c49a7182ef470satok
181b9509d046c911b7b334aa45f693c49a7182ef470satok        mHandler = new Handler();
182b9509d046c911b7b334aa45f693c49a7182ef470satok        mSettingsObserver = new SettingsObserver(mHandler, getActivity());
183afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1849cd11a9aa5ac74ca89432655d019f68d789bc405satok
185c88a7ff1efd10374974e45768bde1658cc1d8483satok    private void updateInputMethodSelectorSummary(int value) {
186c88a7ff1efd10374974e45768bde1658cc1d8483satok        String[] inputMethodSelectorTitles = getResources().getStringArray(
187c88a7ff1efd10374974e45768bde1658cc1d8483satok                R.array.input_method_selector_titles);
188c88a7ff1efd10374974e45768bde1658cc1d8483satok        if (inputMethodSelectorTitles.length > value) {
189c88a7ff1efd10374974e45768bde1658cc1d8483satok            mShowInputMethodSelectorPref.setSummary(inputMethodSelectorTitles[value]);
190c88a7ff1efd10374974e45768bde1658cc1d8483satok            mShowInputMethodSelectorPref.setValue(String.valueOf(value));
191afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
192afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
19380a7a1dbf22d689723d39bad9ba319b6f4b0201dThe Android Open Source Project
19471ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard    private void updateUserDictionaryPreference(Preference userDictionaryPreference) {
195c087e35d7f9a968ea035e931aa318cf36a3e1b90Jean Chalard        final Activity activity = getActivity();
196f54622e46c9164e4ab46c09c9c3ff173828d5940Jean Chalard        final TreeSet<String> localeList = UserDictionaryList.getUserDictionaryLocalesSet(activity);
197410e75b15bd7ecfcb8985c4368fec5e355e2c099Jean Chalard        if (null == localeList) {
198410e75b15bd7ecfcb8985c4368fec5e355e2c099Jean Chalard            // The locale list is null if and only if the user dictionary service is
199410e75b15bd7ecfcb8985c4368fec5e355e2c099Jean Chalard            // not present or disabled. In this case we need to remove the preference.
2008ba5c42b213c4cd5b8773595fea2a1be6a18d711Jean Chalard            getPreferenceScreen().removePreference(userDictionaryPreference);
201410e75b15bd7ecfcb8985c4368fec5e355e2c099Jean Chalard        } else if (localeList.size() <= 1) {
2024e658ba969830e8c9617dc8938271df1ed09aa44Jean Chalard            final Intent intent =
2034e658ba969830e8c9617dc8938271df1ed09aa44Jean Chalard                    new Intent(UserDictionaryList.USER_DICTIONARY_SETTINGS_INTENT_ACTION);
20471ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard            userDictionaryPreference.setTitle(R.string.user_dict_single_settings_title);
2054e658ba969830e8c9617dc8938271df1ed09aa44Jean Chalard            userDictionaryPreference.setIntent(intent);
206b9f837dd1da22f41c72e0cdc1454a486dbc6c448Jean Chalard            userDictionaryPreference.setFragment(
207b9f837dd1da22f41c72e0cdc1454a486dbc6c448Jean Chalard                    com.android.settings.UserDictionarySettings.class.getName());
20871ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard            // If the size of localeList is 0, we don't set the locale parameter in the
20971ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard            // extras. This will be interpreted by the UserDictionarySettings class as
21071ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard            // meaning "the current locale".
211f54622e46c9164e4ab46c09c9c3ff173828d5940Jean Chalard            // Note that with the current code for UserDictionaryList#getUserDictionaryLocalesSet()
21271ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard            // the locale list always has at least one element, since it always includes the current
213f54622e46c9164e4ab46c09c9c3ff173828d5940Jean Chalard            // locale explicitly. @see UserDictionaryList.getUserDictionaryLocalesSet().
21471ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard            if (localeList.size() == 1) {
21571ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard                final String locale = (String)localeList.toArray()[0];
21671ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard                userDictionaryPreference.getExtras().putString("locale", locale);
21771ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard            }
218c087e35d7f9a968ea035e931aa318cf36a3e1b90Jean Chalard        } else {
21971ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard            userDictionaryPreference.setTitle(R.string.user_dict_multiple_settings_title);
22071ad1f4e3e819a40a830a148a2d1bd7b10fed09dJean Chalard            userDictionaryPreference.setFragment(UserDictionaryList.class.getName());
221c087e35d7f9a968ea035e931aa318cf36a3e1b90Jean Chalard        }
222c087e35d7f9a968ea035e931aa318cf36a3e1b90Jean Chalard    }
223c087e35d7f9a968ea035e931aa318cf36a3e1b90Jean Chalard
224afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
225d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public void onResume() {
226afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onResume();
22796cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown
2289bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov        mSettingsObserver.resume();
229093cf6094c2fdf6d84e3ae7ecb53aa955e893c38Jean-Baptiste Queru        mIm.registerInputDeviceListener(this, null);
23096cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown
2313fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        if (!mIsOnlyImeSettings) {
2323fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            if (mLanguagePref != null) {
2333fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                Configuration conf = getResources().getConfiguration();
234140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                String language = conf.locale.getLanguage();
235140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                String localeString;
236140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                // TODO: This is not an accurate way to display the locale, as it is
237140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                // just working around the fact that we support limited dialects
238140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                // and want to pretend that the language is valid for all locales.
239140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                // We need a way to support languages that aren't tied to a particular
240140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                // locale instead of hiding the locale qualifier.
241cbde502ebb2ffe00eec713a91e1f05d753b2b603Benjamin Poiesz                if (language.equals("zz")) {
242cbde502ebb2ffe00eec713a91e1f05d753b2b603Benjamin Poiesz                    String country = conf.locale.getCountry();
243cbde502ebb2ffe00eec713a91e1f05d753b2b603Benjamin Poiesz                    if (country.equals("ZZ")) {
244cbde502ebb2ffe00eec713a91e1f05d753b2b603Benjamin Poiesz                        localeString = "[Developer] Accented English (zz_ZZ)";
245cbde502ebb2ffe00eec713a91e1f05d753b2b603Benjamin Poiesz                    } else if (country.equals("ZY")) {
246cbde502ebb2ffe00eec713a91e1f05d753b2b603Benjamin Poiesz                        localeString = "[Developer] Fake Bi-Directional (zz_ZY)";
247cbde502ebb2ffe00eec713a91e1f05d753b2b603Benjamin Poiesz                    } else {
248cbde502ebb2ffe00eec713a91e1f05d753b2b603Benjamin Poiesz                        localeString = "";
249cbde502ebb2ffe00eec713a91e1f05d753b2b603Benjamin Poiesz                    }
250cbde502ebb2ffe00eec713a91e1f05d753b2b603Benjamin Poiesz                } else if (hasOnlyOneLanguageInstance(language,
251140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                        Resources.getSystem().getAssets().getLocales())) {
252140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                    localeString = conf.locale.getDisplayLanguage(conf.locale);
253140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                } else {
254140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                    localeString = conf.locale.getDisplayName(conf.locale);
255140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                }
256140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                if (localeString.length() > 1) {
257140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                    localeString = Character.toUpperCase(localeString.charAt(0))
258140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                            + localeString.substring(1);
259140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                    mLanguagePref.setSummary(localeString);
2603fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                }
2613fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            }
2623fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
2633fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            updateUserDictionaryPreference(findPreference(KEY_USER_DICTIONARY_SETTINGS));
2643fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
2653fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                mShowInputMethodSelectorPref.setOnPreferenceChangeListener(this);
2663fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            }
2673fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
2683fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
2693fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        // Hard keyboard
270e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        if (!mHardKeyboardPreferenceList.isEmpty()) {
2713fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            for (int i = 0; i < sHardKeyboardKeys.length; ++i) {
272427a7ba1048d81b6b4fdcf29072c7584f6c18b87Jean Chalard                CheckBoxPreference chkPref = (CheckBoxPreference)
2733fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                        mHardKeyboardCategory.findPreference(sHardKeyboardKeys[i]);
2743fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                chkPref.setChecked(
2753fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                        System.getInt(getContentResolver(), sSystemSettingNames[i], 1) > 0);
2760f2e6dec7c8dc136783eacb5b62c9d3248c4845aAmith Yamasani            }
2770f2e6dec7c8dc136783eacb5b62c9d3248c4845aAmith Yamasani        }
278c88a7ff1efd10374974e45768bde1658cc1d8483satok
279f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        updateInputDevices();
280e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown
2813fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        // IME
2823fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        InputMethodAndSubtypeUtil.loadInputMethodSubtypeList(
2833fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                this, getContentResolver(), mImis, null);
2843fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        updateActiveInputMethodsSummary();
285afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
286afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
287afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
288d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public void onPause() {
289afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onPause();
29096cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown
29196cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown        mIm.unregisterInputDeviceListener(this);
292093cf6094c2fdf6d84e3ae7ecb53aa955e893c38Jean-Baptiste Queru        mSettingsObserver.pause();
29396cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown
2943fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
2953fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            mShowInputMethodSelectorPref.setOnPreferenceChangeListener(null);
2963fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
2973fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        InputMethodAndSubtypeUtil.saveInputMethodSubtypeList(
298e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                this, getContentResolver(), mImis, !mHardKeyboardPreferenceList.isEmpty());
299afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
300afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
30186997beac8ccd3d9e1deedb4a7afe6ddeb3a0bd7The Android Open Source Project    @Override
30296cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown    public void onInputDeviceAdded(int deviceId) {
303f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        updateInputDevices();
30496cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown    }
30596cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown
30696cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown    @Override
30796cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown    public void onInputDeviceChanged(int deviceId) {
308f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        updateInputDevices();
30996cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown    }
31096cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown
31196cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown    @Override
31296cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown    public void onInputDeviceRemoved(int deviceId) {
313f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        updateInputDevices();
31496cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown    }
31596cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown
31696cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown    @Override
31786997beac8ccd3d9e1deedb4a7afe6ddeb3a0bd7The Android Open Source Project    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
318afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Input Method stuff
319a718832e28095219a897c6e95e903c1a3fe57c12Ying Wang        if (Utils.isMonkeyRunning()) {
320afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return false;
321afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
322c88a7ff1efd10374974e45768bde1658cc1d8483satok        if (preference instanceof PreferenceScreen) {
323c88c6bbcd0d3901fe9f61bab82a17ec49ad62e6dDaisuke Miyakawa            if (preference.getFragment() != null) {
324c88c6bbcd0d3901fe9f61bab82a17ec49ad62e6dDaisuke Miyakawa                // Fragment will be handled correctly by the super class.
325c88a7ff1efd10374974e45768bde1658cc1d8483satok            } else if (KEY_CURRENT_INPUT_METHOD.equals(preference.getKey())) {
326f58090d5224fa03e8f4d8a980306952686a152f0Daisuke Miyakawa                final InputMethodManager imm = (InputMethodManager)
327f58090d5224fa03e8f4d8a980306952686a152f0Daisuke Miyakawa                        getSystemService(Context.INPUT_METHOD_SERVICE);
328103cc7da5f3ff9a46aa0b1dd9fcd0c7759c2d096satok                imm.showInputMethodPicker();
329afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
3303fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        } else if (preference instanceof CheckBoxPreference) {
3313fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
332e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            if (!mHardKeyboardPreferenceList.isEmpty()) {
3333fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                for (int i = 0; i < sHardKeyboardKeys.length; ++i) {
3343fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                    if (chkPref == mHardKeyboardCategory.findPreference(sHardKeyboardKeys[i])) {
3353fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                        System.putInt(getContentResolver(), sSystemSettingNames[i],
3363fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                                chkPref.isChecked() ? 1 : 0);
3373fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                        return true;
3383fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                    }
3393fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                }
3403fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            }
341f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown            if (chkPref == mGameControllerCategory.findPreference("vibrate_input_devices")) {
342f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown                System.putInt(getContentResolver(), Settings.System.VIBRATE_INPUT_DEVICES,
343f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown                        chkPref.isChecked() ? 1 : 0);
344f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown                return true;
345f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown            }
346afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
347afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return super.onPreferenceTreeClick(preferenceScreen, preference);
348afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
349afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
350140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani    private boolean hasOnlyOneLanguageInstance(String languageCode, String[] locales) {
351140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani        int count = 0;
352140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani        for (String localeCode : locales) {
353140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani            if (localeCode.length() > 2
354140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                    && localeCode.startsWith(languageCode)) {
355140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                count++;
356140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                if (count > 1) {
357140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                    return false;
358140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani                }
359140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani            }
360140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani        }
361140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani        return count == 1;
362140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani    }
363140b6f5234a9b49dd1ec431e7adcf10754daeab1Amith Yamasani
364c88a7ff1efd10374974e45768bde1658cc1d8483satok    private void saveInputMethodSelectorVisibility(String value) {
365c88a7ff1efd10374974e45768bde1658cc1d8483satok        try {
366c88a7ff1efd10374974e45768bde1658cc1d8483satok            int intValue = Integer.valueOf(value);
367c88a7ff1efd10374974e45768bde1658cc1d8483satok            Settings.Secure.putInt(getContentResolver(),
368c88a7ff1efd10374974e45768bde1658cc1d8483satok                    Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY, intValue);
369c88a7ff1efd10374974e45768bde1658cc1d8483satok            updateInputMethodSelectorSummary(intValue);
370c88a7ff1efd10374974e45768bde1658cc1d8483satok        } catch(NumberFormatException e) {
371c88a7ff1efd10374974e45768bde1658cc1d8483satok        }
372c88a7ff1efd10374974e45768bde1658cc1d8483satok    }
373c88a7ff1efd10374974e45768bde1658cc1d8483satok
374c88a7ff1efd10374974e45768bde1658cc1d8483satok    private int loadInputMethodSelectorVisibility() {
375c88a7ff1efd10374974e45768bde1658cc1d8483satok        return Settings.Secure.getInt(getContentResolver(),
376c88a7ff1efd10374974e45768bde1658cc1d8483satok                Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY,
377c88a7ff1efd10374974e45768bde1658cc1d8483satok                mDefaultInputMethodSelectorVisibility);
378c88a7ff1efd10374974e45768bde1658cc1d8483satok    }
379c88a7ff1efd10374974e45768bde1658cc1d8483satok
38020108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai    @Override
381c88a7ff1efd10374974e45768bde1658cc1d8483satok    public boolean onPreferenceChange(Preference preference, Object value) {
3823fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
3833fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            if (preference == mShowInputMethodSelectorPref) {
3843fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                if (value instanceof String) {
3853fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                    saveInputMethodSelectorVisibility((String)value);
3863fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                }
387c88a7ff1efd10374974e45768bde1658cc1d8483satok            }
38820108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        }
389c88a7ff1efd10374974e45768bde1658cc1d8483satok        return false;
39020108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai    }
39120108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai
3923fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private void updateActiveInputMethodsSummary() {
3933fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        for (Preference pref : mInputMethodPreferenceList) {
3943fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            if (pref instanceof InputMethodPreference) {
3953fa13775e805df6cc7244d3f93105c5d3a5b748fsatok                ((InputMethodPreference)pref).updateSummary();
3963fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            }
3973fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
398b9509d046c911b7b334aa45f693c49a7182ef470satok        updateCurrentImeName();
399b9509d046c911b7b334aa45f693c49a7182ef470satok    }
400b9509d046c911b7b334aa45f693c49a7182ef470satok
401b9509d046c911b7b334aa45f693c49a7182ef470satok    private void updateCurrentImeName() {
402b9509d046c911b7b334aa45f693c49a7182ef470satok        final Context context = getActivity();
403b9509d046c911b7b334aa45f693c49a7182ef470satok        if (context == null || mImm == null) return;
404b9509d046c911b7b334aa45f693c49a7182ef470satok        final Preference curPref = getPreferenceScreen().findPreference(KEY_CURRENT_INPUT_METHOD);
405b9509d046c911b7b334aa45f693c49a7182ef470satok        if (curPref != null) {
406b9509d046c911b7b334aa45f693c49a7182ef470satok            final CharSequence curIme = InputMethodAndSubtypeUtil.getCurrentInputMethodName(
407b9509d046c911b7b334aa45f693c49a7182ef470satok                    context, getContentResolver(), mImm, mImis, getPackageManager());
408b9509d046c911b7b334aa45f693c49a7182ef470satok            if (!TextUtils.isEmpty(curIme)) {
409b9509d046c911b7b334aa45f693c49a7182ef470satok                synchronized(this) {
410b9509d046c911b7b334aa45f693c49a7182ef470satok                    curPref.setSummary(curIme);
411b9509d046c911b7b334aa45f693c49a7182ef470satok                }
412b9509d046c911b7b334aa45f693c49a7182ef470satok            }
413b9509d046c911b7b334aa45f693c49a7182ef470satok        }
4143fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
4153fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
4163fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private InputMethodPreference getInputMethodPreference(InputMethodInfo imi, int imiSize) {
4173fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        final PackageManager pm = getPackageManager();
4183fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        final CharSequence label = imi.loadLabel(pm);
4193fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        // IME settings
4203fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        final Intent intent;
4213fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        final String settingsActivity = imi.getSettingsActivity();
4223fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        if (!TextUtils.isEmpty(settingsActivity)) {
4233fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            intent = new Intent(Intent.ACTION_MAIN);
4243fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            intent.setClassName(imi.getPackageName(), settingsActivity);
4253fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        } else {
4263fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            intent = null;
4273fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
4283fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
4293fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        // Add a check box for enabling/disabling IME
4303fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        InputMethodPreference pref = new InputMethodPreference(this, intent, mImm, imi, imiSize);
4313fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        pref.setKey(imi.getId());
4323fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        pref.setTitle(label);
4333fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        return pref;
4343fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
4353fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
436f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown    private void updateInputDevices() {
437f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        updateHardKeyboards();
438f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        updateGameControllers();
439f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown    }
440f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown
441e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown    private void updateHardKeyboards() {
442e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        mHardKeyboardPreferenceList.clear();
443e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        if (getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY) {
444e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            final int[] devices = InputDevice.getDeviceIds();
445e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            for (int i = 0; i < devices.length; i++) {
446e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                InputDevice device = InputDevice.getDevice(devices[i]);
447e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                if (device != null
4484397f406a3c9e09ca2d5174ba46328345faa504eJeff Brown                        && !device.isVirtual()
449bf677f48b73fc8d6fea9f09ad9d0e423f982d260Jeff Brown                        && device.isFullKeyboard()) {
450e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                    final String inputDeviceDescriptor = device.getDescriptor();
451e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                    final String keyboardLayoutDescriptor =
452766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                            mIm.getCurrentKeyboardLayoutForInputDevice(inputDeviceDescriptor);
453e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                    final KeyboardLayout keyboardLayout = keyboardLayoutDescriptor != null ?
45496cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown                            mIm.getKeyboardLayout(keyboardLayoutDescriptor) : null;
455e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown
456e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                    final PreferenceScreen pref = new PreferenceScreen(getActivity(), null);
457e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                    pref.setTitle(device.getName());
458e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                    if (keyboardLayout != null) {
459a350352e03a1cd08942cce99d7e5f6a1b48c224fJeff Brown                        pref.setSummary(keyboardLayout.toString());
460512d0cb3eb82d3e95807f018b035fba8a6d48f34Jeff Brown                    } else {
461512d0cb3eb82d3e95807f018b035fba8a6d48f34Jeff Brown                        pref.setSummary(R.string.keyboard_layout_default_label);
462e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                    }
463766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                    pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
464766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                        @Override
465766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                        public boolean onPreferenceClick(Preference preference) {
466766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                            showKeyboardLayoutDialog(inputDeviceDescriptor);
467766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                            return true;
468766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                        }
469766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                    });
470e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                    mHardKeyboardPreferenceList.add(pref);
471e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                }
4723fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            }
4733fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
4743fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
475e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        if (!mHardKeyboardPreferenceList.isEmpty()) {
476e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            for (int i = mHardKeyboardCategory.getPreferenceCount(); i-- > 0; ) {
477e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                final Preference pref = mHardKeyboardCategory.getPreference(i);
478e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                if (pref.getOrder() < 1000) {
479e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                    mHardKeyboardCategory.removePreference(pref);
480e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                }
481e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            }
4823fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
483e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            Collections.sort(mHardKeyboardPreferenceList);
484e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            final int count = mHardKeyboardPreferenceList.size();
485e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            for (int i = 0; i < count; i++) {
486e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                final Preference pref = mHardKeyboardPreferenceList.get(i);
487e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                pref.setOrder(i);
488e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown                mHardKeyboardCategory.addPreference(pref);
489e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            }
49096cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown
49196cdcd80a8ba9d9a808a712037c3e4fa3fdcf084Jeff Brown            getPreferenceScreen().addPreference(mHardKeyboardCategory);
492e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown        } else {
493e46c5f30caddb10c69eee62fc2f9db3f26f29bb5Jeff Brown            getPreferenceScreen().removePreference(mHardKeyboardCategory);
4943fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
4953fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
496b9509d046c911b7b334aa45f693c49a7182ef470satok
497766b286187d02b3da6e0142376a4478072f30a16Jeff Brown    private void showKeyboardLayoutDialog(String inputDeviceDescriptor) {
498766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        KeyboardLayoutDialogFragment fragment =
499766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                new KeyboardLayoutDialogFragment(inputDeviceDescriptor);
500766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        fragment.setTargetFragment(this, 0);
501766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        fragment.show(getActivity().getFragmentManager(), "keyboardLayout");
502766b286187d02b3da6e0142376a4478072f30a16Jeff Brown    }
503766b286187d02b3da6e0142376a4478072f30a16Jeff Brown
504766b286187d02b3da6e0142376a4478072f30a16Jeff Brown    @Override
505766b286187d02b3da6e0142376a4478072f30a16Jeff Brown    public void onSetupKeyboardLayouts(String inputDeviceDescriptor) {
506766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        final Intent intent = new Intent(Intent.ACTION_MAIN);
507766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        intent.setClass(getActivity(), KeyboardLayoutPickerActivity.class);
508766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        intent.putExtra(KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_DESCRIPTOR,
509766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                inputDeviceDescriptor);
510766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        mIntentWaitingForResult = intent;
511766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        startActivityForResult(intent, 0);
512766b286187d02b3da6e0142376a4478072f30a16Jeff Brown    }
513766b286187d02b3da6e0142376a4478072f30a16Jeff Brown
514766b286187d02b3da6e0142376a4478072f30a16Jeff Brown    @Override
515766b286187d02b3da6e0142376a4478072f30a16Jeff Brown    public void onActivityResult(int requestCode, int resultCode, Intent data) {
516766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        super.onActivityResult(requestCode, resultCode, data);
517766b286187d02b3da6e0142376a4478072f30a16Jeff Brown
518766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        if (mIntentWaitingForResult != null) {
519766b286187d02b3da6e0142376a4478072f30a16Jeff Brown            String inputDeviceDescriptor = mIntentWaitingForResult.getStringExtra(
520766b286187d02b3da6e0142376a4478072f30a16Jeff Brown                    KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_DESCRIPTOR);
521766b286187d02b3da6e0142376a4478072f30a16Jeff Brown            mIntentWaitingForResult = null;
522766b286187d02b3da6e0142376a4478072f30a16Jeff Brown            showKeyboardLayoutDialog(inputDeviceDescriptor);
523766b286187d02b3da6e0142376a4478072f30a16Jeff Brown        }
524766b286187d02b3da6e0142376a4478072f30a16Jeff Brown    }
525766b286187d02b3da6e0142376a4478072f30a16Jeff Brown
526f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown    private void updateGameControllers() {
527f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        if (haveInputDeviceWithVibrator()) {
528f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown            getPreferenceScreen().addPreference(mGameControllerCategory);
529f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown
530f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown            CheckBoxPreference chkPref = (CheckBoxPreference)
531f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown                    mGameControllerCategory.findPreference("vibrate_input_devices");
532f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown            chkPref.setChecked(System.getInt(getContentResolver(),
533f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown                    Settings.System.VIBRATE_INPUT_DEVICES, 1) > 0);
534f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        } else {
535f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown            getPreferenceScreen().removePreference(mGameControllerCategory);
536f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        }
537f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown    }
538f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown
539f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown    private boolean haveInputDeviceWithVibrator() {
540f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        final int[] devices = InputDevice.getDeviceIds();
541f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        for (int i = 0; i < devices.length; i++) {
542f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown            InputDevice device = InputDevice.getDevice(devices[i]);
543f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown            if (device != null && !device.isVirtual() && device.getVibrator().hasVibrator()) {
544f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown                return true;
545f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown            }
546f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        }
547f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown        return false;
548f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown    }
549f8fb0e5b240b1e954660b8221eaa9a18a310a1dfJeff Brown
550b9509d046c911b7b334aa45f693c49a7182ef470satok    private class SettingsObserver extends ContentObserver {
5519bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov        private Context mContext;
5529bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov
553b9509d046c911b7b334aa45f693c49a7182ef470satok        public SettingsObserver(Handler handler, Context context) {
554b9509d046c911b7b334aa45f693c49a7182ef470satok            super(handler);
5559bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov            mContext = context;
5569bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov        }
5579bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov
5589bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov        @Override public void onChange(boolean selfChange) {
5599bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov            updateCurrentImeName();
5609bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov        }
5619bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov
5629bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov        public void resume() {
5639bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov            final ContentResolver cr = mContext.getContentResolver();
564b9509d046c911b7b334aa45f693c49a7182ef470satok            cr.registerContentObserver(
565b9509d046c911b7b334aa45f693c49a7182ef470satok                    Settings.Secure.getUriFor(Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
566b9509d046c911b7b334aa45f693c49a7182ef470satok            cr.registerContentObserver(Settings.Secure.getUriFor(
567b9509d046c911b7b334aa45f693c49a7182ef470satok                    Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, this);
568b9509d046c911b7b334aa45f693c49a7182ef470satok        }
569b9509d046c911b7b334aa45f693c49a7182ef470satok
5709bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov        public void pause() {
5719bcc60704991879a0f8c9098eef26233942d6fe2Shuhrat Dehkanov            mContext.getContentResolver().unregisterContentObserver(this);
572b9509d046c911b7b334aa45f693c49a7182ef470satok        }
573b9509d046c911b7b334aa45f693c49a7182ef470satok    }
574afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
575