diff options
| author | lpeter <lpeter@google.com> | 2020-03-05 20:32:16 +0800 |
|---|---|---|
| committer | lpeter <lpeter@google.com> | 2020-03-20 12:16:44 +0800 |
| commit | 133fce01713ddd03fdcb36bc40fa01ccddb02dc0 (patch) | |
| tree | 83581bffdbf64fea8813fe17c4b7b64e15c95ef3 | |
| parent | 3fe090f73747cd78a61a60c1588deae9b9350e9e (diff) | |
Move the logic of transferTouchFocusToImeWindow to IMMS.
It would better move logic of transferTouchFocusToImeWindow
from WindowManagerService to InputMethodManagerService.
Bug: 149574510
Test: atest CtsAutoFillServiceTestCases
Test: atest CtsInputMethodTestCases
Change-Id: I268b09781e5eb7c77c4912efdc8fd5d6936ada27
8 files changed, 112 insertions, 41 deletions
diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java index d8da548d9bd3..f6cd726dda4a 100644 --- a/core/java/android/hardware/input/InputManagerInternal.java +++ b/core/java/android/hardware/input/InputManagerInternal.java @@ -16,7 +16,9 @@ package android.hardware.input; +import android.annotation.NonNull; import android.hardware.display.DisplayViewport; +import android.os.IBinder; import android.view.InputEvent; import java.util.List; @@ -59,4 +61,21 @@ public abstract class InputManagerInternal { * Set whether the input stack should deliver pulse gesture events when the device is asleep. */ public abstract void setPulseGestureEnabled(boolean enabled); + + /** + * Atomically transfers touch focus from one window to another as identified by + * their input channels. It is possible for multiple windows to have + * touch focus if they support split touch dispatch + * {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this + * method only transfers touch focus of the specified window without affecting + * other windows that may also have touch focus at the same time. + * + * @param fromChannelToken The channel token of a window that currently has touch focus. + * @param toChannelToken The channel token of the window that should receive touch focus in + * place of the first. + * @return {@code true} if the transfer was successful. {@code false} if the window with the + * specified channel did not actually have touch focus at the time of the request. + */ + public abstract boolean transferTouchFocus(@NonNull IBinder fromChannelToken, + @NonNull IBinder toChannelToken); } diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java index 71d4acec7c6a..c26d7eea8351 100644 --- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java +++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java @@ -44,7 +44,7 @@ import com.android.internal.view.inline.IInlineContentProvider; import com.android.server.LocalServices; import com.android.server.UiThread; import com.android.server.autofill.RemoteInlineSuggestionRenderService; -import com.android.server.wm.WindowManagerInternal; +import com.android.server.inputmethod.InputMethodManagerInternal; import java.util.ArrayList; import java.util.List; @@ -312,10 +312,9 @@ public final class InlineSuggestionFactory { @Override public void onTransferTouchFocusToImeWindow(IBinder sourceInputToken, int displayId) throws RemoteException { - //TODO(b/149574510): Move logic to IMMS - final WindowManagerInternal windowManagerInternal = LocalServices.getService( - WindowManagerInternal.class); - if (!windowManagerInternal.transferTouchFocusToImeWindow(sourceInputToken, + final InputMethodManagerInternal inputMethodManagerInternal = + LocalServices.getService(InputMethodManagerInternal.class); + if (!inputMethodManagerInternal.transferTouchFocusToImeWindow(sourceInputToken, displayId)) { Slog.e(TAG, "Cannot transfer touch focus from suggestion to IME"); onErrorCallback.run(); diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index ca06b47a6e80..065e0c3e45c8 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -2465,5 +2465,11 @@ public class InputManagerService extends IInputManager.Stub } } } + + @Override + public boolean transferTouchFocus(@NonNull IBinder fromChannelToken, + @NonNull IBinder toChannelToken) { + return InputManagerService.this.transferTouchFocus(fromChannelToken, toChannelToken); + } } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java index 68e6c1885ec2..d49d4b2c3278 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java @@ -18,6 +18,7 @@ package com.android.server.inputmethod; import android.annotation.NonNull; import android.annotation.UserIdInt; +import android.os.IBinder; import android.view.inputmethod.InlineSuggestionsRequest; import android.view.inputmethod.InputMethodInfo; @@ -92,6 +93,16 @@ public abstract class InputMethodManagerInternal { public abstract void registerInputMethodListListener(InputMethodListListener listener); /** + * Transfers input focus from a given input token to that of the IME window. + * + * @param sourceInputToken The source token. + * @param displayId The display hosting the IME window. + * @return {@code true} if the transfer is successful. + */ + public abstract boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken, + int displayId); + + /** * Fake implementation of {@link InputMethodManagerInternal}. All the methods do nothing. */ private static final InputMethodManagerInternal NOP = @@ -124,6 +135,12 @@ public abstract class InputMethodManagerInternal { @Override public void registerInputMethodListListener(InputMethodListListener listener) { } + + @Override + public boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken, + int displayId) { + return false; + } }; /** diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 868631cc2543..37c0edc5f115 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -65,6 +65,7 @@ import android.database.ContentObserver; import android.graphics.Matrix; import android.graphics.drawable.Drawable; import android.hardware.display.DisplayManagerInternal; +import android.hardware.input.InputManagerInternal; import android.inputmethodservice.InputMethodService; import android.net.Uri; import android.os.Binder; @@ -307,6 +308,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final SettingsObserver mSettingsObserver; final IWindowManager mIWindowManager; final WindowManagerInternal mWindowManagerInternal; + final InputManagerInternal mInputManagerInternal; private final DisplayManagerInternal mDisplayManagerInternal; final HandlerCaller mCaller; final boolean mHasFeature; @@ -620,6 +622,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub int mCurTokenDisplayId = INVALID_DISPLAY; /** + * The host input token of the current active input method. + */ + @GuardedBy("mMethodMap") + @Nullable + private IBinder mCurHostInputToken; + + /** * The display ID of the input method indicates the fallback display which returned by * {@link #computeImeDisplayIdForTarget}. */ @@ -1615,6 +1624,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mIWindowManager = IWindowManager.Stub.asInterface( ServiceManager.getService(Context.WINDOW_SERVICE)); mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); + mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mImeDisplayValidator = displayId -> mWindowManagerInternal.shouldShowIme(displayId); mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() { @@ -1987,7 +1997,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub executeOrSendMessage(mCurMethod, mCaller.obtainMessageOOO(MSG_INLINE_SUGGESTIONS_REQUEST, mCurMethod, requestInfo, new InlineSuggestionsRequestCallbackDecorator(callback, - imi.getPackageName(), mCurTokenDisplayId))); + imi.getPackageName(), mCurTokenDisplayId, mCurToken, + this))); } else { callback.onInlineSuggestionsUnsupported(); } @@ -2009,12 +2020,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private final int mImeDisplayId; + @NonNull + private final IBinder mImeToken; + @NonNull + private final InputMethodManagerService mImms; + InlineSuggestionsRequestCallbackDecorator( - @NonNull IInlineSuggestionsRequestCallback callback, - @NonNull String imePackageName, int displayId) { + @NonNull IInlineSuggestionsRequestCallback callback, @NonNull String imePackageName, + int displayId, @NonNull IBinder imeToken, @NonNull InputMethodManagerService imms) { mCallback = callback; mImePackageName = imePackageName; mImeDisplayId = displayId; + mImeToken = imeToken; + mImms = imms; } @Override @@ -2034,6 +2052,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + "]."); } request.setHostDisplayId(mImeDisplayId); + mImms.setCurHostInputToken(mImeToken, request.getHostInputToken()); mCallback.onInlineSuggestionsRequest(request, callback, imeFieldId, inputViewStarted); } @@ -2049,6 +2068,21 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } /** + * Sets current host input token. + * + * @param callerImeToken the token has been made for the current active input method + * @param hostInputToken the host input token of the current active input method + */ + void setCurHostInputToken(@NonNull IBinder callerImeToken, @Nullable IBinder hostInputToken) { + synchronized (mMethodMap) { + if (!calledWithValidTokenLocked(callerImeToken)) { + return; + } + mCurHostInputToken = hostInputToken; + } + } + + /** * @param imiId if null, returns enabled subtypes for the current imi * @return enabled subtypes of the specified imi */ @@ -2549,6 +2583,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub updateSystemUiLocked(mImeWindowVis, mBackDisposition); mCurToken = null; mCurTokenDisplayId = INVALID_DISPLAY; + mCurHostInputToken = null; } mCurId = null; @@ -4813,6 +4848,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } + private boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken, + int displayId) { + //TODO(b/150843766): Check if Input Token is valid. + final IBinder curHostInputToken; + synchronized (mMethodMap) { + if (displayId != mCurTokenDisplayId || mCurHostInputToken == null) { + return false; + } + curHostInputToken = mCurHostInputToken; + } + return mInputManagerInternal.transferTouchFocus(sourceInputToken, curHostInputToken); + } + private static final class LocalServiceImpl extends InputMethodManagerInternal { @NonNull private final InputMethodManagerService mService; @@ -4852,6 +4900,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub public void registerInputMethodListListener(InputMethodListListener listener) { mService.mInputMethodListListeners.addIfAbsent(listener); } + + @Override + public boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken, + int displayId) { + return mService.transferTouchFocusToImeWindow(sourceInputToken, displayId); + } } @BinderThread @@ -4963,6 +5017,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + " mBoundToMethod=" + mBoundToMethod + " mVisibleBound=" + mVisibleBound); p.println(" mCurToken=" + mCurToken); p.println(" mCurTokenDisplayId=" + mCurTokenDisplayId); + p.println(" mCurHostInputToken=" + mCurHostInputToken); p.println(" mCurIntent=" + mCurIntent); method = mCurMethod; p.println(" mCurMethod=" + mCurMethod); diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index 0e6c0dbbca2d..0d16ee0e1d5a 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -25,6 +25,7 @@ import android.annotation.AnyThread; import android.annotation.BinderThread; import android.annotation.IntDef; import android.annotation.MainThread; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.annotation.WorkerThread; @@ -209,6 +210,13 @@ public final class MultiClientInputMethodManagerService { InputMethodListListener listener) { reportNotSupported(); } + + @Override + public boolean transferTouchFocusToImeWindow( + @NonNull IBinder sourceInputToken, int displayId) { + reportNotSupported(); + return false; + } }); } diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 0661cb981975..e011c7945882 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -569,16 +569,6 @@ public abstract class WindowManagerInternal { IBinder windowToken, int accessibilityWindowId); /** - * Transfers input focus from a given input token to that of the IME window. - * - * @param sourceInputToken The source token. - * @param displayId The display hosting the IME window. - * @return Whether transfer was successful. - */ - public abstract boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken, - int displayId); - - /** * * Returns the window name associated to the given binder. * diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 22e7ce7d97f1..23ba528b6aee 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7566,29 +7566,6 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken, - int displayId) { - final IBinder destinationInputToken; - - synchronized (mGlobalLock) { - final DisplayContent displayContent = mRoot.getDisplayContent(displayId); - if (displayContent == null) { - return false; - } - final WindowState imeWindow = displayContent.mInputMethodWindow; - if (imeWindow == null) { - return false; - } - if (imeWindow.mInputChannel == null) { - return false; - } - destinationInputToken = imeWindow.mInputChannel.getToken(); - } - - return mInputManager.transferTouchFocus(sourceInputToken, destinationInputToken); - } - - @Override public String getWindowName(@NonNull IBinder binder) { synchronized (mGlobalLock) { final WindowState w = mWindowMap.get(binder); |
