diff options
| author | 2023-03-29 01:30:47 +0000 | |
|---|---|---|
| committer | 2023-03-29 01:30:47 +0000 | |
| commit | bc482a262e4bf407c225f0094aa6a49f98be192f (patch) | |
| tree | bb4f315d33ebc59aab1a12cbf526808cfe8a9461 | |
| parent | 69b03326bcbfb75a9214c321b4ad01a33c69b340 (diff) | |
| parent | 3deca2264eceae629183048c7fe185f271284940 (diff) | |
Merge "Implement flicker test for dragging" into udc-dev
3 files changed, 189 insertions, 2 deletions
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragTest.kt new file mode 100644 index 000000000000..083cfd294f96 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragTest.kt @@ -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.platform.test.annotations.RequiresDevice +import android.tools.device.flicker.junit.FlickerParametersRunnerFactory +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 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 dragging of a PIP window. + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class PipDragTest(flicker: FlickerTest) : PipTransition(flicker) { + private var isDraggedLeft: Boolean = true + override val transition: FlickerBuilder.() -> Unit + get() = { + val stringExtras = mapOf(ActivityOptions.Pip.EXTRA_ENTER_PIP to "true") + + setup { + tapl.setEnableRotation(true) + // Launch the PIP activity and wait for it to enter PiP mode + RemoveAllTasksButHomeRule.removeAllTasksButHome() + pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras) + + // determine the direction of dragging to test for + isDraggedLeft = pipApp.isCloserToRightEdge(wmHelper) + } + teardown { + // release the primary pointer after dragging without release + pipApp.releasePipAfterDragging() + + pipApp.exit(wmHelper) + tapl.setEnableRotation(false) + } + transitions { + pipApp.dragPipWindowAwayFromEdgeWithoutRelease(wmHelper, 50) + } + } + + @Postsubmit + @Test + fun pipLayerMovesAwayFromEdge() { + flicker.assertLayers { + val pipLayerList = layers { pipApp.layerMatchesAnyOf(it) && it.isVisible } + pipLayerList.zipWithNext { previous, current -> + if (isDraggedLeft) { + previous.visibleRegion.isToTheRight(current.visibleRegion.region) + } else { + 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() + } + } +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GestureHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GestureHelper.java index 858cd7672fe3..a8f1b3de564e 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GestureHelper.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GestureHelper.java @@ -26,6 +26,8 @@ import android.view.MotionEvent; import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerProperties; +import androidx.annotation.Nullable; + /** * Injects gestures given an {@link Instrumentation} object. */ @@ -36,6 +38,13 @@ public class GestureHelper { private final UiAutomation mUiAutomation; /** + * Primary pointer should be cached here for separate release + */ + @Nullable private PointerProperties mPrimaryPtrProp; + @Nullable private PointerCoords mPrimaryPtrCoord; + private long mPrimaryPtrDownTime; + + /** * A pair of floating point values. */ public static class Tuple { @@ -53,6 +62,52 @@ public class GestureHelper { } /** + * Injects a series of {@link MotionEvent}s to simulate a drag gesture without pointer release. + * + * Simulates a drag gesture without releasing the primary pointer. The primary pointer info + * will be cached for potential release later on by {@code releasePrimaryPointer()} + * + * @param startPoint initial coordinates of the primary pointer + * @param endPoint final coordinates of the primary pointer + * @param steps number of steps to take to animate dragging + * @return true if gesture is injected successfully + */ + public boolean dragWithoutRelease(@NonNull Tuple startPoint, + @NonNull Tuple endPoint, int steps) { + PointerProperties ptrProp = getPointerProp(0, MotionEvent.TOOL_TYPE_FINGER); + PointerCoords ptrCoord = getPointerCoord(startPoint.x, startPoint.y, 1, 1); + + PointerProperties[] ptrProps = new PointerProperties[] { ptrProp }; + PointerCoords[] ptrCoords = new PointerCoords[] { ptrCoord }; + + long downTime = SystemClock.uptimeMillis(); + + if (!primaryPointerDown(ptrProp, ptrCoord, downTime)) { + return false; + } + + // cache the primary pointer info for later potential release + mPrimaryPtrProp = ptrProp; + mPrimaryPtrCoord = ptrCoord; + mPrimaryPtrDownTime = downTime; + + return movePointers(ptrProps, ptrCoords, new Tuple[] { endPoint }, downTime, steps); + } + + /** + * Release primary pointer if previous gesture has cached the primary pointer info. + * + * @return true if the release was injected successfully + */ + public boolean releasePrimaryPointer() { + if (mPrimaryPtrProp != null && mPrimaryPtrCoord != null) { + return primaryPointerUp(mPrimaryPtrProp, mPrimaryPtrCoord, mPrimaryPtrDownTime); + } + + return false; + } + + /** * Injects a series of {@link MotionEvent} objects to simulate a pinch gesture. * * @param startPoint1 initial coordinates of the first pointer diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt index de57d06a5619..e497ae4779a7 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt @@ -58,6 +58,43 @@ open class PipAppHelper(instrumentation: Instrumentation) : } /** + * Drags the PIP window to the provided final coordinates without releasing the pointer. + */ + fun dragPipWindowAwayFromEdgeWithoutRelease( + wmHelper: WindowManagerStateHelper, + steps: Int + ) { + val initWindowRect = getWindowRect(wmHelper).clone() + + // initial pointer at the center of the window + val initialCoord = GestureHelper.Tuple(initWindowRect.centerX().toFloat(), + initWindowRect.centerY().toFloat()) + + // the offset to the right (or left) of the window center to drag the window to + val offset = 50 + + // 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 negative + // otherwise the offset is positive + val endX = initWindowRect.centerX() + + offset * (if (isCloserToRightEdge(wmHelper)) -1 else 1) + val finalCoord = GestureHelper.Tuple(endX.toFloat(), initWindowRect.centerY().toFloat()) + + // drag to the final coordinate + gestureHelper.dragWithoutRelease(initialCoord, finalCoord, steps) + } + + /** + * Releases the primary pointer. + * + * Injects the release of the primary pointer if the primary pointer info was cached after + * another gesture was injected without pointer release. + */ + fun releasePipAfterDragging() { + gestureHelper.releasePrimaryPointer() + } + + /** * Drags the PIP window away from the screen edge while not crossing the display center. * * @throws IllegalStateException if default display bounds are not available @@ -72,10 +109,10 @@ open class PipAppHelper(instrumentation: Instrumentation) : 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 + // the offset to the right (or left) of the display center to drag the window to val offset = 20 - // the actual final x coordinate with the offset included + // 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) |