diff options
10 files changed, 106 insertions, 4 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index fec797e64f8f..7bc0d52737e3 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -49829,6 +49829,7 @@ package android.view { method public default void removeOnBufferTransformHintChangedListener(@NonNull android.view.AttachedSurfaceControl.OnBufferTransformHintChangedListener); method public default void setChildBoundingInsets(@NonNull android.graphics.Rect); method public default void setTouchableRegion(@Nullable android.graphics.Region); + method @FlaggedApi("com.android.window.flags.transfer_gesture_to_embedded") public default boolean transferHostTouchGestureToEmbedded(@NonNull android.view.SurfaceControlViewHost.SurfacePackage); } @UiThread public static interface AttachedSurfaceControl.OnBufferTransformHintChangedListener { diff --git a/core/java/android/view/AttachedSurfaceControl.java b/core/java/android/view/AttachedSurfaceControl.java index d5457511876b..fd5517d29d74 100644 --- a/core/java/android/view/AttachedSurfaceControl.java +++ b/core/java/android/view/AttachedSurfaceControl.java @@ -231,4 +231,19 @@ public interface AttachedSurfaceControl { default void removeTrustedPresentationCallback(@NonNull SurfaceControl.Transaction t, @NonNull Consumer<Boolean> listener) { } + + /** + * Transfer the currently in progress touch gesture from the host to the requested + * {@link SurfaceControlViewHost.SurfacePackage}. This requires that the + * SurfaceControlViewHost was created with the current host's inputToken. + * + * @param surfacePackage The SurfacePackage to transfer the gesture to. + * @return Whether the touch stream was transferred. + */ + @FlaggedApi(Flags.FLAG_TRANSFER_GESTURE_TO_EMBEDDED) + default boolean transferHostTouchGestureToEmbedded( + @NonNull SurfaceControlViewHost.SurfacePackage surfacePackage) { + throw new UnsupportedOperationException( + "transferHostTouchGestureToEmbedded is unimplemented"); + } } diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 7acf2f8ce06d..02e97dae70e2 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -357,4 +357,6 @@ interface IWindowSession { boolean cancelDraw(IWindow window); boolean transferEmbeddedTouchFocusToHost(IWindow embeddedWindow); + + boolean transferHostTouchGestureToEmbedded(IWindow hostWindow, IBinder transferTouchToken); } diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index 57b19a8ce12f..405653123f79 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -287,7 +287,8 @@ public class SurfaceControlViewHost { } /** - * Returns an input token used which can be used to request focus on the embedded surface. + * Returns an input token used which can be used to request focus on the embedded surface + * or to transfer touch gesture to the embedded surface. * * @hide */ @@ -526,7 +527,8 @@ public class SurfaceControlViewHost { } /** - * Returns an input token used which can be used to request focus on the embedded surface. + * Returns an input token used which can be used to request focus on the embedded surface + * or to transfer touch gesture to the embedded surface. * * @hide */ diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 24223694e421..1ee303ccdd02 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -11893,4 +11893,17 @@ public final class ViewRootImpl implements ViewParent, } Log.d(mTag, msg); } + + @Override + public boolean transferHostTouchGestureToEmbedded( + @NonNull SurfaceControlViewHost.SurfacePackage surfacePackage) { + final IWindowSession realWm = WindowManagerGlobal.getWindowSession(); + try { + return realWm.transferHostTouchGestureToEmbedded(mWindow, + surfacePackage.getInputToken()); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + return false; + } } diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 7c3b6ae42fcf..652fe2445ddc 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -656,6 +656,14 @@ public class WindowlessWindowManager implements IWindowSession { return false; } + @Override + public boolean transferHostTouchGestureToEmbedded(IWindow hostWindow, + IBinder embeddedInputToken) { + Log.e(TAG, "Received request to transferHostTouchGestureToEmbedded on" + + " WindowlessWindowManager. We shouldn't get here!"); + return false; + } + void setParentInterface(@Nullable ISurfaceControlViewHostParent parentInterface) { IBinder oldInterface = mParentInterface == null ? null : mParentInterface.asBinder(); IBinder newInterface = parentInterface == null ? null : parentInterface.asBinder(); diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig index 5ad5c79f2d42..68eddff19922 100644 --- a/core/java/android/window/flags/window_surfaces.aconfig +++ b/core/java/android/window/flags/window_surfaces.aconfig @@ -25,3 +25,10 @@ flag { is_fixed_read_only: true bug: "304508760" } + +flag { + namespace: "window_surfaces" + name: "transfer_gesture_to_embedded" + description: "Enable public API for Window Surfaces" + bug: "287076178" +} diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java index 275396f459bd..14628782eac7 100644 --- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java +++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java @@ -150,8 +150,8 @@ class EmbeddedWindowController { /** * A unique token associated with the embedded window that can be used by the host window - * to request focus transfer to the embedded. This is not the input token since we don't - * want to give clients access to each others input token. + * to request focus transfer and gesture transfer to the embedded. This is not the input + * token since we don't want to give clients access to each others input token. */ private final IBinder mInputTransferToken; diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index a756847d59ea..0c55d8a85df1 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -964,6 +964,23 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override + public boolean transferHostTouchGestureToEmbedded(IWindow hostWindow, + IBinder inputTransferToken) { + if (hostWindow == null) { + return false; + } + + final long identity = Binder.clearCallingIdentity(); + boolean didTransfer; + try { + didTransfer = mService.transferHostTouchGestureToEmbedded(this, hostWindow, + inputTransferToken); + } finally { + Binder.restoreCallingIdentity(identity); + } + return didTransfer; + } + @Override public void generateDisplayHash(IWindow window, Rect boundsInWindow, String hashAlgorithm, RemoteCallback callback) { final long origId = Binder.clearCallingIdentity(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 9eb3389ff43c..6e3d24b9f711 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -8960,6 +8960,43 @@ public class WindowManagerService extends IWindowManager.Stub } } + boolean transferHostTouchGestureToEmbedded(Session session, IWindow hostWindow, + IBinder inputTransferToken) { + final IBinder hostInputChannel, embeddedInputChannel; + synchronized (mGlobalLock) { + final WindowState hostWindowState = windowForClientLocked(session, hostWindow, false); + if (hostWindowState == null) { + Slog.w(TAG, "Attempt to transfer touch gesture with invalid host window"); + return false; + } + + final EmbeddedWindowController.EmbeddedWindow ew = + mEmbeddedWindowController.getByInputTransferToken(inputTransferToken); + if (ew == null || ew.mHostWindowState == null) { + Slog.w(TAG, "Attempt to transfer touch gesture to non-existent embedded window"); + return false; + } + if (ew.mHostWindowState.mClient.asBinder() != hostWindow.asBinder()) { + Slog.w(TAG, "Attempt to transfer touch gesture to embedded window not associated" + + " with host window"); + return false; + } + embeddedInputChannel = ew.getInputChannelToken(); + if (embeddedInputChannel == null) { + Slog.w(TAG, "Attempt to transfer touch focus from embedded window with no input" + + " channel"); + return false; + } + hostInputChannel = hostWindowState.mInputChannelToken; + if (hostInputChannel == null) { + Slog.w(TAG, + "Attempt to transfer touch focus to a host window with no input channel"); + return false; + } + return mInputManager.transferTouchFocus(hostInputChannel, embeddedInputChannel); + } + } + private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid, int displayId, SurfaceControl surface, String name, InputApplicationHandle applicationHandle, int flags, |