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 "proto.h"
27 #include "util.h"
28 #include "input_parse.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 = 1;
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 InjectFunctionMap funs[] = {
56 {"help", std::bind(&InjectionEventDispatch::OnHelp, this)},
57 {"sendevent", std::bind(&InjectionEventDispatch::OnSendEvent, this)},
58 {"json", std::bind(&InjectionEventDispatch::OnJson, this)},
59 };
60
61 for (auto &it : funs) {
62 if (!RegisterInjectEvent(it)) {
63 MMI_HILOGW("Failed to register event errCode:%{public}d", EVENT_REG_FAIL);
64 continue;
65 }
66 }
67 }
68
OnJson()69 int32_t InjectionEventDispatch::OnJson()
70 {
71 CALL_DEBUG_ENTER;
72 if (injectArgvs_.size() < ARGVS_CODE_INDEX) {
73 MMI_HILOGE("Path is error");
74 return RET_ERR;
75 }
76 std::string jsonBuf = ReadJsonFile(injectArgvs_.at(JSON_FILE_PATH_INDEX));
77 if (jsonBuf.empty()) {
78 MMI_HILOGE("Read file failed");
79 return RET_ERR;
80 }
81 bool logStatus = false;
82 if (injectArgvs_.size() > ARGVS_CODE_INDEX) {
83 if (injectArgvs_.at(ARGVS_CODE_INDEX) == "log") {
84 logStatus = true;
85 }
86 }
87 return manageInjectDevice_.TransformJsonData(DataInit(jsonBuf, logStatus));
88 }
89
GetFunId() const90 std::string InjectionEventDispatch::GetFunId() const
91 {
92 return funId_;
93 }
94
VerifyArgvs(const int32_t & argc,const std::vector<std::string> & argv)95 bool InjectionEventDispatch::VerifyArgvs(const int32_t &argc, const std::vector<std::string> &argv)
96 {
97 CALL_DEBUG_ENTER;
98 if (argc < ARGV_VALID || argv.at(ARGVS_TARGET_INDEX).empty()) {
99 MMI_HILOGE("Invalid Input Para, Please Check the validity of the para. errCode:%{public}d", PARAM_INPUT_FAIL);
100 return false;
101 }
102
103 bool result = false;
104 for (const auto &item : injectFuns_) {
105 std::string temp(argv.at(ARGVS_TARGET_INDEX));
106 if (temp == item.first) {
107 funId_ = temp;
108 result = true;
109 break;
110 }
111 }
112 if (result) {
113 injectArgvs_.clear();
114 for (uint64_t i = 1; i < static_cast<uint64_t>(argc); i++) {
115 injectArgvs_.push_back(argv[i]);
116 }
117 argvNum_ = argc - 1;
118 }
119
120 return result;
121 }
122
Run()123 void InjectionEventDispatch::Run()
124 {
125 CALL_DEBUG_ENTER;
126 std::string id = GetFunId();
127 auto fun = GetFun(id);
128 CHKPV(fun);
129 auto ret = (*fun)();
130 if (ret == RET_OK) {
131 MMI_HILOGI("Inject function success id:%{public}s", id.c_str());
132 } else {
133 MMI_HILOGE("Inject function failed id:%{public}s", id.c_str());
134 }
135 }
136
ExecuteFunction(std::string funId)137 int32_t InjectionEventDispatch::ExecuteFunction(std::string funId)
138 {
139 if (funId.empty()) {
140 return RET_ERR;
141 }
142 auto fun = GetFun(funId);
143 if (!fun) {
144 MMI_HILOGE("Event injection Unknown fuction id:%{public}s", funId.c_str());
145 return false;
146 }
147 MMI_HILOGI("Inject tools into function:%{public}s", funId.c_str());
148 int32_t ret = RET_ERR;
149 ret = (*fun)();
150 if (ret == RET_OK) {
151 MMI_HILOGI("Inject function success id:%{public}s", funId.c_str());
152 } else {
153 MMI_HILOGE("Inject function failed id:%{public}s", funId.c_str());
154 }
155
156 return ret;
157 }
158
OnHelp()159 int32_t InjectionEventDispatch::OnHelp()
160 {
161 InjectionToolsHelpFunc helpFunc;
162 std::string ret = helpFunc.GetHelpText();
163 MMI_HILOGI("%{public}s", ret.c_str());
164 return RET_OK;
165 }
166
CheckValue(const std::string & inputValue)167 bool InjectionEventDispatch::CheckValue(const std::string &inputValue)
168 {
169 if ((inputValue.length()) > INPUT_VALUE_LENGTH) {
170 MMI_HILOGE("The value entered is out of range, value:%{public}s", inputValue.c_str());
171 return false;
172 }
173 bool isValueNumber = regex_match(inputValue, std::regex("(-[\\d+]+)|(\\d+)"));
174 if (isValueNumber) {
175 int32_t numberValue = stoi(inputValue);
176 if ((numberValue >= INT32_MIN) && (numberValue <= INT32_MAX)) {
177 return true;
178 }
179 }
180 return false;
181 }
182
CheckCode(const std::string & inputCode)183 bool InjectionEventDispatch::CheckCode(const std::string &inputCode)
184 {
185 if ((inputCode.length()) > INPUT_CODE_LENGTH) {
186 MMI_HILOGE("The value entered is out of range, code:%{public}s", inputCode.c_str());
187 return false;
188 }
189 bool isCodeNumber = regex_match(inputCode, std::regex("\\d+"));
190 if (isCodeNumber) {
191 int32_t numberCode = stoi(inputCode);
192 if ((numberCode >= 0) && (numberCode <= UINT16_MAX)) {
193 return true;
194 }
195 }
196 return false;
197 }
198
CheckType(const std::string & inputType)199 bool InjectionEventDispatch::CheckType(const std::string &inputType)
200 {
201 if ((inputType.length()) > INPUT_TYPE_LENGTH) {
202 MMI_HILOGE("The value entered is out of range, type:%{public}s", inputType.c_str());
203 return false;
204 }
205 bool isTypeNumber = regex_match(inputType, std::regex("\\d+"));
206 if (isTypeNumber) {
207 int32_t numberType = stoi(inputType);
208 if ((numberType >= 0) && (numberType <= INPUT_TYPE_MAX)) {
209 return true;
210 }
211 }
212 return false;
213 }
214
CheckEventValue(const std::string & inputType,const std::string & inputCode,const std::string & inputValue)215 bool InjectionEventDispatch::CheckEventValue(const std::string &inputType, const std::string &inputCode,
216 const std::string &inputValue)
217 {
218 if (!(CheckType(inputType))) {
219 MMI_HILOGE("Input error in type, type:%{public}s", inputType.c_str());
220 return false;
221 }
222 if (!(CheckCode(inputCode))) {
223 MMI_HILOGE("Input error in code, code:%{public}s", inputCode.c_str());
224 return false;
225 }
226 if (!(CheckValue(inputValue))) {
227 MMI_HILOGE("Input error in value, value:%{public}s", inputValue.c_str());
228 return false;
229 }
230 return true;
231 }
232
OnSendEvent()233 int32_t InjectionEventDispatch::OnSendEvent()
234 {
235 if (injectArgvs_.size() != SEND_EVENT_ARGV_COUNTS) {
236 MMI_HILOGE("Wrong number of input parameters, errCode:%{public}d", PARAM_INPUT_FAIL);
237 return RET_ERR;
238 }
239 std::string deviceNode = injectArgvs_[SEND_EVENT_DEV_NODE_INDEX];
240 if (deviceNode.empty()) {
241 MMI_HILOGE("Device node:%{public}s is not existent", deviceNode.c_str());
242 return RET_ERR;
243 }
244 char realPath[PATH_MAX] = {};
245 if (realpath(deviceNode.c_str(), realPath) == nullptr) {
246 MMI_HILOGE("Path is error, path:%{public}s", deviceNode.c_str());
247 return RET_ERR;
248 }
249 int32_t fd = open(realPath, O_RDWR);
250 if (fd < 0) {
251 MMI_HILOGE("Open device node:%{public}s failed, errCode:%{public}d", deviceNode.c_str(), FILE_OPEN_FAIL);
252 return RET_ERR;
253 }
254 struct timeval tm;
255 gettimeofday(&tm, 0);
256 struct input_event event = {};
257 event.input_event_sec = tm.tv_sec;
258 event.input_event_usec = tm.tv_usec;
259 if (!(CheckEventValue(injectArgvs_[SEND_EVENT_TYPE_INDEX], injectArgvs_[SEND_EVENT_CODE_INDEX],
260 injectArgvs_[SEND_EVENT_VALUE_INDEX]))) {
261 return RET_ERR;
262 }
263 event.type = static_cast<uint16_t>(std::stoi(injectArgvs_[SEND_EVENT_TYPE_INDEX]));
264 event.code = static_cast<uint16_t>(std::stoi(injectArgvs_[SEND_EVENT_CODE_INDEX]));
265 event.value = static_cast<int32_t>(std::stoi(injectArgvs_[SEND_EVENT_VALUE_INDEX]));
266 int32_t ret = write(fd, &event, sizeof(event));
267 if (ret != sizeof(event)) {
268 MMI_HILOGE("Send event to device node failed.");
269 return RET_ERR;
270 }
271 if (fd >= 0) {
272 close(fd);
273 }
274 return RET_OK;
275 }
276 } // namespace MMI
277 } // namespace OHOS
278