Merge "Support IME switcher icon visibility update"

This commit is contained in:
Yohei Yukawa
2022-01-29 00:42:58 +00:00
committed by Android (Google) Code Review
8 changed files with 157 additions and 23 deletions

View File

@@ -70,6 +70,7 @@ class IInputMethodWrapper extends IInputMethod.Stub
private static final int DO_SET_INPUT_CONTEXT = 20;
private static final int DO_UNSET_INPUT_CONTEXT = 30;
private static final int DO_START_INPUT = 32;
private static final int DO_ON_SHOULD_SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN_CHANGED = 35;
private static final int DO_CREATE_SESSION = 40;
private static final int DO_SET_SESSION_ENABLED = 45;
private static final int DO_SHOW_SOFT_INPUT = 60;
@@ -175,7 +176,7 @@ class IInputMethodWrapper extends IInputMethod.Stub
try {
inputMethod.initializeInternal((IBinder) args.arg1,
(IInputMethodPrivilegedOperations) args.arg2, msg.arg1,
(boolean) args.arg3);
(boolean) args.arg3, msg.arg2 != 0);
} finally {
args.recycle();
}
@@ -195,14 +196,22 @@ class IInputMethodWrapper extends IInputMethod.Stub
final EditorInfo info = (EditorInfo) args.arg3;
final CancellationGroup cancellationGroup = (CancellationGroup) args.arg4;
final boolean restarting = args.argi5 == 1;
final boolean shouldShowImeSwitcherWhenImeIsShown = args.argi6 != 0;
final InputConnection ic = inputContext != null
? new RemoteInputConnection(mTarget, inputContext, cancellationGroup)
: null;
info.makeCompatible(mTargetSdkVersion);
inputMethod.dispatchStartInputWithToken(ic, info, restarting, startInputToken);
inputMethod.dispatchStartInputWithToken(ic, info, restarting, startInputToken,
shouldShowImeSwitcherWhenImeIsShown);
args.recycle();
return;
}
case DO_ON_SHOULD_SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN_CHANGED: {
final boolean shouldShowImeSwitcherWhenImeIsShown = msg.arg1 != 0;
inputMethod.onShouldShowImeSwitcherWhenImeIsShownChanged(
shouldShowImeSwitcherWhenImeIsShown);
return;
}
case DO_CREATE_SESSION: {
SomeArgs args = (SomeArgs)msg.obj;
inputMethod.createSession(new InputMethodSessionCallbackWrapper(
@@ -291,10 +300,11 @@ class IInputMethodWrapper extends IInputMethod.Stub
@BinderThread
@Override
public void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privOps,
int configChanges, boolean stylusHwSupported) {
mCaller.executeOrSendMessage(
mCaller.obtainMessageIOOO(
DO_INITIALIZE_INTERNAL, configChanges, token, privOps, stylusHwSupported));
int configChanges, boolean stylusHwSupported,
boolean shouldShowImeSwitcherWhenImeIsShown) {
mCaller.executeOrSendMessage(mCaller.obtainMessageIIOOO(DO_INITIALIZE_INTERNAL,
configChanges, shouldShowImeSwitcherWhenImeIsShown ? 1 : 0, token, privOps,
stylusHwSupported));
}
@BinderThread
@@ -334,13 +344,23 @@ class IInputMethodWrapper extends IInputMethod.Stub
@BinderThread
@Override
public void startInput(IBinder startInputToken, IInputContext inputContext,
EditorInfo attribute, boolean restarting) {
EditorInfo attribute, boolean restarting, boolean shouldShowImeSwitcherWhenImeIsShown) {
if (mCancellationGroup == null) {
Log.e(TAG, "startInput must be called after bindInput.");
mCancellationGroup = new CancellationGroup();
}
mCaller.executeOrSendMessage(mCaller.obtainMessageOOOOII(DO_START_INPUT, startInputToken,
inputContext, attribute, mCancellationGroup, restarting ? 1 : 0, 0 /* unused */));
inputContext, attribute, mCancellationGroup, restarting ? 1 : 0,
shouldShowImeSwitcherWhenImeIsShown ? 1 : 0));
}
@BinderThread
@Override
public void onShouldShowImeSwitcherWhenImeIsShownChanged(
boolean shouldShowImeSwitcherWhenImeIsShown) {
mCaller.executeOrSendMessage(mCaller.obtainMessageI(
DO_ON_SHOULD_SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN_CHANGED,
shouldShowImeSwitcherWhenImeIsShown ? 1 : 0));
}
@BinderThread

