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_tools_help_func.h"
17
18 #include <getopt.h>
19
20 #include <algorithm>
21 #include <iostream>
22 #include <string>
23
24 #include <unistd.h>
25
26 namespace OHOS {
27 namespace MMI {
28 namespace {
29 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "InjectionToolsHelpFunc" };
30 constexpr int32_t SEND_EVENT_ARGV_COUNTS = 6;
31 constexpr int32_t JSON_ARGV_COUNTS = 3;
32 constexpr int32_t HELP_ARGV_COUNTS = 2;
33 constexpr int32_t SHORT_OPTION_LENGTH = 2;
34 } // namespace
35
CheckInjectionCommand(int32_t argc,char ** argv)36 bool InjectionToolsHelpFunc::CheckInjectionCommand(int32_t argc, char **argv)
37 {
38 CALL_DEBUG_ENTER;
39 int32_t c = -1;
40 if (!SelectOptions(argc, argv, c)) {
41 MMI_HILOGE("Select option failed");
42 return false;
43 }
44 switch (c) {
45 case 'S': {
46 if (!SendEventOption(argc, argv)) {
47 MMI_HILOGE("SendEvent option failed");
48 return false;
49 }
50 break;
51 }
52 case 'J': {
53 if (!JsonOption(argc, argv)) {
54 MMI_HILOGE("Json option failed");
55 return false;
56 }
57 break;
58 }
59 case '?': {
60 if (!HelpOption(argc, argv)) {
61 MMI_HILOGE("Help option failed");
62 return false;
63 }
64 break;
65 }
66 default: {
67 std::cout << "invalid command" << std::endl;
68 return false;
69 }
70 }
71 return true;
72 }
73
SelectOptions(int32_t argc,char ** argv,int32_t & opt)74 bool InjectionToolsHelpFunc::SelectOptions(int32_t argc, char **argv, int32_t &opt)
75 {
76 CALL_DEBUG_ENTER;
77 if (argc < SHORT_OPTION_LENGTH) {
78 std::cout << "Please enter options or parameters" << std::endl;
79 return false;
80 }
81 struct option longOptions[] = {
82 {"sendevent", no_argument, nullptr, 'S'},
83 {"json", no_argument, nullptr, 'J'},
84 {"help", no_argument, nullptr, '?'},
85 {nullptr, 0, nullptr, 0}
86 };
87 std::string inputOptions = argv[optind];
88 if (inputOptions.find('-') == inputOptions.npos) {
89 for (uint32_t i = 0; i < sizeof(longOptions) / sizeof(struct option) - 1; ++i) {
90 if (longOptions[i].name == inputOptions) {
91 opt = longOptions[i].val;
92 optind++;
93 break;
94 }
95 }
96 } else if ((inputOptions.length() != SHORT_OPTION_LENGTH) && (inputOptions[inputOptions.find('-') + 1] != '-')) {
97 std::cout << "More than one short option is not supported" << std::endl;
98 return false;
99 } else {
100 int32_t optionIndex = 0;
101 opt = getopt_long(argc, argv, "SJ?", longOptions, &optionIndex);
102 }
103 if (opt == -1) {
104 std::cout << "Nonstandard input parameters" << std::endl;
105 return false;
106 }
107 return true;
108 }
109
SendEventOption(int32_t argc,char ** argv)110 bool InjectionToolsHelpFunc::SendEventOption(int32_t argc, char **argv)
111 {
112 CALL_DEBUG_ENTER;
113 if (argc != SEND_EVENT_ARGV_COUNTS) {
114 std::cout << "Wrong number of input parameters" << std::endl;
115 return false;
116 }
117 std::string deviceNode = argv[optind];
118 if (deviceNode.empty()) {
119 std::cout << "Device node does not exist: " << deviceNode.c_str() << std::endl;
120 return false;
121 }
122 char realPath[PATH_MAX] = {};
123 if (realpath(deviceNode.c_str(), realPath) == nullptr) {
124 std::cout << "Device node path is error, path: " << deviceNode.c_str() << std::endl;
125 return false;
126 }
127 while (++optind < argc) {
128 std::string deviceInfo = argv[optind];
129 if (!IsNumberic(deviceInfo)) {
130 std::cout << "Parameter is error, element: " << deviceInfo.c_str() << std::endl;
131 return false;
132 }
133 }
134 SetArgvs(argc, argv, "sendevent");
135 return true;
136 }
137
JsonOption(int32_t argc,char ** argv)138 bool InjectionToolsHelpFunc::JsonOption(int32_t argc, char **argv)
139 {
140 CALL_DEBUG_ENTER;
141 if (argc < JSON_ARGV_COUNTS) {
142 std::cout << "Wrong number of input parameters" << std::endl;
143 return false;
144 }
145 const std::string jsonFile = argv[optind];
146 std::string jsonBuf = ReadJsonFile(jsonFile);
147 if (jsonBuf.empty()) {
148 return false;
149 }
150 SetArgvs(argc, argv, "json");
151 return true;
152 }
153
HelpOption(int32_t argc,char ** argv)154 bool InjectionToolsHelpFunc::HelpOption(int32_t argc, char **argv)
155 {
156 CALL_DEBUG_ENTER;
157 if (argc != HELP_ARGV_COUNTS) {
158 std::cout << "Wrong number of input parameters" << std::endl;
159 return false;
160 }
161 SetArgvs(argc, argv, "help");
162 return true;
163 }
164
IsNumberic(const std::string & str)165 bool InjectionToolsHelpFunc::IsNumberic(const std::string &str)
166 {
167 return !str.empty() && std::all_of(str.begin(), str.end(), ::isdigit);
168 }
169
SetArgvs(int32_t argc,char ** argv,const std::string & str)170 void InjectionToolsHelpFunc::SetArgvs(int32_t argc, char **argv, const std::string &str)
171 {
172 injectArgvs_.clear();
173 injectArgvs_.push_back(str);
174 for (int32_t i = SHORT_OPTION_LENGTH; i < argc; ++i) {
175 injectArgvs_.push_back(argv[i]);
176 }
177 }
178
GetArgvs() const179 std::vector<std::string> InjectionToolsHelpFunc::GetArgvs() const
180 {
181 return injectArgvs_;
182 }
183
ShowUsage()184 void InjectionToolsHelpFunc::ShowUsage()
185 {
186 std::cout << "Usage: mmi-event-injection <option> <command> <arg>..." << std::endl;
187 std::cout << "The option are: " << std::endl;
188 std::cout << "commands for sendevent: " << std::endl;
189 std::cout << " -inject the original event to the device node" << std::endl;
190 std::cout << "-S <device_node> <type> <code> <value> " << std::endl;
191 std::cout << "--sendevent <device_node> <type> <code> <value> " << std::endl;
192 std::cout << "sendevent <device_node> <type> <code> <value> " << std::endl;
193 std::cout << "commands for json: " << std::endl;
194 std::cout << " -Inject a json file that writes all action information to the virtual device" << std::endl;
195 std::cout << "-J <file_name> --json <file_name> josn <file_name>" << std::endl;
196 std::cout << "-? --help help " << std::endl;
197 }
198 } // namespace MMI
199 } // namespace OHOS
200