1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at 6c29fa5a6Sopenharmony_ci * 7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c29fa5a6Sopenharmony_ci * 9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and 13c29fa5a6Sopenharmony_ci * limitations under the License. 14c29fa5a6Sopenharmony_ci */ 15c29fa5a6Sopenharmony_ci 16c29fa5a6Sopenharmony_ci#include "injection_event_dispatch.h" 17c29fa5a6Sopenharmony_ci 18c29fa5a6Sopenharmony_ci#include <cctype> 19c29fa5a6Sopenharmony_ci#include <cstdio> 20c29fa5a6Sopenharmony_ci#include <iostream> 21c29fa5a6Sopenharmony_ci#include <regex> 22c29fa5a6Sopenharmony_ci#include <string> 23c29fa5a6Sopenharmony_ci#include <typeinfo> 24c29fa5a6Sopenharmony_ci 25c29fa5a6Sopenharmony_ci#include "error_multimodal.h" 26c29fa5a6Sopenharmony_ci#include "input_parse.h" 27c29fa5a6Sopenharmony_ci#include "proto.h" 28c29fa5a6Sopenharmony_ci#include "util.h" 29c29fa5a6Sopenharmony_ci 30c29fa5a6Sopenharmony_ci#undef MMI_LOG_TAG 31c29fa5a6Sopenharmony_ci#define MMI_LOG_TAG "InjectionEventDispatch" 32c29fa5a6Sopenharmony_ci 33c29fa5a6Sopenharmony_cinamespace OHOS { 34c29fa5a6Sopenharmony_cinamespace MMI { 35c29fa5a6Sopenharmony_cinamespace { 36c29fa5a6Sopenharmony_ciconstexpr uint32_t SEND_EVENT_ARGV_COUNTS { 5 }; 37c29fa5a6Sopenharmony_ciconstexpr uint32_t SEND_EVENT_DEV_NODE_INDEX { 1 }; 38c29fa5a6Sopenharmony_ciconstexpr uint32_t SEND_EVENT_TYPE_INDEX { 2 }; 39c29fa5a6Sopenharmony_ciconstexpr uint32_t SEND_EVENT_CODE_INDEX { 3 }; 40c29fa5a6Sopenharmony_ciconstexpr uint32_t SEND_EVENT_VALUE_INDEX { 4 }; 41c29fa5a6Sopenharmony_ciconstexpr int32_t ARGVS_TARGET_INDEX { 0 }; 42c29fa5a6Sopenharmony_ciconstexpr int32_t ARGVS_CODE_INDEX { 2 }; 43c29fa5a6Sopenharmony_ciconstexpr int32_t JSON_FILE_PATH_INDEX { 1 }; 44c29fa5a6Sopenharmony_ciconstexpr uint32_t INPUT_TYPE_LENGTH { 3 }; 45c29fa5a6Sopenharmony_ciconstexpr uint16_t INPUT_TYPE_MAX { 100 }; 46c29fa5a6Sopenharmony_ciconstexpr uint32_t INPUT_CODE_LENGTH { 6 }; 47c29fa5a6Sopenharmony_ciconstexpr uint32_t INPUT_VALUE_LENGTH { 11 }; 48c29fa5a6Sopenharmony_ci} // namespace 49c29fa5a6Sopenharmony_ci 50c29fa5a6Sopenharmony_civoid InjectionEventDispatch::Init() 51c29fa5a6Sopenharmony_ci{ 52c29fa5a6Sopenharmony_ci InitManageFunction(); 53c29fa5a6Sopenharmony_ci} 54c29fa5a6Sopenharmony_ci 55c29fa5a6Sopenharmony_civoid InjectionEventDispatch::InitManageFunction() 56c29fa5a6Sopenharmony_ci{ 57c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 58c29fa5a6Sopenharmony_ci InjectFunctionMap funs[] = { 59c29fa5a6Sopenharmony_ci {"help", [this] { return this->OnHelp(); }}, 60c29fa5a6Sopenharmony_ci {"sendevent", [this] { return this->OnSendEvent(); }}, 61c29fa5a6Sopenharmony_ci {"json", [this] { return this->OnJson(); }}, 62c29fa5a6Sopenharmony_ci }; 63c29fa5a6Sopenharmony_ci 64c29fa5a6Sopenharmony_ci for (auto &it : funs) { 65c29fa5a6Sopenharmony_ci if (!RegisterInjectEvent(it)) { 66c29fa5a6Sopenharmony_ci MMI_HILOGW("Failed to register event errCode:%{public}d", EVENT_REG_FAIL); 67c29fa5a6Sopenharmony_ci continue; 68c29fa5a6Sopenharmony_ci } 69c29fa5a6Sopenharmony_ci } 70c29fa5a6Sopenharmony_ci} 71c29fa5a6Sopenharmony_ci 72c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::OnJson() 73c29fa5a6Sopenharmony_ci{ 74c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 75c29fa5a6Sopenharmony_ci if (injectArgvs_.size() < ARGVS_CODE_INDEX) { 76c29fa5a6Sopenharmony_ci MMI_HILOGE("Path is error"); 77c29fa5a6Sopenharmony_ci return RET_ERR; 78c29fa5a6Sopenharmony_ci } 79c29fa5a6Sopenharmony_ci std::string jsonBuf = ReadJsonFile(injectArgvs_.at(JSON_FILE_PATH_INDEX)); 80c29fa5a6Sopenharmony_ci if (jsonBuf.empty()) { 81c29fa5a6Sopenharmony_ci MMI_HILOGE("Read file failed"); 82c29fa5a6Sopenharmony_ci return RET_ERR; 83c29fa5a6Sopenharmony_ci } 84c29fa5a6Sopenharmony_ci bool logStatus = false; 85c29fa5a6Sopenharmony_ci if (injectArgvs_.size() > ARGVS_CODE_INDEX) { 86c29fa5a6Sopenharmony_ci if (injectArgvs_.at(ARGVS_CODE_INDEX) == "log") { 87c29fa5a6Sopenharmony_ci logStatus = true; 88c29fa5a6Sopenharmony_ci } 89c29fa5a6Sopenharmony_ci } 90c29fa5a6Sopenharmony_ci return manageInjectDevice_.TransformJsonData(DataInit(jsonBuf, logStatus)); 91c29fa5a6Sopenharmony_ci} 92c29fa5a6Sopenharmony_ci 93c29fa5a6Sopenharmony_civoid InjectionEventDispatch::SetArgvs(const std::vector<std::string> &injectArgvs) 94c29fa5a6Sopenharmony_ci{ 95c29fa5a6Sopenharmony_ci injectArgvs_ = injectArgvs; 96c29fa5a6Sopenharmony_ci} 97c29fa5a6Sopenharmony_ci 98c29fa5a6Sopenharmony_cistd::string InjectionEventDispatch::GetFunId() const 99c29fa5a6Sopenharmony_ci{ 100c29fa5a6Sopenharmony_ci return funId_; 101c29fa5a6Sopenharmony_ci} 102c29fa5a6Sopenharmony_ci 103c29fa5a6Sopenharmony_cibool InjectionEventDispatch::VerifyArgvs() 104c29fa5a6Sopenharmony_ci{ 105c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 106c29fa5a6Sopenharmony_ci std::string temp = injectArgvs_.at(ARGVS_TARGET_INDEX); 107c29fa5a6Sopenharmony_ci if (temp.empty()) { 108c29fa5a6Sopenharmony_ci MMI_HILOGE("Invalid Input parameter"); 109c29fa5a6Sopenharmony_ci return false; 110c29fa5a6Sopenharmony_ci } 111c29fa5a6Sopenharmony_ci auto it = injectFuns_.find(temp); 112c29fa5a6Sopenharmony_ci if (it == injectFuns_.end()) { 113c29fa5a6Sopenharmony_ci MMI_HILOGE("Parameter bound function not found"); 114c29fa5a6Sopenharmony_ci return false; 115c29fa5a6Sopenharmony_ci } 116c29fa5a6Sopenharmony_ci funId_ = temp; 117c29fa5a6Sopenharmony_ci return true; 118c29fa5a6Sopenharmony_ci} 119c29fa5a6Sopenharmony_ci 120c29fa5a6Sopenharmony_civoid InjectionEventDispatch::Run() 121c29fa5a6Sopenharmony_ci{ 122c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 123c29fa5a6Sopenharmony_ci std::string id = GetFunId(); 124c29fa5a6Sopenharmony_ci auto fun = GetFun(id); 125c29fa5a6Sopenharmony_ci CHKPV(fun); 126c29fa5a6Sopenharmony_ci auto ret = (*fun)(); 127c29fa5a6Sopenharmony_ci if (ret == RET_OK) { 128c29fa5a6Sopenharmony_ci MMI_HILOGI("Inject function success id:%{public}s", id.c_str()); 129c29fa5a6Sopenharmony_ci } else { 130c29fa5a6Sopenharmony_ci MMI_HILOGE("Inject function failed id:%{public}s", id.c_str()); 131c29fa5a6Sopenharmony_ci } 132c29fa5a6Sopenharmony_ci} 133c29fa5a6Sopenharmony_ci 134c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::ExecuteFunction(std::string funId) 135c29fa5a6Sopenharmony_ci{ 136c29fa5a6Sopenharmony_ci if (funId.empty()) { 137c29fa5a6Sopenharmony_ci return RET_ERR; 138c29fa5a6Sopenharmony_ci } 139c29fa5a6Sopenharmony_ci auto fun = GetFun(funId); 140c29fa5a6Sopenharmony_ci if (!fun) { 141c29fa5a6Sopenharmony_ci MMI_HILOGE("Event injection Unknown fuction id:%{public}s", funId.c_str()); 142c29fa5a6Sopenharmony_ci return false; 143c29fa5a6Sopenharmony_ci } 144c29fa5a6Sopenharmony_ci MMI_HILOGI("Inject tools into function:%{public}s", funId.c_str()); 145c29fa5a6Sopenharmony_ci int32_t ret = RET_ERR; 146c29fa5a6Sopenharmony_ci ret = (*fun)(); 147c29fa5a6Sopenharmony_ci if (ret == RET_OK) { 148c29fa5a6Sopenharmony_ci MMI_HILOGI("Inject function success id:%{public}s", funId.c_str()); 149c29fa5a6Sopenharmony_ci } else { 150c29fa5a6Sopenharmony_ci MMI_HILOGE("Inject function failed id:%{public}s", funId.c_str()); 151c29fa5a6Sopenharmony_ci } 152c29fa5a6Sopenharmony_ci 153c29fa5a6Sopenharmony_ci return ret; 154c29fa5a6Sopenharmony_ci} 155c29fa5a6Sopenharmony_ci 156c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::OnHelp() 157c29fa5a6Sopenharmony_ci{ 158c29fa5a6Sopenharmony_ci InjectionToolsHelpFunc helpFunc; 159c29fa5a6Sopenharmony_ci helpFunc.ShowUsage(); 160c29fa5a6Sopenharmony_ci return RET_OK; 161c29fa5a6Sopenharmony_ci} 162c29fa5a6Sopenharmony_ci 163c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::GetDeviceIndex(const std::string &deviceNameText) const 164c29fa5a6Sopenharmony_ci{ 165c29fa5a6Sopenharmony_ci if (deviceNameText.empty()) { 166c29fa5a6Sopenharmony_ci MMI_HILOGE("The deviceNameText is empty"); 167c29fa5a6Sopenharmony_ci return RET_ERR; 168c29fa5a6Sopenharmony_ci } 169c29fa5a6Sopenharmony_ci for (const auto &item : allDevices_) { 170c29fa5a6Sopenharmony_ci if (deviceNameText == item.chipName) { 171c29fa5a6Sopenharmony_ci return item.devIndex; 172c29fa5a6Sopenharmony_ci } 173c29fa5a6Sopenharmony_ci } 174c29fa5a6Sopenharmony_ci MMI_HILOGW("Get device index failed"); 175c29fa5a6Sopenharmony_ci return RET_ERR; 176c29fa5a6Sopenharmony_ci} 177c29fa5a6Sopenharmony_ci 178c29fa5a6Sopenharmony_cibool InjectionEventDispatch::CheckValue(const std::string &inputValue) 179c29fa5a6Sopenharmony_ci{ 180c29fa5a6Sopenharmony_ci if ((inputValue.length()) > INPUT_VALUE_LENGTH) { 181c29fa5a6Sopenharmony_ci MMI_HILOGE("The value entered is out of range, value:%{public}s", inputValue.c_str()); 182c29fa5a6Sopenharmony_ci return false; 183c29fa5a6Sopenharmony_ci } 184c29fa5a6Sopenharmony_ci bool isValueNumber = regex_match(inputValue, std::regex("(-[\\d+]+)|(\\d+)")); 185c29fa5a6Sopenharmony_ci if (isValueNumber) { 186c29fa5a6Sopenharmony_ci int32_t numberValue = stoi(inputValue); 187c29fa5a6Sopenharmony_ci if ((numberValue >= INT32_MIN) && (numberValue <= INT32_MAX)) { 188c29fa5a6Sopenharmony_ci return true; 189c29fa5a6Sopenharmony_ci } 190c29fa5a6Sopenharmony_ci } 191c29fa5a6Sopenharmony_ci return false; 192c29fa5a6Sopenharmony_ci} 193c29fa5a6Sopenharmony_ci 194c29fa5a6Sopenharmony_cibool InjectionEventDispatch::CheckCode(const std::string &inputCode) 195c29fa5a6Sopenharmony_ci{ 196c29fa5a6Sopenharmony_ci if ((inputCode.length()) > INPUT_CODE_LENGTH) { 197c29fa5a6Sopenharmony_ci MMI_HILOGE("The value entered is out of range, code:%{public}s", inputCode.c_str()); 198c29fa5a6Sopenharmony_ci return false; 199c29fa5a6Sopenharmony_ci } 200c29fa5a6Sopenharmony_ci bool isCodeNumber = regex_match(inputCode, std::regex("\\d+")); 201c29fa5a6Sopenharmony_ci if (isCodeNumber) { 202c29fa5a6Sopenharmony_ci int32_t numberCode = stoi(inputCode); 203c29fa5a6Sopenharmony_ci if ((numberCode >= 0) && (numberCode <= UINT16_MAX)) { 204c29fa5a6Sopenharmony_ci return true; 205c29fa5a6Sopenharmony_ci } 206c29fa5a6Sopenharmony_ci } 207c29fa5a6Sopenharmony_ci return false; 208c29fa5a6Sopenharmony_ci} 209c29fa5a6Sopenharmony_ci 210c29fa5a6Sopenharmony_cibool InjectionEventDispatch::CheckType(const std::string &inputType) 211c29fa5a6Sopenharmony_ci{ 212c29fa5a6Sopenharmony_ci if ((inputType.length()) > INPUT_TYPE_LENGTH) { 213c29fa5a6Sopenharmony_ci MMI_HILOGE("The value entered is out of range, type:%{public}s", inputType.c_str()); 214c29fa5a6Sopenharmony_ci return false; 215c29fa5a6Sopenharmony_ci } 216c29fa5a6Sopenharmony_ci bool isTypeNumber = regex_match(inputType, std::regex("\\d+")); 217c29fa5a6Sopenharmony_ci if (isTypeNumber) { 218c29fa5a6Sopenharmony_ci int32_t numberType = stoi(inputType); 219c29fa5a6Sopenharmony_ci if ((numberType >= 0) && (numberType <= INPUT_TYPE_MAX)) { 220c29fa5a6Sopenharmony_ci return true; 221c29fa5a6Sopenharmony_ci } 222c29fa5a6Sopenharmony_ci } 223c29fa5a6Sopenharmony_ci return false; 224c29fa5a6Sopenharmony_ci} 225c29fa5a6Sopenharmony_ci 226c29fa5a6Sopenharmony_cibool InjectionEventDispatch::CheckEventValue(const std::string &inputType, const std::string &inputCode, 227c29fa5a6Sopenharmony_ci const std::string &inputValue) 228c29fa5a6Sopenharmony_ci{ 229c29fa5a6Sopenharmony_ci if (!(CheckType(inputType))) { 230c29fa5a6Sopenharmony_ci MMI_HILOGE("Input error in type, type:%{public}s", inputType.c_str()); 231c29fa5a6Sopenharmony_ci return false; 232c29fa5a6Sopenharmony_ci } 233c29fa5a6Sopenharmony_ci if (!(CheckCode(inputCode))) { 234c29fa5a6Sopenharmony_ci MMI_HILOGE("Input error in code, code:%{public}s", inputCode.c_str()); 235c29fa5a6Sopenharmony_ci return false; 236c29fa5a6Sopenharmony_ci } 237c29fa5a6Sopenharmony_ci if (!(CheckValue(inputValue))) { 238c29fa5a6Sopenharmony_ci MMI_HILOGE("Input error in value, value:%{public}s", inputValue.c_str()); 239c29fa5a6Sopenharmony_ci return false; 240c29fa5a6Sopenharmony_ci } 241c29fa5a6Sopenharmony_ci return true; 242c29fa5a6Sopenharmony_ci} 243c29fa5a6Sopenharmony_ci 244c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::OnSendEvent() 245c29fa5a6Sopenharmony_ci{ 246c29fa5a6Sopenharmony_ci if (injectArgvs_.size() != SEND_EVENT_ARGV_COUNTS) { 247c29fa5a6Sopenharmony_ci MMI_HILOGE("Wrong number of input parameters, errCode:%{public}d", PARAM_INPUT_FAIL); 248c29fa5a6Sopenharmony_ci return RET_ERR; 249c29fa5a6Sopenharmony_ci } 250c29fa5a6Sopenharmony_ci std::string deviceNode = injectArgvs_[SEND_EVENT_DEV_NODE_INDEX]; 251c29fa5a6Sopenharmony_ci if (deviceNode.empty()) { 252c29fa5a6Sopenharmony_ci MMI_HILOGE("Device node:%{public}s is not existent", deviceNode.c_str()); 253c29fa5a6Sopenharmony_ci return RET_ERR; 254c29fa5a6Sopenharmony_ci } 255c29fa5a6Sopenharmony_ci char realPath[PATH_MAX] = {}; 256c29fa5a6Sopenharmony_ci if (realpath(deviceNode.c_str(), realPath) == nullptr) { 257c29fa5a6Sopenharmony_ci MMI_HILOGE("Path is error, path:%{private}s", deviceNode.c_str()); 258c29fa5a6Sopenharmony_ci return RET_ERR; 259c29fa5a6Sopenharmony_ci } 260c29fa5a6Sopenharmony_ci int32_t fd = open(realPath, O_RDWR); 261c29fa5a6Sopenharmony_ci if (fd < 0) { 262c29fa5a6Sopenharmony_ci MMI_HILOGE("Open device node:%{public}s failed, errCode:%{public}d", deviceNode.c_str(), FILE_OPEN_FAIL); 263c29fa5a6Sopenharmony_ci return RET_ERR; 264c29fa5a6Sopenharmony_ci } 265c29fa5a6Sopenharmony_ci struct timeval tm; 266c29fa5a6Sopenharmony_ci gettimeofday(&tm, 0); 267c29fa5a6Sopenharmony_ci struct input_event event = {}; 268c29fa5a6Sopenharmony_ci event.input_event_sec = tm.tv_sec; 269c29fa5a6Sopenharmony_ci event.input_event_usec = tm.tv_usec; 270c29fa5a6Sopenharmony_ci if (!(CheckEventValue(injectArgvs_[SEND_EVENT_TYPE_INDEX], injectArgvs_[SEND_EVENT_CODE_INDEX], 271c29fa5a6Sopenharmony_ci injectArgvs_[SEND_EVENT_VALUE_INDEX]))) { 272c29fa5a6Sopenharmony_ci return RET_ERR; 273c29fa5a6Sopenharmony_ci } 274c29fa5a6Sopenharmony_ci event.type = static_cast<uint16_t>(std::stoi(injectArgvs_[SEND_EVENT_TYPE_INDEX])); 275c29fa5a6Sopenharmony_ci event.code = static_cast<uint16_t>(std::stoi(injectArgvs_[SEND_EVENT_CODE_INDEX])); 276c29fa5a6Sopenharmony_ci event.value = static_cast<int32_t>(std::stoi(injectArgvs_[SEND_EVENT_VALUE_INDEX])); 277c29fa5a6Sopenharmony_ci int32_t ret = write(fd, &event, sizeof(event)); 278c29fa5a6Sopenharmony_ci if (ret != sizeof(event)) { 279c29fa5a6Sopenharmony_ci MMI_HILOGE("Send event to device node failed"); 280c29fa5a6Sopenharmony_ci return RET_ERR; 281c29fa5a6Sopenharmony_ci } 282c29fa5a6Sopenharmony_ci if (fd >= 0) { 283c29fa5a6Sopenharmony_ci close(fd); 284c29fa5a6Sopenharmony_ci } 285c29fa5a6Sopenharmony_ci return RET_OK; 286c29fa5a6Sopenharmony_ci} 287c29fa5a6Sopenharmony_ci 288c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::GetDevTypeIndex(int32_t devIndex) const 289c29fa5a6Sopenharmony_ci{ 290c29fa5a6Sopenharmony_ci for (const auto &item : allDevices_) { 291c29fa5a6Sopenharmony_ci if (devIndex == item.devIndex) { 292c29fa5a6Sopenharmony_ci return item.devType; 293c29fa5a6Sopenharmony_ci } 294c29fa5a6Sopenharmony_ci } 295c29fa5a6Sopenharmony_ci return RET_ERR; 296c29fa5a6Sopenharmony_ci} 297c29fa5a6Sopenharmony_ci 298c29fa5a6Sopenharmony_ciint32_t InjectionEventDispatch::GetDevIndexType(int32_t devType) const 299c29fa5a6Sopenharmony_ci{ 300c29fa5a6Sopenharmony_ci for (const auto &item : allDevices_) { 301c29fa5a6Sopenharmony_ci if (item.devType == devType) { 302c29fa5a6Sopenharmony_ci return item.devIndex; 303c29fa5a6Sopenharmony_ci } 304c29fa5a6Sopenharmony_ci } 305c29fa5a6Sopenharmony_ci return RET_ERR; 306c29fa5a6Sopenharmony_ci} 307c29fa5a6Sopenharmony_ci} // namespace MMI 308c29fa5a6Sopenharmony_ci} // namespace OHOS 309