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 "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:p:";
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
CreateCommandMap()42 ErrCode CommonEventCommand::CreateCommandMap()
43 {
44 commandMap_ = {
45 {"help", std::bind(&CommonEventCommand::RunAsHelpCommand, this)},
46 {"publish", std::bind(&CommonEventCommand::RunAsPublishCommand, this)},
47 {"dump", std::bind(&CommonEventCommand::RunAsDumpCommand, this)},
48 };
49 return ERR_OK;
50 }
51
RunAsHelpCommand()52 ErrCode CommonEventCommand::RunAsHelpCommand()
53 {
54 EVENT_LOGI("enter");
55 resultReceiver_.append(HELP_MSG);
56 return ERR_OK;
57 }
58
RunAsPublishCommand()59 ErrCode CommonEventCommand::RunAsPublishCommand()
60 {
61 EVENT_LOGI("enter");
62 ErrCode result = ERR_OK;
63 PublishCmdInfo cmdInfo;
64 bool hasOption = false;
65 SetPublishCmdInfo(cmdInfo, result, hasOption);
66 if (!hasOption) {
67 resultReceiver_.append(HELP_MSG_NO_OPTION);
68 resultReceiver_.append(HELP_MSG_PUBLISH);
69 return ERR_INVALID_VALUE;
70 }
71 if (result == ERR_OK && resultReceiver_.empty() && cmdInfo.action.empty()) {
72 resultReceiver_.append(HELP_MSG_NO_EVENT_OPTION);
73 result = ERR_INVALID_VALUE;
74 }
75 if (result == ERR_OK) {
76 Want want;
77 want.SetAction(cmdInfo.action);
78 CommonEventData commonEventData;
79 commonEventData.SetWant(want);
80 commonEventData.SetCode(cmdInfo.code);
81 commonEventData.SetData(cmdInfo.data);
82 CommonEventPublishInfo publishInfo;
83 publishInfo.SetSticky(cmdInfo.isSticky);
84 publishInfo.SetOrdered(cmdInfo.isOrdered);
85 // publish the common event
86 int32_t publishResult = CommonEvent::GetInstance()->PublishCommonEventAsUser(
87 commonEventData, publishInfo, nullptr, cmdInfo.userId);
88 if (publishResult == ERR_OK) {
89 resultReceiver_ = STRING_PUBLISH_COMMON_EVENT_OK;
90 } else {
91 resultReceiver_ = STRING_PUBLISH_COMMON_EVENT_NG;
92 }
93 } else {
94 resultReceiver_.append(HELP_MSG_PUBLISH);
95 }
96 return result;
97 }
98
SetPublishCmdInfo(PublishCmdInfo & cmdInfo,ErrCode & result,bool & hasOption)99 void CommonEventCommand::SetPublishCmdInfo(PublishCmdInfo &cmdInfo, ErrCode &result, bool &hasOption)
100 {
101 int option;
102 while ((option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr)) != -1) {
103 hasOption = true;
104 if (option == '?') {
105 CheckPublishOpt();
106 result = ERR_INVALID_VALUE;
107 return;
108 }
109 switch (option) {
110 case 'h':
111 result = ERR_INVALID_VALUE;
112 break;
113 case 'e':
114 cmdInfo.action = optarg;
115 break;
116 case 's':
117 cmdInfo.isSticky = true;
118 break;
119 case 'o':
120 cmdInfo.isOrdered = true;
121 break;
122 case 'c':
123 cmdInfo.code = atoi(optarg);
124 break;
125 case 'd':
126 cmdInfo.data = optarg;
127 break;
128 case 'u':
129 cmdInfo.userId = atoi(optarg);
130 break;
131 default:
132 break;
133 }
134 }
135 }
136
CheckPublishOpt()137 void CommonEventCommand::CheckPublishOpt()
138 {
139 switch (optopt) {
140 case 'e': {
141 resultReceiver_.append("error: option 'e' requires a value.\n");
142 break;
143 }
144 case 'c': {
145 resultReceiver_.append("error: option 'c' requires a value.\n");
146 break;
147 }
148 case 'd': {
149 resultReceiver_.append("error: option 'd' requires a value.\n");
150 break;
151 }
152 case 'u': {
153 resultReceiver_.append("error: option 'u' requires a value.\n");
154 break;
155 }
156 default: {
157 resultReceiver_.append("error: unknown option.\n");
158 break;
159 }
160 }
161 }
162
RunAsDumpCommand()163 ErrCode CommonEventCommand::RunAsDumpCommand()
164 {
165 #ifdef CEM_BUILD_VARIANT_USER
166 resultReceiver_.append(USER_DUMP_COMMON_EVENT_NG);
167 return ERR_INVALID_VALUE;
168 #endif
169 EVENT_LOGI("enter");
170 ErrCode result = ERR_OK;
171 bool hasOption = false;
172 DumpCmdInfo cmdInfo;
173 SetDumpCmdInfo(cmdInfo, result, hasOption);
174 if (!hasOption) {
175 resultReceiver_.append(HELP_MSG_NO_OPTION);
176 resultReceiver_.append(HELP_MSG_DUMP);
177 return ERR_INVALID_VALUE;
178 }
179 if (result == ERR_OK) {
180 std::vector<std::string> dumpResults;
181 bool dumpResult = CommonEvent::GetInstance()->DumpState(
182 static_cast<int32_t>(cmdInfo.eventType), cmdInfo.action, cmdInfo.userId, dumpResults);
183 if (dumpResult) {
184 EVENT_LOGI("event size %{public}zu", dumpResults.size());
185 for (const auto &it : dumpResults) {
186 EVENT_LOGI("event %{public}s", it.c_str());
187 resultReceiver_.append(it + "\n");
188 }
189 } else {
190 resultReceiver_ = STRING_DUMP_COMMON_EVENT_NG;
191 }
192 } else {
193 resultReceiver_.append(HELP_MSG_DUMP);
194 }
195 return result;
196 }
197
SetDumpCmdInfo(DumpCmdInfo & cmdInfo,ErrCode & result,bool & hasOption)198 void CommonEventCommand::SetDumpCmdInfo(DumpCmdInfo &cmdInfo, ErrCode &result, bool &hasOption)
199 {
200 int option;
201 while ((option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr)) != -1) {
202 hasOption = true;
203 if (option == '?') {
204 CheckDumpOpt();
205 result = ERR_INVALID_VALUE;
206 return;
207 }
208 switch (option) {
209 case 'h':
210 result = ERR_INVALID_VALUE;
211 break;
212 case 'e':
213 cmdInfo.action = optarg;
214 break;
215 case 'u':
216 cmdInfo.userId = atoi(optarg);
217 break;
218 case 'p':
219 CheckDumpEventType(cmdInfo, result);
220 break;
221 default:
222 break;
223 }
224 }
225 }
226
CheckDumpOpt()227 void CommonEventCommand::CheckDumpOpt()
228 {
229 switch (optopt) {
230 case 'e':
231 resultReceiver_.append("error: option 'e' requires a value.\n");
232 break;
233 case 'u':
234 resultReceiver_.append("error: option 'u' requires a value.\n");
235 break;
236 default:
237 resultReceiver_.append("error: unknown option.\n");
238 break;
239 }
240 }
241
CheckDumpEventType(DumpCmdInfo & cmdInfo,ErrCode & result)242 void CommonEventCommand::CheckDumpEventType(DumpCmdInfo &cmdInfo, ErrCode &result)
243 {
244 if (strcmp(optarg, "subscriber") == 0) {
245 cmdInfo.eventType = DumpEventType::SUBSCRIBER;
246 } else if (strcmp(optarg, "sticky") == 0) {
247 cmdInfo.eventType = DumpEventType::STICKY;
248 } else if (strcmp(optarg, "pending") == 0) {
249 cmdInfo.eventType = DumpEventType::PENDING;
250 } else if (strcmp(optarg, "history") == 0) {
251 cmdInfo.eventType = DumpEventType::HISTORY;
252 } else {
253 resultReceiver_.append("error: option 'p' requires a value.\n");
254 result = ERR_INVALID_VALUE;
255 }
256 }
257 } // namespace EventFwk
258 } // namespace OHOS
259