Clean up references to ModuleDef and ModuleRepo as we go

Cleaning up the references and freeing the memory has
become necessary because of a huge amount of used memory.

Test: local unit tests,
run cts --shards 2 (and dump heap to verify ModuleRepo is
gone)
run cts-dev -m CtsGestureTestCases --shard-count 2
Bug: 36269460

Change-Id: Id5b84fddc7eaecd28b351f5b7de6820b52cf7121
(cherry picked from commit e3e3f11a0fb96d3e5f7c675fd791584ac0909613)
(cherry picked from commit 07640d98102ec6edc9aceaed5832f9297cada36c)
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
index 23138d5..746f45f 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
@@ -348,7 +348,7 @@
 
             // FIXME: Each shard will do a full initialization which is not optimal. Need a way
             // to be more specific on what to initialize.
-            List<IModuleDef> modules;
+            LinkedList<IModuleDef> modules;
             synchronized (mModuleRepo) {
                 if (!mModuleRepo.isInitialized()) {
                     setupFilters();
@@ -387,6 +387,7 @@
                 CLog.logAndDisplay(LogLevel.INFO, "Starting %d module%s on %s", moduleCount,
                         (moduleCount > 1) ? "s" : "", mDevice.getSerialNumber());
             }
+
             if (mRebootBeforeTest) {
                 CLog.d("Rebooting device before test starts as requested.");
                 mDevice.reboot();
@@ -435,10 +436,14 @@
                     throw new RuntimeException(e);
                 }
             }
+            // Module Repo is not useful anymore
+            mModuleRepo.tearDown();
+            mModuleRepo = null;
             // Run the tests
-            for (int i = 0; i < moduleCount; i++) {
-
-                IModuleDef module = modules.get(i);
+            while (!modules.isEmpty()) {
+                // Make sure we remove the modules from the reference list when we are done with
+                // them.
+                IModuleDef module = modules.poll();
                 long start = System.currentTimeMillis();
 
                 if (mRebootPerModule) {
@@ -457,9 +462,6 @@
                     runPreModuleCheck(module.getName(), checkers, mDevice, listener);
                 }
                 try {
-                    if (module.getTest() instanceof IBuildReceiver) {
-                        ((IBuildReceiver)module.getTest()).setBuild(mBuildHelper.getBuildInfo());
-                    }
                     module.run(listener);
                 } catch (DeviceUnresponsiveException due) {
                     // being able to catch a DeviceUnresponsiveException here implies that recovery
@@ -487,6 +489,7 @@
                 if (checkers != null && !checkers.isEmpty()) {
                     runPostModuleCheck(module.getName(), checkers, mDevice, listener);
                 }
+                module = null;
             }
         } catch (FileNotFoundException fnfe) {
             throw new RuntimeException("Failed to initialize modules", fnfe);
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
index 1f6a53e..f75fbd1 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
@@ -19,8 +19,8 @@
 import com.android.tradefed.testtype.IAbi;
 
 import java.io.File;
+import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -41,9 +41,10 @@
             Set<String> mIncludeFilters, Set<String> mExcludeFilters, IBuildInfo buildInfo);
 
     /**
-     * @return a {@link Map} of all modules to run on the device referenced by the given serial.
+     * @return a {@link LinkedList} of all modules to run on the device referenced by the given
+     * serial.
      */
-    List<IModuleDef> getModules(String serial, int shardIndex);
+    LinkedList<IModuleDef> getModules(String serial, int shardIndex);
 
     /**
      * @return the number of shards this repo is initialized for.
@@ -64,4 +65,9 @@
      * @return An array of all module ids in the repo.
      */
     String[] getModuleIds();
+
+    /**
+     * Clean up all internal references.
+     */
+    void tearDown();
 }
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
index 330bea2..64c25b9 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
@@ -46,6 +46,7 @@
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -441,11 +442,11 @@
      * {@inheritDoc}
      */
     @Override
-    public List<IModuleDef> getModules(String serial, int shardIndex) {
+    public LinkedList<IModuleDef> getModules(String serial, int shardIndex) {
         Collections.sort(mNonTokenModules, new ExecutionOrderComparator());
         List<IModuleDef> modules = getShard(mNonTokenModules, shardIndex, mTotalShards);
         if (modules == null) {
-            modules = new ArrayList<IModuleDef>();
+            modules = new LinkedList<IModuleDef>();
         }
         long estimatedTime = 0;
         for (IModuleDef def : modules) {
@@ -475,7 +476,9 @@
         Collections.sort(modules, new ExecutionOrderComparator());
         CLog.logAndDisplay(LogLevel.INFO, "%s running %s modules, expected to complete in %s: %s",
                 serial, modules.size(), TimeUtil.formatElapsedTime(estimatedTime), modules);
-        return modules;
+        LinkedList<IModuleDef> tests = new LinkedList<>();
+        tests.addAll(modules);
+        return tests;
     }
 
     /**
@@ -569,4 +572,17 @@
         mInitCount = 0;
         mTokenModuleScheduled = null;
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void tearDown() {
+        mNonTokenModules.clear();
+        mTokenModules.clear();
+        mIncludeFilters.clear();
+        mExcludeFilters.clear();
+        mTestArgs.clear();
+        mModuleArgs.clear();
+    }
 }
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
index 03a6d0e..ef402e1 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
@@ -33,6 +33,7 @@
 
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 
@@ -282,8 +283,8 @@
                 return true;
             }
             @Override
-            public List<IModuleDef> getModules(String serial, int shardIndex) {
-                return new ArrayList<IModuleDef>();
+            public LinkedList<IModuleDef> getModules(String serial, int shardIndex) {
+                return new LinkedList<IModuleDef>();
             }
         }, 0);
         mTest.setDevice(mMockDevice);