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