Fix derived plan.

-Remove all ABI based test filtering from TestPackageDef and TestPlan.
-TestPackageDef and TestPlan represent exactly what exists in the corresponding XML files
-All ABI filtering happens in CtsTest.
-Minor cleanup

Change-Id: If9bc2ef31d70409f01bb098f4a1642be490bcb4c
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
index 7333de2..ca4e050 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
@@ -80,7 +80,7 @@
             public void run() {
                 CtsBuildHelper ctsBuild = getCtsBuild();
                 if (ctsBuild != null) {
-                    listPackages(ctsBuild, AbiUtils.getAbisSupportedByCts());
+                    listPackages(ctsBuild);
                 }
             }
         }, LIST_PATTERN, "packages");
@@ -193,8 +193,8 @@
         }
     }
 
-    private void listPackages(CtsBuildHelper ctsBuild, Set<String> abis) {
-        ITestPackageRepo testCaseRepo = new TestPackageRepo(ctsBuild.getTestCasesDir(), abis, false);
+    private void listPackages(CtsBuildHelper ctsBuild) {
+        ITestPackageRepo testCaseRepo = new TestPackageRepo(ctsBuild.getTestCasesDir(), false);
         for (String packageName : testCaseRepo.getPackageNames()) {
             printLine(packageName);
         }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java
index 713e8fa..3881c0e 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java
@@ -116,8 +116,8 @@
     public ITestPlan createDerivedPlan(CtsBuildHelper build, Set<String> abis)
             throws ConfigurationException {
         checkFields(build);
-        ITestPackageRepo pkgDefRepo = new TestPackageRepo(build.getTestCasesDir(),
-                abis, mIncludeKnownFailures);
+        ITestPackageRepo pkgDefRepo =
+                new TestPackageRepo(build.getTestCasesDir(), mIncludeKnownFailures);
         ITestPlan derivedPlan = new TestPlan(mPlanName, abis);
         for (TestPackageResult pkg : mResult.getPackages()) {
             Collection<TestIdentifier> filteredTests = pkg.getTestsWithStatus(mResultFilter);
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index 088bc8e..ce48664 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -64,7 +64,6 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Queue;
 import java.util.Set;
 
 
@@ -205,11 +204,10 @@
         private final ITestPackageDef mPackageDef;
         private final Collection<TestIdentifier> mKnownTests;
 
-        TestPackage(ITestPackageDef packageDef, IRemoteTest testForPackage,
-                Collection<TestIdentifier> knownTests) {
+        TestPackage(ITestPackageDef packageDef, IRemoteTest testForPackage) {
             mPackageDef = packageDef;
             mTestForPackage = testForPackage;
-            mKnownTests = knownTests;
+            mKnownTests = packageDef.getTests();
         }
 
         IRemoteTest getTestForPackage() {
@@ -324,7 +322,7 @@
     }
 
     /**
-     * Create a new {@link CtsTest} that will run the given {@List} of {@link TestPackage}s.
+     * Create a new {@link CtsTest} that will run the given {@link List} of {@link TestPackage}s.
      */
     public CtsTest(int shardAssignment, int totalShards) {
         if (shardAssignment < 0) {
@@ -448,8 +446,6 @@
      * Set the CTS build container.
      * <p/>
      * Exposed so unit tests can mock the provided build.
-     *
-     * @param buildHelper
      */
     void setBuildHelper(CtsBuildHelper buildHelper) {
         mCtsBuild = buildHelper;
@@ -468,6 +464,7 @@
         if (abiSet == null || abiSet.isEmpty()) {
             throw new IllegalArgumentException("could not get device's ABIs");
         }
+        Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "ABIs: " + abiSet);
 
         checkFields();
         setupTestPackageList(abiSet);
@@ -482,14 +479,12 @@
         }
 
         // Setup the a map of Test id to ResultFilter
-        Map<String, ResultFilter> filterMap = new HashMap<String, ResultFilter>();
+        Map<String, ResultFilter> filterMap = new HashMap<>();
         int totalTestCount = 0;
         for (TestPackage testPackage : mTestPackageList) {
-            if (testPackage.getKnownTests().size() > 0) {
-                ResultFilter resultFilter = new ResultFilter(listener, testPackage);
-                totalTestCount += resultFilter.getKnownTestCount();
-                filterMap.put(testPackage.getPackageDef().getId(), resultFilter);
-            }
+            ResultFilter resultFilter = new ResultFilter(listener, testPackage);
+            totalTestCount += resultFilter.getKnownTestCount();
+            filterMap.put(testPackage.getPackageDef().getId(), resultFilter);
         }
 
         // collect and install the prerequisiteApks first, to save time when multiple test
@@ -520,10 +515,6 @@
                         prerequisiteApks.get(currentAbi.getName()), currentAbi);
                 }
 
-                if (testPackage.getKnownTests().size() == 0) {
-                    // Skip empty packages. For example, those created by derived plans.
-                    continue;
-                }
                 IRemoteTest test = testPackage.getTestForPackage();
                 if (test instanceof IBuildReceiver) {
                     ((IBuildReceiver) test).setBuild(mBuildInfo);
@@ -571,19 +562,20 @@
     }
 
     /**
-     * @param packages The package list to filter
-     * @param abis The ABIs to test on
-     * @return A list of {@link TestPackage} which test one of the given ABIs
+     * @param allTestPackageDefList The package list to filter
+     * @param deviceAbiSet The ABIs supported by the device being tested
+     * @return A {@link List} of {@link ITestPackageDef}s that should be tested
      */
-    private static List<TestPackage> filterTestPackagesByAbi(
-            List<TestPackage> packages, Set<String> abis) {
-        List<TestPackage> testPackages = new LinkedList<>();
-        for (TestPackage test : packages) {
-            if (abis.contains(test.getAbi().getName())) {
-                testPackages.add(test);
+    private static List<ITestPackageDef> filterByAbi(
+            List<ITestPackageDef> allTestPackageDefList, Set<String> deviceAbiSet) {
+        List<ITestPackageDef> filteredTestPackageDefList = new LinkedList<>();
+        for (ITestPackageDef testPackageDef : allTestPackageDefList) {
+            if (deviceAbiSet.contains(testPackageDef.getAbi().getName())) {
+                // We only need test packages that are not empty and of matching ABIs
+                filteredTestPackageDefList.add(testPackageDef);
             }
         }
-        return testPackages;
+        return filteredTestPackageDefList;
     }
 
     /** Reboot then the device iff the list of packages exceeds the minimum */
@@ -593,7 +585,7 @@
             return;
         }
 
-        Set<String> packageNameSet = new HashSet<String>();
+        Set<String> packageNameSet = new HashSet<>();
         for (TestPackage testPackage : testPackageList) {
             // Parse the package name
             packageNameSet.add(AbiUtils.parseTestName(testPackage.getPackageDef().getId()));
@@ -688,84 +680,85 @@
             Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Resume tests using existing package list");
             return;
         }
-        Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "ABIs: " + abis);
-
-        List<TestPackage> testPkgList = new ArrayList<TestPackage>();
         try {
             // Collect ALL tests
             ITestPackageRepo testRepo = createTestCaseRepo();
-            List<ITestPackageDef> testPkgDefs = new ArrayList<>(getTestPackagesToRun(testRepo, abis));
-            // Sort testPkgDefs. Note: run() relies on the fact that the list is reliably sorted for
-            // sharding purposes
+            List<ITestPackageDef> testPkgDefs = new ArrayList<>(getAvailableTestPackages(testRepo));
+            testPkgDefs = filterByAbi(testPkgDefs, abis);
+            // Note: run() relies on the fact that the list is reliably sorted for sharding purposes
             Collections.sort(testPkgDefs);
-            ITestPackageDef[] testPackageDefArray =
-                    testPkgDefs.toArray(new ITestPackageDef[testPkgDefs.size()]);
-            int totalShards = Math.min(mTotalShards, testPkgDefs.size());
-
-            for (int i = mShardAssignment; i < testPkgDefs.size(); i += totalShards) {
-                ITestPackageDef testPackageDef = testPackageDefArray[i];
+            // Create test package list.
+            List<TestPackage> testPackageList = new ArrayList<>();
+            for (ITestPackageDef testPackageDef : testPkgDefs) {
+                // Note: createTest filters the test list inside of testPackageDef by exclusion list
                 IRemoteTest testForPackage = testPackageDef.createTest(mCtsBuild.getTestCasesDir());
-                if (testForPackage != null) {
-                    testPkgList.add(
-                        new TestPackage(testPackageDef, testForPackage, testPackageDef.getTests()));
+                if (testPackageDef.getTests().size() > 0) {
+                    testPackageList.add(new TestPackage(testPackageDef, testForPackage));
                 }
             }
-            mTestPackageList.addAll(filterTestPackagesByAbi(testPkgList, abis));
+
+            // Filter by shard
+            int numTestPackages = testPackageList.size();
+            int totalShards = Math.min(mTotalShards, numTestPackages);
+
+            List<TestPackage> shardTestPackageList = new ArrayList<>();
+            for (int i = mShardAssignment; i < numTestPackages; i += totalShards) {
+                shardTestPackageList.add(testPackageList.get(i));
+            }
+            mTestPackageList.addAll(shardTestPackageList);
         } catch (FileNotFoundException e) {
-            throw new IllegalArgumentException("failed to find CTS plan file", e);
+            throw new IllegalArgumentException("failed to find XTS plan file", e);
         } catch (ParseException e) {
-            throw new IllegalArgumentException("failed to parse CTS plan file", e);
+            throw new IllegalArgumentException("failed to parse XTS plan file", e);
         } catch (ConfigurationException e) {
             throw new IllegalArgumentException("failed to process arguments", e);
         }
     }
 
     /**
-     * Return the list of test package defs to run
+     * Return the {@link Set} of {@link ITestPackageDef}s to run unfiltered by ABI
      *
-     * @return the list of test package defs to run
+     * @return the {@link Set} of {@link ITestPackageDef}s to run
      * @throws ParseException
      * @throws FileNotFoundException
      * @throws ConfigurationException
      */
-    private Set<ITestPackageDef> getTestPackagesToRun(
-            ITestPackageRepo testRepo, Set<String> abiSet)
+    private Set<ITestPackageDef> getAvailableTestPackages(ITestPackageRepo testRepo)
                 throws ParseException, FileNotFoundException, ConfigurationException {
         // use LinkedHashSet to have predictable iteration order
-        Set<ITestPackageDef> testPkgDefs = new LinkedHashSet<ITestPackageDef>();
+        Set<ITestPackageDef> testPkgDefs = new LinkedHashSet<>();
         if (mPlanName != null) {
             Log.i(LOG_TAG, String.format("Executing CTS test plan %s", mPlanName));
             File ctsPlanFile = mCtsBuild.getTestPlanFile(mPlanName);
             ITestPlan plan = createPlan(mPlanName);
             plan.parse(createXmlStream(ctsPlanFile));
 
-            for (String packageName : plan.getTestNames()) {
-                if (mExcludedPackageNames.contains(packageName)) {
+            for (String testId : plan.getTestIds()) {
+                if (mExcludedPackageNames.contains(AbiUtils.parseTestName(testId))) {
                     continue;
                 }
-                Set<ITestPackageDef> testPackageDefSet = testRepo.getTestPackages(packageName);
-                if (testPackageDefSet.isEmpty()) {
-                    CLog.e("Could not find test package %s referenced in plan %s", packageName,
-                            mPlanName);
+                ITestPackageDef testPackageDef = testRepo.getTestPackage(testId);
+                if (testPackageDef == null) {
+                    CLog.e("Could not find test id %s referenced in plan %s", testId, mPlanName);
+                    continue;
                 }
-                for (ITestPackageDef testPackageDef : testPackageDefSet) {
-                    if (abiSet.contains(testPackageDef.getAbi().getName())) {
-                        testPackageDef.setTestFilter(plan.getTestFilter(testPackageDef.getId()));
-                        testPkgDefs.add(testPackageDef);
-                    }
-                }
+
+                testPackageDef.setTestFilter(plan.getTestFilter(testId));
+                testPkgDefs.add(testPackageDef);
             }
         } else if (mPackageNames.size() > 0){
-            Log.i(LOG_TAG, String.format("Executing CTS test packages %s", mPackageNames));
+            Log.i(LOG_TAG, String.format("Executing XTS test packages %s", mPackageNames));
+
+            Map<String, List<ITestPackageDef>> testPackageDefMap =
+                    testRepo.getTestPackageDefsByName();
+
             for (String name : mPackageNames) {
-                Set<ITestPackageDef> testPackages = testRepo.getTestPackages(name);
-                if (!testPackages.isEmpty()) {
-                    testPkgDefs.addAll(testPackages);
-                } else {
+                if (!testPackageDefMap.containsKey(name)) {
                     throw new IllegalArgumentException(String.format(
                             "Could not find test package %s. " +
-                            "Use 'list packages' to see available packages." , name));
+                                    "Use 'list packages' to see available packages.", name));
                 }
+                testPkgDefs.addAll(testPackageDefMap.get(name));
             }
         } else if (mClassName != null) {
             Log.i(LOG_TAG, String.format("Executing CTS test class %s", mClassName));
@@ -788,21 +781,18 @@
             PlanCreator planCreator = new PlanCreator(uniquePlanName, mContinueSessionId,
                     CtsTestStatus.NOT_EXECUTED);
             ITestPlan plan = createPlan(planCreator);
-            for (String packageName : plan.getTestNames()) {
-                if (mExcludedPackageNames.contains(packageName)) {
+            for (String testId : plan.getTestIds()) {
+                if (mExcludedPackageNames.contains(AbiUtils.parseTestName(testId))) {
                     continue;
                 }
-                Set<ITestPackageDef> testPackageDefSet = testRepo.getTestPackages(packageName);
-                if (testPackageDefSet.isEmpty()) {
-                    CLog.e("Could not find test package %s referenced in plan %s", packageName,
-                            mPlanName);
+                ITestPackageDef testPackageDef = testRepo.getTestPackage(testId);
+                if (testPackageDef == null) {
+                    CLog.e("Could not find test id %s referenced in plan %s", testId, mPlanName);
+                    continue;
                 }
-                for (ITestPackageDef testPackageDef : testPackageDefSet) {
-                    if (abiSet.contains(testPackageDef.getAbi().getName())) {
-                        testPackageDef.setTestFilter(plan.getTestFilter(testPackageDef.getId()));
-                        testPkgDefs.add(testPackageDef);
-                    }
-                }
+
+                testPackageDef.setTestFilter(plan.getTestFilter(testId));
+                testPkgDefs.add(testPackageDef);
             }
         } else {
             // should never get here - was checkFields() not called?
@@ -813,10 +803,11 @@
 
     /**
      * Return the list of unique prerequisite Android package names
-     * @param testPackages
+     *
+     * @param testPackages The {@link TestPackage}s that contain prerequisites
      */
     private Collection<String> getPrerequisitePackageNames(List<TestPackage> testPackages) {
-        Set<String> pkgNames = new HashSet<String>();
+        Set<String> pkgNames = new HashSet<>();
         for (TestPackage testPkg : testPackages) {
             String pkgName = testPkg.mPackageDef.getTargetPackageName();
             if (pkgName != null) {
@@ -827,12 +818,12 @@
     }
 
     /**
-     * @return a {@link Set} containing {@ITestPackageDef}s pertaining to the given
+     * @return a {@link Set} containing {@link ITestPackageDef}s pertaining to the given
      *     {@code className} and {@code methodName}.
      */
     private static Set<ITestPackageDef> buildTestPackageDefSet(
             ITestPackageRepo testRepo, String className, String methodName) {
-        Set<ITestPackageDef> testPkgDefs = new LinkedHashSet<ITestPackageDef>();
+        Set<ITestPackageDef> testPkgDefs = new LinkedHashSet<>();
         // try to find packages to run from class name
         List<String> packageIds = testRepo.findPackageIdsForTest(className);
         if (packageIds.isEmpty()) {
@@ -851,7 +842,8 @@
 
     /**
      * Return the list (by abi) of unique prerequisite apks to install
-     * @param testPackages
+     *
+     * @param testPackages The {@link List} of {@link TestPackage} that contain prerequisite APKs
      */
     private Map<String, Set<String>> getPrerequisiteApks(
             List<TestPackage> testPackages, Set<String> abiSet) {
@@ -884,7 +876,7 @@
      *
      * Install the collection of test apk file names
      *
-     * @param prerequisiteApks
+     * @param prerequisiteApks The APKs that must be installed
      * @throws DeviceNotAvailableException
      */
     private void installPrerequisiteApks(Collection<String> prerequisiteApks, IAbi abi)
@@ -910,7 +902,7 @@
     /**
      * Uninstalls the collection of android package names from device.
      *
-     * @param uninstallPackages
+     * @param uninstallPackages The packages that must be uninstalled
      */
     private void uninstallPrequisiteApks(Collection<String> uninstallPackages)
             throws DeviceNotAvailableException {
@@ -929,7 +921,7 @@
         }
         checkFields();
 
-        List<IRemoteTest> shardQueue = new LinkedList<IRemoteTest>();
+        List<IRemoteTest> shardQueue = new LinkedList<>();
         for (int shardAssignment = 0; shardAssignment < mShards; shardAssignment++) {
             CtsTest ctsTest = new CtsTest(shardAssignment, mShards /* totalShards */);
             OptionCopier.copyOptionsNoThrow(this, ctsTest);
@@ -964,8 +956,7 @@
      * Exposed for unit testing
      */
     ITestPackageRepo createTestCaseRepo() {
-        return new TestPackageRepo(mCtsBuild.getTestCasesDir(), AbiUtils.getAbisSupportedByCts(),
-                mIncludeKnownFailures);
+        return new TestPackageRepo(mCtsBuild.getTestCasesDir(), mIncludeKnownFailures);
     }
 
     /**
@@ -986,7 +977,7 @@
      */
     Set<String> getAbis() throws DeviceNotAvailableException {
         String bitness = (mForceAbi == null) ? "" : mForceAbi;
-        Set<String> abis = new HashSet<String>();
+        Set<String> abis = new HashSet<>();
         for (String abi : AbiFormatter.getSupportedAbis(mDevice, bitness)) {
             if (AbiUtils.isAbiSupportedByCts(abi)) {
                 abis.add(abi);
@@ -1057,10 +1048,10 @@
     /**
      * Forward the digest and package name to the listener as a metric
      *
-     * @param listener
+     * @param listener Handles test results
      */
     private static void forwardPackageDetails(ITestPackageDef def, ITestInvocationListener listener) {
-        Map<String, String> metrics = new HashMap<String, String>(3);
+        Map<String, String> metrics = new HashMap<>(3);
         metrics.put(PACKAGE_NAME_METRIC, def.getName());
         metrics.put(PACKAGE_ABI_METRIC, def.getAbi().getName());
         metrics.put(PACKAGE_DIGEST_METRIC, def.getDigest());
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
index e925c91..8a5c822 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
@@ -37,12 +37,6 @@
     public String getId();
 
     /**
-     * Get the appPackageName of the test package.
-     * @return the {@link String} appPackageName
-     */
-    public String getAppPackageName();
-
-    /**
      * Creates a runnable {@link IRemoteTest} from info stored in this definition.
      *
      * @param testCaseDir {@link File} representing directory of test case data
@@ -52,22 +46,6 @@
     public IRemoteTest createTest(File testCaseDir);
 
     /**
-     * Determine if given test is defined in this package.
-     *
-     * @param testDef the {@link TestIdentifier}
-     * @return <code>true</code> if test is defined
-     */
-    public boolean isKnownTest(TestIdentifier testDef);
-
-    /**
-     * Determine if given test class is defined in this package.
-     *
-     * @param testClassName the fully qualified test class name
-     * @return <code>true</code> if test class is defined
-     */
-    public boolean isKnownTestClass(String testClassName);
-
-    /**
      * Get the collection of tests in this test package.
      */
     public Collection<TestIdentifier> getTests();
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java
index d1d4111..234f437 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java
@@ -19,7 +19,7 @@
 import com.android.cts.util.AbiUtils;
 
 import java.util.List;
-import java.util.Set;
+import java.util.Map;
 
 /**
  * Interface for accessing tests from the CTS repository.
@@ -36,12 +36,19 @@
     public ITestPackageDef getTestPackage(String id);
 
     /**
-     * Get a {@link Set} of {@link TestPackageDef} given a name
-     *
-     * @param name the string package name
-     * @return a {@link Set} of {@link TestPackageDef}
+     * @return a sorted {@link List} of all package ids found in repo.
      */
-    public Set<ITestPackageDef> getTestPackages(String name);
+    public List<String> getPackageIds();
+
+    /**
+     * @return a sorted {@link List} of test package names
+     */
+    public List<String> getPackageNames();
+
+    /**
+     * @return A {@link Map} of test package name to a {@link List} of {@link ITestPackageDef}s.
+     */
+    public Map<String, List<ITestPackageDef>> getTestPackageDefsByName();
 
     /**
      * Attempt to find the package ids for a given test class name
@@ -50,15 +57,4 @@
      * @return a {@link List} of package ids.
      */
     public List<String> findPackageIdsForTest(String testClassName);
-
-    /**
-     * @return a sorted {@link List} of all package ids found in repo.
-     */
-    public List<String> getPackageIds();
-
-    /**
-     * @return a sorted {@link List} of all package names found in repo.
-     */
-    public List<String> getPackageNames();
-
 }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ResultFilter.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ResultFilter.java
index 67a0f29..f4f2f5d 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ResultFilter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ResultFilter.java
@@ -24,9 +24,7 @@
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index 9389816..9ef6257 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -112,11 +112,7 @@
         mAppPackageName = appPackageName;
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getAppPackageName() {
+    String getAppPackageName() {
         return mAppPackageName;
     }
 
@@ -124,10 +120,6 @@
         mRunTimeArgs = runTimeArgs;
     }
 
-    String getRunTimeArgs() {
-        return mRunTimeArgs;
-    }
-
     void setAppNameSpace(String appNameSpace) {
         mAppNameSpace = appNameSpace;
     }
@@ -374,19 +366,7 @@
         return mTestFilter.filter(mTests);
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isKnownTest(TestIdentifier testDef) {
-        return mTests.contains(testDef);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isKnownTestClass(String className) {
+    boolean isKnownTestClass(String className) {
         return mTestClasses.contains(className);
     }
 
@@ -471,7 +451,7 @@
      * @return The hex encoded string.
      */
     private String toHexString(byte[] arr) {
-        StringBuffer buf = new StringBuffer(arr.length * 2);
+        StringBuilder buf = new StringBuilder(arr.length * 2);
         for (byte b : arr) {
             buf.append(String.format("%02x", b & 0xFF));
         }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java
index c1f168d..aea6613 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java
@@ -40,31 +40,21 @@
 
     private static final String LOG_TAG = "TestCaseRepo";
 
-    private final File mTestCaseDir;
-
     /** mapping of ABI to a mapping of appPackageName to test definition */
     private final Map<String, Map<String, TestPackageDef>> mTestMap;
-    /** set of ABIs */
-    private final Set<String> mAbis;
     private final boolean mIncludeKnownFailures;
 
     /**
      * Creates a {@link TestPackageRepo}, initialized from provided repo files
      *
      * @param testCaseDir directory containing all test case definition xml and build files
-     * @param abis Holds the ABIs which the test must be run against. This must be a subset of the
      * ABIs supported by the device under test.
      * @param includeKnownFailures Whether to run tests which are known to fail.
      */
-    public TestPackageRepo(File testCaseDir, Set<String> abis, boolean includeKnownFailures) {
-        mTestCaseDir = testCaseDir;
-        mTestMap = new HashMap<String, Map<String, TestPackageDef>>();
-        mAbis = abis;
-        for (String abi : abis) {
-            mTestMap.put(abi, new HashMap<String, TestPackageDef>());
-        }
+    public TestPackageRepo(File testCaseDir, boolean includeKnownFailures) {
+        mTestMap = new HashMap<>();
         mIncludeKnownFailures = includeKnownFailures;
-        parse(mTestCaseDir);
+        parse(testCaseDir);
     }
 
     /**
@@ -78,25 +68,22 @@
     }
 
     private void parseTestFromXml(File xmlFile)  {
-        TestPackageXmlParser parser = new TestPackageXmlParser(mAbis, mIncludeKnownFailures);
+        TestPackageXmlParser parser = new TestPackageXmlParser(mIncludeKnownFailures);
         try {
             parser.parse(createStreamFromFile(xmlFile));
             Set<TestPackageDef> defs = parser.getTestPackageDefs();
-            if (!defs.isEmpty()) {
-                for (TestPackageDef def : defs) {
-                    String name = def.getAppPackageName();
-                    String abi = def.getAbi().getName();
-                    if (def.getTests().size() > 0) {
-                        mTestMap.get(abi).put(name, def);
-                    } else {
-                        Log.d(LOG_TAG, String.format("No tests in %s for %s, skipping",
-                                name, abi));
-                    }
-                }
-            } else {
+            if (defs.isEmpty()) {
                 Log.w(LOG_TAG, String.format("Could not find test package info in xml file %s",
                         xmlFile.getAbsolutePath()));
             }
+            for (TestPackageDef def : defs) {
+                String name = def.getAppPackageName();
+                String abi = def.getAbi().getName();
+                if (!mTestMap.containsKey(abi)) {
+                    mTestMap.put(abi, new HashMap<String, TestPackageDef>());
+                }
+                mTestMap.get(abi).put(name, def);
+            }
         } catch (FileNotFoundException e) {
             Log.e(LOG_TAG, String.format("Could not find test case xml file %s",
                     xmlFile.getAbsolutePath()));
@@ -113,7 +100,7 @@
      * <p/>
      * Exposed for unit testing
      *
-     * @param xmlFile
+     * @param xmlFile The file containing the xml description of the package
      * @return stream to read data
      *
      */
@@ -150,14 +137,54 @@
      * {@inheritDoc}
      */
     @Override
-    public Set<ITestPackageDef> getTestPackages(String appPackageName) {
-        Set<ITestPackageDef> defs = new HashSet<ITestPackageDef>();
-        for (String abi : mAbis) {
-            if (mTestMap.get(abi).containsKey(appPackageName)) {
-                defs.add(mTestMap.get(abi).get(appPackageName));
+    public List<String> getPackageIds() {
+        Set<String> ids = new HashSet<>();
+        for (String abi : mTestMap.keySet()) {
+            Map<String, TestPackageDef> testNameMap = mTestMap.get(abi);
+            for (TestPackageDef testPackageDef : testNameMap.values()) {
+                ids.add(testPackageDef.getId());
             }
         }
-        return defs;
+        List<String> idList = new ArrayList<>(ids);
+        Collections.sort(idList);
+        return idList;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<String> getPackageNames() {
+        Set<String> nameSet = new HashSet<String>();
+        for (String abi : mTestMap.keySet()) {
+            Map<String, TestPackageDef> testNameMap = mTestMap.get(abi);
+            for (TestPackageDef testPackageDef : testNameMap.values()) {
+                nameSet.add(AbiUtils.parseTestName(testPackageDef.getId()));
+            }
+        }
+        List<String> nameList = new ArrayList<>(nameSet);
+        Collections.sort(nameList);
+        return nameList;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Map<String, List<ITestPackageDef>> getTestPackageDefsByName() {
+        Map<String, List<ITestPackageDef>> packageDefMap =
+                new HashMap<String, List<ITestPackageDef>>();
+
+        for (String abi : mTestMap.keySet()) {
+            Map<String, TestPackageDef> testNameMap = mTestMap.get(abi);
+            for (String packageName : testNameMap.keySet()) {
+                if (!packageDefMap.containsKey(packageName)) {
+                    packageDefMap.put(packageName, new ArrayList<ITestPackageDef>());
+                }
+                packageDefMap.get(packageName).add(testNameMap.get(packageName));
+            }
+        }
+        return packageDefMap;
     }
 
     /**
@@ -177,34 +204,4 @@
         Collections.sort(idList);
         return idList;
     }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public List<String> getPackageIds() {
-        Set<String> ids = new HashSet<String>();
-        for (String abi : mAbis) {
-            for (String name : mTestMap.get(abi).keySet()) {
-                ids.add(AbiUtils.createId(abi, name));
-            }
-        }
-        List<String> idList = new ArrayList<String>(ids);
-        Collections.sort(idList);
-        return idList;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public List<String> getPackageNames() {
-        Set<String> names = new HashSet<String>();
-        for (String abi : mAbis) {
-            names.addAll(mTestMap.get(abi).keySet());
-        }
-        List<String> packageNames = new ArrayList<String>(names);
-        Collections.sort(packageNames);
-        return packageNames;
-    }
 }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
index 8f4f1b0..baceb8b 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
@@ -40,18 +40,14 @@
 
     private static final String LOG_TAG = "TestPackageXmlParser";
 
-    private final Set<String> mAbis;
     private final boolean mIncludeKnownFailures;
 
     private Map<String, TestPackageDef> mPackageDefs = new HashMap<String, TestPackageDef>();
 
     /**
-     * @param abis Holds the ABIs which the test must be run against. This must be a subset of the
-     * ABIs supported by the device under test.
      * @param includeKnownFailures Whether to run tests which are known to fail.
      */
-    public TestPackageXmlParser(Set<String> abis, boolean includeKnownFailures) {
-        mAbis = abis;
+    public TestPackageXmlParser(boolean includeKnownFailures) {
         mIncludeKnownFailures = includeKnownFailures;
     }
 
@@ -88,7 +84,7 @@
                 final String runTimeArgs = attributes.getValue("runtimeArgs");
                 final String testType = getTestType(attributes);
 
-                for (String abiName : mAbis) {
+                for (String abiName : AbiUtils.getAbisSupportedByCts()) {
                     Abi abi = new Abi(abiName, AbiUtils.getBitness(abiName));
                     TestPackageDef packageDef = new TestPackageDef();
                     packageDef.setAppPackageName(appPackageName);
@@ -154,13 +150,11 @@
                         Set<String> abis = new HashSet<String>();
                         if (abiList == null) {
                             // If no specification, add all supported abis
-                            abis.addAll(mAbis);
+                            abis.addAll(AbiUtils.getAbisSupportedByCts());
                         } else {
-                            for (String abi : abiList.split(", ")) {
-                                if (mAbis.contains(abi)) {
-                                    // Else only add the abi which are supported
-                                    abis.add(abi);
-                                }
+                            for (String abi : abiList.split(",")) {
+                                // Else only add the abi which are supported
+                                abis.add(abi.trim());
                             }
                         }
                         for (String abi : abis) {
@@ -206,9 +200,9 @@
     }
 
     /**
-     * @returns the set of {@link TestPackageDef} containing data parsed from xml
+     * @return the set of {@link TestPackageDef} containing data parsed from xml
      */
     public Set<TestPackageDef> getTestPackageDefs() {
-        return new HashSet<TestPackageDef>(mPackageDefs.values());
+        return new HashSet<>(mPackageDefs.values());
     }
 }
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java
index b6604e5..30e2ba8 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java
@@ -35,8 +35,10 @@
 import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -81,7 +83,7 @@
         mMockDevice = EasyMock.createMock(ITestDevice.class);
         mMockListener = EasyMock.createNiceMock(ITestInvocationListener.class);
         mStubBuildHelper = new StubCtsBuildHelper();
-        mMockPackageDefs = new HashSet<ITestPackageDef>();
+        mMockPackageDefs = new HashSet<>();
         mMockPackageDef = EasyMock.createMock(ITestPackageDef.class);
         mMockPackageDefs.add(mMockPackageDef);
         EasyMock.expect(mMockPackageDef.getTargetApkName()).andStubReturn(null);
@@ -124,7 +126,7 @@
      */
     @SuppressWarnings("unchecked")
     public void testRun_plan() throws DeviceNotAvailableException, ParseException {
-        setParsePlanExceptations();
+        setParsePlanExpectations();
 
         setCreateAndRunTestExpectations();
 
@@ -139,6 +141,12 @@
     @SuppressWarnings("unchecked")
     public void testRun_package() throws DeviceNotAvailableException {
         mCtsTest.addPackageName(PACKAGE_NAME);
+        Map<String, List<ITestPackageDef>> nameMap = new HashMap<>();
+        List<ITestPackageDef> testPackageDefList = new ArrayList<>();
+        testPackageDefList.add(mMockPackageDef);
+        nameMap.put(PACKAGE_NAME, testPackageDefList);
+
+        EasyMock.expect(mMockRepo.getTestPackageDefsByName()).andReturn(nameMap);
 
         setCreateAndRunTestExpectations();
 
@@ -153,7 +161,12 @@
     @SuppressWarnings("unchecked")
     public void testRun_resume() throws DeviceNotAvailableException {
         mCtsTest.addPackageName(PACKAGE_NAME);
+        Map<String, List<ITestPackageDef>> nameMap = new HashMap<>();
+        List<ITestPackageDef> testPackageDefList = new ArrayList<>();
+        testPackageDefList.add(mMockPackageDef);
+        nameMap.put(PACKAGE_NAME, testPackageDefList);
 
+        EasyMock.expect(mMockRepo.getTestPackageDefsByName()).andReturn(nameMap);
         setCreateAndRunTestExpectations();
         // abort the first run
         EasyMock.expectLastCall().andThrow(new DeviceNotAvailableException());
@@ -219,7 +232,7 @@
     public void testRun_excludedPackage() throws DeviceNotAvailableException, ParseException {
         mCtsTest.setPlanName(PLAN_NAME);
         mMockPlan.parse((InputStream) EasyMock.anyObject());
-        EasyMock.expect(mMockPlan.getTestNames()).andReturn(NAMES);
+        EasyMock.expect(mMockPlan.getTestIds()).andReturn(IDS);
 
         mCtsTest.addExcludedPackageName(PACKAGE_NAME);
 
@@ -234,7 +247,7 @@
      */
     public void testRun_continueSession() throws DeviceNotAvailableException {
         mCtsTest.setContinueSessionId(1);
-        EasyMock.expect(mMockPlan.getTestNames()).andReturn(NAMES);
+        EasyMock.expect(mMockPlan.getTestIds()).andReturn(IDS);
         TestFilter filter = new TestFilter();
         EasyMock.expect(mMockPlan.getTestFilter(ID)).andReturn(filter);
 
@@ -250,10 +263,10 @@
     /**
      * Set EasyMock expectations for parsing {@link #PLAN_NAME}
      */
-    private void setParsePlanExceptations() throws ParseException {
+    private void setParsePlanExpectations() throws ParseException {
         mCtsTest.setPlanName(PLAN_NAME);
         mMockPlan.parse((InputStream) EasyMock.anyObject());
-        EasyMock.expect(mMockPlan.getTestNames()).andReturn(NAMES);
+        EasyMock.expect(mMockPlan.getTestIds()).andReturn(IDS);
         TestFilter filter = new TestFilter();
         EasyMock.expect(mMockPlan.getTestFilter(ID)).andReturn(filter);
         mMockPackageDef.setTestFilter(filter);
@@ -265,10 +278,9 @@
     private void setCreateAndRunTestExpectations() throws DeviceNotAvailableException {
         EasyMock.expect(mMockRepo.getPackageNames()).andReturn(NAMES).anyTimes();
         EasyMock.expect(mMockRepo.getPackageIds()).andReturn(IDS).anyTimes();
-        EasyMock.expect(mMockRepo.getTestPackages(PACKAGE_NAME)).andReturn(mMockPackageDefs).anyTimes();
         EasyMock.expect(mMockRepo.getTestPackage(ID)).andReturn(mMockPackageDef).anyTimes();
         EasyMock.expect(mMockPackageDef.createTest((File) EasyMock.anyObject())).andReturn(mMockTest);
-        EasyMock.expect(mMockPackageDef.getTests()).andReturn(TEST_IDENTIFIER_LIST);
+        EasyMock.expect(mMockPackageDef.getTests()).andReturn(TEST_IDENTIFIER_LIST).times(2);
         EasyMock.expect(mMockPackageDef.getName()).andReturn(PACKAGE_NAME).atLeastOnce();
         EasyMock.expect(mMockPackageDef.getAbi()).andReturn(UnitTests.ABI).atLeastOnce();
         EasyMock.expect(mMockPackageDef.getId()).andReturn(ID).atLeastOnce();
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
index 5591b65..6d87a61 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
@@ -16,29 +16,28 @@
 
 package com.android.cts.tradefed.testtype;
 
-import com.android.cts.tradefed.command.CtsConsole;
 import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
 
+import junit.framework.TestCase;
+
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.Iterator;
 
-import junit.framework.TestCase;
-
 /**
  * Unit tests for {@link TestPackageXmlParser}.
  */
 public class TestPackageXmlParserTest extends TestCase {
 
-    private static String INSTR_TEST_DATA =
+    private static final String INSTR_TEST_DATA =
         "<TestPackage AndroidFramework=\"Android 1.0\" appNameSpace=\"com.example\" " +
         "appPackageName=\"android.example\" name=\"CtsExampleTestCases\" " +
         "runner=\"android.test.InstrumentationTestRunner\" version=\"1.0\">" +
         "</TestPackage>";
 
-    private static String HOST_TEST_DATA =
+    private static final String HOST_TEST_DATA =
         "<TestPackage hostSideOnly=\"true\" >\n" +
         "    <TestSuite name=\"com\" >\n" +
         "        <TestSuite name=\"example\" >\n" +
@@ -55,23 +54,22 @@
         "    </TestSuite>\n" +
         "</TestPackage>";
 
-    private static String BAD_HOST_TEST_DATA =
+    private static final String BAD_HOST_TEST_DATA =
         "<TestPackage hostSideOnly=\"blah\" >" +
         "</TestPackage>";
 
-    private static String VM_HOST_TEST_XML = "<TestPackage vmHostTest=\"true\"></TestPackage>";
+    private static final String VM_HOST_TEST_XML =
+            "<TestPackage vmHostTest=\"true\"></TestPackage>";
 
-    private static String NATIVE_TEST_XML = "<TestPackage testType=\"native\"></TestPackage>";
+    private static final String NATIVE_TEST_XML = "<TestPackage testType=\"native\"></TestPackage>";
 
-    private static String NO_TEST_DATA =
-        "<invalid />";
+    private static final String NO_TEST_DATA = "<invalid />";
 
     /**
      * Test parsing test case xml containing an instrumentation test definition.
      */
     public void testParse_instrPackage() throws ParseException  {
-        TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
-                true);
+        TestPackageXmlParser parser = new TestPackageXmlParser(true);
         parser.parse(getStringAsStream(INSTR_TEST_DATA));
         for (TestPackageDef def : parser.getTestPackageDefs()) {
             assertEquals("com.example", def.getAppNameSpace());
@@ -85,8 +83,7 @@
      * Test parsing test case xml containing an host test attribute and test data.
      */
     public void testParse_hostTest() throws ParseException  {
-        TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
-                true);
+        TestPackageXmlParser parser = new TestPackageXmlParser(true);
         parser.parse(getStringAsStream(HOST_TEST_DATA));
         for (TestPackageDef def : parser.getTestPackageDefs()) {
             assertEquals(TestPackageDef.HOST_SIDE_ONLY_TEST, def.getTestType());
@@ -110,8 +107,7 @@
     }
 
     public void testParse_hostTest_noKnownFailures() throws ParseException  {
-        TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
-                false);
+        TestPackageXmlParser parser = new TestPackageXmlParser(false);
         parser.parse(getStringAsStream(HOST_TEST_DATA));
         for (TestPackageDef def : parser.getTestPackageDefs()) {
             assertEquals(TestPackageDef.HOST_SIDE_ONLY_TEST, def.getTestType());
@@ -134,8 +130,7 @@
      * Test parsing test case xml containing an invalid host test attribute.
      */
     public void testParse_badHostTest() throws ParseException  {
-        TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
-                true);
+        TestPackageXmlParser parser = new TestPackageXmlParser(true);
         parser.parse(getStringAsStream(BAD_HOST_TEST_DATA));
         for (TestPackageDef def : parser.getTestPackageDefs()) {
             assertFalse(TestPackageDef.HOST_SIDE_ONLY_TEST.equals(def.getTestType()));
@@ -151,8 +146,7 @@
     }
 
     private void assertTestType(String expectedType, String xml) throws ParseException {
-        TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
-                true);
+        TestPackageXmlParser parser = new TestPackageXmlParser(true);
         parser.parse(getStringAsStream(xml));
         for (TestPackageDef def : parser.getTestPackageDefs()) {
             assertEquals(expectedType, def.getTestType());
@@ -163,8 +157,7 @@
      * Test parsing a test case xml with no test package data.
      */
     public void testParse_noData() throws ParseException  {
-        TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
-                true);
+        TestPackageXmlParser parser = new TestPackageXmlParser(true);
         parser.parse(getStringAsStream(NO_TEST_DATA));
         assertTrue(parser.getTestPackageDefs().isEmpty());
     }