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