Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c884961 authored by Yifan Hong's avatar Yifan Hong Committed by Automerger Merge Worker
Browse files

Merge "lshal: Add --all --types=all, and use in bugreport" am: 623b87ce am:...

Merge "lshal: Add --all --types=all, and use in bugreport" am: 623b87ce am: 15c7d5fe am: 68583c2c am: 75e35c76

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1393273

Change-Id: If20e619d8616501b2a9c74ce354c4e9360865da2
parents 277d87a3 75e35c76
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -1307,12 +1307,12 @@ static Dumpstate::RunStatus RunDumpsysNormal() {


static void DumpHals() {
static void DumpHals() {
    if (!ds.IsZipping()) {
    if (!ds.IsZipping()) {
        RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z", "--debug"},
        RunCommand("HARDWARE HALS", {"lshal", "--all", "--types=all", "--debug"},
                   CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
                   CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
        return;
        return;
    }
    }
    DurationReporter duration_reporter("DUMP HALS");
    DurationReporter duration_reporter("DUMP HALS");
    RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z"},
    RunCommand("HARDWARE HALS", {"lshal", "--all", "--types=all"},
               CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
               CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());


    using android::hidl::manager::V1_0::IServiceManager;
    using android::hidl::manager::V1_0::IServiceManager;
+70 −40
Original line number Original line Diff line number Diff line
@@ -916,6 +916,18 @@ void ListCommand::initFetchTypes() {
    }
    }
}
}


// Get all values of enum type T, assuming the first value is 0 and the last value is T::LAST.
// T::LAST is not included in the returned list.
template <typename T>
std::vector<T> GetAllValues() {
    using BaseType = std::underlying_type_t<T>;
    std::vector<T> ret;
    for (BaseType i = 0; i < static_cast<BaseType>(T::LAST); ++i) {
        ret.push_back(static_cast<T>(i));
    }
    return ret;
}

void ListCommand::registerAllOptions() {
void ListCommand::registerAllOptions() {
    int v = mOptions.size();
    int v = mOptions.size();
    // A list of acceptable command line options
    // A list of acceptable command line options
@@ -989,6 +1001,15 @@ void ListCommand::registerAllOptions() {
       "    - declared: only declared in VINTF manifest but is not registered to hwservicemanager;\n"
       "    - declared: only declared in VINTF manifest but is not registered to hwservicemanager;\n"
       "    - N/A: no information for passthrough HALs."});
       "    - N/A: no information for passthrough HALs."});


    mOptions.push_back({'A', "all", no_argument, v++,
                        [](ListCommand* thiz, const char*) {
                            auto allColumns = GetAllValues<TableColumnType>();
                            thiz->mSelectedColumns.insert(thiz->mSelectedColumns.end(),
                                                          allColumns.begin(), allColumns.end());
                            return OK;
                        },
                        "print all columns"});

    // long options without short alternatives
    // long options without short alternatives
    mOptions.push_back({'\0', "init-vintf", no_argument, v++, [](ListCommand* thiz, const char* arg) {
    mOptions.push_back({'\0', "init-vintf", no_argument, v++, [](ListCommand* thiz, const char* arg) {
        thiz->mVintf = true;
        thiz->mVintf = true;
@@ -1019,20 +1040,26 @@ void ListCommand::registerAllOptions() {
        thiz->mNeat = true;
        thiz->mNeat = true;
        return OK;
        return OK;
    }, "output is machine parsable (no explanatory text).\nCannot be used with --debug."});
    }, "output is machine parsable (no explanatory text).\nCannot be used with --debug."});
    mOptions.push_back({'\0', "types", required_argument, v++, [](ListCommand* thiz, const char* arg) {
    mOptions.push_back(
        if (!arg) { return USAGE; }
            {'\0', "types", required_argument, v++,

             [](ListCommand* thiz, const char* arg) {
        static const std::map<std::string, HalType> kHalTypeMap {
                 if (!arg) {
            {"binderized", HalType::BINDERIZED_SERVICES},
                     return USAGE;
            {"b", HalType::BINDERIZED_SERVICES},
                 }
            {"passthrough_clients", HalType::PASSTHROUGH_CLIENTS},

            {"c", HalType::PASSTHROUGH_CLIENTS},
                 static const std::map<std::string, std::vector<HalType>> kHalTypeMap{
            {"passthrough_libs", HalType::PASSTHROUGH_LIBRARIES},
                         {"binderized", {HalType::BINDERIZED_SERVICES}},
            {"l", HalType::PASSTHROUGH_LIBRARIES},
                         {"b", {HalType::BINDERIZED_SERVICES}},
            {"vintf", HalType::VINTF_MANIFEST},
                         {"passthrough_clients", {HalType::PASSTHROUGH_CLIENTS}},
            {"v", HalType::VINTF_MANIFEST},
                         {"c", {HalType::PASSTHROUGH_CLIENTS}},
            {"lazy", HalType::LAZY_HALS},
                         {"passthrough_libs", {HalType::PASSTHROUGH_LIBRARIES}},
            {"z", HalType::LAZY_HALS},
                         {"l", {HalType::PASSTHROUGH_LIBRARIES}},
                         {"vintf", {HalType::VINTF_MANIFEST}},
                         {"v", {HalType::VINTF_MANIFEST}},
                         {"lazy", {HalType::LAZY_HALS}},
                         {"z", {HalType::LAZY_HALS}},
                         {"all", GetAllValues<HalType>()},
                         {"a", GetAllValues<HalType>()},
                 };
                 };


                 std::vector<std::string> halTypesArgs = split(std::string(arg), ',');
                 std::vector<std::string> halTypesArgs = split(std::string(arg), ',');
@@ -1041,24 +1068,27 @@ void ListCommand::registerAllOptions() {


                     const auto& halTypeIter = kHalTypeMap.find(halTypeArg);
                     const auto& halTypeIter = kHalTypeMap.find(halTypeArg);
                     if (halTypeIter == kHalTypeMap.end()) {
                     if (halTypeIter == kHalTypeMap.end()) {

                         thiz->err() << "Unrecognized HAL type: " << halTypeArg << std::endl;
                         thiz->err() << "Unrecognized HAL type: " << halTypeArg << std::endl;
                         return USAGE;
                         return USAGE;
                     }
                     }


                     // Append unique (non-repeated) HAL types to the reporting list
                     // Append unique (non-repeated) HAL types to the reporting list
            HalType halType = halTypeIter->second;
                     for (auto halType : halTypeIter->second) {
                         if (std::find(thiz->mListTypes.begin(), thiz->mListTypes.end(), halType) ==
                         if (std::find(thiz->mListTypes.begin(), thiz->mListTypes.end(), halType) ==
                             thiz->mListTypes.end()) {
                             thiz->mListTypes.end()) {
                             thiz->mListTypes.push_back(halType);
                             thiz->mListTypes.push_back(halType);
                         }
                         }
                     }
                     }
                 }


        if (thiz->mListTypes.empty()) { return USAGE; }
                 if (thiz->mListTypes.empty()) {
                     return USAGE;
                 }
                 return OK;
                 return OK;
    }, "comma-separated list of one or more sections.\nThe output is restricted to the selected "
             },
       "section(s). Valid options\nare: (b|binderized), (c|passthrough_clients), (l|"
             "comma-separated list of one or more sections.\nThe output is restricted to the "
       "passthrough_libs), (v|vintf), and (z|lazy).\nDefault is `bcl`."});
             "selected section(s). Valid options\nare: (b|binderized), (c|passthrough_clients), (l|"
             "passthrough_libs), (v|vintf), (z|lazy), and (a|all).\nDefault is `b,c,l`."});
}
}


