Copy any additional files from the previous result after retry

bug:34720468
Change-Id: I15447df27c34edb86ac06124581646ba1d77dafd
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
index 620fa0a..e63ecdf 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
@@ -502,6 +502,10 @@
                     mBuildHelper.getSuiteBuild(), mResult, mResultDir, startTime,
                     elapsedTime + startTime, mReferenceUrl, getLogUrl(),
                     mBuildHelper.getCommandLineArgs());
+            if (mRetrySessionId != null) {
+                copyRetryFiles(ResultHandler.getResultDirectory(
+                        mBuildHelper.getResultsDir(), mRetrySessionId), mResultDir);
+            }
             File zippedResults = zipResults(mResultDir);
 
             // Create failure report after zip file so extra data is not uploaded
@@ -720,6 +724,33 @@
     }
 
     /**
+     * Recursively copy any other files found in the previous session's result directory to the
+     * new result directory, so long as they don't already exist. For example, a "screenshots"
+     * directory generated in a previous session by a passing test will not be generated on retry
+     * unless copied from the old result directory.
+     *
+     * @param oldResultsDir
+     * @param newResultsDir
+     */
+    static void copyRetryFiles(File oldResultsDir, File newResultsDir) {
+        File[] oldFiles = oldResultsDir.listFiles();
+        for (File oldFile : oldFiles) {
+            File newFile = new File (newResultsDir, oldFile.getName());
+            if (!newFile.exists()) {
+                try {
+                    if (oldFile.isDirectory()) {
+                        FileUtil.recursiveCopy(oldFile, newFile);
+                    } else {
+                        FileUtil.copyFile(oldFile, newFile);
+                    }
+                } catch (IOException e) {
+                    warn("Failed to copy file \"%s\" from previous session", oldFile.getName());
+                }
+            }
+        }
+    }
+
+    /**
      * Zip the contents of the given results directory.
      *
      * @param resultsDir
diff --git a/common/util/src/com/android/compatibility/common/util/ResultHandler.java b/common/util/src/com/android/compatibility/common/util/ResultHandler.java
index 1cdc38a..14a41af 100644
--- a/common/util/src/com/android/compatibility/common/util/ResultHandler.java
+++ b/common/util/src/com/android/compatibility/common/util/ResultHandler.java
@@ -499,6 +499,22 @@
     }
 
     /**
+     * Get the result directory for the given sessionId.
+     */
+    public static File getResultDirectory(File resultsDir, Integer sessionId) {
+        if (sessionId < 0) {
+            throw new IllegalArgumentException(
+                String.format("Invalid session id [%d] ", sessionId));
+        }
+        List<File> allResultDirs = getResultDirectories(resultsDir);
+        if (sessionId >= allResultDirs.size()) {
+            throw new IllegalArgumentException(String.format("Invalid session id [%d], results" +
+                    "directory contains only %d results", sessionId, allResultDirs.size()));
+        }
+        return allResultDirs.get(sessionId);
+    }
+
+    /**
      * Get a list of child directories that contain test invocation results
      * @param resultsDir the root test result directory
      * @return