summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-01-07 02:27:45 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-01-07 02:27:45 +0000
commit0b9279fc6a33285edb20d4e1880baaaba31b91fa (patch)
tree8172e3b7653bae9995cc5edd67b50c0260c5d41a
parent31ced6f4267f6e449d9f6151f09e13bc8a6f35d6 (diff)
parent5014803f3c9e4a8ce3baf5cc8ea7305ea945cc1f (diff)
downloadplatform_testing-android13-qpr2-s6-release.tar.gz
Change-Id: I67f3cbcf0d8c6fc8708d5198b79e544489a11f69
-rw-r--r--libraries/collectors-helper/perfetto/src/com/android/helpers/PerfettoHelper.java24
-rw-r--r--libraries/collectors-helper/perfetto/test/src/com/android/helpers/tests/PerfettoHelperTest.java13
-rw-r--r--libraries/device-collectors/src/main/java/android/device/collectors/PerfettoListener.java10
-rw-r--r--libraries/device-collectors/src/test/java/android/device/collectors/PerfettoListenerTest.java4
-rw-r--r--libraries/tapl-common/src/android/platform/test/scenario/tapl_common/TaplUiObject.kt85
-rw-r--r--libraries/uiautomator-helpers/src/android/platform/uiautomator_helpers/BetterSwipe.kt16
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) {