• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "common_event_command.h"
17 
18 #include <getopt.h>
19 
20 #include "common_event.h"
21 #include "common_event_constant.h"
22 #include "common_event_manager.h"
23 #include "event_log_wrapper.h"
24 #include "singleton.h"
25 
26 namespace OHOS {
27 namespace EventFwk {
28 namespace {
29 const std::string SHORT_OPTIONS = "he:asoc:d:u:";
30 const struct option LONG_OPTIONS[] = {
31     {"help", no_argument, nullptr, 'h'},
32     {"all", no_argument, nullptr, 'a'},
33     {"event", required_argument, nullptr, 'e'},
34     {"sticky", no_argument, nullptr, 's'},
35     {"ordered", no_argument, nullptr, 'o'},
36     {"code", required_argument, nullptr, 'c'},
37     {"data", required_argument, nullptr, 'd'},
38     {"user-id", required_argument, nullptr, 'u'},
39 };
40 }  // namespace
41 
CommonEventCommand(int argc,char * argv[])42 CommonEventCommand::CommonEventCommand(int argc, char *argv[])
43     : ShellCommand(argc, argv, TOOL_NAME)
44 {
45     EVENT_LOGI("enter");
46 
47     for (int i = 0; i < argc_; i++) {
48         EVENT_LOGI("argv_[%{public}d]: %{public}s", i, argv_[i]);
49     }
50 }
51 
CreateCommandMap()52 ErrCode CommonEventCommand::CreateCommandMap()
53 {
54     commandMap_ = {
55         {"help", std::bind(&CommonEventCommand::RunAsHelpCommand, this)},
56         {"publish", std::bind(&CommonEventCommand::RunAsPublishCommand, this)},
57         {"dump", std::bind(&CommonEventCommand::RunAsDumpCommand, this)},
58     };
59 
60     return OHOS::ERR_OK;
61 }
62 
CreateMessageMap()63 ErrCode CommonEventCommand::CreateMessageMap()
64 {
65     messageMap_ = {};
66 
67     return OHOS::ERR_OK;
68 }
69 
init()70 ErrCode CommonEventCommand::init()
71 {
72     EVENT_LOGI("enter");
73 
74     ErrCode result = OHOS::ERR_OK;
75 
76     if (!commonEventPtr_) {
77         commonEventPtr_ = DelayedSingleton<CommonEvent>::GetInstance();
78     }
79 
80     if (!commonEventPtr_) {
81         result = OHOS::ERR_INVALID_VALUE;
82     }
83 
84     return result;
85 }
86 
RunAsHelpCommand()87 ErrCode CommonEventCommand::RunAsHelpCommand()
88 {
89     EVENT_LOGI("enter");
90 
91     resultReceiver_.append(HELP_MSG);
92 
93     return OHOS::ERR_OK;
94 }
95 
RunAsPublishCommand()96 ErrCode CommonEventCommand::RunAsPublishCommand()
97 {
98     EVENT_LOGI("enter");
99 
100     ErrCode result = OHOS::ERR_OK;
101 
102     int option = -1;
103     std::int32_t userId = ALL_USER;
104     int counter = 0;
105 
106     bool isSticky = false;
107     bool isOrdered = false;
108 
109     std::string action = "";
110     int code = 0;
111     std::string data = "";
112 
113     while (true) {
114         counter++;
115 
116         option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
117 
118         EVENT_LOGI("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
119 
120         if (optind < 0 || optind > argc_) {
121             return OHOS::ERR_INVALID_VALUE;
122         }
123 
124         for (int i = 0; i < argc_; i++) {
125             EVENT_LOGI("argv_[%{public}d]: %{public}s", i, argv_[i]);
126         }
127 
128         if (option == -1) {
129             if (counter == 1) {
130                 // When scanning the first argument
131                 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
132                     // 'cem publish' with no option: cem publish
133                     // 'cem publish' with a wrong argument: cem publish xxx
134                     EVENT_LOGI("'cem publish' with no option.");
135 
136                     resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
137 
138                     result = OHOS::ERR_INVALID_VALUE;
139                 }
140             }
141             break;
142         }
143 
144         if (option == '?') {
145             switch (optopt) {
146                 case 'e': {
147                     // 'cem publish -e' with no argument: cem publish -e
148                     // 'cem publish --event' with no argument: cem publish --event
149                     EVENT_LOGI("'cem publish -e' with no argument.");
150 
151                     resultReceiver_.append("error: option ");
152                     resultReceiver_.append("requires a value.\n");
153 
154                     result = OHOS::ERR_INVALID_VALUE;
155                     break;
156                 }
157                 case 'c': {
158                     // 'cem publish -e <name> -c' with no argument: cem publish -e <name> -c
159                     // 'cem publish --event <name> -c' with no argument: cem publish --event -c
160                     EVENT_LOGI("'cem publish -e <name> -c' with no argument.");
161 
162                     resultReceiver_.append("error: option ");
163                     resultReceiver_.append("requires a value.\n");
164 
165                     result = OHOS::ERR_INVALID_VALUE;
166                     break;
167                 }
168                 case 'd': {
169                     // 'cem publish -e <name> -d' with no argument: cem publish -e <name> -d
170                     // 'cem publish --event <name> -d' with no argument: cem publish --event -d
171                     EVENT_LOGI("'cem publish -e <name> -d' with no argument.");
172 
173                     resultReceiver_.append("error: option ");
174                     resultReceiver_.append("requires a value.\n");
175 
176                     result = OHOS::ERR_INVALID_VALUE;
177                     break;
178                 }
179                 case 'u':
180                     // 'cem publish -e <name> -u' with no argument: cem publish -e <name> -d
181                     // 'cem publish --event <name> -d' with no argument: cem publish --event -d
182                     EVENT_LOGI("'cem publish -e <name> -u' with no argument.");
183 
184                     resultReceiver_.append("error: option ");
185                     resultReceiver_.append("requires a value.\n");
186 
187                     result = OHOS::ERR_INVALID_VALUE;
188                     break;
189                 case 0: {
190                     // 'cem publish' with an unknown option: cem publish --x
191                     // 'cem publish' with an unknown option: cem publish --xxx
192                     std::string unknownOption = "";
193                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
194 
195                     EVENT_LOGI("'cem publish' with an unknown option.");
196 
197                     resultReceiver_.append(unknownOptionMsg);
198                     result = OHOS::ERR_INVALID_VALUE;
199                     break;
200                 }
201                 default: {
202                     // 'cem publish' with an unknown option: cem publish -x
203                     // 'cem publish' with an unknown option: cem publish -xxx
204                     std::string unknownOption = "";
205                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
206 
207                     EVENT_LOGI("'cem publish' with an unknown option.");
208 
209                     resultReceiver_.append(unknownOptionMsg);
210                     result = OHOS::ERR_INVALID_VALUE;
211                     break;
212                 }
213             }
214             break;
215         }
216 
217         switch (option) {
218             case 'h': {
219                 // 'cem publish -h'
220                 // 'cem publish --help'
221                 result = OHOS::ERR_INVALID_VALUE;
222                 break;
223             }
224             case 'e': {
225                 // 'cem publish -e <name>'
226                 // 'cem publish --event <name>'
227                 action = optarg;
228                 break;
229             }
230             case 's': {
231                 // 'cem publish -e <name> -s '
232                 // 'cem publish -e <name> --sticky'
233                 isSticky = true;
234                 break;
235             }
236             case 'o': {
237                 // 'cem publish -e <name> -o '
238                 // 'cem publish -e <name> --ordered'
239                 isOrdered = true;
240                 break;
241             }
242             case 'c': {
243                 // 'cem publish -e <name> -c 1024 '
244                 // 'cem publish -e <name> --code 1024'
245                 code = atoi(optarg);
246                 break;
247             }
248             case 'd': {
249                 // 'cem publish -e <name> -d 1024 '
250                 // 'cem publish -e <name> --data 1024'
251                 data = optarg;
252                 break;
253             }
254             case 'u': {
255                 // 'cem publish -e <name> -u 100'
256                 // 'cem publish --event <name> -u 100'
257                 userId = atoi(optarg);
258                 break;
259             }
260             case 0: {
261                 break;
262             }
263             default: {
264                 break;
265             }
266         }
267     }
268 
269     if (result == OHOS::ERR_OK) {
270         if (resultReceiver_ == "" && action.size() == 0) {
271             // 'cem publish ...' with no event option
272             EVENT_LOGI("'cem publish' with no event option.");
273 
274             resultReceiver_.append(HELP_MSG_NO_EVENT_OPTION + "\n");
275             result = OHOS::ERR_INVALID_VALUE;
276         }
277     }
278 
279     if (result != OHOS::ERR_OK) {
280         resultReceiver_.append(HELP_MSG_PUBLISH);
281     } else {
282         /* Publish */
283 
284         // make a want
285         Want want;
286         want.SetAction(action);
287 
288         // make common event data
289         CommonEventData commonEventData;
290         commonEventData.SetWant(want);
291 
292         // set code
293         commonEventData.SetCode(code);
294 
295         // set data
296         commonEventData.SetData(data);
297 
298         // make publish info
299         CommonEventPublishInfo publishInfo;
300         publishInfo.SetSticky(isSticky);
301         publishInfo.SetOrdered(isOrdered);
302 
303         // publish the common event
304         std::shared_ptr<CommonEventSubscriber> subscriber = nullptr;
305         bool publishResult = commonEventPtr_->PublishCommonEventAsUser(
306             commonEventData, publishInfo, subscriber, userId);
307         if (publishResult) {
308             resultReceiver_ = STRING_PUBLISH_COMMON_EVENT_OK + "\n";
309         } else {
310             resultReceiver_ = STRING_PUBLISH_COMMON_EVENT_NG + "\n";
311         }
312     }
313 
314     return result;
315 }
316 
RunAsDumpCommand()317 ErrCode CommonEventCommand::RunAsDumpCommand()
318 {
319     EVENT_LOGI("enter");
320 
321     ErrCode result = OHOS::ERR_OK;
322     std::vector<std::string> dumpResults;
323 
324     std::string action = "";
325     std::int32_t userId = ALL_USER;
326 
327     int option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
328 
329     EVENT_LOGI("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
330 
331     if (optind < 0 || optind > argc_) {
332         return OHOS::ERR_INVALID_VALUE;
333     }
334 
335     for (int i = 0; i < argc_; i++) {
336         EVENT_LOGI("argv_[%{public}d]: %{public}s", i, argv_[i]);
337     }
338 
339     switch (option) {
340         case 'h': {
341             // 'cem dump -h'
342             // 'cem dump --help'
343             result = OHOS::ERR_INVALID_VALUE;
344             break;
345         }
346         case 'a': {
347             // 'cem dump -a'
348             // 'cem dump --all'
349             break;
350         }
351         case 'e': {
352             // 'cem dump -e <name>'
353             // 'cem dump --event <name>'
354             action = optarg;
355             break;
356         }
357         case 'u': {
358             // 'cem dump -e <name> -u 100'
359             // 'cem dump --event <name> -u 100'
360             userId = atoi(optarg);
361             break;
362         }
363         case '?': {
364             switch (optopt) {
365                 case 'e': {
366                     // 'cem dump -e' with no argument: cem dump -e
367                     // 'cem dump --event' with no argument: cem dump --event
368                     EVENT_LOGI("'cem dump -s' with no argument.");
369 
370                     resultReceiver_.append("error: option ");
371                     resultReceiver_.append("requires a value.\n");
372                     result = OHOS::ERR_INVALID_VALUE;
373                     break;
374                 }
375                 case 'u':
376                     // 'cem dump -e' with no argument: cem dump -e
377                     // 'cem dump --event' with no argument: cem dump --user-id
378                     EVENT_LOGI("'cem dump -u' with no argument.");
379 
380                     resultReceiver_.append("error: option ");
381                     resultReceiver_.append("requires a value.\n");
382                     result = OHOS::ERR_INVALID_VALUE;
383                     break;
384                 case 0: {
385                     // 'cem dump' with an unknown option: cem dump --x
386                     // 'cem dump' with an unknown option: cem dump --xxx
387                     std::string unknownOption = "";
388                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
389 
390                     EVENT_LOGI("'cem dump' with an unknown option.");
391 
392                     resultReceiver_.append(unknownOptionMsg);
393                     result = OHOS::ERR_INVALID_VALUE;
394                     break;
395                 }
396                 default: {
397                     // 'cem dump' with an unknown option: cem dump -x
398                     // 'cem dump' with an unknown option: cem dump -xxx
399                     std::string unknownOption = "";
400                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
401 
402                     EVENT_LOGI("'cem dump' with an unknown option.");
403 
404                     resultReceiver_.append(unknownOptionMsg);
405                     result = OHOS::ERR_INVALID_VALUE;
406                     break;
407                 }
408             }
409             break;
410         }
411         default: {
412             if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
413                 // 'cem dump' with no option: cem dump
414                 // 'cem dump' with a wrong argument: cem dump xxx
415                 EVENT_LOGI("'cem dump' with no option.");
416 
417                 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
418                 result = OHOS::ERR_INVALID_VALUE;
419             }
420             break;
421         }
422     }
423 
424     if (result != OHOS::ERR_OK) {
425         resultReceiver_.append(HELP_MSG_DUMP);
426     } else {
427         // dump state
428         bool dumpResult = commonEventPtr_->DumpState(action, userId, dumpResults);
429         if (dumpResult) {
430             for (auto it : dumpResults) {
431                 resultReceiver_ += it + "\n";
432             }
433         } else {
434             resultReceiver_ = STRING_DUMP_COMMON_EVENT_NG + "\n";
435         }
436     }
437 
438     return result;
439 }
440 }  // namespace EventFwk
441 }  // namespace OHOS
442