Retain all flicker trace files after the run

The video files are necessary to detect other types of flickers not checked in the tests.

This CL adds a "PASS_" or "FAIL_" prefix to the trace files for easier verification.

Bug: 213393948
Test: atest FlickerLibTest
Change-Id: I2588cd7dff1da64c8a7407b592b46b57a8d43440
diff --git a/libraries/flicker/src/com/android/server/wm/flicker/FlickerResult.kt b/libraries/flicker/src/com/android/server/wm/flicker/FlickerResult.kt
index 62da20d..94eb194 100644
--- a/libraries/flicker/src/com/android/server/wm/flicker/FlickerResult.kt
+++ b/libraries/flicker/src/com/android/server/wm/flicker/FlickerResult.kt
@@ -76,20 +76,10 @@
     }
 
     /**
-     * Remove from the device the trace files associated with passed runs.
-     *
-     * If an test fails, or if the transition crashes, retain all traces related to
-     * that run.
+     * Add a prefix to all trace files indicating the test status (pass/fail)
      */
     fun cleanUp() {
-        if (error != null) {
-            return
-        }
-        runs.forEach {
-            if (it.canDelete(failures)) {
-                it.cleanUp()
-            }
-        }
+        runs.forEach { it.cleanUp(failures) }
     }
 
     fun isEmpty(): Boolean = error == null && runs.isEmpty()
diff --git a/libraries/flicker/src/com/android/server/wm/flicker/FlickerRunResult.kt b/libraries/flicker/src/com/android/server/wm/flicker/FlickerRunResult.kt
index 22de5b9..d799e58 100644
--- a/libraries/flicker/src/com/android/server/wm/flicker/FlickerRunResult.kt
+++ b/libraries/flicker/src/com/android/server/wm/flicker/FlickerRunResult.kt
@@ -34,6 +34,7 @@
 import java.io.IOException
 import java.nio.file.Files
 import java.nio.file.Path
+import java.nio.file.StandardCopyOption
 
 /**
  * Defines the result of a flicker run
@@ -75,25 +76,34 @@
         return result
     }
 
-    private fun Path?.tryDelete() {
+    private fun rename(source: Path, isFailure: Boolean) {
+        if (!Files.exists(source)) {
+            return
+        }
         try {
-            this?.let { Files.deleteIfExists(it) }
+            val prefix = if (isFailure) FAIL_PREFIX else PASS_PREFIX
+            val newFileName = prefix + source.fileName.toString()
+            val target = source.resolveSibling(newFileName)
+            Files.move(source, target, StandardCopyOption.REPLACE_EXISTING)
         } catch (e: IOException) {
             Log.e(FLICKER_TAG, "Unable do delete $this", e)
         }
     }
 
-    fun canDelete(failures: List<FlickerAssertionError>): Boolean {
-        return failures.flatMap { it.traceFiles }.none { failureTrace ->
+    private fun containsFailure(failures: List<FlickerAssertionError>): Boolean {
+        return failures.flatMap { it.traceFiles }.any { failureTrace ->
             this.traceFiles.any { it == failureTrace }
         }
     }
 
     /**
-     * Delete the trace files collected
+     * Rename the trace files according to the run status (pass/fail)
+     *
+     * @param failures List of all failures during the flicker execution
      */
-    fun cleanUp() {
-        this.traceFiles.forEach { it.tryDelete() }
+    fun cleanUp(failures: List<FlickerAssertionError>) {
+        val containsFailure = containsFailure(failures)
+        this.traceFiles.forEach { rename(it, containsFailure) }
     }
 
     class Builder @JvmOverloads constructor(private val iteration: Int = 0) {
@@ -205,4 +215,9 @@
             return result
         }
     }
+
+    companion object {
+        private const val PASS_PREFIX = "PASS_"
+        private const val FAIL_PREFIX = "FAIL_"
+    }
 }