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

Commit b7ddc9e5 authored by Yifan Hong's avatar Yifan Hong
Browse files

Dump client PIDs for passthrough HALs.

* This is done with registerPassthroughClient in IServiceManager; when a
  service is retrieved through the passthrough service manager, its PID
  will be recoreded by the binderized service manager.
* The action of dumping all available dynamic libraries is now done by
  dumpAllLibraries.
Bug: 34712252
Test: lshal

Change-Id: I7f08e3255ffed0f46435843504e0e225d0d9bbc9
parent b24760fd
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ class HardwareServiceManagerMock : public HServiceManager {
                const hidl_string&,
                const sp<IServiceNotification>&));
    MOCK_METHOD1(debugDump, R<void>(debugDump_cb));
    MOCK_METHOD3(registerPassthroughClient, R<void>(
        const hidl_string&, const hidl_string&, int32_t));

};

+76 −0
Original line number Diff line number Diff line
@@ -28,7 +28,9 @@
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/ServiceManagement.h>

using ::android::sp;
using ::android::hardware::hidl_string;
using ::android::hidl::manager::V1_0::IServiceManager;

template <typename A, typename B, typename C, typename D, typename E, typename F>
void printColumn(std::stringstream &stream,
@@ -45,6 +47,21 @@ void printColumn(std::stringstream &stream,
           << endl;
}

template <typename A>
std::string join(const A &components, const std::string &separator) {
    std::stringstream out;
    bool first = true;
    for (const auto &component : components) {
        if (!first) {
            out << separator;
        }
        out << component;

        first = false;
    }
    return out.str();
}

std::string toHexString(uint64_t t) {
    std::ostringstream os;
    os << std::hex << std::setfill('0') << std::setw(16) << t;
@@ -92,6 +109,56 @@ bool getReferencedPids(
    return true;
}

void dumpAllLibraries(std::stringstream &stream, const std::string &mode,
            const sp<IServiceManager> &manager) {
    using namespace ::std;
    using namespace ::android::hardware;
    using namespace ::android::hidl::manager::V1_0;
    using namespace ::android::hidl::base::V1_0;
    auto ret = manager->list([&] (const auto &fqInstanceNames) {
        for (const auto &fqInstanceName : fqInstanceNames) {
            const auto pair = split(fqInstanceName, '/');
            const auto &serviceName = pair.first;
            const auto &instanceName = pair.second;
            printColumn(stream,
                serviceName,
                instanceName,
                mode,
                "N/A",
                "N/A",
                "N/A");
        }
    });
    if (!ret.isOk()) {
        cerr << "Error: Failed to call debugDump on defaultServiceManager(): "
             << ret.description() << endl;
    }
}

void dumpPassthrough(std::stringstream &stream, const std::string &mode,
            const sp<IServiceManager> &manager) {
    using namespace ::std;
    using namespace ::android::hardware;
    using namespace ::android::hidl::manager::V1_0;
    using namespace ::android::hidl::base::V1_0;
    auto ret = manager->debugDump([&] (const auto &infos) {
        for (const auto &info : infos) {

            printColumn(stream,
                info.interfaceName,
                info.instanceName,
                mode,
                info.clientPids.size() == 1 ? std::to_string(info.clientPids[0]) : "N/A",
                "N/A",
                join(info.clientPids, " "));
        }
    });
    if (!ret.isOk()) {
        cerr << "Error: Failed to call debugDump on defaultServiceManager(): "
             << ret.description() << endl;
    }
}

void dumpBinderized(std::stringstream &stream, const std::string &mode,
            const sp<IServiceManager> &manager) {
    using namespace ::std;
@@ -187,6 +254,15 @@ int dump() {
        cerr << "Failed to get defaultServiceManager()!" << endl;
    } else {
        dumpBinderized(stream, "hwbinder", bManager);
        // Passthrough PIDs are registered to the binderized manager as well.
        dumpPassthrough(stream, "passthrough", bManager);
    }

    auto pManager = getPassthroughServiceManager();
    if (pManager == nullptr) {
        cerr << "Failed to get getPassthroughServiceManager()!" << endl;
    } else {
        dumpAllLibraries(stream, "passthrough", pManager);
    }

    cout << stream.rdbuf();