1/*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "hidumper.h"
17
18#include "dinput_errcode.h"
19#include "dinput_log.h"
20#include "dinput_softbus_define.h"
21#include "dinput_utils_tool.h"
22
23namespace OHOS {
24namespace DistributedHardware {
25namespace DistributedInput {
26IMPLEMENT_SINGLE_INSTANCE(HiDumper);
27namespace {
28    const std::string ARGS_HELP = "-h";
29    const std::string ARGS_NODE_INFO = "-nodeinfo";
30    const std::string ARGS_SESSION_INFO = "-sessioninfo";
31
32    const std::map<std::string, HiDumperFlag> ARGS_MAP = {
33        {ARGS_HELP, HiDumperFlag::GET_HELP},
34        {ARGS_NODE_INFO, HiDumperFlag::GET_NODE_INFO},
35        {ARGS_SESSION_INFO, HiDumperFlag::GET_SESSION_INFO},
36    };
37
38    const std::map<SessionStatus, std::string> SESSION_STATUS = {
39        {SessionStatus::CLOSED, "closed"},
40        {SessionStatus::OPENING, "opening"},
41        {SessionStatus::OPENED, "opened"},
42        {SessionStatus::CLOSING, "closing"},
43    };
44}
45
46bool HiDumper::HiDump(const std::vector<std::string> &args, std::string &result)
47{
48    if (args.empty()) {
49        DHLOGE("args is empty");
50        return false;
51    }
52
53    result.clear();
54    int32_t argsSize = static_cast<int32_t>(args.size());
55    for (int32_t i = 0; i < argsSize; i++) {
56        DHLOGI("HiDumper Dump args[%{public}d]: %{public}s.", i, args.at(i).c_str());
57    }
58    if (ProcessDump(args[0], result) != DH_SUCCESS) {
59        return false;
60    }
61    return true;
62}
63
64int32_t HiDumper::ProcessDump(const std::string &args, std::string &result)
65{
66    DHLOGI("ProcessDump Dump.");
67    int32_t ret = ERR_DH_INPUT_HIDUMP_INVALID_ARGS;
68    result.clear();
69
70    std::map<std::string, HiDumperFlag>::const_iterator operatorIter;
71    {
72        std::lock_guard<std::mutex> lock(operationMutex_);
73        operatorIter = ARGS_MAP.find(args);
74        if (operatorIter == ARGS_MAP.end()) {
75            result.append("unknown command");
76            DHLOGI("ProcessDump");
77            return ret;
78        }
79    }
80
81    HiDumperFlag hidumperFlag = operatorIter->second;
82    switch (hidumperFlag) {
83        case HiDumperFlag::GET_HELP: {
84            ret = ShowHelp(result);
85            break;
86        }
87        case HiDumperFlag::GET_NODE_INFO: {
88            ret = GetAllNodeInfos(result);
89            break;
90        }
91        case HiDumperFlag::GET_SESSION_INFO: {
92            ret = GetSessionInfo(result);
93            break;
94        }
95        default:
96            break;
97    }
98    return ret;
99}
100
101int32_t HiDumper::GetAllNodeInfos(std::string &result)
102{
103    DHLOGI("GetAllNodeInfos Dump.");
104    std::lock_guard<std::mutex> node_lock(nodeMutex_);
105    for (auto iter = nodeInfos_.begin(); iter != nodeInfos_.end(); iter++) {
106        result.append("\n{");
107        result.append("\n   deviceid :   ");
108        result.append(GetAnonyString((*iter).devId));
109        result.append("\n   nodename :   ");
110        result.append((*iter).virNodeName);
111        result.append("\n   dhId :   ");
112        result.append(GetAnonyString((*iter).inputDhId));
113        result.append("\n},");
114    }
115    return DH_SUCCESS;
116}
117
118void HiDumper::DeleteNodeInfo(const std::string &deviceId, const std::string &dhId)
119{
120    DHLOGI("DeleteNodeInfo Dump.");
121    std::lock_guard<std::mutex> node_lock(nodeMutex_);
122    for (auto iter = nodeInfos_.begin(); iter != nodeInfos_.end();) {
123        if ((*iter).devId.compare(deviceId) == 0 && (*iter).inputDhId.compare(dhId) == 0) {
124            iter = nodeInfos_.erase(iter);
125        } else {
126            iter++;
127        }
128    }
129}
130
131int32_t HiDumper::GetSessionInfo(std::string &result)
132{
133    DHLOGI("GetSessionInfo Dump.");
134    std::lock_guard<std::mutex> lock(sessionMutex_);
135    for (auto iter = sessionInfos_.begin(); iter != sessionInfos_.end(); iter++) {
136        result.append("\n{");
137        result.append("\n   remotedevid :   ");
138        result.append(GetAnonyString(iter->first));
139        result.append("\n   sessionid :   ");
140        result.append(std::to_string(iter->second.sesId));
141        result.append("\n   mysessionname :   ");
142        result.append(iter->second.mySesName);
143        result.append("\n   peersessionname :   ");
144        result.append(iter->second.peerSesName);
145
146        std::string sessionStatus("");
147        auto item = SESSION_STATUS.find(iter->second.sessionState);
148        if (item == SESSION_STATUS.end()) {
149            sessionStatus = "unknown state";
150        } else {
151            sessionStatus = SESSION_STATUS.find(iter->second.sessionState)->second;
152        }
153        result.append("\n   sessionstate :   ");
154        result.append(sessionStatus);
155        result.append("\n},");
156    }
157    return DH_SUCCESS;
158}
159
160void HiDumper::DeleteSessionInfo(const std::string &remoteDevId)
161{
162    DHLOGI("DeleteSessionInfo Dump.");
163    std::lock_guard<std::mutex> session_lock(sessionMutex_);
164    auto iter = sessionInfos_.find(remoteDevId);
165    if (iter == sessionInfos_.end()) {
166        DHLOGI("remote deviceid does not exist");
167        return;
168    } else {
169        sessionInfos_.erase(iter);
170    }
171}
172
173int32_t HiDumper::ShowHelp(std::string &result)
174{
175    DHLOGI("ShowHelp Dump.");
176    result.append("Usage:dump  <command> [options]\n")
177        .append("Description:\n")
178        .append("-nodeinfo        ")
179        .append("dump all input node information in the system\n")
180        .append("-sessioninfo     ")
181        .append("dump all input session information in the system\n");
182    return DH_SUCCESS;
183}
184
185void HiDumper::SaveNodeInfo(const std::string &deviceId, const std::string &nodeName, const std::string &dhId)
186{
187    std::lock_guard<std::mutex> node_lock(nodeMutex_);
188    NodeInfo nodeInfo = {
189        .devId = deviceId,
190        .virNodeName = nodeName,
191        .inputDhId = dhId,
192    };
193    nodeInfos_.push_back(nodeInfo);
194}
195
196void HiDumper::CreateSessionInfo(const std::string &remoteDevId, const int32_t &sessionId,
197    const std::string &mySessionName, const std::string &peerSessionName, const SessionStatus &sessionStatus)
198{
199    std::lock_guard<std::mutex> session_lock(sessionMutex_);
200    auto iter = sessionInfos_.find(remoteDevId);
201    if (iter == sessionInfos_.end()) {
202        SessionInfo sessionInfo = {
203            .sesId = sessionId,
204            .mySesName = mySessionName,
205            .peerSesName = peerSessionName,
206            .sessionState = sessionStatus,
207        };
208        sessionInfos_[remoteDevId] = sessionInfo;
209    }
210}
211
212void HiDumper::SetSessionStatus(const std::string &remoteDevId, const SessionStatus &sessionStatus)
213{
214    std::lock_guard<std::mutex> session_lock(sessionMutex_);
215    auto iter = sessionInfos_.find(remoteDevId);
216    if (iter == sessionInfos_.end()) {
217        DHLOGI("remote deviceid does not exist");
218        return;
219    }
220    sessionInfos_[remoteDevId].sessionState = sessionStatus;
221}
222} // namespace DistributedInput
223} // namespace DistributedHardware
224} // namespace OHOS
225
226