Merge "Reduce member fileds in InputMethodMenuController" into main
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index c4d94ee..4f998ee 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -276,7 +276,7 @@
final Context mContext;
final Resources mRes;
private final Handler mHandler;
- final InputMethodSettings mSettings;
+ private final InputMethodSettings mSettings;
final SettingsObserver mSettingsObserver;
private final SparseBooleanArray mLoggedDeniedGetInputMethodWindowVisibleHeightForUid =
new SparseBooleanArray(0);
@@ -316,7 +316,7 @@
// Mapping from deviceId to the device-specific imeId for that device.
private final SparseArray<String> mVirtualDeviceMethodMap = new SparseArray<>();
- final InputMethodSubtypeSwitchingController mSwitchingController;
+ private final InputMethodSubtypeSwitchingController mSwitchingController;
final HardwareKeyboardShortcutController mHardwareKeyboardShortcutController =
new HardwareKeyboardShortcutController();
@@ -4812,7 +4812,20 @@
Slog.e(TAG, "Unknown subtype picker mode = " + msg.arg1);
return false;
}
- mMenuController.showInputMethodMenu(showAuxSubtypes, displayId);
+ synchronized (ImfLock.class) {
+ final boolean isScreenLocked = mWindowManagerInternal.isKeyguardLocked()
+ && mWindowManagerInternal.isKeyguardSecure(
+ mSettings.getCurrentUserId());
+ final String lastInputMethodId = mSettings.getSelectedInputMethod();
+ int lastInputMethodSubtypeId =
+ mSettings.getSelectedInputMethodSubtypeId(lastInputMethodId);
+
+ final List<ImeSubtypeListItem> imList = mSwitchingController
+ .getSortedInputMethodAndSubtypeListForImeMenuLocked(
+ showAuxSubtypes, isScreenLocked);
+ mMenuController.showInputMethodMenuLocked(showAuxSubtypes, displayId,
+ lastInputMethodId, lastInputMethodSubtypeId, imList);
+ }
return true;
// ---------------------------------------------------------
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
index bc3643a..6ed4848 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
@@ -19,6 +19,7 @@
import static com.android.server.inputmethod.InputMethodManagerService.DEBUG;
import static com.android.server.inputmethod.InputMethodUtils.NOT_A_SUBTYPE_ID;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlertDialog;
import android.content.Context;
@@ -52,8 +53,6 @@
private static final String TAG = InputMethodMenuController.class.getSimpleName();
private final InputMethodManagerService mService;
- private final InputMethodUtils.InputMethodSettings mSettings;
- private final InputMethodSubtypeSwitchingController mSwitchingController;
private final WindowManagerInternal mWindowManagerInternal;
private AlertDialog.Builder mDialogBuilder;
@@ -70,142 +69,135 @@
InputMethodMenuController(InputMethodManagerService service) {
mService = service;
- mSettings = mService.mSettings;
- mSwitchingController = mService.mSwitchingController;
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
}
- void showInputMethodMenu(boolean showAuxSubtypes, int displayId) {
+ @GuardedBy("ImfLock.class")
+ void showInputMethodMenuLocked(boolean showAuxSubtypes, int displayId,
+ String preferredInputMethodId, int preferredInputMethodSubtypeId,
+ @NonNull List<ImeSubtypeListItem> imList) {
if (DEBUG) Slog.v(TAG, "Show switching menu. showAuxSubtypes=" + showAuxSubtypes);
- synchronized (ImfLock.class) {
- final int userId = mService.getCurrentImeUserIdLocked();
- final boolean isScreenLocked = mWindowManagerInternal.isKeyguardLocked()
- && mWindowManagerInternal.isKeyguardSecure(userId);
- final String lastInputMethodId = mSettings.getSelectedInputMethod();
- int lastInputMethodSubtypeId =
- mSettings.getSelectedInputMethodSubtypeId(lastInputMethodId);
- if (DEBUG) Slog.v(TAG, "Current IME: " + lastInputMethodId);
+ final int userId = mService.getCurrentImeUserIdLocked();
- final List<ImeSubtypeListItem> imList = mSwitchingController
- .getSortedInputMethodAndSubtypeListForImeMenuLocked(
- showAuxSubtypes, isScreenLocked);
- if (imList.isEmpty()) {
- return;
- }
-
- hideInputMethodMenuLocked();
-
- if (lastInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {
- final InputMethodSubtype currentSubtype =
- mService.getCurrentInputMethodSubtypeLocked();
- if (currentSubtype != null) {
- final String curMethodId = mService.getSelectedMethodIdLocked();
- final InputMethodInfo currentImi =
- mService.queryInputMethodForCurrentUserLocked(curMethodId);
- lastInputMethodSubtypeId = SubtypeUtils.getSubtypeIdFromHashCode(
- currentImi, currentSubtype.hashCode());
- }
- }
-
- final int size = imList.size();
- mIms = new InputMethodInfo[size];
- mSubtypeIds = new int[size];
- int checkedItem = 0;
- for (int i = 0; i < size; ++i) {
- final ImeSubtypeListItem item = imList.get(i);
- mIms[i] = item.mImi;
- mSubtypeIds[i] = item.mSubtypeId;
- if (mIms[i].getId().equals(lastInputMethodId)) {
- int subtypeId = mSubtypeIds[i];
- if ((subtypeId == NOT_A_SUBTYPE_ID)
- || (lastInputMethodSubtypeId == NOT_A_SUBTYPE_ID && subtypeId == 0)
- || (subtypeId == lastInputMethodSubtypeId)) {
- checkedItem = i;
- }
- }
- }
-
- if (mDialogWindowContext == null) {
- mDialogWindowContext = new InputMethodDialogWindowContext();
- }
- final Context dialogWindowContext = mDialogWindowContext.get(displayId);
- mDialogBuilder = new AlertDialog.Builder(dialogWindowContext);
- mDialogBuilder.setOnCancelListener(dialog -> hideInputMethodMenu());
-
- final Context dialogContext = mDialogBuilder.getContext();
- final TypedArray a = dialogContext.obtainStyledAttributes(null,
- com.android.internal.R.styleable.DialogPreference,
- com.android.internal.R.attr.alertDialogStyle, 0);
- final Drawable dialogIcon = a.getDrawable(
- com.android.internal.R.styleable.DialogPreference_dialogIcon);
- a.recycle();
-
- mDialogBuilder.setIcon(dialogIcon);
-
- final LayoutInflater inflater = dialogContext.getSystemService(LayoutInflater.class);
- final View tv = inflater.inflate(
- com.android.internal.R.layout.input_method_switch_dialog_title, null);
- mDialogBuilder.setCustomTitle(tv);
-
- // Setup layout for a toggle switch of the hardware keyboard
- mSwitchingDialogTitleView = tv;
- mSwitchingDialogTitleView
- .findViewById(com.android.internal.R.id.hard_keyboard_section)
- .setVisibility(mWindowManagerInternal.isHardKeyboardAvailable()
- ? View.VISIBLE : View.GONE);
- final Switch hardKeySwitch = mSwitchingDialogTitleView.findViewById(
- com.android.internal.R.id.hard_keyboard_switch);
- hardKeySwitch.setChecked(mShowImeWithHardKeyboard);
- hardKeySwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
- SecureSettingsWrapper.putBoolean(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
- isChecked, userId);
- // Ensure that the input method dialog is dismissed when changing
- // the hardware keyboard state.
- hideInputMethodMenu();
- });
-
- final ImeSubtypeListAdapter adapter = new ImeSubtypeListAdapter(dialogContext,
- com.android.internal.R.layout.input_method_switch_item, imList, checkedItem);
- final DialogInterface.OnClickListener choiceListener = (dialog, which) -> {
- synchronized (ImfLock.class) {
- if (mIms == null || mIms.length <= which || mSubtypeIds == null
- || mSubtypeIds.length <= which) {
- return;
- }
- final InputMethodInfo im = mIms[which];
- int subtypeId = mSubtypeIds[which];
- adapter.mCheckedItem = which;
- adapter.notifyDataSetChanged();
- if (im != null) {
- if (subtypeId < 0 || subtypeId >= im.getSubtypeCount()) {
- subtypeId = NOT_A_SUBTYPE_ID;
- }
- mService.setInputMethodLocked(im.getId(), subtypeId);
- }
- hideInputMethodMenuLocked();
- }
- };
- mDialogBuilder.setSingleChoiceItems(adapter, checkedItem, choiceListener);
-
- mSwitchingDialog = mDialogBuilder.create();
- mSwitchingDialog.setCanceledOnTouchOutside(true);
- final Window w = mSwitchingDialog.getWindow();
- final WindowManager.LayoutParams attrs = w.getAttributes();
- w.setType(WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
- w.setHideOverlayWindows(true);
- // Use an alternate token for the dialog for that window manager can group the token
- // with other IME windows based on type vs. grouping based on whichever token happens
- // to get selected by the system later on.
- attrs.token = dialogWindowContext.getWindowContextToken();
- attrs.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
- attrs.setTitle("Select input method");
- w.setAttributes(attrs);
- mService.updateSystemUiLocked();
- mService.sendOnNavButtonFlagsChangedLocked();
- mSwitchingDialog.show();
-
+ if (imList.isEmpty()) {
+ return;
}
+
+ hideInputMethodMenuLocked();
+
+ if (preferredInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {
+ final InputMethodSubtype currentSubtype =
+ mService.getCurrentInputMethodSubtypeLocked();
+ if (currentSubtype != null) {
+ final String curMethodId = mService.getSelectedMethodIdLocked();
+ final InputMethodInfo currentImi =
+ mService.queryInputMethodForCurrentUserLocked(curMethodId);
+ preferredInputMethodSubtypeId = SubtypeUtils.getSubtypeIdFromHashCode(
+ currentImi, currentSubtype.hashCode());
+ }
+ }
+
+ // Find out which item should be checked by default.
+ final int size = imList.size();
+ mIms = new InputMethodInfo[size];
+ mSubtypeIds = new int[size];
+ int checkedItem = 0;
+ for (int i = 0; i < size; ++i) {
+ final ImeSubtypeListItem item = imList.get(i);
+ mIms[i] = item.mImi;
+ mSubtypeIds[i] = item.mSubtypeId;
+ if (mIms[i].getId().equals(preferredInputMethodId)) {
+ int subtypeId = mSubtypeIds[i];
+ if ((subtypeId == NOT_A_SUBTYPE_ID)
+ || (preferredInputMethodSubtypeId == NOT_A_SUBTYPE_ID && subtypeId == 0)
+ || (subtypeId == preferredInputMethodSubtypeId)) {
+ checkedItem = i;
+ }
+ }
+ }
+
+ if (mDialogWindowContext == null) {
+ mDialogWindowContext = new InputMethodDialogWindowContext();
+ }
+ final Context dialogWindowContext = mDialogWindowContext.get(displayId);
+ mDialogBuilder = new AlertDialog.Builder(dialogWindowContext);
+ mDialogBuilder.setOnCancelListener(dialog -> hideInputMethodMenu());
+
+ final Context dialogContext = mDialogBuilder.getContext();
+ final TypedArray a = dialogContext.obtainStyledAttributes(null,
+ com.android.internal.R.styleable.DialogPreference,
+ com.android.internal.R.attr.alertDialogStyle, 0);
+ final Drawable dialogIcon = a.getDrawable(
+ com.android.internal.R.styleable.DialogPreference_dialogIcon);
+ a.recycle();
+
+ mDialogBuilder.setIcon(dialogIcon);
+
+ final LayoutInflater inflater = dialogContext.getSystemService(LayoutInflater.class);
+ final View tv = inflater.inflate(
+ com.android.internal.R.layout.input_method_switch_dialog_title, null);
+ mDialogBuilder.setCustomTitle(tv);
+
+ // Setup layout for a toggle switch of the hardware keyboard
+ mSwitchingDialogTitleView = tv;
+ mSwitchingDialogTitleView
+ .findViewById(com.android.internal.R.id.hard_keyboard_section)
+ .setVisibility(mWindowManagerInternal.isHardKeyboardAvailable()
+ ? View.VISIBLE : View.GONE);
+ final Switch hardKeySwitch = mSwitchingDialogTitleView.findViewById(
+ com.android.internal.R.id.hard_keyboard_switch);
+ hardKeySwitch.setChecked(mShowImeWithHardKeyboard);
+ hardKeySwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ SecureSettingsWrapper.putBoolean(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
+ isChecked, userId);
+ // Ensure that the input method dialog is dismissed when changing
+ // the hardware keyboard state.
+ hideInputMethodMenu();
+ });
+
+ // Fill the list items with onClick listener, which takes care of IME (and subtype)
+ // switching when clicked.
+ final ImeSubtypeListAdapter adapter = new ImeSubtypeListAdapter(dialogContext,
+ com.android.internal.R.layout.input_method_switch_item, imList, checkedItem);
+ final DialogInterface.OnClickListener choiceListener = (dialog, which) -> {
+ synchronized (ImfLock.class) {
+ if (mIms == null || mIms.length <= which || mSubtypeIds == null
+ || mSubtypeIds.length <= which) {
+ return;
+ }
+ final InputMethodInfo im = mIms[which];
+ int subtypeId = mSubtypeIds[which];
+ adapter.mCheckedItem = which;
+ adapter.notifyDataSetChanged();
+ if (im != null) {
+ if (subtypeId < 0 || subtypeId >= im.getSubtypeCount()) {
+ subtypeId = NOT_A_SUBTYPE_ID;
+ }
+ mService.setInputMethodLocked(im.getId(), subtypeId);
+ }
+ hideInputMethodMenuLocked();
+ }
+ };
+ mDialogBuilder.setSingleChoiceItems(adapter, checkedItem, choiceListener);
+
+ // Final steps to instantiate a dialog to show it up.
+ mSwitchingDialog = mDialogBuilder.create();
+ mSwitchingDialog.setCanceledOnTouchOutside(true);
+ final Window w = mSwitchingDialog.getWindow();
+ final WindowManager.LayoutParams attrs = w.getAttributes();
+ w.setType(WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
+ w.setHideOverlayWindows(true);
+ // Use an alternate token for the dialog for that window manager can group the token
+ // with other IME windows based on type vs. grouping based on whichever token happens
+ // to get selected by the system later on.
+ attrs.token = dialogWindowContext.getWindowContextToken();
+ attrs.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+ attrs.setTitle("Select input method");
+ w.setAttributes(attrs);
+ mService.updateSystemUiLocked();
+ mService.sendOnNavButtonFlagsChangedLocked();
+ mSwitchingDialog.show();
}
void updateKeyboardFromSettingsLocked() {