Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 716ac1c2 authored by Rob Carr's avatar Rob Carr
Browse files

SurfaceControlViewHost: Expose transferTouchGesture API.

A key feature of SurfaceControlViewHost is that touches are given
directly to the embedded View hierarchy, however in some cases
this can interfere with the seamlessness of embedding. For example
if we are not clicking on an embedded element but in fact
intending to scroll its container.

Allowing transferring the current touch gesture to the host
provides a way to solve this problem. We expose this through
a SurfaceControlViewHost specific API in order to restrict scope
and avoid sharing of any new tokens.

Bug: 256993188
Change-Id: If94dbe4b862b6a159f2c0baee55dcb8c82c22e37
parent 0d098718
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
}
+23 −2
Original line number Diff line number Diff line
@@ -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;
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -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;
    }
}
+16 −0
Original line number Diff line number Diff line
@@ -909,6 +909,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) {
+32 −0
Original line number Diff line number Diff line
@@ -8669,6 +8669,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,