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
This commit is contained in:
lpeter
2020-03-05 20:32:16 +08:00
parent 3fe090f737
commit 133fce0171
8 changed files with 112 additions and 41 deletions

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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);
}
}
}

View File

@@ -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;
@@ -91,6 +92,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.
*/
@@ -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;
}
};
/**

View File

@@ -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;
@@ -619,6 +621,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);
}
@@ -2048,6 +2067,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);

View File

@@ -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;
}
});
}

View File

@@ -568,16 +568,6 @@ public abstract class WindowManagerInternal {
public abstract void setAccessibilityIdToSurfaceMetadata(
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.

View File

@@ -7565,29 +7565,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) {