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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user