Filter lshal-reported HALs using CL arguments

Currently, lshal reports all available HALs (under 3 labels: binderized
services, passthrough clients, and passthrough libraries). This change
allows users to restrict the command's output to one or more of these
associations.

Bug: 68653063
Test: Manually tested lshal with/without the --types flag, and with
various permutations of the HAL types. Ensured that --debug and --neat
are still functional.

Change-Id: Idcd22746f8ec3f0d4d5d981a84400f2683a1272a
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index f23095e..3fc957b 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -567,6 +567,90 @@
     EXPECT_EQ("", err.str());
 }
 
+TEST_F(ListTest, DumpSingleHalType) {
+    const std::string expected =
+        "[fake description 0]\n"
+        "Interface            Transport Arch Thread Use Server PTR              Clients\n"
+        "a.h.foo1@1.0::IFoo/1 hwbinder  64   11/21      1      0000000000002711 2 4\n"
+        "a.h.foo2@2.0::IFoo/2 hwbinder  64   12/22      2      0000000000002712 3 5\n"
+        "\n";
+
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=binderized"})));
+    EXPECT_EQ(expected, out.str());
+    EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, DumpReorderedHalTypes) {
+    const std::string expected =
+        "[fake description 0]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo3@3.0::IFoo/3 passthrough 32   N/A        N/A    N/A 4 6\n"
+        "a.h.foo4@4.0::IFoo/4 passthrough 32   N/A        N/A    N/A 5 7\n"
+        "\n"
+        "[fake description 1]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo5@5.0::IFoo/5 passthrough 32   N/A        N/A    N/A 6 8\n"
+        "a.h.foo6@6.0::IFoo/6 passthrough 32   N/A        N/A    N/A 7 9\n"
+        "\n"
+        "[fake description 2]\n"
+        "Interface            Transport Arch Thread Use Server PTR              Clients\n"
+        "a.h.foo1@1.0::IFoo/1 hwbinder  64   11/21      1      0000000000002711 2 4\n"
+        "a.h.foo2@2.0::IFoo/2 hwbinder  64   12/22      2      0000000000002712 3 5\n"
+        "\n";
+
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=passthrough_clients",
+                                            "--types=passthrough_libs", "--types=binderized"})));
+    EXPECT_EQ(expected, out.str());
+    EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, DumpAbbreviatedHalTypes) {
+    const std::string expected =
+        "[fake description 0]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo3@3.0::IFoo/3 passthrough 32   N/A        N/A    N/A 4 6\n"
+        "a.h.foo4@4.0::IFoo/4 passthrough 32   N/A        N/A    N/A 5 7\n"
+        "\n"
+        "[fake description 1]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo5@5.0::IFoo/5 passthrough 32   N/A        N/A    N/A 6 8\n"
+        "a.h.foo6@6.0::IFoo/6 passthrough 32   N/A        N/A    N/A 7 9\n"
+        "\n";
+
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,l"})));
+    EXPECT_EQ(expected, out.str());
+    EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, DumpEmptyAndDuplicateHalTypes) {
+    const std::string expected =
+        "[fake description 0]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo3@3.0::IFoo/3 passthrough 32   N/A        N/A    N/A 4 6\n"
+        "a.h.foo4@4.0::IFoo/4 passthrough 32   N/A        N/A    N/A 5 7\n"
+        "\n"
+        "[fake description 1]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo5@5.0::IFoo/5 passthrough 32   N/A        N/A    N/A 6 8\n"
+        "a.h.foo6@6.0::IFoo/6 passthrough 32   N/A        N/A    N/A 7 9\n"
+        "\n";
+
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,l,,,l,l,c,",
+                                            "--types=passthrough_libs,passthrough_clients"})));
+    EXPECT_EQ(expected, out.str());
+    EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, UnknownHalType) {
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(1u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,a"})));
+    EXPECT_THAT(err.str(), HasSubstr("Unrecognized HAL type: a"));
+}
+
 class HelpTest : public ::testing::Test {
 public:
     void SetUp() override {