Implement drag then snap flicker test

Add a flicker test for dragging the pip window
away from the edge and verifying that it snaps
back to that same edge

Bug: 264555500

Test: atest WMShellFlickerTests:PipDragThenSnapTest
Change-Id: I3397f7f47198b33f4d0250704ef5f2fd54446517
(cherry picked from commit d389b97058)
This commit is contained in:
Ikram Gabiyev
2023-02-28 00:44:07 +00:00
parent 580c875e46
commit 7789c03138
2 changed files with 162 additions and 2 deletions

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2023 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
import android.platform.test.annotations.Postsubmit
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.graphics.Rect
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.testapp.ActivityOptions
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
/**
* Test the snapping of a PIP window via dragging, releasing, and checking its final location.
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class PipDragThenSnapTest(flicker: FlickerTest) : PipTransition(flicker){
override val transition: FlickerBuilder.() -> Unit
get() = {
val stringExtras: Map<String, String> =
mapOf(ActivityOptions.Pip.EXTRA_ENTER_PIP to "true")
// cache the starting bounds here
val startBounds = Rect()
setup {
// Launch the PIP activity and wait for it to enter PiP mode
setRotation(Rotation.ROTATION_0)
RemoveAllTasksButHomeRule.removeAllTasksButHome()
pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras)
val initRegion = pipApp.dragPipWindowAwayFromEdge(wmHelper, 50)
startBounds
.set(initRegion.left, initRegion.top, initRegion.right, initRegion.bottom)
}
transitions {
// continue the transition until the PIP snaps
pipApp.waitForPipToSnapTo(wmHelper, startBounds)
}
}
/** Checks that the visible region area of [pipApp] always moves right during the animation. */
@Postsubmit
@Test
fun pipLayerMovesRight() {
flicker.assertLayers {
val pipLayerList = layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
pipLayerList.zipWithNext { previous, current ->
current.visibleRegion.isToTheRight(previous.visibleRegion.region)
}
}
}
companion object {
/**
* Creates the test configurations.
*
* See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<FlickerTest> {
return FlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
}
}
}

View File

@@ -58,7 +58,51 @@ open class PipAppHelper(instrumentation: Instrumentation) :
}
/**
* Expands the PIP window my using the pinch out gesture.
* Drags the PIP window away from the screen edge while not crossing the display center.
*
* @throws IllegalStateException if default display bounds are not available
* @return initial bounds of the PIP window
*/
fun dragPipWindowAwayFromEdge(wmHelper: WindowManagerStateHelper, steps: Int): Rect {
val initWindowRect = getWindowRect(wmHelper).clone()
// initial pointer at the center of the window
val startX = initWindowRect.centerX()
val y = initWindowRect.centerY()
val displayRect = wmHelper.currentState.wmState.getDefaultDisplay()?.displayRect
?: throw IllegalStateException("Default display is null")
// the offset to the right of the display center to drag the window to
val offset = 20
// the actual final x coordinate with the offset included
// if the pip window is closer to the right edge of the display the offset is positive
// otherwise the offset is negative
val endX = displayRect.centerX() + offset * (if (isCloserToRightEdge(wmHelper)) 1 else -1)
// drag the window to the left but not beyond the center of the display
uiDevice.drag(startX, y, endX, y, steps)
return initWindowRect
}
/**
* Returns true if PIP window is closer to the right edge of the display than left.
*
* @throws IllegalStateException if default display bounds are not available
*/
private fun isCloserToRightEdge(wmHelper: WindowManagerStateHelper): Boolean {
val windowRect = getWindowRect(wmHelper)
val displayRect = wmHelper.currentState.wmState.getDefaultDisplay()?.displayRect
?: throw IllegalStateException("Default display is null")
return windowRect.centerX() > displayRect.centerX()
}
/**
* Expands the PIP window by using the pinch out gesture.
*
* @param percent The percentage by which to increase the pip window size.
* @throws IllegalArgumentException if percentage isn't between 0.0f and 1.0f
@@ -106,7 +150,7 @@ open class PipAppHelper(instrumentation: Instrumentation) :
}
/**
* Minimizes the PIP window my using the pinch in gesture.
* Minimizes the PIP window by using the pinch in gesture.
*
* @param percent The percentage by which to decrease the pip window size.
* @throws IllegalArgumentException if percentage isn't between 0.0f and 1.0f
@@ -307,6 +351,27 @@ open class PipAppHelper(instrumentation: Instrumentation) :
.waitForAndVerify()
}
/**
* Waits until the PIP window snaps horizontally to the provided bounds.
*
* @param finalRightX the final x coordinate of the right edge of the pip window
*/
fun waitForPipToSnapTo(wmHelper: WindowManagerStateHelper, finalBounds: android.graphics.Rect) {
wmHelper
.StateSyncBuilder()
.add("pipWindowSnapped") {
val pipAppWindow =
it.wmState.visibleWindows.firstOrNull { window ->
this.windowMatchesAnyOf(window)
}
?: return@add false
val pipRegionBounds = pipAppWindow.frameRegion.bounds
return@add pipRegionBounds.left == finalBounds.left &&
pipRegionBounds.right == finalBounds.right
}
.waitForAndVerify()
}
companion object {
private const val TAG = "PipAppHelper"
private const val ENTER_PIP_BUTTON_ID = "enter_pip"