Home | History | Annotate | Download | only in lshal
      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 
     37 namespace android {
     38 namespace lshal {
     39 
     40 class Lshal;
     41 
     42 struct 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 
     48 class ListCommand : public Command {
     49 public:
     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 
     81 protected:
     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 
    159 private:
    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