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 if (isValueNumber) {
186 int32_t numberValue = stoi(inputValue);
187 if ((numberValue >= INT32_MIN) && (numberValue <= INT32_MAX)) {
188 return true;
189 }
190 }
191 return false;
192 }
193
CheckCode(const std::string & inputCode)194 bool InjectionEventDispatch::CheckCode(const std::string &inputCode)
195 {
196 if ((inputCode.length()) > INPUT_CODE_LENGTH) {
197 MMI_HILOGE("The value entered is out of range, code:%{public}s", inputCode.c_str());
198 return false;
199 }
200 bool isCodeNumber = regex_match(inputCode, std::regex("\\d+"));
201 if (isCodeNumber) {
202 int32_t numberCode = stoi(inputCode);
203 if ((numberCode >= 0) && (numberCode <= UINT16_MAX)) {
204 return true;
205 }
206 }
207 return false;
208 }
209
CheckType(const std::string & inputType)210 bool InjectionEventDispatch::CheckType(const std::string &inputType)
211 {
212 if ((inputType.length()) > INPUT_TYPE_LENGTH) {
213 MMI_HILOGE("The value entered is out of range, type:%{public}s", inputType.c_str());
214 return false;
215 }
216 bool isTypeNumber = regex_match(inputType, std::regex("\\d+"));
217 if (isTypeNumber) {
218 int32_t numberType = stoi(inputType);
219 if ((numberType >= 0) && (numberType <= INPUT_TYPE_MAX)) {
220 return true;
221 }
222 }
223 return false;
224 }
225
CheckEventValue(const std::string & inputType,const std::string & inputCode,const std::string & inputValue)226 bool InjectionEventDispatch::CheckEventValue(const std::string &inputType, const std::string &inputCode,
227 const std::string &inputValue)
228 {
229 if (!(CheckType(inputType))) {
230 MMI_HILOGE("Input error in type, type:%{public}s", inputType.c_str());
231 return false;
232 }
233 if (!(CheckCode(inputCode))) {
234 MMI_HILOGE("Input error in code, code:%{public}s", inputCode.c_str());
235 return false;
236 }
237 if (!(CheckValue(inputValue))) {
238 MMI_HILOGE("Input error in value, value:%{public}s", inputValue.c_str());
239 return false;
240 }
241 return true;
242 }
243
OnSendEvent()244 int32_t InjectionEventDispatch::OnSendEvent()
245 {
246 if (injectArgvs_.size() != SEND_EVENT_ARGV_COUNTS) {
247 MMI_HILOGE("Wrong number of input parameters, errCode:%{public}d", PARAM_INPUT_FAIL);
248 return RET_ERR;
249 }
250 std::string deviceNode = injectArgvs_[SEND_EVENT_DEV_NODE_INDEX];
251 if (deviceNode.empty()) {
252 MMI_HILOGE("Device node:%{public}s is not existent", deviceNode.c_str());
253 return RET_ERR;
254 }
255 char realPath[PATH_MAX] = {};
256 if (realpath(deviceNode.c_str(), realPath) == nullptr) {
257 MMI_HILOGE("Path is error, path:%{private}s", deviceNode.c_str());
258 return RET_ERR;
259 }
260 int32_t fd = open(realPath, O_RDWR);
261 if (fd < 0) {
262 MMI_HILOGE("Open device node:%{public}s failed, errCode:%{public}d", deviceNode.c_str(), FILE_OPEN_FAIL);
263 return RET_ERR;
264 }
265 struct timeval tm;
266 gettimeofday(&tm, 0);
267 struct input_event event = {};
268 event.input_event_sec = tm.tv_sec;
269 event.input_event_usec = tm.tv_usec;
270 if (!(CheckEventValue(injectArgvs_[SEND_EVENT_TYPE_INDEX], injectArgvs_[SEND_EVENT_CODE_INDEX],
271 injectArgvs_[SEND_EVENT_VALUE_INDEX]))) {
272 return RET_ERR;
273 }
274 event.type = static_cast<uint16_t>(std::stoi(injectArgvs_[SEND_EVENT_TYPE_INDEX]));
275 event.code = static_cast<uint16_t>(std::stoi(injectArgvs_[SEND_EVENT_CODE_INDEX]));
276 event.value = static_cast<int32_t>(std::stoi(injectArgvs_[SEND_EVENT_VALUE_INDEX]));
277 int32_t ret = write(fd, &event, sizeof(event));
278 if (ret != sizeof(event)) {
279 MMI_HILOGE("Send event to device node failed");
280 return RET_ERR;
281 }
282 if (fd >= 0) {
283 close(fd);
284 }
285 return RET_OK;
286 }
287
GetDevTypeIndex(int32_t devIndex) const288 int32_t InjectionEventDispatch::GetDevTypeIndex(int32_t devIndex) const
289 {
290 for (const auto &item : allDevices_) {
291 if (devIndex == item.devIndex) {
292 return item.devType;
293 }
294 }
295 return RET_ERR;
296 }
297
GetDevIndexType(int32_t devType) const298 int32_t InjectionEventDispatch::GetDevIndexType(int32_t devType) const
299 {
300 for (const auto &item : allDevices_) {
301 if (item.devType == devType) {
302 return item.devIndex;
303 }
304 }
305 return RET_ERR;
306 }
307 } // namespace MMI
308 } // namespace OHOS
309