diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-01-07 02:27:45 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-01-07 02:27:45 +0000 |
commit | 0b9279fc6a33285edb20d4e1880baaaba31b91fa (patch) | |
tree | 8172e3b7653bae9995cc5edd67b50c0260c5d41a | |
parent | 31ced6f4267f6e449d9f6151f09e13bc8a6f35d6 (diff) | |
parent | 5014803f3c9e4a8ce3baf5cc8ea7305ea945cc1f (diff) | |
download | platform_testing-android13-qpr2-s6-release.tar.gz |
Snap for 9463735 from 5014803f3c9e4a8ce3baf5cc8ea7305ea945cc1f to tm-qpr2-releaseandroid-13.0.0_r49android-13.0.0_r45android-13.0.0_r44android-13.0.0_r43android-13.0.0_r42android-13.0.0_r41android-13.0.0_r40android-13.0.0_r39android-13.0.0_r38android-13.0.0_r37android-13.0.0_r36android-13.0.0_r35android-13.0.0_r34android-13.0.0_r33android-13.0.0_r32android13-qpr2-s9-releaseandroid13-qpr2-s8-releaseandroid13-qpr2-s7-releaseandroid13-qpr2-s6-releaseandroid13-qpr2-s5-releaseandroid13-qpr2-s3-releaseandroid13-qpr2-s2-releaseandroid13-qpr2-s12-releaseandroid13-qpr2-s11-releaseandroid13-qpr2-s10-releaseandroid13-qpr2-s1-releaseandroid13-qpr2-releaseandroid13-qpr2-b-s1-release
Change-Id: I67f3cbcf0d8c6fc8708d5198b79e544489a11f69
6 files changed, 128 insertions, 24 deletions
diff --git a/libraries/collectors-helper/perfetto/src/com/android/helpers/PerfettoHelper.java b/libraries/collectors-helper/perfetto/src/com/android/helpers/PerfettoHelper.java index 2b8f2bf8d..e8fe47edb 100644 --- a/libraries/collectors-helper/perfetto/src/com/android/helpers/PerfettoHelper.java +++ b/libraries/collectors-helper/perfetto/src/com/android/helpers/PerfettoHelper.java @@ -34,19 +34,21 @@ import java.nio.file.Paths; public class PerfettoHelper { private static final String LOG_TAG = PerfettoHelper.class.getSimpleName(); - // Command to start the perfetto tracing in the background. - // perfetto -b -c /data/misc/perfetto-traces/trace_config.pb -o - // /data/misc/perfetto-traces/trace_output.pb - private static final String PERFETTO_START_CMD = "perfetto --background -c %s%s -o %s"; + // Command to start the perfetto tracing in the background. The "perfetto" process will wait + // until tracing is fully started (i.e. all data sources are active) before backgrounding and + // returning from the original shell invocation. + // perfetto --background-wait -c /data/misc/perfetto-traces/trace_config.pb -o + // /data/misc/perfetto-traces/trace_output.perfetto-trace + private static final String PERFETTO_START_CMD = "perfetto --background-wait -c %s%s -o %s"; private static final String PERFETTO_TMP_OUTPUT_FILE = - "/data/misc/perfetto-traces/trace_output.pb"; + "/data/misc/perfetto-traces/trace_output.perfetto-trace"; // Additional arg to indicate that the perfetto config file is text format. private static final String PERFETTO_TXT_PROTO_ARG = " --txt"; // Command to stop (i.e kill) the perfetto tracing. private static final String PERFETTO_STOP_CMD = "kill %d"; // Command to return the process details if it is still running otherwise returns empty string. private static final String PERFETTO_PROC_ID_EXIST_CHECK = "ls -l /proc/%d/exe"; - // Remove the trace output file /data/misc/perfetto-traces/trace_output.pb + // Remove the trace output file /data/misc/perfetto-traces/trace_output.perfetto-trace private static final String REMOVE_CMD = "rm %s"; // Command to move the perfetto output trace file to given folder. private static final String MOVE_CMD = "mv %s %s"; @@ -63,7 +65,7 @@ public class PerfettoHelper { /** * Start the perfetto tracing in background using the given config file and write the ouput to - * /data/misc/perfetto-traces/trace_output.pb. Perfetto has access only to + * /data/misc/perfetto-traces/trace_output.perfetto-trace. Perfetto has access only to * /data/misc/perfetto-traces/ folder. So the config file has to be under * /data/misc/perfetto-traces/ folder in the device. * @@ -116,9 +118,9 @@ public class PerfettoHelper { } /** - * Stop the perfetto trace collection under /data/misc/perfetto-traces/trace_output.pb after - * waiting for given time in msecs and copy the output to the destination file. - * + * Stop the perfetto trace collection and redirect the output to + * /data/misc/perfetto-traces/trace_output.perfetto-trace after waiting for given time in msecs + * and copy the output to the destination file. * @param waitTimeInMsecs time to wait in msecs before stopping the trace collection. * @param destinationFile file to copy the perfetto output trace. * @return true if the trace collection is successfull otherwise false. @@ -215,7 +217,7 @@ public class PerfettoHelper { } } - // Copy the collected trace from /data/misc/perfetto-traces/trace_output.pb to + // Copy the collected trace from /data/misc/perfetto-traces/trace_output.perfetto-trace to // destinationFile try { String moveResult = mUIDevice.executeShellCommand(String.format( diff --git a/libraries/collectors-helper/perfetto/test/src/com/android/helpers/tests/PerfettoHelperTest.java b/libraries/collectors-helper/perfetto/test/src/com/android/helpers/tests/PerfettoHelperTest.java index 541217c08..72e06ad28 100644 --- a/libraries/collectors-helper/perfetto/test/src/com/android/helpers/tests/PerfettoHelperTest.java +++ b/libraries/collectors-helper/perfetto/test/src/com/android/helpers/tests/PerfettoHelperTest.java @@ -61,8 +61,9 @@ public class PerfettoHelperTest { if (isPerfettoStartSuccess) { mPerfettoHelper.setPerfettoConfigRootDir("/data/misc/perfetto-traces/"); UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - mPerfettoHelper.stopCollecting(1000, "data/local/tmp/out.pb"); - uiDevice.executeShellCommand(String.format(REMOVE_CMD, "/data/local/tmp/out.pb")); + mPerfettoHelper.stopCollecting(1000, "data/local/tmp/out.perfetto-trace"); + uiDevice.executeShellCommand(String.format(REMOVE_CMD, + "/data/local/tmp/out.perfetto-trace")); } } @@ -121,7 +122,7 @@ public class PerfettoHelperTest { public void testPerfettoValidOutputPath() throws Exception { assertTrue(mPerfettoHelper.startCollecting("trace_config.textproto", true)); isPerfettoStartSuccess = true; - assertTrue(mPerfettoHelper.stopCollecting(1000, "data/local/tmp/out.pb")); + assertTrue(mPerfettoHelper.stopCollecting(1000, "data/local/tmp/out.perfetto-trace")); } /** @@ -132,7 +133,7 @@ public class PerfettoHelperTest { assertTrue(mPerfettoHelper.startCollecting("trace_config.textproto", true)); isPerfettoStartSuccess = true; // Don't have permission to create new folder under /data - assertFalse(mPerfettoHelper.stopCollecting(1000, "/data/xxx/xyz/out.pb")); + assertFalse(mPerfettoHelper.stopCollecting(1000, "/data/xxx/xyz/out.perfetto-trace")); } /** @@ -143,10 +144,10 @@ public class PerfettoHelperTest { public void testPerfettoSuccess() throws Exception { assertTrue(mPerfettoHelper.startCollecting("trace_config.textproto", true)); isPerfettoStartSuccess = true; - assertTrue(mPerfettoHelper.stopCollecting(1000, "/data/local/tmp/out.pb")); + assertTrue(mPerfettoHelper.stopCollecting(1000, "/data/local/tmp/out.perfetto-trace")); UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); String[] fileStats = uiDevice.executeShellCommand(String.format( - FILE_SIZE_IN_BYTES, "/data/local/tmp/out.pb")).split(" "); + FILE_SIZE_IN_BYTES, "/data/local/tmp/out.perfetto-trace")).split(" "); int fileSize = Integer.parseInt(fileStats[0].trim()); assertTrue(fileSize > 0); } diff --git a/libraries/device-collectors/src/main/java/android/device/collectors/PerfettoListener.java b/libraries/device-collectors/src/main/java/android/device/collectors/PerfettoListener.java index 875f60294..2626bc9d0 100644 --- a/libraries/device-collectors/src/main/java/android/device/collectors/PerfettoListener.java +++ b/libraries/device-collectors/src/main/java/android/device/collectors/PerfettoListener.java @@ -39,7 +39,7 @@ import org.junit.runner.notification.Failure; /** * A {@link PerfettoListener} that captures the perfetto trace during each test method * and save the perfetto trace files under - * <root_folder>/<test_display_name>/PerfettoListener/<test_display_name>-<invocation_count>.pb + * <root>/<test_name>/PerfettoListener/<test_name>-<invocation_count>.perfetto-trace */ @OptionClass(alias = "perfetto-collector") public class PerfettoListener extends BaseMetricListener { @@ -225,14 +225,14 @@ public class PerfettoListener extends BaseMetricListener { () -> { Log.i(getTag(), "Stopping perfetto after test ended."); // Construct test output directory in the below format - // <root_folder>/<test_name>/PerfettoListener/<test_name>-<count>.pb + // <root>/<test_name>/PerfettoListener/<test_name>-<count>.perfetto-trace Path path = Paths.get( mTestOutputRoot, getTestFileName(description), this.getClass().getSimpleName(), String.format( - "%s%s-%d.pb", + "%s%s-%d.perfetto-trace", PERFETTO_PREFIX, getTestFileName(description), mTestIdInvocationCount.get( @@ -265,13 +265,13 @@ public class PerfettoListener extends BaseMetricListener { () -> { Log.i(getTag(), "Stopping perfetto after test run ended."); // Construct test output directory in the below format - // <root_folder>/PerfettoListener/<randomUUID>.pb + // <root_folder>/PerfettoListener/<randomUUID>.perfetto-trace Path path = Paths.get( mTestOutputRoot, this.getClass().getSimpleName(), String.format( - "%s%d.pb", + "%s%d.perfetto-trace", PERFETTO_PREFIX, UUID.randomUUID().hashCode())); stopPerfettoTracing(path, runData); }; diff --git a/libraries/device-collectors/src/test/java/android/device/collectors/PerfettoListenerTest.java b/libraries/device-collectors/src/test/java/android/device/collectors/PerfettoListenerTest.java index 600e1c4e7..80b961610 100644 --- a/libraries/device-collectors/src/test/java/android/device/collectors/PerfettoListenerTest.java +++ b/libraries/device-collectors/src/test/java/android/device/collectors/PerfettoListenerTest.java @@ -132,7 +132,7 @@ public class PerfettoListenerTest { mListener.onTestEnd(mDataRecord, mTest1Desc); verify(mPerfettoHelper, times(1)).stopCollecting(anyLong(), eq( "/sdcard/test_results/run_test1/PerfettoListener_1_Proxy/" - + "perfetto_run_test1-1.pb")); + + "perfetto_run_test1-1.perfetto-trace")); } @@ -540,7 +540,7 @@ public class PerfettoListenerTest { mListener.onTestEnd(mDataRecord, mTest1DescWithSpaces); verify(mPerfettoHelper, times(1)).stopCollecting(anyLong(), eq( "/sdcard/test_results/run#123_test1#456/PerfettoListener_1_Proxy/" - + "perfetto_run#123_test1#456-1.pb")); + + "perfetto_run#123_test1#456-1.perfetto-trace")); } diff --git a/libraries/tapl-common/src/android/platform/test/scenario/tapl_common/TaplUiObject.kt b/libraries/tapl-common/src/android/platform/test/scenario/tapl_common/TaplUiObject.kt index 28d997b27..694c75df2 100644 --- a/libraries/tapl-common/src/android/platform/test/scenario/tapl_common/TaplUiObject.kt +++ b/libraries/tapl-common/src/android/platform/test/scenario/tapl_common/TaplUiObject.kt @@ -15,7 +15,12 @@ */ package android.platform.test.scenario.tapl_common +import android.graphics.Point +import android.graphics.Rect +import android.platform.uiautomator_helpers.BetterSwipe +import android.platform.uiautomator_helpers.PRECISE_GESTURE_INTERPOLATOR import androidx.test.uiautomator.By +import androidx.test.uiautomator.Direction import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.Until @@ -25,6 +30,34 @@ import androidx.test.uiautomator.Until * @param [name] Name of the object for diags */ class TaplUiObject constructor(val uiObject: UiObject2, private val name: String) { + // Margins used for gestures (avoids touching too close to the object's edge). + private var mMarginLeft = 5 + private var mMarginTop = 5 + private var mMarginRight = 5 + private var mMarginBottom = 5 + + /** Sets the margins used for gestures in pixels. */ + fun setGestureMargin(margin: Int) { + setGestureMargins(margin, margin, margin, margin) + } + + /** Sets the margins used for gestures in pixels. */ + fun setGestureMargins(left: Int, top: Int, right: Int, bottom: Int) { + mMarginLeft = left + mMarginTop = top + mMarginRight = right + mMarginBottom = bottom + } + + /** Returns this object's visible bounds with the margins removed. */ + private fun getVisibleBoundsForGestures(): Rect { + val ret: Rect = uiObject.visibleBounds + ret.left = ret.left + mMarginLeft + ret.top = ret.top + mMarginTop + ret.right = ret.right - mMarginRight + ret.bottom = ret.bottom - mMarginBottom + return ret + } /** Wait for the object to become clickable and enabled, then clicks the object. */ fun click() { @@ -47,4 +80,56 @@ class TaplUiObject constructor(val uiObject: UiObject2, private val name: String ) return TaplUiObject(childObject, childObjectName) } + + /** + * Performs a horizontal or vertical swipe over an area. + * + * @param area The area to swipe over. + * @param direction The direction in which to swipe. + * @param percent The size of the swipe as a percentage of the total area. + */ + private fun scrollRect(area: Rect, direction: Direction, percent: Float) { + val start: Point + val end: Point + when (direction) { + Direction.LEFT -> { + start = Point(area.right, area.centerY()) + end = Point(area.right - (area.width() * percent).toInt(), area.centerY()) + } + Direction.RIGHT -> { + start = Point(area.left, area.centerY()) + end = Point(area.left + (area.width() * percent).toInt(), area.centerY()) + } + Direction.UP -> { + start = Point(area.centerX(), area.bottom) + end = Point(area.centerX(), area.bottom - (area.height() * percent).toInt()) + } + Direction.DOWN -> { + start = Point(area.centerX(), area.top) + end = Point(area.centerX(), area.top + (area.height() * percent).toInt()) + } + else -> throw RuntimeException() + } + + BetterSwipe.from(start).to(end, interpolator = PRECISE_GESTURE_INTERPOLATOR).release() + } + + /** + * Performs a scroll gesture on this object. + * + * @param direction The direction in which to scroll. + * @param percent The distance to scroll as a percentage of this object's visible size. + */ + fun scroll(direction: Direction, percent: Float) { + require(percent >= 0.0f) { "Percent must be greater than 0.0f" } + require(percent <= 1.0f) { "Percent must be less than 1.0f" } + + // To scroll, we swipe in the opposite direction + val swipeDirection: Direction = Direction.reverse(direction) + + // Scroll by performing repeated swipes + val bounds: Rect = getVisibleBoundsForGestures() + val segment = Math.min(percent, 1.0f) + scrollRect(bounds, swipeDirection, segment) + } } diff --git a/libraries/uiautomator-helpers/src/android/platform/uiautomator_helpers/BetterSwipe.kt b/libraries/uiautomator-helpers/src/android/platform/uiautomator_helpers/BetterSwipe.kt index d6bf17ed6..42cc7c369 100644 --- a/libraries/uiautomator-helpers/src/android/platform/uiautomator_helpers/BetterSwipe.kt +++ b/libraries/uiautomator-helpers/src/android/platform/uiautomator_helpers/BetterSwipe.kt @@ -102,6 +102,22 @@ object BetterSwipe { return this } + /** + * Swipes from the current point to [end] in [duration] using [interpolator] for the gesture + * speed. Pass [FLING_GESTURE_INTERPOLATOR] for a fling-like gesture that may leave the + * surface moving by inertia. Don't use it to drag objects to a precisely specified + * position. [PRECISE_GESTURE_INTERPOLATOR] will result in a precise drag-like gesture not + * triggering inertia. + */ + @JvmOverloads + fun to( + end: Point, + duration: Duration = DEFAULT_DURATION, + interpolator: TimeInterpolator = FLING_GESTURE_INTERPOLATOR + ): Swipe { + return to(PointF(end.x.toFloat(), end.y.toFloat()), duration, interpolator) + } + /** Moves the pointer up, finishing the swipe. Further calls will result in an exception. */ @JvmOverloads fun release(sync: Boolean = true) { |