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