summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java51
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java9
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/Android.bp18
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt46
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt26
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt102
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfExitPipToAppViaIntentTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfSetRequestedOrientationWhilePinned.kt97
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java8
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/BottomHalfPipAppHelper.kt11
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt5
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/BottomHalfPipLaunchingActivity.java6
14 files changed, 339 insertions, 58 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 55e90e74a404..bec75b3d865c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -664,10 +664,12 @@ public class PipAnimationController {
// TODO(b/375977163): polish the animation to restoring the PIP task back from
// swipe-pip-to-home. Ideally we should send the transitionInfo after reparenting
// the PIP activity back to the original task.
- if (shouldUseMainWindowFrame) {
+ if (shouldUseMainWindowFrame && isOutPipDirection) {
// If we should animate the main window frame, set it to the rotatedRect
// instead. The end bounds reported by transitionInfo is the bounds before
// rotation, while main window frame is calculated after the rotation.
+ // Note that we only override main window frame for leaving pip animation as
+ // the pip activity should match parent.
rotatedEndRect.set(mainWindowFrame);
} else {
// Rotate the end bounds according to the rotation delta because the display
@@ -810,11 +812,19 @@ public class PipAnimationController {
}
}
final Rect sourceBounds = new Rect(initialContainerRect);
+ Rect relativeEndWindowFrame = null;
+ if (isOutPipDirection) {
+ relativeEndWindowFrame = rotatedEndRect;
+ }
+ if (relativeEndWindowFrame != null) {
+ relativeEndWindowFrame.offset(leashOffset.x, leashOffset.y);
+ }
sourceBounds.inset(insets);
getSurfaceTransactionHelper()
.rotateAndScaleWithCrop(tx, leash, initialContainerRect, bounds,
insets, degree, x, y, isOutPipDirection,
- rotationDelta == ROTATION_270 /* clockwise */)
+ rotationDelta == ROTATION_270 /* clockwise */,
+ relativeEndWindowFrame)
.round(tx, leash, sourceBounds, bounds)
.shadow(tx, leash, shouldApplyShadowRadius());
if (!handlePipTransaction(leash, tx, bounds, 1f /* alpha */)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
index b02bd0ffec6c..955a981799f5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
@@ -25,6 +25,8 @@ import android.graphics.RectF;
import android.view.Choreographer;
import android.view.SurfaceControl;
+import androidx.annotation.Nullable;
+
import com.android.wm.shell.R;
import com.android.wm.shell.transition.Transitions;
@@ -224,12 +226,17 @@ public class PipSurfaceTransactionHelper {
/**
* Operates the rotation according to the given degrees and scale (setMatrix) according to the
* source bounds and rotated destination bounds. The crop will be the unscaled source bounds.
+ *
+ * @param relativeEndWindowFrame specified if
+ * {@link android.app.TaskInfo#topActivityMainWindowFrame} is provided. It's only applied for
+ * the animation that {@code isExpanding} PIP to original task.
* @return same {@link PipSurfaceTransactionHelper} instance for method chaining
*/
- public PipSurfaceTransactionHelper rotateAndScaleWithCrop(SurfaceControl.Transaction tx,
- SurfaceControl leash, Rect sourceBounds, Rect destinationBounds, Rect insets,
+ public PipSurfaceTransactionHelper rotateAndScaleWithCrop(
+ @NonNull SurfaceControl.Transaction tx, @NonNull SurfaceControl leash,
+ @NonNull Rect sourceBounds, @NonNull Rect destinationBounds, @NonNull Rect insets,
float degrees, float positionX, float positionY, boolean isExpanding,
- boolean clockwise) {
+ boolean clockwise, @Nullable Rect relativeEndWindowFrame) {
mTmpDestinationRect.set(sourceBounds);
mTmpDestinationRect.inset(insets);
final int srcW = mTmpDestinationRect.width();
@@ -240,23 +247,31 @@ public class PipSurfaceTransactionHelper {
// destination are different.
final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH;
final Rect crop = mTmpDestinationRect;
- crop.set(0, 0, Transitions.SHELL_TRANSITIONS_ROTATION ? destH
- : destW, Transitions.SHELL_TRANSITIONS_ROTATION ? destW : destH);
- // Inverse scale for crop to fit in screen coordinates.
- crop.scale(1 / scale);
- crop.offset(insets.left, insets.top);
- if (isExpanding) {
- // Expand bounds (shrink insets) in source orientation.
- positionX -= insets.left * scale;
- positionY -= insets.top * scale;
+ if (isExpanding && relativeEndWindowFrame != null) {
+ // If relative end window frame is provided, it usually means the top activity chooses
+ // a customized layout which may not match parent. In this case, we should crop the
+ // task surface with the window frame. Note that we don't need to consider the insets
+ // because the main window frame excludes the insets.
+ crop.set(relativeEndWindowFrame);
} else {
- // Shrink bounds (expand insets) in destination orientation.
- if (clockwise) {
- positionX -= insets.top * scale;
- positionY += insets.left * scale;
+ crop.set(0, 0, Transitions.SHELL_TRANSITIONS_ROTATION ? destH
+ : destW, Transitions.SHELL_TRANSITIONS_ROTATION ? destW : destH);
+ // Inverse scale for crop to fit in screen coordinates.
+ crop.scale(1 / scale);
+ crop.offset(insets.left, insets.top);
+ if (isExpanding) {
+ // Expand bounds (shrink insets) in source orientation.
+ positionX -= insets.left * scale;
+ positionY -= insets.top * scale;
} else {
- positionX += insets.top * scale;
- positionY -= insets.left * scale;
+ // Shrink bounds (expand insets) in destination orientation.
+ if (clockwise) {
+ positionX -= insets.top * scale;
+ positionY += insets.left * scale;
+ } else {
+ positionX += insets.top * scale;
+ positionY -= insets.left * scale;
+ }
}
}
mTmpTransform.setScale(scale, scale);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 0042ec954f32..bd676ce69cfe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -844,7 +844,8 @@ public class PipTransition extends PipTransitionController {
}
mSurfaceTransactionHelper.rotateAndScaleWithCrop(finishTransaction,
pipLeash, endBounds, endBounds, new Rect(), degree, x, y,
- true /* isExpanding */, rotationDelta == ROTATION_270 /* clockwise */);
+ true /* isExpanding */, rotationDelta == ROTATION_270 /* clockwise */,
+ null /* relativeEndWindowFrame */);
} else {
rotationDelta = Surface.ROTATION_0;
}
@@ -868,7 +869,9 @@ public class PipTransition extends PipTransitionController {
// Get the start bounds in new orientation.
final Rect startBounds = new Rect(pipChange.getStartAbsBounds());
rotateBounds(startBounds, displayRotationChange.getStartAbsBounds(), rotateDelta);
- final Rect endBounds = new Rect(pipChange.getEndAbsBounds());
+ final Rect windowFrame = taskInfo.topActivityMainWindowFrame;
+ final Rect endBounds = new Rect(windowFrame != null
+ ? windowFrame : pipChange.getEndAbsBounds());
startBounds.offset(-offset.x, -offset.y);
endBounds.offset(-offset.x, -offset.y);
@@ -888,7 +891,7 @@ public class PipTransition extends PipTransitionController {
}
mSurfaceTransactionHelper.rotateAndScaleWithCrop(startTransaction, pipChange.getLeash(),
endBounds, startBounds, new Rect(), degree, x, y, true /* isExpanding */,
- pipRotateDelta == ROTATION_270 /* clockwise */);
+ pipRotateDelta == ROTATION_270 /* clockwise */, null /* relativeEndWindowFrame */);
startTransaction.apply();
rotator.cleanUp(finishTransaction);
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/Android.bp b/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
index 6e0dcdb21fa8..c760cf1d2094 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
@@ -75,8 +75,8 @@ android_test {
],
static_libs: ["WMShellFlickerTestsBase"],
test_suites: [
- "device-tests",
"csuite",
+ "device-tests",
],
data: ["trace_config/*"],
}
@@ -117,9 +117,11 @@ test_module_config {
"com.android.wm.shell.flicker.pip.ShowPipAndRotateDisplay",
"com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfAutoEnterPipOnGoToHomeTest",
"com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfEnterPipOnUserLeaveHintTest",
+ "com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfEnterPipToOtherOrientation",
"com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfEnterPipViaAppUiButtonTest",
"com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfExitPipToAppViaExpandButtonTest",
"com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfExitPipToAppViaIntentTest",
+ "com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfSetRequestedOrientationWhilePinned",
],
test_suites: ["device-tests"],
}
@@ -308,5 +310,19 @@ test_module_config {
test_suites: ["device-tests"],
}
+test_module_config {
+ name: "WMShellFlickerTestsPip-BottomHalfEnterPipToOtherOrientation",
+ base: "WMShellFlickerTestsPip",
+ include_filters: ["com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfEnterPipToOtherOrientation"],
+ test_suites: ["device-tests"],
+}
+
+test_module_config {
+ name: "WMShellFlickerTestsPip-BottomHalfSetRequestedOrientationWhilePinned",
+ base: "WMShellFlickerTestsPip",
+ include_filters: ["com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfSetRequestedOrientationWhilePinned"],
+ test_suites: ["device-tests"],
+}
+
// End breakdowns for WMShellFlickerTestsPip module
////////////////////////////////////////////////////////////////////////////////
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index 49efd1d56256..636549fa0662 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -16,7 +16,6 @@
package com.android.wm.shell.flicker.pip
-import android.app.Activity
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.RequiresFlagsDisabled
@@ -38,9 +37,10 @@ import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.pip.common.PipTransition
import com.android.wm.shell.flicker.pip.common.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE
import com.android.wm.shell.flicker.pip.common.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_PORTRAIT
-import org.junit.Assume
-import org.junit.Before
+import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
import org.junit.FixMethodOrder
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -72,10 +72,10 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
-class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(flicker) {
+open class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(flicker) {
override val pipApp: PipAppHelper = PipAppHelper(instrumentation)
- private val testApp = FixedOrientationAppHelper(instrumentation)
- private val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
+ internal val testApp = FixedOrientationAppHelper(instrumentation)
+ internal val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
override val thisTransition: FlickerBuilder.() -> Unit = {
@@ -112,32 +112,27 @@ class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(fli
}
/**
- * This test is not compatible with Tablets. When using [Activity.setRequestedOrientation] to
- * fix a orientation, Tablets instead keep the same orientation and add letterboxes
- */
- @Before
- fun setup() {
- Assume.assumeFalse(tapl.isTablet)
- }
-
- /**
* Checks that all parts of the screen are covered at the start and end of the transition
*/
@Presubmit
@Test
- fun entireScreenCoveredAtStartAndEnd() = flicker.entireScreenCovered()
+ fun entireScreenCoveredAtStartAndEnd() {
+ assumeFalse(tapl.isTablet)
+ flicker.entireScreenCovered()
+ }
/** Checks [pipApp] window remains visible and on top throughout the transition */
@Presubmit
@Test
fun pipAppWindowIsAlwaysOnTop() {
+ assumeFalse(tapl.isTablet)
flicker.assertWm { isAppWindowOnTop(pipApp) }
}
/** Checks that [testApp] window is not visible at the start */
@Presubmit
@Test
- fun testAppWindowInvisibleOnStart() {
+ open fun testAppWindowInvisibleOnStart() {
flicker.assertWmStart { isAppWindowInvisible(testApp) }
}
@@ -145,13 +140,15 @@ class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(fli
@Presubmit
@Test
fun testAppWindowVisibleOnEnd() {
+ assumeFalse(tapl.isTablet)
flicker.assertWmEnd { isAppWindowVisible(testApp) }
}
/** Checks that [testApp] layer is not visible at the start */
@Presubmit
@Test
- fun testAppLayerInvisibleOnStart() {
+ open fun testAppLayerInvisibleOnStart() {
+ assumeFalse(tapl.isTablet)
flicker.assertLayersStart { isInvisible(testApp) }
}
@@ -159,6 +156,7 @@ class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(fli
@Presubmit
@Test
fun testAppLayerVisibleOnEnd() {
+ assumeFalse(tapl.isTablet)
flicker.assertLayersEnd { isVisible(testApp) }
}
@@ -168,8 +166,8 @@ class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(fli
*/
@Presubmit
@Test
- fun pipAppLayerCoversFullScreenOnStart() {
- Assume.assumeFalse(tapl.isTablet)
+ open fun pipAppLayerCoversFullScreenOnStart() {
+ assumeFalse(tapl.isTablet)
flicker.assertLayersStart { visibleRegion(pipApp).coversExactly(startingBounds) }
}
@@ -177,10 +175,11 @@ class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(fli
* Checks that the visible region of [pipApp] covers the full display area at the start of the
* transition
*/
+ @Ignore("TODO(b/356277166): enable the tablet test")
@Postsubmit
@Test
- fun pipAppLayerPlusLetterboxCoversFullScreenOnStartTablet() {
- Assume.assumeFalse(tapl.isTablet)
+ open fun pipAppLayerPlusLetterboxCoversFullScreenOnStartTablet() {
+ assumeTrue(tapl.isTablet)
flicker.assertLayersStart {
visibleRegion(pipApp.or(ComponentNameMatcher.LETTERBOX)).coversExactly(startingBounds)
}
@@ -193,6 +192,7 @@ class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(fli
@Presubmit
@Test
fun testAppPlusPipLayerCoversFullScreenOnEnd() {
+ assumeFalse(tapl.isTablet)
flicker.assertLayersEnd {
val pipRegion = visibleRegion(pipApp).region
visibleRegion(testApp).plus(pipRegion).coversExactly(endingBounds)
@@ -202,6 +202,7 @@ class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(fli
@Postsubmit
@Test
fun menuOverlayMatchesTaskSurface() {
+ assumeFalse(tapl.isTablet)
flicker.assertLayersEnd {
val pipAppRegion = visibleRegion(pipApp)
val pipMenuRegion = visibleRegion(ComponentNameMatcher.PIP_MENU_OVERLAY)
@@ -212,6 +213,7 @@ class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(fli
@Presubmit
@Test
fun pipLayerRemainInsideVisibleBounds() {
+ assumeFalse(tapl.isTablet)
// during the transition we assert the center point is within the display bounds, since it
// might go outside of bounds as we resize from landscape fullscreen to destination bounds,
// and once the animation is over we assert that it's fully within the display bounds, at
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
index f9a9df43a009..2f4c8008f220 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
@@ -64,7 +64,7 @@ class ExitPipToAppViaIntentTest(flicker: LegacyFlickerTest) : ExitPipToAppTransi
}
transitions {
// This will bring PipApp to fullscreen
- pipApp.exitPipToFullScreenViaIntent(wmHelper)
+ pipApp.exitPipToOriginalTaskViaIntent(wmHelper)
// Wait until the other app is no longer visible
wmHelper.StateSyncBuilder().withWindowSurfaceDisappeared(testApp).waitForAndVerify()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
index 9d46ac1d6e00..86c32de6461d 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
@@ -43,8 +43,26 @@ import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
/**
- * Test exiting Pip with orientation changes. To run this test:
- * `atest WMShellFlickerTestsPip1:SetRequestedOrientationWhilePinned`
+ * Test leaving pip while changing orientation (from pip window in portrait to app in landscape)
+ *
+ * To run this test: `atest WMShellFlickerTestsPip:SetRequestedOrientationWhilePinned`
+ *
+ * Actions:
+ * ```
+ * Launch [pipApp] on a fixed landscape orientation
+ * Broadcast action [ACTION_ENTER_PIP] to enter pip mode in portrait
+ * Restore PIP from the original task to landscape
+ * ```
+ *
+ * Notes:
+ * ```
+ * 1. Some default assertions (e.g., nav bar, status bar and screen covered)
+ * are inherited [PipTransition]
+ * 2. Part of the test setup occurs automatically via
+ * [android.tools.flicker.legacy.runner.TransitionRunner],
+ * including configuring navigation mode, initial orientation and ensuring no
+ * apps are running before setup
+ * ```
*/
@RequiresDevice
@RunWith(Parameterized::class)
@@ -53,7 +71,7 @@ import org.junit.runners.Parameterized
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
open class SetRequestedOrientationWhilePinned(flicker: LegacyFlickerTest) : PipTransition(flicker) {
private val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
- private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
+ internal open val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions {
@@ -131,7 +149,7 @@ open class SetRequestedOrientationWhilePinned(flicker: LegacyFlickerTest) : PipT
@Presubmit
@Test
- fun pipAppLayerCoversFullScreen() {
+ open fun pipAppLayerCoversDisplayBoundsOnEnd() {
flicker.assertLayersEnd { visibleRegion(pipApp).coversExactly(endingBounds) }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt
new file mode 100644
index 000000000000..4987ab7b9344
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip.nonmatchparent
+
+import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.tools.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.flicker.legacy.LegacyFlickerTest
+import android.tools.traces.component.ComponentNameMatcher
+import com.android.server.wm.flicker.helpers.BottomHalfPipAppHelper
+import com.android.server.wm.flicker.helpers.PipAppHelper
+import com.android.wm.shell.Flags
+import com.android.wm.shell.flicker.pip.EnterPipToOtherOrientation
+import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test entering pip while changing orientation (from bottom half app in landscape to pip window in
+ * portrait)
+ *
+ * To run this test: `atest WMShellFlickerTestsPip:BottomHalfEnterPipToOtherOrientation`
+ *
+ * Actions:
+ * ```
+ * Launch [testApp] on a fixed portrait orientation
+ * Launch [pipApp] on a fixed landscape orientation
+ * Broadcast action [ACTION_ENTER_PIP] to enter pip mode
+ * ```
+ *
+ * Notes:
+ * ```
+ * 1. Some default assertions (e.g., nav bar, status bar and screen covered)
+ * are inherited [PipTransition]
+ * 2. Part of the test setup occurs automatically via
+ * [android.tools.flicker.legacy.runner.TransitionRunner],
+ * including configuring navigation mode, initial orientation and ensuring no
+ * apps are running before setup
+ * ```
+ */
+// TODO(b/380796448): re-enable tests after the support of non-match parent PIP animation for PIP2.
+@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
+@RequiresFlagsEnabled(com.android.window.flags.Flags.FLAG_BETTER_SUPPORT_NON_MATCH_PARENT_ACTIVITY)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class BottomHalfEnterPipToOtherOrientation(flicker: LegacyFlickerTest) :
+ EnterPipToOtherOrientation(flicker)
+{
+ override val pipApp: PipAppHelper = BottomHalfPipAppHelper(instrumentation)
+
+ @Presubmit
+ @Test
+ override fun pipAppLayerCoversFullScreenOnStart() {
+ // Test app and pip app should covers the entire screen on start.
+ assumeFalse(tapl.isTablet)
+ flicker.assertLayersStart {
+ visibleRegion(pipApp.or(testApp)).coversExactly(startingBounds)
+ }
+ }
+
+ @Ignore("TODO(b/356277166): enable the tablet test")
+ @Presubmit
+ @Test
+ override fun pipAppLayerPlusLetterboxCoversFullScreenOnStartTablet() {
+ // Test app and pip app should covers the entire screen on start.
+ assumeTrue(tapl.isTablet)
+ flicker.assertLayersStart {
+ visibleRegion(pipApp.or(ComponentNameMatcher.LETTERBOX)).coversExactly(startingBounds)
+ }
+ }
+
+ @Presubmit
+ @Test
+ override fun testAppWindowInvisibleOnStart() {
+ // Test app and pip app should covers the entire screen on start.
+ }
+
+ @Presubmit
+ @Test
+ override fun testAppLayerInvisibleOnStart() {
+ // Test app and pip app should covers the entire screen on start.
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfExitPipToAppViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfExitPipToAppViaIntentTest.kt
index 8ed9cd23005b..8a10c78465bc 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfExitPipToAppViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfExitPipToAppViaIntentTest.kt
@@ -67,7 +67,7 @@ class BottomHalfExitPipToAppViaIntentTest(flicker: LegacyFlickerTest) :
}
transitions {
// This will bring PipApp to fullscreen
- pipApp.exitPipToFullScreenViaIntent(wmHelper)
+ pipApp.exitPipToOriginalTaskViaIntent(wmHelper)
// Wait until the transition idle and test and pip app still shows.
wmHelper.StateSyncBuilder().withLayerVisible(testApp).withLayerVisible(pipApp)
.withAppTransitionIdle().waitForAndVerify()
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfSetRequestedOrientationWhilePinned.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfSetRequestedOrientationWhilePinned.kt
new file mode 100644
index 000000000000..42f5a50c3310
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfSetRequestedOrientationWhilePinned.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip.nonmatchparent
+
+import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.tools.Rotation
+import android.tools.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.flicker.legacy.FlickerBuilder
+import android.tools.flicker.legacy.LegacyFlickerTest
+import android.tools.traces.parsers.toFlickerComponent
+import com.android.server.wm.flicker.helpers.BottomHalfPipAppHelper
+import com.android.server.wm.flicker.helpers.PipAppHelper
+import com.android.server.wm.flicker.testapp.ActivityOptions.BottomHalfPip
+import com.android.wm.shell.Flags
+import com.android.wm.shell.flicker.pip.SetRequestedOrientationWhilePinned
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test leaving pip while changing orientation (from pip window in portrait to bottom half app in
+ * landscape)
+ *
+ * To run this test: `atest WMShellFlickerTestsPip:BottomHalfSetRequestedOrientationWhilePinned`
+ *
+ * Actions:
+ * ```
+ * Launch bottom half [pipApp] on a fixed landscape orientation via launching app
+ * Broadcast action [ACTION_ENTER_PIP] to enter pip mode
+ * Restore PIP from the original task to landscape
+ * ```
+ *
+ * Notes:
+ * ```
+ * 1. Some default assertions (e.g., nav bar, status bar and screen covered)
+ * are inherited [PipTransition]
+ * 2. Part of the test setup occurs automatically via
+ * [android.tools.flicker.legacy.runner.TransitionRunner],
+ * including configuring navigation mode, initial orientation and ensuring no
+ * apps are running before setup
+ * ```
+ */
+// TODO(b/380796448): re-enable tests after the support of non-match parent PIP animation for PIP2.
+@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
+@RequiresFlagsEnabled(com.android.window.flags.Flags.FLAG_BETTER_SUPPORT_NON_MATCH_PARENT_ACTIVITY)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class BottomHalfSetRequestedOrientationWhilePinned(flicker: LegacyFlickerTest) :
+ SetRequestedOrientationWhilePinned(flicker)
+{
+ override val pipApp: PipAppHelper = BottomHalfPipAppHelper(
+ instrumentation,
+ useLaunchingActivity = true
+ )
+
+ override val thisTransition: FlickerBuilder.() -> Unit = {
+ transitions {
+ // Launch the activity back into fullscreen and ensure that it is now in landscape
+ pipApp.exitPipToOriginalTaskViaIntent(wmHelper)
+ // System bar may fade out during fixed rotation.
+ wmHelper
+ .StateSyncBuilder()
+ .withTopVisibleApp(pipApp)
+ .withRotation(Rotation.ROTATION_90)
+ .withNavOrTaskBarVisible()
+ .withStatusBarVisible()
+ .waitForAndVerify()
+ }
+ }
+
+ @Presubmit
+ @Test
+ override fun pipAppLayerCoversDisplayBoundsOnEnd() {
+ flicker.assertLayersEnd {
+ visibleRegion(pipApp
+ .or(BottomHalfPip.LAUNCHING_APP_COMPONENT.toFlickerComponent()))
+ .coversExactly(endingBounds)
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
index 6d37ed766aef..53f6cda62f55 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
@@ -189,7 +189,7 @@ public class PipAnimationControllerTest extends ShellTestCase {
// Apply fraction 1 to compute the end value.
animator.applySurfaceControlTransaction(mLeash, tx, 1);
- assertEquals("Expect use main window frame", mTaskInfo.topActivityMainWindowFrame,
+ assertEquals("Expect main window frame", mTaskInfo.topActivityMainWindowFrame,
animator.mCurrentValue);
// PiP to fullscreen.
@@ -200,9 +200,11 @@ public class PipAnimationControllerTest extends ShellTestCase {
endBounds, null, TRANSITION_DIRECTION_TO_PIP, 0, ROTATION_270,
false /* alwaysAnimateTaskBounds */);
animator.applySurfaceControlTransaction(mLeash, tx, 1);
+ final Rect rotatedEndBounds = new Rect(endBounds);
+ rotateBounds(rotatedEndBounds, startBounds, ROTATION_270);
- assertEquals("Expect use main window frame", mTaskInfo.topActivityMainWindowFrame,
- animator.mCurrentValue);
+ assertEquals("Expect rotated bounds. We only use main window frame for "
+ + "leave-pip animation", rotatedEndBounds, animator.mCurrentValue);
}
@Test
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/BottomHalfPipAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/BottomHalfPipAppHelper.kt
index 6573c2c83f20..ed2cff4a9515 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/BottomHalfPipAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/BottomHalfPipAppHelper.kt
@@ -19,6 +19,7 @@ package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
import android.content.Intent
import android.tools.traces.parsers.toFlickerComponent
+import android.tools.traces.parsers.WindowManagerStateHelper
import com.android.server.wm.flicker.testapp.ActivityOptions
class BottomHalfPipAppHelper(
@@ -38,4 +39,14 @@ class BottomHalfPipAppHelper(
ActivityOptions.BottomHalfPip.COMPONENT
}
}
+
+ override fun exitPipToOriginalTaskViaIntent(wmHelper: WindowManagerStateHelper) {
+ launchViaIntent(
+ wmHelper,
+ Intent().apply {
+ component = ActivityOptions.BottomHalfPip.COMPONENT
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ )
+ }
} \ No newline at end of file
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
index de17bf422c0c..344cac1ac7e5 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -75,8 +75,9 @@ open class PipAppHelper(
.waitForAndVerify()
}
- /** Expand the PIP window back to full screen via intent and wait until the app is visible */
- fun exitPipToFullScreenViaIntent(wmHelper: WindowManagerStateHelper) = launchViaIntent(wmHelper)
+ /** Expand the PIP window back to original task via intent and wait until the app is visible */
+ open fun exitPipToOriginalTaskViaIntent(wmHelper: WindowManagerStateHelper) =
+ launchViaIntent(wmHelper)
fun changeAspectRatio(wmHelper: WindowManagerStateHelper) {
val intent = Intent("com.android.wm.shell.flicker.testapp.ASPECT_RATIO")
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/BottomHalfPipLaunchingActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/BottomHalfPipLaunchingActivity.java
index d9d4361411bb..209f71e4f307 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/BottomHalfPipLaunchingActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/BottomHalfPipLaunchingActivity.java
@@ -24,8 +24,12 @@ public class BottomHalfPipLaunchingActivity extends SimpleActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
final Intent intent = new Intent(this, BottomHalfPipActivity.class);
+ // Pass extras to BottomHalfPipActivity.
+ final Bundle extras = getIntent().getExtras();
+ if (extras != null) {
+ intent.putExtras(extras);
+ }
startActivity(intent);
}
}