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