// Create 'longopts' argument to getopt_long. Caller is responsible for maintaining
// Create 'longopts' argument to getopt_long. Caller is responsible for maintaining
+3 −0
Original line number Original line Diff line number Diff line
@@ -52,6 +52,9 @@ enum class HalType {
    PASSTHROUGH_LIBRARIES,
    PASSTHROUGH_LIBRARIES,
    VINTF_MANIFEST,
    VINTF_MANIFEST,
    LAZY_HALS,
    LAZY_HALS,

    // Not a real HalType. Used to determine all HalTypes.
    LAST,
};
};


class ListCommand : public Command {
class ListCommand : public Command {
+10 −4
Original line number Original line Diff line number Diff line
@@ -35,19 +35,25 @@ using android::procpartition::Partition;
using Pids = std::vector<int32_t>;
using Pids = std::vector<int32_t>;


enum class TableColumnType : unsigned int {
enum class TableColumnType : unsigned int {
    INTERFACE_NAME,
    INTERFACE_NAME = 0,
    TRANSPORT,
    TRANSPORT,
    SERVER_PID,
    SERVER_PID,
    SERVER_CMD,
    SERVER_ADDR,
    SERVER_ADDR,
    CLIENT_PIDS,
    CLIENT_CMDS,
    ARCH,
    ARCH,
    THREADS,
    THREADS,
    RELEASED,
    RELEASED,
    HASH,
    HASH,
    VINTF,
    VINTF,
    SERVICE_STATUS,
    SERVICE_STATUS,
    CLIENT_PIDS,

    // Not a real TableColumnType. Used to determine all TableColumnTypes.
    LAST,

