1c29fa5a6Sopenharmony_ci/*
2c29fa5a6Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License.
5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at
6c29fa5a6Sopenharmony_ci *
7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8c29fa5a6Sopenharmony_ci *
9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and
13c29fa5a6Sopenharmony_ci * limitations under the License.
14c29fa5a6Sopenharmony_ci */
15c29fa5a6Sopenharmony_ci
16c29fa5a6Sopenharmony_ci#include "injection_event_dispatch.h"
17c29fa5a6Sopenharmony_ci
18c29fa5a6Sopenharmony_ci#include <cctype>
19c29fa5a6Sopenharmony_ci#include <cstdio>
20c29fa5a6Sopenharmony_ci#include <iostream>
21c29fa5a6Sopenharmony_ci#include <regex>
22c29fa5a6Sopenharmony_ci#include <string>
23c29fa5a6Sopenharmony_ci#include <typeinfo>
24c29fa5a6Sopenharmony_ci
25c29fa5a6Sopenharmony_ci#include "error_multimodal.h"
26c29fa5a6Sopenharmony_ci#include "input_parse.h"
27c29fa5a6Sopenharmony_ci#include "proto.h"
28c29fa5a6Sopenharmony_ci#include "util.h"
29c29fa5a6Sopenharmony_ci
30c29fa5a6Sopenharmony_ci#undef MMI_LOG_TAG
31c29fa5a6Sopenharmony_ci#define MMI_LOG_TAG "InjectionEventDispatch"
32c29fa5a6Sopenharmony_ci
33c29fa5a6Sopenharmony_cinamespace OHOS {
34c29fa5a6Sopenharmony_cinamespace MMI {
35c29fa5a6Sopenharmony_cinamespace {
36c29fa5a6Sopenharmony_ciconstexpr uint32_t SEND_EVENT_ARGV_COUNTS { 5 };
37c29fa5a6Sopenharmony_ciconstexpr uint32_t SEND_EVENT_DEV_NODE_INDEX { 1 };
38c29fa5a6Sopenharmony_ciconstexpr uint32_t SEND_EVENT_TYPE_INDEX { 2 };
39c29fa5a6Sopenharmony_ciconstexpr uint32_t SEND_EVENT_CODE_INDEX { 3 };
40c29fa5a6Sopenharmony_ciconstexpr uint32_t SEND_EVENT_VALUE_INDEX { 4 };
41c29fa5a6Sopenharmony_ciconstexpr int32_t ARGVS_TARGET_INDEX { 0 };
42c29fa5a6Sopenharmony_ciconstexpr int32_t ARGVS_CODE_INDEX { 2 };
43c29fa5a6Sopenharmony_ciconstexpr int32_t JSON_FILE_PATH_INDEX { 1 };
44c29fa5a6Sopenharmony_ciconstexpr uint32_t INPUT_TYPE_LENGTH { 3 };
45c29fa5a6Sopenharmony_ciconstexpr uint16_t INPUT_TYPE_MAX { 100 };
46c29fa5a6Sopenharmony_ciconstexpr uint32_t INPUT_CODE_LENGTH { 6 };
47c29fa5a6Sopenharmony_ciconstexpr uint32_t INPUT_VALUE_LENGTH { 11 };
48c29fa5a6Sopenharmony_ci} // namespace
49c29fa5a6Sopenharmony_ci
50c29fa5a6Sopenharmony_civoid InjectionEventDispatch::Init()
51c29fa5a6Sopenharmony_ci{
52c29fa5a6Sopenharmony_ci    InitManageFunction();
53c29fa5a6Sopenharmony_ci}
54c29fa5a6Sopenharmony_ci
55c29fa5a6Sopenharmony_civoid InjectionEventDispatch::InitManageFunction()
56c29fa5a6Sopenharmony_ci{
57c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
58c29fa5a6Sopenharmony_ci    InjectFunctionMap funs[] = {
59c29fa5a6Sopenharmony_ci        {"help", [this] { return this->OnHelp(); }},
60c29fa5a6Sopenharmony_ci        {"sendevent", [this] { return this->OnSendEvent(); }},
61c29fa5a6Sopenharmony_ci        {"json", [this] { return this->OnJson(); }},
62c29fa5a6Sopenharmony_ci    };
63c29fa5a6Sopenharmony_ci
64c29fa5a6Sopenharmony_ci    for (auto &it : funs) {
65c29fa5a6Sopenharmony_ci        if (!RegisterInjectEvent(it)) {
66c29fa5a6Sopenharmony_ci            MMI_HILOGW("Failed to register event errCode:%{public}d", EVENT_REG_FAIL);
67c29fa5a6Sopenharmony_ci            continue;
68c29fa5a6Sopenharmony_ci        }
69c29fa5a6Sopenharmony_ci    }
70c29fa5a6Sopenharmony_ci}
71c29fa5a6Sopenharmony_ci
72c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::OnJson()
73c29fa5a6Sopenharmony_ci{
74c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
75c29fa5a6Sopenharmony_ci    if (injectArgvs_.size() < ARGVS_CODE_INDEX) {
76c29fa5a6Sopenharmony_ci        MMI_HILOGE("Path is error");
77c29fa5a6Sopenharmony_ci        return RET_ERR;
78c29fa5a6Sopenharmony_ci    }
79c29fa5a6Sopenharmony_ci    std::string jsonBuf = ReadJsonFile(injectArgvs_.at(JSON_FILE_PATH_INDEX));
80c29fa5a6Sopenharmony_ci    if (jsonBuf.empty()) {
81c29fa5a6Sopenharmony_ci        MMI_HILOGE("Read file failed");
82c29fa5a6Sopenharmony_ci        return RET_ERR;
83c29fa5a6Sopenharmony_ci    }
84c29fa5a6Sopenharmony_ci    bool logStatus = false;
85c29fa5a6Sopenharmony_ci    if (injectArgvs_.size() > ARGVS_CODE_INDEX) {
86c29fa5a6Sopenharmony_ci        if (injectArgvs_.at(ARGVS_CODE_INDEX) == "log") {
87c29fa5a6Sopenharmony_ci            logStatus = true;
88c29fa5a6Sopenharmony_ci        }
89c29fa5a6Sopenharmony_ci    }
90c29fa5a6Sopenharmony_ci    return manageInjectDevice_.TransformJsonData(DataInit(jsonBuf, logStatus));
91c29fa5a6Sopenharmony_ci}
92c29fa5a6Sopenharmony_ci
93c29fa5a6Sopenharmony_civoid InjectionEventDispatch::SetArgvs(const std::vector<std::string> &injectArgvs)
94c29fa5a6Sopenharmony_ci{
95c29fa5a6Sopenharmony_ci    injectArgvs_ = injectArgvs;
96c29fa5a6Sopenharmony_ci}
97c29fa5a6Sopenharmony_ci
98c29fa5a6Sopenharmony_cistd::string InjectionEventDispatch::GetFunId() const
99c29fa5a6Sopenharmony_ci{
100c29fa5a6Sopenharmony_ci    return funId_;
101c29fa5a6Sopenharmony_ci}
102c29fa5a6Sopenharmony_ci
103c29fa5a6Sopenharmony_cibool InjectionEventDispatch::VerifyArgvs()
104c29fa5a6Sopenharmony_ci{
105c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
106c29fa5a6Sopenharmony_ci    std::string temp = injectArgvs_.at(ARGVS_TARGET_INDEX);
107c29fa5a6Sopenharmony_ci    if (temp.empty()) {
108c29fa5a6Sopenharmony_ci        MMI_HILOGE("Invalid Input parameter");
109c29fa5a6Sopenharmony_ci        return false;
110c29fa5a6Sopenharmony_ci    }
111c29fa5a6Sopenharmony_ci    auto it = injectFuns_.find(temp);
112c29fa5a6Sopenharmony_ci    if (it == injectFuns_.end()) {
113c29fa5a6Sopenharmony_ci        MMI_HILOGE("Parameter bound function not found");
114c29fa5a6Sopenharmony_ci        return false;
115c29fa5a6Sopenharmony_ci    }
116c29fa5a6Sopenharmony_ci    funId_ = temp;
117c29fa5a6Sopenharmony_ci    return true;
118c29fa5a6Sopenharmony_ci}
119c29fa5a6Sopenharmony_ci
120c29fa5a6Sopenharmony_civoid InjectionEventDispatch::Run()
121c29fa5a6Sopenharmony_ci{
122c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
123c29fa5a6Sopenharmony_ci    std::string id = GetFunId();
124c29fa5a6Sopenharmony_ci    auto fun = GetFun(id);
125c29fa5a6Sopenharmony_ci    CHKPV(fun);
126c29fa5a6Sopenharmony_ci    auto ret = (*fun)();
127c29fa5a6Sopenharmony_ci    if (ret == RET_OK) {
128c29fa5a6Sopenharmony_ci        MMI_HILOGI("Inject function success id:%{public}s", id.c_str());
129c29fa5a6Sopenharmony_ci    } else {
130c29fa5a6Sopenharmony_ci        MMI_HILOGE("Inject function failed id:%{public}s", id.c_str());
131c29fa5a6Sopenharmony_ci    }
132c29fa5a6Sopenharmony_ci}
133c29fa5a6Sopenharmony_ci
134c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::ExecuteFunction(std::string funId)
135c29fa5a6Sopenharmony_ci{
136c29fa5a6Sopenharmony_ci    if (funId.empty()) {
137c29fa5a6Sopenharmony_ci        return RET_ERR;
138c29fa5a6Sopenharmony_ci    }
139c29fa5a6Sopenharmony_ci    auto fun = GetFun(funId);
140c29fa5a6Sopenharmony_ci    if (!fun) {
141c29fa5a6Sopenharmony_ci        MMI_HILOGE("Event injection Unknown fuction id:%{public}s", funId.c_str());
142c29fa5a6Sopenharmony_ci        return false;
143c29fa5a6Sopenharmony_ci    }
144c29fa5a6Sopenharmony_ci    MMI_HILOGI("Inject tools into function:%{public}s", funId.c_str());
145c29fa5a6Sopenharmony_ci    int32_t ret = RET_ERR;
146c29fa5a6Sopenharmony_ci    ret = (*fun)();
147c29fa5a6Sopenharmony_ci    if (ret == RET_OK) {
148c29fa5a6Sopenharmony_ci        MMI_HILOGI("Inject function success id:%{public}s", funId.c_str());
149c29fa5a6Sopenharmony_ci    } else {
150c29fa5a6Sopenharmony_ci        MMI_HILOGE("Inject function failed id:%{public}s", funId.c_str());
151c29fa5a6Sopenharmony_ci    }
152c29fa5a6Sopenharmony_ci
153c29fa5a6Sopenharmony_ci    return ret;
154c29fa5a6Sopenharmony_ci}
155c29fa5a6Sopenharmony_ci
156c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::OnHelp()
157c29fa5a6Sopenharmony_ci{
158c29fa5a6Sopenharmony_ci    InjectionToolsHelpFunc helpFunc;
159c29fa5a6Sopenharmony_ci    helpFunc.ShowUsage();
160c29fa5a6Sopenharmony_ci    return RET_OK;
161c29fa5a6Sopenharmony_ci}
162c29fa5a6Sopenharmony_ci
163c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::GetDeviceIndex(const std::string &deviceNameText) const
164c29fa5a6Sopenharmony_ci{
165c29fa5a6Sopenharmony_ci    if (deviceNameText.empty()) {
166c29fa5a6Sopenharmony_ci        MMI_HILOGE("The deviceNameText is empty");
167c29fa5a6Sopenharmony_ci        return RET_ERR;
168c29fa5a6Sopenharmony_ci    }
169c29fa5a6Sopenharmony_ci    for (const auto &item : allDevices_) {
170c29fa5a6Sopenharmony_ci        if (deviceNameText == item.chipName) {
171c29fa5a6Sopenharmony_ci            return item.devIndex;
172c29fa5a6Sopenharmony_ci        }
173c29fa5a6Sopenharmony_ci    }
174c29fa5a6Sopenharmony_ci    MMI_HILOGW("Get device index failed");
175c29fa5a6Sopenharmony_ci    return RET_ERR;
176c29fa5a6Sopenharmony_ci}
177c29fa5a6Sopenharmony_ci
178c29fa5a6Sopenharmony_cibool InjectionEventDispatch::CheckValue(const std::string &inputValue)
179c29fa5a6Sopenharmony_ci{
180c29fa5a6Sopenharmony_ci    if ((inputValue.length()) > INPUT_VALUE_LENGTH) {
181c29fa5a6Sopenharmony_ci        MMI_HILOGE("The value entered is out of range, value:%{public}s", inputValue.c_str());
182c29fa5a6Sopenharmony_ci        return false;
183c29fa5a6Sopenharmony_ci    }
184c29fa5a6Sopenharmony_ci    bool isValueNumber = regex_match(inputValue, std::regex("(-[\\d+]+)|(\\d+)"));
185c29fa5a6Sopenharmony_ci    if (isValueNumber) {
186c29fa5a6Sopenharmony_ci        int32_t numberValue = stoi(inputValue);
187c29fa5a6Sopenharmony_ci        if ((numberValue >= INT32_MIN) && (numberValue <= INT32_MAX)) {
188c29fa5a6Sopenharmony_ci            return true;
189c29fa5a6Sopenharmony_ci        }
190c29fa5a6Sopenharmony_ci    }
191c29fa5a6Sopenharmony_ci    return false;
192c29fa5a6Sopenharmony_ci}
193c29fa5a6Sopenharmony_ci
194c29fa5a6Sopenharmony_cibool InjectionEventDispatch::CheckCode(const std::string &inputCode)
195c29fa5a6Sopenharmony_ci{
196c29fa5a6Sopenharmony_ci    if ((inputCode.length()) > INPUT_CODE_LENGTH) {
197c29fa5a6Sopenharmony_ci        MMI_HILOGE("The value entered is out of range, code:%{public}s", inputCode.c_str());
198c29fa5a6Sopenharmony_ci        return false;
199c29fa5a6Sopenharmony_ci    }
200c29fa5a6Sopenharmony_ci    bool isCodeNumber = regex_match(inputCode, std::regex("\\d+"));
201c29fa5a6Sopenharmony_ci    if (isCodeNumber) {
202c29fa5a6Sopenharmony_ci        int32_t numberCode = stoi(inputCode);
203c29fa5a6Sopenharmony_ci        if ((numberCode >= 0) && (numberCode <= UINT16_MAX)) {
204c29fa5a6Sopenharmony_ci            return true;
205c29fa5a6Sopenharmony_ci        }
206c29fa5a6Sopenharmony_ci    }
207c29fa5a6Sopenharmony_ci    return false;
208c29fa5a6Sopenharmony_ci}
209c29fa5a6Sopenharmony_ci
210c29fa5a6Sopenharmony_cibool InjectionEventDispatch::CheckType(const std::string &inputType)
211c29fa5a6Sopenharmony_ci{
212c29fa5a6Sopenharmony_ci    if ((inputType.length()) > INPUT_TYPE_LENGTH) {
213c29fa5a6Sopenharmony_ci        MMI_HILOGE("The value entered is out of range, type:%{public}s", inputType.c_str());
214c29fa5a6Sopenharmony_ci        return false;
215c29fa5a6Sopenharmony_ci    }
216c29fa5a6Sopenharmony_ci    bool isTypeNumber = regex_match(inputType, std::regex("\\d+"));
217c29fa5a6Sopenharmony_ci    if (isTypeNumber) {
218c29fa5a6Sopenharmony_ci        int32_t numberType = stoi(inputType);
219c29fa5a6Sopenharmony_ci        if ((numberType >= 0) && (numberType <= INPUT_TYPE_MAX)) {
220c29fa5a6Sopenharmony_ci            return true;
221c29fa5a6Sopenharmony_ci        }
222c29fa5a6Sopenharmony_ci    }
223c29fa5a6Sopenharmony_ci    return false;
224c29fa5a6Sopenharmony_ci}
225c29fa5a6Sopenharmony_ci
226c29fa5a6Sopenharmony_cibool InjectionEventDispatch::CheckEventValue(const std::string &inputType, const std::string &inputCode,
227c29fa5a6Sopenharmony_ci    const std::string &inputValue)
228c29fa5a6Sopenharmony_ci{
229c29fa5a6Sopenharmony_ci    if (!(CheckType(inputType))) {
230c29fa5a6Sopenharmony_ci        MMI_HILOGE("Input error in type, type:%{public}s", inputType.c_str());
231c29fa5a6Sopenharmony_ci        return false;
232c29fa5a6Sopenharmony_ci    }
233c29fa5a6Sopenharmony_ci    if (!(CheckCode(inputCode))) {
234c29fa5a6Sopenharmony_ci        MMI_HILOGE("Input error in code, code:%{public}s", inputCode.c_str());
235c29fa5a6Sopenharmony_ci        return false;
236c29fa5a6Sopenharmony_ci    }
237c29fa5a6Sopenharmony_ci    if (!(CheckValue(inputValue))) {
238c29fa5a6Sopenharmony_ci        MMI_HILOGE("Input error in value, value:%{public}s", inputValue.c_str());
239c29fa5a6Sopenharmony_ci        return false;
240c29fa5a6Sopenharmony_ci    }
241c29fa5a6Sopenharmony_ci    return true;
242c29fa5a6Sopenharmony_ci}
243c29fa5a6Sopenharmony_ci
244c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::OnSendEvent()
245c29fa5a6Sopenharmony_ci{
246c29fa5a6Sopenharmony_ci    if (injectArgvs_.size() != SEND_EVENT_ARGV_COUNTS) {
247c29fa5a6Sopenharmony_ci        MMI_HILOGE("Wrong number of input parameters, errCode:%{public}d", PARAM_INPUT_FAIL);
248c29fa5a6Sopenharmony_ci        return RET_ERR;
249c29fa5a6Sopenharmony_ci    }
250c29fa5a6Sopenharmony_ci    std::string deviceNode = injectArgvs_[SEND_EVENT_DEV_NODE_INDEX];
251c29fa5a6Sopenharmony_ci    if (deviceNode.empty()) {
252c29fa5a6Sopenharmony_ci        MMI_HILOGE("Device node:%{public}s is not existent", deviceNode.c_str());
253c29fa5a6Sopenharmony_ci        return RET_ERR;
254c29fa5a6Sopenharmony_ci    }
255c29fa5a6Sopenharmony_ci    char realPath[PATH_MAX] = {};
256c29fa5a6Sopenharmony_ci    if (realpath(deviceNode.c_str(), realPath) == nullptr) {
257c29fa5a6Sopenharmony_ci        MMI_HILOGE("Path is error, path:%{private}s", deviceNode.c_str());
258c29fa5a6Sopenharmony_ci        return RET_ERR;
259c29fa5a6Sopenharmony_ci    }
260c29fa5a6Sopenharmony_ci    int32_t fd = open(realPath, O_RDWR);
261c29fa5a6Sopenharmony_ci    if (fd < 0) {
262c29fa5a6Sopenharmony_ci        MMI_HILOGE("Open device node:%{public}s failed, errCode:%{public}d", deviceNode.c_str(), FILE_OPEN_FAIL);
263c29fa5a6Sopenharmony_ci        return RET_ERR;
264c29fa5a6Sopenharmony_ci    }
265c29fa5a6Sopenharmony_ci    struct timeval tm;
266c29fa5a6Sopenharmony_ci    gettimeofday(&tm, 0);
267c29fa5a6Sopenharmony_ci    struct input_event event = {};
268c29fa5a6Sopenharmony_ci    event.input_event_sec = tm.tv_sec;
269c29fa5a6Sopenharmony_ci    event.input_event_usec = tm.tv_usec;
270c29fa5a6Sopenharmony_ci    if (!(CheckEventValue(injectArgvs_[SEND_EVENT_TYPE_INDEX], injectArgvs_[SEND_EVENT_CODE_INDEX],
271c29fa5a6Sopenharmony_ci        injectArgvs_[SEND_EVENT_VALUE_INDEX]))) {
272c29fa5a6Sopenharmony_ci        return RET_ERR;
273c29fa5a6Sopenharmony_ci    }
274c29fa5a6Sopenharmony_ci    event.type = static_cast<uint16_t>(std::stoi(injectArgvs_[SEND_EVENT_TYPE_INDEX]));
275c29fa5a6Sopenharmony_ci    event.code = static_cast<uint16_t>(std::stoi(injectArgvs_[SEND_EVENT_CODE_INDEX]));
276c29fa5a6Sopenharmony_ci    event.value = static_cast<int32_t>(std::stoi(injectArgvs_[SEND_EVENT_VALUE_INDEX]));
277c29fa5a6Sopenharmony_ci    int32_t ret = write(fd, &event, sizeof(event));
278c29fa5a6Sopenharmony_ci    if (ret != sizeof(event)) {
279c29fa5a6Sopenharmony_ci        MMI_HILOGE("Send event to device node failed");
280c29fa5a6Sopenharmony_ci        return RET_ERR;
281c29fa5a6Sopenharmony_ci    }
282c29fa5a6Sopenharmony_ci    if (fd >= 0) {
283c29fa5a6Sopenharmony_ci        close(fd);
284c29fa5a6Sopenharmony_ci    }
285c29fa5a6Sopenharmony_ci    return RET_OK;
286c29fa5a6Sopenharmony_ci}
287c29fa5a6Sopenharmony_ci
288c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::GetDevTypeIndex(int32_t devIndex) const
289c29fa5a6Sopenharmony_ci{
290c29fa5a6Sopenharmony_ci    for (const auto &item : allDevices_) {
291c29fa5a6Sopenharmony_ci        if (devIndex == item.devIndex) {
292c29fa5a6Sopenharmony_ci            return item.devType;
293c29fa5a6Sopenharmony_ci        }
294c29fa5a6Sopenharmony_ci    }
295c29fa5a6Sopenharmony_ci    return RET_ERR;
296c29fa5a6Sopenharmony_ci}
297c29fa5a6Sopenharmony_ci
298c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::GetDevIndexType(int32_t devType) const
299c29fa5a6Sopenharmony_ci{
300c29fa5a6Sopenharmony_ci    for (const auto &item : allDevices_) {
301c29fa5a6Sopenharmony_ci        if (item.devType == devType) {
302c29fa5a6Sopenharmony_ci            return item.devIndex;
303c29fa5a6Sopenharmony_ci        }
304c29fa5a6Sopenharmony_ci    }
305c29fa5a6Sopenharmony_ci    return RET_ERR;
306c29fa5a6Sopenharmony_ci}
307c29fa5a6Sopenharmony_ci} // namespace MMI
308c29fa5a6Sopenharmony_ci} // namespace OHOS
309