Add CTS specific console for cts-tradefed.

Change-Id: Ibe4e454e645067ccbb465ff6ccc339fd783829c0
diff --git a/tools/tradefed-host/etc/cts-tradefed b/tools/tradefed-host/etc/cts-tradefed
index f3677d5..0ca361a 100755
--- a/tools/tradefed-host/etc/cts-tradefed
+++ b/tools/tradefed-host/etc/cts-tradefed
@@ -72,5 +72,5 @@
     JAR_PATH=${JAR_PATH}:${JAR_DIR}/${JAR}
 done
 
-java -cp ${JAR_PATH} -DCTS_ROOT=${CTS_ROOT} com.android.tradefed.command.Console "$@"
+java -cp ${JAR_PATH} -DCTS_ROOT=${CTS_ROOT} com.android.cts.tradefed.command.CtsConsole "$@"
 
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
new file mode 100644
index 0000000..9c647a2
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.tradefed.command;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.tradefed.testtype.ITestCaseRepo;
+import com.android.cts.tradefed.testtype.TestCaseRepo;
+import com.android.tradefed.command.Console;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.RegexTrie;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Specialization of trade federation console that adds CTS commands to list plans and packages.
+ */
+public class CtsConsole extends Console {
+
+    private CtsBuildHelper mCtsBuild = null;
+
+
+    CtsConsole() {
+        super();
+    }
+
+    /**
+     * Adds the 'list packages' and 'list plans' commands
+     */
+    @Override
+    protected void setCustomCommands(RegexTrie<Runnable> trie, List<String> genericHelp,
+            Map<String, String> commandHelp) {
+        trie.put(new Runnable() {
+            @Override
+            public void run() {
+                CtsBuildHelper ctsBuild = getCtsBuild();
+                if (ctsBuild != null) {
+                    listPlans(ctsBuild);
+                }
+            }
+        }, LIST_PATTERN, "p(?:lans)?");
+        trie.put(new Runnable() {
+            @Override
+            public void run() {
+                CtsBuildHelper ctsBuild = getCtsBuild();
+                if (ctsBuild != null) {
+                    listPackages(ctsBuild);
+                }
+            }
+        }, LIST_PATTERN, "packages");
+
+        // find existing help for 'LIST_PATTERN' commands, and append these commands help
+        String listHelp = commandHelp.get(LIST_PATTERN);
+        if (listHelp == null) {
+            // no help? Unexpected, but soldier on
+            listHelp = new String();
+        }
+        String combinedHelp = String.format("%s" + LINE_SEPARATOR +
+                "\tp[lans]  List all CTS test plans" + LINE_SEPARATOR +
+                "\tpackages  List all CTS packages" + LINE_SEPARATOR, listHelp);
+        commandHelp.put(LIST_PATTERN, combinedHelp);
+    }
+
+    private void listPlans(CtsBuildHelper ctsBuild) {
+        FilenameFilter xmlFilter = new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".xml");
+            }
+        };
+        try {
+            for (File planFile : ctsBuild.getTestPlansDir().listFiles(xmlFilter)) {
+                printLine(FileUtil.getBaseName(planFile.getName()));
+            }
+        }
+        catch (FileNotFoundException e) {
+            printLine("Could not find CTS plan folder");
+        }
+    }
+
+    private void listPackages(CtsBuildHelper ctsBuild) {
+        ITestCaseRepo testCaseRepo = new TestCaseRepo(ctsBuild.getTestCasesDir());
+        for (String packageUri : testCaseRepo.getPackageNames()) {
+            printLine(packageUri);
+        }
+    }
+
+    private CtsBuildHelper getCtsBuild() {
+        if (mCtsBuild == null) {
+            String ctsInstallPath = System.getProperty("CTS_ROOT");
+            if (ctsInstallPath != null) {
+                mCtsBuild = new CtsBuildHelper(new File(ctsInstallPath));
+                try {
+                    mCtsBuild.validateStructure();
+                } catch (FileNotFoundException e) {
+                    printLine(String.format("Invalid cts install: %s", e.getMessage()));
+                    mCtsBuild = null;
+                }
+            } else {
+                printLine("Could not find CTS install location: CTS_ROOT env variable not set");
+            }
+        }
+        return mCtsBuild;
+    }
+
+    public static void main(String[] args) {
+        CtsConsole console = new CtsConsole();
+        console.run(args);
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestCaseRepo.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestCaseRepo.java
index ffcde46..f3930c9 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestCaseRepo.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestCaseRepo.java
@@ -16,11 +16,13 @@
 
 package com.android.cts.tradefed.testtype;
 
+import java.util.Collection;
+
 
 /**
  * Interface for accessing tests from the CTS repository.
  */
-interface ITestCaseRepo {
+public interface ITestCaseRepo {
 
     /**
      * Get a {@link TestPackageDef} given a uri
@@ -38,4 +40,9 @@
      */
     public String findPackageForTest(String testClassName);
 
+    /**
+     * Return a sorted {@link Collection} of all package names found in repo.
+     */
+    public Collection<String> getPackageNames();
+
 }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestCaseRepo.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestCaseRepo.java
index 404da4d..6b2a00d 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestCaseRepo.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestCaseRepo.java
@@ -24,13 +24,17 @@
 import java.io.FileNotFoundException;
 import java.io.FilenameFilter;
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Map;
 
 /**
  * Retrieves CTS test case definitions from the repository.
  */
-class TestCaseRepo implements ITestCaseRepo {
+public class TestCaseRepo implements ITestCaseRepo {
 
     private static final String LOG_TAG = "TestCaseRepo";
 
@@ -129,4 +133,15 @@
         }
         return null;
     }
+
+    /**
+     * Return a list of all package names found in repo.
+     * @return
+     */
+    public Collection<String> getPackageNames() {
+        List<String> packageNames = new ArrayList<String>();
+        packageNames.addAll(mTestMap.keySet());
+        Collections.sort(packageNames);
+        return packageNames;
+    }
 }