From a1223cfe6f2e04da1ab6e0ad781068687446ee56 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Thu, 1 May 2014 20:26:41 +0900 Subject: [PATCH] Take supportsSwitchingToNextInputMethod into considertaion With this CL, InputMethodManager#switchToNextInputMethod starts behaving as if there are two rotation groups: one is for the new input methods that are declared with supportsSwitchingToNextInputMethod set to true to indicate they have some language switching UI, and the other is for the other input methods to preserve the existing behavior. In addition to the above change, this CL also fixes the behavior of InputMethodManager#shouldOfferSwitchingToNextInputMethod() so as to return true if and only if the former rotation group consists of two or more input methods, as originally designed. BUG: 12981505 Change-Id: I84291fd4a7d6192b3bd0c366c49586e79135584f --- ...InputMethodSubtypeSwitchingController.java | 36 +++++++++++++------ ...tMethodSubtypeSwitchingControllerTest.java | 24 ++++++------- 2 files changed, 37 insertions(+), 23 deletions(-) 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