View File

@@ -658,7 +658,7 @@ public class InputMethodService extends AbstractInputMethodService {
@Override
public final void initializeInternal(@NonNull IBinder token,
IInputMethodPrivilegedOperations privilegedOperations, int configChanges,
boolean stylusHwSupported) {
boolean stylusHwSupported, boolean shouldShowImeSwitcherWhenImeIsShown) {
if (mDestroyed) {
Log.i(TAG, "The InputMethodService has already onDestroyed()."
+ "Ignore the initialization.");
@@ -671,6 +671,8 @@ public class InputMethodService extends AbstractInputMethodService {
if (stylusHwSupported) {
mInkWindow = new InkWindow(mWindow.getContext());
}
mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
shouldShowImeSwitcherWhenImeIsShown);
attachToken(token);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
@@ -780,9 +782,10 @@ public class InputMethodService extends AbstractInputMethodService {
@Override
public final void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
@NonNull EditorInfo editorInfo, boolean restarting,
@NonNull IBinder startInputToken) {
@NonNull IBinder startInputToken, boolean shouldShowImeSwitcherWhenImeIsShown) {
mPrivOps.reportStartInputAsync(startInputToken);
mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
shouldShowImeSwitcherWhenImeIsShown);
if (restarting) {
restartInput(inputConnection, editorInfo);
} else {
@@ -790,6 +793,18 @@ public class InputMethodService extends AbstractInputMethodService {
}
}
/**
* {@inheritDoc}
* @hide
*/
@MainThread
@Override
public void onShouldShowImeSwitcherWhenImeIsShownChanged(
boolean shouldShowImeSwitcherWhenImeIsShown) {
mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
shouldShowImeSwitcherWhenImeIsShown);
}
/**
* {@inheritDoc}
* @hide

View File

@@ -74,6 +74,10 @@ final class NavigationBarController {
default void onDestroy() {
}
default void setShouldShowImeSwitcherWhenImeIsShown(
boolean shouldShowImeSwitcherWhenImeIsShown) {
}
default void onSystemBarAppearanceChanged(@Appearance int appearance) {
}
@@ -109,6 +113,10 @@ final class NavigationBarController {
mImpl.onDestroy();
}
void setShouldShowImeSwitcherWhenImeIsShown(boolean shouldShowImeSwitcherWhenImeIsShown) {
mImpl.setShouldShowImeSwitcherWhenImeIsShown(shouldShowImeSwitcherWhenImeIsShown);
}
void onSystemBarAppearanceChanged(@Appearance int appearance) {
mImpl.onSystemBarAppearanceChanged(appearance);
}
@@ -139,6 +147,8 @@ final class NavigationBarController {
@Nullable
private BroadcastReceiver mSystemOverlayChangedReceiver;
private boolean mShouldShowImeSwitcherWhenImeIsShown;
@Appearance
private int mAppearance;
@@ -205,7 +215,9 @@ final class NavigationBarController {
// TODO(b/213337792): Support InputMethodService#setBackDisposition().
// TODO(b/213337792): Set NAVIGATION_HINT_IME_SHOWN only when necessary.
final int hints = StatusBarManager.NAVIGATION_HINT_BACK_ALT
| StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
| (mShouldShowImeSwitcherWhenImeIsShown
? StatusBarManager.NAVIGATION_HINT_IME_SHOWN
: 0);
navigationBarView.setNavigationIconHints(hints);
}
} else {
@@ -422,6 +434,31 @@ final class NavigationBarController {
}
}
@Override
public void setShouldShowImeSwitcherWhenImeIsShown(
boolean shouldShowImeSwitcherWhenImeIsShown) {
if (mDestroyed) {
return;
}
if (mShouldShowImeSwitcherWhenImeIsShown == shouldShowImeSwitcherWhenImeIsShown) {
return;
}
mShouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherWhenImeIsShown;
if (mNavigationBarFrame == null) {
return;
}
final NavigationBarView navigationBarView =
mNavigationBarFrame.findViewByPredicate(NavigationBarView.class::isInstance);
if (navigationBarView == null) {
return;
}
final int hints = StatusBarManager.NAVIGATION_HINT_BACK_ALT
| (shouldShowImeSwitcherWhenImeIsShown
? StatusBarManager.NAVIGATION_HINT_IME_SHOWN : 0);
navigationBarView.setNavigationIconHints(hints);
}
@Override
public void onSystemBarAppearanceChanged(@Appearance int appearance) {
if (mDestroyed) {
@@ -471,6 +508,7 @@ final class NavigationBarController {
public String toDebugString() {
return "{mRenderGesturalNavButtons=" + mRenderGesturalNavButtons
+ " mNavigationBarFrame=" + mNavigationBarFrame
+ " mShouldShowImeSwitcherWhenImeIsShown" + mShouldShowImeSwitcherWhenImeIsShown
+ " mAppearance=0x" + Integer.toHexString(mAppearance)
+ " mDarkIntensity=" + mDarkIntensity
+ "}";

View File

@@ -105,12 +105,14 @@ public interface InputMethod {
* current IME.
* @param configChanges {@link InputMethodInfo#getConfigChanges()} declared by IME.
* @param stylusHwSupported {@link InputMethodInfo#supportsStylusHandwriting()} declared by IME.
* @param shouldShowImeSwitcherWhenImeIsShown {@code true} If the IME switcher is expected to be
* shown while the IME is shown.
* @hide
*/
@MainThread
default void initializeInternal(IBinder token,
IInputMethodPrivilegedOperations privilegedOperations, int configChanges,
boolean stylusHwSupported) {
boolean stylusHwSupported, boolean shouldShowImeSwitcherWhenImeIsShown) {
attachToken(token);
}
@@ -229,6 +231,8 @@ public interface InputMethod {
* the next {@link #startInput(InputConnection, EditorInfo, IBinder)} as
* long as your implementation of {@link InputMethod} relies on such
* IPCs
* @param shouldShowImeSwitcherWhenImeIsShown {@code true} If the IME switcher is expected to be
* shown while the IME is shown.
* @see #startInput(InputConnection, EditorInfo)
* @see #restartInput(InputConnection, EditorInfo)
* @see EditorInfo
@@ -237,7 +241,7 @@ public interface InputMethod {
@MainThread
default void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
@NonNull EditorInfo editorInfo, boolean restarting,
@NonNull IBinder startInputToken) {
@NonNull IBinder startInputToken, boolean shouldShowImeSwitcherWhenImeIsShown) {
if (restarting) {
restartInput(inputConnection, editorInfo);
} else {
@@ -245,6 +249,18 @@ public interface InputMethod {
}
}
/**
* Notifies that whether the IME should show the IME switcher or not is being changed.
*
* @param shouldShowImeSwitcherWhenImeIsShown {@code true} If the IME switcher is expected to be
* shown while the IME is shown.
* @hide
*/
@MainThread
default void onShouldShowImeSwitcherWhenImeIsShownChanged(
boolean shouldShowImeSwitcherWhenImeIsShown) {
}
/**
* Create a new {@link InputMethodSession} that can be handed to client
* applications for interacting with the input method. You can later

View File

@@ -37,7 +37,8 @@ import com.android.internal.view.InlineSuggestionsRequestInfo;
*/
oneway interface IInputMethod {
void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privOps,
int configChanges, boolean stylusHwSupported);
int configChanges, boolean stylusHwSupported,
boolean shouldShowImeSwitcherWhenImeIsShown);
void onCreateInlineSuggestionsRequest(in InlineSuggestionsRequestInfo requestInfo,
in IInlineSuggestionsRequestCallback cb);
@@ -47,7 +48,10 @@ oneway interface IInputMethod {
void unbindInput();
void startInput(in IBinder startInputToken, in IInputContext inputContext,
in EditorInfo attribute, boolean restarting);
in EditorInfo attribute, boolean restarting,
boolean shouldShowImeSwitcherWhenImeIsShown);
void onShouldShowImeSwitcherWhenImeIsShownChanged(boolean shouldShowImeSwitcherWhenImeIsShown);
void createSession(in InputChannel channel, IInputSessionCallback callback);

View File

@@ -107,9 +107,11 @@ final class IInputMethodInvoker {
@AnyThread
void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privOps,
int configChanges, boolean stylusHwSupported) {
int configChanges, boolean stylusHwSupported,
boolean shouldShowImeSwitcherWhenImeIsShown) {
try {
mTarget.initializeInternal(token, privOps, configChanges, stylusHwSupported);
mTarget.initializeInternal(token, privOps, configChanges, stylusHwSupported,
shouldShowImeSwitcherWhenImeIsShown);
} catch (RemoteException e) {
logRemoteException(e);
}
@@ -145,9 +147,20 @@ final class IInputMethodInvoker {
@AnyThread
void startInput(IBinder startInputToken, IInputContext inputContext, EditorInfo attribute,
boolean restarting) {
boolean restarting, boolean shouldShowImeSwitcherWhenImeIsShown) {
try {
mTarget.startInput(startInputToken, inputContext, attribute, restarting);
mTarget.startInput(startInputToken, inputContext, attribute, restarting,
shouldShowImeSwitcherWhenImeIsShown);
} catch (RemoteException e) {
logRemoteException(e);
}
}
@AnyThread
void onShouldShowImeSwitcherWhenImeIsShownChanged(boolean shouldShowImeSwitcherWhenImeIsShown) {
try {
mTarget.onShouldShowImeSwitcherWhenImeIsShownChanged(
shouldShowImeSwitcherWhenImeIsShown);
} catch (RemoteException e) {
logRemoteException(e);
}

View File

@@ -2325,10 +2325,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
true /* direct */);
}
final boolean shouldShowImeSwitcherWhenImeIsShown =
shouldShowImeSwitcherWhenImeIsShownLocked();
final SessionState session = mCurClient.curSession;
setEnabledSessionLocked(session);
session.method.startInput(startInputToken, mCurInputContext, mCurAttribute, restarting);
session.method.startInput(startInputToken, mCurInputContext, mCurAttribute, restarting,
shouldShowImeSwitcherWhenImeIsShown);
if (mShowRequested) {
if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
showCurrentInputLocked(mCurFocusedWindow, getAppShowFlagsLocked(), null,
@@ -2528,7 +2530,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
+ mCurTokenDisplayId);
}
inputMethod.initializeInternal(token, new InputMethodPrivilegedOperationsImpl(this, token),
configChanges, supportStylusHw);
configChanges, supportStylusHw, shouldShowImeSwitcherWhenImeIsShownLocked());
}
@AnyThread
@@ -2730,6 +2732,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
}
@GuardedBy("ImfLock.class")
boolean shouldShowImeSwitcherWhenImeIsShownLocked() {
return shouldShowImeSwitcherLocked(
InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE);
}
@GuardedBy("ImfLock.class")
private boolean shouldShowImeSwitcherLocked(int visibility) {
if (!mShowOngoingImeSwitcherForPhones) return false;
@@ -2990,6 +2998,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// the same enabled IMEs list.
mSwitchingController.resetCircularListLocked(mContext);
sendShouldShowImeSwitcherWhenImeIsShownLocked();
}
@GuardedBy("ImfLock.class")
@@ -4308,6 +4317,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
updateImeWindowStatus(msg.arg1 == 1);
return true;
}
// ---------------------------------------------------------
case MSG_UNBIND_CLIENT:
@@ -4368,6 +4378,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// --------------------------------------------------------------
case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
mMenuController.handleHardKeyboardStatusChange(msg.arg1 == 1);
synchronized (ImfLock.class) {
sendShouldShowImeSwitcherWhenImeIsShownLocked();
}
return true;
case MSG_SYSTEM_UNLOCK_USER: {
final int userId = msg.arg1;
@@ -4638,12 +4651,25 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// the same enabled IMEs list.
mSwitchingController.resetCircularListLocked(mContext);
sendShouldShowImeSwitcherWhenImeIsShownLocked();
// Notify InputMethodListListeners of the new installed InputMethods.
final List<InputMethodInfo> inputMethodList = new ArrayList<>(mMethodList);
mHandler.obtainMessage(MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED,
mSettings.getCurrentUserId(), 0 /* unused */, inputMethodList).sendToTarget();
}
@GuardedBy("ImfLock.class")
void sendShouldShowImeSwitcherWhenImeIsShownLocked() {
final IInputMethodInvoker curMethod = mBindingController.getCurMethod();
if (curMethod == null) {
// No need to send the data if the IME is not yet bound.
return;
}
curMethod.onShouldShowImeSwitcherWhenImeIsShownChanged(
shouldShowImeSwitcherWhenImeIsShownLocked());
}
@GuardedBy("ImfLock.class")
private void updateDefaultVoiceImeIfNeededLocked() {
final String systemSpeechRecognizer =

View File

@@ -203,6 +203,7 @@ final class InputMethodMenuController {
attrs.setTitle("Select input method");
w.setAttributes(attrs);
mService.updateSystemUiLocked();
mService.sendShouldShowImeSwitcherWhenImeIsShownLocked();
mSwitchingDialog.show();
}
}
@@ -238,6 +239,7 @@ final class InputMethodMenuController {
mSwitchingDialogTitleView = null;
mService.updateSystemUiLocked();
mService.sendShouldShowImeSwitcherWhenImeIsShownLocked();
mDialogBuilder = null;
mIms = null;
}