    // Not included in all TableColumnTypes because they replace *PID(S) when the
    // --cmdline option is set.
    SERVER_CMD,
    CLIENT_CMDS,
};
};


enum : unsigned int {
enum : unsigned int {
+67 −2
Original line number Original line Diff line number Diff line
@@ -708,8 +708,8 @@ TEST_F(ListTest, DumpEmptyAndDuplicateHalTypes) {


TEST_F(ListTest, UnknownHalType) {
TEST_F(ListTest, UnknownHalType) {
    optind = 1; // mimic Lshal::parseArg()
    optind = 1; // mimic Lshal::parseArg()
    EXPECT_EQ(1u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,a"})));
    EXPECT_EQ(1u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,r"})));
    EXPECT_THAT(err.str(), HasSubstr("Unrecognized HAL type: a"));
    EXPECT_THAT(err.str(), HasSubstr("Unrecognized HAL type: r"));
}
}


TEST_F(ListTest, Vintf) {
TEST_F(ListTest, Vintf) {
@@ -793,6 +793,71 @@ TEST_F(ListTest, Vintf) {
    EXPECT_EQ("", err.str());
    EXPECT_EQ("", err.str());
}
}


TEST_F(ListTest, AllColumns) {
    // clang-format off
    const std::string expected =
        "[fake description 0]\n"
        "Interface            Transport Server PTR              Arch Thread Use R Hash                                                             VINTF Status Clients\n"
        "a.h.foo1@1.0::IFoo/1 hwbinder  1      0000000000002711 64   11/21      N 0000000000000000000000000000000000000000000000000000000000000000 X     alive  2 4\n"
        "a.h.foo2@2.0::IFoo/2 hwbinder  2      0000000000002712 64   12/22      Y 0202020202020202020202020202020202020202020202020202020202020202 X     alive  3 5\n"
        "\n"
        "[fake description 1]\n"
        "Interface            Transport   Server PTR Arch Thread Use R Hash VINTF Status Clients\n"
        "a.h.foo3@3.0::IFoo/3 passthrough N/A    N/A 32   N/A        ?      X     N/A    4 6\n"
        "a.h.foo4@4.0::IFoo/4 passthrough N/A    N/A 32   N/A        ?      X     N/A    5 7\n"
        "\n"
        "[fake description 2]\n"
        "Interface            Transport   Server PTR Arch Thread Use R Hash VINTF Status Clients\n"
        "a.h.foo5@5.0::IFoo/5 passthrough N/A    N/A 32   N/A        ?      X     N/A    6 8\n"
        "a.h.foo6@6.0::IFoo/6 passthrough N/A    N/A 32   N/A        ?      X     N/A    7 9\n"
        "\n";
    // clang-format on

    optind = 1; // mimic Lshal::parseArg()
    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "--all"})));
    EXPECT_EQ(expected, out.str());
    EXPECT_EQ("", err.str());
}

TEST_F(ListTest, AllColumnsWithCmd) {
    // clang-format off
    const std::string expected =
        "[fake description 0]\n"
        "Interface            Transport Server CMD     PTR              Arch Thread Use R Hash                                                             VINTF Status Clients CMD\n"
        "a.h.foo1@1.0::IFoo/1 hwbinder  command_line_1 0000000000002711 64   11/21      N 0000000000000000000000000000000000000000000000000000000000000000 X     alive  command_line_2;command_line_4\n"
        "a.h.foo2@2.0::IFoo/2 hwbinder  command_line_2 0000000000002712 64   12/22      Y 0202020202020202020202020202020202020202020202020202020202020202 X     alive  command_line_3;command_line_5\n"
        "\n"
        "[fake description 1]\n"
        "Interface            Transport   Server CMD PTR Arch Thread Use R Hash VINTF Status Clients CMD\n"
        "a.h.foo3@3.0::IFoo/3 passthrough            N/A 32   N/A        ?      X     N/A    command_line_4;command_line_6\n"
        "a.h.foo4@4.0::IFoo/4 passthrough            N/A 32   N/A        ?      X     N/A    command_line_5;command_line_7\n"
        "\n"
        "[fake description 2]\n"
        "Interface            Transport   Server CMD PTR Arch Thread Use R Hash VINTF Status Clients CMD\n"
        "a.h.foo5@5.0::IFoo/5 passthrough            N/A 32   N/A        ?      X     N/A    command_line_6;command_line_8\n"
        "a.h.foo6@6.0::IFoo/6 passthrough            N/A 32   N/A        ?      X     N/A    command_line_7;command_line_9\n"
        "\n";
    // clang-format on

    optind = 1; // mimic Lshal::parseArg()
    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-Am"})));
    EXPECT_EQ(expected, out.str());
    EXPECT_EQ("", err.str());
}

TEST_F(ListTest, AllSections) {
    optind = 1; // mimic Lshal::parseArg()
    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "--types=all"})));
    using HalTypeBase = std::underlying_type_t<HalType>;
    for (HalTypeBase i = 0; i < static_cast<HalTypeBase>(HalType::LAST); ++i) {
        EXPECT_THAT(out.str(), HasSubstr("[fake description " + std::to_string(i) + "]"));
    }
    EXPECT_THAT(out.str(),
                Not(HasSubstr("[fake description " +
                              std::to_string(static_cast<HalTypeBase>(HalType::LAST)) + "]")));
    EXPECT_EQ("", err.str());
}

// Fake service returned by mocked IServiceManager::get for DumpDebug.
// Fake service returned by mocked IServiceManager::get for DumpDebug.
// The interfaceChain and getHashChain functions returns
// The interfaceChain and getHashChain functions returns
// foo(id - 1) -> foo(id - 2) -> ... foo1 -> IBase.
// foo(id - 1) -> foo(id - 2) -> ... foo1 -> IBase.