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/FQName.h> 30 31#include "Command.h" 32#include "NullableOStream.h" 33#include "TableEntry.h" 34#include "TextTable.h" 35#include "utils.h" 36 37namespace android { 38namespace lshal { 39 40class Lshal; 41 42struct PidInfo { 43 std::map<uint64_t, Pids> refPids; // pids that are referenced 44 uint32_t threadUsage; // number of threads in use 45 uint32_t threadCount; // number of threads total 46}; 47 48class ListCommand : public Command { 49public: 50 ListCommand(Lshal &lshal) : Command(lshal) {} 51 virtual ~ListCommand() = default; 52 Status main(const Arg &arg) override; 53 void usage() const override; 54 std::string getSimpleDescription() const override; 55 std::string getName() const override { return GetName(); } 56 57 static std::string GetName(); 58 59 struct RegisteredOption { 60 // short alternative, e.g. 'v'. If '\0', no short options is available. 61 char shortOption; 62 // long alternative, e.g. 'init-vintf' 63 std::string longOption; 64 // no_argument, required_argument or optional_argument 65 int hasArg; 66 // value written to 'flag' by getopt_long 67 int val; 68 // operation when the argument is present 69 std::function<Status(ListCommand* thiz, const char* arg)> op; 70 // help message 71 std::string help; 72 73 const std::string& getHelpMessageForArgument() const; 74 }; 75 // A list of acceptable command line options 76 // key: value returned by getopt_long 77 using RegisteredOptions = std::vector<RegisteredOption>; 78 79 static std::string INIT_VINTF_NOTES; 80 81protected: 82 Status parseArgs(const Arg &arg); 83 Status fetch(); 84 virtual void postprocess(); 85 Status dump(); 86 void putEntry(TableEntrySource source, TableEntry &&entry); 87 Status fetchPassthrough(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager); 88 Status fetchBinderized(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager); 89 Status fetchAllLibraries(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager); 90 91 Status fetchBinderizedEntry(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager, 92 TableEntry *entry); 93 94 // Get relevant information for a PID by parsing files under /d/binder. 95 // It is a virtual member function so that it can be mocked. 96 virtual bool getPidInfo(pid_t serverPid, PidInfo *info) const; 97 // Retrieve from mCachedPidInfos and call getPidInfo if necessary. 98 const PidInfo* getPidInfoCached(pid_t serverPid); 99 100 void dumpTable(const NullableOStream<std::ostream>& out) const; 101 void dumpVintf(const NullableOStream<std::ostream>& out) const; 102 void addLine(TextTable *table, const std::string &interfaceName, const std::string &transport, 103 const std::string &arch, const std::string &threadUsage, const std::string &server, 104 const std::string &serverCmdline, const std::string &address, 105 const std::string &clients, const std::string &clientCmdlines) const; 106 void addLine(TextTable *table, const TableEntry &entry); 107 // Read and return /proc/{pid}/cmdline. 108 virtual std::string parseCmdline(pid_t pid) const; 109 // Return /proc/{pid}/cmdline if it exists, else empty string. 110 const std::string& getCmdline(pid_t pid); 111 // Call getCmdline on all pid in pids. If it returns empty string, the process might 112 // have died, and the pid is removed from pids. 113 void removeDeadProcesses(Pids *pids); 114 115 virtual Partition getPartition(pid_t pid); 116 Partition resolvePartition(Partition processPartition, const FQName& fqName) const; 117 118 void forEachTable(const std::function<void(Table &)> &f); 119 void forEachTable(const std::function<void(const Table &)> &f) const; 120 121 NullableOStream<std::ostream> err() const; 122 NullableOStream<std::ostream> out() const; 123 124 void registerAllOptions(); 125 126 Table mServicesTable{}; 127 Table mPassthroughRefTable{}; 128 Table mImplementationsTable{}; 129 130 std::string mFileOutputPath; 131 TableEntryCompare mSortColumn = nullptr; 132 133 bool mEmitDebugInfo = false; 134 135 // If true, output in VINTF format. Output only entries from the specified partition. 136 bool mVintf = false; 137 Partition mVintfPartition = Partition::UNKNOWN; 138 139 // If true, explanatory text are not emitted. 140 bool mNeat = false; 141 142 // If an entry does not exist, need to ask /proc/{pid}/cmdline to get it. 143 // If an entry exist but is an empty string, process might have died. 144 // If an entry exist and not empty, it contains the cached content of /proc/{pid}/cmdline. 145 std::map<pid_t, std::string> mCmdlines; 146 147 // Cache for getPidInfo. 148 std::map<pid_t, PidInfo> mCachedPidInfos; 149 150 // Cache for getPartition. 151 std::map<pid_t, Partition> mPartitions; 152 153 RegisteredOptions mOptions; 154 // All selected columns 155 std::vector<TableColumnType> mSelectedColumns; 156 // If true, emit cmdlines instead of PIDs 157 bool mEnableCmdlines = false; 158 159private: 160 DISALLOW_COPY_AND_ASSIGN(ListCommand); 161}; 162 163 164} // namespace lshal 165} // namespace android 166 167#endif // FRAMEWORK_NATIVE_CMDS_LSHAL_LIST_COMMAND_H_ 168