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