diff options
21 files changed, 234 insertions, 213 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 0db91f5667ee..177b859da0ad 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -941,7 +941,7 @@ package android.companion.virtual { method public int getAudioRecordingSessionId(int); method public int getDeviceIdForDisplayId(int); method public int getDevicePolicy(int, int); - method @FlaggedApi("android.companion.virtual.flags.interactive_screen_mirror") public boolean isVirtualDeviceOwnedMirrorDisplay(int); + method public boolean isVirtualDeviceOwnedMirrorDisplay(int); method public void playSoundEffect(int, int); } diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java index 8b60580ec114..d07fb2508a49 100644 --- a/core/java/android/companion/virtual/VirtualDeviceManager.java +++ b/core/java/android/companion/virtual/VirtualDeviceManager.java @@ -531,7 +531,6 @@ public final class VirtualDeviceManager { * * @hide */ - @FlaggedApi(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR) @TestApi public boolean isVirtualDeviceOwnedMirrorDisplay(int displayId) { if (mService == null) { diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig index 91586b6bfae2..fc9c94dd5b0f 100644 --- a/core/java/android/companion/virtual/flags.aconfig +++ b/core/java/android/companion/virtual/flags.aconfig @@ -35,13 +35,6 @@ flag { } flag { - name: "consistent_display_flags" - namespace: "virtual_devices" - description: "Make virtual display flags consistent with display manager" - bug: "300905478" -} - -flag { name: "vdm_custom_ime" is_exported: true namespace: "virtual_devices" @@ -89,14 +82,6 @@ flag { } flag { - name: "interactive_screen_mirror" - is_exported: true - namespace: "virtual_devices" - description: "Enable interactive screen mirroring using Virtual Devices" - bug: "292212199" -} - -flag { name: "virtual_stylus" is_exported: true namespace: "virtual_devices" diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java index d754d04e6b33..26f7b360e0fc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java @@ -20,6 +20,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; import android.annotation.NonNull; +import android.annotation.Nullable; import android.graphics.Color; import android.graphics.Rect; import android.view.SurfaceControl; @@ -59,6 +60,23 @@ public class BackAnimationBackground { */ public void ensureBackground(Rect startRect, int color, @NonNull SurfaceControl.Transaction transaction, int statusbarHeight) { + ensureBackground(startRect, color, transaction, statusbarHeight, + null /* cropBounds */, 0 /* cornerRadius */); + } + + /** + * Ensures the back animation background color layer is present. + * + * @param startRect The start bounds of the closing target. + * @param color The background color. + * @param transaction The animation transaction. + * @param statusbarHeight The height of the statusbar (in px). + * @param cropBounds The crop bounds of the surface, set to non-empty to show wallpaper. + * @param cornerRadius The radius of corner, only work when cropBounds is not empty. + */ + public void ensureBackground(Rect startRect, int color, + @NonNull SurfaceControl.Transaction transaction, int statusbarHeight, + @Nullable Rect cropBounds, float cornerRadius) { if (mBackgroundSurface != null) { return; } @@ -78,6 +96,10 @@ public class BackAnimationBackground { transaction.setColor(mBackgroundSurface, colorComponents) .setLayer(mBackgroundSurface, BACKGROUND_LAYER) .show(mBackgroundSurface); + if (cropBounds != null && !cropBounds.isEmpty()) { + transaction.setCrop(mBackgroundSurface, cropBounds) + .setCornerRadius(mBackgroundSurface, cornerRadius); + } mStartBounds = startRect; mIsRequestingStatusBarAppearance = false; mStatusbarHeight = statusbarHeight; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt index 4fd8b8a5f1b8..32e809a23a91 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt @@ -189,10 +189,13 @@ abstract class CrossActivityBackAnimation( preparePreCommitEnteringRectMovement() background.ensureBackground( - closingTarget!!.windowConfiguration.bounds, - getBackgroundColor(), - transaction, - statusbarHeight + closingTarget!!.windowConfiguration.bounds, + getBackgroundColor(), + transaction, + statusbarHeight, + if (closingTarget!!.windowConfiguration.tasksAreFloating()) + closingTarget!!.localBounds else null, + cornerRadius ) ensureScrimLayer() if (isLetterboxed && enteringHasSameLetterbox) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java index 0f2de700d3ae..cb9781e86c87 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java @@ -82,32 +82,26 @@ public class DragPositioningCallbackUtility { final int oldRight = repositionTaskBounds.right; final int oldBottom = repositionTaskBounds.bottom; - repositionTaskBounds.set(taskBoundsAtDragStart); // Make sure the new resizing destination in any direction falls within the stable bounds. - // If not, set the bounds back to the old location that was valid to avoid conflicts with - // some regions such as the gesture area. if ((ctrlType & CTRL_TYPE_LEFT) != 0) { - final int candidateLeft = repositionTaskBounds.left + (int) delta.x; - repositionTaskBounds.left = (candidateLeft > stableBounds.left) - ? candidateLeft : oldLeft; + repositionTaskBounds.left = Math.max(repositionTaskBounds.left + (int) delta.x, + stableBounds.left); } if ((ctrlType & CTRL_TYPE_RIGHT) != 0) { - final int candidateRight = repositionTaskBounds.right + (int) delta.x; - repositionTaskBounds.right = (candidateRight < stableBounds.right) - ? candidateRight : oldRight; + repositionTaskBounds.right = Math.min(repositionTaskBounds.right + (int) delta.x, + stableBounds.right); } if ((ctrlType & CTRL_TYPE_TOP) != 0) { - final int candidateTop = repositionTaskBounds.top + (int) delta.y; - repositionTaskBounds.top = (candidateTop > stableBounds.top) - ? candidateTop : oldTop; + repositionTaskBounds.top = Math.max(repositionTaskBounds.top + (int) delta.y, + stableBounds.top); } if ((ctrlType & CTRL_TYPE_BOTTOM) != 0) { - final int candidateBottom = repositionTaskBounds.bottom + (int) delta.y; - repositionTaskBounds.bottom = (candidateBottom < stableBounds.bottom) - ? candidateBottom : oldBottom; + repositionTaskBounds.bottom = Math.min(repositionTaskBounds.bottom + (int) delta.y, + stableBounds.bottom); } + // If width or height are negative or exceeding the width or height constraints, revert the // respective bounds to use previous bound dimensions. if (isExceedingWidthConstraint(repositionTaskBounds, stableBounds, displayController, @@ -120,14 +114,12 @@ public class DragPositioningCallbackUtility { repositionTaskBounds.top = oldTop; repositionTaskBounds.bottom = oldBottom; } - // If there are no changes to the bounds after checking new bounds against minimum width - // and height, do not set bounds and return false - if (oldLeft == repositionTaskBounds.left && oldTop == repositionTaskBounds.top - && oldRight == repositionTaskBounds.right - && oldBottom == repositionTaskBounds.bottom) { - return false; - } - return true; + + // If there are no changes to the bounds after checking new bounds against minimum and + // maximum width and height, do not set bounds and return false + return oldLeft != repositionTaskBounds.left || oldTop != repositionTaskBounds.top + || oldRight != repositionTaskBounds.right + || oldBottom != repositionTaskBounds.bottom; } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java index fd7bed7c60de..6dedf6da3ab7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java @@ -16,6 +16,7 @@ package com.android.wm.shell.windowdecor; +import static android.view.InputDevice.SOURCE_MOUSE; import static android.view.InputDevice.SOURCE_TOUCHSCREEN; import static com.android.wm.shell.shared.desktopmode.DesktopModeFlags.EDGE_DRAG_RESIZE; @@ -166,7 +167,10 @@ final class DragResizeWindowGeometry { static boolean isEdgeResizePermitted(@NonNull Context context, @NonNull MotionEvent e) { if (EDGE_DRAG_RESIZE.isEnabled(context)) { return e.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS - || e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE; + || e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE + // Touchpad input + || (e.isFromSource(SOURCE_MOUSE) + && e.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER); } else { return e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE; } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt index e52971120478..1f33ae69b724 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt @@ -93,7 +93,7 @@ class DragPositioningCallbackUtilityTest { fun setup() { MockitoAnnotations.initMocks(this) mockitoSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT) - .spyStatic(DesktopModeStatus::class.java).startMocking() + .spyStatic(DesktopModeStatus::class.java).startMocking() whenever(taskToken.asBinder()).thenReturn(taskBinder) whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) @@ -108,9 +108,9 @@ class DragPositioningCallbackUtilityTest { whenever(mockContext.getResources()).thenReturn(mockResources) whenever(mockWindowDecoration.mDecorWindowContext.resources).thenReturn(mockResources) whenever(mockResources.getDimensionPixelSize(R.dimen.desktop_mode_minimum_window_width)) - .thenReturn(DESKTOP_MODE_MIN_WIDTH) + .thenReturn(DESKTOP_MODE_MIN_WIDTH) whenever(mockResources.getDimensionPixelSize(R.dimen.desktop_mode_minimum_window_height)) - .thenReturn(DESKTOP_MODE_MIN_HEIGHT) + .thenReturn(DESKTOP_MODE_MIN_HEIGHT) whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID } } @@ -129,9 +129,11 @@ class DragPositioningCallbackUtilityTest { val newY = STARTING_BOUNDS.top.toFloat() + 95 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration) + mockWindowDecoration + ) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) @@ -149,9 +151,11 @@ class DragPositioningCallbackUtilityTest { val newY = STARTING_BOUNDS.top.toFloat() + 5 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration) + mockWindowDecoration + ) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top + 5) @@ -169,9 +173,11 @@ class DragPositioningCallbackUtilityTest { val newY = STARTING_BOUNDS.top.toFloat() + 105 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration) + mockWindowDecoration + ) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) @@ -189,9 +195,11 @@ class DragPositioningCallbackUtilityTest { val newY = STARTING_BOUNDS.top.toFloat() + 80 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration) + mockWindowDecoration + ) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top + 80) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 80) @@ -208,9 +216,11 @@ class DragPositioningCallbackUtilityTest { val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration) + mockWindowDecoration + ) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right) @@ -221,52 +231,95 @@ class DragPositioningCallbackUtilityTest { fun testDragEndSnapsTaskBoundsWhenOutsideValidDragArea() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) val repositionTaskBounds = Rect(STARTING_BOUNDS) - val validDragArea = Rect(DISPLAY_BOUNDS.left - 100, + val validDragArea = Rect( + DISPLAY_BOUNDS.left - 100, STABLE_BOUNDS.top, DISPLAY_BOUNDS.right - 100, - DISPLAY_BOUNDS.bottom - 100) + DISPLAY_BOUNDS.bottom - 100 + ) - DragPositioningCallbackUtility.updateTaskBounds(repositionTaskBounds, STARTING_BOUNDS, - startingPoint, startingPoint.x - 1000, (DISPLAY_BOUNDS.bottom + 1000).toFloat()) - DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(repositionTaskBounds, - validDragArea) + DragPositioningCallbackUtility.updateTaskBounds( + repositionTaskBounds, STARTING_BOUNDS, + startingPoint, startingPoint.x - 1000, (DISPLAY_BOUNDS.bottom + 1000).toFloat() + ) + DragPositioningCallbackUtility.snapTaskBoundsIfNecessary( + repositionTaskBounds, + validDragArea + ) assertThat(repositionTaskBounds.left).isEqualTo(validDragArea.left) assertThat(repositionTaskBounds.top).isEqualTo(validDragArea.bottom) assertThat(repositionTaskBounds.right) - .isEqualTo(validDragArea.left + STARTING_BOUNDS.width()) + .isEqualTo(validDragArea.left + STARTING_BOUNDS.width()) assertThat(repositionTaskBounds.bottom) - .isEqualTo(validDragArea.bottom + STARTING_BOUNDS.height()) + .isEqualTo(validDragArea.bottom + STARTING_BOUNDS.height()) } @Test fun testChangeBounds_toDisallowedBounds_freezesAtLimit() { - val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), - STARTING_BOUNDS.bottom.toFloat()) + val startingPoint = PointF( + STARTING_BOUNDS.right.toFloat(), + STARTING_BOUNDS.bottom.toFloat() + ) val repositionTaskBounds = Rect(STARTING_BOUNDS) // Initial resize to width and height 110px. var newX = STARTING_BOUNDS.right.toFloat() + 10 var newY = STARTING_BOUNDS.bottom.toFloat() + 10 var delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - assertTrue(DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, - repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration)) + assertTrue( + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, + repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, + mockWindowDecoration + ) + ) // Resize width to 120px, height to disallowed area which should not result in a change. newX += 10 newY = DISALLOWED_RESIZE_AREA.top.toFloat() delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - assertTrue(DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, - repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration)) + assertTrue( + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, + repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, + mockWindowDecoration + ) + ) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right + 20) - assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom + 10) + assertThat(repositionTaskBounds.bottom).isEqualTo(STABLE_BOUNDS.bottom) + } + + + @Test + fun testChangeBounds_beyondStableBounds_freezesAtStableBounds() { + val startingPoint = PointF( + STARTING_BOUNDS.right.toFloat(), + STARTING_BOUNDS.bottom.toFloat() + ) + val repositionTaskBounds = Rect(STARTING_BOUNDS) + + // Resize to beyond stable bounds. + val newX = STARTING_BOUNDS.right.toFloat() + STABLE_BOUNDS.width() + val newY = STARTING_BOUNDS.bottom.toFloat() + STABLE_BOUNDS.height() + + val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) + assertTrue( + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, + repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, + mockWindowDecoration + ) + ) + assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) + assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) + assertThat(repositionTaskBounds.right).isEqualTo(STABLE_BOUNDS.right) + assertThat(repositionTaskBounds.bottom).isEqualTo(STABLE_BOUNDS.bottom) } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS) fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeLessThanMin_shouldNotChangeBounds() { - doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) } + doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(mockContext) } initializeTaskInfo(taskMinWidth = -1, taskMinHeight = -1) val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat()) @@ -277,9 +330,11 @@ class DragPositioningCallbackUtilityTest { val newY = STARTING_BOUNDS.bottom.toFloat() - 99 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration) + mockWindowDecoration + ) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right) @@ -289,7 +344,7 @@ class DragPositioningCallbackUtilityTest { @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS) fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeAllowedSize_shouldChangeBounds() { - doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) } + doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(mockContext) } initializeTaskInfo(taskMinWidth = -1, taskMinHeight = -1) val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat()) @@ -300,9 +355,11 @@ class DragPositioningCallbackUtilityTest { val newY = STARTING_BOUNDS.bottom.toFloat() - 80 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration) + mockWindowDecoration + ) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 80) @@ -321,9 +378,11 @@ class DragPositioningCallbackUtilityTest { val newY = STARTING_BOUNDS.bottom.toFloat() - 99 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration) + mockWindowDecoration + ) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right) @@ -342,9 +401,11 @@ class DragPositioningCallbackUtilityTest { val newY = STARTING_BOUNDS.bottom.toFloat() - 50 val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, - mockWindowDecoration) + mockWindowDecoration + ) assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 50) @@ -355,8 +416,10 @@ class DragPositioningCallbackUtilityTest { @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS) fun testChangeBounds_windowSizeExceedsStableBounds_shouldBeAllowedToChangeBounds() { val startingPoint = - PointF(OFF_CENTER_STARTING_BOUNDS.right.toFloat(), - OFF_CENTER_STARTING_BOUNDS.bottom.toFloat()) + PointF( + OFF_CENTER_STARTING_BOUNDS.right.toFloat(), + OFF_CENTER_STARTING_BOUNDS.bottom.toFloat() + ) val repositionTaskBounds = Rect(OFF_CENTER_STARTING_BOUNDS) // Increase height and width by STABLE_BOUNDS. Subtract by 5px so that it doesn't reach // the disallowed drag area. @@ -365,9 +428,11 @@ class DragPositioningCallbackUtilityTest { val newY = STABLE_BOUNDS.bottom.toFloat() - offset val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, repositionTaskBounds, OFF_CENTER_STARTING_BOUNDS, STABLE_BOUNDS, delta, - mockDisplayController, mockWindowDecoration) + mockDisplayController, mockWindowDecoration + ) assertThat(repositionTaskBounds.width()).isGreaterThan(STABLE_BOUNDS.right) assertThat(repositionTaskBounds.height()).isGreaterThan(STABLE_BOUNDS.bottom) } @@ -375,10 +440,12 @@ class DragPositioningCallbackUtilityTest { @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS) fun testChangeBoundsInDesktopMode_windowSizeExceedsStableBounds_shouldBeLimitedToDisplaySize() { - doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) } + doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(mockContext) } val startingPoint = - PointF(OFF_CENTER_STARTING_BOUNDS.right.toFloat(), - OFF_CENTER_STARTING_BOUNDS.bottom.toFloat()) + PointF( + OFF_CENTER_STARTING_BOUNDS.right.toFloat(), + OFF_CENTER_STARTING_BOUNDS.bottom.toFloat() + ) val repositionTaskBounds = Rect(OFF_CENTER_STARTING_BOUNDS) // Increase height and width by STABLE_BOUNDS. Subtract by 5px so that it doesn't reach // the disallowed drag area. @@ -387,9 +454,11 @@ class DragPositioningCallbackUtilityTest { val newY = STABLE_BOUNDS.bottom.toFloat() - offset val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) - DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, repositionTaskBounds, OFF_CENTER_STARTING_BOUNDS, STABLE_BOUNDS, delta, - mockDisplayController, mockWindowDecoration) + mockDisplayController, mockWindowDecoration + ) assertThat(repositionTaskBounds.width()).isLessThan(STABLE_BOUNDS.right) assertThat(repositionTaskBounds.height()).isLessThan(STABLE_BOUNDS.bottom) } @@ -423,7 +492,8 @@ class DragPositioningCallbackUtilityTest { DISPLAY_BOUNDS.left, DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT, DISPLAY_BOUNDS.right, - DISPLAY_BOUNDS.bottom) + DISPLAY_BOUNDS.bottom + ) private val STABLE_BOUNDS = Rect( DISPLAY_BOUNDS.left, DISPLAY_BOUNDS.top, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt index 2ce59ff0a4a9..3a3e965b625e 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt @@ -678,6 +678,7 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM) val rectAfterDrag = Rect(STARTING_BOUNDS) rectAfterDrag.right += 2000 + rectAfterDrag.bottom = STABLE_BOUNDS_LANDSCAPE.bottom // First drag; we should fetch stable bounds. verify(mockDisplayLayout, Mockito.times(1)).getStableBounds(any()) verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> @@ -705,8 +706,8 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat(), STARTING_BOUNDS.right.toFloat() + 2000, STARTING_BOUNDS.bottom.toFloat() + 2000, CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM) - rectAfterDrag.right -= 2000 - rectAfterDrag.bottom += 2000 + rectAfterDrag.right = STABLE_BOUNDS_PORTRAIT.right + rectAfterDrag.bottom = STARTING_BOUNDS.bottom + 2000 verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt index 08a6e1ba676b..6ae16edaf3df 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt @@ -372,6 +372,7 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM) val rectAfterDrag = Rect(STARTING_BOUNDS) rectAfterDrag.right += 2000 + rectAfterDrag.bottom = STABLE_BOUNDS_LANDSCAPE.bottom // First drag; we should fetch stable bounds. verify(mockDisplayLayout, times(1)).getStableBounds(any()) verify(mockTransitions).startTransition(eq(TRANSIT_CHANGE), argThat { wct -> @@ -396,8 +397,8 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { performDrag(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat(), STARTING_BOUNDS.right.toFloat() + 2000, STARTING_BOUNDS.bottom.toFloat() + 2000, CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM) - rectAfterDrag.right -= 2000 - rectAfterDrag.bottom += 2000 + rectAfterDrag.right = STABLE_BOUNDS_PORTRAIT.right + rectAfterDrag.bottom = STARTING_BOUNDS.bottom + 2000 verify(mockTransitions).startTransition(eq(TRANSIT_CHANGE), argThat { wct -> return@argThat wct.changes.any { (token, change) -> diff --git a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt index e4b290d7d10e..15a3cbdb8072 100644 --- a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt @@ -17,7 +17,6 @@ package com.android.systemui.display.domain.interactor import android.companion.virtual.VirtualDeviceManager -import android.companion.virtual.flags.Flags import android.view.Display import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background @@ -155,8 +154,7 @@ constructor( } private fun isVirtualDeviceOwnedMirrorDisplay(display: Display): Boolean { - return Flags.interactiveScreenMirror() && - virtualDeviceManager != null && + return virtualDeviceManager != null && virtualDeviceManager.isVirtualDeviceOwnedMirrorDisplay(display.displayId) } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt index fa400593c990..0451ce6d9fce 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt @@ -19,6 +19,7 @@ package com.android.systemui.volume.panel.component.volume.domain.interactor import android.media.AudioDeviceInfo import android.media.AudioManager import com.android.settingslib.volume.data.repository.AudioRepository +import com.android.settingslib.volume.domain.interactor.AudioModeInteractor import com.android.settingslib.volume.shared.model.AudioStream import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession @@ -42,6 +43,7 @@ constructor( @VolumePanelScope scope: CoroutineScope, mediaOutputInteractor: MediaOutputInteractor, audioRepository: AudioRepository, + audioModeInteractor: AudioModeInteractor, ) { val volumePanelSliders: StateFlow<List<SliderType>> = @@ -49,9 +51,14 @@ constructor( mediaOutputInteractor.activeMediaDeviceSessions, mediaOutputInteractor.defaultActiveMediaSession.filterData(), audioRepository.communicationDevice, - ) { activeSessions, defaultSession, communicationDevice -> + audioModeInteractor.isOngoingCall, + ) { activeSessions, defaultSession, communicationDevice, isOngoingCall -> coroutineScope { val viewModels = buildList { + if (isOngoingCall) { + addCall(communicationDevice?.type) + } + if (defaultSession?.isTheSameSession(activeSessions.remote) == true) { addSession(activeSessions.remote) addStream(AudioManager.STREAM_MUSIC) @@ -60,11 +67,10 @@ constructor( addSession(activeSessions.remote) } - if (communicationDevice?.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO) { - addStream(AudioManager.STREAM_BLUETOOTH_SCO) - } else { - addStream(AudioManager.STREAM_VOICE_CALL) + if (!isOngoingCall) { + addCall(communicationDevice?.type) } + addStream(AudioManager.STREAM_RING) addStream(AudioManager.STREAM_NOTIFICATION) addStream(AudioManager.STREAM_ALARM) @@ -74,6 +80,14 @@ constructor( } .stateIn(scope, SharingStarted.Eagerly, emptyList()) + private fun MutableList<SliderType>.addCall(communicationDeviceType: Int?) { + if (communicationDeviceType == AudioDeviceInfo.TYPE_BLUETOOTH_SCO) { + addStream(AudioManager.STREAM_BLUETOOTH_SCO) + } else { + addStream(AudioManager.STREAM_VOICE_CALL) + } + } + private fun MutableList<SliderType>.addSession(remoteMediaDeviceSession: MediaDeviceSession?) { if (remoteMediaDeviceSession?.canAdjustVolume == true) { add(SliderType.MediaDeviceCast(remoteMediaDeviceSession)) diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt index 4b4d69a31db4..45732deb9aa6 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt @@ -16,6 +16,7 @@ package com.android.systemui.volume.panel.component.volume.ui.viewmodel +import com.android.settingslib.volume.domain.interactor.AudioModeInteractor import com.android.settingslib.volume.shared.model.AudioStream import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaDeviceSessionInteractor import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor @@ -35,9 +36,11 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn @@ -58,24 +61,31 @@ constructor( mediaDeviceSessionInteractor: MediaDeviceSessionInteractor, private val streamSliderViewModelFactory: AudioStreamSliderViewModel.Factory, private val castVolumeSliderViewModelFactory: CastVolumeSliderViewModel.Factory, + audioModeInteractor: AudioModeInteractor, streamsInteractor: AudioSlidersInteractor, ) { private val mutableIsExpanded = MutableStateFlow<Boolean?>(null) - private val isPlaybackActive: Flow<Boolean?> = - mediaOutputInteractor.defaultActiveMediaSession - .filterData() - .flatMapLatest { session -> - if (session == null) { - flowOf(false) - } else { - mediaDeviceSessionInteractor.playbackState(session).map { it?.isActive == true } - } + private val isActive: Flow<Boolean?> = + combine( + audioModeInteractor.isOngoingCall, + mediaOutputInteractor.defaultActiveMediaSession.filterData().flatMapLatest { session + -> + if (session == null) { + flowOf(false) + } else { + mediaDeviceSessionInteractor.playbackState(session).map { + it?.isActive == true + } + } + }, + ) { isOngoingCall, isPlaybackActive -> + isOngoingCall || isPlaybackActive } - .onEach { isPlaybackActive -> mutableIsExpanded.value = !isPlaybackActive } .stateIn(scope, SharingStarted.Eagerly, null) + private val portraitExpandable: Flow<SlidersExpandableViewModel> = - isPlaybackActive + isActive .filterNotNull() .flatMapLatest { isActive -> if (isActive) { @@ -105,6 +115,10 @@ constructor( } .stateIn(scope, SharingStarted.Eagerly, emptyList()) + init { + isActive.filterNotNull().onEach { mutableIsExpanded.value = !it }.launchIn(scope) + } + fun isExpandable(isPortrait: Boolean): Flow<SlidersExpandableViewModel> { return if (isPortrait) { portraitExpandable diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt index fd9964f938c8..a2b50fd2ec17 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt @@ -17,8 +17,6 @@ package com.android.systemui.display.domain.interactor import android.companion.virtual.VirtualDeviceManager -import android.companion.virtual.flags.Flags.FLAG_INTERACTIVE_SCREEN_MIRROR -import android.platform.test.annotations.EnableFlags import android.testing.TestableLooper import android.view.Display import android.view.Display.TYPE_EXTERNAL @@ -160,7 +158,6 @@ class ConnectedDisplayInteractorTest : SysuiTestCase() { } @Test - @EnableFlags(FLAG_INTERACTIVE_SCREEN_MIRROR) fun displayState_virtualDeviceOwnedMirrorVirtualDisplay_connected() = testScope.runTest { whenever(virtualDeviceManager.isVirtualDeviceOwnedMirrorDisplay(anyInt())) @@ -183,7 +180,6 @@ class ConnectedDisplayInteractorTest : SysuiTestCase() { } @Test - @EnableFlags(FLAG_INTERACTIVE_SCREEN_MIRROR) fun virtualDeviceOwnedMirrorVirtualDisplay_emitsConnectedDisplayAddition() = testScope.runTest { whenever(virtualDeviceManager.isVirtualDeviceOwnedMirrorDisplay(anyInt())) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt index a0a39d14dcf6..63386d016a7a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt @@ -17,15 +17,17 @@ package com.android.systemui.volume.panel.component.volume.domain.interactor import com.android.systemui.kosmos.Kosmos -import com.android.systemui.kosmos.testScope +import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.volume.data.repository.audioRepository +import com.android.systemui.volume.domain.interactor.audioModeInteractor import com.android.systemui.volume.mediaOutputInteractor val Kosmos.audioSlidersInteractor by Kosmos.Fixture { AudioSlidersInteractor( - testScope.backgroundScope, + applicationCoroutineScope, mediaOutputInteractor, audioRepository, + audioModeInteractor, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt index 45a291e0e401..6e848ce26d9b 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt @@ -18,6 +18,7 @@ package com.android.systemui.volume.panel.component.volume.ui.viewmodel import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope +import com.android.systemui.volume.domain.interactor.audioModeInteractor import com.android.systemui.volume.mediaDeviceSessionInteractor import com.android.systemui.volume.mediaOutputInteractor import com.android.systemui.volume.panel.component.volume.domain.interactor.audioSlidersInteractor @@ -32,6 +33,7 @@ val Kosmos.audioVolumeComponentViewModel by mediaDeviceSessionInteractor, audioStreamSliderViewModelFactory, castVolumeSliderViewModelFactory, + audioModeInteractor, audioSlidersInteractor, ) } diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index 2db54435199b..1be352e8e3da 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -137,11 +137,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub | DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS; - private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS_PRE_VIC = - DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC - | DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT - | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; - private static final String PERSISTENT_ID_PREFIX_CDM_ASSOCIATION = "companion:"; /** @@ -373,9 +368,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS; - if (!Flags.consistentDisplayFlags()) { - flags |= DEFAULT_VIRTUAL_DISPLAY_FLAGS_PRE_VIC; - } if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) { flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED; } @@ -1254,10 +1246,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub // as the virtual display doesn't have any focused windows. Hence, call this for // associating any input device to the source display if the input device emits any key events. private int getTargetDisplayIdForInput(int displayId) { - if (!Flags.interactiveScreenMirror()) { - return displayId; - } - DisplayManagerInternal displayManager = LocalServices.getService( DisplayManagerInternal.class); int mirroredDisplayId = displayManager.getDisplayIdToMirror(displayId); @@ -1313,9 +1301,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub int displayId; displayId = mDisplayManagerInternal.createVirtualDisplay(virtualDisplayConfig, callback, this, gwpc, packageName); - gwpc.setDisplayId(displayId, /* isMirrorDisplay= */ Flags.interactiveScreenMirror() - && mDisplayManagerInternal.getDisplayIdToMirror(displayId) - != Display.INVALID_DISPLAY); + boolean isMirrorDisplay = + mDisplayManagerInternal.getDisplayIdToMirror(displayId) != Display.INVALID_DISPLAY; + gwpc.setDisplayId(displayId, isMirrorDisplay); boolean showPointer; synchronized (mVirtualDeviceLock) { diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 9e905abd78ed..55a6ce7142f3 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -64,7 +64,6 @@ import android.app.AppOpsManager; import android.app.compat.CompatChanges; import android.companion.virtual.IVirtualDevice; import android.companion.virtual.VirtualDeviceManager; -import android.companion.virtual.flags.Flags; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.content.BroadcastReceiver; @@ -1633,8 +1632,7 @@ public final class DisplayManagerService extends SystemService { && (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { // Only a valid media projection or a virtual device can create a mirror virtual // display. - if (!canProjectVideo(projection) - && !isMirroringSupportedByVirtualDevice(virtualDevice)) { + if (!canProjectVideo(projection) && virtualDevice == null) { throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or " + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate " + "MediaProjection token in order to create a screen sharing virtual " @@ -1896,10 +1894,6 @@ public final class DisplayManagerService extends SystemService { return -1; } - private static boolean isMirroringSupportedByVirtualDevice(IVirtualDevice virtualDevice) { - return Flags.interactiveScreenMirror() && virtualDevice != null; - } - private void resizeVirtualDisplayInternal(IBinder appToken, int width, int height, int densityDpi) { synchronized (mSyncRoot) { diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java index 767effd0ef12..87867f6ab7d2 100644 --- a/services/core/java/com/android/server/wm/BackNavigationController.java +++ b/services/core/java/com/android/server/wm/BackNavigationController.java @@ -283,8 +283,10 @@ class BackNavigationController { // keyguard locked and activities are unable to show when locked. backType = BackNavigationInfo.TYPE_CALLBACK; } - } else if (currentTask.mAtmService.getLockTaskController().isTaskLocked(currentTask)) { + } else if (currentTask.mAtmService.getLockTaskController().isTaskLocked(currentTask) + || currentTask.getWindowConfiguration().tasksAreFloating()) { // Do not predict if current task is in task locked. + // Also, it is unable to play cross task animation for floating task. backType = BackNavigationInfo.TYPE_CALLBACK; } else { // Check back-to-home or cross-task diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java index 2b03dc4f78ad..bbf2ecbb9380 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -69,7 +69,6 @@ import android.app.PropertyInvalidatedCache; import android.companion.virtual.IVirtualDevice; import android.companion.virtual.IVirtualDeviceManager; import android.companion.virtual.VirtualDeviceManager; -import android.companion.virtual.flags.Flags; import android.compat.testing.PlatformCompatChangeRule; import android.content.BroadcastReceiver; import android.content.Context; @@ -374,7 +373,6 @@ public class DisplayManagerServiceTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(mMockFlags.isConnectedDisplayManagementEnabled()).thenReturn(false); - mSetFlagsRule.disableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR); mLocalServiceKeeperRule.overrideLocalService( InputManagerInternal.class, mMockInputManagerInternal); @@ -1298,44 +1296,11 @@ public class DisplayManagerServiceTest { } /** - * Tests that it's not allowed to create an auto-mirror virtual display when display mirroring - * is not supported in a virtual device. - */ - @Test - public void createAutoMirrorDisplay_virtualDeviceDoesntSupportMirroring_throwsException() - throws Exception { - mSetFlagsRule.disableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR); - DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); - DisplayManagerInternal localService = displayManager.new LocalService(); - registerDefaultDisplays(displayManager); - when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); - when(mContext.checkCallingPermission(CAPTURE_VIDEO_OUTPUT)).thenReturn( - PackageManager.PERMISSION_DENIED); - IVirtualDevice virtualDevice = mock(IVirtualDevice.class); - when(virtualDevice.getDeviceId()).thenReturn(1); - when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true); - - final VirtualDisplayConfig.Builder builder = - new VirtualDisplayConfig.Builder(VIRTUAL_DISPLAY_NAME, 600, 800, 320) - .setFlags(VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) - .setUniqueId("uniqueId --- mirror display"); - assertThrows(SecurityException.class, () -> { - localService.createVirtualDisplay( - builder.build(), - mMockAppToken /* callback */, - virtualDevice /* virtualDeviceToken */, - mock(DisplayWindowPolicyController.class), - PACKAGE_NAME); - }); - } - - /** * Tests that the virtual display is added to the default display group when created with * VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR using a virtual device. */ @Test public void createAutoMirrorVirtualDisplay_addsDisplayToDefaultDisplayGroup() throws Exception { - mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR); DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); DisplayManagerInternal localService = displayManager.new LocalService(); registerDefaultDisplays(displayManager); @@ -1368,7 +1333,6 @@ public class DisplayManagerServiceTest { */ @Test public void createAutoMirrorVirtualDisplay_mirrorsDefaultDisplay() throws Exception { - mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR); DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); DisplayManagerInternal localService = displayManager.new LocalService(); registerDefaultDisplays(displayManager); @@ -1400,7 +1364,6 @@ public class DisplayManagerServiceTest { */ @Test public void createOwnContentOnlyVirtualDisplay_doesNotMirrorAnyDisplay() throws Exception { - mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR); DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); DisplayManagerInternal localService = displayManager.new LocalService(); registerDefaultDisplays(displayManager); @@ -1436,7 +1399,6 @@ public class DisplayManagerServiceTest { */ @Test public void createAutoMirrorVirtualDisplay_flagAlwaysUnlockedNotSet() throws Exception { - mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR); DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); DisplayManagerInternal localService = displayManager.new LocalService(); registerDefaultDisplays(displayManager); @@ -1472,7 +1434,6 @@ public class DisplayManagerServiceTest { */ @Test public void createAutoMirrorVirtualDisplay_flagPresentationNotSet() throws Exception { - mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR); DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); DisplayManagerInternal localService = displayManager.new LocalService(); registerDefaultDisplays(displayManager); diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java index c2882124e6e3..4d067f6bfc62 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java @@ -62,7 +62,6 @@ import android.companion.virtual.VirtualDeviceManager; import android.companion.virtual.VirtualDeviceParams; import android.companion.virtual.audio.IAudioConfigChangedCallback; import android.companion.virtual.audio.IAudioRoutingCallback; -import android.companion.virtual.flags.Flags; import android.companion.virtual.sensor.VirtualSensor; import android.companion.virtual.sensor.VirtualSensorCallback; import android.companion.virtual.sensor.VirtualSensorConfig; @@ -1686,7 +1685,6 @@ public class VirtualDeviceManagerServiceTest { @Test public void openNonBlockedAppOnMirrorDisplay_flagEnabled_cannotBeLaunched() { - mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR); when(mDisplayManagerInternalMock.getDisplayIdToMirror(anyInt())) .thenReturn(Display.DEFAULT_DISPLAY); addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); @@ -1711,31 +1709,6 @@ public class VirtualDeviceManagerServiceTest { } @Test - public void openNonBlockedAppOnMirrorDisplay_flagDisabled_launchesActivity() { - mSetFlagsRule.disableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR); - when(mDisplayManagerInternalMock.getDisplayIdToMirror(anyInt())) - .thenReturn(Display.DEFAULT_DISPLAY); - addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest( - DISPLAY_ID_1); - doNothing().when(mContext).startActivityAsUser(any(), any(), any()); - - ActivityInfo activityInfo = getActivityInfo( - NONBLOCKED_APP_PACKAGE_NAME, - NONBLOCKED_APP_PACKAGE_NAME, - /* displayOnRemoteDevices */ true, - /* targetDisplayCategory */ null); - assertThat(gwpc.canActivityBeLaunched(activityInfo, null, - WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false, - /* isResultExpected = */ false, /* intentSender= */ null)) - .isTrue(); - Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( - activityInfo, mAssociationInfo.getDisplayName()); - verify(mContext, never()).startActivityAsUser(argThat(intent -> - intent.filterEquals(blockedAppIntent)), any(), any()); - } - - @Test public void registerRunningAppsChangedListener_onRunningAppsChanged_listenersNotified() { ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(UID_1, UID_2)); addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); |