• 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 "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