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
30namespace android {
31namespace lshal {
32
33using android::procpartition::Partition;
34using Pids = std::vector<int32_t>;
35
36enum : unsigned int {
37    HWSERVICEMANAGER_LIST, // through defaultServiceManager()->list()
38    PTSERVICEMANAGER_REG_CLIENT, // through registerPassthroughClient
39    LIST_DLLIB, // through listing dynamic libraries
40};
41using TableEntrySource = unsigned int;
42
43enum : unsigned int {
44    ARCH_UNKNOWN = 0,
45    ARCH32       = 1 << 0,
46    ARCH64       = 1 << 1,
47    ARCH_BOTH    = ARCH32 | ARCH64
48};
49using Architecture = unsigned int;
50
51enum 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
65enum {
66    NO_PID = -1,
67    NO_PTR = 0
68};
69
70struct 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
85    static bool sortByInterfaceName(const TableEntry &a, const TableEntry &b) {
86        return a.interfaceName < b.interfaceName;
87    };
88    static bool sortByServerPid(const TableEntry &a, const TableEntry &b) {
89        return a.serverPid < b.serverPid;
90    };
91
92    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
108using SelectedColumns = std::vector<TableColumnType>;
109
110class Table {
111public:
112    using Entries = std::vector<TableEntry>;
113
114    Entries::iterator begin() { return mEntries.begin(); }
115    Entries::const_iterator begin() const { return mEntries.begin(); }
116    Entries::iterator end() { return mEntries.end(); }
117    Entries::const_iterator end() const { return mEntries.end(); }
118    size_t size() const { return mEntries.size(); }
119
120    void add(TableEntry&& entry) { mEntries.push_back(std::move(entry)); }
121
122    void setSelectedColumns(const SelectedColumns& s) { mSelectedColumns = s; }
123    const SelectedColumns& getSelectedColumns() const { return mSelectedColumns; }
124
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
131private:
132    std::string mDescription;
133    Entries mEntries;
134    SelectedColumns mSelectedColumns;
135};
136
137using TableEntryCompare = std::function<bool(const TableEntry &, const TableEntry &)>;
138
139class MergedTable {
140public:
141    MergedTable(std::vector<const Table*>&& tables) : mTables(std::move(tables)) {}
142    TextTable createTextTable();
143private:
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