Merge "Consolidate InputMethodManager#toggleSoftInput reliability" into sc-dev

This commit is contained in:
Ming-Shin Lu
2021-04-27 02:32:35 +00:00
committed by Android (Google) Code Review
14 changed files with 98 additions and 80 deletions

View File

@@ -19315,7 +19315,7 @@ package android.inputmethodservice {
method public void appPrivateCommand(String, android.os.Bundle);
method public void displayCompletions(android.view.inputmethod.CompletionInfo[]);
method public void finishInput();
method public void toggleSoftInput(int, int);
method @Deprecated public void toggleSoftInput(int, int);
method public void updateCursor(android.graphics.Rect);
method public void updateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo);
method public void updateExtractedText(int, android.view.inputmethod.ExtractedText);
@@ -52000,8 +52000,8 @@ package android.view.inputmethod {
method @Deprecated public void showStatusIcon(android.os.IBinder, String, @DrawableRes int);
method @Deprecated public boolean switchToLastInputMethod(android.os.IBinder);
method @Deprecated public boolean switchToNextInputMethod(android.os.IBinder, boolean);
method public void toggleSoftInput(int, int);
method public void toggleSoftInputFromWindow(android.os.IBinder, int, int);
method @Deprecated public void toggleSoftInput(int, int);
method @Deprecated public void toggleSoftInputFromWindow(android.os.IBinder, int, int);
method @Deprecated public void updateCursor(android.view.View, int, int, int, int);
method public void updateCursorAnchorInfo(android.view.View, android.view.inputmethod.CursorAnchorInfo);
method public void updateExtractedText(android.view.View, int, android.view.inputmethod.ExtractedText);
@@ -52024,7 +52024,7 @@ package android.view.inputmethod {
method public void dispatchTrackballEvent(int, android.view.MotionEvent, android.view.inputmethod.InputMethodSession.EventCallback);
method public void displayCompletions(android.view.inputmethod.CompletionInfo[]);
method public void finishInput();
method public void toggleSoftInput(int, int);
method @Deprecated public void toggleSoftInput(int, int);
method public void updateCursor(android.graphics.Rect);
method public void updateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo);
method public void updateExtractedText(int, android.view.inputmethod.ExtractedText);

View File

@@ -49,7 +49,6 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
private static final int DO_UPDATE_CURSOR = 95;
private static final int DO_UPDATE_CURSOR_ANCHOR_INFO = 99;
private static final int DO_APP_PRIVATE_COMMAND = 100;
private static final int DO_TOGGLE_SOFT_INPUT = 105;
private static final int DO_FINISH_SESSION = 110;
private static final int DO_VIEW_CLICKED = 115;
private static final int DO_NOTIFY_IME_HIDDEN = 120;
@@ -123,10 +122,6 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
args.recycle();
return;
}
case DO_TOGGLE_SOFT_INPUT: {
mInputMethodSession.toggleSoftInput(msg.arg1, msg.arg2);
return;
}
case DO_FINISH_SESSION: {
doFinishSession();
return;
@@ -217,12 +212,6 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
mCaller.obtainMessageOO(DO_APP_PRIVATE_COMMAND, action, data));
}
@Override
public void toggleSoftInput(int showFlags, int hideFlags) {
mCaller.executeOrSendMessage(
mCaller.obtainMessageII(DO_TOGGLE_SOFT_INPUT, showFlags, hideFlags));
}
@Override
public void finishSession() {
mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_SESSION));

View File

@@ -1042,8 +1042,14 @@ public class InputMethodService extends AbstractInputMethodService {
}
/**
*
* Handles a request to toggle the IME visibility.
*
* @deprecated Starting in {@link Build.VERSION_CODES#S} the system no longer invokes this
* method, instead it explicitly shows or hides the IME. An {@code InputMethodService}
* wishing to toggle its own visibility should instead invoke {@link
* InputMethodService#requestShowSelf} or {@link InputMethodService#requestHideSelf}
*/
@Deprecated
public void toggleSoftInput(int showFlags, int hideFlags) {
InputMethodService.this.onToggleSoftInput(showFlags, hideFlags);
}

View File

