diff options
5 files changed, 80 insertions, 2 deletions
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 943d64ab986c..fc47e6973ce8 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -353,4 +353,6 @@ interface IWindowSession { * Returns whether this window needs to cancel draw and retry later. */ boolean cancelDraw(IWindow window); + + boolean transferEmbeddedTouchFocusToHost(IWindow embeddedWindow); } diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index 50ce7b634e99..134625e18f7b 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -194,7 +194,7 @@ public class SurfaceControlViewHost { * is more akin to a PopupWindow in that the size is user specified * independent of configuration width and height. * - * In order to receive the configuration change via + * In order to receive the configuration change via * {@link View#onConfigurationChanged}, the context used with the * SurfaceControlViewHost and it's embedded view hierarchy must * be a WindowContext obtained from {@link Context#createWindowContext}. @@ -460,5 +460,26 @@ public class SurfaceControlViewHost { (WindowManagerImpl) mViewRoot.mContext.getSystemService(Context.WINDOW_SERVICE); attrs.token = wm.getDefaultToken(); } -} + /** + * Transfer the currently in progress touch gesture to the parent + * (if any) of this SurfaceControlViewHost. This requires that the + * SurfaceControlViewHost was created with an associated hostInputToken. + * + * @return Whether the touch stream was transferred. + * @hide + */ + public boolean transferTouchGestureToHost() { + if (mViewRoot == null) { + return false; + } + + final IWindowSession realWm = WindowManagerGlobal.getWindowSession(); + try { + return realWm.transferEmbeddedTouchFocusToHost(mViewRoot.mWindow); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + return false; + } +} diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index edf33f15a9ca..ecb555735b27 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -561,4 +561,11 @@ public class WindowlessWindowManager implements IWindowSession { public boolean cancelDraw(IWindow window) { return false; } + + @Override + public boolean transferEmbeddedTouchFocusToHost(IWindow window) { + Log.e(TAG, "Received request to transferEmbeddedTouch focus on WindowlessWindowManager" + + " we shouldn't get here!"); + return false; + } } diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index b5c82a8f46fd..15a5ebf19c4d 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -910,6 +910,22 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override + public boolean transferEmbeddedTouchFocusToHost(IWindow embeddedWindow) { + if (embeddedWindow == null) { + return false; + } + + final long identity = Binder.clearCallingIdentity(); + boolean didTransfer = false; + try { + didTransfer = mService.transferEmbeddedTouchFocusToHost(embeddedWindow); + } 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 d058892c1735..9b09d9410294 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -8682,6 +8682,38 @@ public class WindowManagerService extends IWindowManager.Stub clientChannel.copyTo(outInputChannel); } + boolean transferEmbeddedTouchFocusToHost(IWindow embeddedWindow) { + final IBinder windowBinder = embeddedWindow.asBinder(); + final IBinder hostInputChannel, embeddedInputChannel; + synchronized (mGlobalLock) { + final EmbeddedWindowController.EmbeddedWindow ew = + mEmbeddedWindowController.getByWindowToken(windowBinder); + if (ew == null) { + Slog.w(TAG, "Attempt to transfer touch focus from non-existent embedded window"); + return false; + } + final WindowState hostWindowState = ew.getWindowState(); + if (hostWindowState == null) { + Slog.w(TAG, "Attempt to transfer touch focus from embedded window with no" + + " associated host"); + 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(embeddedInputChannel, hostInputChannel); + } + } + private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid, int displayId, SurfaceControl surface, String name, InputApplicationHandle applicationHandle, int flags, |