InputMethodAndSubtypeEnabler.java revision 4a5f889f80b683446e498f244d0eadfd979ca5d0
14a5f889f80b683446e498f244d0eadfd979ca5d0satok/* 24a5f889f80b683446e498f244d0eadfd979ca5d0satok * Copyright (C) 2010 The Android Open Source Project 34a5f889f80b683446e498f244d0eadfd979ca5d0satok * 44a5f889f80b683446e498f244d0eadfd979ca5d0satok * Licensed under the Apache License, Version 2.0 (the "License"); 54a5f889f80b683446e498f244d0eadfd979ca5d0satok * you may not use this file except in compliance with the License. 64a5f889f80b683446e498f244d0eadfd979ca5d0satok * You may obtain a copy of the License at 74a5f889f80b683446e498f244d0eadfd979ca5d0satok * 84a5f889f80b683446e498f244d0eadfd979ca5d0satok * http://www.apache.org/licenses/LICENSE-2.0 94a5f889f80b683446e498f244d0eadfd979ca5d0satok * 104a5f889f80b683446e498f244d0eadfd979ca5d0satok * Unless required by applicable law or agreed to in writing, software 114a5f889f80b683446e498f244d0eadfd979ca5d0satok * distributed under the License is distributed on an "AS IS" BASIS, 124a5f889f80b683446e498f244d0eadfd979ca5d0satok * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134a5f889f80b683446e498f244d0eadfd979ca5d0satok * See the License for the specific language governing permissions and 144a5f889f80b683446e498f244d0eadfd979ca5d0satok * limitations under the License. 154a5f889f80b683446e498f244d0eadfd979ca5d0satok */ 164a5f889f80b683446e498f244d0eadfd979ca5d0satok 174a5f889f80b683446e498f244d0eadfd979ca5d0satokpackage com.android.settings; 184a5f889f80b683446e498f244d0eadfd979ca5d0satok 194a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.app.AlertDialog; 204a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.content.Context; 214a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.content.DialogInterface; 224a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.content.pm.ApplicationInfo; 234a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.content.pm.PackageManager; 244a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.content.res.Configuration; 254a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.os.Bundle; 264a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.preference.CheckBoxPreference; 274a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.preference.Preference; 284a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.preference.PreferenceActivity; 294a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.preference.PreferenceCategory; 304a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.preference.PreferenceScreen; 314a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.provider.Settings; 324a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.text.TextUtils; 334a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.view.inputmethod.InputMethodInfo; 344a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.view.inputmethod.InputMethodManager; 354a5f889f80b683446e498f244d0eadfd979ca5d0satokimport android.view.inputmethod.InputMethodSubtype; 364a5f889f80b683446e498f244d0eadfd979ca5d0satok 374a5f889f80b683446e498f244d0eadfd979ca5d0satokimport java.util.ArrayList; 384a5f889f80b683446e498f244d0eadfd979ca5d0satokimport java.util.HashSet; 394a5f889f80b683446e498f244d0eadfd979ca5d0satokimport java.util.List; 404a5f889f80b683446e498f244d0eadfd979ca5d0satok 414a5f889f80b683446e498f244d0eadfd979ca5d0satokpublic class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment { 424a5f889f80b683446e498f244d0eadfd979ca5d0satok 434a5f889f80b683446e498f244d0eadfd979ca5d0satok private boolean mHaveHardKeyboard; 444a5f889f80b683446e498f244d0eadfd979ca5d0satok 454a5f889f80b683446e498f244d0eadfd979ca5d0satok private List<InputMethodInfo> mInputMethodProperties; 464a5f889f80b683446e498f244d0eadfd979ca5d0satok 474a5f889f80b683446e498f244d0eadfd979ca5d0satok private final TextUtils.SimpleStringSplitter mStringColonSplitter 484a5f889f80b683446e498f244d0eadfd979ca5d0satok = new TextUtils.SimpleStringSplitter(':'); 494a5f889f80b683446e498f244d0eadfd979ca5d0satok 504a5f889f80b683446e498f244d0eadfd979ca5d0satok private String mLastInputMethodId; 514a5f889f80b683446e498f244d0eadfd979ca5d0satok private String mLastTickedInputMethodId; 524a5f889f80b683446e498f244d0eadfd979ca5d0satok 534a5f889f80b683446e498f244d0eadfd979ca5d0satok private AlertDialog mDialog = null; 544a5f889f80b683446e498f244d0eadfd979ca5d0satok 554a5f889f80b683446e498f244d0eadfd979ca5d0satok @Override 564a5f889f80b683446e498f244d0eadfd979ca5d0satok public void onCreate(Bundle icicle) { 574a5f889f80b683446e498f244d0eadfd979ca5d0satok super.onCreate(icicle); 584a5f889f80b683446e498f244d0eadfd979ca5d0satok Configuration config = getResources().getConfiguration(); 594a5f889f80b683446e498f244d0eadfd979ca5d0satok mHaveHardKeyboard = (config.keyboard == Configuration.KEYBOARD_QWERTY); 604a5f889f80b683446e498f244d0eadfd979ca5d0satok onCreateIMM(); 614a5f889f80b683446e498f244d0eadfd979ca5d0satok setPreferenceScreen(createPreferenceHierarchy()); 624a5f889f80b683446e498f244d0eadfd979ca5d0satok } 634a5f889f80b683446e498f244d0eadfd979ca5d0satok 644a5f889f80b683446e498f244d0eadfd979ca5d0satok @Override 654a5f889f80b683446e498f244d0eadfd979ca5d0satok public void onResume() { 664a5f889f80b683446e498f244d0eadfd979ca5d0satok super.onResume(); 674a5f889f80b683446e498f244d0eadfd979ca5d0satok loadInputMethodSubtypeList(); 684a5f889f80b683446e498f244d0eadfd979ca5d0satok } 694a5f889f80b683446e498f244d0eadfd979ca5d0satok 704a5f889f80b683446e498f244d0eadfd979ca5d0satok @Override 714a5f889f80b683446e498f244d0eadfd979ca5d0satok public void onPause() { 724a5f889f80b683446e498f244d0eadfd979ca5d0satok super.onPause(); 734a5f889f80b683446e498f244d0eadfd979ca5d0satok saveInputMethodSubtypeList(); 744a5f889f80b683446e498f244d0eadfd979ca5d0satok } 754a5f889f80b683446e498f244d0eadfd979ca5d0satok 764a5f889f80b683446e498f244d0eadfd979ca5d0satok @Override 774a5f889f80b683446e498f244d0eadfd979ca5d0satok public boolean onPreferenceTreeClick( 784a5f889f80b683446e498f244d0eadfd979ca5d0satok PreferenceScreen preferenceScreen, Preference preference) { 794a5f889f80b683446e498f244d0eadfd979ca5d0satok 804a5f889f80b683446e498f244d0eadfd979ca5d0satok if (preference instanceof CheckBoxPreference) { 814a5f889f80b683446e498f244d0eadfd979ca5d0satok final CheckBoxPreference chkPref = (CheckBoxPreference) preference; 824a5f889f80b683446e498f244d0eadfd979ca5d0satok final String id = chkPref.getKey(); 834a5f889f80b683446e498f244d0eadfd979ca5d0satok // TODO: Check subtype or not here 844a5f889f80b683446e498f244d0eadfd979ca5d0satok if (chkPref.isChecked()) { 854a5f889f80b683446e498f244d0eadfd979ca5d0satok InputMethodInfo selImi = null; 864a5f889f80b683446e498f244d0eadfd979ca5d0satok final int N = mInputMethodProperties.size(); 874a5f889f80b683446e498f244d0eadfd979ca5d0satok for (int i = 0; i < N; i++) { 884a5f889f80b683446e498f244d0eadfd979ca5d0satok InputMethodInfo imi = mInputMethodProperties.get(i); 894a5f889f80b683446e498f244d0eadfd979ca5d0satok if (id.equals(imi.getId())) { 904a5f889f80b683446e498f244d0eadfd979ca5d0satok selImi = imi; 914a5f889f80b683446e498f244d0eadfd979ca5d0satok if (isSystemIme(imi)) { 924a5f889f80b683446e498f244d0eadfd979ca5d0satok setSubtypesPreferenceEnabled(id, true); 934a5f889f80b683446e498f244d0eadfd979ca5d0satok // This is a built-in IME, so no need to warn. 944a5f889f80b683446e498f244d0eadfd979ca5d0satok mLastTickedInputMethodId = id; 954a5f889f80b683446e498f244d0eadfd979ca5d0satok return super.onPreferenceTreeClick(preferenceScreen, preference); 964a5f889f80b683446e498f244d0eadfd979ca5d0satok } 974a5f889f80b683446e498f244d0eadfd979ca5d0satok break; 984a5f889f80b683446e498f244d0eadfd979ca5d0satok } 994a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1004a5f889f80b683446e498f244d0eadfd979ca5d0satok if (selImi == null) { 1014a5f889f80b683446e498f244d0eadfd979ca5d0satok return super.onPreferenceTreeClick(preferenceScreen, preference); 1024a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1034a5f889f80b683446e498f244d0eadfd979ca5d0satok chkPref.setChecked(false); 1044a5f889f80b683446e498f244d0eadfd979ca5d0satok if (mDialog == null) { 1054a5f889f80b683446e498f244d0eadfd979ca5d0satok mDialog = (new AlertDialog.Builder(getActivity())) 1064a5f889f80b683446e498f244d0eadfd979ca5d0satok .setTitle(android.R.string.dialog_alert_title) 1074a5f889f80b683446e498f244d0eadfd979ca5d0satok .setIcon(android.R.drawable.ic_dialog_alert) 1084a5f889f80b683446e498f244d0eadfd979ca5d0satok .setCancelable(true) 1094a5f889f80b683446e498f244d0eadfd979ca5d0satok .setPositiveButton(android.R.string.ok, 1104a5f889f80b683446e498f244d0eadfd979ca5d0satok new DialogInterface.OnClickListener() { 1114a5f889f80b683446e498f244d0eadfd979ca5d0satok public void onClick(DialogInterface dialog, int which) { 1124a5f889f80b683446e498f244d0eadfd979ca5d0satok chkPref.setChecked(true); 1134a5f889f80b683446e498f244d0eadfd979ca5d0satok setSubtypesPreferenceEnabled(id, true); 1144a5f889f80b683446e498f244d0eadfd979ca5d0satok mLastTickedInputMethodId = id; 1154a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1164a5f889f80b683446e498f244d0eadfd979ca5d0satok 1174a5f889f80b683446e498f244d0eadfd979ca5d0satok }) 1184a5f889f80b683446e498f244d0eadfd979ca5d0satok .setNegativeButton(android.R.string.cancel, 1194a5f889f80b683446e498f244d0eadfd979ca5d0satok new DialogInterface.OnClickListener() { 1204a5f889f80b683446e498f244d0eadfd979ca5d0satok public void onClick(DialogInterface dialog, int which) { 1214a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1224a5f889f80b683446e498f244d0eadfd979ca5d0satok 1234a5f889f80b683446e498f244d0eadfd979ca5d0satok }) 1244a5f889f80b683446e498f244d0eadfd979ca5d0satok .create(); 1254a5f889f80b683446e498f244d0eadfd979ca5d0satok } else { 1264a5f889f80b683446e498f244d0eadfd979ca5d0satok if (mDialog.isShowing()) { 1274a5f889f80b683446e498f244d0eadfd979ca5d0satok mDialog.dismiss(); 1284a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1294a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1304a5f889f80b683446e498f244d0eadfd979ca5d0satok mDialog.setMessage(getResources().getString( 1314a5f889f80b683446e498f244d0eadfd979ca5d0satok R.string.ime_security_warning, 1324a5f889f80b683446e498f244d0eadfd979ca5d0satok selImi.getServiceInfo().applicationInfo.loadLabel(getPackageManager()))); 1334a5f889f80b683446e498f244d0eadfd979ca5d0satok mDialog.show(); 1344a5f889f80b683446e498f244d0eadfd979ca5d0satok } else { 1354a5f889f80b683446e498f244d0eadfd979ca5d0satok if (id.equals(mLastTickedInputMethodId)) { 1364a5f889f80b683446e498f244d0eadfd979ca5d0satok mLastTickedInputMethodId = null; 1374a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1384a5f889f80b683446e498f244d0eadfd979ca5d0satok setSubtypesPreferenceEnabled(id, false); 1394a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1404a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1414a5f889f80b683446e498f244d0eadfd979ca5d0satok return super.onPreferenceTreeClick(preferenceScreen, preference); 1424a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1434a5f889f80b683446e498f244d0eadfd979ca5d0satok 1444a5f889f80b683446e498f244d0eadfd979ca5d0satok @Override 1454a5f889f80b683446e498f244d0eadfd979ca5d0satok public void onDestroy() { 1464a5f889f80b683446e498f244d0eadfd979ca5d0satok super.onDestroy(); 1474a5f889f80b683446e498f244d0eadfd979ca5d0satok if (mDialog != null) { 1484a5f889f80b683446e498f244d0eadfd979ca5d0satok mDialog.dismiss(); 1494a5f889f80b683446e498f244d0eadfd979ca5d0satok mDialog = null; 1504a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1514a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1524a5f889f80b683446e498f244d0eadfd979ca5d0satok 1534a5f889f80b683446e498f244d0eadfd979ca5d0satok private void onCreateIMM() { 1544a5f889f80b683446e498f244d0eadfd979ca5d0satok InputMethodManager imm = (InputMethodManager) getSystemService( 1554a5f889f80b683446e498f244d0eadfd979ca5d0satok Context.INPUT_METHOD_SERVICE); 1564a5f889f80b683446e498f244d0eadfd979ca5d0satok 1574a5f889f80b683446e498f244d0eadfd979ca5d0satok // TODO: Change mInputMethodProperties to Map 1584a5f889f80b683446e498f244d0eadfd979ca5d0satok mInputMethodProperties = imm.getInputMethodList(); 1594a5f889f80b683446e498f244d0eadfd979ca5d0satok 1604a5f889f80b683446e498f244d0eadfd979ca5d0satok mLastInputMethodId = Settings.Secure.getString(getContentResolver(), 1614a5f889f80b683446e498f244d0eadfd979ca5d0satok Settings.Secure.DEFAULT_INPUT_METHOD); 1624a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1634a5f889f80b683446e498f244d0eadfd979ca5d0satok 1644a5f889f80b683446e498f244d0eadfd979ca5d0satok private PreferenceScreen createPreferenceHierarchy() { 1654a5f889f80b683446e498f244d0eadfd979ca5d0satok // Root 1664a5f889f80b683446e498f244d0eadfd979ca5d0satok PreferenceScreen root = getPreferenceManager().createPreferenceScreen(getActivity()); 1674a5f889f80b683446e498f244d0eadfd979ca5d0satok 1684a5f889f80b683446e498f244d0eadfd979ca5d0satok int N = (mInputMethodProperties == null ? 0 : mInputMethodProperties.size()); 1694a5f889f80b683446e498f244d0eadfd979ca5d0satok // TODO: Use iterator. 1704a5f889f80b683446e498f244d0eadfd979ca5d0satok for (int i = 0; i < N; ++i) { 1714a5f889f80b683446e498f244d0eadfd979ca5d0satok PreferenceCategory keyboardSettingsCategory = new PreferenceCategory(getActivity()); 1724a5f889f80b683446e498f244d0eadfd979ca5d0satok root.addPreference(keyboardSettingsCategory); 1734a5f889f80b683446e498f244d0eadfd979ca5d0satok InputMethodInfo property = mInputMethodProperties.get(i); 1744a5f889f80b683446e498f244d0eadfd979ca5d0satok String prefKey = property.getId(); 1754a5f889f80b683446e498f244d0eadfd979ca5d0satok 1764a5f889f80b683446e498f244d0eadfd979ca5d0satok PackageManager pm = getPackageManager(); 1774a5f889f80b683446e498f244d0eadfd979ca5d0satok CharSequence label = property.loadLabel(pm); 1784a5f889f80b683446e498f244d0eadfd979ca5d0satok boolean systemIME = isSystemIme(property); 1794a5f889f80b683446e498f244d0eadfd979ca5d0satok 1804a5f889f80b683446e498f244d0eadfd979ca5d0satok keyboardSettingsCategory.setTitle(label); 1814a5f889f80b683446e498f244d0eadfd979ca5d0satok 1824a5f889f80b683446e498f244d0eadfd979ca5d0satok // Add a check box. 1834a5f889f80b683446e498f244d0eadfd979ca5d0satok // Don't show the toggle if it's the only keyboard in the system, or it's a system IME. 1844a5f889f80b683446e498f244d0eadfd979ca5d0satok if (mHaveHardKeyboard || (N > 1 && !systemIME)) { 1854a5f889f80b683446e498f244d0eadfd979ca5d0satok CheckBoxPreference chkbxPref = new CheckBoxPreference(getActivity()); 1864a5f889f80b683446e498f244d0eadfd979ca5d0satok chkbxPref.setKey(prefKey); 1874a5f889f80b683446e498f244d0eadfd979ca5d0satok chkbxPref.setTitle(label); 1884a5f889f80b683446e498f244d0eadfd979ca5d0satok keyboardSettingsCategory.addPreference(chkbxPref); 1894a5f889f80b683446e498f244d0eadfd979ca5d0satok } 1904a5f889f80b683446e498f244d0eadfd979ca5d0satok 1914a5f889f80b683446e498f244d0eadfd979ca5d0satok ArrayList<InputMethodSubtype> subtypes = property.getSubtypes(); 1924a5f889f80b683446e498f244d0eadfd979ca5d0satok if (subtypes.size() > 0) { 1934a5f889f80b683446e498f244d0eadfd979ca5d0satok PreferenceCategory subtypesCategory = new PreferenceCategory(getActivity()); 1944a5f889f80b683446e498f244d0eadfd979ca5d0satok subtypesCategory.setTitle(getResources().getString( 1954a5f889f80b683446e498f244d0eadfd979ca5d0satok R.string.input_methods_and_subtype_enabler_title_format, label)); 1964a5f889f80b683446e498f244d0eadfd979ca5d0satok root.addPreference(subtypesCategory); 1974a5f889f80b683446e498f244d0eadfd979ca5d0satok for (InputMethodSubtype subtype: subtypes) { 1984a5f889f80b683446e498f244d0eadfd979ca5d0satok CharSequence subtypeLabel; 1994a5f889f80b683446e498f244d0eadfd979ca5d0satok int nameResId = subtype.getNameResId(); 2004a5f889f80b683446e498f244d0eadfd979ca5d0satok if (nameResId != 0) { 2014a5f889f80b683446e498f244d0eadfd979ca5d0satok subtypeLabel = pm.getText(property.getPackageName(), nameResId, 2024a5f889f80b683446e498f244d0eadfd979ca5d0satok property.getServiceInfo().applicationInfo); 2034a5f889f80b683446e498f244d0eadfd979ca5d0satok } else { 2044a5f889f80b683446e498f244d0eadfd979ca5d0satok int modeResId = subtype.getModeResId(); 2054a5f889f80b683446e498f244d0eadfd979ca5d0satok CharSequence language = subtype.getLocale(); 2064a5f889f80b683446e498f244d0eadfd979ca5d0satok CharSequence mode = modeResId == 0 ? null 2074a5f889f80b683446e498f244d0eadfd979ca5d0satok : pm.getText(property.getPackageName(), modeResId, 2084a5f889f80b683446e498f244d0eadfd979ca5d0satok property.getServiceInfo().applicationInfo); 2094a5f889f80b683446e498f244d0eadfd979ca5d0satok // TODO: Use more friendly Title and UI 2104a5f889f80b683446e498f244d0eadfd979ca5d0satok subtypeLabel = (mode == null ? "" : mode) + "," 2114a5f889f80b683446e498f244d0eadfd979ca5d0satok + (language == null ? "" : language); 2124a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2134a5f889f80b683446e498f244d0eadfd979ca5d0satok CheckBoxPreference chkbxPref = new CheckBoxPreference(getActivity()); 2144a5f889f80b683446e498f244d0eadfd979ca5d0satok chkbxPref.setKey(prefKey + subtype.hashCode()); 2154a5f889f80b683446e498f244d0eadfd979ca5d0satok chkbxPref.setTitle(subtypeLabel); 2164a5f889f80b683446e498f244d0eadfd979ca5d0satok chkbxPref.setSummary(label); 2174a5f889f80b683446e498f244d0eadfd979ca5d0satok subtypesCategory.addPreference(chkbxPref); 2184a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2194a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2204a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2214a5f889f80b683446e498f244d0eadfd979ca5d0satok return root; 2224a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2234a5f889f80b683446e498f244d0eadfd979ca5d0satok 2244a5f889f80b683446e498f244d0eadfd979ca5d0satok private void loadInputMethodSubtypeList() { 2254a5f889f80b683446e498f244d0eadfd979ca5d0satok final HashSet<String> enabled = new HashSet<String>(); 2264a5f889f80b683446e498f244d0eadfd979ca5d0satok String enabledStr = Settings.Secure.getString(getContentResolver(), 2274a5f889f80b683446e498f244d0eadfd979ca5d0satok Settings.Secure.ENABLED_INPUT_METHODS); 2284a5f889f80b683446e498f244d0eadfd979ca5d0satok if (enabledStr != null) { 2294a5f889f80b683446e498f244d0eadfd979ca5d0satok final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter; 2304a5f889f80b683446e498f244d0eadfd979ca5d0satok splitter.setString(enabledStr); 2314a5f889f80b683446e498f244d0eadfd979ca5d0satok while (splitter.hasNext()) { 2324a5f889f80b683446e498f244d0eadfd979ca5d0satok enabled.add(splitter.next()); 2334a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2344a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2354a5f889f80b683446e498f244d0eadfd979ca5d0satok 2364a5f889f80b683446e498f244d0eadfd979ca5d0satok // Update the statuses of the Check Boxes. 2374a5f889f80b683446e498f244d0eadfd979ca5d0satok int N = mInputMethodProperties.size(); 2384a5f889f80b683446e498f244d0eadfd979ca5d0satok // TODO: Use iterator. 2394a5f889f80b683446e498f244d0eadfd979ca5d0satok for (int i = 0; i < N; ++i) { 2404a5f889f80b683446e498f244d0eadfd979ca5d0satok final String id = mInputMethodProperties.get(i).getId(); 2414a5f889f80b683446e498f244d0eadfd979ca5d0satok CheckBoxPreference pref = (CheckBoxPreference) findPreference( 2424a5f889f80b683446e498f244d0eadfd979ca5d0satok mInputMethodProperties.get(i).getId()); 2434a5f889f80b683446e498f244d0eadfd979ca5d0satok if (pref != null) { 2444a5f889f80b683446e498f244d0eadfd979ca5d0satok boolean isEnabled = enabled.contains(id); 2454a5f889f80b683446e498f244d0eadfd979ca5d0satok pref.setChecked(isEnabled); 2464a5f889f80b683446e498f244d0eadfd979ca5d0satok setSubtypesPreferenceEnabled(id, isEnabled); 2474a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2484a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2494a5f889f80b683446e498f244d0eadfd979ca5d0satok mLastTickedInputMethodId = null; 2504a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2514a5f889f80b683446e498f244d0eadfd979ca5d0satok 2524a5f889f80b683446e498f244d0eadfd979ca5d0satok private void saveInputMethodSubtypeList() { 2534a5f889f80b683446e498f244d0eadfd979ca5d0satok StringBuilder builder = new StringBuilder(); 2544a5f889f80b683446e498f244d0eadfd979ca5d0satok StringBuilder disabledSysImes = new StringBuilder(); 2554a5f889f80b683446e498f244d0eadfd979ca5d0satok 2564a5f889f80b683446e498f244d0eadfd979ca5d0satok int firstEnabled = -1; 2574a5f889f80b683446e498f244d0eadfd979ca5d0satok int N = mInputMethodProperties.size(); 2584a5f889f80b683446e498f244d0eadfd979ca5d0satok for (int i = 0; i < N; ++i) { 2594a5f889f80b683446e498f244d0eadfd979ca5d0satok final InputMethodInfo property = mInputMethodProperties.get(i); 2604a5f889f80b683446e498f244d0eadfd979ca5d0satok final String id = property.getId(); 2614a5f889f80b683446e498f244d0eadfd979ca5d0satok CheckBoxPreference pref = (CheckBoxPreference) findPreference(id); 2624a5f889f80b683446e498f244d0eadfd979ca5d0satok boolean currentInputMethod = id.equals(mLastInputMethodId); 2634a5f889f80b683446e498f244d0eadfd979ca5d0satok boolean systemIme = isSystemIme(property); 2644a5f889f80b683446e498f244d0eadfd979ca5d0satok // TODO: Append subtypes by using the separator ";" 2654a5f889f80b683446e498f244d0eadfd979ca5d0satok if (((N == 1 || systemIme) && !mHaveHardKeyboard) 2664a5f889f80b683446e498f244d0eadfd979ca5d0satok || (pref != null && pref.isChecked())) { 2674a5f889f80b683446e498f244d0eadfd979ca5d0satok if (builder.length() > 0) builder.append(':'); 2684a5f889f80b683446e498f244d0eadfd979ca5d0satok builder.append(id); 2694a5f889f80b683446e498f244d0eadfd979ca5d0satok if (firstEnabled < 0) { 2704a5f889f80b683446e498f244d0eadfd979ca5d0satok firstEnabled = i; 2714a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2724a5f889f80b683446e498f244d0eadfd979ca5d0satok } else if (currentInputMethod) { 2734a5f889f80b683446e498f244d0eadfd979ca5d0satok mLastInputMethodId = mLastTickedInputMethodId; 2744a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2754a5f889f80b683446e498f244d0eadfd979ca5d0satok // If it's a disabled system ime, add it to the disabled list so that it 2764a5f889f80b683446e498f244d0eadfd979ca5d0satok // doesn't get enabled automatically on any changes to the package list 2774a5f889f80b683446e498f244d0eadfd979ca5d0satok if (pref != null && !pref.isChecked() && systemIme && mHaveHardKeyboard) { 2784a5f889f80b683446e498f244d0eadfd979ca5d0satok if (disabledSysImes.length() > 0) disabledSysImes.append(":"); 2794a5f889f80b683446e498f244d0eadfd979ca5d0satok disabledSysImes.append(id); 2804a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2814a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2824a5f889f80b683446e498f244d0eadfd979ca5d0satok 2834a5f889f80b683446e498f244d0eadfd979ca5d0satok // If the last input method is unset, set it as the first enabled one. 2844a5f889f80b683446e498f244d0eadfd979ca5d0satok if (TextUtils.isEmpty(mLastInputMethodId)) { 2854a5f889f80b683446e498f244d0eadfd979ca5d0satok if (firstEnabled >= 0) { 2864a5f889f80b683446e498f244d0eadfd979ca5d0satok mLastInputMethodId = mInputMethodProperties.get(firstEnabled).getId(); 2874a5f889f80b683446e498f244d0eadfd979ca5d0satok } else { 2884a5f889f80b683446e498f244d0eadfd979ca5d0satok mLastInputMethodId = null; 2894a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2904a5f889f80b683446e498f244d0eadfd979ca5d0satok } 2914a5f889f80b683446e498f244d0eadfd979ca5d0satok 2924a5f889f80b683446e498f244d0eadfd979ca5d0satok Settings.Secure.putString(getContentResolver(), 2934a5f889f80b683446e498f244d0eadfd979ca5d0satok Settings.Secure.ENABLED_INPUT_METHODS, builder.toString()); 2944a5f889f80b683446e498f244d0eadfd979ca5d0satok Settings.Secure.putString(getContentResolver(), 2954a5f889f80b683446e498f244d0eadfd979ca5d0satok Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS, disabledSysImes.toString()); 2964a5f889f80b683446e498f244d0eadfd979ca5d0satok Settings.Secure.putString(getContentResolver(), 2974a5f889f80b683446e498f244d0eadfd979ca5d0satok Settings.Secure.DEFAULT_INPUT_METHOD, 2984a5f889f80b683446e498f244d0eadfd979ca5d0satok mLastInputMethodId != null ? mLastInputMethodId : ""); 2994a5f889f80b683446e498f244d0eadfd979ca5d0satok } 3004a5f889f80b683446e498f244d0eadfd979ca5d0satok 3014a5f889f80b683446e498f244d0eadfd979ca5d0satok private void setSubtypesPreferenceEnabled(String id, boolean enabled) { 3024a5f889f80b683446e498f244d0eadfd979ca5d0satok PreferenceScreen preferenceScreen = getPreferenceScreen(); 3034a5f889f80b683446e498f244d0eadfd979ca5d0satok final int N = mInputMethodProperties.size(); 3044a5f889f80b683446e498f244d0eadfd979ca5d0satok // TODO: Use iterator. 3054a5f889f80b683446e498f244d0eadfd979ca5d0satok for (int i = 0; i < N; i++) { 3064a5f889f80b683446e498f244d0eadfd979ca5d0satok InputMethodInfo imi = mInputMethodProperties.get(i); 3074a5f889f80b683446e498f244d0eadfd979ca5d0satok if (id.equals(imi.getId())) { 3084a5f889f80b683446e498f244d0eadfd979ca5d0satok for (InputMethodSubtype subtype: imi.getSubtypes()) { 3094a5f889f80b683446e498f244d0eadfd979ca5d0satok preferenceScreen.findPreference(id + subtype.hashCode()).setEnabled(enabled); 3104a5f889f80b683446e498f244d0eadfd979ca5d0satok } 3114a5f889f80b683446e498f244d0eadfd979ca5d0satok } 3124a5f889f80b683446e498f244d0eadfd979ca5d0satok } 3134a5f889f80b683446e498f244d0eadfd979ca5d0satok } 3144a5f889f80b683446e498f244d0eadfd979ca5d0satok 3154a5f889f80b683446e498f244d0eadfd979ca5d0satok private boolean isSystemIme(InputMethodInfo property) { 3164a5f889f80b683446e498f244d0eadfd979ca5d0satok return (property.getServiceInfo().applicationInfo.flags 3174a5f889f80b683446e498f244d0eadfd979ca5d0satok & ApplicationInfo.FLAG_SYSTEM) != 0; 3184a5f889f80b683446e498f244d0eadfd979ca5d0satok } 3194a5f889f80b683446e498f244d0eadfd979ca5d0satok} 320