Loading core/java/android/hardware/input/InputManagerInternal.java +19 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java +4 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading services/core/java/com/android/server/input/InputManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -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); } } } services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java +17 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading Loading @@ -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; } }; /** Loading services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +58 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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}. Loading Loading @@ -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() { Loading Loading @@ -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(); } Loading @@ -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 Loading @@ -2034,6 +2052,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + "]."); } request.setHostDisplayId(mImeDisplayId); mImms.setCurHostInputToken(mImeToken, request.getHostInputToken()); mCallback.onInlineSuggestionsRequest(request, callback, imeFieldId, inputViewStarted); } Loading @@ -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 Loading Loading @@ -2549,6 +2583,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub updateSystemUiLocked(mImeWindowVis, mBackDisposition); mCurToken = null; mCurTokenDisplayId = INVALID_DISPLAY; mCurHostInputToken = null; } mCurId = null; Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading
core/java/android/hardware/input/InputManagerInternal.java +19 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); }
services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java +4 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading
services/core/java/com/android/server/input/InputManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -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); } } }
services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java +17 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading Loading @@ -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; } }; /** Loading
services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +58 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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}. Loading Loading @@ -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() { Loading Loading @@ -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(); } Loading @@ -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 Loading @@ -2034,6 +2052,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + "]."); } request.setHostDisplayId(mImeDisplayId); mImms.setCurHostInputToken(mImeToken, request.getHostInputToken()); mCallback.onInlineSuggestionsRequest(request, callback, imeFieldId, inputViewStarted); } Loading @@ -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 Loading Loading @@ -2549,6 +2583,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub updateSystemUiLocked(mImeWindowVis, mBackDisposition); mCurToken = null; mCurTokenDisplayId = INVALID_DISPLAY; mCurHostInputToken = null; } mCurId = null; Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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); Loading