OSDN Git Service

Add an lshal command.
authorYifan Hong <elsk@google.com>
Wed, 25 Jan 2017 22:20:34 +0000 (14:20 -0800)
committerYifan Hong <elsk@google.com>
Thu, 26 Jan 2017 07:08:49 +0000 (23:08 -0800)
lshal lists services registered to the binderized
IServiceManager and all services available to the
passthrough IServiceManager as *.so libraries. It
also dumps the reference count for each service.

Bug: 34712252
Test: adb shell lshal
Change-Id: I9436a033cf736b8a8c307a2e87549c9db6379f3f

cmds/lshal/Android.bp [new file with mode: 0644]
cmds/lshal/lshal.cpp [new file with mode: 0644]

diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
new file mode 100644 (file)
index 0000000..dd8104d
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright (C) 2016 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.
+
+cc_binary {
+    name: "lshal",
+    shared_libs: [
+        "libutils",
+        "libhidlbase",
+        "android.hidl.manager@1.0",
+        "libhidltransport",
+    ],
+    srcs: [
+        "lshal.cpp"
+    ],
+}
diff --git a/cmds/lshal/lshal.cpp b/cmds/lshal/lshal.cpp
new file mode 100644 (file)
index 0000000..bc8bf39
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+
+#include <getopt.h>
+
+#include <map>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <hidl/ServiceManagement.h>
+
+template <typename A, typename B, typename C, typename D>
+void printColumn(std::stringstream &stream,
+        const A &a, const B &b, const C &c, const D &d) {
+    using namespace ::std;
+    stream << left
+           << setw(70) << a << "\t"
+           << setw(20) << b << "\t"
+           << setw(10) << c << "\t"
+           << setw(5)  << d << "\t"
+           << endl;
+}
+
+int dump() {
+    using namespace ::std;
+    using namespace ::android::hardware;
+    using namespace ::android::hidl::manager::V1_0;
+
+    std::map<std::string, ::android::sp<IServiceManager>> mapping = {
+            {"hwbinder", defaultServiceManager()},
+            {"passthrough", getPassthroughServiceManager()}
+    };
+
+    std::stringstream stream;
+
+    stream << "All services:" << endl;
+    stream << left;
+    printColumn(stream, "Interface", "Instance", "Transport", "Ref");
+
+    for (const auto &pair : mapping) {
+        const std::string &mode = pair.first;
+        const ::android::sp<IServiceManager> &manager = pair.second;
+
+        if (manager == nullptr) {
+            cerr << "Failed to get IServiceManager for " << mode << "!" << endl;
+            continue;
+        }
+
+        auto ret = manager->debugDump([&](const auto &registered) {
+            for (const auto &info : registered) {
+                printColumn(stream,
+                    info.interfaceName,
+                    info.instanceName.empty() ? "N/A" : info.instanceName,
+                    mode,
+                    info.refCount == 0 ? "N/A" : std::to_string(info.refCount - 1));
+            }
+        });
+        if (!ret.isOk()) {
+            cerr << "Failed to list services for " << mode << ": "
+                 << ret.description() << endl;
+        }
+    }
+    cout << stream.rdbuf();
+    return 0;
+}
+
+int usage() {
+    using namespace ::std;
+    cerr
+        << "usage: lshal" << endl
+        << "           To dump all hals." << endl
+        << "or:" << endl
+        << "       lshal [-h|--help]" << endl
+        << "           -h, --help: show this help information." << endl;
+    return -1;
+}
+
+int main(int argc, char **argv) {
+    static struct option longOptions[] = {
+        {"help", no_argument, 0, 'h' },
+        { 0,               0, 0,  0  }
+    };
+
+    int optionIndex;
+    int c;
+    optind = 1;
+    for (;;) {
+        // using getopt_long in case we want to add other options in the future
+        c = getopt_long(argc, argv, "h", longOptions, &optionIndex);
+        if (c == -1) {
+            break;
+        }
+        switch (c) {
+        case 'h': // falls through
+        default: // see unrecognized options
+            return usage();
+        }
+    }
+    return dump();
+
+}