/*
* 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 "os_account_manager.h"
#include "reminder_store.h"
#include "system_ability_definition.h"
#include "want_agent_helper.h"
namespace OHOS {
namespace Notification {
namespace {
const int32_t BASE_YEAR = 1900;
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;
}
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_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 int32_t ReminderRequest::SUNDAY = 7;
// For database recovery.
const std::string ReminderRequest::REMINDER_ID = "reminder_id";
const std::string ReminderRequest::PKG_NAME = "package_name";
const std::string ReminderRequest::USER_ID = "user_id";
const std::string ReminderRequest::UID = "uid";
const std::string ReminderRequest::SYS_APP = "system_app";
const std::string ReminderRequest::APP_LABEL = "app_label";
const std::string ReminderRequest::REMINDER_TYPE = "reminder_type";
const std::string ReminderRequest::REMINDER_TIME = "reminder_time";
const std::string ReminderRequest::TRIGGER_TIME = "trigger_time";
const std::string ReminderRequest::RTC_TRIGGER_TIME = "rtc_trigger_time";
const std::string ReminderRequest::TIME_INTERVAL = "time_interval";
const std::string ReminderRequest::SNOOZE_TIMES = "snooze_times";
const std::string ReminderRequest::DYNAMIC_SNOOZE_TIMES = "dynamic_snooze_times";
const std::string ReminderRequest::RING_DURATION = "ring_duration";
const std::string ReminderRequest::IS_EXPIRED = "is_expired";
const std::string ReminderRequest::IS_ACTIVE = "is_active";
const std::string ReminderRequest::STATE = "state";
const std::string ReminderRequest::ZONE_ID = "zone_id";
const std::string ReminderRequest::HAS_SCHEDULED_TIMEOUT = "has_ScheduledTimeout";
const std::string ReminderRequest::ACTION_BUTTON_INFO = "button_info";
const std::string ReminderRequest::CUSTOM_BUTTON_URI = "custom_button_uri";
const std::string ReminderRequest::SLOT_ID = "slot_id";
const std::string ReminderRequest::NOTIFICATION_ID = "notification_id";
const std::string ReminderRequest::TITLE = "title";
const std::string ReminderRequest::CONTENT = "content";
const std::string ReminderRequest::SNOOZE_CONTENT = "snooze_content";
const std::string ReminderRequest::EXPIRED_CONTENT = "expired_content";
const std::string ReminderRequest::AGENT = "agent";
const std::string ReminderRequest::MAX_SCREEN_AGENT = "maxScreen_agent";
const std::string ReminderRequest::TAP_DISMISSED = "tapDismissed";
const std::string ReminderRequest::AUTO_DELETED_TIME = "autoDeletedTime";
std::string ReminderRequest::sqlOfAddColumns = "";
std::vector ReminderRequest::columns;
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->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_;
}
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::shared_ptr &buttonWantAgent)
{
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.wantAgent = buttonWantAgent;
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::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;
}
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, oldZoneTriggerTime:%{public}" PRIu64 "\
, newZoneTriggerTime:%{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 oriTime;
(void)gmtime_r(&oldZoneTriggerTime, &oriTime);
time_t newZoneTriggerTime = mktime(&oriTime);
uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(true, false);
return HandleTimeZoneChange(
triggerTimeInMilli_, GetDurationSinceEpochInMilli(newZoneTriggerTime), nextTriggerTime);
}
int64_t ReminderRequest::RecoverInt64FromDb(const std::shared_ptr &resultSet,
const std::string &columnName, const DbRecoveryType &columnType)
{
if (resultSet == nullptr) {
ANSR_LOGE("ResultSet is null");
return 0;
}
switch (columnType) {
case (DbRecoveryType::INT): {
int32_t value;
resultSet->GetInt(ReminderStore::GetColumnIndex(columnName), value);
return static_cast(value);
}
case (DbRecoveryType::LONG): {
int64_t value;
resultSet->GetLong(ReminderStore::GetColumnIndex(columnName), value);
return value;
}
default: {
ANSR_LOGD("ColumnType not support.");
break;
}
}
ANSR_LOGE("Recover data error");
return 0;
}
void ReminderRequest::RecoverFromDb(const std::shared_ptr &resultSet)
{
if (resultSet == nullptr) {
ANSR_LOGE("ResultSet is null");
return;
}
// reminderId
resultSet->GetInt(ReminderStore::GetColumnIndex(REMINDER_ID), reminderId_);
// userId
resultSet->GetInt(ReminderStore::GetColumnIndex(USER_ID), userId_);
// bundleName
resultSet->GetString(ReminderStore::GetColumnIndex(PKG_NAME), bundleName_);
// uid
resultSet->GetInt(ReminderStore::GetColumnIndex(UID), uid_);
// isSystemApp
std::string isSysApp;
resultSet->GetString(ReminderStore::GetColumnIndex(SYS_APP), isSysApp);
isSystemApp_ = isSysApp == "true" ? true : false;
// reminderType
int32_t reminderType;
resultSet->GetInt(ReminderStore::GetColumnIndex(REMINDER_TYPE), reminderType);
reminderType_ = ReminderType(reminderType);
// reminderTime
reminderTimeInMilli_ =
static_cast(RecoverInt64FromDb(resultSet, REMINDER_TIME, DbRecoveryType::LONG));
// triggerTime
triggerTimeInMilli_ =
static_cast(RecoverInt64FromDb(resultSet, TRIGGER_TIME, DbRecoveryType::LONG));
// timeInterval
uint64_t timeIntervalInSecond =
static_cast(RecoverInt64FromDb(resultSet, TIME_INTERVAL, DbRecoveryType::LONG));
SetTimeInterval(timeIntervalInSecond);
// snoozeTimes
snoozeTimes_ = static_cast(RecoverInt64FromDb(resultSet, SNOOZE_TIMES, DbRecoveryType::INT));
// dynamicSnoozeTimes
snoozeTimesDynamic_ =
static_cast(RecoverInt64FromDb(resultSet, DYNAMIC_SNOOZE_TIMES, DbRecoveryType::INT));
// ringDuration
uint64_t ringDurationInSecond =
static_cast(RecoverInt64FromDb(resultSet, RING_DURATION, DbRecoveryType::LONG));
SetRingDuration(ringDurationInSecond);
// isExpired
std::string isExpired;
resultSet->GetString(ReminderStore::GetColumnIndex(IS_EXPIRED), isExpired);
isExpired_ = isExpired == "true" ? true : false;
// state
state_ = static_cast(RecoverInt64FromDb(resultSet, STATE, DbRecoveryType::INT));
// action buttons
RecoverActionButton(resultSet);
// slotType
int32_t slotType;
resultSet->GetInt(ReminderStore::GetColumnIndex(SLOT_ID), slotType);
slotType_ = NotificationConstant::SlotType(slotType);
// notification id
resultSet->GetInt(ReminderStore::GetColumnIndex(NOTIFICATION_ID), notificationId_);
// title
resultSet->GetString(ReminderStore::GetColumnIndex(TITLE), title_);
// content
resultSet->GetString(ReminderStore::GetColumnIndex(CONTENT), content_);
// snoozeContent
resultSet->GetString(ReminderStore::GetColumnIndex(SNOOZE_CONTENT), snoozeContent_);
// expiredContent
resultSet->GetString(ReminderStore::GetColumnIndex(EXPIRED_CONTENT), expiredContent_);
InitNotificationRequest(); // must set before wantAgent & maxScreenWantAgent
// wantAgent
std::string wantAgent;
resultSet->GetString(ReminderStore::GetColumnIndex(AGENT), wantAgent);
RecoverWantAgent(wantAgent, 0);
// maxScreenWantAgent
std::string maxScreenWantAgent;
resultSet->GetString(ReminderStore::GetColumnIndex(MAX_SCREEN_AGENT), maxScreenWantAgent);
RecoverWantAgent(maxScreenWantAgent, 1);
// tapDismissed
std::string tapDismissed;
resultSet->GetString(ReminderStore::GetColumnIndex(TAP_DISMISSED), tapDismissed);
tapDismissed_ = tapDismissed == "true" ? true : false;
// autoDeletedTime
autoDeletedTime_ =
static_cast(RecoverInt64FromDb(resultSet, AUTO_DELETED_TIME, DbRecoveryType::LONG));
// customButtonUri
resultSet->GetString(ReminderStore::GetColumnIndex(CUSTOM_BUTTON_URI), customButtonUri_);
}
void ReminderRequest::RecoverActionButton(const std::shared_ptr &resultSet)
{
if (resultSet == nullptr) {
ANSR_LOGE("ResultSet is null");
return;
}
std::string actionButtonInfo;
resultSet->GetString(ReminderStore::GetColumnIndex(ACTION_BUTTON_INFO), actionButtonInfo);
std::vector multiButton = StringSplit(actionButtonInfo, SEP_BUTTON_MULTI);
for (auto button : multiButton) {
std::vector singleButton = StringSplit(button, SEP_BUTTON_SINGLE);
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);
}
SetActionButton(singleButton.at(BUTTON_TITLE_INDEX),
ActionButtonType(std::stoi(singleButton.at(BUTTON_TYPE_INDEX), nullptr)), buttonWantAgent);
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) const
{
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::RecoverWantAgent(const std::string &wantAgentInfo, const uint8_t &type)
{
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);
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::SetSlotType(const NotificationConstant::SlotType &slotType)
{
slotType_ = slotType;
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)
{
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::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_;
}
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)
{
if ((ringDurationInSeconds == 0) || (ringDurationInSeconds > (UINT64_MAX / MILLI_SECONDS))) {
ANSR_LOGW("setRingDuration, replace to set (1s), for the given is out of legal range");
ringDurationInMilli_ = MILLI_SECONDS;
} else {
ringDurationInMilli_ = ringDurationInSeconds * MILLI_SECONDS;
}
return *this;
}
NotificationConstant::SlotType ReminderRequest::GetSlotType() const
{
return slotType_;
}
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_;
}
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_;
}
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::UpdateNotificationRequest(UpdateNotificationType type, std::string extra)
{
switch (type) {
case UpdateNotificationType::COMMON: {
ANSR_LOGI("UpdateNotification common information");
UpdateNotificationCommon();
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);
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::Marshalling(Parcel &parcel) const
{
// write string
if (!parcel.WriteString(content_)) {
ANSR_LOGE("Failed to write content");
return false;
}
if (!parcel.WriteString(expiredContent_)) {
ANSR_LOGE("Failed to write expiredContent");
return false;
}
if (!parcel.WriteString(snoozeContent_)) {
ANSR_LOGE("Failed to write snoozeContent");
return false;
}
if (!parcel.WriteString(title_)) {
ANSR_LOGE("Failed to write title");
return false;
}
if (!parcel.WriteString(wantAgentInfo_->abilityName)) {
ANSR_LOGE("Failed to write wantAgentInfo`s abilityName");
return false;
}
if (!parcel.WriteString(wantAgentInfo_->pkgName)) {
ANSR_LOGE("Failed to write wantAgentInfo`s pkgName");
return false;
}
if (!parcel.WriteString(maxScreenWantAgentInfo_->abilityName)) {
ANSR_LOGE("Failed to write maxScreenWantAgentInfo`s abilityName");
return false;
}
if (!parcel.WriteString(maxScreenWantAgentInfo_->pkgName)) {
ANSR_LOGE("Failed to write maxScreenWantAgentInfo`s pkgName");
return false;
}
if (!parcel.WriteString(customButtonUri_)) {
ANSR_LOGE("Failed to write customButtonUri");
return false;
}
// write bool
if (!parcel.WriteBool(isExpired_)) {
ANSR_LOGE("Failed to write isExpired");
return false;
}
if (!parcel.WriteBool(isSystemApp_)) {
ANSR_LOGE("Failed to write isSystemApp");
return false;
}
if (!parcel.WriteBool(tapDismissed_)) {
ANSR_LOGE("Failed to write tapDismissed");
return false;
}
// write int
if (!parcel.WriteInt64(autoDeletedTime_)) {
ANSR_LOGE("Failed to write autoDeletedTime");
return false;
}
if (!parcel.WriteInt32(reminderId_)) {
ANSR_LOGE("Failed to write reminderId");
return false;
}
if (!parcel.WriteInt32(notificationId_)) {
ANSR_LOGE("Failed to write notificationId");
return false;
}
if (!parcel.WriteUint64(triggerTimeInMilli_)) {
ANSR_LOGE("Failed to write triggerTimeInMilli");
return false;
}
if (!parcel.WriteUint64(timeIntervalInMilli_)) {
ANSR_LOGE("Failed to write timeIntervalInMilli");
return false;
}
if (!parcel.WriteUint64(ringDurationInMilli_)) {
ANSR_LOGE("Failed to write ringDurationInMilli");
return false;
}
if (!parcel.WriteUint64(reminderTimeInMilli_)) {
ANSR_LOGE("Failed to write reminderTimeInMilli");
return false;
}
if (!parcel.WriteUint8(snoozeTimes_)) {
ANSR_LOGE("Failed to write snoozeTimes");
return false;
}
if (!parcel.WriteUint8(snoozeTimesDynamic_)) {
ANSR_LOGE("Failed to write snoozeTimesDynamic");
return false;
}
if (!parcel.WriteUint8(state_)) {
ANSR_LOGE("Failed to write state");
return false;
}
// write enum
if (!parcel.WriteUint8(static_cast(reminderType_))) {
ANSR_LOGE("Failed to write reminder type");
return false;
}
if (!parcel.WriteInt32(static_cast(slotType_))) {
ANSR_LOGE("Failed to write slot type");
return false;
}
// write map
if (!parcel.WriteUint64(static_cast(actionButtonMap_.size()))) {
ANSR_LOGE("Failed to write action button size");
return false;
}
for (auto button : actionButtonMap_) {
if (!parcel.WriteUint8(static_cast(button.first))) {
ANSR_LOGE("Failed to write action button type");
return false;
}
if (!parcel.WriteString(static_cast(button.second.title))) {
ANSR_LOGE("Failed to write action button title");
return false;
}
if (button.second.wantAgent == nullptr) {
ANSR_LOGE("button wantAgent is null");
return false;
}
if (!parcel.WriteString(button.second.wantAgent->pkgName)) {
ANSR_LOGE("Failed to write action button pkgName");
return false;
}
if (!parcel.WriteString(button.second.wantAgent->abilityName)) {
ANSR_LOGE("Failed to write action button abilityName");
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::ReadFromParcel(Parcel &parcel)
{
// read string
if (!parcel.ReadString(content_)) {
ANSR_LOGE("Failed to read content");
return false;
}
if (!parcel.ReadString(expiredContent_)) {
ANSR_LOGE("to read expiredContent");
return false;
}
if (!parcel.ReadString(snoozeContent_)) {
ANSR_LOGE("to read snoozeContent");
return false;
}
if (!parcel.ReadString(title_)) {
ANSR_LOGE("Failed to read title");
return false;
}
if (!parcel.ReadString(wantAgentInfo_->abilityName)) {
ANSR_LOGE("Failed to read wantAgentInfo`s abilityName");
return false;
}
if (!parcel.ReadString(wantAgentInfo_->pkgName)) {
ANSR_LOGE("Failed to read wantAgentInfo`s pkgName");
return false;
}
if (!parcel.ReadString(maxScreenWantAgentInfo_->abilityName)) {
ANSR_LOGE("Failed to read maxScreenWantAgentInfo`s abilityName");
return false;
}
if (!parcel.ReadString(maxScreenWantAgentInfo_->pkgName)) {
ANSR_LOGE("Failed to read maxScreenWantAgentInfo`s pkgName");
return false;
}
if (!parcel.ReadString(customButtonUri_)) {
ANSR_LOGE("Failed to read customButtonUri");
return false;
}
// read bool
if (!parcel.ReadBool(isExpired_)) {
ANSR_LOGE("Failed to read isExpired");
return false;
}
if (!parcel.ReadBool(isSystemApp_)) {
ANSR_LOGE("Failed to read isSystemApp");
return false;
}
if (!parcel.ReadBool(tapDismissed_)) {
ANSR_LOGE("Failed to read tapDismissed");
return false;
}
// read int
if (!parcel.ReadInt64(autoDeletedTime_)) {
ANSR_LOGE("Failed to read autoDeletedTime");
return false;
}
int32_t tempReminderId = -1;
if (!parcel.ReadInt32(tempReminderId)) {
ANSR_LOGE("Failed to read tempReminderId");
return false;
}
reminderId_ = (tempReminderId == -1) ? reminderId_ : tempReminderId;
if (!parcel.ReadInt32(notificationId_)) {
ANSR_LOGE("Failed to read notificationId");
return false;
}
if (!parcel.ReadUint64(triggerTimeInMilli_)) {
ANSR_LOGE("Failed to read triggerTimeInMilli");
return false;
}
if (!parcel.ReadUint64(timeIntervalInMilli_)) {
ANSR_LOGE("Failed to read timeIntervalInMilli");
return false;
}
if (!parcel.ReadUint64(ringDurationInMilli_)) {
ANSR_LOGE("Failed to read ringDurationInMilli");
return false;
}
if (!parcel.ReadUint64(reminderTimeInMilli_)) {
ANSR_LOGE("Failed to read reminderTimeInMilli");
return false;
}
if (!parcel.ReadUint8(snoozeTimes_)) {
ANSR_LOGE("Failed to read snoozeTimes");
return false;
}
if (!parcel.ReadUint8(snoozeTimesDynamic_)) {
ANSR_LOGE("Failed to read snoozeTimesDynamic");
return false;
}
if (!parcel.ReadUint8(state_)) {
ANSR_LOGE("Failed to read state");
return false;
}
// read enum
uint8_t reminderType = static_cast(ReminderType::INVALID);
if (!parcel.ReadUint8(reminderType)) {
ANSR_LOGE("Failed to read reminderType");
return false;
}
reminderType_ = static_cast(reminderType);
int32_t slotType = static_cast(NotificationConstant::SlotType::OTHER);
if (!parcel.ReadInt32(slotType)) {
ANSR_LOGE("Failed to read slotType");
return false;
}
slotType_ = static_cast(slotType);
// read map
uint64_t buttonMapSize = 0;
if (!parcel.ReadUint64(buttonMapSize)) {
ANSR_LOGE("Failed to read buttonMapSize");
return false;
}
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);
if (!parcel.ReadUint8(buttonType)) {
ANSR_LOGE("Failed to read buttonType");
return false;
}
ActionButtonType type = static_cast(buttonType);
std::string title = parcel.ReadString();
std::string pkgName = parcel.ReadString();
std::string abilityName = parcel.ReadString();
ActionButtonInfo info;
info.type = type;
info.title = title;
info.wantAgent = std::make_shared();
info.wantAgent->pkgName = pkgName;
info.wantAgent->abilityName = abilityName;
actionButtonMap_.insert(std::pair(type, info));
}
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_;
AddActionButtons(true);
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::GetButtonInfo() const
{
std::string info = "";
bool isFirst = true;
for (auto button : actionButtonMap_) {
if (!isFirst) {
info += SEP_BUTTON_MULTI;
}
ActionButtonInfo buttonInfo = button.second;
info += std::to_string(static_cast(button.first)) + SEP_BUTTON_SINGLE + buttonInfo.title;
if (buttonInfo.wantAgent == nullptr) {
continue;
}
info += (SEP_BUTTON_SINGLE + buttonInfo.wantAgent->pkgName + SEP_BUTTON_SINGLE
+ buttonInfo.wantAgent->abilityName);
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 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 = CreateWantAgent(element);
notificationRequest_->SetMaxScreenWantAgent(wantAgent);
}
void ReminderRequest::SetWantAgent(AppExecFwk::ElementName &element)
{
std::shared_ptr wantAgent = CreateWantAgent(element);
notificationRequest_->SetWantAgent(wantAgent);
}
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::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 {
triggerTimeInMilli_ = nowInstantMilli + timeIntervalInMilli_;
snoozeTimesDynamic_ = snoozeTimes_;
if (timeIntervalInMilli_ != 0) {
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()
{
time_t now;
(void)time(&now); // unit is seconds.
notificationRequest_->SetDeliveryTime(GetDurationSinceEpochInMilli(now));
notificationRequest_->SetLabel(NOTIFICATION_LABEL);
notificationRequest_->SetShowDeliveryTime(true);
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);
}
auto flags = std::make_shared();
flags->SetSoundEnabled(NotificationConstant::FlagStatus::CLOSE);
flags->SetVibrationEnabled(NotificationConstant::FlagStatus::CLOSE);
notificationRequest_->SetFlags(flags);
}
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_->SetCreatorBundleName(bundleName_);
notificationRequest_->SetCreatorUid(uid_);
ErrCode errCode = AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid_, userId_);
if (errCode != ERR_OK) {
ANSR_LOGE("GetOsAccountLocalIdFromUid fail.");
return;
}
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 = GetShowTime(triggerTimeInMilli_) +
(snoozeContent_ == "" ? "" : (" (" + snoozeContent_ + ")"));
notificationRequest_->SetTapDismissed(false);
} else {
// the reminder is expired now, when timeInterval is 0
extendContent = GetShowTime(reminderTimeInMilli_) +
(expiredContent_ == "" ? "" : (" (" + expiredContent_ + ")"));
}
} else if (IsAlerting()) {
// the reminder is alerting, or ring duration is 0
extendContent = GetShowTime(reminderTimeInMilli_);
} else if (snoozeTimesDynamic_ != snoozeTimes_) {
// the reminder is snoozing by period artithmetic, when the ring duration is over.
extendContent = GetShowTime(triggerTimeInMilli_) +
(snoozeContent_ == "" ? "" : (" (" + snoozeContent_ + ")"));
notificationRequest_->SetTapDismissed(false);
} else {
// the reminder has already snoozed by period arithmetic, when the ring duration is over.
extendContent = GetShowTime(reminderTimeInMilli_) +
(expiredContent_ == "" ? "" : (" (" + expiredContent_ + ")"));
}
displayContent_ = content_ + " " + 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;
}
}
int32_t ReminderRequest::GetUid(const int32_t &userId, const std::string &bundleName)
{
AppExecFwk::ApplicationInfo info;
sptr systemAbilityManager
= SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (systemAbilityManager == nullptr) {
ANSR_LOGE("Failed to get uid due to get systemAbilityManager is null.");
return -1;
}
sptr remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
if (remoteObject == nullptr) {
ANSR_LOGE("Fail to get bundle manager proxy");
return -1;
}
sptr bundleMgr = iface_cast(remoteObject);
if (bundleMgr == nullptr) {
ANSR_LOGE("Bundle mgr proxy is nullptr");
return -1;
}
bundleMgr->GetApplicationInfo(bundleName, AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, info);
ANSR_LOGD("uid=%{public}d", info.uid);
return static_cast(info.uid);
}
int32_t ReminderRequest::GetUserId(const int32_t &uid)
{
int32_t userId = -1;
AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId);
ANSR_LOGD("userId=%{public}d", userId);
return userId;
}
void ReminderRequest::AppendValuesBucket(const sptr &reminder,
const sptr &bundleOption, NativeRdb::ValuesBucket &values)
{
values.PutInt(REMINDER_ID, reminder->GetReminderId());
values.PutString(PKG_NAME, bundleOption->GetBundleName());
values.PutInt(USER_ID, reminder->GetUserId());
values.PutInt(UID, reminder->GetUid());
values.PutString(SYS_APP, reminder->IsSystemApp() ? "true" : "false");
values.PutString(APP_LABEL, ""); // no use, compatible with old version.
values.PutInt(REMINDER_TYPE, static_cast(reminder->GetReminderType()));
values.PutLong(REMINDER_TIME, reminder->GetReminderTimeInMilli());
values.PutLong(TRIGGER_TIME, reminder->GetTriggerTimeInMilli());
values.PutLong(
RTC_TRIGGER_TIME, reminder->GetTriggerTimeInMilli()); // no use, compatible with old version.
values.PutLong(TIME_INTERVAL, reminder->GetTimeInterval());
values.PutInt(SNOOZE_TIMES, reminder->GetSnoozeTimes());
values.PutInt(DYNAMIC_SNOOZE_TIMES, reminder->GetSnoozeTimesDynamic());
values.PutLong(RING_DURATION, reminder->GetRingDuration());
values.PutString(IS_EXPIRED, reminder->IsExpired() ? "true" : "false");
values.PutString(IS_ACTIVE, ""); // no use, compatible with old version.
values.PutInt(STATE, reminder->GetState());
values.PutString(ZONE_ID, ""); // no use, compatible with old version.
values.PutString(HAS_SCHEDULED_TIMEOUT, ""); // no use, compatible with old version.
values.PutString(ACTION_BUTTON_INFO, reminder->GetButtonInfo());
values.PutString(CUSTOM_BUTTON_URI, reminder->GetCustomButtonUri());
values.PutInt(SLOT_ID, reminder->GetSlotType());
values.PutInt(NOTIFICATION_ID, reminder->GetNotificationId());
values.PutString(TITLE, reminder->GetTitle());
values.PutString(CONTENT, reminder->GetContent());
values.PutString(SNOOZE_CONTENT, reminder->GetSnoozeContent());
values.PutString(EXPIRED_CONTENT, reminder->GetExpiredContent());
auto wantAgentInfo = reminder->GetWantAgentInfo();
if (wantAgentInfo == nullptr) {
std::string info = "null" + ReminderRequest::SEP_WANT_AGENT + "null";
values.PutString(AGENT, info);
} else {
values.PutString(AGENT, wantAgentInfo->pkgName
+ ReminderRequest::SEP_WANT_AGENT + wantAgentInfo->abilityName);
}
auto maxScreenWantAgentInfo = reminder->GetMaxScreenWantAgentInfo();
if (maxScreenWantAgentInfo == nullptr) {
std::string info = "null" + ReminderRequest::SEP_WANT_AGENT + "null";
values.PutString(MAX_SCREEN_AGENT, info);
} else {
values.PutString(MAX_SCREEN_AGENT, maxScreenWantAgentInfo->pkgName
+ ReminderRequest::SEP_WANT_AGENT + maxScreenWantAgentInfo->abilityName);
}
values.PutString(TAP_DISMISSED, reminder->IsTapDismissed() ? "true" : "false");
values.PutLong(AUTO_DELETED_TIME, reminder->GetAutoDeletedTime());
}
void ReminderRequest::InitDbColumns()
{
AddColumn(REMINDER_ID, "INTEGER PRIMARY KEY", false);
AddColumn(PKG_NAME, "TEXT NOT NULL", false);
AddColumn(USER_ID, "INT NOT NULL", false);
AddColumn(UID, "INT NOT NULL", false);
AddColumn(SYS_APP, "TEXT NOT NULL", false);
AddColumn(APP_LABEL, "TEXT", false);
AddColumn(REMINDER_TYPE, "INT NOT NULL", false);
AddColumn(REMINDER_TIME, "BIGINT NOT NULL", false);
AddColumn(TRIGGER_TIME, "BIGINT NOT NULL", false);
AddColumn(RTC_TRIGGER_TIME, "BIGINT NOT NULL", false);
AddColumn(TIME_INTERVAL, "BIGINT NOT NULL", false);
AddColumn(SNOOZE_TIMES, "INT NOT NULL", false);
AddColumn(DYNAMIC_SNOOZE_TIMES, "INT NOT NULL", false);
AddColumn(RING_DURATION, "BIGINT NOT NULL", false);
AddColumn(IS_EXPIRED, "TEXT NOT NULL", false);
AddColumn(IS_ACTIVE, "TEXT NOT NULL", false);
AddColumn(STATE, "INT NOT NULL", false);
AddColumn(ZONE_ID, "TEXT", false);
AddColumn(HAS_SCHEDULED_TIMEOUT, "TEXT", false);
AddColumn(ACTION_BUTTON_INFO, "TEXT", false);
AddColumn(CUSTOM_BUTTON_URI, "TEXT", false);
AddColumn(SLOT_ID, "INT", false);
AddColumn(NOTIFICATION_ID, "INT NOT NULL", false);
AddColumn(TITLE, "TEXT", false);
AddColumn(CONTENT, "TEXT", false);
AddColumn(SNOOZE_CONTENT, "TEXT", false);
AddColumn(EXPIRED_CONTENT, "TEXT", false);
AddColumn(AGENT, "TEXT", false);
AddColumn(MAX_SCREEN_AGENT, "TEXT", false);
AddColumn(TAP_DISMISSED, "TEXT", false);
AddColumn(AUTO_DELETED_TIME, "BIGINT", false);
}
void ReminderRequest::AddColumn(
const std::string &name, const std::string &type, const bool &isEnd)
{
columns.push_back(name);
if (!isEnd) {
sqlOfAddColumns += name + " " + type + ", ";
} else {
sqlOfAddColumns += name + " " + type;
}
}
}
}