Loading core/java/android/inputmethodservice/InputMethodService.java +2 −1 Original line number Diff line number Diff line Loading @@ -4341,7 +4341,8 @@ public class InputMethodService extends AbstractInputMethodService { } /** * Called when the IME switch button was clicked from the client. This will show the input * Called when the IME switch button was clicked from the client. Depending on the number of * enabled IME subtypes, this will either switch to the next IME/subtype, or show the input * method picker dialog. * * @hide Loading core/java/android/view/inputmethod/InputMethodManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -4354,7 +4354,8 @@ public final class InputMethodManager { } /** * Called when the IME switch button was clicked from the system. This will show the input * Called when the IME switch button was clicked from the system. Depending on the number of * enabled IME subtypes, this will either switch to the next IME/subtype, or show the input * method picker dialog. * * @param displayId The ID of the display where the input method picker dialog should be shown. Loading services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +48 −5 Original line number Diff line number Diff line Loading @@ -2625,6 +2625,18 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); return hasMultipleSubtypesForSwitcher(false /* nonAuxOnly */, settings); } /** * Checks whether there at least two subtypes that should be shown for the IME switcher menu, * across all enabled IMEs for the given user. * * @param nonAuxOnly whether to check only for non auxiliary subtypes. * @param settings the input method settings under the given user ID. */ private static boolean hasMultipleSubtypesForSwitcher(boolean nonAuxOnly, @NonNull InputMethodSettings settings) { List<InputMethodInfo> imes = settings.getEnabledInputMethodListWithFilter( InputMethodInfo::shouldShowInInputMethodPicker); final int numImes = imes.size(); Loading Loading @@ -2654,7 +2666,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } } } if (nonAuxCount > 1 || auxCount > 1) { if (Flags.imeSwitcherRevamp() && nonAuxOnly) { return nonAuxCount > 1; } else if (nonAuxCount > 1 || auxCount > 1) { return true; } else if (nonAuxCount == 1 && auxCount == 1) { if (nonAuxSubtype != null && auxSubtype != null Loading Loading @@ -3976,17 +3990,46 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. if (!calledWithValidTokenLocked(token, userData)) { return; } showInputMethodPickerFromSystem( InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES, displayId); onImeSwitchButtonClickLocked(token, displayId, userData); } } @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.WRITE_SECURE_SETTINGS) @Override public void onImeSwitchButtonClickFromSystem(int displayId) { synchronized (ImfLock.class) { final int userId = mCurrentUserId; final var userData = getUserData(userId); final var bindingController = userData.mBindingController; final var curToken = bindingController.getCurToken(); if (curToken == null) { return; } onImeSwitchButtonClickLocked(curToken, displayId, userData); } } /** * Handles a click on the IME switch button. Depending on the number of enabled IME subtypes, * this will either switch to the next IME/subtype, or show the input method picker dialog. * * @param token The token identifying the input method that triggered this. * @param displayId The ID of the display where the input method picker dialog should be shown. * @param userData The data of the user for which to switch IMEs or show the picker dialog. */ @GuardedBy("ImfLock.class") private void onImeSwitchButtonClickLocked(@NonNull IBinder token, int displayId, @NonNull UserData userData) { final int userId = userData.mUserId; final var settings = InputMethodSettingsRepository.get(userId); if (hasMultipleSubtypesForSwitcher(true /* nonAuxOnly */, settings)) { switchToNextInputMethodLocked(token, false /* onlyCurrentIme */, userData); } else { showInputMethodPickerFromSystem( InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES, displayId); } } @NonNull private static IllegalArgumentException getExceptionForUnknownImeId( Loading services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java +8 −3 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -769,7 +770,8 @@ public class InputMethodServiceTest { } /** * Verifies that clicking on the IME switch button shows the Input Method Switcher Menu. * Verifies that clicking on the IME switch button either shows the Input Method Switcher Menu, * or switches the input method. */ @Test public void testImeSwitchButtonClick() throws Exception { Loading @@ -794,13 +796,16 @@ public class InputMethodServiceTest { assertThat(mInputMethodService.isInputViewShown()).isTrue(); final var imm = mContext.getSystemService(InputMethodManager.class); final var initialInfo = imm.getCurrentInputMethodInfo(); final var imeSwitchButtonUiObject = getUiObjectById(INPUT_METHOD_NAV_IME_SWITCHER_ID); imeSwitchButtonUiObject.click(); mInstrumentation.waitForIdleSync(); assertWithMessage("Input Method Switcher Menu is shown") .that(isInputMethodPickerShown(imm)) final var newInfo = imm.getCurrentInputMethodInfo(); assertWithMessage("Input Method Switcher Menu is shown or input method was switched") .that(isInputMethodPickerShown(imm) || !Objects.equals(initialInfo, newInfo)) .isTrue(); assertThat(mInputMethodService.isInputViewShown()).isTrue(); Loading Loading
core/java/android/inputmethodservice/InputMethodService.java +2 −1 Original line number Diff line number Diff line Loading @@ -4341,7 +4341,8 @@ public class InputMethodService extends AbstractInputMethodService { } /** * Called when the IME switch button was clicked from the client. This will show the input * Called when the IME switch button was clicked from the client. Depending on the number of * enabled IME subtypes, this will either switch to the next IME/subtype, or show the input * method picker dialog. * * @hide Loading
core/java/android/view/inputmethod/InputMethodManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -4354,7 +4354,8 @@ public final class InputMethodManager { } /** * Called when the IME switch button was clicked from the system. This will show the input * Called when the IME switch button was clicked from the system. Depending on the number of * enabled IME subtypes, this will either switch to the next IME/subtype, or show the input * method picker dialog. * * @param displayId The ID of the display where the input method picker dialog should be shown. Loading
services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +48 −5 Original line number Diff line number Diff line Loading @@ -2625,6 +2625,18 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); return hasMultipleSubtypesForSwitcher(false /* nonAuxOnly */, settings); } /** * Checks whether there at least two subtypes that should be shown for the IME switcher menu, * across all enabled IMEs for the given user. * * @param nonAuxOnly whether to check only for non auxiliary subtypes. * @param settings the input method settings under the given user ID. */ private static boolean hasMultipleSubtypesForSwitcher(boolean nonAuxOnly, @NonNull InputMethodSettings settings) { List<InputMethodInfo> imes = settings.getEnabledInputMethodListWithFilter( InputMethodInfo::shouldShowInInputMethodPicker); final int numImes = imes.size(); Loading Loading @@ -2654,7 +2666,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } } } if (nonAuxCount > 1 || auxCount > 1) { if (Flags.imeSwitcherRevamp() && nonAuxOnly) { return nonAuxCount > 1; } else if (nonAuxCount > 1 || auxCount > 1) { return true; } else if (nonAuxCount == 1 && auxCount == 1) { if (nonAuxSubtype != null && auxSubtype != null Loading Loading @@ -3976,17 +3990,46 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. if (!calledWithValidTokenLocked(token, userData)) { return; } showInputMethodPickerFromSystem( InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES, displayId); onImeSwitchButtonClickLocked(token, displayId, userData); } } @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.WRITE_SECURE_SETTINGS) @Override public void onImeSwitchButtonClickFromSystem(int displayId) { synchronized (ImfLock.class) { final int userId = mCurrentUserId; final var userData = getUserData(userId); final var bindingController = userData.mBindingController; final var curToken = bindingController.getCurToken(); if (curToken == null) { return; } onImeSwitchButtonClickLocked(curToken, displayId, userData); } } /** * Handles a click on the IME switch button. Depending on the number of enabled IME subtypes, * this will either switch to the next IME/subtype, or show the input method picker dialog. * * @param token The token identifying the input method that triggered this. * @param displayId The ID of the display where the input method picker dialog should be shown. * @param userData The data of the user for which to switch IMEs or show the picker dialog. */ @GuardedBy("ImfLock.class") private void onImeSwitchButtonClickLocked(@NonNull IBinder token, int displayId, @NonNull UserData userData) { final int userId = userData.mUserId; final var settings = InputMethodSettingsRepository.get(userId); if (hasMultipleSubtypesForSwitcher(true /* nonAuxOnly */, settings)) { switchToNextInputMethodLocked(token, false /* onlyCurrentIme */, userData); } else { showInputMethodPickerFromSystem( InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES, displayId); } } @NonNull private static IllegalArgumentException getExceptionForUnknownImeId( Loading
services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java +8 −3 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -769,7 +770,8 @@ public class InputMethodServiceTest { } /** * Verifies that clicking on the IME switch button shows the Input Method Switcher Menu. * Verifies that clicking on the IME switch button either shows the Input Method Switcher Menu, * or switches the input method. */ @Test public void testImeSwitchButtonClick() throws Exception { Loading @@ -794,13 +796,16 @@ public class InputMethodServiceTest { assertThat(mInputMethodService.isInputViewShown()).isTrue(); final var imm = mContext.getSystemService(InputMethodManager.class); final var initialInfo = imm.getCurrentInputMethodInfo(); final var imeSwitchButtonUiObject = getUiObjectById(INPUT_METHOD_NAV_IME_SWITCHER_ID); imeSwitchButtonUiObject.click(); mInstrumentation.waitForIdleSync(); assertWithMessage("Input Method Switcher Menu is shown") .that(isInputMethodPickerShown(imm)) final var newInfo = imm.getCurrentInputMethodInfo(); assertWithMessage("Input Method Switcher Menu is shown or input method was switched") .that(isInputMethodPickerShown(imm) || !Objects.equals(initialInfo, newInfo)) .isTrue(); assertThat(mInputMethodService.isInputViewShown()).isTrue(); Loading