• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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