* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common_event_command.h"
#include <getopt.h>
#include "common_event.h"
#include "common_event_constant.h"
#include "common_event_manager.h"
#include "event_log_wrapper.h"
#include "singleton.h"
namespace OHOS {
namespace EventFwk {
namespace {
const std::string SHORT_OPTIONS = "he:asoc:d:u:p:";
const struct option LONG_OPTIONS[] = {
{"help", no_argument, nullptr, 'h'},
{"all", no_argument, nullptr, 'a'},
{"event", required_argument, nullptr, 'e'},
{"sticky", no_argument, nullptr, 's'},
{"ordered", no_argument, nullptr, 'o'},
{"code", required_argument, nullptr, 'c'},
{"data", required_argument, nullptr, 'd'},
{"user-id", required_argument, nullptr, 'u'},
};
}
ErrCode CommonEventCommand::CreateCommandMap()
{
commandMap_ = {
{"help", std::bind(&CommonEventCommand::RunAsHelpCommand, this)},
{"publish", std::bind(&CommonEventCommand::RunAsPublishCommand, this)},
{"dump", std::bind(&CommonEventCommand::RunAsDumpCommand, this)},
};
return ERR_OK;
}
ErrCode CommonEventCommand::RunAsHelpCommand()
{
EVENT_LOGI(LOG_TAG_CES, "enter");
resultReceiver_.append(HELP_MSG);
return ERR_OK;
}
ErrCode CommonEventCommand::RunAsPublishCommand()
{
EVENT_LOGI(LOG_TAG_CES, "enter");
ErrCode result = ERR_OK;
PublishCmdInfo cmdInfo;
bool hasOption = false;
SetPublishCmdInfo(cmdInfo, result, hasOption);
if (!hasOption) {
resultReceiver_.append(HELP_MSG_NO_OPTION);
resultReceiver_.append(HELP_MSG_PUBLISH);
return ERR_INVALID_VALUE;
}
if (result == ERR_OK && resultReceiver_.empty() && cmdInfo.action.empty()) {
resultReceiver_.append(HELP_MSG_NO_EVENT_OPTION);
result = ERR_INVALID_VALUE;
}
if (result == ERR_OK) {
Want want;
want.SetAction(cmdInfo.action);
CommonEventData commonEventData;
commonEventData.SetWant(want);
commonEventData.SetCode(cmdInfo.code);
commonEventData.SetData(cmdInfo.data);
CommonEventPublishInfo publishInfo;
publishInfo.SetSticky(cmdInfo.isSticky);
publishInfo.SetOrdered(cmdInfo.isOrdered);
int32_t publishResult = CommonEvent::GetInstance()->PublishCommonEventAsUser(
commonEventData, publishInfo, nullptr, cmdInfo.userId);
if (publishResult == ERR_OK) {
resultReceiver_ = STRING_PUBLISH_COMMON_EVENT_OK;
} else {
resultReceiver_ = STRING_PUBLISH_COMMON_EVENT_NG;
}
} else {
resultReceiver_.append(HELP_MSG_PUBLISH);
}
return result;
}
void CommonEventCommand::SetPublishCmdInfo(PublishCmdInfo &cmdInfo, ErrCode &result, bool &hasOption)
{
int option;
while ((option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr)) != -1) {
hasOption = true;
if (option == '?') {
CheckPublishOpt();
result = ERR_INVALID_VALUE;
return;
}
switch (option) {
case 'h':
result = ERR_INVALID_VALUE;
break;
case 'e':
cmdInfo.action = optarg;
break;
case 's':
cmdInfo.isSticky = true;
break;
case 'o':
cmdInfo.isOrdered = true;
break;
case 'c':
cmdInfo.code = atoi(optarg);
break;
case 'd':
cmdInfo.data = optarg;
break;
case 'u':
cmdInfo.userId = atoi(optarg);
break;
default:
break;
}
}
}
void CommonEventCommand::CheckPublishOpt()
{
switch (optopt) {
case 'e': {
resultReceiver_.append("error: option 'e' requires a value.\n");
break;
}
case 'c': {
resultReceiver_.append("error: option 'c' requires a value.\n");
break;
}
case 'd': {
resultReceiver_.append("error: option 'd' requires a value.\n");
break;
}
case 'u': {
resultReceiver_.append("error: option 'u' requires a value.\n");
break;
}
default: {
resultReceiver_.append("error: unknown option.\n");
break;
}
}
}
ErrCode CommonEventCommand::RunAsDumpCommand()
{
#ifdef CEM_SUPPORT_DUMP
EVENT_LOGI(LOG_TAG_CES, "enter");
ErrCode result = ERR_OK;
bool hasOption = false;
DumpCmdInfo cmdInfo;
SetDumpCmdInfo(cmdInfo, result, hasOption);
if (!hasOption) {
resultReceiver_.append(HELP_MSG_NO_OPTION);
resultReceiver_.append(HELP_MSG_DUMP);
return ERR_INVALID_VALUE;
}
if (result == ERR_OK) {
std::vector<std::string> dumpResults;
bool dumpResult = CommonEvent::GetInstance()->DumpState(
static_cast<int32_t>(cmdInfo.eventType), cmdInfo.action, cmdInfo.userId, dumpResults);
if (dumpResult) {
EVENT_LOGI(LOG_TAG_CES, "event size %{public}zu", dumpResults.size());
for (const auto &it : dumpResults) {
EVENT_LOGI(LOG_TAG_CES, "event %{public}s", it.c_str());
resultReceiver_.append(it + "\n");
}
} else {
resultReceiver_ = STRING_DUMP_COMMON_EVENT_NG;
}
} else {
resultReceiver_.append(HELP_MSG_DUMP);
}
return result;
#else
resultReceiver_.append(USER_DUMP_COMMON_EVENT_NG);
return ERR_INVALID_VALUE;
#endif
}
#ifdef CEM_SUPPORT_DUMP
void CommonEventCommand::SetDumpCmdInfo(DumpCmdInfo &cmdInfo, ErrCode &result, bool &hasOption)
{
int option;
while ((option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr)) != -1) {
hasOption = true;
if (option == '?') {
CheckDumpOpt();
result = ERR_INVALID_VALUE;
return;
}
switch (option) {
case 'h':
result = ERR_INVALID_VALUE;
break;
case 'e':
cmdInfo.action = optarg;
break;
case 'u':
cmdInfo.userId = atoi(optarg);
break;
case 'p':
CheckDumpEventType(cmdInfo, result);
break;
default:
break;
}
}
}
void CommonEventCommand::CheckDumpOpt()
{
switch (optopt) {
case 'e':
resultReceiver_.append("error: option 'e' requires a value.\n");
break;
case 'u':
resultReceiver_.append("error: option 'u' requires a value.\n");
break;
default:
resultReceiver_.append("error: unknown option.\n");
break;
}
}
void CommonEventCommand::CheckDumpEventType(DumpCmdInfo &cmdInfo, ErrCode &result)
{
if (strcmp(optarg, "subscriber") == 0) {
cmdInfo.eventType = DumpEventType::SUBSCRIBER;
} else if (strcmp(optarg, "sticky") == 0) {
cmdInfo.eventType = DumpEventType::STICKY;
} else if (strcmp(optarg, "pending") == 0) {
cmdInfo.eventType = DumpEventType::PENDING;
} else if (strcmp(optarg, "history") == 0) {
cmdInfo.eventType = DumpEventType::HISTORY;
} else {
resultReceiver_.append("error: option 'p' requires a value.\n");
result = ERR_INVALID_VALUE;
}
}
#endif
}
}