1 /*
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 #ifndef FRAMEWORK_NATIVE_CMDS_LSHAL_TABLE_ENTRY_H_
18 #define FRAMEWORK_NATIVE_CMDS_LSHAL_TABLE_ENTRY_H_
19 
20 #include <stdint.h>
21 
22 #include <string>
23 #include <vector>
24 #include <iostream>
25 
26 #include <procpartition/procpartition.h>
27 
28 #include "TextTable.h"
29 
30 namespace android {
31 namespace lshal {
32 
33 using android::procpartition::Partition;
34 using Pids = std::vector<int32_t>;
35 
36 enum : unsigned int {
37     HWSERVICEMANAGER_LIST, // through defaultServiceManager()->list()
38     PTSERVICEMANAGER_REG_CLIENT, // through registerPassthroughClient
39     LIST_DLLIB, // through listing dynamic libraries
40 };
41 using TableEntrySource = unsigned int;
42 
43 enum : unsigned int {
44     ARCH_UNKNOWN = 0,
45     ARCH32       = 1 << 0,
46     ARCH64       = 1 << 1,
47     ARCH_BOTH    = ARCH32 | ARCH64
48 };
49 using Architecture = unsigned int;
50 
51 enum class TableColumnType : unsigned int {
52     INTERFACE_NAME,
53     TRANSPORT,
54     SERVER_PID,
55     SERVER_CMD,
56     SERVER_ADDR,
57     CLIENT_PIDS,
58     CLIENT_CMDS,
59     ARCH,
60     THREADS,
61     RELEASED,
62     HASH,
63 };
64 
65 enum {
66     NO_PID = -1,
67     NO_PTR = 0
68 };
69 
70 struct TableEntry {
71     std::string interfaceName{};
72     std::string transport{};
73     int32_t serverPid{NO_PID};
74     uint32_t threadUsage{0};
75     uint32_t threadCount{0};
76     std::string serverCmdline{};
77     uint64_t serverObjectAddress{NO_PTR};
78     Pids clientPids{};
79     std::vector<std::string> clientCmdlines{};
80     Architecture arch{ARCH_UNKNOWN};
81     // empty: unknown, all zeros: unreleased, otherwise: released
82     std::string hash{};
83     Partition partition{Partition::UNKNOWN};
84 
sortByInterfaceNameTableEntry85     static bool sortByInterfaceName(const TableEntry &a, const TableEntry &b) {
86         return a.interfaceName < b.interfaceName;
87     };
sortByServerPidTableEntry88     static bool sortByServerPid(const TableEntry &a, const TableEntry &b) {
89         return a.serverPid < b.serverPid;
90     };
91 
getThreadUsageTableEntry92     std::string getThreadUsage() const {
93         if (threadCount == 0) {
94             return "N/A";
95         }
96 
97         return std::to_string(threadUsage) + "/" + std::to_string(threadCount);
98     }
99 
100     std::string isReleased() const;
101 
102     std::string getField(TableColumnType type) const;
103 
104     bool operator==(const TableEntry& other) const;
105     std::string to_string() const;
106 };
107 
108 using SelectedColumns = std::vector<TableColumnType>;
109 
110 class Table {
111 public:
112     using Entries = std::vector<TableEntry>;
113 
begin()114     Entries::iterator begin() { return mEntries.begin(); }
begin()115     Entries::const_iterator begin() const { return mEntries.begin(); }
end()116     Entries::iterator end() { return mEntries.end(); }
end()117     Entries::const_iterator end() const { return mEntries.end(); }
size()118     size_t size() const { return mEntries.size(); }
119 
add(TableEntry && entry)120     void add(TableEntry&& entry) { mEntries.push_back(std::move(entry)); }
121 
setSelectedColumns(const SelectedColumns & s)122     void setSelectedColumns(const SelectedColumns& s) { mSelectedColumns = s; }
getSelectedColumns()123     const SelectedColumns& getSelectedColumns() const { return mSelectedColumns; }
124 
setDescription(std::string && d)125     void setDescription(std::string&& d) { mDescription = std::move(d); }
126 
127     // Write table content.
128     TextTable createTextTable(bool neat = true,
129         const std::function<std::string(const std::string&)>& emitDebugInfo = nullptr) const;
130 
131 private:
132     std::string mDescription;
133     Entries mEntries;
134     SelectedColumns mSelectedColumns;
135 };
136 
137 using TableEntryCompare = std::function<bool(const TableEntry &, const TableEntry &)>;
138 
139 class MergedTable {
140 public:
MergedTable(std::vector<const Table * > && tables)141     MergedTable(std::vector<const Table*>&& tables) : mTables(std::move(tables)) {}
142     TextTable createTextTable();
143 private:
144     std::vector<const Table*> mTables;
145 };
146 
147 }  // namespace lshal
148 }  // namespace android
149 
150 #endif  // FRAMEWORK_NATIVE_CMDS_LSHAL_TABLE_ENTRY_H_
151