Merge "Move the logic of transferTouchFocusToImeWindow to IMMS." into rvc-dev am: 3e6f5a87f9 am: 71610e5037

Change-Id: I0f5a5b3af3653f120988059ac49675545c4ad181
This commit is contained in:
Peter Li
2020-03-20 07:11:42 +00:00
committed by Automerger Merge Worker
8 changed files with 112 additions and 41 deletions

View File

@@ -16,7 +16,9 @@
package android.hardware.input; package android.hardware.input;
import android.annotation.NonNull;
import android.hardware.display.DisplayViewport; import android.hardware.display.DisplayViewport;
import android.os.IBinder;
import android.view.InputEvent; import android.view.InputEvent;
import java.util.List; 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. * Set whether the input stack should deliver pulse gesture events when the device is asleep.
*/ */
public abstract void setPulseGestureEnabled(boolean enabled); 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.LocalServices;
import com.android.server.UiThread; import com.android.server.UiThread;
import com.android.server.autofill.RemoteInlineSuggestionRenderService; 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.ArrayList;
import java.util.List; import java.util.List;
@@ -312,10 +312,9 @@ public final class InlineSuggestionFactory {
@Override @Override
public void onTransferTouchFocusToImeWindow(IBinder sourceInputToken, int displayId) public void onTransferTouchFocusToImeWindow(IBinder sourceInputToken, int displayId)
throws RemoteException { throws RemoteException {
//TODO(b/149574510): Move logic to IMMS final InputMethodManagerInternal inputMethodManagerInternal =
final WindowManagerInternal windowManagerInternal = LocalServices.getService( LocalServices.getService(InputMethodManagerInternal.class);
WindowManagerInternal.class); if (!inputMethodManagerInternal.transferTouchFocusToImeWindow(sourceInputToken,
if (!windowManagerInternal.transferTouchFocusToImeWindow(sourceInputToken,
displayId)) { displayId)) {
Slog.e(TAG, "Cannot transfer touch focus from suggestion to IME"); Slog.e(TAG, "Cannot transfer touch focus from suggestion to IME");
onErrorCallback.run(); 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.NonNull;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.os.IBinder;
import android.view.inputmethod.InlineSuggestionsRequest; import android.view.inputmethod.InlineSuggestionsRequest;
import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodInfo;
@@ -91,6 +92,16 @@ public abstract class InputMethodManagerInternal {
*/ */
public abstract void registerInputMethodListListener(InputMethodListListener listener); 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. * Fake implementation of {@link InputMethodManagerInternal}. All the methods do nothing.
*/ */
@@ -124,6 +135,12 @@ public abstract class InputMethodManagerInternal {
@Override @Override
public void registerInputMethodListListener(InputMethodListListener listener) { 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.Matrix;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManagerInternal; import android.hardware.display.DisplayManagerInternal;
import android.hardware.input.InputManagerInternal;
import android.inputmethodservice.InputMethodService; import android.inputmethodservice.InputMethodService;
import android.net.Uri; import android.net.Uri;
import android.os.Binder; import android.os.Binder;
@@ -307,6 +308,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final SettingsObserver mSettingsObserver; final SettingsObserver mSettingsObserver;
final IWindowManager mIWindowManager; final IWindowManager mIWindowManager;
final WindowManagerInternal mWindowManagerInternal; final WindowManagerInternal mWindowManagerInternal;
final InputManagerInternal mInputManagerInternal;
private final DisplayManagerInternal mDisplayManagerInternal; private final DisplayManagerInternal mDisplayManagerInternal;
final HandlerCaller mCaller; final HandlerCaller mCaller;
final boolean mHasFeature; final boolean mHasFeature;
@@ -619,6 +621,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/ */
int mCurTokenDisplayId = INVALID_DISPLAY; 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 * The display ID of the input method indicates the fallback display which returned by
* {@link #computeImeDisplayIdForTarget}. * {@link #computeImeDisplayIdForTarget}.
@@ -1615,6 +1624,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mIWindowManager = IWindowManager.Stub.asInterface( mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE)); ServiceManager.getService(Context.WINDOW_SERVICE));
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mImeDisplayValidator = displayId -> mWindowManagerInternal.shouldShowIme(displayId); mImeDisplayValidator = displayId -> mWindowManagerInternal.shouldShowIme(displayId);
mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() { mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() {
@@ -1987,7 +1997,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
executeOrSendMessage(mCurMethod, executeOrSendMessage(mCurMethod,
mCaller.obtainMessageOOO(MSG_INLINE_SUGGESTIONS_REQUEST, mCurMethod, mCaller.obtainMessageOOO(MSG_INLINE_SUGGESTIONS_REQUEST, mCurMethod,
requestInfo, new InlineSuggestionsRequestCallbackDecorator(callback, requestInfo, new InlineSuggestionsRequestCallbackDecorator(callback,
imi.getPackageName(), mCurTokenDisplayId))); imi.getPackageName(), mCurTokenDisplayId, mCurToken,
this)));
} else { } else {
callback.onInlineSuggestionsUnsupported(); callback.onInlineSuggestionsUnsupported();
} }
@@ -2009,12 +2020,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private final int mImeDisplayId; private final int mImeDisplayId;
@NonNull
private final IBinder mImeToken;
@NonNull
private final InputMethodManagerService mImms;
InlineSuggestionsRequestCallbackDecorator( InlineSuggestionsRequestCallbackDecorator(
@NonNull IInlineSuggestionsRequestCallback callback, @NonNull IInlineSuggestionsRequestCallback callback, @NonNull String imePackageName,
@NonNull String imePackageName, int displayId) { int displayId, @NonNull IBinder imeToken, @NonNull InputMethodManagerService imms) {
mCallback = callback; mCallback = callback;
mImePackageName = imePackageName; mImePackageName = imePackageName;
mImeDisplayId = displayId; mImeDisplayId = displayId;
mImeToken = imeToken;
mImms = imms;
} }
@Override @Override
@@ -2034,6 +2052,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
+ "]."); + "].");
} }
request.setHostDisplayId(mImeDisplayId); request.setHostDisplayId(mImeDisplayId);
mImms.setCurHostInputToken(mImeToken, request.getHostInputToken());
mCallback.onInlineSuggestionsRequest(request, callback, imeFieldId, inputViewStarted); 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 * @param imiId if null, returns enabled subtypes for the current imi
* @return enabled subtypes of the specified imi * @return enabled subtypes of the specified imi
@@ -2549,6 +2583,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
updateSystemUiLocked(mImeWindowVis, mBackDisposition); updateSystemUiLocked(mImeWindowVis, mBackDisposition);
mCurToken = null; mCurToken = null;
mCurTokenDisplayId = INVALID_DISPLAY; mCurTokenDisplayId = INVALID_DISPLAY;
mCurHostInputToken = null;
} }
mCurId = 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 { private static final class LocalServiceImpl extends InputMethodManagerInternal {
@NonNull @NonNull
private final InputMethodManagerService mService; private final InputMethodManagerService mService;
@@ -4852,6 +4900,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
public void registerInputMethodListListener(InputMethodListListener listener) { public void registerInputMethodListListener(InputMethodListListener listener) {
mService.mInputMethodListListeners.addIfAbsent(listener); mService.mInputMethodListListeners.addIfAbsent(listener);
} }
@Override
public boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken,
int displayId) {
return mService.transferTouchFocusToImeWindow(sourceInputToken, displayId);
}
} }
@BinderThread @BinderThread
@@ -4963,6 +5017,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
+ " mBoundToMethod=" + mBoundToMethod + " mVisibleBound=" + mVisibleBound); + " mBoundToMethod=" + mBoundToMethod + " mVisibleBound=" + mVisibleBound);
p.println(" mCurToken=" + mCurToken); p.println(" mCurToken=" + mCurToken);
p.println(" mCurTokenDisplayId=" + mCurTokenDisplayId); p.println(" mCurTokenDisplayId=" + mCurTokenDisplayId);
p.println(" mCurHostInputToken=" + mCurHostInputToken);
p.println(" mCurIntent=" + mCurIntent); p.println(" mCurIntent=" + mCurIntent);
method = mCurMethod; method = mCurMethod;
p.println(" mCurMethod=" + mCurMethod); p.println(" mCurMethod=" + mCurMethod);

View File

@@ -25,6 +25,7 @@ import android.annotation.AnyThread;
import android.annotation.BinderThread; import android.annotation.BinderThread;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.annotation.MainThread; import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.annotation.WorkerThread; import android.annotation.WorkerThread;
@@ -209,6 +210,13 @@ public final class MultiClientInputMethodManagerService {
InputMethodListListener listener) { InputMethodListListener listener) {
reportNotSupported(); 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( public abstract void setAccessibilityIdToSurfaceMetadata(
IBinder windowToken, int accessibilityWindowId); 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. * 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 @Override
public String getWindowName(@NonNull IBinder binder) { public String getWindowName(@NonNull IBinder binder) {
synchronized (mGlobalLock) { synchronized (mGlobalLock) {