lshal: Add class Command.

Command is the base class for all *Command classes.

Test: lshal_test

Bug: 35389839
Change-Id: I9aca19e66824536d13e618ffd0f012ac3da9880d
diff --git a/cmds/lshal/Command.h b/cmds/lshal/Command.h
new file mode 100644
index 0000000..b1efb97
--- /dev/null
+++ b/cmds/lshal/Command.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef FRAMEWORK_NATIVE_CMDS_LSHAL_COMMAND_H_
+#define FRAMEWORK_NATIVE_CMDS_LSHAL_COMMAND_H_
+
+#include "utils.h"
+
+namespace android {
+namespace lshal {
+
+class Lshal;
+
+// Base class for all *Commands
+class Command {
+public:
+    Command(Lshal& lshal) : mLshal(lshal) {}
+    virtual ~Command() = default;
+    // Expect optind to be set by Lshal::main and points to the next argument
+    // to process.
+    virtual Status main(const std::string &command, const Arg &arg) = 0;
+
+protected:
+    Lshal& mLshal;
+};
+
+
+}  // namespace lshal
+}  // namespace android
+
+#endif  // FRAMEWORK_NATIVE_CMDS_LSHAL_LIST_COMMAND_H_
diff --git a/cmds/lshal/DebugCommand.cpp b/cmds/lshal/DebugCommand.cpp
index 672cad6..e657bcf 100644
--- a/cmds/lshal/DebugCommand.cpp
+++ b/cmds/lshal/DebugCommand.cpp
@@ -21,9 +21,6 @@
 namespace android {
 namespace lshal {
 
-DebugCommand::DebugCommand(Lshal &lshal) : mLshal(lshal) {
-}
-
 Status DebugCommand::parseArgs(const std::string &command, const Arg &arg) {
     if (optind >= arg.argc) {
         mLshal.usage(command);
diff --git a/cmds/lshal/DebugCommand.h b/cmds/lshal/DebugCommand.h
index fa0f0fa..afa5e97 100644
--- a/cmds/lshal/DebugCommand.h
+++ b/cmds/lshal/DebugCommand.h
@@ -21,6 +21,7 @@
 
 #include <android-base/macros.h>
 
+#include "Command.h"
 #include "utils.h"
 
 namespace android {
@@ -28,14 +29,14 @@
 
 class Lshal;
 
-class DebugCommand {
+class DebugCommand : public Command {
 public:
-    DebugCommand(Lshal &lshal);
-    Status main(const std::string &command, const Arg &arg);
+    DebugCommand(Lshal &lshal) : Command(lshal) {}
+    ~DebugCommand() = default;
+    Status main(const std::string &command, const Arg &arg) override;
 private:
     Status parseArgs(const std::string &command, const Arg &arg);
 
-    Lshal &mLshal;
     std::string mInterfaceName;
     std::vector<std::string> mOptions;
 
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index 4550e41..ffb4424 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -44,9 +44,6 @@
 namespace android {
 namespace lshal {
 
-ListCommand::ListCommand(Lshal &lshal) : mLshal(lshal) {
-}
-
 NullableOStream<std::ostream> ListCommand::out() const {
     return mLshal.out();
 }
diff --git a/cmds/lshal/ListCommand.h b/cmds/lshal/ListCommand.h
index 5047cf8..8d25d94 100644
--- a/cmds/lshal/ListCommand.h
+++ b/cmds/lshal/ListCommand.h
@@ -26,6 +26,7 @@
 #include <android-base/macros.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 
+#include "Command.h"
 #include "NullableOStream.h"
 #include "TableEntry.h"
 #include "TextTable.h"
@@ -42,11 +43,11 @@
     uint32_t threadCount; // number of threads total
 };
 
-class ListCommand {
+class ListCommand : public Command {
 public:
-    ListCommand(Lshal &lshal);
+    ListCommand(Lshal &lshal) : Command(lshal) {}
     virtual ~ListCommand() = default;
-    Status main(const std::string &command, const Arg &arg);
+    Status main(const std::string &command, const Arg &arg) override;
 protected:
     Status parseArgs(const std::string &command, const Arg &arg);
     Status fetch();
@@ -79,8 +80,6 @@
     NullableOStream<std::ostream> err() const;
     NullableOStream<std::ostream> out() const;
 
-    Lshal &mLshal;
-
     Table mServicesTable{};
     Table mPassthroughRefTable{};
     Table mImplementationsTable{};
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index da45d65..9c5c234 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -218,6 +218,17 @@
     }
 }
 
+std::unique_ptr<Command> Lshal::selectCommand(const std::string& command) {
+    // Default command is list
+    if (command == "list" || command == "") {
+        return std::make_unique<ListCommand>(*this);
+    }
+    if (command == "debug") {
+        return std::make_unique<DebugCommand>(*this);
+    }
+    return nullptr;
+}
+
 Status Lshal::main(const Arg &arg) {
     // Allow SIGINT to terminate all threads.
     signal(SIGINT, signalHandler);
@@ -230,12 +241,9 @@
         usage(optind < arg.argc ? arg.argv[optind] : "");
         return USAGE;
     }
-    // Default command is list
-    if (mCommand == "list" || mCommand == "") {
-        return ListCommand{*this}.main(mCommand, arg);
-    }
-    if (mCommand == "debug") {
-        return DebugCommand{*this}.main(mCommand, arg);
+    auto c = selectCommand(mCommand);
+    if (c != nullptr) {
+        return c->main(mCommand, arg);
     }
     usage();
     return USAGE;
diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h
index d3cc4e2..bfd6a40 100644
--- a/cmds/lshal/Lshal.h
+++ b/cmds/lshal/Lshal.h
@@ -24,6 +24,7 @@
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <utils/StrongPointer.h>
 
+#include "Command.h"
 #include "NullableOStream.h"
 #include "utils.h"
 
@@ -50,8 +51,12 @@
             const std::vector<std::string> &options,
             std::ostream &out,
             NullableOStream<std::ostream> err) const;
+
+    std::unique_ptr<Command> selectCommand(const std::string& command);
+
 private:
     Status parseArgs(const Arg &arg);
+
     std::string mCommand;
     Arg mCmdArgs;
     NullableOStream<std::ostream> mOut;