Merge "release-request-0b9b6f3b-8016-4c49-abb8-7a2eb58b4a1f-for-aosp-nougat-cts-release-4290372 snap-temp-L11500000097693914" into nougat-cts-release
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
index 4cc0351..acdaa0a 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
@@ -157,9 +157,6 @@
     public void addDynamicConfigFile(String moduleName, File configFile) {
         mBuildInfo.addBuildAttribute(DynamicConfigHostSide.CONFIG_PATH_PREFIX + moduleName,
                 configFile.getAbsolutePath());
-        // If invocation fails and ResultReporter never moves this file into the result,
-        // using setFile() ensures BuildInfo will delete upon cleanUp().
-        mBuildInfo.setFile(configFile.getName(), configFile, "1" /* version */);
     }
 
     public void setModuleIds(String[] moduleIds) {
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 fecc216..32d3cda 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
@@ -483,7 +483,7 @@
         long startTime = mResult.getStartTime();
         try {
             // Zip the full test results directory.
-            copyDynamicConfigFiles();
+            copyDynamicConfigFiles(mBuildHelper.getDynamicConfigFiles(), mResultDir);
             copyFormattingFiles(mResultDir, mBuildHelper.getSuiteName());
 
             File resultFile = ResultHandler.writeResults(mBuildHelper.getSuiteName(),
@@ -702,32 +702,18 @@
      * @param configFiles
      * @param resultsDir
      */
-    private void copyDynamicConfigFiles() {
-        File configDir = new File(mResultDir, "config");
-        if (!configDir.mkdir()) {
-            warn("Failed to make dynamic config directory \"%s\" in the result",
-                    configDir.getAbsolutePath());
-        }
+    static void copyDynamicConfigFiles(Map<String, File> configFiles, File resultsDir) {
+        if (configFiles.size() == 0) return;
 
-        Set<String> uniqueModules = new HashSet<>();
-        for (IBuildInfo buildInfo : mMasterBuildInfos) {
-            CompatibilityBuildHelper helper = new CompatibilityBuildHelper(buildInfo);
-            Map<String, File> dcFiles = helper.getDynamicConfigFiles();
-            for (String moduleName : dcFiles.keySet()) {
-                File srcFile = dcFiles.get(moduleName);
-                if (!uniqueModules.contains(moduleName)) {
-                    // have not seen config for this module yet, copy into result
-                    File destFile = new File(configDir, moduleName + ".dynamic");
-                    try {
-                        FileUtil.copyFile(srcFile, destFile);
-                        uniqueModules.add(moduleName); // Add to uniqueModules if copy succeeds
-                    } catch (IOException e) {
-                        warn("Failure when copying config file \"%s\" to \"%s\" for module %s",
-                                srcFile.getAbsolutePath(), destFile.getAbsolutePath(), moduleName);
-                        CLog.e(e);
-                    }
-                }
-                FileUtil.deleteFile(srcFile);
+        File folder = new File(resultsDir, "config");
+        folder.mkdir();
+        for (String moduleName : configFiles.keySet()) {
+            File resultFile = new File(folder, moduleName+".dynamic");
+            try {
+                FileUtil.copyFile(configFiles.get(moduleName), resultFile);
+                FileUtil.deleteFile(configFiles.get(moduleName));
+            } catch (IOException e) {
+                warn("Failed to copy config file for %s to file", moduleName);
             }
         }
     }
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
index 2570432..7600eb7 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
@@ -28,6 +28,7 @@
 import com.android.tradefed.targetprep.BuildError;
 import com.android.tradefed.targetprep.ITargetCleaner;
 import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.util.FileUtil;
 import com.android.tradefed.util.StreamUtil;
 
 import org.json.JSONException;
@@ -49,6 +50,7 @@
     }
 
     private static final String LOG_TAG = DynamicConfigPusher.class.getSimpleName();
+    private static final String TMP_FOLDER_DYNAMIC_FILES = "dynamic-config-files";
 
     @Option(name = "cleanup", description = "Whether to remove config files from the test " +
             "target after test completion.")
@@ -66,7 +68,8 @@
             "from the server, e.g. \"1.0\". Defaults to suite version string.")
     private static String mVersion;
 
-    private String mDeviceFilePushed;
+
+    private String mFilePushed;
 
     void setModuleName(String moduleName) {
         mModuleName = moduleName;
@@ -112,27 +115,46 @@
                     "Dynamic config override URL is not set, using local configuration values");
         }
 
-        // Use DynamicConfigHandler to merge local and service configuration into one file
-        File hostFile = null;
+        File src = null;
         try {
-            hostFile = DynamicConfigHandler.getMergedDynamicConfigFile(
+            src = DynamicConfigHandler.getMergedDynamicConfigFile(
                     localConfigFile, apfeConfigInJson, mModuleName);
         } catch (IOException | XmlPullParserException | JSONException e) {
             throw new TargetSetupError("Cannot get merged dynamic config file", e);
         }
 
-        if (TestTarget.DEVICE.equals(mTarget)) {
-            String deviceDest = String.format("%s%s.dynamic",
-                    DynamicConfig.CONFIG_FOLDER_ON_DEVICE, mModuleName);
-            if (!device.pushFile(hostFile, deviceDest)) {
-                throw new TargetSetupError(String.format(
-                        "Failed to push local '%s' to remote '%s'", hostFile.getAbsolutePath(),
-                        deviceDest));
-            }
-            mDeviceFilePushed = deviceDest;
+        switch (mTarget) {
+            case DEVICE:
+                String deviceDest = DynamicConfig.CONFIG_FOLDER_ON_DEVICE + src.getName();
+                if (!device.pushFile(src, deviceDest)) {
+                    throw new TargetSetupError(String.format(
+                            "Failed to push local '%s' to remote '%s'",
+                            src.getAbsolutePath(), deviceDest));
+                } else {
+                    mFilePushed = deviceDest;
+                    buildHelper.addDynamicConfigFile(mModuleName, src);
+                }
+                break;
+
+            case HOST:
+                File storageDir = null;
+                try {
+                    storageDir = FileUtil.createTempDir(TMP_FOLDER_DYNAMIC_FILES);
+                } catch (IOException e) {
+                    throw new TargetSetupError("Fail to create a tmp folder for dynamic config "
+                            + "files", e);
+                }
+                File hostDest = new File(storageDir, src.getName());
+                try {
+                    FileUtil.copyFile(src, hostDest);
+                } catch (IOException e) {
+                    throw new TargetSetupError(String.format("Failed to copy file from %s to %s",
+                            src.getAbsolutePath(), hostDest.getAbsolutePath()), e);
+                }
+                mFilePushed = storageDir.getAbsolutePath();
+                buildHelper.addDynamicConfigFile(mModuleName, src);
+                break;
         }
-        // add host file to build
-        buildHelper.addDynamicConfigFile(mModuleName, hostFile);
     }
 
     /**
@@ -141,10 +163,16 @@
     @Override
     public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)
             throws DeviceNotAvailableException {
-        // Remove any file we have pushed to the device, host file will be moved to the result
-        // directory by ResultReporter upon invocation completion.
-        if (mDeviceFilePushed != null && !(e instanceof DeviceNotAvailableException) && mCleanup) {
-            device.executeShellCommand("rm -r " + mDeviceFilePushed);
+        switch (mTarget) {
+            case DEVICE:
+                if (!(e instanceof DeviceNotAvailableException)
+                        && mCleanup && mFilePushed != null) {
+                    device.executeShellCommand("rm -r " + mFilePushed);
+                }
+                break;
+            case HOST:
+                FileUtil.recursiveDelete(new File(mFilePushed));
+                break;
         }
     }
 }
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java b/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
index 0528a1b..8df1ebc 100644
--- a/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
+++ b/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
@@ -37,8 +37,7 @@
 
 public class DynamicConfigHandler {
 
-    private final static String MERGED_CONFIG_FILE = "dynamic-config-files-merged";
-    private final static String FILE_EXT = ".dynamic";
+    private final static String MERGED_CONFIG_FILE_FOLDER = "dynamic-config-files-merged";
     private static final String NS = null; //xml constant representing null namespace
     private static final String ENCODING = "UTF-8";
 
@@ -77,7 +76,8 @@
     private static File storeMergedConfigFile(Map<String, List<String>> configMap,
             String moduleName) throws XmlPullParserException, IOException {
 
-        File mergedConfigFile = FileUtil.createTempFile(MERGED_CONFIG_FILE, FILE_EXT);
+        File folder = FileUtil.createTempDir(MERGED_CONFIG_FILE_FOLDER);
+        File mergedConfigFile = new File(folder, moduleName + ".dynamic");
         OutputStream stream = new FileOutputStream(mergedConfigFile);
         XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer();
         serializer.setOutput(stream, ENCODING);
diff --git a/common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java b/common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java
index 204a8f1..36c4970 100644
--- a/common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java
+++ b/common/host-side/util/tests/src/com/android/compatibility/common/util/DynamicConfigHandlerTest.java
@@ -16,9 +16,6 @@
 
 package com.android.compatibility.common.util;
 
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.StreamUtil;
-
 import junit.framework.TestCase;
 
 import java.io.File;
@@ -95,31 +92,26 @@
     public void testDynamicConfigHandler() throws Exception {
         String module = "test1";
         File localConfigFile = createFileFromStr(localConfig, module);
-        File mergedFile = null;
-        try {
-            mergedFile = DynamicConfigHandler
-                    .getMergedDynamicConfigFile(localConfigFile, overrideJson, module);
 
-            Map<String, List<String>> configMap = DynamicConfig.createConfigMap(mergedFile);
+        File mergedFile = DynamicConfigHandler
+                .getMergedDynamicConfigFile(localConfigFile, overrideJson, module);
 
-            assertEquals("override-config-val-1", configMap.get("override-config-1").get(0));
-            assertTrue(configMap.get("override-config-list-1")
-                    .contains("override-config-list-val-1-1"));
-            assertTrue(configMap.get("override-config-list-1")
-                    .contains("override-config-list-val-1-2"));
-            assertTrue(configMap.get("override-config-list-3").size() == 0);
+        Map<String, List<String>> configMap = DynamicConfig.createConfigMap(mergedFile);
 
-            assertEquals("test config 1", configMap.get("test-config-1").get(0));
-            assertTrue(configMap.get("config-list").contains("config2"));
+        assertEquals("override-config-val-1", configMap.get("override-config-1").get(0));
+        assertTrue(configMap.get("override-config-list-1")
+                .contains("override-config-list-val-1-1"));
+        assertTrue(configMap.get("override-config-list-1")
+                .contains("override-config-list-val-1-2"));
+        assertTrue(configMap.get("override-config-list-3").size() == 0);
 
-            assertEquals("override-config-val-2", configMap.get("override-config-2").get(0));
-            assertEquals(1, configMap.get("override-config-list-2").size());
-            assertTrue(configMap.get("override-config-list-2")
-                    .contains("override-config-list-val-2-1"));
-        } finally {
-            FileUtil.deleteFile(localConfigFile);
-            FileUtil.recursiveDelete(mergedFile);
-        }
+        assertEquals("test config 1", configMap.get("test-config-1").get(0));
+        assertTrue(configMap.get("config-list").contains("config2"));
+
+        assertEquals("override-config-val-2", configMap.get("override-config-2").get(0));
+        assertEquals(1, configMap.get("override-config-list-2").size());
+        assertTrue(configMap.get("override-config-list-2")
+                .contains("override-config-list-val-2-1"));
     }
 
 
@@ -131,7 +123,9 @@
             stream.write(configStr.getBytes());
             stream.flush();
         } finally {
-            StreamUtil.close(stream);
+            if (stream != null) {
+                stream.close();
+            }
         }
         return file;
     }