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

Commit 204c023a authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Add focus support for SurfaceControlViewHost

This change introduces a new call for clients to request focus on their
embedded views. In order to accomplish this, the owner of the
SurfacePackage sends an input token that can identify the input channel
of the embedded window. This token is forwarded as part of the focus
request.

WindowManager will authenticate the calling window and the relationship
between the host and the embedded window. Once authenticated, the
request will be forwarded to InputDispatcher. InputDispatcher will grant
the focus to the SurfaceControlViewHost if the host window is currently
focused or transfer focus back to the host window if the
SurfaceControlViewHost is focused. Otherwise the request is dropped.

In addition, SurfaceView, the host in this scenario, now overrides the
onFocused function to transfer focus to and from the embedded view.

Test: atest SurfaceControlViewHostTests
Bug: 151179149

Change-Id: Ia95545a60d73db4c03679bce9747d2e275806838
parent 38cc1531
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -344,4 +344,17 @@ interface IWindowSession {
     */
     */
    void updateInputChannel(in IBinder channelToken, int displayId, in SurfaceControl surface,
    void updateInputChannel(in IBinder channelToken, int displayId, in SurfaceControl surface,
            int flags, int privateFlags, in Region region);
            int flags, int privateFlags, in Region region);

    /**
     * Transfer window focus to an embedded window if the calling window has focus.
     *
     * @param window - calling window owned by the caller. Window can be null if there
     *                 is no host window but the caller must have permissions to create an embedded
     *                 window without a host window.
     * @param inputToken - token identifying the embedded window that should gain focus.
     * @param grantFocus - true if focus should be granted to the embedded window, false if focus
     *                     should be transferred back to the host window. If there is no host
     *                     window, the system will try to find a new focus target.
     */
    void grantEmbeddedWindowFocus(IWindow window, in IBinder inputToken, boolean grantFocus);
}
}
+17 −2
Original line number Original line Diff line number Diff line
@@ -70,10 +70,13 @@ public class SurfaceControlViewHost {
    public static final class SurfacePackage implements Parcelable {
    public static final class SurfacePackage implements Parcelable {
        private SurfaceControl mSurfaceControl;
        private SurfaceControl mSurfaceControl;
        private final IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection;
        private final IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection;
        private final IBinder mInputToken;


        SurfacePackage(SurfaceControl sc, IAccessibilityEmbeddedConnection connection) {
        SurfacePackage(SurfaceControl sc, IAccessibilityEmbeddedConnection connection,
                       IBinder inputToken) {
            mSurfaceControl = sc;
            mSurfaceControl = sc;
            mAccessibilityEmbeddedConnection = connection;
            mAccessibilityEmbeddedConnection = connection;
            mInputToken = inputToken;
        }
        }


        private SurfacePackage(Parcel in) {
        private SurfacePackage(Parcel in) {
@@ -81,6 +84,7 @@ public class SurfaceControlViewHost {
            mSurfaceControl.readFromParcel(in);
            mSurfaceControl.readFromParcel(in);
            mAccessibilityEmbeddedConnection = IAccessibilityEmbeddedConnection.Stub.asInterface(
            mAccessibilityEmbeddedConnection = IAccessibilityEmbeddedConnection.Stub.asInterface(
                    in.readStrongBinder());
                    in.readStrongBinder());
            mInputToken = in.readStrongBinder();
        }
        }


        /**
        /**
@@ -126,6 +130,15 @@ public class SurfaceControlViewHost {
             mSurfaceControl = null;
             mSurfaceControl = null;
        }
        }


        /**
         * Returns an input token used which can be used to request focus on the embedded surface.
         *
         * @hide
         */
        public IBinder getInputToken() {
            return mInputToken;
        }

        public static final @NonNull Creator<SurfacePackage> CREATOR
        public static final @NonNull Creator<SurfacePackage> CREATOR
             = new Creator<SurfacePackage>() {
             = new Creator<SurfacePackage>() {
                     public SurfacePackage createFromParcel(Parcel in) {
                     public SurfacePackage createFromParcel(Parcel in) {
@@ -198,7 +211,8 @@ public class SurfaceControlViewHost {
     */
     */
    public @Nullable SurfacePackage getSurfacePackage() {
    public @Nullable SurfacePackage getSurfacePackage() {
        if (mSurfaceControl != null && mAccessibilityEmbeddedConnection != null) {
        if (mSurfaceControl != null && mAccessibilityEmbeddedConnection != null) {
            return new SurfacePackage(mSurfaceControl, mAccessibilityEmbeddedConnection);
            return new SurfacePackage(mSurfaceControl, mAccessibilityEmbeddedConnection,
                    mViewRoot.getInputToken());
        } else {
        } else {
            return null;
            return null;
        }
        }
@@ -210,6 +224,7 @@ public class SurfaceControlViewHost {
    @TestApi
    @TestApi
    public void setView(@NonNull View view, @NonNull WindowManager.LayoutParams attrs) {
    public void setView(@NonNull View view, @NonNull WindowManager.LayoutParams attrs) {
        Objects.requireNonNull(view);
        Objects.requireNonNull(view);
        view.setLayoutParams(attrs);
        mViewRoot.setView(view, attrs, null);
        mViewRoot.setView(view, attrs, null);
    }
    }


+17 −0
Original line number Original line Diff line number Diff line
@@ -1846,6 +1846,23 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        }
        }
    }
    }


    @Override
    protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
                                  @Nullable Rect previouslyFocusedRect) {
        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
        final ViewRootImpl viewRoot = getViewRootImpl();
        if (mSurfacePackage == null || viewRoot == null) {
            return;
        }
        try {
            viewRoot.mWindowSession.grantEmbeddedWindowFocus(viewRoot.mWindow,
                    mSurfacePackage.getInputToken(), gainFocus);
        } catch (Exception e) {
            Log.e(TAG, System.identityHashCode(this)
                    + "Exception requesting focus on embedded window", e);
        }
    }

    /**
    /**
     * Wrapper of accessibility embedded connection for embedded view hierarchy.
     * Wrapper of accessibility embedded connection for embedded view hierarchy.
     */
     */
+5 −0
Original line number Original line Diff line number Diff line
@@ -457,4 +457,9 @@ public class WindowlessWindowManager implements IWindowSession {
      return surfaceInsets != null
      return surfaceInsets != null
          ? attrs.height + surfaceInsets.top + surfaceInsets.bottom : attrs.height;
          ? attrs.height + surfaceInsets.top + surfaceInsets.bottom : attrs.height;
    }
    }

    @Override
    public void grantEmbeddedWindowFocus(IWindow callingWindow, IBinder targetInputToken,
                                         boolean grantFocus) {
    }
}
}
+12 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,12 @@
      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
    },
    },
    "-2107721178": {
      "message": "grantEmbeddedWindowFocus win=%s grantFocus=%s",
      "level": "VERBOSE",
      "group": "WM_DEBUG_FOCUS",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "-2101985723": {
    "-2101985723": {
      "message": "Failed looking up window session=%s callers=%s",
      "message": "Failed looking up window session=%s callers=%s",
      "level": "WARN",
      "level": "WARN",
@@ -1597,6 +1603,12 @@
      "group": "WM_DEBUG_BOOT",
      "group": "WM_DEBUG_BOOT",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    },
    "397105698": {
      "message": "grantEmbeddedWindowFocus remove request for win=%s dropped since no candidate was found",
      "level": "VERBOSE",
      "group": "WM_DEBUG_FOCUS",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "399841913": {
    "399841913": {
      "message": "SURFACE RECOVER DESTROY: %s",
      "message": "SURFACE RECOVER DESTROY: %s",
      "level": "INFO",
      "level": "INFO",
Loading