Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DefaultWindowDecoration.kt +20 −6 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeTouchEventListener.java +1 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +16 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/caption/CaptionController.kt +2 −6 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java +0 −3 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading @@ -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); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DefaultWindowDecoration.kt +20 −6 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeTouchEventListener.java +1 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +16 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/caption/CaptionController.kt +2 −6 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java +0 −3 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading @@ -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); Loading