blob: bc8bf39d0e10000023cea7e56b1bfcb79fe2790a [file] [log] [blame]
Yifan Hong85dd3ad2017-01-25 14:20:34 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18#include <getopt.h>
19
20#include <map>
21#include <iomanip>
22#include <iostream>
23#include <sstream>
24
25#include <android/hidl/manager/1.0/IServiceManager.h>
26#include <hidl/ServiceManagement.h>
27
28template <typename A, typename B, typename C, typename D>
29void printColumn(std::stringstream &stream,
30 const A &a, const B &b, const C &c, const D &d) {
31 using namespace ::std;
32 stream << left
33 << setw(70) << a << "\t"
34 << setw(20) << b << "\t"
35 << setw(10) << c << "\t"
36 << setw(5) << d << "\t"
37 << endl;
38}
39
40int dump() {
41 using namespace ::std;
42 using namespace ::android::hardware;
43 using namespace ::android::hidl::manager::V1_0;
44
45 std::map<std::string, ::android::sp<IServiceManager>> mapping = {
46 {"hwbinder", defaultServiceManager()},
47 {"passthrough", getPassthroughServiceManager()}
48 };
49
50 std::stringstream stream;
51
52 stream << "All services:" << endl;
53 stream << left;
54 printColumn(stream, "Interface", "Instance", "Transport", "Ref");
55
56 for (const auto &pair : mapping) {
57 const std::string &mode = pair.first;
58 const ::android::sp<IServiceManager> &manager = pair.second;
59
60 if (manager == nullptr) {
61 cerr << "Failed to get IServiceManager for " << mode << "!" << endl;
62 continue;
63 }
64
65 auto ret = manager->debugDump([&](const auto &registered) {
66 for (const auto &info : registered) {
67 printColumn(stream,
68 info.interfaceName,
69 info.instanceName.empty() ? "N/A" : info.instanceName,
70 mode,
71 info.refCount == 0 ? "N/A" : std::to_string(info.refCount - 1));
72 }
73 });
74 if (!ret.isOk()) {
75 cerr << "Failed to list services for " << mode << ": "
76 << ret.description() << endl;
77 }
78 }
79 cout << stream.rdbuf();
80 return 0;
81}
82
83int usage() {
84 using namespace ::std;
85 cerr
86 << "usage: lshal" << endl
87 << " To dump all hals." << endl
88 << "or:" << endl
89 << " lshal [-h|--help]" << endl
90 << " -h, --help: show this help information." << endl;
91 return -1;
92}
93
94int main(int argc, char **argv) {
95 static struct option longOptions[] = {
96 {"help", no_argument, 0, 'h' },
97 { 0, 0, 0, 0 }
98 };
99
100 int optionIndex;
101 int c;
102 optind = 1;
103 for (;;) {
104 // using getopt_long in case we want to add other options in the future
105 c = getopt_long(argc, argv, "h", longOptions, &optionIndex);
106 if (c == -1) {
107 break;
108 }
109 switch (c) {
110 case 'h': // falls through
111 default: // see unrecognized options
112 return usage();
113 }
114 }
115 return dump();
116
117}