• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 #ifndef FRAMEWORK_NATIVE_CMDS_LSHAL_LIST_COMMAND_H_
18 #define FRAMEWORK_NATIVE_CMDS_LSHAL_LIST_COMMAND_H_
19 
20 #include <getopt.h>
21 #include <stdint.h>
22 
23 #include <fstream>
24 #include <string>
25 #include <vector>
26 
27 #include <android-base/macros.h>
28 #include <android/hidl/manager/1.0/IServiceManager.h>
29 #include <hidl-util/FqInstance.h>
30 #include <vintf/HalManifest.h>
31 #include <vintf/VintfObject.h>
32 
33 #include "Command.h"
34 #include "NullableOStream.h"
35 #include "TableEntry.h"
36 #include "TextTable.h"
37 #include "utils.h"
38 
39 namespace android {
40 namespace lshal {
41 
42 class Lshal;
43 
44 struct PidInfo {
45     std::map<uint64_t, Pids> refPids; // pids that are referenced
46     uint32_t threadUsage; // number of threads in use
47     uint32_t threadCount; // number of threads total
48 };
49 
50 enum class HalType {
51     BINDERIZED_SERVICES = 0,
52     PASSTHROUGH_CLIENTS,
53     PASSTHROUGH_LIBRARIES,
54     VINTF_MANIFEST,
55     LAZY_HALS,
56 };
57 
58 class ListCommand : public Command {
59 public:
ListCommand(Lshal & lshal)60     explicit ListCommand(Lshal &lshal) : Command(lshal) {}
61     virtual ~ListCommand() = default;
62     Status main(const Arg &arg) override;
63     void usage() const override;
64     std::string getSimpleDescription() const override;
getName()65     std::string getName() const override { return GetName(); }
66 
67     static std::string GetName();
68 
69     struct RegisteredOption {
70         // short alternative, e.g. 'v'. If '\0', no short options is available.
71         char shortOption;
72         // long alternative, e.g. 'init-vintf'
73         std::string longOption;
74         // no_argument, required_argument or optional_argument
75         int hasArg;
76         // value written to 'flag' by getopt_long
77         int val;
78         // operation when the argument is present
79         std::function<Status(ListCommand* thiz, const char* arg)> op;
80         // help message
81         std::string help;
82 
83         const std::string& getHelpMessageForArgument() const;
84     };
85     // A list of acceptable command line options
86     // key: value returned by getopt_long
87     using RegisteredOptions = std::vector<RegisteredOption>;
88 
89     static std::string INIT_VINTF_NOTES;
90 
91 protected:
92     Status parseArgs(const Arg &arg);
93     // Retrieve first-hand information
94     Status fetch();
95     // Retrieve derived information base on existing table
96     virtual void postprocess();
97     Status dump();
98     void putEntry(HalType type, TableEntry &&entry);
99     Status fetchPassthrough(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
100     Status fetchBinderized(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
101     Status fetchAllLibraries(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
102     Status fetchManifestHals();
103     Status fetchLazyHals();
104 
105     Status fetchBinderizedEntry(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager,
106                                 TableEntry *entry);
107 
108     // Get relevant information for a PID by parsing files under /d/binder.
109     // It is a virtual member function so that it can be mocked.
110     virtual bool getPidInfo(pid_t serverPid, PidInfo *info) const;
111     // Retrieve from mCachedPidInfos and call getPidInfo if necessary.
112     const PidInfo* getPidInfoCached(pid_t serverPid);
113 
114     void dumpTable(const NullableOStream<std::ostream>& out) const;
115     void dumpVintf(const NullableOStream<std::ostream>& out) const;
116     void addLine(TextTable *table, const std::string &interfaceName, const std::string &transport,
117                  const std::string &arch, const std::string &threadUsage, const std::string &server,
118                  const std::string &serverCmdline, const std::string &address,
119                  const std::string &clients, const std::string &clientCmdlines) const;
120     void addLine(TextTable *table, const TableEntry &entry);
121     // Read and return /proc/{pid}/cmdline.
122     virtual std::string parseCmdline(pid_t pid) const;
123     // Return /proc/{pid}/cmdline if it exists, else empty string.
124     const std::string& getCmdline(pid_t pid);
125     // Call getCmdline on all pid in pids. If it returns empty string, the process might
126     // have died, and the pid is removed from pids.
127     void removeDeadProcesses(Pids *pids);
128 
129     virtual Partition getPartition(pid_t pid);
130     Partition resolvePartition(Partition processPartition, const FqInstance &fqInstance) const;
131 
132     VintfInfo getVintfInfo(const std::string &fqInstanceName, vintf::TransportArch ta) const;
133     // Allow to mock these functions for testing.
134     virtual std::shared_ptr<const vintf::HalManifest> getDeviceManifest() const;
135     virtual std::shared_ptr<const vintf::CompatibilityMatrix> getDeviceMatrix() const;
136     virtual std::shared_ptr<const vintf::HalManifest> getFrameworkManifest() const;
137     virtual std::shared_ptr<const vintf::CompatibilityMatrix> getFrameworkMatrix() const;
138 
139     void forEachTable(const std::function<void(Table &)> &f);
140     void forEachTable(const std::function<void(const Table &)> &f) const;
141     Table* tableForType(HalType type);
142     const Table* tableForType(HalType type) const;
143 
144     NullableOStream<std::ostream> err() const;
145     NullableOStream<std::ostream> out() const;
146 
147     void registerAllOptions();
148 
149     // helper functions to dumpVintf.
150     bool addEntryWithInstance(const TableEntry &entry, vintf::HalManifest *manifest) const;
151     bool addEntryWithoutInstance(const TableEntry &entry, const vintf::HalManifest *manifest) const;
152 
153     // Helper function. Whether to fetch entries corresponding to a given HAL type.
154     bool shouldFetchHalType(const HalType &type) const;
155 
156     void initFetchTypes();
157 
158     // Helper functions ti add HALs that are listed in VINTF manifest to LAZY_HALS table.
159     bool hasHwbinderEntry(const TableEntry& entry) const;
160     bool hasPassthroughEntry(const TableEntry& entry) const;
161 
162     Table mServicesTable{};
163     Table mPassthroughRefTable{};
164     Table mImplementationsTable{};
165     Table mManifestHalsTable{};
166     Table mLazyHalsTable{};
167 
168     std::string mFileOutputPath;
169     TableEntryCompare mSortColumn = nullptr;
170 
171     bool mEmitDebugInfo = false;
172 
173     // If true, output in VINTF format. Output only entries from the specified partition.
174     bool mVintf = false;
175     Partition mVintfPartition = Partition::UNKNOWN;
176 
177     // If true, explanatory text are not emitted.
178     bool mNeat = false;
179 
180     // Type(s) of HAL associations to list.
181     std::vector<HalType> mListTypes{};
182     // Type(s) of HAL associations to fetch.
183     std::set<HalType> mFetchTypes{};
184 
185     // If an entry does not exist, need to ask /proc/{pid}/cmdline to get it.
186     // If an entry exist but is an empty string, process might have died.
187     // If an entry exist and not empty, it contains the cached content of /proc/{pid}/cmdline.
188     std::map<pid_t, std::string> mCmdlines;
189 
190     // Cache for getPidInfo.
191     std::map<pid_t, PidInfo> mCachedPidInfos;
192 
193     // Cache for getPartition.
194     std::map<pid_t, Partition> mPartitions;
195 
196     RegisteredOptions mOptions;
197     // All selected columns
198     std::vector<TableColumnType> mSelectedColumns;
199     // If true, emit cmdlines instead of PIDs
200     bool mEnableCmdlines = false;
201 
202 private:
203     DISALLOW_COPY_AND_ASSIGN(ListCommand);
204 };
205 
206 
207 }  // namespace lshal
208 }  // namespace android
209 
210 #endif  // FRAMEWORK_NATIVE_CMDS_LSHAL_LIST_COMMAND_H_
211