@@ -256,18 +256,6 @@ final class MultiClientInputMethodClientCallbackAdaptor {
}
}
@Override
public void toggleSoftInput(int showFlags, int hideFlags) {
synchronized (mSessionLock) {
if (mCallbackImpl == null || mHandler == null) {
return;
}
mHandler.sendMessage(PooledLambda.obtainMessage(
CallbackImpl::toggleSoftInput, mCallbackImpl, showFlags,
hideFlags));
}
}
@Override
public void finishSession() {
synchronized (mSessionLock) {
@@ -419,13 +407,6 @@ final class MultiClientInputMethodClientCallbackAdaptor {
mOriginalCallback.onAppPrivateCommand(action, data);
}
void toggleSoftInput(int showFlags, int hideFlags) {
if (mFinished) {
return;
}
mOriginalCallback.onToggleSoftInput(showFlags, hideFlags);
}
void finishSession() {
if (mFinished) {
return;

View File

@@ -165,16 +165,6 @@ public final class MultiClientInputMethodServiceDelegate {
@SoftInputModeFlags int softInputMode,
int targetWindowHandle);
/**
* Called when the associated IME client called {@link
* android.view.inputmethod.InputMethodManager#toggleSoftInput(int, int)}.
*
* @param showFlags The flag passed by the client.
* @param hideFlags The flag passed by the client.
* @see android.inputmethodservice.InputMethodService#onToggleSoftInput(int, int)
*/
void onToggleSoftInput(int showFlags, int hideFlags);
/**
* Called when the associated IME client called {@link
* android.view.inputmethod.InputMethodManager#updateCursorAnchorInfo(View,

View File

@@ -93,6 +93,7 @@ import com.android.internal.inputmethod.Completable;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
import com.android.internal.inputmethod.ResultCallbacks;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;
import com.android.internal.inputmethod.UnbindReason;
@@ -1696,6 +1697,11 @@ public final class InputMethodManager {
* {@link #RESULT_HIDDEN}.
*/
public boolean showSoftInput(View view, int flags, ResultReceiver resultReceiver) {
return showSoftInput(view, flags, resultReceiver, SoftInputShowHideReason.SHOW_SOFT_INPUT);
}
private boolean showSoftInput(View view, int flags, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason) {
ImeTracing.getInstance().triggerClientDump("InputMethodManager#showSoftInput", this,
null /* icProto */);
// Re-dispatch if there is a context mismatch.
@@ -1719,6 +1725,7 @@ public final class InputMethodManager {
view.getWindowToken(),
flags,
resultReceiver,
reason,
ResultCallbacks.of(value));
return Completable.getResult(value);
} catch (RemoteException e) {
@@ -1753,6 +1760,7 @@ public final class InputMethodManager {
mCurRootView.getView().getWindowToken(),
flags,
resultReceiver,
SoftInputShowHideReason.SHOW_SOFT_INPUT,
ResultCallbacks.of(value));
Completable.getResult(value); // ignore the result
} catch (RemoteException e) {
@@ -1817,6 +1825,12 @@ public final class InputMethodManager {
*/
public boolean hideSoftInputFromWindow(IBinder windowToken, int flags,
ResultReceiver resultReceiver) {
return hideSoftInputFromWindow(windowToken, flags, resultReceiver,
SoftInputShowHideReason.HIDE_SOFT_INPUT);
}
private boolean hideSoftInputFromWindow(IBinder windowToken, int flags,
ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
ImeTracing.getInstance().triggerClientDump("InputMethodManager#hideSoftInputFromWindow",
this, null /* icProto */);
checkFocus();
@@ -1828,8 +1842,8 @@ public final class InputMethodManager {
try {
final Completable.Boolean value = Completable.createBoolean();
mService.hideSoftInput(
mClient, windowToken, flags, resultReceiver, ResultCallbacks.of(value));
mService.hideSoftInput(mClient, windowToken, flags, resultReceiver, reason,
ResultCallbacks.of(value));
return Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1849,7 +1863,14 @@ public final class InputMethodManager {
* @param hideFlags Provides additional operating flags. May be
* 0 or have the {@link #HIDE_IMPLICIT_ONLY},
* {@link #HIDE_NOT_ALWAYS} bit set.
**/
*
* @deprecated Use {@link #showSoftInput(View, int)} or
* {@link #hideSoftInputFromWindow(IBinder, int)} explicitly instead.
* In particular during focus changes, the current visibility of the IME is not
* well defined. Starting in {@link Build.VERSION_CODES#S Android S}, this only
* has an effect if the calling app is the current IME focus.
*/
@Deprecated
public void toggleSoftInputFromWindow(IBinder windowToken, int showFlags, int hideFlags) {
ImeTracing.getInstance().triggerClientDump(
"InputMethodManager#toggleSoftInputFromWindow", InputMethodManager.this,
@@ -1859,9 +1880,7 @@ public final class InputMethodManager {
if (servedView == null || servedView.getWindowToken() != windowToken) {
return;
}
if (mCurrentInputMethodSession != null) {
mCurrentInputMethodSession.toggleSoftInput(showFlags, hideFlags);
}
toggleSoftInput(showFlags, hideFlags);
}
}
@@ -1876,13 +1895,29 @@ public final class InputMethodManager {
* @param hideFlags Provides additional operating flags. May be
* 0 or have the {@link #HIDE_IMPLICIT_ONLY},
* {@link #HIDE_NOT_ALWAYS} bit set.
*
* @deprecated Use {@link #showSoftInput(View, int)} or
* {@link #hideSoftInputFromWindow(IBinder, int)} explicitly instead.
* In particular during focus changes, the current visibility of the IME is not
* well defined. Starting in {@link Build.VERSION_CODES#S Android S}, this only
* has an effect if the calling app is the current IME focus.
*/
@Deprecated
public void toggleSoftInput(int showFlags, int hideFlags) {
ImeTracing.getInstance().triggerClientDump(
"InputMethodManager#toggleSoftInput", InputMethodManager.this,
null /* icProto */);
if (mCurrentInputMethodSession != null) {
mCurrentInputMethodSession.toggleSoftInput(showFlags, hideFlags);
synchronized (mH) {
final View view = getServedViewLocked();
if (mImeInsetsConsumer != null && view != null) {
if (mImeInsetsConsumer.isRequestedVisible()) {
hideSoftInputFromWindow(view.getWindowToken(), hideFlags, null,
SoftInputShowHideReason.HIDE_TOGGLE_SOFT_INPUT);
} else {
showSoftInput(view, showFlags, null,
SoftInputShowHideReason.SHOW_TOGGLE_SOFT_INPUT);
}
}
}
}
@@ -2166,6 +2201,7 @@ public final class InputMethodManager {
mCurRootView.getView().getWindowToken(),
HIDE_NOT_ALWAYS,
null,
SoftInputShowHideReason.HIDE_SOFT_INPUT,
ResultCallbacks.of(value));
Completable.getResult(value); // ignore the result
} catch (RemoteException e) {

View File

@@ -17,6 +17,8 @@
package android.view.inputmethod;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -172,7 +174,13 @@ public interface InputMethodSession {
* @param hideFlags Provides additional operating flags. May be
* 0 or have the {@link InputMethodManager#HIDE_IMPLICIT_ONLY},
* {@link InputMethodManager#HIDE_NOT_ALWAYS} bit set.
*
* @deprecated Starting in {@link Build.VERSION_CODES#S} the system no longer invokes this
* method, instead it explicitly shows or hides the IME. An {@code InputMethodService}
* wishing to toggle its own visibility should instead invoke {@link
* InputMethodService#requestShowSelf} or {@link InputMethodService#requestHideSelf}
*/
@Deprecated
public void toggleSoftInput(int showFlags, int hideFlags);
/**

View File

@@ -95,15 +95,6 @@ final class InputMethodSessionWrapper {
}
}
@AnyThread
void toggleSoftInput(int showFlags, int hideFlags) {
try {
mSession.toggleSoftInput(showFlags, hideFlags);
} catch (RemoteException e) {
Log.w(TAG, "IME died", e);
}
}
@AnyThread
void appPrivateCommand(String action, Bundle data) {
try {

View File

@@ -230,6 +230,10 @@ public final class InputMethodDebug {
return "HIDE_REMOVE_CLIENT";
case SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY:
return "SHOW_RESTORE_IME_VISIBILITY";
case SoftInputShowHideReason.SHOW_TOGGLE_SOFT_INPUT:
return "SHOW_TOGGLE_SOFT_INPUT";
case SoftInputShowHideReason.HIDE_TOGGLE_SOFT_INPUT:
return "HIDE_TOGGLE_SOFT_INPUT";
default:
return "Unknown=" + reason;
}

View File

@@ -50,7 +50,9 @@ import java.lang.annotation.Retention;
SoftInputShowHideReason.HIDE_BUBBLES,
SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR,
SoftInputShowHideReason.HIDE_REMOVE_CLIENT,
SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY})
SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY,
SoftInputShowHideReason.SHOW_TOGGLE_SOFT_INPUT,
SoftInputShowHideReason.HIDE_TOGGLE_SOFT_INPUT})
public @interface SoftInputShowHideReason {
/** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */
int SHOW_SOFT_INPUT = 0;
@@ -174,4 +176,16 @@ public @interface SoftInputShowHideReason {
* {@link com.android.server.wm.WindowManagerInternal#shouldRestoreImeVisibility}.
*/
int SHOW_RESTORE_IME_VISIBILITY = 22;
/**
* Show soft input by
* {@link android.view.inputmethod.InputMethodManager#toggleSoftInput(int, int)};
*/
int SHOW_TOGGLE_SOFT_INPUT = 23;
/**
* Hide soft input by
* {@link android.view.inputmethod.InputMethodManager#toggleSoftInput(int, int)};
*/
int HIDE_TOGGLE_SOFT_INPUT = 24;
}

View File

@@ -52,9 +52,9 @@ interface IInputMethodManager {
oneway void getLastInputMethodSubtype(in IInputMethodSubtypeResultCallback resultCallback);
oneway void showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags,
in ResultReceiver resultReceiver, in IBooleanResultCallback resultCallback);
in ResultReceiver resultReceiver, int reason, in IBooleanResultCallback resultCallback);
oneway void hideSoftInput(in IInputMethodClient client, IBinder windowToken, int flags,
in ResultReceiver resultReceiver, in IBooleanResultCallback resultCallback);
in ResultReceiver resultReceiver, int reason, in IBooleanResultCallback resultCallback);
// If windowToken is null, this just does startInput(). Otherwise this reports that a window
// has gained focus, and if 'attribute' is non-null then also does startInput.
// @NonNull

View File

@@ -43,8 +43,6 @@ oneway interface IInputMethodSession {
void appPrivateCommand(String action, in Bundle data);
void toggleSoftInput(int showFlags, int hideFlags);
void finishSession();
void updateCursorAnchorInfo(in CursorAnchorInfo cursorAnchorInfo);

View File

@@ -3143,7 +3143,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void showSoftInput(IInputMethodClient client, IBinder windowToken, int flags,
ResultReceiver resultReceiver, IBooleanResultCallback resultCallback) {
ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
IBooleanResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showSoftInput");
int uid = Binder.getCallingUid();
@@ -3172,8 +3173,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
return showCurrentInputLocked(windowToken, flags, resultReceiver,
SoftInputShowHideReason.SHOW_SOFT_INPUT);
return showCurrentInputLocked(windowToken, flags, resultReceiver, reason);
} finally {
Binder.restoreCallingIdentity(ident);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -3262,7 +3262,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void hideSoftInput(IInputMethodClient client, IBinder windowToken, int flags,
ResultReceiver resultReceiver, IBooleanResultCallback resultCallback) {
ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
IBooleanResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> {
int uid = Binder.getCallingUid();
ImeTracing.getInstance().triggerManagerServiceDump(
@@ -3296,8 +3297,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
return InputMethodManagerService.this.hideCurrentInputLocked(windowToken,
flags, resultReceiver,
SoftInputShowHideReason.HIDE_SOFT_INPUT);
flags, resultReceiver, reason);
} finally {
Binder.restoreCallingIdentity(ident);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -3326,8 +3326,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// since Android Eclair. That's why we need to accept IMM#hideSoftInput() even when only
// IMMS#InputShown indicates that the software keyboard is shown.
// TODO: Clean up, IMMS#mInputShown, IMMS#mImeWindowVis and mShowRequested.
final boolean shouldHideSoftInput = (mCurMethod != null) && (mInputShown ||
(mImeWindowVis & InputMethodService.IME_ACTIVE) != 0);
final boolean shouldHideSoftInput = (mCurMethod != null) && (mInputShown
|| (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0);
boolean res;
if (shouldHideSoftInput) {
final Binder hideInputToken = new Binder();
@@ -4476,7 +4476,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
((IInputMethod) args.arg1).showSoftInput(
(IBinder) args.arg3, msg.arg1, (ResultReceiver) args.arg2);
mSoftInputShowHideHistory.addEntry(new SoftInputShowHideHistory.Entry(
mCurClient, mCurAttribute,
mCurFocusedWindowClient, mCurAttribute,
mWindowManagerInternal.getWindowName(mCurFocusedWindow),
mCurFocusedWindowSoftInputMode, reason, mInFullscreenMode,
mWindowManagerInternal.getWindowName(
@@ -4499,7 +4499,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
((IInputMethod)args.arg1).hideSoftInput(
(IBinder) args.arg3, 0, (ResultReceiver)args.arg2);
mSoftInputShowHideHistory.addEntry(new SoftInputShowHideHistory.Entry(
mCurClient, mCurAttribute,
mCurFocusedWindowClient, mCurAttribute,
mWindowManagerInternal.getWindowName(mCurFocusedWindow),
mCurFocusedWindowSoftInputMode, reason, mInFullscreenMode,
mWindowManagerInternal.getWindowName(

View File

@@ -1521,8 +1521,8 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
public void showSoftInput(
IInputMethodClient client, IBinder token, int flags,
ResultReceiver resultReceiver, IBooleanResultCallback resultCallback) {
IInputMethodClient client, IBinder token, int flags, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason, IBooleanResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> showSoftInputInternal(client, token, flags, resultReceiver));
}
@@ -1577,7 +1577,8 @@ public final class MultiClientInputMethodManagerService {
@Override
public void hideSoftInput(
IInputMethodClient client, IBinder windowToken, int flags,
ResultReceiver resultReceiver, IBooleanResultCallback resultCallback) {
ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
IBooleanResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> hideSoftInputInternal(client, windowToken, flags, resultReceiver));