diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java index cba09d1af7960..e3f21cf5f21bd 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java +++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java @@ -227,25 +227,39 @@ public class InputMethodSubtypeSwitchingController { if (imList.size() <= 1) { return null; } + // Here we have two rotation groups, depending on the returned boolean value of + // {@link InputMethodInfo#supportsSwitchingToNextInputMethod()}. + final boolean expectedValueOfSupportsSwitchingToNextInputMethod = + imi.supportsSwitchingToNextInputMethod(); final int N = imList.size(); final int currentSubtypeId = subtype != null ? InputMethodUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode()) : NOT_A_SUBTYPE_ID; for (int i = 0; i < N; ++i) { final ImeSubtypeListItem isli = imList.get(i); - if (isli.mImi.equals(imi) && isli.mSubtypeId == currentSubtypeId) { - if (!onlyCurrentIme) { - return imList.get((i + 1) % N); - } - for (int j = 0; j < N - 1; ++j) { - final ImeSubtypeListItem candidate = imList.get((i + j + 1) % N); - if (candidate.mImi.equals(imi)) { - return candidate; - } - } - return null; + // Skip until the current IME/subtype is found. + if (!isli.mImi.equals(imi) || isli.mSubtypeId != currentSubtypeId) { + continue; } + // Found the current IME/subtype. Start searching the next IME/subtype from here. + for (int j = 0; j < N - 1; ++j) { + final ImeSubtypeListItem candidate = imList.get((i + j + 1) % N); + // Skip if the candidate doesn't belong to the expected rotation group. + if (expectedValueOfSupportsSwitchingToNextInputMethod != + candidate.mImi.supportsSwitchingToNextInputMethod()) { + continue; + } + // Skip if searching inside the current IME only, but the candidate is not + // the current IME. + if (onlyCurrentIme && !candidate.mImi.equals(imi)) { + continue; + } + return candidate; + } + // No appropriate IME/subtype is found in the list. Give up. + return null; } + // The current IME/subtype is not found in the list. Give up. return null; } diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeSwitchingControllerTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeSwitchingControllerTest.java index 6d335295637bd..23b6780a21dc0 100644 --- a/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeSwitchingControllerTest.java +++ b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeSwitchingControllerTest.java @@ -73,7 +73,6 @@ public class InputMethodSubtypeSwitchingControllerTest extends InstrumentationTe DUMMY_FORCE_DEFAULT, supportsSwitchingToNextInputMethod); for (int i = 0; i < subtypes.size(); ++i) { final String subtypeLocale = subtypeLocales.get(i); - final InputMethodSubtype subtype = subtypes.get(i); items.add(new ImeSubtypeListItem(imeName, subtypeLocale, imi, i, subtypeLocale, SYSTEM_LOCALE)); } @@ -116,36 +115,37 @@ public class InputMethodSubtypeSwitchingControllerTest extends InstrumentationTe imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype( currentIme.mSubtypeName.toString())); assertEquals(imList.get(2), nextIme); - // "switchAwareLatinIme/fr" -> "nonSwitchAwareLatinIme/en_UK + // "switchAwareLatinIme/fr" -> "switchAwareJapaneseIme/ja_JP" currentIme = imList.get(2); nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl( imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype( currentIme.mSubtypeName.toString())); - assertEquals(imList.get(3), nextIme); + assertEquals(imList.get(5), nextIme); + // "switchAwareJapaneseIme/ja_JP" -> "switchAwareLatinIme/en_US" + currentIme = imList.get(5); + nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl( + imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype( + currentIme.mSubtypeName.toString())); + assertEquals(imList.get(0), nextIme); + // "nonSwitchAwareLatinIme/en_UK" -> "nonSwitchAwareLatinIme/hi" currentIme = imList.get(3); nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl( imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype( currentIme.mSubtypeName.toString())); assertEquals(imList.get(4), nextIme); - // "nonSwitchAwareLatinIme/hi" -> "switchAwareJapaneseIme/ja_JP" + // "nonSwitchAwareLatinIme/hi" -> "nonSwitchAwareJapaneseIme/ja_JP" currentIme = imList.get(4); - nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl( - imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype( - currentIme.mSubtypeName.toString())); - assertEquals(imList.get(5), nextIme); - // "switchAwareJapaneseIme/ja_JP" -> "nonSwitchAwareJapaneseIme/ja_JP" - currentIme = imList.get(5); nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl( imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype( currentIme.mSubtypeName.toString())); assertEquals(imList.get(6), nextIme); - // "nonSwitchAwareJapaneseIme/ja_JP" -> "switchAwareLatinIme/en_US" + // "nonSwitchAwareJapaneseIme/ja_JP" -> "nonSwitchAwareLatinIme/en_UK" currentIme = imList.get(6); nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl( imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype( currentIme.mSubtypeName.toString())); - assertEquals(imList.get(0), nextIme); + assertEquals(imList.get(3), nextIme); } @SmallTest