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

Commit 96ceaf62 authored by ryanlwlin's avatar ryanlwlin Committed by Jacky Kao
Browse files

Use shellRoot to identify PIP menu window

Pip menu is an untouchable window which is exculded
from accessibility windows list. However it is touchable
when users touch in the pip mode window.

To fix it, we add this window to visible windows
list by comparing the window token.

Bug: 191736824
Test: a11y CTS & unit tests
Change-Id: I0ac0d0487d0bec9ef04a2ba5770ba499d5125b11
parent c6245d13
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -1645,10 +1645,11 @@ final class AccessibilityController {


            // Ignore non-touchable windows, except the split-screen divider, which is
            // Ignore non-touchable windows, except the split-screen divider, which is
            // occasionally non-touchable but still useful for identifying split-screen
            // occasionally non-touchable but still useful for identifying split-screen
            // mode.
            // mode and the PIP menu.
            if (((a11yWindow.getFlags()
            if (((a11yWindow.getFlags()
                    & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0)
                    & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0)
                    && (a11yWindow.getType() != TYPE_DOCK_DIVIDER)) {
                    && (a11yWindow.getType() != TYPE_DOCK_DIVIDER
                    && !a11yWindow.isPIPMenu())) {
                return false;
                return false;
            }
            }


+21 −6
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Region;
import android.os.Handler;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.util.Slog;
import android.util.Slog;
@@ -104,9 +105,14 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
            inverseMatrix.set(mMagnificationSpecInverseMatrix.get(displayId));
            inverseMatrix.set(mMagnificationSpecInverseMatrix.get(displayId));
        }
        }


        final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
        final ShellRoot shellroot = dc.mShellRoots.get(WindowManager.SHELL_ROOT_LAYER_PIP);
        final IBinder pipMenuIBinder =
                shellroot != null ? shellroot.getAccessibilityWindowToken() : null;
        for (final InputWindowHandle windowHandle : inputWindowHandles) {
        for (final InputWindowHandle windowHandle : inputWindowHandles) {
            final AccessibilityWindow accessibilityWindow =
            final AccessibilityWindow accessibilityWindow =
                    AccessibilityWindow.initializeData(mService, windowHandle, inverseMatrix);
                    AccessibilityWindow.initializeData(mService, windowHandle, inverseMatrix,
                            pipMenuIBinder);


            outWindows.add(accessibilityWindow);
            outWindows.add(accessibilityWindow);
        }
        }
@@ -334,6 +340,7 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
        private int mFlags;
        private int mFlags;
        private int mType;
        private int mType;
        private int mPrivateFlags;
        private int mPrivateFlags;
        private boolean mIsPIPMenu;
        private boolean mIsFocused;
        private boolean mIsFocused;
        private boolean mShouldMagnify;
        private boolean mShouldMagnify;
        private boolean mIgnoreDuetoRecentsAnimation;
        private boolean mIgnoreDuetoRecentsAnimation;
@@ -350,7 +357,7 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
         * @param inverseMatrix The magnification spec inverse matrix.
         * @param inverseMatrix The magnification spec inverse matrix.
         */
         */
        public static AccessibilityWindow initializeData(WindowManagerService service,
        public static AccessibilityWindow initializeData(WindowManagerService service,
                InputWindowHandle inputWindowHandle, Matrix inverseMatrix) {
                InputWindowHandle inputWindowHandle, Matrix inverseMatrix, IBinder pipIBinder) {
            final IWindow window = inputWindowHandle.getWindow();
            final IWindow window = inputWindowHandle.getWindow();
            final WindowState windowState = window != null ? service.mWindowMap.get(
            final WindowState windowState = window != null ? service.mWindowMap.get(
                    window.asBinder()) : null;
                    window.asBinder()) : null;
@@ -361,6 +368,7 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
            instance.mDisplayId = inputWindowHandle.displayId;
            instance.mDisplayId = inputWindowHandle.displayId;
            instance.mFlags = inputWindowHandle.layoutParamsFlags;
            instance.mFlags = inputWindowHandle.layoutParamsFlags;
            instance.mType = inputWindowHandle.layoutParamsType;
            instance.mType = inputWindowHandle.layoutParamsType;
            instance.mIsPIPMenu = inputWindowHandle.getWindow().asBinder().equals(pipIBinder);


            // TODO (b/199357848): gets the private flag of the window from other way.
            // TODO (b/199357848): gets the private flag of the window from other way.
            instance.mPrivateFlags = windowState != null ? windowState.mAttrs.privateFlags : 0;
            instance.mPrivateFlags = windowState != null ? windowState.mAttrs.privateFlags : 0;
@@ -491,6 +499,13 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
            return mTouchableRegionInScreen.isEmpty();
            return mTouchableRegionInScreen.isEmpty();
        }
        }


        /**
         * @return true if this window is PIP menu.
         */
        public boolean isPIPMenu() {
            return mIsPIPMenu;
        }

        private static void getTouchableRegionInWindow(boolean shouldMagnify, Region inRegion,
        private static void getTouchableRegionInWindow(boolean shouldMagnify, Region inRegion,
                Region outRegion, Rect frame, Matrix inverseMatrix) {
                Region outRegion, Rect frame, Matrix inverseMatrix) {
            // Some modal windows, like the activity with Theme.dialog, has the full screen
            // Some modal windows, like the activity with Theme.dialog, has the full screen
@@ -547,10 +562,9 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
            // one is PIP.
            // one is PIP.
            if (windowInfo.type == TYPE_DOCK_DIVIDER) {
            if (windowInfo.type == TYPE_DOCK_DIVIDER) {
                windowInfo.title = "Splitscreen Divider";
                windowInfo.title = "Splitscreen Divider";
            } else {
            } else if (window.mIsPIPMenu) {
                windowInfo.title = "Picture-in-Picture menu";
                windowInfo.title = "Picture-in-Picture menu";
            }
            }

            return windowInfo;
            return windowInfo;
        }
        }


@@ -565,18 +579,19 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {


        @Override
        @Override
        public String toString() {
        public String toString() {
            String builder = "A11yWindow=[" + mWindow
            String builder = "A11yWindow=[" + mWindow.asBinder()
                    + ", displayId=" + mDisplayId
                    + ", displayId=" + mDisplayId
                    + ", flag=0x" + Integer.toHexString(mFlags)
                    + ", flag=0x" + Integer.toHexString(mFlags)
                    + ", type=" + mType
                    + ", type=" + mType
                    + ", privateFlag=0x" + Integer.toHexString(mPrivateFlags)
                    + ", privateFlag=0x" + Integer.toHexString(mPrivateFlags)
                    + ", focused=" + mIsFocused
                    + ", focused=" + mIsFocused
                    + ", magnify=" + mShouldMagnify
                    + ", mShouldMagnify=" + mShouldMagnify
                    + ", ignoreDuetoRecentsAnimation=" + mIgnoreDuetoRecentsAnimation
                    + ", ignoreDuetoRecentsAnimation=" + mIgnoreDuetoRecentsAnimation
                    + ", mIsTrustedOverlay=" + mIsTrustedOverlay
                    + ", mIsTrustedOverlay=" + mIsTrustedOverlay
                    + ", regionInScreen=" + mTouchableRegionInScreen
                    + ", regionInScreen=" + mTouchableRegionInScreen
                    + ", touchableRegion=" + mTouchableRegionInWindow
                    + ", touchableRegion=" + mTouchableRegionInWindow
                    + ", letterBoxBounds=" + mLetterBoxBounds
                    + ", letterBoxBounds=" + mLetterBoxBounds
                    + ", isPIPMenu=" + mIsPIPMenu
                    + ", windowInfo=" + mWindowInfo
                    + ", windowInfo=" + mWindowInfo
                    + "]";
                    + "]";


+6 −42
Original line number Original line Diff line number Diff line
@@ -25,15 +25,14 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMAT
import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Point;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.RemoteException;
import android.util.Slog;
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.DisplayInfo;
import android.view.IWindow;
import android.view.IWindow;
import android.view.SurfaceControl;
import android.view.SurfaceControl;
import android.view.WindowInfo;
import android.view.WindowManager;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.Animation;


@@ -136,48 +135,13 @@ public class ShellRoot {
                ANIMATION_TYPE_WINDOW_ANIMATION);
                ANIMATION_TYPE_WINDOW_ANIMATION);
    }
    }


    WindowInfo getWindowInfo() {
    @Nullable
        if (mShellRootLayer != SHELL_ROOT_LAYER_DIVIDER
    IBinder getAccessibilityWindowToken() {
                && mShellRootLayer != SHELL_ROOT_LAYER_PIP) {
        if (mAccessibilityWindow != null) {
            return null;
            return mAccessibilityWindow.asBinder();
        }
        if (mShellRootLayer == SHELL_ROOT_LAYER_DIVIDER
                && !mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()) {
            return null;
        }
        if (mShellRootLayer == SHELL_ROOT_LAYER_PIP
                && mDisplayContent.getDefaultTaskDisplayArea().getRootPinnedTask() == null) {
            return null;
        }
        }
        if (mAccessibilityWindow == null) {
        return null;
        return null;
    }
    }
        WindowInfo windowInfo = WindowInfo.obtain();
        windowInfo.displayId = mToken.getDisplayArea().getDisplayContent().mDisplayId;
        windowInfo.type = mToken.windowType;
        windowInfo.layer = mToken.getWindowLayerFromType();
        windowInfo.token = mAccessibilityWindow.asBinder();
        windowInfo.focused = false;
        windowInfo.hasFlagWatchOutsideTouch = false;
        final Rect regionRect = new Rect();


        // DividerView
        if (mShellRootLayer == SHELL_ROOT_LAYER_DIVIDER) {
            windowInfo.inPictureInPicture = false;
            mDisplayContent.getDockedDividerController().getTouchRegion(regionRect);
            windowInfo.regionInScreen.set(regionRect);
            windowInfo.title = "Splitscreen Divider";
        }
        // PipMenuView
        if (mShellRootLayer == SHELL_ROOT_LAYER_PIP) {
            windowInfo.inPictureInPicture = true;
            mDisplayContent.getDefaultTaskDisplayArea().getRootPinnedTask().getBounds(regionRect);
            windowInfo.regionInScreen.set(regionRect);
            windowInfo.title = "Picture-in-Picture menu";
        }
        return windowInfo;
    }


    void setAccessibilityWindow(IWindow window) {
    void setAccessibilityWindow(IWindow window) {
        if (mAccessibilityWindow != null) {
        if (mAccessibilityWindow != null) {