Always show auxiliary subtypes from NavBar keyboard icon.

The auxiliary subtypes should be listed if the input method picker is
opened from NavBar keyboard icon.  However there is only
IMM#showInputMethodPicker() API to open input method picker and this is
also used from LockScreen or Settings UI.  Auxiliary subtypes should not
be listed there(Id7cf5d122).  Thus framework shows auxiliary subtypes
based on IMMS#mInputShown and LockScreen state, but it is not a perfect
solution.  If a physical keyboard is connected, the soft input may be
gone.  As the result, auxiliary subtypes won't be listed even if it is
opened from NavBar keyboard icon.

To fix this issue, this CL introduces IMM#showInputMethodPicker(boolean)
to be able to decide showing auxiliary subtypes by caller.
Note that IMM#showInputMethodPicker(boolean) is still hidden with @hide.
There is no public API change in this CL.

Bug: 20763994

Change-Id: I1e50ee42838a1bf64a612da4904aa93458d44ea4
This commit is contained in:
Seigo Nonaka
2015-05-04 13:02:22 -07:00
parent d4474cb945
commit 80ff4ed6bb
6 changed files with 68 additions and 14 deletions

View File

@@ -247,6 +247,13 @@ public final class InputMethodManager {
/** @hide */
public static final int DISPATCH_HANDLED = 1;
/** @hide */
public static final int SHOW_IM_PICKER_MODE_AUTO = 0;
/** @hide */
public static final int SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES = 1;
/** @hide */
public static final int SHOW_IM_PICKER_MODE_EXCLUDE_AUXILIARY_SUBTYPES = 2;
final IInputMethodManager mService;
final Looper mMainLooper;
@@ -1890,9 +1897,28 @@ public final class InputMethodManager {
}
}
/**
* Shows the input method chooser dialog.
*
* @param showAuxiliarySubtypes Set true to show auxiliary input methods.
* @hide
*/
public void showInputMethodPicker(boolean showAuxiliarySubtypes) {
synchronized (mH) {
try {
final int mode = showAuxiliarySubtypes ?
SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES:
SHOW_IM_PICKER_MODE_EXCLUDE_AUXILIARY_SUBTYPES;
mService.showInputMethodPickerFromClient(mClient, mode);
} catch (RemoteException e) {
Log.w(TAG, "IME died: " + mCurId, e);
}
}
}
private void showInputMethodPickerLocked() {
try {
mService.showInputMethodPickerFromClient(mClient);
mService.showInputMethodPickerFromClient(mClient, SHOW_IM_PICKER_MODE_AUTO);
} catch (RemoteException e) {
Log.w(TAG, "IME died: " + mCurId, e);
}

View File

@@ -196,7 +196,7 @@ public class InputMethodSubtypeSwitchingController {
}
public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(
boolean showSubtypes, boolean inputShown, boolean isScreenLocked) {
boolean showSubtypes, boolean includeAuxiliarySubtypes, boolean isScreenLocked) {
final ArrayList<ImeSubtypeListItem> imList =
new ArrayList<ImeSubtypeListItem>();
final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =
@@ -205,6 +205,12 @@ public class InputMethodSubtypeSwitchingController {
if (immis == null || immis.size() == 0) {
return Collections.emptyList();
}
if (isScreenLocked && includeAuxiliarySubtypes) {
if (DEBUG) {
Slog.w(TAG, "Auxiliary subtypes are not allowed to be shown in lock screen.");
}
includeAuxiliarySubtypes = false;
}
mSortedImmis.clear();
mSortedImmis.putAll(immis);
for (InputMethodInfo imi : mSortedImmis.keySet()) {
@@ -227,7 +233,7 @@ public class InputMethodSubtypeSwitchingController {
final String subtypeHashCode = String.valueOf(subtype.hashCode());
// We show all enabled IMEs and subtypes when an IME is shown.
if (enabledSubtypeSet.contains(subtypeHashCode)
&& ((inputShown && !isScreenLocked) || !subtype.isAuxiliary())) {
&& (includeAuxiliarySubtypes || !subtype.isAuxiliary())) {
final CharSequence subtypeLabel =
subtype.overridesImplicitlyEnabledSubtype() ? null : subtype
.getDisplayName(mContext, imi.getPackageName(),
@@ -516,8 +522,8 @@ public class InputMethodSubtypeSwitchingController {
}
public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeListLocked(boolean showSubtypes,
boolean inputShown, boolean isScreenLocked) {
boolean includingAuxiliarySubtypes, boolean isScreenLocked) {
return mSubtypeList.getSortedInputMethodAndSubtypeList(
showSubtypes, inputShown, isScreenLocked);
showSubtypes, includingAuxiliarySubtypes, isScreenLocked);
}
}

View File

@@ -59,7 +59,8 @@ interface IInputMethodManager {
int controlFlags, int softInputMode, int windowFlags,
in EditorInfo attribute, IInputContext inputContext);
void showInputMethodPickerFromClient(in IInputMethodClient client);
void showInputMethodPickerFromClient(in IInputMethodClient client,
int auxiliarySubtypeMode);
void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
void setInputMethod(in IBinder token, String id);
void setInputMethodAndSubtype(in IBinder token, String id, in InputMethodSubtype subtype);

View File

@@ -162,7 +162,8 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
switchImeButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mCallback.userActivity(); // Leave the screen on a bit longer
mImm.showInputMethodPicker();
// Do not show auxiliary subtypes in password lock screen.
mImm.showInputMethodPicker(false /* showAuxiliarySubtypes */);
}
});
}

View File

@@ -144,7 +144,7 @@ public class NavigationBarView extends LinearLayout {
@Override
public void onClick(View view) {
((InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE))
.showInputMethodPicker();
.showInputMethodPicker(true /* showAuxiliarySubtypes */);
}
};

View File

@@ -2238,7 +2238,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
public void showInputMethodPickerFromClient(IInputMethodClient client) {
public void showInputMethodPickerFromClient(
IInputMethodClient client, int auxiliarySubtypeMode) {
if (!calledFromValidUser()) {
return;
}
@@ -2251,7 +2252,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Always call subtype picker, because subtype picker is a superset of input method
// picker.
mHandler.sendEmptyMessage(MSG_SHOW_IM_SUBTYPE_PICKER);
mHandler.sendMessage(mCaller.obtainMessageI(
MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode));
}
}
@@ -2597,7 +2599,25 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
SomeArgs args;
switch (msg.what) {
case MSG_SHOW_IM_SUBTYPE_PICKER:
showInputMethodMenu();
final boolean showAuxSubtypes;
switch (msg.arg1) {
case InputMethodManager.SHOW_IM_PICKER_MODE_AUTO:
// This is undocumented so far, but IMM#showInputMethodPicker() has been
// implemented so that auxiliary subtypes will be excluded when the soft
// keyboard is invisible.
showAuxSubtypes = mInputShown;
break;
case InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES:
showAuxSubtypes = true;
break;
case InputMethodManager.SHOW_IM_PICKER_MODE_EXCLUDE_AUXILIARY_SUBTYPES:
showAuxSubtypes = false;
break;
default:
Slog.e(TAG, "Unknown subtype picker mode = " + msg.arg1);
return false;
}
showInputMethodMenu(showAuxSubtypes);
return true;
case MSG_SHOW_IM_SUBTYPE_ENABLER:
@@ -2880,8 +2900,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
&& mKeyguardManager.isKeyguardLocked() && mKeyguardManager.isKeyguardSecure();
}
private void showInputMethodMenu() {
if (DEBUG) Slog.v(TAG, "Show switching menu");
private void showInputMethodMenu(boolean showAuxSubtypes) {
if (DEBUG) Slog.v(TAG, "Show switching menu. showAuxSubtypes=" + showAuxSubtypes);
final Context context = mContext;
final boolean isScreenLocked = isScreenLocked();
@@ -2902,7 +2922,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final List<ImeSubtypeListItem> imList =
mSwitchingController.getSortedInputMethodAndSubtypeListLocked(
true /* showSubtypes */, mInputShown, isScreenLocked);
true /* showSubtypes */, showAuxSubtypes, isScreenLocked);
if (lastInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {
final InputMethodSubtype currentSubtype = getCurrentInputMethodSubtypeLocked();