/*
* 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 "reminder_request.h"
#include "ans_const_define.h"
#include "ans_log_wrapper.h"
#include "bundle_mgr_interface.h"
#include "bundle_mgr_proxy.h"
#include "if_system_ability_manager.h"
#include "ipc_skeleton.h"
#include "iservice_registry.h"
#include "locale_config.h"
#include "system_ability_definition.h"
#include "want_agent_helper.h"
#include "nlohmann/json.hpp"
#include "want_params_wrapper.h"
namespace OHOS {
namespace Notification {
namespace {
const int32_t BASE_YEAR = 1900;
const int32_t SINGLE_BUTTON_INVALID = 0;
const int32_t SINGLE_BUTTON_JSONSTRING = 0;
const int32_t SINGLE_BUTTON_ONLY_ONE = 1;
const int32_t SINGLE_BUTTON_MIN_LEN = 2;
const int32_t SINGLE_BUTTON_MAX_LEN = 4;
const int32_t BUTTON_TYPE_INDEX = 0;
const int32_t BUTTON_TITLE_INDEX = 1;
const int32_t BUTTON_PKG_INDEX = 2;
const int32_t BUTTON_ABILITY_INDEX = 3;
const int32_t WANT_AGENT_URI_INDEX = 2;
const int32_t INDENT = -1;
const char* const PARAM_EXTRA_KEY = "NotificationRequest_extraInfo";
}
int32_t ReminderRequest::GLOBAL_ID = 0;
const uint64_t ReminderRequest::INVALID_LONG_LONG_VALUE = 0;
const uint16_t ReminderRequest::INVALID_U16_VALUE = 0;
const uint16_t ReminderRequest::MILLI_SECONDS = 1000;
const uint16_t ReminderRequest::SAME_TIME_DISTINGUISH_MILLISECONDS = 1000;
const uint32_t ReminderRequest::MIN_TIME_INTERVAL_IN_MILLI = 5 * 60 * 1000;
const uint8_t ReminderRequest::INVALID_U8_VALUE = 0;
const uint8_t ReminderRequest::REMINDER_STATUS_INACTIVE = 0;
const uint8_t ReminderRequest::REMINDER_STATUS_ACTIVE = 1;
const uint8_t ReminderRequest::REMINDER_STATUS_ALERTING = 2;
const uint8_t ReminderRequest::REMINDER_STATUS_SHOWING = 4;
const uint8_t ReminderRequest::REMINDER_STATUS_SNOOZE = 8;
const uint8_t ReminderRequest::TIME_HOUR_OFFSET = 12;
const std::string ReminderRequest::NOTIFICATION_LABEL = "REMINDER_AGENT";
const std::string ReminderRequest::REMINDER_EVENT_ALARM_ALERT = "ohos.event.notification.reminder.ALARM_ALERT";
const std::string ReminderRequest::REMINDER_EVENT_CLOSE_ALERT = "ohos.event.notification.reminder.CLOSE_ALERT";
const std::string ReminderRequest::REMINDER_EVENT_SNOOZE_ALERT = "ohos.event.notification.reminder.SNOOZE_ALERT";
const std::string ReminderRequest::REMINDER_EVENT_CUSTOM_ALERT = "ohos.event.notification.reminder.COSTUM_ALERT";
const std::string ReminderRequest::REMINDER_EVENT_CLICK_ALERT = "ohos.event.notification.reminder.CLICK_ALERT";
const std::string ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT = "ohos.event.notification.reminder.ALERT_TIMEOUT";
const std::string ReminderRequest::REMINDER_EVENT_REMOVE_NOTIFICATION =
"ohos.event.notification.reminder.REMOVE_NOTIFICATION";
const std::string ReminderRequest::PARAM_REMINDER_ID = "REMINDER_ID";
const std::string ReminderRequest::SEP_BUTTON_SINGLE = "";
const std::string ReminderRequest::SEP_BUTTON_MULTI = "";
const std::string ReminderRequest::SEP_WANT_AGENT = "";
const std::string ReminderRequest::SEP_BUTTON_VALUE_TYPE = "";
const std::string ReminderRequest::SEP_BUTTON_VALUE = "";
const std::string ReminderRequest::SEP_BUTTON_VALUE_BLOB = "";
const uint8_t ReminderRequest::DAYS_PER_WEEK = 7;
const uint8_t ReminderRequest::MONDAY = 1;
const uint8_t ReminderRequest::SUNDAY = 7;
const uint8_t ReminderRequest::HOURS_PER_DAY = 24;
const uint16_t ReminderRequest::SECONDS_PER_HOUR = 3600;
template
void GetJsonValue(const nlohmann::json& root, const std::string& name, T& value)
{
using ValueType = std::remove_cv_t>;
if constexpr (std::is_same_v) {
if (!root.contains(name) || !root[name].is_string()) {
value = T();
return;
}
value = root[name].get();
return;
}
value = T();
}
inline static bool IsVaildButtonType(const std::string& type)
{
// check action button type range
if (type.size() != 1) {
return false;
}
if (type[0] >= '0' && type[0] <= '3') {
return true;
}
return false;
}
ReminderRequest::ReminderRequest()
{
InitServerObj();
}
ReminderRequest::ReminderRequest(const ReminderRequest &other)
{
this->content_ = other.content_;
this->expiredContent_ = other.expiredContent_;
this->snoozeContent_ = other.snoozeContent_;
this->displayContent_ = other.displayContent_;
this->title_ = other.title_;
this->isExpired_ = other.isExpired_;
this->isSystemApp_ = other.isSystemApp_;
this->snoozeTimes_ = other.snoozeTimes_;
this->snoozeTimesDynamic_ = other.snoozeTimesDynamic_;
this->state_ = other.state_;
this->notificationId_ = other.notificationId_;
this->reminderId_ = other.reminderId_;
this->reminderTimeInMilli_ = other.reminderTimeInMilli_;
this->ringDurationInMilli_ = other.ringDurationInMilli_;
this->triggerTimeInMilli_ = other.triggerTimeInMilli_;
this->timeIntervalInMilli_ = other.timeIntervalInMilli_;
this->reminderType_ = other.reminderType_;
this->slotType_ = other.slotType_;
this->snoozeSlotType_ = other.snoozeSlotType_;
this->notificationRequest_ = other.notificationRequest_;
this->wantAgentInfo_ = other.wantAgentInfo_;
this->maxScreenWantAgentInfo_ = other.maxScreenWantAgentInfo_;
this->actionButtonMap_ = other.actionButtonMap_;
this->tapDismissed_= other.tapDismissed_;
this->autoDeletedTime_ = other.autoDeletedTime_;
this->customButtonUri_ = other.customButtonUri_;
this->groupId_ = other.groupId_;
this->customRingUri_ = other.customRingUri_;
this->creatorBundleName_ = other.creatorBundleName_;
}
ReminderRequest::ReminderRequest(int32_t reminderId)
{
reminderId_ = reminderId;
InitServerObj();
}
ReminderRequest::ReminderRequest(ReminderType reminderType)
{
reminderType_ = reminderType;
InitServerObj();
}
bool ReminderRequest::CanRemove() const
{
if ((state_ & (REMINDER_STATUS_SHOWING | REMINDER_STATUS_ALERTING | REMINDER_STATUS_ACTIVE)) == 0) {
return true;
}
return false;
}
bool ReminderRequest::CanShow() const
{
// when system time change by user manually, and the reminde is to show immediately,
// the show reminder just need to be triggered by ReminderDataManager#RefreshRemindersLocked(uint8_t).
// we need to make the REMINDER_EVENT_ALARM_ALERT do nothing.
uint64_t nowInstantMilli = GetNowInstantMilli();
if (nowInstantMilli == 0) {
return false;
}
if (nowInstantMilli < (GetReminderTimeInMilli() + MIN_TIME_INTERVAL_IN_MILLI)) {
return false;
}
return true;
}
std::string ReminderRequest::Dump() const
{
const time_t nextTriggerTime = static_cast(triggerTimeInMilli_ / MILLI_SECONDS);
std::string dateTimeInfo = GetTimeInfoInner(nextTriggerTime, TimeFormat::YMDHMS, true);
return "Reminder["
"reminderId=" + std::to_string(reminderId_) +
", type=" + std::to_string(static_cast(reminderType_)) +
", state=" + GetState(state_) +
", nextTriggerTime=" + dateTimeInfo.c_str() +
"]";
}
ReminderRequest& ReminderRequest::SetActionButton(const std::string &title, const ActionButtonType &type,
const std::string &resource, const std::shared_ptr &buttonWantAgent,
const std::shared_ptr &buttonDataShareUpdate)
{
if ((type != ActionButtonType::CLOSE) && (type != ActionButtonType::SNOOZE) && (type != ActionButtonType::CUSTOM)) {
ANSR_LOGI("Button type is not support: %{public}d.", static_cast(type));
return *this;
}
ActionButtonInfo actionButtonInfo;
actionButtonInfo.type = type;
actionButtonInfo.title = title;
actionButtonInfo.resource = resource;
actionButtonInfo.wantAgent = buttonWantAgent;
actionButtonInfo.dataShareUpdate = buttonDataShareUpdate;
actionButtonMap_.insert(std::pair(type, actionButtonInfo));
return *this;
}
ReminderRequest& ReminderRequest::SetContent(const std::string &content)
{
content_ = content;
return *this;
}
ReminderRequest& ReminderRequest::SetExpiredContent(const std::string &expiredContent)
{
expiredContent_ = expiredContent;
return *this;
}
void ReminderRequest::SetExpired(bool isExpired)
{
isExpired_ = isExpired;
}
void ReminderRequest::InitCreatorBundleName(const std::string &creatorBundleName)
{
creatorBundleName_ = creatorBundleName;
}
void ReminderRequest::InitCreatorUid(const int32_t creatorUid)
{
creatorUid_ = creatorUid;
}
void ReminderRequest::InitReminderId()
{
std::lock_guard lock(std::mutex);
if (GLOBAL_ID < 0) {
ANSR_LOGW("GLOBAL_ID overdule");
GLOBAL_ID = 0;
}
reminderId_ = ++GLOBAL_ID;
ANSR_LOGI("reminderId_=%{public}d", reminderId_);
}
void ReminderRequest::InitUserId(const int32_t &userId)
{
userId_ = userId;
}
void ReminderRequest::InitUid(const int32_t &uid)
{
uid_ = uid;
}
void ReminderRequest::InitBundleName(const std::string &bundleName)
{
bundleName_ = bundleName;
}
bool ReminderRequest::IsExpired() const
{
return isExpired_;
}
bool ReminderRequest::IsShowing() const
{
if ((state_ & REMINDER_STATUS_SHOWING) != 0) {
return true;
}
return false;
}
void ReminderRequest::OnClose(bool updateNext)
{
if ((state_ & REMINDER_STATUS_SHOWING) == 0) {
ANSR_LOGE("onClose, the state of reminder is incorrect, state:%{public}s", GetState(state_).c_str());
return;
}
SetState(false, REMINDER_STATUS_SHOWING | REMINDER_STATUS_SNOOZE, "onClose()");
if ((state_ & REMINDER_STATUS_ALERTING) != 0) {
SetState(false, REMINDER_STATUS_ALERTING, "onClose");
}
if (updateNext) {
uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(true, false);
if (nextTriggerTime == INVALID_LONG_LONG_VALUE) {
isExpired_ = true;
} else {
SetTriggerTimeInMilli(nextTriggerTime);
snoozeTimesDynamic_ = snoozeTimes_;
}
}
}
bool ReminderRequest::OnDateTimeChange()
{
uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(true, false);
return HandleSysTimeChange(triggerTimeInMilli_, nextTriggerTime);
}
bool ReminderRequest::HandleSysTimeChange(uint64_t oriTriggerTime, uint64_t optTriggerTime)
{
if (isExpired_) {
return false;
}
uint64_t now = GetNowInstantMilli();
if (now == 0) {
ANSR_LOGE("get now time failed.");
return false;
}
if (oriTriggerTime == 0 && optTriggerTime < now) {
ANSR_LOGW("trigger time is less than now time.");
return false;
}
bool showImmediately = false;
if (optTriggerTime != INVALID_LONG_LONG_VALUE && (optTriggerTime <= oriTriggerTime || oriTriggerTime == 0)) {
// case1. switch to a previous time
SetTriggerTimeInMilli(optTriggerTime);
snoozeTimesDynamic_ = snoozeTimes_;
} else {
if (oriTriggerTime <= now) {
// case2. switch to a future time, trigger time is less than now time.
// when the reminder show immediately, trigger time will update in onShow function.
snoozeTimesDynamic_ = 0;
showImmediately = true;
} else {
// case3. switch to a future time, trigger time is larger than now time.
showImmediately = false;
}
}
return showImmediately;
}
bool ReminderRequest::HandleTimeZoneChange(
uint64_t oldZoneTriggerTime, uint64_t newZoneTriggerTime, uint64_t optTriggerTime)
{
if (isExpired_) {
return false;
}
ANSR_LOGD("Handle timezone change, old:%{public}" PRIu64 ", new:%{public}" PRIu64 "",
oldZoneTriggerTime, newZoneTriggerTime);
if (oldZoneTriggerTime == newZoneTriggerTime) {
return false;
}
bool showImmediately = false;
if (optTriggerTime != INVALID_LONG_LONG_VALUE && oldZoneTriggerTime < newZoneTriggerTime) {
// case1. timezone change to smaller
SetTriggerTimeInMilli(optTriggerTime);
snoozeTimesDynamic_ = snoozeTimes_;
} else {
// case2. timezone change to larger
time_t now;
(void)time(&now); // unit is seconds.
if (static_cast(now) < 0) {
ANSR_LOGE("Get now time error");
return false;
}
if (newZoneTriggerTime <= GetDurationSinceEpochInMilli(now)) {
snoozeTimesDynamic_ = 0;
showImmediately = true;
} else {
SetTriggerTimeInMilli(newZoneTriggerTime);
showImmediately = false;
}
}
return showImmediately;
}
void ReminderRequest::OnSameNotificationIdCovered()
{
SetState(false, REMINDER_STATUS_ALERTING | REMINDER_STATUS_SHOWING | REMINDER_STATUS_SNOOZE,
"OnSameNotificationIdCovered");
}
void ReminderRequest::OnShow(bool isPlaySoundOrVibration, bool isSysTimeChanged, bool allowToNotify)
{
if ((state_ & (REMINDER_STATUS_ACTIVE | REMINDER_STATUS_SNOOZE)) != 0) {
SetState(false, REMINDER_STATUS_ACTIVE | REMINDER_STATUS_SNOOZE, "onShow()");
}
if (isSysTimeChanged) {
uint64_t nowInstantMilli = GetNowInstantMilli();
if (nowInstantMilli == 0) {
ANSR_LOGW("Onshow, get now time error");
}
reminderTimeInMilli_ = nowInstantMilli;
} else {
reminderTimeInMilli_ = triggerTimeInMilli_;
}
UpdateNextReminder(false);
if (allowToNotify) {
SetState(true, REMINDER_STATUS_SHOWING, "OnShow");
if (isPlaySoundOrVibration) {
SetState(true, REMINDER_STATUS_ALERTING, "OnShow");
}
UpdateNotificationStateForAlert();
}
}
void ReminderRequest::OnShowFail()
{
SetState(false, REMINDER_STATUS_SHOWING, "OnShowFailed()");
}
bool ReminderRequest::OnSnooze()
{
if ((state_ & REMINDER_STATUS_SNOOZE) != 0) {
ANSR_LOGW("onSnooze, the state of reminder is incorrect, state: %{public}s", (GetState(state_)).c_str());
return false;
}
if ((state_ & REMINDER_STATUS_ALERTING) != 0) {
SetState(false, REMINDER_STATUS_ALERTING, "onSnooze()");
}
SetSnoozeTimesDynamic(GetSnoozeTimes());
if (!UpdateNextReminder(true)) {
return false;
}
UpdateNotificationStateForSnooze();
if (timeIntervalInMilli_ > 0) {
SetState(true, REMINDER_STATUS_SNOOZE, "onSnooze()");
}
return true;
}
void ReminderRequest::OnStart()
{
if ((state_ & REMINDER_STATUS_ACTIVE) != 0) {
ANSR_LOGE(
"start failed, the state of reminder is incorrect, state: %{public}s", (GetState(state_)).c_str());
return;
}
if (isExpired_) {
ANSR_LOGE("start failed, the reminder is expired");
return;
}
SetState(true, REMINDER_STATUS_ACTIVE, "OnStart()");
}
void ReminderRequest::OnStop()
{
ANSR_LOGI("Stop the previous active reminder, %{public}s", this->Dump().c_str());
if ((state_ & REMINDER_STATUS_ACTIVE) == 0) {
ANSR_LOGW("onStop, the state of reminder is incorrect, state: %{public}s", (GetState(state_)).c_str());
return;
}
SetState(false, REMINDER_STATUS_ACTIVE, "OnStop");
}
bool ReminderRequest::OnTerminate()
{
if ((state_ & REMINDER_STATUS_ALERTING) == 0) {
ANSR_LOGW("onTerminate, the state of reminder is %{public}s", (GetState(state_)).c_str());
return false;
}
SetState(false, REMINDER_STATUS_ALERTING, "onTerminate");
UpdateNotificationStateForAlert();
return true;
}
bool ReminderRequest::OnTimeZoneChange()
{
time_t oldZoneTriggerTime = static_cast(triggerTimeInMilli_ / MILLI_SECONDS);
struct tm *localOriTime = localtime(&oldZoneTriggerTime);
if (localOriTime == nullptr) {
ANSR_LOGE("oldZoneTriggerTime is null");
return false;
}
time_t newZoneTriggerTime = mktime(localOriTime);
uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(true, false);
return HandleTimeZoneChange(
triggerTimeInMilli_, GetDurationSinceEpochInMilli(newZoneTriggerTime), nextTriggerTime);
}
void ReminderRequest::RecoverActionButtonJsonMode(const std::string &jsonString)
{
if (!nlohmann::json::accept(jsonString)) {
ANSR_LOGW("not a json string!");
return;
}
nlohmann::json root = nlohmann::json::parse(jsonString, nullptr, false);
if (root.is_discarded()) {
ANSR_LOGW("parse json data failed!");
return;
}
std::string type;
GetJsonValue(root, "type", type);
if (!IsVaildButtonType(type)) {
ANSR_LOGW("unkown button type!");
return;
}
std::string title;
GetJsonValue(root, "title", title);
std::string resource;
GetJsonValue(root, "resource", resource);
auto buttonWantAgent = std::make_shared();
if (root.contains("wantAgent") && !root["wantAgent"].empty()) {
nlohmann::json wantAgent = root["wantAgent"];
GetJsonValue(wantAgent, "pkgName", buttonWantAgent->pkgName);
GetJsonValue(wantAgent, "abilityName", buttonWantAgent->abilityName);
}
auto buttonDataShareUpdate = std::make_shared();
if (root.contains("dataShareUpdate") && !root["dataShareUpdate"].empty()) {
nlohmann::json dataShareUpdate = root["dataShareUpdate"];
GetJsonValue(dataShareUpdate, "uri", buttonDataShareUpdate->uri);
GetJsonValue(dataShareUpdate, "equalTo", buttonDataShareUpdate->equalTo);
GetJsonValue(dataShareUpdate, "valuesBucket", buttonDataShareUpdate->valuesBucket);
}
SetActionButton(title, ActionButtonType(std::stoi(type, nullptr)),
resource, buttonWantAgent, buttonDataShareUpdate);
}
void ReminderRequest::DeserializeButtonInfo(const std::string& buttonInfoStr)
{
std::vector multiButton = StringSplit(buttonInfoStr, SEP_BUTTON_MULTI);
for (auto button : multiButton) {
std::vector singleButton = StringSplit(button, SEP_BUTTON_SINGLE);
if (singleButton.size() <= SINGLE_BUTTON_INVALID) {
ANSR_LOGW("RecoverButton fail");
return;
}
if (singleButton.size() == SINGLE_BUTTON_ONLY_ONE) {
std::string jsonString = singleButton.at(SINGLE_BUTTON_JSONSTRING);
RecoverActionButtonJsonMode(jsonString);
continue;
}
// old method Soon to be deleted
if (singleButton.size() < SINGLE_BUTTON_MIN_LEN) {
ANSR_LOGW("RecoverButton fail");
return;
}
auto buttonWantAgent = std::make_shared();
if (singleButton.size() == SINGLE_BUTTON_MAX_LEN) {
buttonWantAgent->pkgName = singleButton.at(BUTTON_PKG_INDEX);
buttonWantAgent->abilityName = singleButton.at(BUTTON_ABILITY_INDEX);
}
std::string resource = "";
auto buttonDataShareUpdate = std::make_shared();
SetActionButton(singleButton.at(BUTTON_TITLE_INDEX),
ActionButtonType(std::atoi(singleButton.at(BUTTON_TYPE_INDEX).c_str())),
resource, buttonWantAgent, buttonDataShareUpdate);
ANSR_LOGI("RecoverButton title:%{public}s, pkgName:%{public}s, abilityName:%{public}s",
singleButton.at(BUTTON_TITLE_INDEX).c_str(), buttonWantAgent->pkgName.c_str(),
buttonWantAgent->abilityName.c_str());
}
}
std::vector ReminderRequest::StringSplit(std::string source, const std::string &split)
{
std::vector result;
if (source.empty()) {
return result;
}
size_t pos = 0;
while ((pos = source.find(split)) != std::string::npos) {
std::string token = source.substr(0, pos);
if (!token.empty()) {
result.push_back(token);
}
source.erase(0, pos + split.length());
}
if (!source.empty()) {
result.push_back(source);
}
return result;
}
void ReminderRequest::RecoverWantAgentByJson(const std::string& wantAgentInfo, const uint8_t& type)
{
nlohmann::json root = nlohmann::json::parse(wantAgentInfo, nullptr, false);
if (root.is_discarded()) {
ANSR_LOGW("parse json data failed");
return;
}
if (!root.contains("pkgName") || !root["pkgName"].is_string() ||
!root.contains("abilityName") || !root["abilityName"].is_string() ||
!root.contains("uri") || !root["uri"].is_string() ||
!root.contains("parameters") || !root["parameters"].is_string()) {
return;
}
std::string pkgName = root.at("pkgName").get();
std::string abilityName = root.at("abilityName").get();
std::string uri = root.at("uri").get();
std::string parameters = root.at("parameters").get();
switch (type) {
case WANT_AGENT_FLAG: {
auto wai = std::make_shared();
wai->pkgName = pkgName;
wai->abilityName = abilityName;
wai->uri = uri;
wai->parameters = AAFwk::WantParamWrapper::ParseWantParams(parameters);
SetWantAgentInfo(wai);
break;
}
case MAX_WANT_AGENT_FLAG: {
auto maxScreenWantAgentInfo = std::make_shared();
maxScreenWantAgentInfo->pkgName = pkgName;
maxScreenWantAgentInfo->abilityName = abilityName;
SetMaxScreenWantAgentInfo(maxScreenWantAgentInfo);
break;
}
default: {
ANSR_LOGW("RecoverWantAgent type not support");
break;
}
}
}
void ReminderRequest::DeserializeWantAgent(const std::string &wantAgentInfo, const uint8_t type)
{
if (nlohmann::json::accept(wantAgentInfo)) {
RecoverWantAgentByJson(wantAgentInfo, type);
return;
}
std::vector info = StringSplit(wantAgentInfo, ReminderRequest::SEP_WANT_AGENT);
uint8_t minLen = 2;
if (info.size() < minLen) {
ANSR_LOGW("RecoverWantAgent fail");
return;
}
ANSR_LOGD("pkg=%{public}s, ability=%{public}s", info.at(0).c_str(), info.at(1).c_str());
switch (type) {
case 0: {
auto wai = std::make_shared();
wai->pkgName = info.at(0);
wai->abilityName = info.at(1);
if (info.size() > minLen) {
wai->uri = info.at(WANT_AGENT_URI_INDEX);
}
SetWantAgentInfo(wai);
break;
}
case 1: {
auto maxScreenWantAgentInfo = std::make_shared();
maxScreenWantAgentInfo->pkgName = info.at(0);
maxScreenWantAgentInfo->abilityName = info.at(1);
SetMaxScreenWantAgentInfo(maxScreenWantAgentInfo);
break;
}
default: {
ANSR_LOGW("RecoverWantAgent type not support");
break;
}
}
}
ReminderRequest& ReminderRequest::SetMaxScreenWantAgentInfo(
const std::shared_ptr &maxScreenWantAgentInfo)
{
maxScreenWantAgentInfo_ = maxScreenWantAgentInfo;
return *this;
}
ReminderRequest& ReminderRequest::SetNotificationId(int32_t notificationId)
{
notificationId_ = notificationId;
return *this;
}
ReminderRequest& ReminderRequest::SetGroupId(const std::string &groupId)
{
groupId_ = groupId;
return *this;
}
ReminderRequest& ReminderRequest::SetSlotType(const NotificationConstant::SlotType &slotType)
{
slotType_ = slotType;
return *this;
}
ReminderRequest& ReminderRequest::SetSnoozeSlotType(const NotificationConstant::SlotType &snoozeSlotType)
{
snoozeSlotType_ = snoozeSlotType;
return *this;
}
ReminderRequest& ReminderRequest::SetSnoozeContent(const std::string &snoozeContent)
{
snoozeContent_ = snoozeContent;
return *this;
}
ReminderRequest& ReminderRequest::SetSnoozeTimes(const uint8_t snoozeTimes)
{
snoozeTimes_ = snoozeTimes;
SetSnoozeTimesDynamic(snoozeTimes);
return *this;
}
ReminderRequest& ReminderRequest::SetSnoozeTimesDynamic(const uint8_t snooziTimes)
{
snoozeTimesDynamic_ = snooziTimes;
return *this;
}
ReminderRequest& ReminderRequest::SetTimeInterval(const uint64_t timeIntervalInSeconds)
{
if (timeIntervalInSeconds > (UINT64_MAX / MILLI_SECONDS)) {
ANSR_LOGW("SetTimeInterval, replace to set (0s), for the given is out of legal range");
timeIntervalInMilli_ = 0;
} else {
uint64_t timeIntervalInMilli = timeIntervalInSeconds * MILLI_SECONDS;
if (timeIntervalInMilli > 0 && timeIntervalInMilli < MIN_TIME_INTERVAL_IN_MILLI) {
ANSR_LOGW("SetTimeInterval, replace to set %{public}u, for the given is 0<%{public}" PRIu64 "<%{public}u",
MIN_TIME_INTERVAL_IN_MILLI / MILLI_SECONDS, timeIntervalInSeconds,
MIN_TIME_INTERVAL_IN_MILLI / MILLI_SECONDS);
timeIntervalInMilli_ = MIN_TIME_INTERVAL_IN_MILLI;
} else {
timeIntervalInMilli_ = timeIntervalInMilli;
}
}
return *this;
}
ReminderRequest& ReminderRequest::SetTitle(const std::string &title)
{
title_ = title;
return *this;
}
void ReminderRequest::SetTriggerTimeInMilli(uint64_t triggerTimeInMilli)
{
triggerTimeInMilli_ = triggerTimeInMilli;
}
ReminderRequest& ReminderRequest::SetWantAgentInfo(const std::shared_ptr &wantAgentInfo)
{
if (wantAgentInfo != nullptr) {
wantAgentInfo_ = wantAgentInfo;
}
return *this;
}
bool ReminderRequest::ShouldShowImmediately() const
{
uint64_t nowInstantMilli = GetNowInstantMilli();
if (nowInstantMilli == 0) {
return false;
}
if (triggerTimeInMilli_ > nowInstantMilli) {
return false;
}
return true;
}
std::map ReminderRequest::GetActionButtons(
) const
{
return actionButtonMap_;
}
std::string ReminderRequest::GetCreatorBundleName() const
{
return creatorBundleName_;
}
int32_t ReminderRequest::GetCreatorUid() const
{
return creatorUid_;
}
std::string ReminderRequest::GetContent() const
{
return content_;
}
std::string ReminderRequest::GetExpiredContent() const
{
return expiredContent_;
}
std::shared_ptr ReminderRequest::GetMaxScreenWantAgentInfo() const
{
return maxScreenWantAgentInfo_;
}
int32_t ReminderRequest::GetNotificationId() const
{
return notificationId_;
}
std::string ReminderRequest::GetGroupId() const
{
return groupId_;
}
sptr ReminderRequest::GetNotificationRequest() const
{
return notificationRequest_;
}
int32_t ReminderRequest::GetReminderId() const
{
return reminderId_;
}
uint64_t ReminderRequest::GetReminderTimeInMilli() const
{
return reminderTimeInMilli_;
}
void ReminderRequest::SetReminderId(int32_t reminderId)
{
reminderId_ = reminderId;
}
void ReminderRequest::SetReminderTimeInMilli(const uint64_t reminderTimeInMilli)
{
reminderTimeInMilli_ = reminderTimeInMilli;
}
ReminderRequest& ReminderRequest::SetRingDuration(const uint64_t ringDurationInSeconds)
{
uint64_t ringDuration = ringDurationInSeconds * MILLI_SECONDS;
ringDurationInMilli_ = std::min(ringDuration, MAX_RING_DURATION);
return *this;
}
NotificationConstant::SlotType ReminderRequest::GetSlotType() const
{
return slotType_;
}
NotificationConstant::SlotType ReminderRequest::GetSnoozeSlotType() const
{
return snoozeSlotType_;
}
std::string ReminderRequest::GetSnoozeContent() const
{
return snoozeContent_;
}
uint8_t ReminderRequest::GetSnoozeTimes() const
{
return snoozeTimes_;
}
uint8_t ReminderRequest::GetSnoozeTimesDynamic() const
{
return snoozeTimesDynamic_;
}
uint8_t ReminderRequest::GetState() const
{
return state_;
}
uint64_t ReminderRequest::GetTimeInterval() const
{
return timeIntervalInMilli_ / MILLI_SECONDS;
}
std::string ReminderRequest::GetTitle() const
{
return title_;
}
uint64_t ReminderRequest::GetTriggerTimeInMilli() const
{
return triggerTimeInMilli_;
}
int32_t ReminderRequest::GetUserId() const
{
return userId_;
}
int32_t ReminderRequest::GetUid() const
{
return uid_;
}
std::string ReminderRequest::GetBundleName() const
{
return bundleName_;
}
void ReminderRequest::SetReminderType(const ReminderType type)
{
reminderType_ = type;
}
void ReminderRequest::SetState(const uint8_t state)
{
state_ = state;
}
void ReminderRequest::SetRepeatDaysOfWeek(const uint8_t repeatDaysOfWeek)
{
repeatDaysOfWeek_ = repeatDaysOfWeek;
}
void ReminderRequest::SetSystemApp(bool isSystem)
{
isSystemApp_ = isSystem;
}
bool ReminderRequest::IsSystemApp() const
{
return isSystemApp_;
}
void ReminderRequest::SetTapDismissed(bool tapDismissed)
{
tapDismissed_ = tapDismissed;
}
bool ReminderRequest::IsTapDismissed() const
{
return tapDismissed_;
}
void ReminderRequest::SetAutoDeletedTime(int64_t autoDeletedTime)
{
autoDeletedTime_ = autoDeletedTime;
}
int64_t ReminderRequest::GetAutoDeletedTime() const
{
return autoDeletedTime_;
}
void ReminderRequest::SetCustomButtonUri(const std::string &uri)
{
customButtonUri_ = uri;
}
std::string ReminderRequest::GetCustomButtonUri() const
{
return customButtonUri_;
}
void ReminderRequest::SetCustomRingUri(const std::string &uri)
{
customRingUri_ = uri;
}
std::string ReminderRequest::GetCustomRingUri() const
{
return customRingUri_;
}
sptr ReminderRequest::GetNotificationBundleOption() const
{
return notificationOption_;
}
void ReminderRequest::SetNotificationBundleOption(const sptr& option)
{
notificationOption_ = option;
}
std::shared_ptr ReminderRequest::GetWantAgentInfo() const
{
return wantAgentInfo_;
}
ReminderRequest::ReminderType ReminderRequest::GetReminderType() const
{
return reminderType_;
}
uint16_t ReminderRequest::GetRingDuration() const
{
return ringDurationInMilli_ / MILLI_SECONDS;
}
bool ReminderRequest::UpdateNextReminder()
{
return false;
}
bool ReminderRequest::SetNextTriggerTime()
{
return false;
}
void ReminderRequest::SetWantAgentStr(const std::string& wantStr)
{
wantAgentStr_ = wantStr;
}
std::string ReminderRequest::GetWantAgentStr()
{
return wantAgentStr_;
}
void ReminderRequest::SetMaxWantAgentStr(const std::string& maxWantStr)
{
maxWantAgentStr_ = maxWantStr;
}
std::string ReminderRequest::GetMaxWantAgentStr()
{
return maxWantAgentStr_;
}
void ReminderRequest::UpdateNotificationRequest(UpdateNotificationType type, std::string extra)
{
switch (type) {
case UpdateNotificationType::COMMON: {
ANSR_LOGI("UpdateNotification common information");
if (extra == "snooze") {
UpdateNotificationCommon(true);
} else {
UpdateNotificationCommon(false);
}
break;
}
case UpdateNotificationType::REMOVAL_WANT_AGENT: {
ANSR_LOGI("UpdateNotification removal_want_agent");
AddRemovalWantAgent();
break;
}
case UpdateNotificationType::WANT_AGENT: {
ANSR_LOGI("UpdateNotification want_agent");
AppExecFwk::ElementName wantAgent("", wantAgentInfo_->pkgName, wantAgentInfo_->abilityName);
SetWantAgent(wantAgent);
SetExtraInfo(wantAgentInfo_->parameters);
break;
}
case UpdateNotificationType::MAX_SCREEN_WANT_AGENT: {
ANSR_LOGI("UpdateNotification max_screen_want_agent");
AppExecFwk::ElementName maxScreenWantAgent(
"", maxScreenWantAgentInfo_->pkgName, maxScreenWantAgentInfo_->abilityName);
SetMaxScreenWantAgent(maxScreenWantAgent);
break;
}
case UpdateNotificationType::BUNDLE_INFO: {
ANSR_LOGI("UpdateNotification hap information");
UpdateNotificationBundleInfo();
break;
}
case UpdateNotificationType::CONTENT: {
break;
}
default:
break;
}
}
bool ReminderRequest::MarshallingActionButton(Parcel& parcel) const
{
// write map
uint64_t actionButtonMapSize = static_cast(actionButtonMap_.size());
WRITE_UINT64_RETURN_FALSE_LOG(parcel, actionButtonMapSize, "actionButtonMapSize");
for (auto button : actionButtonMap_) {
uint8_t buttonType = static_cast(button.first);
WRITE_UINT8_RETURN_FALSE_LOG(parcel, buttonType, "buttonType");
WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.title, "buttonTitle");
WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.resource, "buttonResource");
if (button.second.wantAgent == nullptr) {
ANSR_LOGE("button wantAgent is null");
return false;
}
WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.wantAgent->pkgName, "wantAgent's pkgName");
WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.wantAgent->abilityName, "wantAgent's abilityName");
if (button.second.dataShareUpdate == nullptr) {
ANSR_LOGE("button dataShareUpdate is null");
return false;
}
WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.dataShareUpdate->uri,
"dataShareUpdate's uri");
WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.dataShareUpdate->equalTo,
"dataShareUpdate's equalTo");
WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.dataShareUpdate->valuesBucket,
"dataShareUpdate's valuesBucket");
}
return true;
}
bool ReminderRequest::MarshallingWantParameters(Parcel& parcel, const AAFwk::WantParams& params) const
{
if (params.Size() == 0) {
if (!parcel.WriteInt32(VALUE_NULL)) {
return false;
}
} else {
if (!parcel.WriteInt32(VALUE_OBJECT)) {
return false;
}
if (!parcel.WriteParcelable(¶ms)) {
return false;
}
}
return true;
}
bool ReminderRequest::Marshalling(Parcel &parcel) const
{
// write string
WRITE_STRING_RETURN_FALSE_LOG(parcel, content_, "content");
WRITE_STRING_RETURN_FALSE_LOG(parcel, expiredContent_, "expiredContent");
WRITE_STRING_RETURN_FALSE_LOG(parcel, snoozeContent_, "snoozeContent");
WRITE_STRING_RETURN_FALSE_LOG(parcel, title_, "title");
WRITE_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->abilityName, "wantAgentInfo's abilityName");
WRITE_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->pkgName, "wantAgentInfo's pkgName");
WRITE_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->uri, "wantAgentInfo's uri");
if (!MarshallingWantParameters(parcel, wantAgentInfo_->parameters)) {
ANSR_LOGE("Failed to write wantAgentInfo's parameters");
return false;
}
WRITE_STRING_RETURN_FALSE_LOG(parcel, maxScreenWantAgentInfo_->abilityName, "maxScreenWantAgentInfo's abilityName");
WRITE_STRING_RETURN_FALSE_LOG(parcel, maxScreenWantAgentInfo_->pkgName, "maxScreenWantAgentInfo's pkgName");
WRITE_STRING_RETURN_FALSE_LOG(parcel, customButtonUri_, "customButtonUri");
WRITE_STRING_RETURN_FALSE_LOG(parcel, groupId_, "groupId");
WRITE_STRING_RETURN_FALSE_LOG(parcel, customRingUri_, "customRingUri");
WRITE_STRING_RETURN_FALSE_LOG(parcel, creatorBundleName_, "creatorBundleName");
// write bool
WRITE_BOOL_RETURN_FALSE_LOG(parcel, isExpired_, "isExpired");
WRITE_BOOL_RETURN_FALSE_LOG(parcel, tapDismissed_, "tapDismissed");
// write int
WRITE_INT64_RETURN_FALSE_LOG(parcel, autoDeletedTime_, "autoDeletedTime");
WRITE_INT32_RETURN_FALSE_LOG(parcel, reminderId_, "reminderId");
WRITE_INT32_RETURN_FALSE_LOG(parcel, notificationId_, "notificationId");
WRITE_UINT64_RETURN_FALSE_LOG(parcel, triggerTimeInMilli_, "triggerTimeInMilli");
WRITE_UINT64_RETURN_FALSE_LOG(parcel, timeIntervalInMilli_, "timeIntervalInMilli");
WRITE_UINT64_RETURN_FALSE_LOG(parcel, ringDurationInMilli_, "ringDurationInMilli");
WRITE_UINT64_RETURN_FALSE_LOG(parcel, reminderTimeInMilli_, "reminderTimeInMilli");
WRITE_UINT8_RETURN_FALSE_LOG(parcel, snoozeTimes_, "snoozeTimes");
WRITE_UINT8_RETURN_FALSE_LOG(parcel, snoozeTimesDynamic_, "snoozeTimesDynamic");
WRITE_UINT8_RETURN_FALSE_LOG(parcel, state_, "state");
// write enum
uint8_t reminderType = static_cast(reminderType_);
WRITE_UINT8_RETURN_FALSE_LOG(parcel, reminderType, "reminderType");
int32_t slotType = static_cast(slotType_);
WRITE_INT32_RETURN_FALSE_LOG(parcel, slotType, "slotType");
int32_t snoozeSlotType = static_cast(snoozeSlotType_);
WRITE_INT32_RETURN_FALSE_LOG(parcel, snoozeSlotType, "snoozeSlotType");
if (!MarshallingActionButton(parcel)) {
return false;
}
return true;
}
ReminderRequest *ReminderRequest::Unmarshalling(Parcel &parcel)
{
auto objptr = new (std::nothrow) ReminderRequest();
if (objptr == nullptr) {
ANSR_LOGE("Failed to create reminder due to no memory.");
return objptr;
}
if (!objptr->ReadFromParcel(parcel)) {
delete objptr;
objptr = nullptr;
}
return objptr;
}
bool ReminderRequest::ReadActionButtonFromParcel(Parcel& parcel)
{
uint64_t buttonMapSize = 0;
READ_UINT64_RETURN_FALSE_LOG(parcel, buttonMapSize, "actionButtonMapSize");
buttonMapSize = (buttonMapSize < MAX_ACTION_BUTTON_NUM) ? buttonMapSize : MAX_ACTION_BUTTON_NUM;
for (uint64_t i = 0; i < buttonMapSize; i++) {
uint8_t buttonType = static_cast(ActionButtonType::INVALID);
READ_UINT8_RETURN_FALSE_LOG(parcel, buttonType, "buttonType");
ActionButtonType type = static_cast(buttonType);
std::string title = parcel.ReadString();
std::string resource = parcel.ReadString();
std::string pkgName = parcel.ReadString();
std::string abilityName = parcel.ReadString();
std::string uri = parcel.ReadString();
std::string equalTo = parcel.ReadString();
std::string valuesBucket = parcel.ReadString();
ActionButtonInfo info;
info.type = type;
info.title = title;
info.resource = resource;
info.wantAgent = std::make_shared();
if (info.wantAgent == nullptr) {
return false;
}
info.wantAgent->pkgName = pkgName;
info.wantAgent->abilityName = abilityName;
info.dataShareUpdate = std::make_shared();
if (info.dataShareUpdate == nullptr) {
return false;
}
info.dataShareUpdate->uri = uri;
info.dataShareUpdate->equalTo = equalTo;
info.dataShareUpdate->valuesBucket = valuesBucket;
actionButtonMap_.insert(std::pair(type, info));
}
return true;
}
bool ReminderRequest::ReadWantParametersFromParcel(Parcel& parcel, AAFwk::WantParams& wantParams)
{
int empty = VALUE_NULL;
if (!parcel.ReadInt32(empty)) {
return false;
}
if (empty == VALUE_OBJECT) {
auto params = parcel.ReadParcelable();
if (params != nullptr) {
wantParams = *params;
delete params;
params = nullptr;
} else {
return false;
}
}
return true;
}
bool ReminderRequest::ReadFromParcel(Parcel &parcel)
{
READ_STRING_RETURN_FALSE_LOG(parcel, content_, "content");
READ_STRING_RETURN_FALSE_LOG(parcel, expiredContent_, "expiredContent");
READ_STRING_RETURN_FALSE_LOG(parcel, snoozeContent_, "snoozeContent");
READ_STRING_RETURN_FALSE_LOG(parcel, title_, "title");
READ_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->abilityName, "wantAgentInfo's abilityName");
READ_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->pkgName, "wantAgentInfo's pkgName");
READ_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->uri, "wantAgentInfo's uri");
if (!ReadWantParametersFromParcel(parcel, wantAgentInfo_->parameters)) {
ANSR_LOGE("Failed to write wantAgentInfo's parameters");
return false;
}
READ_STRING_RETURN_FALSE_LOG(parcel, maxScreenWantAgentInfo_->abilityName, "maxScreenWantAgentInfo's abilityName");
READ_STRING_RETURN_FALSE_LOG(parcel, maxScreenWantAgentInfo_->pkgName, "maxScreenWantAgentInfo's pkgName");
READ_STRING_RETURN_FALSE_LOG(parcel, customButtonUri_, "customButtonUri");
READ_STRING_RETURN_FALSE_LOG(parcel, groupId_, "groupId");
READ_STRING_RETURN_FALSE_LOG(parcel, customRingUri_, "customRingUri");
READ_STRING_RETURN_FALSE_LOG(parcel, creatorBundleName_, "creatorBundleName");
READ_BOOL_RETURN_FALSE_LOG(parcel, isExpired_, "isExpired");
READ_BOOL_RETURN_FALSE_LOG(parcel, tapDismissed_, "tapDismissed");
READ_INT64_RETURN_FALSE_LOG(parcel, autoDeletedTime_, "autoDeletedTime");
int32_t tempReminderId = -1;
READ_INT32_RETURN_FALSE_LOG(parcel, tempReminderId, "reminderId");
reminderId_ = (tempReminderId == -1) ? reminderId_ : tempReminderId;
READ_INT32_RETURN_FALSE_LOG(parcel, notificationId_, "notificationId");
READ_UINT64_RETURN_FALSE_LOG(parcel, triggerTimeInMilli_, "triggerTimeInMilli");
READ_UINT64_RETURN_FALSE_LOG(parcel, timeIntervalInMilli_, "timeIntervalInMilli");
READ_UINT64_RETURN_FALSE_LOG(parcel, ringDurationInMilli_, "ringDurationInMilli");
READ_UINT64_RETURN_FALSE_LOG(parcel, reminderTimeInMilli_, "reminderTimeInMilli");
READ_UINT8_RETURN_FALSE_LOG(parcel, snoozeTimes_, "snoozeTimes");
READ_UINT8_RETURN_FALSE_LOG(parcel, snoozeTimesDynamic_, "snoozeTimesDynamic");
READ_UINT8_RETURN_FALSE_LOG(parcel, state_, "state");
uint8_t reminderType = static_cast(ReminderType::INVALID);
READ_UINT8_RETURN_FALSE_LOG(parcel, reminderType, "reminderType");
reminderType_ = static_cast(reminderType);
int32_t slotType = static_cast(NotificationConstant::SlotType::OTHER);
READ_INT32_RETURN_FALSE_LOG(parcel, slotType, "slotType");
slotType_ = static_cast(slotType);
int32_t snoozeSlotType = static_cast(NotificationConstant::SlotType::OTHER);
READ_INT32_RETURN_FALSE_LOG(parcel, snoozeSlotType, "snoozeSlotType");
snoozeSlotType_ = static_cast(snoozeSlotType);
if (!ReadActionButtonFromParcel(parcel)) {
return false;
}
if (!InitNotificationRequest()) {
return false;
}
return true;
}
bool ReminderRequest::InitNotificationRequest()
{
ANSR_LOGI("Init notification");
notificationRequest_ = new (std::nothrow) NotificationRequest(notificationId_);
if (notificationRequest_ == nullptr) {
ANSR_LOGE("Failed to create notification.");
return false;
}
displayContent_ = content_;
return true;
}
void ReminderRequest::InitServerObj()
{
wantAgentInfo_ = wantAgentInfo_ == nullptr ? std::make_shared() : wantAgentInfo_;
maxScreenWantAgentInfo_ =
maxScreenWantAgentInfo_ == nullptr ? std::make_shared() : maxScreenWantAgentInfo_;
}
bool ReminderRequest::IsAlerting() const
{
return (state_ & REMINDER_STATUS_ALERTING) != 0;
}
uint64_t ReminderRequest::GetDurationSinceEpochInMilli(const time_t target)
{
auto tarEndTimePoint = std::chrono::system_clock::from_time_t(target);
auto tarDuration = std::chrono::duration_cast(tarEndTimePoint.time_since_epoch());
int64_t tarDate = tarDuration.count();
if (tarDate < 0) {
ANSR_LOGW("tarDuration is less than 0.");
return INVALID_LONG_LONG_VALUE;
}
return static_cast(tarDate);
}
std::string ReminderRequest::GetDateTimeInfo(const time_t &timeInSecond) const
{
return GetTimeInfoInner(timeInSecond, TimeFormat::YMDHMS, true);
}
std::string ReminderRequest::SerializeButtonInfo() const
{
std::string info = "";
bool isFirst = true;
for (auto button : actionButtonMap_) {
if (!isFirst) {
info += SEP_BUTTON_MULTI;
}
ActionButtonInfo buttonInfo = button.second;
nlohmann::json root;
root["type"] = std::to_string(static_cast(button.first));
root["title"] = buttonInfo.title;
root["resource"] = buttonInfo.resource;
if (buttonInfo.wantAgent != nullptr) {
nlohmann::json wantAgentfriends;
wantAgentfriends["pkgName"] = buttonInfo.wantAgent->pkgName;
wantAgentfriends["abilityName"] = buttonInfo.wantAgent->abilityName;
root["wantAgent"] = wantAgentfriends;
}
if (buttonInfo.dataShareUpdate != nullptr) {
nlohmann::json dataShareUpdatefriends;
dataShareUpdatefriends["uri"] = buttonInfo.dataShareUpdate->uri;
dataShareUpdatefriends["equalTo"] = buttonInfo.dataShareUpdate->equalTo;
dataShareUpdatefriends["valuesBucket"] = buttonInfo.dataShareUpdate->valuesBucket;
root["dataShareUpdate"] = dataShareUpdatefriends;
}
std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
info += str;
isFirst = false;
}
return info;
}
uint64_t ReminderRequest::GetNowInstantMilli() const
{
time_t now;
(void)time(&now); // unit is seconds.
if (static_cast(now) < 0) {
ANSR_LOGE("Get now time error");
return 0;
}
return GetDurationSinceEpochInMilli(now);
}
std::string ReminderRequest::GetShowTime(const uint64_t showTime) const
{
if (reminderType_ == ReminderType::TIMER) {
return "";
}
return GetTimeInfoInner(static_cast(showTime / MILLI_SECONDS), TimeFormat::HM, false);
}
std::string ReminderRequest::GetTimeInfoInner(const time_t &timeInSecond, const TimeFormat &format,
bool keep24Hour) const
{
const uint8_t dateTimeLen = 80;
char dateTimeBuffer[dateTimeLen];
struct tm timeInfo;
(void)localtime_r(&timeInSecond, &timeInfo);
bool is24HourClock = OHOS::Global::I18n::LocaleConfig::Is24HourClock();
if (!is24HourClock && timeInfo.tm_hour > TIME_HOUR_OFFSET && !keep24Hour) {
timeInfo.tm_hour -= TIME_HOUR_OFFSET;
}
switch (format) {
case TimeFormat::YMDHMS: {
(void)strftime(dateTimeBuffer, dateTimeLen, "%Y-%m-%d %H:%M:%S", &timeInfo);
break;
}
case TimeFormat::HM: {
(void)strftime(dateTimeBuffer, dateTimeLen, "%H:%M", &timeInfo);
break;
}
default: {
ANSR_LOGW("Time format not support.");
break;
}
}
std::string dateTimeInfo(dateTimeBuffer);
return dateTimeInfo;
}
std::string ReminderRequest::GetState(const uint8_t state) const
{
std::string stateInfo = "'";
if (state == REMINDER_STATUS_INACTIVE) {
stateInfo += "Inactive";
} else {
bool hasSeparator = false;
if ((state & REMINDER_STATUS_ACTIVE) != 0) {
stateInfo += "Active";
hasSeparator = true;
}
if ((state & REMINDER_STATUS_ALERTING) != 0) {
if (hasSeparator) {
stateInfo += ",";
}
stateInfo += "Alerting";
hasSeparator = true;
}
if ((state & REMINDER_STATUS_SHOWING) != 0) {
if (hasSeparator) {
stateInfo += ",";
}
stateInfo += "Showing";
hasSeparator = true;
}
if ((state & REMINDER_STATUS_SNOOZE) != 0) {
if (hasSeparator) {
stateInfo += ",";
}
stateInfo += "Snooze";
}
}
stateInfo += "'";
return stateInfo;
}
void ReminderRequest::AddActionButtons(const bool includeSnooze)
{
int32_t requestCode = 10;
std::vector flags;
flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
for (auto button : actionButtonMap_) {
auto want = std::make_shared();
auto type = button.first;
switch (type) {
case ActionButtonType::CLOSE:
want->SetAction(REMINDER_EVENT_CLOSE_ALERT);
break;
case ActionButtonType::SNOOZE:
if (includeSnooze) {
want->SetAction(REMINDER_EVENT_SNOOZE_ALERT);
} else {
ANSR_LOGD("Not add action button, type is snooze, as includeSnooze is false");
continue;
}
break;
case ActionButtonType::CUSTOM:
want->SetAction(REMINDER_EVENT_CUSTOM_ALERT);
if (button.second.wantAgent == nullptr) {
return;
}
want->SetParam("PkgName", button.second.wantAgent->pkgName);
want->SetParam("AbilityName", button.second.wantAgent->abilityName);
break;
default:
break;
}
want->SetParam(PARAM_REMINDER_ID, reminderId_);
std::vector> wants;
wants.push_back(want);
auto title = static_cast(button.second.title);
AbilityRuntime::WantAgent::WantAgentInfo buttonWantAgentInfo(
requestCode,
AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
flags,
wants,
nullptr
);
std::string identity = IPCSkeleton::ResetCallingIdentity();
std::shared_ptr buttonWantAgent =
AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(buttonWantAgentInfo, userId_);
IPCSkeleton::SetCallingIdentity(identity);
std::shared_ptr actionButton
= NotificationActionButton::Create(nullptr, title, buttonWantAgent);
notificationRequest_->AddActionButton(actionButton);
}
}
void ReminderRequest::AddRemovalWantAgent()
{
int32_t requestCode = 10;
std::vector flags;
flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
auto want = std::make_shared();
want->SetAction(REMINDER_EVENT_REMOVE_NOTIFICATION);
want->SetParam(PARAM_REMINDER_ID, reminderId_);
std::vector> wants;
wants.push_back(want);
AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
requestCode,
AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
flags,
wants,
nullptr
);
std::string identity = IPCSkeleton::ResetCallingIdentity();
std::shared_ptr wantAgent =
AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo, userId_);
IPCSkeleton::SetCallingIdentity(identity);
notificationRequest_->SetRemovalWantAgent(wantAgent);
}
std::shared_ptr ReminderRequest::CreateWantAgent(
AppExecFwk::ElementName &element) const
{
int32_t requestCode = 10;
std::vector wantFlags;
wantFlags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
auto want = std::make_shared();
want->SetAction(REMINDER_EVENT_CLICK_ALERT);
want->SetParam(PARAM_REMINDER_ID, reminderId_);
std::vector> wantes;
wantes.push_back(want);
AbilityRuntime::WantAgent::WantAgentInfo wantInfo(
requestCode,
AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
wantFlags,
wantes,
nullptr
);
std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
auto wantAgent = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantInfo, userId_);
IPCSkeleton::SetCallingIdentity(callingIdentity);
return wantAgent;
}
std::shared_ptr ReminderRequest::CreateMaxWantAgent(
AppExecFwk::ElementName &element) const
{
int32_t requestCode = 10;
std::vector flags;
flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
auto want = std::make_shared();
want->SetElement(element);
std::vector> wants;
wants.push_back(want);
AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
requestCode,
AbilityRuntime::WantAgent::WantAgentConstant::OperationType::START_ABILITY,
flags,
wants,
nullptr
);
std::string identity = IPCSkeleton::ResetCallingIdentity();
auto wantAgent = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo, userId_);
IPCSkeleton::SetCallingIdentity(identity);
return wantAgent;
}
void ReminderRequest::SetMaxScreenWantAgent(AppExecFwk::ElementName &element)
{
std::shared_ptr wantAgent = CreateMaxWantAgent(element);
notificationRequest_->SetMaxScreenWantAgent(wantAgent);
}
void ReminderRequest::SetWantAgent(AppExecFwk::ElementName &element)
{
std::shared_ptr wantAgent = CreateWantAgent(element);
notificationRequest_->SetWantAgent(wantAgent);
}
void ReminderRequest::SetExtraInfo(const AAFwk::WantParams& params)
{
if (params.HasParam(PARAM_EXTRA_KEY)) {
std::shared_ptr extras = std::make_shared(
params.GetWantParams(PARAM_EXTRA_KEY));
notificationRequest_->SetAdditionalData(extras);
}
}
void ReminderRequest::SetState(bool deSet, const uint8_t newState, std::string function)
{
uint8_t oldState = state_;
if (deSet) {
state_ |= newState;
} else {
state_ &= static_cast(~newState);
}
ANSR_LOGI("Switch the reminder(reminderId=%{public}d) state, from %{public}s to %{public}s, called by %{public}s",
reminderId_, GetState(oldState).c_str(), GetState(state_).c_str(), function.c_str());
}
void ReminderRequest::SetStateToInActive()
{
SetState(false, (REMINDER_STATUS_SHOWING | REMINDER_STATUS_ALERTING | REMINDER_STATUS_ACTIVE),
"SetStateToInActive");
}
void ReminderRequest::UpdateActionButtons(const bool &setSnooze)
{
if (notificationRequest_ == nullptr) {
ANSR_LOGE("updateActionButtons failed, the notificationRequest is null");
return;
}
notificationRequest_->ClearActionButtons();
if (setSnooze) {
AddActionButtons(false);
} else {
AddActionButtons(true);
}
}
bool ReminderRequest::UpdateNextReminder(const bool &force)
{
bool result = true;
if (force) {
uint64_t nowInstantMilli = GetNowInstantMilli();
if (nowInstantMilli == 0) {
result = false;
} else {
if (timeIntervalInMilli_ != 0) {
triggerTimeInMilli_ = nowInstantMilli + timeIntervalInMilli_;
snoozeTimesDynamic_ = snoozeTimes_;
isExpired_ = false;
}
}
} else {
result = UpdateNextReminder();
}
std::string info = result ? "success" : "no next";
ANSR_LOGI("updateNextReminder(id=%{public}d, %{public}s): force=%{public}d, trigger time is: %{public}s",
reminderId_, info.c_str(), force,
GetDateTimeInfo(static_cast(triggerTimeInMilli_ / MILLI_SECONDS)).c_str());
return result;
}
void ReminderRequest::UpdateNotificationCommon(bool isSnooze)
{
time_t now;
(void)time(&now); // unit is seconds.
notificationRequest_->SetDeliveryTime(GetDurationSinceEpochInMilli(now));
notificationRequest_->SetLabel(NOTIFICATION_LABEL);
notificationRequest_->SetShowDeliveryTime(true);
if (isSnooze) {
if (snoozeSlotType_ == NotificationConstant::SlotType::OTHER) {
notificationRequest_->SetSlotType(NotificationConstant::SlotType::CONTENT_INFORMATION);
} else {
notificationRequest_->SetSlotType(snoozeSlotType_);
}
} else {
notificationRequest_->SetSlotType(slotType_);
}
notificationRequest_->SetTapDismissed(tapDismissed_);
notificationRequest_->SetAutoDeletedTime(autoDeletedTime_);
auto notificationNormalContent = std::make_shared();
notificationNormalContent->SetText(displayContent_);
notificationNormalContent->SetTitle(title_);
auto notificationContent = std::make_shared(notificationNormalContent);
notificationRequest_->SetContent(notificationContent);
if ((reminderType_ == ReminderRequest::ReminderType::TIMER) ||
(reminderType_ == ReminderRequest::ReminderType::ALARM)) {
notificationRequest_->SetUnremovable(true);
}
}
void ReminderRequest::UpdateNotificationBundleInfo()
{
std::string ownerBundleName = notificationRequest_->GetOwnerBundleName();
if (!(ownerBundleName.empty())) {
return;
}
ANSR_LOGD("ownerBundleName=%{public}s, bundleName_=%{public}s",
ownerBundleName.c_str(), bundleName_.c_str());
notificationRequest_->SetOwnerBundleName(bundleName_);
notificationRequest_->SetOwnerUid(uid_);
notificationRequest_->SetCreatorBundleName(bundleName_);
notificationRequest_->SetCreatorUid(uid_);
notificationRequest_->SetCreatorUserId(userId_);
}
void ReminderRequest::UpdateNotificationContent(const bool &setSnooze)
{
if (notificationRequest_ == nullptr) {
ANSR_LOGE("updateNotificationContent failed, the notificationRequest is null");
return;
}
std::string extendContent = "";
if (setSnooze) {
if (timeIntervalInMilli_ != 0) {
// snooze the reminder by manual
extendContent = snoozeContent_;
notificationRequest_->SetTapDismissed(false);
} else {
// the reminder is expired now, when timeInterval is 0
extendContent = expiredContent_;
}
} else if (IsAlerting()) {
// the reminder is alerting, or ring duration is 0
extendContent = "";
} else if (snoozeTimesDynamic_ != snoozeTimes_) {
// the reminder is snoozing by period artithmetic, when the ring duration is over.
extendContent = snoozeContent_;
notificationRequest_->SetTapDismissed(false);
} else {
// the reminder has already snoozed by period arithmetic, when the ring duration is over.
extendContent = expiredContent_;
}
if (extendContent == "") {
displayContent_ = content_;
} else {
displayContent_ = extendContent;
}
ANSR_LOGD("Display content=%{public}s", displayContent_.c_str());
}
void ReminderRequest::UpdateNotificationStateForAlert()
{
ANSR_LOGD("UpdateNotification content and buttons");
UpdateNotificationContent(false);
UpdateActionButtons(false);
}
void ReminderRequest::UpdateNotificationStateForSnooze()
{
ANSR_LOGD("UpdateNotification content and buttons");
UpdateNotificationContent(true);
UpdateActionButtons(true);
}
int32_t ReminderRequest::GetActualTime(const TimeTransferType &type, int32_t cTime)
{
switch (type) {
case (TimeTransferType::YEAR): // year
return BASE_YEAR + cTime;
case (TimeTransferType::MONTH): // month
return 1 + cTime;
case (TimeTransferType::WEEK): { // week
return cTime == 0 ? SUNDAY : cTime;
}
default:
return -1;
}
}
int32_t ReminderRequest::GetCTime(const TimeTransferType &type, int32_t actualTime)
{
switch (type) {
case (TimeTransferType::YEAR): // year
return actualTime - BASE_YEAR;
case (TimeTransferType::MONTH): // month
return actualTime - 1;
case (TimeTransferType::WEEK): { // week
return actualTime == SUNDAY ? 0 : actualTime;
}
default:
return -1;
}
}
void ReminderRequest::SerializeWantAgent(std::string& wantInfoStr, std::string& maxWantInfoStr)
{
std::string pkgName;
std::string abilityName;
std::string uri;
std::string parameters;
if (wantAgentInfo_ != nullptr) {
pkgName = wantAgentInfo_->pkgName;
abilityName = wantAgentInfo_->abilityName;
uri = wantAgentInfo_->uri;
AAFwk::WantParamWrapper wrapper(wantAgentInfo_->parameters);
parameters = wrapper.ToString();
}
nlohmann::json wantInfo;
wantInfo["pkgName"] = pkgName;
wantInfo["abilityName"] = abilityName;
wantInfo["uri"] = uri;
wantInfo["parameters"] = parameters;
wantInfoStr = wantInfo.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
if (maxScreenWantAgentInfo_ != nullptr) {
pkgName = maxScreenWantAgentInfo_->pkgName;
abilityName = maxScreenWantAgentInfo_->abilityName;
uri = "";
parameters = "";
}
nlohmann::json maxWantInfo;
maxWantInfo["pkgName"] = pkgName;
maxWantInfo["abilityName"] = abilityName;
maxWantInfo["uri"] = uri;
maxWantInfo["parameters"] = parameters;
maxWantInfoStr = maxWantInfo.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
}
int64_t ReminderRequest::GetNextDaysOfWeek(const time_t now, const time_t target) const
{
struct tm nowTime;
(void)localtime_r(&now, &nowTime);
int32_t today = GetActualTime(TimeTransferType::WEEK, nowTime.tm_wday);
int32_t dayCount = now >= target ? 1 : 0;
for (; dayCount <= DAYS_PER_WEEK; dayCount++) {
int32_t day = (today + dayCount) % DAYS_PER_WEEK;
day = (day == 0) ? SUNDAY : day;
if (IsRepeatDaysOfWeek(day)) {
break;
}
}
ANSR_LOGI("NextDayInterval is %{public}d", dayCount);
time_t nextTriggerTime = target + dayCount * HOURS_PER_DAY * SECONDS_PER_HOUR;
return GetTriggerTime(now, nextTriggerTime);
}
bool ReminderRequest::IsRepeatDaysOfWeek(int32_t day) const
{
return (repeatDaysOfWeek_ & (1 << (day - 1))) > 0;
}
time_t ReminderRequest::GetTriggerTimeWithDST(const time_t now, const time_t nextTriggerTime) const
{
time_t triggerTime = nextTriggerTime;
struct tm nowLocal;
struct tm nextLocal;
(void)localtime_r(&now, &nowLocal);
(void)localtime_r(&nextTriggerTime, &nextLocal);
if (nowLocal.tm_isdst == 0 && nextLocal.tm_isdst > 0) {
triggerTime -= SECONDS_PER_HOUR;
} else if (nowLocal.tm_isdst > 0 && nextLocal.tm_isdst == 0) {
triggerTime += SECONDS_PER_HOUR;
}
return triggerTime;
}
uint8_t ReminderRequest::GetRepeatDaysOfWeek() const
{
return repeatDaysOfWeek_;
}
void ReminderRequest::SetRepeatDaysOfWeek(bool set, const std::vector &daysOfWeek)
{
if (daysOfWeek.size() == 0) {
return;
}
if (daysOfWeek.size() > DAYS_PER_WEEK) {
ANSR_LOGE("The length of daysOfWeek should not larger than 7");
return;
}
for (auto it = daysOfWeek.begin(); it != daysOfWeek.end(); ++it) {
if (*it < MONDAY || *it > SUNDAY) {
continue;
}
if (set) {
repeatDaysOfWeek_ |= 1 << (*it - 1);
} else {
repeatDaysOfWeek_ &= ~(1 << (*it - 1));
}
}
}
std::vector ReminderRequest::GetDaysOfWeek() const
{
std::vector repeatDays;
int32_t days[] = {1, 2, 3, 4, 5, 6, 7};
int32_t len = sizeof(days) / sizeof(int32_t);
for (int32_t i = 0; i < len; i++) {
if (IsRepeatDaysOfWeek(days[i])) {
repeatDays.push_back(days[i]);
}
}
return repeatDays;
}
uint64_t ReminderRequest::GetTriggerTime(const time_t now, const time_t nextTriggerTime) const
{
time_t triggerTime = GetTriggerTimeWithDST(now, nextTriggerTime);
struct tm test;
(void)localtime_r(&triggerTime, &test);
ANSR_LOGI("NextTriggerTime: year=%{public}d, mon=%{public}d, day=%{public}d, hour=%{public}d, "
"min=%{public}d, sec=%{public}d, week=%{public}d, nextTriggerTime=%{public}lld",
GetActualTime(TimeTransferType::YEAR, test.tm_year),
GetActualTime(TimeTransferType::MONTH, test.tm_mon),
test.tm_mday,
test.tm_hour,
test.tm_min,
test.tm_sec,
GetActualTime(TimeTransferType::WEEK, test.tm_wday),
(long long)triggerTime);
if (static_cast(triggerTime) <= 0) {
return 0;
}
return GetDurationSinceEpochInMilli(triggerTime);
}
void ReminderRequest::OnLanguageChange(const std::shared_ptr &resMgr)
{
if (resMgr == nullptr) {
return;
}
// update title
for (auto &button : actionButtonMap_) {
if (button.second.resource.empty()) {
continue;
}
std::string title;
resMgr->GetStringByName(button.second.resource.c_str(), title);
if (title.empty()) {
continue;
}
button.second.title = title;
}
}
}
}