Adding screen recording to toggle tests
This would be a useful addition to recently added screenshots
and other artifacts which can be seen here:
https://fusion2.corp.google.com/invocations/c8c16af0-15a1-4f03-b074-4435d82193ce/artifacts
Tests classes are supposed to always have ScreenRecordRule,
but individual tests should be marked with @ScreenRecord
only during investigations because @ScreenRecord may affect
performance characteristics.
Bug: 202567877
Test: atest PlatformScenarioTests:android.platform.test.scenario.sysui.quicksettings.ToggleFlashlightOff#testToggle
Change-Id: Ib261c55a645d70d51b75fd779058c0183444eb31
diff --git a/libraries/health/rules/src/android/platform/test/rule/FailureWatcher.java b/libraries/health/rules/src/android/platform/test/rule/FailureWatcher.java
index 7940d79..3b46815 100644
--- a/libraries/health/rules/src/android/platform/test/rule/FailureWatcher.java
+++ b/libraries/health/rules/src/android/platform/test/rule/FailureWatcher.java
@@ -47,7 +47,7 @@
onError(mDevice, description, e);
}
- static File diagFile(Description description, String prefix, String ext) {
+ public static File diagFile(Description description, String prefix, String ext) {
return new File(
getInstrumentation().getTargetContext().getFilesDir(),
prefix
diff --git a/libraries/health/rules/src/android/platform/test/rule/ScreenRecordRule.java b/libraries/health/rules/src/android/platform/test/rule/ScreenRecordRule.java
new file mode 100644
index 0000000..fb9d052
--- /dev/null
+++ b/libraries/health/rules/src/android/platform/test/rule/ScreenRecordRule.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2021 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 android.platform.test.rule;
+
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import androidx.test.uiautomator.UiDevice;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.io.File;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Rule which captures a screen record for a test. After adding this rule to the test class, apply
+ * the annotation @ScreenRecord to individual tests
+ */
+public class ScreenRecordRule implements TestRule {
+
+ private static final String TAG = "ScreenRecordRule";
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ if (description.getAnnotation(ScreenRecord.class) == null) {
+ return base;
+ }
+
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ Instrumentation inst = getInstrumentation();
+ UiAutomation automation = inst.getUiAutomation();
+ UiDevice device = UiDevice.getInstance(inst);
+
+ File outputFile = FailureWatcher.diagFile(description, "ScreenRecord", "mp4");
+ device.executeShellCommand("killall screenrecord");
+ ParcelFileDescriptor output =
+ automation.executeShellCommand("screenrecord " + outputFile);
+ String screenRecordPid = device.executeShellCommand("pidof screenrecord");
+ try {
+ base.evaluate();
+ } finally {
+ device.executeShellCommand("kill -INT " + screenRecordPid);
+ Log.e(TAG, "Screenrecord captured at: " + outputFile);
+ output.close();
+ }
+ // Delete the file if the test was successful.
+ automation.executeShellCommand("rm " + outputFile);
+ }
+ };
+ }
+
+ /** Interface to indicate that the test should capture screenrecord */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public @interface ScreenRecord {}
+}