Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1fca6cc authored by Ikram Gabiyev's avatar Ikram Gabiyev Committed by Automerger Merge Worker
Browse files

Merge "Implement flicker test for dragging" into udc-dev am: bc482a26

parents 001f81ce bc482a26
Loading
Loading
Loading
Loading
+95 −0
Original line number Original line Diff line number Diff line
/*
 * 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
+55 −0
Original line number Original line Diff line number Diff line
@@ -26,6 +26,8 @@ import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
import android.view.MotionEvent.PointerProperties;


import androidx.annotation.Nullable;

/**
/**
 * Injects gestures given an {@link Instrumentation} object.
 * Injects gestures given an {@link Instrumentation} object.
 */
 */
@@ -35,6 +37,13 @@ public class GestureHelper {


    private final UiAutomation mUiAutomation;
    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.
     * A pair of floating point values.
     */
     */
@@ -52,6 +61,52 @@ public class GestureHelper {
        mUiAutomation = instrumentation.getUiAutomation();
        mUiAutomation = instrumentation.getUiAutomation();
    }
    }


    /**
     * 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.
     * Injects a series of {@link MotionEvent} objects to simulate a pinch gesture.
     *
     *
+39 −2
Original line number Original line Diff line number Diff line
@@ -57,6 +57,43 @@ open class PipAppHelper(instrumentation: Instrumentation) :
        obj.click()
        obj.click()
    }
    }


    /**
     * 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.
     * Drags the PIP window away from the screen edge while not crossing the display center.
     *
     *
@@ -72,10 +109,10 @@ open class PipAppHelper(instrumentation: Instrumentation) :
        val displayRect = wmHelper.currentState.wmState.getDefaultDisplay()?.displayRect
        val displayRect = wmHelper.currentState.wmState.getDefaultDisplay()?.displayRect
                ?: throw IllegalStateException("Default display is null")
                ?: 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
        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
        // if the pip window is closer to the right edge of the display the offset is positive
        // otherwise the offset is negative
        // otherwise the offset is negative
        val endX = displayRect.centerX() + offset * (if (isCloserToRightEdge(wmHelper)) 1 else -1)
        val endX = displayRect.centerX() + offset * (if (isCloserToRightEdge(wmHelper)) 1 else -1)