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

Commit d536cb7c authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Make the caption window spy when requesting custom headers" into main

parents e7ce6356 e1e7fe05
Loading
Loading
Loading
Loading
+20 −6
Original line number Diff line number Diff line
@@ -430,11 +430,25 @@ constructor(
        var shouldSetAppBounds = false
        if (isAppHeader) {
            if (taskInfo.isTransparentCaptionBarAppearance) {
                if (!DesktopModeFlags.ENABLE_ACCESSIBLE_CUSTOM_HEADERS.isTrue) {
                    // Allow input to fall through to the windows below so that the app can respond
                    // to input events on their custom content.
                // The app is requesting to customize the caption bar, which means input on
                // customizable/exclusion regions must go to the app instead of to the system.
                // Custom touchable regions OR spy windows are usually sufficient to satisfy this
                // requirement for the general case, but some edge cases make it so we actually
                // need both:
                // 1) Spy window by itself does not let a11y services "see" through the window and
                // focus the custom content. The touchable region carveout helps here. Note that
                // this is set by |CaptionController#calculateLimitedTouchableRegion|.
                // 2) When the app has a modal window on top of the window that reports exclusion
                // regions, the modal window actually blocks the exclusion region from being
                // reported to SystemUI, which prevents the window decoration from correctly
                // setting the touchable region (of the caption) and thus touching the
                // custom region has the input consumed by the caption and makes it impossible for
                // the modal to be closed in this region, see b/414521306.
                // So by setting the spy feature the input can fall through to the windows below,
                // but more precisely it allows the first motion event over a modal window to fall
                // through and dismiss the modal, even when the caption touchable region is not
                // being limited.
                inputFeatures = inputFeatures or WindowManager.LayoutParams.INPUT_FEATURE_SPY
                }
            } else if (DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION.isTrue) {
                if (shouldExcludeCaptionFromAppBounds) {
                    shouldSetAppBounds = true
@@ -855,7 +869,7 @@ constructor(

    /** Checks if touch event occurred in caption's customizable region. */
    fun checkTouchEventInCustomizableRegion(e: MotionEvent): Boolean =
        (captionController as? AppHandleController)?.checkTouchEventInCustomizableRegion(e) ?: false
        captionController?.checkTouchEventInCustomizableRegion(e) ?: false

    /** Adds inset for caption if one exists. */
    fun addCaptionInset(wct: WindowContainerTransaction) {
+1 −5
Original line number Diff line number Diff line
@@ -114,9 +114,6 @@ public class DesktopModeTouchEventListener
     * Whether to pilfer the next motion event to send cancellations to the windows below.
     * Useful when the caption window is spy and the gesture should be handled by the system
     * instead of by the app for their custom header content.
     * Should not have any effect when
     * {@link DesktopModeFlags#ENABLE_ACCESSIBLE_CUSTOM_HEADERS}, because a spy window is not
     * used then.
     */
    private boolean mIsCustomHeaderGesture;
    private boolean mIsResizeGesture;
@@ -334,8 +331,7 @@ public class DesktopModeTouchEventListener
                    viewName, mIsCustomHeaderGesture, mIsResizeGesture);
            return false;
        }
        if (mInputManager != null
                && !DesktopModeFlags.ENABLE_ACCESSIBLE_CUSTOM_HEADERS.isTrue()) {
        if (mInputManager != null) {
            ViewRootImpl viewRootImpl = v.getViewRootImpl();
            if (viewRootImpl != null) {
                // Pilfer so that windows below receive cancellations for this gesture.
+16 −5
Original line number Diff line number Diff line
@@ -1131,18 +1131,29 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            if (TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo)) {
                // The app is requesting to customize the caption bar, which means input on
                // customizable/exclusion regions must go to the app instead of to the system.
                // This may be accomplished with spy windows or custom touchable regions:
                // Custom touchable regions OR spy windows are usually sufficient to satisfy this
                // requirement for the general case, but some edge cases make it so we actually
                // need both:
                // 1) Spy window by itself does not let a11y services "see" through the window and
                // focus the custom content. The touchable region carveout helps here.
                // 2) When the app has a modal window on top of the window that reports exclusion
                // regions, the modal window actually blocks the exclusion region from being
                // reported to SystemUI, which prevents the window decoration from correctly
                // setting the touchable region (of the caption) and thus touching the custom
                // region has the input consumed by the caption and makes it impossible for the
                // modal to be closed in this region, see b/414521306.
                if (DesktopModeFlags.ENABLE_ACCESSIBLE_CUSTOM_HEADERS.isTrue()) {
                    // Set the touchable region of the caption to only the areas where input should
                    // be handled by the system (i.e. non custom-excluded areas). The region will
                    // be calculated based on occluding caption elements and exclusion areas
                    // reported by the app.
                    relayoutParams.mLimitTouchRegionToSystemAreas = true;
                } else {
                    // Allow input to fall through to the windows below so that the app can respond
                    // to input events on their custom content.
                    relayoutParams.mInputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
                }
                // Also allow input to fall through to the windows below so that the app can
                // respond to input events on their custom content, but more precisely to allow
                // the first motion event over a modal window to fall through and dismiss the modal,
                // even when the caption touchable region is not being limited.
                relayoutParams.mInputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
            } else {
                if (ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION.isTrue()) {
                    if (shouldExcludeCaptionFromAppBounds) {
+2 −6
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.view.MotionEvent
import android.view.SurfaceControl
import android.view.View
import android.view.WindowManager
import android.window.DesktopModeFlags
import android.window.WindowContainerTransaction
import com.android.app.tracing.traceSection
import com.android.internal.protolog.ProtoLog
@@ -280,11 +279,8 @@ abstract class CaptionController<T>(
        decorWindowContext: Context,
        localCaptionBounds: Rect,
    ): Region? {
        // If app is not requesting custom caption, touchable region is not limited so return null
        if (
            !taskInfo.isTransparentCaptionBarAppearance ||
                !DesktopModeFlags.ENABLE_ACCESSIBLE_CUSTOM_HEADERS.isTrue
        ) {
        if (!taskInfo.isTransparentCaptionBarAppearance) {
            // App is not requesting custom caption, touchable region is not limited so return null.
            return null
        }

+0 −3
Original line number Diff line number Diff line
@@ -663,7 +663,6 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
    }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_ACCESSIBLE_CUSTOM_HEADERS)
    public void updateRelayoutParams_freeformAndTransparentAppearance_allowsInputFallthrough() {
        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
@@ -691,7 +690,6 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
    }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_ACCESSIBLE_CUSTOM_HEADERS)
    public void updateRelayoutParams_freeformButOpaqueAppearance_disallowsInputFallthrough() {
        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
@@ -717,7 +715,6 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
    }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_ACCESSIBLE_CUSTOM_HEADERS)
    public void updateRelayoutParams_fullscreen_disallowsInputFallthrough() {
        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);