diff --git a/AndroidManifest.xml b/AndroidManifest.xml index eff03972acd..4366b0b876c 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -573,14 +573,10 @@ - - - - + android:label="@string/language_keyboard_settings_title" + android:icon="@drawable/ic_settings_language" + android:taskAffinity="com.android.settings" + android:parentActivityName="Settings"> @@ -597,6 +593,16 @@ android:value="true" /> + + + + + + + + Failed to open settings for %1$s + + Keyboard and input methods + + Virtual keyboard + + Physical keyboard + + Available virtual keyboard + + Add a virtual keyboard + + Keyboard assistance + + Show virtual keyboard + + Keep it on screen while physical keyboard is active + + Keyboard shortcuts helper + Mouse/trackpad diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml index 83a0985bc90..9cc01456b1d 100644 --- a/res/xml/language_settings.xml +++ b/res/xml/language_settings.xml @@ -41,23 +41,34 @@ /> - + android:title="@string/keyboard_and_input_methods_category"> - + android:title="@string/virtual_keyboard_category" + android:fragment="com.android.settings.inputmethod.VirtualKeyboardFragment" /> + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/xml/virtual_keyboard_settings.xml b/res/xml/virtual_keyboard_settings.xml new file mode 100644 index 00000000000..e5a5f388e09 --- /dev/null +++ b/res/xml/virtual_keyboard_settings.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/src/com/android/settings/InstrumentedFragment.java b/src/com/android/settings/InstrumentedFragment.java index bb2f948105f..ea39cf3e8d7 100644 --- a/src/com/android/settings/InstrumentedFragment.java +++ b/src/com/android/settings/InstrumentedFragment.java @@ -38,6 +38,9 @@ public abstract class InstrumentedFragment extends PreferenceFragment { public static final int BILLING_CYCLE = UNDECLARED + 8; public static final int APP_DATA_USAGE = UNDECLARED + 9; public static final int USER_LOCALE_LIST = UNDECLARED + 10; + public static final int VIRTUAL_KEYBOARDS = UNDECLARED + 11; + public static final int PHYSICAL_KEYBOARDS = UNDECLARED + 12; + public static final int ENABLE_VIRTUAL_KEYBOARDS = UNDECLARED + 13; /** * Declare the view of this category. diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index edd0b4ccd2a..1c636b8d807 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -39,6 +39,7 @@ public class Settings extends SettingsActivity { public static class WifiSettingsActivity extends SettingsActivity { /* empty */ } public static class WifiP2pSettingsActivity extends SettingsActivity { /* empty */ } public static class InputMethodAndLanguageSettingsActivity extends SettingsActivity { /* empty */ } + public static class AvailableVirtualKeyboardActivity extends SettingsActivity { /* empty */ } public static class KeyboardLayoutPickerActivity extends SettingsActivity { /* empty */ } public static class InputMethodAndSubtypeEnablerActivity extends SettingsActivity { /* empty */ } public static class SpellCheckersSettingsActivity extends SettingsActivity { /* empty */ } diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 403e760fa48..dc134ff4a32 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -77,6 +77,7 @@ import com.android.settings.deviceinfo.StorageSettings; import com.android.settings.fuelgauge.BatterySaverSettings; import com.android.settings.fuelgauge.PowerUsageDetail; import com.android.settings.fuelgauge.PowerUsageSummary; +import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment; import com.android.settings.inputmethod.InputMethodAndLanguageSettings; import com.android.settings.inputmethod.KeyboardLayoutPickerFragment; import com.android.settings.inputmethod.SpellCheckersSettings; @@ -250,6 +251,7 @@ public class SettingsActivity extends SettingsDrawerActivity DateTimeSettings.class.getName(), LocaleListEditor.class.getName(), InputMethodAndLanguageSettings.class.getName(), + AvailableVirtualKeyboardFragment.class.getName(), SpellCheckersSettings.class.getName(), UserDictionaryList.class.getName(), UserDictionarySettings.class.getName(), diff --git a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java new file mode 100644 index 00000000000..2e4242aec65 --- /dev/null +++ b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.inputmethod; + +import android.app.Activity; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Bundle; +import android.support.v7.preference.PreferenceScreen; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; + +import com.android.settings.R; +import com.android.settings.InstrumentedFragment; +import com.android.settings.SettingsPreferenceFragment; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFragment + implements InputMethodPreference.OnSavePreferenceListener { + + private final ArrayList mInputMethodPreferenceList = new ArrayList<>(); + private InputMethodSettingValuesWrapper mInputMethodSettingValues; + private InputMethodManager mImm; + private DevicePolicyManager mDpm; + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + Activity activity = getActivity(); + PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(activity); + screen.setTitle(activity.getString(R.string.available_virtual_keyboard_category)); + setPreferenceScreen(screen); + mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(activity); + mImm = activity.getSystemService(InputMethodManager.class); + mDpm = activity.getSystemService(DevicePolicyManager.class); + } + + @Override + public void onResume() { + super.onResume(); + // Refresh internal states in mInputMethodSettingValues to keep the latest + // "InputMethodInfo"s and "InputMethodSubtype"s + mInputMethodSettingValues.refreshAllInputMethodAndSubtypes(); + updateInputMethodPreferenceViews(); + } + + @Override + public void onSaveInputMethodPreference(final InputMethodPreference pref) { + final boolean hasHardwareKeyboard = getResources().getConfiguration().keyboard + == Configuration.KEYBOARD_QWERTY; + InputMethodAndSubtypeUtil.saveInputMethodSubtypeList(this, getContentResolver(), + mImm.getInputMethodList(), hasHardwareKeyboard); + // Update input method settings and preference list. + mInputMethodSettingValues.refreshAllInputMethodAndSubtypes(); + for (final InputMethodPreference p : mInputMethodPreferenceList) { + p.updatePreferenceViews(); + } + } + + @Override + protected int getMetricsCategory() { + return InstrumentedFragment.ENABLE_VIRTUAL_KEYBOARDS; + } + + private void updateInputMethodPreferenceViews() { + mInputMethodSettingValues.refreshAllInputMethodAndSubtypes(); + // Clear existing "InputMethodPreference"s + mInputMethodPreferenceList.clear(); + List permittedList = mDpm.getPermittedInputMethodsForCurrentUser(); + final Context context = getPrefContext(); + final List imis = mInputMethodSettingValues.getInputMethodList(); + final int N = (imis == null ? 0 : imis.size()); + for (int i = 0; i < N; ++i) { + final InputMethodInfo imi = imis.get(i); + final boolean isAllowedByOrganization = permittedList == null + || permittedList.contains(imi.getPackageName()); + final InputMethodPreference pref = new InputMethodPreference( + context, imi, true, isAllowedByOrganization, this); + mInputMethodPreferenceList.add(pref); + } + final Collator collator = Collator.getInstance(); + Collections.sort(mInputMethodPreferenceList, new Comparator() { + @Override + public int compare(InputMethodPreference lhs, InputMethodPreference rhs) { + return lhs.compareTo(rhs, collator); + } + }); + getPreferenceScreen().removeAll(); + for (int i = 0; i < N; ++i) { + final InputMethodPreference pref = mInputMethodPreferenceList.get(i); + pref.setOrder(i); + getPreferenceScreen().addPreference(pref); + InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference(pref); + pref.updatePreferenceViews(); + } + } +} diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java index 9022538c094..7564cc75259 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java +++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java @@ -157,12 +157,16 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment startingIntent.getAction()); if (mShowsOnlyFullImeAndKeyboardList) { getPreferenceScreen().removeAll(); - getPreferenceScreen().addPreference(mHardKeyboardCategory); + if (mHardKeyboardCategory != null) { + getPreferenceScreen().addPreference(mHardKeyboardCategory); + } if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) { getPreferenceScreen().addPreference(mShowInputMethodSelectorPref); } - mKeyboardSettingsCategory.removeAll(); - getPreferenceScreen().addPreference(mKeyboardSettingsCategory); + if (mKeyboardSettingsCategory != null) { + mKeyboardSettingsCategory.removeAll(); + getPreferenceScreen().addPreference(mKeyboardSettingsCategory); + } } // Build hard keyboard and game controller preference categories. @@ -376,6 +380,10 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment } private void updateInputMethodPreferenceViews() { + if (mKeyboardSettingsCategory == null) { + return; + } + synchronized (mInputMethodPreferenceList) { // Clear existing "InputMethodPreference"s for (final InputMethodPreference pref : mInputMethodPreferenceList) { @@ -510,6 +518,10 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment } private void updateHardKeyboards() { + if (mHardKeyboardCategory == null) { + return; + } + mHardKeyboardPreferenceList.clear(); final int[] devices = InputDevice.getDeviceIds(); for (int i = 0; i < devices.length; i++) { diff --git a/src/com/android/settings/inputmethod/KeyboardLayoutDialogFragment.java b/src/com/android/settings/inputmethod/KeyboardLayoutDialogFragment.java index ad7a2b167a5..68ceeefc062 100644 --- a/src/com/android/settings/inputmethod/KeyboardLayoutDialogFragment.java +++ b/src/com/android/settings/inputmethod/KeyboardLayoutDialogFragment.java @@ -301,7 +301,7 @@ public class KeyboardLayoutDialogFragment extends DialogFragment } } - private static final class KeyboardLayoutLoader extends AsyncTaskLoader { + static final class KeyboardLayoutLoader extends AsyncTaskLoader { private final InputDeviceIdentifier mInputDeviceIdentifier; public KeyboardLayoutLoader(Context context, InputDeviceIdentifier inputDeviceIdentifier) { diff --git a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java new file mode 100644 index 00000000000..8f7d99e2595 --- /dev/null +++ b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.inputmethod; + +import android.app.Activity; +import android.app.LoaderManager; +import android.content.Intent; +import android.content.Loader; +import android.database.ContentObserver; +import android.hardware.input.InputDeviceIdentifier; +import android.hardware.input.InputManager; +import android.hardware.input.KeyboardLayout; +import android.os.Bundle; +import android.os.Handler; +import android.provider.Settings.Secure; +import android.support.v7.preference.Preference; +import android.support.v7.preference.Preference.OnPreferenceChangeListener; +import android.support.v7.preference.PreferenceCategory; +import android.support.v14.preference.SwitchPreference; +import android.util.Pair; +import android.view.InputDevice; +import android.view.inputmethod.InputMethodInfo; +import android.widget.Toast; + +import com.android.internal.inputmethod.InputMethodUtils; +import com.android.internal.util.Preconditions; +import com.android.settings.R; +import com.android.settings.InstrumentedFragment; +import com.android.settings.Settings; +import com.android.settings.SettingsPreferenceFragment; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; + +public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment + implements LoaderManager.LoaderCallbacks, + InputManager.InputDeviceListener { + + private static final int USER_SYSTEM = 0; + private static final String KEYBOARD_ASSISTANCE_CATEGORY = "keyboard_assistance_category"; + private static final String SHOW_VIRTUAL_KEYBOARD_SWITCH = "show_virtual_keyboard_switch"; + private static final String KEYBOARD_SHORTCUTS_HELPER = "keyboard_shortcuts_helper"; + + private final ArrayList mHardKeyboardPreferenceList = new ArrayList<>(); + private final HashMap> mLoaderReference + = new HashMap<>(); + private InputManager mIm; + private PreferenceCategory mKeyboardAssistanceCategory; + private SwitchPreference mShowVirtualKeyboardSwitch; + private InputMethodUtils.InputMethodSettings mSettings; + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + Activity activity = Preconditions.checkNotNull(getActivity()); + addPreferencesFromResource(R.xml.physical_keyboard_settings); + mIm = Preconditions.checkNotNull(activity.getSystemService(InputManager.class)); + mSettings = new InputMethodUtils.InputMethodSettings( + activity.getResources(), + getContentResolver(), + new HashMap(), + new ArrayList(), + USER_SYSTEM); + mKeyboardAssistanceCategory = Preconditions.checkNotNull( + (PreferenceCategory) findPreference(KEYBOARD_ASSISTANCE_CATEGORY)); + mShowVirtualKeyboardSwitch = Preconditions.checkNotNull( + (SwitchPreference) mKeyboardAssistanceCategory.findPreference( + SHOW_VIRTUAL_KEYBOARD_SWITCH)); + findPreference(KEYBOARD_SHORTCUTS_HELPER).setOnPreferenceClickListener( + new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + toggleKeyboardShortcutsMenu(); + return true; + } + }); + } + + @Override + public void onResume() { + super.onResume(); + updateHardKeyboards(); + mIm.registerInputDeviceListener(this, null); + mShowVirtualKeyboardSwitch.setOnPreferenceChangeListener( + mShowVirtualKeyboardSwitchPreferenceChangeListener); + registerShowVirtualKeyboardSettingsObserver(); + } + + @Override + public void onPause() { + super.onPause(); + clearHardKeyboardsData(); + mIm.unregisterInputDeviceListener(this); + mShowVirtualKeyboardSwitch.setOnPreferenceChangeListener(null); + unregisterShowVirtualKeyboardSettingsObserver(); + } + + @Override + public Loader onCreateLoader(int id, Bundle args) { + InputDeviceIdentifier deviceId = mLoaderReference.get(id).first; + return new KeyboardLayoutDialogFragment.KeyboardLayoutLoader( + getActivity().getBaseContext(), deviceId); + } + + @Override + public void onLoadFinished( + final Loader loader, + KeyboardLayoutDialogFragment.Keyboards data) { + // TODO: Investigate why this is being called twice. + final InputDeviceIdentifier deviceId = mLoaderReference.get(loader.getId()).first; + final PreferenceCategory category = mLoaderReference.get(loader.getId()).second; + category.removeAll(); + for (KeyboardLayout layout : data.keyboardLayouts) { + if (layout != null) { + Preference pref = new Preference(getPrefContext(), null); + pref.setTitle(layout.getLabel()); + pref.setSummary(layout.getCollection()); + pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + showKeyboardLayoutScreen(deviceId); + return true; + } + }); + category.addPreference(pref); + } + } + } + + @Override + public void onLoaderReset(Loader loader) {} + + @Override + public void onInputDeviceAdded(int deviceId) { + updateHardKeyboards(); + } + + @Override + public void onInputDeviceRemoved(int deviceId) { + updateHardKeyboards(); + } + + @Override + public void onInputDeviceChanged(int deviceId) { + updateHardKeyboards(); + } + + @Override + protected int getMetricsCategory() { + return InstrumentedFragment.PHYSICAL_KEYBOARDS; + } + + private void updateHardKeyboards() { + clearHardKeyboardsData(); + final int[] devices = InputDevice.getDeviceIds(); + for (int deviceIndex = 0; deviceIndex < devices.length; deviceIndex++) { + InputDevice device = InputDevice.getDevice(devices[deviceIndex]); + if (device != null + && !device.isVirtual() + && device.isFullKeyboard()) { + final InputDeviceIdentifier deviceId = device.getIdentifier(); + final String keyboardLayoutDescriptor = + mIm.getCurrentKeyboardLayoutForInputDevice(deviceId); + final KeyboardLayout keyboardLayout = keyboardLayoutDescriptor != null ? + mIm.getKeyboardLayout(keyboardLayoutDescriptor) : null; + + final PreferenceCategory category = new PreferenceCategory(getPrefContext(), null); + category.setTitle(device.getName()); + if (keyboardLayout != null) { + category.setSummary(keyboardLayout.toString()); + } else { + category.setSummary(R.string.keyboard_layout_default_label); + } + mLoaderReference.put(deviceIndex, new Pair(deviceId, category)); + mHardKeyboardPreferenceList.add(category); + } + } + + Collections.sort(mHardKeyboardPreferenceList); + final int count = mHardKeyboardPreferenceList.size(); + for (int i = 0; i < count; i++) { + final PreferenceCategory category = mHardKeyboardPreferenceList.get(i); + category.setOrder(i); + getPreferenceScreen().addPreference(category); + } + mKeyboardAssistanceCategory.setOrder(count); + getPreferenceScreen().addPreference(mKeyboardAssistanceCategory); + + for (int deviceIndex : mLoaderReference.keySet()) { + getLoaderManager().initLoader(deviceIndex, null, this); + } + updateShowVirtualKeyboardSwitch(); + } + + private void showKeyboardLayoutScreen(InputDeviceIdentifier inputDeviceIdentifier) { + final Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setClass(getActivity(), Settings.KeyboardLayoutPickerActivity.class); + intent.putExtra(KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_IDENTIFIER, + inputDeviceIdentifier); + startActivity(intent); + } + + private void clearHardKeyboardsData() { + getPreferenceScreen().removeAll(); + for (int index = 0; index < mLoaderReference.size(); index++) { + getLoaderManager().destroyLoader(index); + } + mLoaderReference.clear(); + mHardKeyboardPreferenceList.clear(); + } + + private void registerShowVirtualKeyboardSettingsObserver() { + unregisterShowVirtualKeyboardSettingsObserver(); + getActivity().getContentResolver().registerContentObserver( + Secure.getUriFor(Secure.SHOW_IME_WITH_HARD_KEYBOARD), + false, + mContentObserver, + USER_SYSTEM); + updateShowVirtualKeyboardSwitch(); + } + + private void unregisterShowVirtualKeyboardSettingsObserver() { + getActivity().getContentResolver().unregisterContentObserver(mContentObserver); + } + + private void updateShowVirtualKeyboardSwitch() { + mShowVirtualKeyboardSwitch.setChecked(mSettings.isShowImeWithHardKeyboardEnabled()); + } + + private void toggleKeyboardShortcutsMenu() { + // TODO: Implement. + Toast.makeText(getActivity(), "toggleKeyboardShortcutsMenu", Toast.LENGTH_SHORT).show(); + } + + private final OnPreferenceChangeListener mShowVirtualKeyboardSwitchPreferenceChangeListener = + new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + mSettings.setShowImeWithHardKeyboard((Boolean) newValue); + return false; + } + }; + + private final ContentObserver mContentObserver = new ContentObserver(new Handler(true)) { + @Override + public void onChange(boolean selfChange) { + updateShowVirtualKeyboardSwitch(); + } + }; +} diff --git a/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java new file mode 100644 index 00000000000..541c68655e9 --- /dev/null +++ b/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.inputmethod; + +import android.app.Activity; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.os.Bundle; +import android.support.v7.preference.Preference; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; + +import com.android.internal.util.Preconditions; +import com.android.settings.R; +import com.android.settings.InstrumentedFragment; +import com.android.settings.SettingsPreferenceFragment; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public final class VirtualKeyboardFragment extends SettingsPreferenceFragment { + + private static final String ADD_VIRTUAL_KEYBOARD_SCREEN = "add_virtual_keyboard_screen"; + + private final ArrayList mInputMethodPreferenceList = new ArrayList<>(); + private InputMethodManager mImm; + private DevicePolicyManager mDpm; + private Preference mAddVirtualKeyboardScreen; + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + Activity activity = Preconditions.checkNotNull(getActivity()); + addPreferencesFromResource(R.xml.virtual_keyboard_settings); + mImm = Preconditions.checkNotNull(activity.getSystemService(InputMethodManager.class)); + mDpm = Preconditions.checkNotNull(activity.getSystemService(DevicePolicyManager.class)); + mAddVirtualKeyboardScreen = Preconditions.checkNotNull( + findPreference(ADD_VIRTUAL_KEYBOARD_SCREEN)); + } + + @Override + public void onResume() { + super.onResume(); + // Refresh internal states in mInputMethodSettingValues to keep the latest + // "InputMethodInfo"s and "InputMethodSubtype"s + updateInputMethodPreferenceViews(); + } + + @Override + protected int getMetricsCategory() { + return InstrumentedFragment.VIRTUAL_KEYBOARDS; + } + + private void updateInputMethodPreferenceViews() { + // Clear existing "InputMethodPreference"s + mInputMethodPreferenceList.clear(); + List permittedList = mDpm.getPermittedInputMethodsForCurrentUser(); + final Context context = getPrefContext(); + final List imis = mImm.getEnabledInputMethodList(); + final int N = (imis == null ? 0 : imis.size()); + for (int i = 0; i < N; ++i) { + final InputMethodInfo imi = imis.get(i); + final boolean isAllowedByOrganization = permittedList == null + || permittedList.contains(imi.getPackageName()); + final InputMethodPreference pref = new InputMethodPreference( + context, + imi, + false, /* isImeEnabler */ + isAllowedByOrganization, + null /* this can be null since isImeEnabler is false */); + mInputMethodPreferenceList.add(pref); + } + final Collator collator = Collator.getInstance(); + Collections.sort(mInputMethodPreferenceList, new Comparator() { + @Override + public int compare(InputMethodPreference lhs, InputMethodPreference rhs) { + return lhs.compareTo(rhs, collator); + } + }); + getPreferenceScreen().removeAll(); + for (int i = 0; i < N; ++i) { + final InputMethodPreference pref = mInputMethodPreferenceList.get(i); + pref.setOrder(i); + getPreferenceScreen().addPreference(pref); + InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference(pref); + pref.updatePreferenceViews(); + } + mAddVirtualKeyboardScreen.setOrder(N); + getPreferenceScreen().addPreference(mAddVirtualKeyboardScreen); + } +}