• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "reminder_request.h"
17 #include "reminder_request_factory.h"
18 
19 #include "ans_const_define.h"
20 #include "ans_log_wrapper.h"
21 #include "bundle_mgr_interface.h"
22 #include "bundle_mgr_proxy.h"
23 #include "if_system_ability_manager.h"
24 #include "ipc_skeleton.h"
25 #include "iservice_registry.h"
26 #include "locale_config.h"
27 #include "system_ability_definition.h"
28 #include "want_agent_helper.h"
29 #include "nlohmann/json.hpp"
30 #include "want_params_wrapper.h"
31 
32 namespace OHOS {
33 namespace Notification {
34 namespace {
35 const int32_t BASE_YEAR = 1900;
36 const int32_t SINGLE_BUTTON_INVALID = 0;
37 const int32_t SINGLE_BUTTON_JSONSTRING = 0;
38 const int32_t SINGLE_BUTTON_ONLY_ONE = 1;
39 const int32_t SINGLE_BUTTON_MIN_LEN = 2;
40 const int32_t SINGLE_BUTTON_MAX_LEN = 4;
41 const int32_t BUTTON_TYPE_INDEX = 0;
42 const int32_t BUTTON_TITLE_INDEX = 1;
43 const int32_t BUTTON_PKG_INDEX = 2;
44 const int32_t BUTTON_ABILITY_INDEX = 3;
45 const int32_t WANT_AGENT_URI_INDEX = 2;
46 const int32_t INDENT = -1;
47 
48 const char* const PARAM_EXTRA_KEY = "NotificationRequest_extraInfo";
49 }
50 
51 int32_t ReminderRequest::GLOBAL_ID = 0;
52 const uint64_t ReminderRequest::INVALID_LONG_LONG_VALUE = 0;
53 const uint16_t ReminderRequest::INVALID_U16_VALUE = 0;
54 const uint16_t ReminderRequest::MILLI_SECONDS = 1000;
55 const uint16_t ReminderRequest::SAME_TIME_DISTINGUISH_MILLISECONDS = 1000;
56 const uint32_t ReminderRequest::MIN_TIME_INTERVAL_IN_MILLI = 5 * 60 * 1000;
57 const uint8_t ReminderRequest::INVALID_U8_VALUE = 0;
58 const uint8_t ReminderRequest::REMINDER_STATUS_INACTIVE = 0;
59 const uint8_t ReminderRequest::REMINDER_STATUS_ACTIVE = 1;
60 const uint8_t ReminderRequest::REMINDER_STATUS_ALERTING = 2;
61 const uint8_t ReminderRequest::REMINDER_STATUS_SHOWING = 4;
62 const uint8_t ReminderRequest::REMINDER_STATUS_SNOOZE = 8;
63 const uint8_t ReminderRequest::TIME_HOUR_OFFSET = 12;
64 const std::string ReminderRequest::NOTIFICATION_LABEL = "REMINDER_AGENT";
65 const std::string ReminderRequest::REMINDER_EVENT_ALARM_ALERT = "ohos.event.notification.reminder.ALARM_ALERT";
66 const std::string ReminderRequest::REMINDER_EVENT_CLOSE_ALERT = "ohos.event.notification.reminder.CLOSE_ALERT";
67 const std::string ReminderRequest::REMINDER_EVENT_SNOOZE_ALERT = "ohos.event.notification.reminder.SNOOZE_ALERT";
68 const std::string ReminderRequest::REMINDER_EVENT_CUSTOM_ALERT = "ohos.event.notification.reminder.COSTUM_ALERT";
69 const std::string ReminderRequest::REMINDER_EVENT_CLICK_ALERT = "ohos.event.notification.reminder.CLICK_ALERT";
70 const std::string ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT = "ohos.event.notification.reminder.ALERT_TIMEOUT";
71 const std::string ReminderRequest::REMINDER_EVENT_REMOVE_NOTIFICATION =
72     "ohos.event.notification.reminder.REMOVE_NOTIFICATION";
73 const std::string ReminderRequest::PARAM_REMINDER_ID = "REMINDER_ID";
74 const std::string ReminderRequest::PARAM_REMINDER_SHARE = "REMINDER_SHARE_FLAG";
75 const std::string ReminderRequest::SEP_BUTTON_SINGLE = "<SEP,/>";
76 const std::string ReminderRequest::SEP_BUTTON_MULTI = "<SEP#/>";
77 const std::string ReminderRequest::SEP_WANT_AGENT = "<SEP#/>";
78 const std::string ReminderRequest::SEP_BUTTON_VALUE_TYPE = "<SEP;/>";
79 const std::string ReminderRequest::SEP_BUTTON_VALUE = "<SEP:/>";
80 const std::string ReminderRequest::SEP_BUTTON_VALUE_BLOB = "<SEP-/>";
81 const uint8_t ReminderRequest::DAYS_PER_WEEK = 7;
82 const uint8_t ReminderRequest::MONDAY = 1;
83 const uint8_t ReminderRequest::SUNDAY = 7;
84 const uint8_t ReminderRequest::HOURS_PER_DAY = 24;
85 const uint16_t ReminderRequest::SECONDS_PER_HOUR = 3600;
86 
87 template <typename T>
GetJsonValue(const nlohmann::json & root,const std::string & name,T & value)88 void GetJsonValue(const nlohmann::json& root, const std::string& name, T& value)
89 {
90     value = T();
91     if (!root.contains(name)) {
92         return;
93     }
94     using ValueType = std::remove_cv_t<std::remove_reference_t<T>>;
95     if constexpr (std::is_same_v<std::string, ValueType>) {
96         if (root[name].is_string()) {
97             value = root[name].get<std::string>();
98         }
99     } else if constexpr (std::is_same_v<int32_t, ValueType>) {
100         if (root[name].is_number()) {
101             value = root[name].get<int32_t>();
102         }
103     }
104 }
105 
IsVaildButtonType(const std::string & type)106 inline static bool IsVaildButtonType(const std::string& type)
107 {
108     // check action button type range
109     if (type.size() != 1) {
110         return false;
111     }
112     if (type[0] >= '0' && type[0] <= '3') {
113         return true;
114     }
115     return false;
116 }
117 
ReminderRequest()118 ReminderRequest::ReminderRequest()
119 {
120     InitServerObj();
121 }
122 
ReminderRequest(const ReminderRequest & other)123 ReminderRequest::ReminderRequest(const ReminderRequest &other)
124 {
125     this->content_ = other.content_;
126     this->expiredContent_ = other.expiredContent_;
127     this->snoozeContent_ = other.snoozeContent_;
128     this->displayContent_ = other.displayContent_;
129     this->title_ = other.title_;
130     this->isExpired_ = other.isExpired_;
131     this->isSystemApp_ = other.isSystemApp_;
132     this->snoozeTimes_ = other.snoozeTimes_;
133     this->snoozeTimesDynamic_ = other.snoozeTimesDynamic_;
134     this->state_ = other.state_;
135     this->notificationId_ = other.notificationId_;
136     this->reminderId_ = other.reminderId_;
137     this->reminderTimeInMilli_ = other.reminderTimeInMilli_;
138     this->ringDurationInMilli_ = other.ringDurationInMilli_;
139     this->triggerTimeInMilli_ = other.triggerTimeInMilli_;
140     this->timeIntervalInMilli_ = other.timeIntervalInMilli_;
141     this->reminderType_ = other.reminderType_;
142     this->slotType_ = other.slotType_;
143     this->snoozeSlotType_ = other.snoozeSlotType_;
144     this->wantAgentInfo_ = other.wantAgentInfo_;
145     this->maxScreenWantAgentInfo_ = other.maxScreenWantAgentInfo_;
146     this->actionButtonMap_ = other.actionButtonMap_;
147     this->tapDismissed_= other.tapDismissed_;
148     this->autoDeletedTime_ = other.autoDeletedTime_;
149     this->customButtonUri_ = other.customButtonUri_;
150     this->groupId_ = other.groupId_;
151     this->customRingUri_ = other.customRingUri_;
152     this->creatorBundleName_ = other.creatorBundleName_;
153     this->titleResourceId_ = other.titleResourceId_;
154     this->contentResourceId_ = other.contentResourceId_;
155     this->expiredContentResourceId_ = other.expiredContentResourceId_;
156     this->snoozeContentResourceId_ = other.snoozeContentResourceId_;
157 }
158 
ReminderRequest(int32_t reminderId)159 ReminderRequest::ReminderRequest(int32_t reminderId)
160 {
161     reminderId_ = reminderId;
162     InitServerObj();
163 }
164 
ReminderRequest(ReminderType reminderType)165 ReminderRequest::ReminderRequest(ReminderType reminderType)
166 {
167     reminderType_ = reminderType;
168     InitServerObj();
169 }
170 
CanRemove() const171 bool ReminderRequest::CanRemove() const
172 {
173     if ((state_ & (REMINDER_STATUS_SHOWING | REMINDER_STATUS_ALERTING | REMINDER_STATUS_ACTIVE)) == 0) {
174         return true;
175     }
176     return false;
177 }
178 
CanShow() const179 bool ReminderRequest::CanShow() const
180 {
181     // when system time change by user manually, and the reminde is to show immediately,
182     // the show reminder just need to be triggered by ReminderDataManager#RefreshRemindersLocked(uint8_t).
183     // we need to make the REMINDER_EVENT_ALARM_ALERT do nothing.
184     uint64_t nowInstantMilli = GetNowInstantMilli();
185     if (nowInstantMilli == 0) {
186         return false;
187     }
188     if (nowInstantMilli < (GetReminderTimeInMilli() + MIN_TIME_INTERVAL_IN_MILLI)) {
189         return false;
190     }
191     return true;
192 }
193 
Dump() const194 std::string ReminderRequest::Dump() const
195 {
196     const time_t nextTriggerTime = static_cast<time_t>(triggerTimeInMilli_ / MILLI_SECONDS);
197     std::string dateTimeInfo = GetTimeInfoInner(nextTriggerTime, TimeFormat::YMDHMS, true);
198     return "Reminder["
199            "reminderId=" + std::to_string(reminderId_) +
200            ", type=" + std::to_string(static_cast<uint8_t>(reminderType_)) +
201            ", state=" + GetState(state_) +
202            ", nextTriggerTime=" + dateTimeInfo.c_str() +
203            "]";
204 }
205 
SetActionButton(const std::string & title,const ActionButtonType & type,const std::string & resource,const std::shared_ptr<ButtonWantAgent> & buttonWantAgent,const std::shared_ptr<ButtonDataShareUpdate> & buttonDataShareUpdate)206 ReminderRequest& ReminderRequest::SetActionButton(const std::string &title, const ActionButtonType &type,
207     const std::string &resource, const std::shared_ptr<ButtonWantAgent> &buttonWantAgent,
208     const std::shared_ptr<ButtonDataShareUpdate> &buttonDataShareUpdate)
209 {
210     if ((type != ActionButtonType::CLOSE) && (type != ActionButtonType::SNOOZE) && (type != ActionButtonType::CUSTOM)) {
211         ANSR_LOGI("Button type is not support: %{public}d.", static_cast<uint8_t>(type));
212         return *this;
213     }
214     ActionButtonInfo actionButtonInfo;
215     actionButtonInfo.type = type;
216     actionButtonInfo.title = title;
217     actionButtonInfo.resource = resource;
218     actionButtonInfo.wantAgent = buttonWantAgent;
219     actionButtonInfo.dataShareUpdate = buttonDataShareUpdate;
220 
221     actionButtonMap_.insert(std::pair<ActionButtonType, ActionButtonInfo>(type, actionButtonInfo));
222     return *this;
223 }
224 
SetContent(const std::string & content)225 ReminderRequest& ReminderRequest::SetContent(const std::string &content)
226 {
227     content_ = content;
228     return *this;
229 }
230 
SetExpiredContent(const std::string & expiredContent)231 ReminderRequest& ReminderRequest::SetExpiredContent(const std::string &expiredContent)
232 {
233     expiredContent_ = expiredContent;
234     return *this;
235 }
236 
SetExpired(bool isExpired)237 void ReminderRequest::SetExpired(bool isExpired)
238 {
239     isExpired_ = isExpired;
240 }
241 
InitCreatorBundleName(const std::string & creatorBundleName)242 void ReminderRequest::InitCreatorBundleName(const std::string &creatorBundleName)
243 {
244     creatorBundleName_ = creatorBundleName;
245 }
246 
InitCreatorUid(const int32_t creatorUid)247 void ReminderRequest::InitCreatorUid(const int32_t creatorUid)
248 {
249     creatorUid_ = creatorUid;
250 }
251 
InitReminderId()252 void ReminderRequest::InitReminderId()
253 {
254     std::lock_guard<std::mutex> lock(std::mutex);
255     if (GLOBAL_ID < 0) {
256         ANSR_LOGW("GLOBAL_ID overdule");
257         GLOBAL_ID = 0;
258     }
259     reminderId_ = ++GLOBAL_ID;
260     ANSR_LOGI("reminderId_=%{public}d", reminderId_);
261 }
262 
InitUserId(const int32_t & userId)263 void ReminderRequest::InitUserId(const int32_t &userId)
264 {
265     userId_ = userId;
266 }
267 
InitUid(const int32_t & uid)268 void ReminderRequest::InitUid(const int32_t &uid)
269 {
270     uid_ = uid;
271 }
272 
InitBundleName(const std::string & bundleName)273 void ReminderRequest::InitBundleName(const std::string &bundleName)
274 {
275     bundleName_ = bundleName;
276 }
277 
IsExpired() const278 bool ReminderRequest::IsExpired() const
279 {
280     return isExpired_;
281 }
282 
IsShowing() const283 bool ReminderRequest::IsShowing() const
284 {
285     if ((state_ & REMINDER_STATUS_SHOWING) != 0) {
286         return true;
287     }
288     return false;
289 }
290 
OnClose(bool updateNext)291 void ReminderRequest::OnClose(bool updateNext)
292 {
293     if ((state_ & REMINDER_STATUS_SHOWING) == 0) {
294         ANSR_LOGE("onClose, the state of reminder is incorrect, state:%{public}s", GetState(state_).c_str());
295         return;
296     }
297     SetState(false, REMINDER_STATUS_SHOWING | REMINDER_STATUS_SNOOZE, "onClose()");
298     if ((state_ & REMINDER_STATUS_ALERTING) != 0) {
299         SetState(false, REMINDER_STATUS_ALERTING, "onClose");
300     }
301     if (updateNext) {
302         uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(true, false);
303         if (nextTriggerTime == INVALID_LONG_LONG_VALUE) {
304             isExpired_ = true;
305         } else {
306             SetTriggerTimeInMilli(nextTriggerTime);
307             snoozeTimesDynamic_ = snoozeTimes_;
308         }
309     }
310 }
311 
OnDateTimeChange()312 bool ReminderRequest::OnDateTimeChange()
313 {
314     uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(true, false);
315     return HandleSysTimeChange(triggerTimeInMilli_, nextTriggerTime);
316 }
317 
HandleSysTimeChange(uint64_t oriTriggerTime,uint64_t optTriggerTime)318 bool ReminderRequest::HandleSysTimeChange(uint64_t oriTriggerTime, uint64_t optTriggerTime)
319 {
320     if (isExpired_) {
321         return false;
322     }
323     uint64_t now = GetNowInstantMilli();
324     if (now == 0) {
325         ANSR_LOGE("get now time failed.");
326         return false;
327     }
328     if (oriTriggerTime == 0 && optTriggerTime < now) {
329         ANSR_LOGW("trigger time is less than now time.");
330         return false;
331     }
332     bool showImmediately = false;
333     if (optTriggerTime != INVALID_LONG_LONG_VALUE && (optTriggerTime <= oriTriggerTime || oriTriggerTime == 0)) {
334         // case1. switch to a previous time
335         SetTriggerTimeInMilli(optTriggerTime);
336         snoozeTimesDynamic_ = snoozeTimes_;
337     } else {
338         if (oriTriggerTime <= now) {
339             // case2. switch to a future time, trigger time is less than now time.
340             // when the reminder show immediately, trigger time will update in onShow function.
341             snoozeTimesDynamic_ = 0;
342             showImmediately = true;
343         } else {
344             // case3. switch to a future time, trigger time is larger than now time.
345             showImmediately = false;
346         }
347     }
348     return showImmediately;
349 }
350 
HandleTimeZoneChange(uint64_t oldZoneTriggerTime,uint64_t newZoneTriggerTime,uint64_t optTriggerTime)351 bool ReminderRequest::HandleTimeZoneChange(
352     uint64_t oldZoneTriggerTime, uint64_t newZoneTriggerTime, uint64_t optTriggerTime)
353 {
354     if (isExpired_) {
355         return false;
356     }
357     ANSR_LOGD("Handle timezone change, old:%{public}" PRIu64 ", new:%{public}" PRIu64 "",
358         oldZoneTriggerTime, newZoneTriggerTime);
359     if (oldZoneTriggerTime == newZoneTriggerTime) {
360         return false;
361     }
362     bool showImmediately = false;
363     if (optTriggerTime != INVALID_LONG_LONG_VALUE && oldZoneTriggerTime < newZoneTriggerTime) {
364         // case1. timezone change to smaller
365         SetTriggerTimeInMilli(optTriggerTime);
366         snoozeTimesDynamic_ = snoozeTimes_;
367     } else {
368         // case2. timezone change to larger
369         time_t now;
370         (void)time(&now);  // unit is seconds.
371         if (static_cast<int64_t>(now) < 0) {
372             ANSR_LOGE("Get now time error");
373             return false;
374         }
375         if (newZoneTriggerTime <= GetDurationSinceEpochInMilli(now)) {
376             snoozeTimesDynamic_ = 0;
377             showImmediately = true;
378         } else {
379             SetTriggerTimeInMilli(newZoneTriggerTime);
380             showImmediately = false;
381         }
382     }
383     return showImmediately;
384 }
385 
OnSameNotificationIdCovered()386 void ReminderRequest::OnSameNotificationIdCovered()
387 {
388     ANSR_LOGI("Reminder[%{public}d] same notification id covered.", reminderId_);
389     OnClose(true);
390 }
391 
OnShow(bool isPlaySoundOrVibration,bool isSysTimeChanged,bool allowToNotify)392 void ReminderRequest::OnShow(bool isPlaySoundOrVibration, bool isSysTimeChanged, bool allowToNotify)
393 {
394     if ((state_ & (REMINDER_STATUS_ACTIVE | REMINDER_STATUS_SNOOZE)) != 0) {
395         SetState(false, REMINDER_STATUS_ACTIVE | REMINDER_STATUS_SNOOZE, "onShow()");
396     }
397     if (isSysTimeChanged) {
398         uint64_t nowInstantMilli = GetNowInstantMilli();
399         if (nowInstantMilli == 0) {
400             ANSR_LOGW("Onshow, get now time error");
401         }
402         reminderTimeInMilli_ = nowInstantMilli;
403     } else {
404         reminderTimeInMilli_ = triggerTimeInMilli_;
405     }
406     UpdateNextReminder(false);
407     if (allowToNotify) {
408         SetState(true, REMINDER_STATUS_SHOWING, "OnShow");
409         if (isPlaySoundOrVibration) {
410             SetState(true, REMINDER_STATUS_ALERTING, "OnShow");
411         }
412     }
413 }
414 
OnShowFail()415 void ReminderRequest::OnShowFail()
416 {
417     SetState(false, REMINDER_STATUS_SHOWING, "OnShowFailed()");
418 }
419 
OnSnooze()420 bool ReminderRequest::OnSnooze()
421 {
422     if ((state_ & REMINDER_STATUS_SNOOZE) != 0) {
423         ANSR_LOGW("onSnooze, the state of reminder is incorrect, state: %{public}s", (GetState(state_)).c_str());
424         return false;
425     }
426     if ((state_ & REMINDER_STATUS_ALERTING) != 0) {
427         SetState(false, REMINDER_STATUS_ALERTING, "onSnooze()");
428     }
429     SetSnoozeTimesDynamic(GetSnoozeTimes());
430     if (!UpdateNextReminder(true)) {
431         return false;
432     }
433     if (timeIntervalInMilli_ > 0) {
434         SetState(true, REMINDER_STATUS_SNOOZE, "onSnooze()");
435     }
436     return true;
437 }
438 
OnStart()439 void ReminderRequest::OnStart()
440 {
441     if ((state_ & REMINDER_STATUS_ACTIVE) != 0) {
442         ANSR_LOGE(
443             "start failed, the state of reminder is incorrect, state: %{public}s", (GetState(state_)).c_str());
444         return;
445     }
446     if (isExpired_) {
447         ANSR_LOGE("start failed, the reminder is expired");
448         return;
449     }
450     SetState(true, REMINDER_STATUS_ACTIVE, "OnStart()");
451 }
452 
OnStop()453 void ReminderRequest::OnStop()
454 {
455     ANSR_LOGI("Stop the previous active reminder, %{public}s", this->Dump().c_str());
456     if ((state_ & REMINDER_STATUS_ACTIVE) == 0) {
457         ANSR_LOGW("onStop, the state of reminder is incorrect, state: %{public}s", (GetState(state_)).c_str());
458         return;
459     }
460     SetState(false, REMINDER_STATUS_ACTIVE, "OnStop");
461 }
462 
OnTerminate()463 bool ReminderRequest::OnTerminate()
464 {
465     if ((state_ & REMINDER_STATUS_ALERTING) == 0) {
466         ANSR_LOGW("onTerminate, the state of reminder is %{public}s", (GetState(state_)).c_str());
467         return false;
468     }
469     SetState(false, REMINDER_STATUS_ALERTING, "onTerminate");
470     return true;
471 }
472 
OnTimeZoneChange()473 bool ReminderRequest::OnTimeZoneChange()
474 {
475     time_t oldZoneTriggerTime = static_cast<time_t>(triggerTimeInMilli_ / MILLI_SECONDS);
476     struct tm *localOriTime = localtime(&oldZoneTriggerTime);
477     if (localOriTime == nullptr) {
478         ANSR_LOGE("oldZoneTriggerTime is null");
479         return false;
480     }
481     time_t newZoneTriggerTime = mktime(localOriTime);
482     uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(true, false);
483     return HandleTimeZoneChange(
484         triggerTimeInMilli_, GetDurationSinceEpochInMilli(newZoneTriggerTime), nextTriggerTime);
485 }
486 
RecoverActionButtonJsonMode(const std::string & jsonString)487 void ReminderRequest::RecoverActionButtonJsonMode(const std::string &jsonString)
488 {
489     if (!nlohmann::json::accept(jsonString)) {
490         ANSR_LOGW("not a json string!");
491         return;
492     }
493     nlohmann::json root = nlohmann::json::parse(jsonString, nullptr, false);
494     if (root.is_discarded()) {
495         ANSR_LOGW("parse json data failed!");
496         return;
497     }
498     std::string type;
499     GetJsonValue<std::string>(root, "type", type);
500     if (!IsVaildButtonType(type)) {
501         ANSR_LOGW("unkown button type!");
502         return;
503     }
504     std::string title;
505     GetJsonValue<std::string>(root, "title", title);
506     std::string resource;
507     GetJsonValue<std::string>(root, "resource", resource);
508     auto buttonWantAgent = std::make_shared<ReminderRequest::ButtonWantAgent>();
509     if (root.contains("wantAgent") && !root["wantAgent"].empty()) {
510         nlohmann::json wantAgent = root["wantAgent"];
511         GetJsonValue<std::string>(wantAgent, "pkgName", buttonWantAgent->pkgName);
512         GetJsonValue<std::string>(wantAgent, "abilityName", buttonWantAgent->abilityName);
513     }
514     auto buttonDataShareUpdate = std::make_shared<ReminderRequest::ButtonDataShareUpdate>();
515     if (root.contains("dataShareUpdate") && !root["dataShareUpdate"].empty()) {
516         nlohmann::json dataShareUpdate = root["dataShareUpdate"];
517         GetJsonValue<std::string>(dataShareUpdate, "uri", buttonDataShareUpdate->uri);
518         GetJsonValue<std::string>(dataShareUpdate, "equalTo", buttonDataShareUpdate->equalTo);
519         GetJsonValue<std::string>(dataShareUpdate, "valuesBucket", buttonDataShareUpdate->valuesBucket);
520     }
521     SetActionButton(title, ActionButtonType(std::stoi(type, nullptr)),
522         resource, buttonWantAgent, buttonDataShareUpdate);
523 }
524 
DeserializeButtonInfoFromJson(const std::string & jsonString)525 void ReminderRequest::DeserializeButtonInfoFromJson(const std::string& jsonString)
526 {
527     if (jsonString.empty()) {
528         return;
529     }
530     if (!nlohmann::json::accept(jsonString)) {
531         ANSR_LOGW("Not a json string.");
532         return;
533     }
534     nlohmann::json root = nlohmann::json::parse(jsonString, nullptr, false);
535     if (root.is_discarded()) {
536         ANSR_LOGW("Parse json data failed.");
537         return;
538     }
539     if (!root.is_array()) {
540         return;
541     }
542     for (auto& button : root) {
543         int32_t type = static_cast<int32_t>(ActionButtonType::INVALID);
544         GetJsonValue<int32_t>(button, "type", type);
545         std::string title;
546         GetJsonValue<std::string>(button, "title", title);
547         std::string resource;
548         GetJsonValue<std::string>(button, "titleResource", resource);
549         std::string uri;
550         auto buttonWantAgent = std::make_shared<ReminderRequest::ButtonWantAgent>();
551         if (button.contains("wantAgent") && !button["wantAgent"].empty()) {
552             nlohmann::json wantAgent = button["wantAgent"];
553             GetJsonValue<std::string>(wantAgent, "pkgName", buttonWantAgent->pkgName);
554             GetJsonValue<std::string>(wantAgent, "abilityName", buttonWantAgent->abilityName);
555             GetJsonValue<std::string>(wantAgent, "uri", uri);
556         }
557         auto buttonDataShareUpdate = std::make_shared<ReminderRequest::ButtonDataShareUpdate>();
558         if (button.contains("dataShareUpdate") && !button["dataShareUpdate"].empty()) {
559             nlohmann::json dataShareUpdate = button["dataShareUpdate"];
560             GetJsonValue<std::string>(dataShareUpdate, "uri", buttonDataShareUpdate->uri);
561             GetJsonValue<std::string>(dataShareUpdate, "equalTo", buttonDataShareUpdate->equalTo);
562             GetJsonValue<std::string>(dataShareUpdate, "valuesBucket", buttonDataShareUpdate->valuesBucket);
563         }
564         if (type == static_cast<int32_t>(ActionButtonType::CUSTOM)) {
565             customButtonUri_ = uri;
566         }
567         SetActionButton(title, ActionButtonType(type), resource, buttonWantAgent, buttonDataShareUpdate);
568     }
569 }
570 
DeserializeButtonInfo(const std::string & buttonInfoStr)571 void ReminderRequest::DeserializeButtonInfo(const std::string& buttonInfoStr)
572 {
573     std::vector<std::string> multiButton = StringSplit(buttonInfoStr, SEP_BUTTON_MULTI);
574     for (auto button : multiButton) {
575         std::vector<std::string> singleButton = StringSplit(button, SEP_BUTTON_SINGLE);
576         if (singleButton.size() <= SINGLE_BUTTON_INVALID) {
577             ANSR_LOGW("RecoverButton fail");
578             return;
579         }
580         if (singleButton.size() == SINGLE_BUTTON_ONLY_ONE) {
581             std::string jsonString = singleButton.at(SINGLE_BUTTON_JSONSTRING);
582             RecoverActionButtonJsonMode(jsonString);
583             continue;
584         }
585         // old method Soon to be deleted
586         if (singleButton.size() < SINGLE_BUTTON_MIN_LEN) {
587             ANSR_LOGW("RecoverButton fail");
588             return;
589         }
590         auto buttonWantAgent = std::make_shared<ReminderRequest::ButtonWantAgent>();
591         if (singleButton.size() == SINGLE_BUTTON_MAX_LEN) {
592             buttonWantAgent->pkgName = singleButton.at(BUTTON_PKG_INDEX);
593             buttonWantAgent->abilityName = singleButton.at(BUTTON_ABILITY_INDEX);
594         }
595         std::string resource = "";
596         auto buttonDataShareUpdate = std::make_shared<ReminderRequest::ButtonDataShareUpdate>();
597         SetActionButton(singleButton.at(BUTTON_TITLE_INDEX),
598             ActionButtonType(std::atoi(singleButton.at(BUTTON_TYPE_INDEX).c_str())),
599             resource, buttonWantAgent, buttonDataShareUpdate);
600         ANSR_LOGI("RecoverButton title:%{public}s, pkgName:%{public}s, abilityName:%{public}s",
601             singleButton.at(BUTTON_TITLE_INDEX).c_str(), buttonWantAgent->pkgName.c_str(),
602             buttonWantAgent->abilityName.c_str());
603     }
604 }
605 
StringSplit(std::string source,const std::string & split)606 std::vector<std::string> ReminderRequest::StringSplit(std::string source, const std::string &split)
607 {
608     std::vector<std::string> result;
609     if (source.empty()) {
610         return result;
611     }
612     size_t pos = 0;
613     while ((pos = source.find(split)) != std::string::npos) {
614         std::string token = source.substr(0, pos);
615         if (!token.empty()) {
616             result.push_back(token);
617         }
618         source.erase(0, pos + split.length());
619     }
620     if (!source.empty()) {
621         result.push_back(source);
622     }
623     return result;
624 }
625 
StringToDouble(const std::string & str)626 double ReminderRequest::StringToDouble(const std::string& str)
627 {
628     char* pEnd = nullptr;
629     errno = 0;
630     double res = std::strtod(str.c_str(), &pEnd);
631     if (errno == ERANGE || pEnd == str.c_str() || *pEnd != '\0' ||
632         (res < std::numeric_limits<double>::min()) ||
633         res > std::numeric_limits<double>::max()) {
634         return 0.0;
635     }
636     return res;
637 }
638 
StringToInt(const std::string & str)639 int32_t ReminderRequest::StringToInt(const std::string& str)
640 {
641     char* pEnd = nullptr;
642     errno = 0;
643     int64_t res = std::strtol(str.c_str(), &pEnd, 10);
644     if (errno == ERANGE || pEnd == str.c_str() || *pEnd != '\0' ||
645         (res < std::numeric_limits<int32_t>::min()) ||
646         res > std::numeric_limits<int32_t>::max()) {
647         return 0;
648     }
649     return static_cast<int32_t>(res);
650 }
651 
RecoverWantAgentByJson(const std::string & wantAgentInfo,const uint8_t & type)652 void ReminderRequest::RecoverWantAgentByJson(const std::string& wantAgentInfo, const uint8_t& type)
653 {
654     nlohmann::json root = nlohmann::json::parse(wantAgentInfo, nullptr, false);
655     if (root.is_discarded()) {
656         ANSR_LOGW("parse json data failed");
657         return;
658     }
659     switch (type) {
660         case WANT_AGENT_FLAG: {
661             auto wai = std::make_shared<ReminderRequest::WantAgentInfo>();
662             GetJsonValue<std::string>(root, "pkgName", wai->pkgName);
663             GetJsonValue<std::string>(root, "abilityName", wai->abilityName);
664             GetJsonValue<std::string>(root, "uri", wai->uri);
665             std::string parameters;
666             GetJsonValue<std::string>(root, "parameters", parameters);
667             wai->parameters = AAFwk::WantParamWrapper::ParseWantParams(parameters);
668             SetWantAgentInfo(wai);
669             break;
670         }
671         case MAX_WANT_AGENT_FLAG: {
672             auto maxScreenWantAgentInfo = std::make_shared<ReminderRequest::MaxScreenAgentInfo>();
673             GetJsonValue<std::string>(root, "pkgName", maxScreenWantAgentInfo->pkgName);
674             GetJsonValue<std::string>(root, "abilityName", maxScreenWantAgentInfo->abilityName);
675             SetMaxScreenWantAgentInfo(maxScreenWantAgentInfo);
676             break;
677         }
678         default: {
679             ANSR_LOGW("RecoverWantAgent type not support");
680             break;
681         }
682     }
683 }
684 
DeserializeWantAgent(const std::string & wantAgentInfo,const uint8_t type)685 void ReminderRequest::DeserializeWantAgent(const std::string &wantAgentInfo, const uint8_t type)
686 {
687     if (nlohmann::json::accept(wantAgentInfo)) {
688         RecoverWantAgentByJson(wantAgentInfo, type);
689         return;
690     }
691     std::vector<std::string> info = StringSplit(wantAgentInfo, ReminderRequest::SEP_WANT_AGENT);
692     uint8_t minLen = 2;
693     if (info.size() < minLen) {
694         ANSR_LOGW("RecoverWantAgent fail");
695         return;
696     }
697     ANSR_LOGD("pkg=%{public}s, ability=%{public}s", info.at(0).c_str(), info.at(1).c_str());
698     switch (type) {
699         case 0: {
700             auto wai = std::make_shared<ReminderRequest::WantAgentInfo>();
701             wai->pkgName = info.at(0);
702             wai->abilityName = info.at(1);
703             if (info.size() > minLen) {
704                 wai->uri = info.at(WANT_AGENT_URI_INDEX);
705             }
706             SetWantAgentInfo(wai);
707             break;
708         }
709         case 1: {
710             auto maxScreenWantAgentInfo = std::make_shared<ReminderRequest::MaxScreenAgentInfo>();
711             maxScreenWantAgentInfo->pkgName = info.at(0);
712             maxScreenWantAgentInfo->abilityName = info.at(1);
713             SetMaxScreenWantAgentInfo(maxScreenWantAgentInfo);
714             break;
715         }
716         default: {
717             ANSR_LOGW("RecoverWantAgent type not support");
718             break;
719         }
720     }
721 }
722 
SetMaxScreenWantAgentInfo(const std::shared_ptr<MaxScreenAgentInfo> & maxScreenWantAgentInfo)723 ReminderRequest& ReminderRequest::SetMaxScreenWantAgentInfo(
724     const std::shared_ptr<MaxScreenAgentInfo> &maxScreenWantAgentInfo)
725 {
726     maxScreenWantAgentInfo_ = maxScreenWantAgentInfo;
727     return *this;
728 }
729 
SetNotificationId(int32_t notificationId)730 ReminderRequest& ReminderRequest::SetNotificationId(int32_t notificationId)
731 {
732     notificationId_ = notificationId;
733     return *this;
734 }
735 
SetGroupId(const std::string & groupId)736 ReminderRequest& ReminderRequest::SetGroupId(const std::string &groupId)
737 {
738     groupId_ = groupId;
739     return *this;
740 }
741 
SetSlotType(const NotificationConstant::SlotType & slotType)742 ReminderRequest& ReminderRequest::SetSlotType(const NotificationConstant::SlotType &slotType)
743 {
744     slotType_ = slotType;
745     return *this;
746 }
747 
SetSnoozeSlotType(const NotificationConstant::SlotType & snoozeSlotType)748 ReminderRequest& ReminderRequest::SetSnoozeSlotType(const NotificationConstant::SlotType &snoozeSlotType)
749 {
750     snoozeSlotType_ = snoozeSlotType;
751     return *this;
752 }
753 
SetSnoozeContent(const std::string & snoozeContent)754 ReminderRequest& ReminderRequest::SetSnoozeContent(const std::string &snoozeContent)
755 {
756     snoozeContent_ = snoozeContent;
757     return *this;
758 }
759 
SetSnoozeTimes(const uint8_t snoozeTimes)760 ReminderRequest& ReminderRequest::SetSnoozeTimes(const uint8_t snoozeTimes)
761 {
762     snoozeTimes_ = snoozeTimes;
763     SetSnoozeTimesDynamic(snoozeTimes);
764     return *this;
765 }
766 
SetSnoozeTimesDynamic(const uint8_t snooziTimes)767 ReminderRequest& ReminderRequest::SetSnoozeTimesDynamic(const uint8_t snooziTimes)
768 {
769     snoozeTimesDynamic_ = snooziTimes;
770     return *this;
771 }
772 
SetTimeInterval(const uint64_t timeIntervalInSeconds)773 ReminderRequest& ReminderRequest::SetTimeInterval(const uint64_t timeIntervalInSeconds)
774 {
775     if (timeIntervalInSeconds > (UINT64_MAX / MILLI_SECONDS)) {
776         ANSR_LOGW("SetTimeInterval, replace to set (0s), for the given is out of legal range");
777         timeIntervalInMilli_ = 0;
778     } else {
779         uint64_t timeIntervalInMilli = timeIntervalInSeconds * MILLI_SECONDS;
780         if (timeIntervalInMilli > 0 && timeIntervalInMilli < MIN_TIME_INTERVAL_IN_MILLI) {
781             ANSR_LOGW("SetTimeInterval, replace to set %{public}u, for the given is 0<%{public}" PRIu64 "<%{public}u",
782                 MIN_TIME_INTERVAL_IN_MILLI / MILLI_SECONDS, timeIntervalInSeconds,
783                 MIN_TIME_INTERVAL_IN_MILLI / MILLI_SECONDS);
784             timeIntervalInMilli_ = MIN_TIME_INTERVAL_IN_MILLI;
785         } else {
786             timeIntervalInMilli_ = timeIntervalInMilli;
787         }
788     }
789     return *this;
790 }
791 
SetTitle(const std::string & title)792 ReminderRequest& ReminderRequest::SetTitle(const std::string &title)
793 {
794     title_ = title;
795     return *this;
796 }
797 
SetTriggerTimeInMilli(uint64_t triggerTimeInMilli)798 void ReminderRequest::SetTriggerTimeInMilli(uint64_t triggerTimeInMilli)
799 {
800     triggerTimeInMilli_ = triggerTimeInMilli;
801 }
802 
SetWantAgentInfo(const std::shared_ptr<WantAgentInfo> & wantAgentInfo)803 ReminderRequest& ReminderRequest::SetWantAgentInfo(const std::shared_ptr<WantAgentInfo> &wantAgentInfo)
804 {
805     if (wantAgentInfo != nullptr) {
806         wantAgentInfo_ = wantAgentInfo;
807     }
808     return *this;
809 }
810 
ShouldShowImmediately() const811 bool ReminderRequest::ShouldShowImmediately() const
812 {
813     uint64_t nowInstantMilli = GetNowInstantMilli();
814     if (nowInstantMilli == 0) {
815         return false;
816     }
817     if (triggerTimeInMilli_ > nowInstantMilli) {
818         return false;
819     }
820     return true;
821 }
822 
GetActionButtons() const823 std::map<ReminderRequest::ActionButtonType, ReminderRequest::ActionButtonInfo> ReminderRequest::GetActionButtons(
824     ) const
825 {
826     return actionButtonMap_;
827 }
828 
SetActionButtons(const std::map<ActionButtonType,ActionButtonInfo> & buttons)829 void ReminderRequest::SetActionButtons(const std::map<ActionButtonType, ActionButtonInfo>& buttons)
830 {
831     actionButtonMap_ = buttons;
832 }
833 
GetCreatorBundleName() const834 std::string ReminderRequest::GetCreatorBundleName() const
835 {
836     return creatorBundleName_;
837 }
838 
GetCreatorUid() const839 int32_t ReminderRequest::GetCreatorUid() const
840 {
841     return creatorUid_;
842 }
843 
GetContent() const844 std::string ReminderRequest::GetContent() const
845 {
846     return content_;
847 }
848 
GetExpiredContent() const849 std::string ReminderRequest::GetExpiredContent() const
850 {
851     return expiredContent_;
852 }
853 
GetMaxScreenWantAgentInfo() const854 std::shared_ptr<ReminderRequest::MaxScreenAgentInfo> ReminderRequest::GetMaxScreenWantAgentInfo() const
855 {
856     return maxScreenWantAgentInfo_;
857 }
858 
GetNotificationId() const859 int32_t ReminderRequest::GetNotificationId() const
860 {
861     return notificationId_;
862 }
863 
GetGroupId() const864 std::string ReminderRequest::GetGroupId() const
865 {
866     return groupId_;
867 }
868 
GetReminderId() const869 int32_t ReminderRequest::GetReminderId() const
870 {
871     return reminderId_;
872 }
873 
GetReminderTimeInMilli() const874 uint64_t ReminderRequest::GetReminderTimeInMilli() const
875 {
876     return reminderTimeInMilli_;
877 }
878 
SetReminderId(int32_t reminderId)879 void ReminderRequest::SetReminderId(int32_t reminderId)
880 {
881     reminderId_ = reminderId;
882 }
883 
SetReminderTimeInMilli(const uint64_t reminderTimeInMilli)884 void ReminderRequest::SetReminderTimeInMilli(const uint64_t reminderTimeInMilli)
885 {
886     reminderTimeInMilli_ = reminderTimeInMilli;
887 }
888 
SetRingDuration(const uint64_t ringDurationInSeconds)889 ReminderRequest& ReminderRequest::SetRingDuration(const uint64_t ringDurationInSeconds)
890 {
891     uint64_t ringDuration = ringDurationInSeconds * MILLI_SECONDS;
892     ringDurationInMilli_ = std::min(ringDuration, MAX_RING_DURATION);
893     return *this;
894 }
895 
GetSlotType() const896 NotificationConstant::SlotType ReminderRequest::GetSlotType() const
897 {
898     return slotType_;
899 }
900 
GetSnoozeSlotType() const901 NotificationConstant::SlotType ReminderRequest::GetSnoozeSlotType() const
902 {
903     return snoozeSlotType_;
904 }
905 
GetSnoozeContent() const906 std::string ReminderRequest::GetSnoozeContent() const
907 {
908     return snoozeContent_;
909 }
910 
GetSnoozeTimes() const911 uint8_t ReminderRequest::GetSnoozeTimes() const
912 {
913     return snoozeTimes_;
914 }
915 
GetSnoozeTimesDynamic() const916 uint8_t ReminderRequest::GetSnoozeTimesDynamic() const
917 {
918     return snoozeTimesDynamic_;
919 }
920 
GetState() const921 uint8_t ReminderRequest::GetState() const
922 {
923     return state_;
924 }
925 
GetTimeInterval() const926 uint64_t ReminderRequest::GetTimeInterval() const
927 {
928     return timeIntervalInMilli_ / MILLI_SECONDS;
929 }
930 
GetTitle() const931 std::string ReminderRequest::GetTitle() const
932 {
933     return title_;
934 }
935 
GetTriggerTimeInMilli() const936 uint64_t ReminderRequest::GetTriggerTimeInMilli() const
937 {
938     return triggerTimeInMilli_;
939 }
940 
GetUserId() const941 int32_t ReminderRequest::GetUserId() const
942 {
943     return userId_;
944 }
945 
GetUid() const946 int32_t ReminderRequest::GetUid() const
947 {
948     return uid_;
949 }
950 
GetBundleName() const951 std::string ReminderRequest::GetBundleName() const
952 {
953     return bundleName_;
954 }
955 
SetReminderType(const ReminderType type)956 void ReminderRequest::SetReminderType(const ReminderType type)
957 {
958     reminderType_ = type;
959 }
960 
SetState(const uint8_t state)961 void ReminderRequest::SetState(const uint8_t state)
962 {
963     state_ = state;
964 }
965 
SetRepeatDaysOfWeek(const uint8_t repeatDaysOfWeek)966 void ReminderRequest::SetRepeatDaysOfWeek(const uint8_t repeatDaysOfWeek)
967 {
968     repeatDaysOfWeek_ = repeatDaysOfWeek;
969 }
970 
SetSystemApp(bool isSystem)971 void ReminderRequest::SetSystemApp(bool isSystem)
972 {
973     isSystemApp_ = isSystem;
974 }
975 
IsSystemApp() const976 bool ReminderRequest::IsSystemApp() const
977 {
978     return isSystemApp_;
979 }
980 
SetTapDismissed(bool tapDismissed)981 void ReminderRequest::SetTapDismissed(bool tapDismissed)
982 {
983     tapDismissed_ = tapDismissed;
984 }
985 
IsTapDismissed() const986 bool ReminderRequest::IsTapDismissed() const
987 {
988     return tapDismissed_;
989 }
990 
SetAutoDeletedTime(int64_t autoDeletedTime)991 void ReminderRequest::SetAutoDeletedTime(int64_t autoDeletedTime)
992 {
993     autoDeletedTime_ = autoDeletedTime;
994 }
995 
GetAutoDeletedTime() const996 int64_t ReminderRequest::GetAutoDeletedTime() const
997 {
998     return autoDeletedTime_;
999 }
1000 
SetCustomButtonUri(const std::string & uri)1001 void ReminderRequest::SetCustomButtonUri(const std::string &uri)
1002 {
1003     customButtonUri_ = uri;
1004 }
1005 
GetCustomButtonUri() const1006 std::string ReminderRequest::GetCustomButtonUri() const
1007 {
1008     return customButtonUri_;
1009 }
1010 
IsShare() const1011 bool ReminderRequest::IsShare() const
1012 {
1013     return isShare_;
1014 }
1015 
SetShare(const bool isShare)1016 void ReminderRequest::SetShare(const bool isShare)
1017 {
1018     isShare_ = isShare;
1019 }
1020 
SetCustomRingUri(const std::string & uri)1021 void ReminderRequest::SetCustomRingUri(const std::string &uri)
1022 {
1023     customRingUri_ = uri;
1024 }
1025 
GetCustomRingUri() const1026 std::string ReminderRequest::GetCustomRingUri() const
1027 {
1028     return customRingUri_;
1029 }
1030 
GetWantAgentInfo() const1031 std::shared_ptr<ReminderRequest::WantAgentInfo> ReminderRequest::GetWantAgentInfo() const
1032 {
1033     return wantAgentInfo_;
1034 }
1035 
GetReminderType() const1036 ReminderRequest::ReminderType ReminderRequest::GetReminderType() const
1037 {
1038     return reminderType_;
1039 }
1040 
GetRingDuration() const1041 uint16_t ReminderRequest::GetRingDuration() const
1042 {
1043     return ringDurationInMilli_ / MILLI_SECONDS;
1044 }
1045 
UpdateNextReminder()1046 bool ReminderRequest::UpdateNextReminder()
1047 {
1048     return false;
1049 }
1050 
SetNextTriggerTime()1051 bool ReminderRequest::SetNextTriggerTime()
1052 {
1053     return false;
1054 }
1055 
SetWantAgentStr(const std::string & wantStr)1056 void ReminderRequest::SetWantAgentStr(const std::string& wantStr)
1057 {
1058     wantAgentStr_ = wantStr;
1059 }
1060 
GetWantAgentStr()1061 std::string ReminderRequest::GetWantAgentStr()
1062 {
1063     return wantAgentStr_;
1064 }
1065 
SetMaxWantAgentStr(const std::string & maxWantStr)1066 void ReminderRequest::SetMaxWantAgentStr(const std::string& maxWantStr)
1067 {
1068     maxWantAgentStr_ = maxWantStr;
1069 }
1070 
GetMaxWantAgentStr()1071 std::string ReminderRequest::GetMaxWantAgentStr()
1072 {
1073     return maxWantAgentStr_;
1074 }
1075 
UpdateNotificationRequest(NotificationRequest & notificationRequest,const bool isSnooze)1076 void ReminderRequest::UpdateNotificationRequest(NotificationRequest& notificationRequest, const bool isSnooze)
1077 {
1078     if (isSnooze) {
1079         UpdateNotificationStateForSnooze(notificationRequest);
1080         UpdateNotificationCommon(notificationRequest, true);
1081     } else {
1082         UpdateNotificationStateForAlert(notificationRequest);
1083     }
1084     UpdateNotificationCommon(notificationRequest, isSnooze);
1085     UpdateNotificationAddRemovalWantAgent(notificationRequest);
1086     UpdateNotificationWantAgent(notificationRequest);
1087     UpdateNotificationMaxScreenWantAgent(notificationRequest);
1088     UpdateNotificationBundleInfo(notificationRequest);
1089 }
1090 
UpdateNotificationWantAgent(NotificationRequest & notificationRequest)1091 void ReminderRequest::UpdateNotificationWantAgent(NotificationRequest& notificationRequest)
1092 {
1093     ANSR_LOGI("UpdateNotification want_agent");
1094     AppExecFwk::ElementName element("", wantAgentInfo_->pkgName, wantAgentInfo_->abilityName);
1095     std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> wantAgent = CreateWantAgent(element);
1096     notificationRequest.SetWantAgent(wantAgent);
1097     if (wantAgentInfo_->parameters.HasParam(PARAM_EXTRA_KEY)) {
1098         std::shared_ptr<AAFwk::WantParams> extras = std::make_shared<AAFwk::WantParams>(
1099             wantAgentInfo_->parameters.GetWantParams(PARAM_EXTRA_KEY));
1100         notificationRequest.SetAdditionalData(extras);
1101     }
1102 }
1103 
UpdateNotificationMaxScreenWantAgent(NotificationRequest & notificationRequest)1104 void ReminderRequest::UpdateNotificationMaxScreenWantAgent(NotificationRequest& notificationRequest)
1105 {
1106     AppExecFwk::ElementName element(
1107         "", maxScreenWantAgentInfo_->pkgName, maxScreenWantAgentInfo_->abilityName);
1108         std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> wantAgent = CreateMaxWantAgent(element);
1109     notificationRequest.SetMaxScreenWantAgent(wantAgent);
1110 }
1111 
MarshallingActionButton(Parcel & parcel) const1112 bool ReminderRequest::MarshallingActionButton(Parcel& parcel) const
1113 {
1114     // write map
1115     uint64_t actionButtonMapSize = static_cast<uint64_t>(actionButtonMap_.size());
1116     WRITE_UINT64_RETURN_FALSE_LOG(parcel, actionButtonMapSize, "actionButtonMapSize");
1117     for (auto button : actionButtonMap_) {
1118         uint8_t buttonType = static_cast<uint8_t>(button.first);
1119         WRITE_UINT8_RETURN_FALSE_LOG(parcel, buttonType, "buttonType");
1120         WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.title, "buttonTitle");
1121         WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.resource, "buttonResource");
1122 
1123         if (button.second.wantAgent == nullptr) {
1124             ANSR_LOGE("button wantAgent is null");
1125             return false;
1126         }
1127 
1128         WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.wantAgent->pkgName, "wantAgent's pkgName");
1129         WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.wantAgent->abilityName, "wantAgent's abilityName");
1130 
1131         if (button.second.dataShareUpdate == nullptr) {
1132             ANSR_LOGE("button dataShareUpdate is null");
1133             return false;
1134         }
1135         WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.dataShareUpdate->uri,
1136             "dataShareUpdate's uri");
1137         WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.dataShareUpdate->equalTo,
1138             "dataShareUpdate's equalTo");
1139         WRITE_STRING_RETURN_FALSE_LOG(parcel, button.second.dataShareUpdate->valuesBucket,
1140             "dataShareUpdate's valuesBucket");
1141     }
1142     return true;
1143 }
1144 
MarshallingWantParameters(Parcel & parcel,const AAFwk::WantParams & params) const1145 bool ReminderRequest::MarshallingWantParameters(Parcel& parcel, const AAFwk::WantParams& params) const
1146 {
1147     if (params.Size() == 0) {
1148         if (!parcel.WriteInt32(VALUE_NULL)) {
1149             return false;
1150         }
1151     } else {
1152         if (!parcel.WriteInt32(VALUE_OBJECT)) {
1153             return false;
1154         }
1155         if (!parcel.WriteParcelable(&params)) {
1156             return false;
1157         }
1158     }
1159     return true;
1160 }
1161 
Marshalling(Parcel & parcel) const1162 bool ReminderRequest::Marshalling(Parcel &parcel) const
1163 {
1164     auto reminderRequest = ReminderRequestFactory::CreateReminderRequest(reminderType_);
1165     if (reminderRequest == nullptr) {
1166         ANSR_LOGE("Failed to create reminder due to no memory.");
1167         return false;
1168     }
1169     return reminderRequest->WriteParcel(parcel);
1170 }
1171 
WriteParcel(Parcel & parcel) const1172 bool ReminderRequest::WriteParcel(Parcel &parcel) const
1173 {
1174     // write enum
1175     uint8_t reminderType = static_cast<uint8_t>(reminderType_);
1176     WRITE_UINT8_RETURN_FALSE_LOG(parcel, reminderType, "reminderType");
1177     // write string
1178     WRITE_STRING_RETURN_FALSE_LOG(parcel, content_, "content");
1179     WRITE_STRING_RETURN_FALSE_LOG(parcel, expiredContent_, "expiredContent");
1180     WRITE_STRING_RETURN_FALSE_LOG(parcel, snoozeContent_, "snoozeContent");
1181     WRITE_STRING_RETURN_FALSE_LOG(parcel, title_, "title");
1182     WRITE_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->abilityName, "wantAgentInfo's abilityName");
1183     WRITE_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->pkgName, "wantAgentInfo's pkgName");
1184     WRITE_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->uri, "wantAgentInfo's uri");
1185     if (!MarshallingWantParameters(parcel, wantAgentInfo_->parameters)) {
1186         ANSR_LOGE("Failed to write wantAgentInfo's parameters");
1187         return false;
1188     }
1189     WRITE_STRING_RETURN_FALSE_LOG(parcel, maxScreenWantAgentInfo_->abilityName, "maxScreenWantAgentInfo's abilityName");
1190     WRITE_STRING_RETURN_FALSE_LOG(parcel, maxScreenWantAgentInfo_->pkgName, "maxScreenWantAgentInfo's pkgName");
1191     WRITE_STRING_RETURN_FALSE_LOG(parcel, customButtonUri_, "customButtonUri");
1192     WRITE_STRING_RETURN_FALSE_LOG(parcel, groupId_, "groupId");
1193     WRITE_STRING_RETURN_FALSE_LOG(parcel, customRingUri_, "customRingUri");
1194     WRITE_STRING_RETURN_FALSE_LOG(parcel, creatorBundleName_, "creatorBundleName");
1195 
1196     // write bool
1197     WRITE_BOOL_RETURN_FALSE_LOG(parcel, isExpired_, "isExpired");
1198     WRITE_BOOL_RETURN_FALSE_LOG(parcel, tapDismissed_, "tapDismissed");
1199 
1200     // write int
1201     WRITE_INT64_RETURN_FALSE_LOG(parcel, autoDeletedTime_, "autoDeletedTime");
1202     WRITE_INT32_RETURN_FALSE_LOG(parcel, reminderId_, "reminderId");
1203     WRITE_INT32_RETURN_FALSE_LOG(parcel, notificationId_, "notificationId");
1204 
1205     WRITE_UINT64_RETURN_FALSE_LOG(parcel, triggerTimeInMilli_, "triggerTimeInMilli");
1206     WRITE_UINT64_RETURN_FALSE_LOG(parcel, timeIntervalInMilli_, "timeIntervalInMilli");
1207     WRITE_UINT64_RETURN_FALSE_LOG(parcel, ringDurationInMilli_, "ringDurationInMilli");
1208     WRITE_UINT64_RETURN_FALSE_LOG(parcel, reminderTimeInMilli_, "reminderTimeInMilli");
1209     WRITE_UINT8_RETURN_FALSE_LOG(parcel, snoozeTimes_, "snoozeTimes");
1210     WRITE_UINT8_RETURN_FALSE_LOG(parcel, snoozeTimesDynamic_, "snoozeTimesDynamic");
1211     WRITE_UINT8_RETURN_FALSE_LOG(parcel, state_, "state");
1212 
1213     int32_t slotType = static_cast<int32_t>(slotType_);
1214     WRITE_INT32_RETURN_FALSE_LOG(parcel, slotType, "slotType");
1215 
1216     int32_t snoozeSlotType = static_cast<int32_t>(snoozeSlotType_);
1217     WRITE_INT32_RETURN_FALSE_LOG(parcel, snoozeSlotType, "snoozeSlotType");
1218     WRITE_INT32_RETURN_FALSE_LOG(parcel, titleResourceId_, "titleResourceId");
1219     WRITE_INT32_RETURN_FALSE_LOG(parcel, contentResourceId_, "contentResourceId");
1220     WRITE_INT32_RETURN_FALSE_LOG(parcel, expiredContentResourceId_, "expiredContentResourceId");
1221     WRITE_INT32_RETURN_FALSE_LOG(parcel, snoozeContentResourceId_, "snoozeContentResourceId");
1222 
1223     if (!MarshallingActionButton(parcel)) {
1224         return false;
1225     }
1226     return true;
1227 }
1228 
ReadReminderTypeFormParcel(Parcel & parcel,ReminderType & tarReminderType)1229 bool ReminderRequest::ReadReminderTypeFormParcel(Parcel &parcel, ReminderType& tarReminderType)
1230 {
1231     uint8_t reminderType = static_cast<uint8_t>(ReminderType::INVALID);
1232     READ_UINT8_RETURN_FALSE_LOG(parcel, reminderType, "reminderType");
1233     tarReminderType = static_cast<ReminderType>(reminderType);
1234     return true;
1235 }
1236 
Unmarshalling(Parcel & parcel)1237 ReminderRequest *ReminderRequest::Unmarshalling(Parcel &parcel)
1238 {
1239     ReminderType tarReminderType = ReminderType::INVALID;
1240     ReadReminderTypeFormParcel(parcel, tarReminderType);
1241     auto reminderRequest = ReminderRequestFactory::CreateReminderRequest(tarReminderType);
1242     if (reminderRequest == nullptr) {
1243         ANSR_LOGE("Failed to create reminder due to no memory.");
1244         return reminderRequest;
1245     }
1246     if (!reminderRequest->ReadFromParcel(parcel)) {
1247         delete reminderRequest;
1248         reminderRequest = nullptr;
1249     }
1250     return reminderRequest;
1251 }
1252 
ReadActionButtonFromParcel(Parcel & parcel)1253 bool ReminderRequest::ReadActionButtonFromParcel(Parcel& parcel)
1254 {
1255     uint64_t buttonMapSize = 0;
1256     READ_UINT64_RETURN_FALSE_LOG(parcel, buttonMapSize, "actionButtonMapSize");
1257     buttonMapSize = (buttonMapSize < MAX_ACTION_BUTTON_NUM) ? buttonMapSize : MAX_ACTION_BUTTON_NUM;
1258     for (uint64_t i = 0; i < buttonMapSize; i++) {
1259         uint8_t buttonType = static_cast<uint8_t>(ActionButtonType::INVALID);
1260         READ_UINT8_RETURN_FALSE_LOG(parcel, buttonType, "buttonType");
1261         ActionButtonType type = static_cast<ActionButtonType>(buttonType);
1262         std::string title = parcel.ReadString();
1263         std::string resource = parcel.ReadString();
1264         std::string pkgName = parcel.ReadString();
1265         std::string abilityName = parcel.ReadString();
1266         std::string uri = parcel.ReadString();
1267         std::string equalTo = parcel.ReadString();
1268         std::string valuesBucket = parcel.ReadString();
1269         ActionButtonInfo info;
1270         info.type = type;
1271         info.title = title;
1272         info.resource = resource;
1273         info.wantAgent = std::make_shared<ButtonWantAgent>();
1274         if (info.wantAgent == nullptr) {
1275             return false;
1276         }
1277         info.wantAgent->pkgName = pkgName;
1278         info.wantAgent->abilityName = abilityName;
1279         info.dataShareUpdate = std::make_shared<ButtonDataShareUpdate>();
1280         if (info.dataShareUpdate == nullptr) {
1281             return false;
1282         }
1283         info.dataShareUpdate->uri = uri;
1284         info.dataShareUpdate->equalTo = equalTo;
1285         info.dataShareUpdate->valuesBucket = valuesBucket;
1286         actionButtonMap_.insert(std::pair<ActionButtonType, ActionButtonInfo>(type, info));
1287     }
1288     return true;
1289 }
1290 
ReadWantParametersFromParcel(Parcel & parcel,AAFwk::WantParams & wantParams)1291 bool ReminderRequest::ReadWantParametersFromParcel(Parcel& parcel, AAFwk::WantParams& wantParams)
1292 {
1293     int empty = VALUE_NULL;
1294     if (!parcel.ReadInt32(empty)) {
1295         return false;
1296     }
1297     if (empty == VALUE_OBJECT) {
1298         auto params = parcel.ReadParcelable<AAFwk::WantParams>();
1299         if (params != nullptr) {
1300             wantParams = *params;
1301             delete params;
1302             params = nullptr;
1303         } else {
1304             return false;
1305         }
1306     }
1307     return true;
1308 }
1309 
ReadFromParcel(Parcel & parcel)1310 bool ReminderRequest::ReadFromParcel(Parcel &parcel)
1311 {
1312     READ_STRING_RETURN_FALSE_LOG(parcel, content_, "content");
1313     READ_STRING_RETURN_FALSE_LOG(parcel, expiredContent_, "expiredContent");
1314     READ_STRING_RETURN_FALSE_LOG(parcel, snoozeContent_, "snoozeContent");
1315     READ_STRING_RETURN_FALSE_LOG(parcel, title_, "title");
1316     READ_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->abilityName, "wantAgentInfo's abilityName");
1317     READ_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->pkgName, "wantAgentInfo's pkgName");
1318     READ_STRING_RETURN_FALSE_LOG(parcel, wantAgentInfo_->uri, "wantAgentInfo's uri");
1319     if (!ReadWantParametersFromParcel(parcel, wantAgentInfo_->parameters)) {
1320         ANSR_LOGE("Failed to write wantAgentInfo's parameters");
1321         return false;
1322     }
1323     READ_STRING_RETURN_FALSE_LOG(parcel, maxScreenWantAgentInfo_->abilityName, "maxScreenWantAgentInfo's abilityName");
1324     READ_STRING_RETURN_FALSE_LOG(parcel, maxScreenWantAgentInfo_->pkgName, "maxScreenWantAgentInfo's pkgName");
1325     READ_STRING_RETURN_FALSE_LOG(parcel, customButtonUri_, "customButtonUri");
1326     READ_STRING_RETURN_FALSE_LOG(parcel, groupId_, "groupId");
1327     READ_STRING_RETURN_FALSE_LOG(parcel, customRingUri_, "customRingUri");
1328     READ_STRING_RETURN_FALSE_LOG(parcel, creatorBundleName_, "creatorBundleName");
1329 
1330     READ_BOOL_RETURN_FALSE_LOG(parcel, isExpired_, "isExpired");
1331     READ_BOOL_RETURN_FALSE_LOG(parcel, tapDismissed_, "tapDismissed");
1332 
1333     READ_INT64_RETURN_FALSE_LOG(parcel, autoDeletedTime_, "autoDeletedTime");
1334 
1335     int32_t tempReminderId = -1;
1336     READ_INT32_RETURN_FALSE_LOG(parcel, tempReminderId, "reminderId");
1337     reminderId_ = (tempReminderId == -1) ? reminderId_ : tempReminderId;
1338 
1339     READ_INT32_RETURN_FALSE_LOG(parcel, notificationId_, "notificationId");
1340 
1341     READ_UINT64_RETURN_FALSE_LOG(parcel, triggerTimeInMilli_, "triggerTimeInMilli");
1342     READ_UINT64_RETURN_FALSE_LOG(parcel, timeIntervalInMilli_, "timeIntervalInMilli");
1343     READ_UINT64_RETURN_FALSE_LOG(parcel, ringDurationInMilli_, "ringDurationInMilli");
1344     READ_UINT64_RETURN_FALSE_LOG(parcel, reminderTimeInMilli_, "reminderTimeInMilli");
1345 
1346     READ_UINT8_RETURN_FALSE_LOG(parcel, snoozeTimes_, "snoozeTimes");
1347     READ_UINT8_RETURN_FALSE_LOG(parcel, snoozeTimesDynamic_, "snoozeTimesDynamic");
1348     READ_UINT8_RETURN_FALSE_LOG(parcel, state_, "state");
1349     int32_t slotType = static_cast<int32_t>(NotificationConstant::SlotType::OTHER);
1350     READ_INT32_RETURN_FALSE_LOG(parcel, slotType, "slotType");
1351     slotType_ = static_cast<NotificationConstant::SlotType>(slotType);
1352 
1353     int32_t snoozeSlotType = static_cast<int32_t>(NotificationConstant::SlotType::OTHER);
1354     READ_INT32_RETURN_FALSE_LOG(parcel, snoozeSlotType, "snoozeSlotType");
1355     snoozeSlotType_ = static_cast<NotificationConstant::SlotType>(snoozeSlotType);
1356     READ_INT32_RETURN_FALSE_LOG(parcel, titleResourceId_, "titleResourceId");
1357     READ_INT32_RETURN_FALSE_LOG(parcel, contentResourceId_, "contentResourceId");
1358     READ_INT32_RETURN_FALSE_LOG(parcel, expiredContentResourceId_, "expiredContentResourceId");
1359     READ_INT32_RETURN_FALSE_LOG(parcel, snoozeContentResourceId_, "snoozeContentResourceId");
1360     if (!ReadActionButtonFromParcel(parcel)) {
1361         return false;
1362     }
1363 
1364     return true;
1365 }
1366 
InitServerObj()1367 void ReminderRequest::InitServerObj()
1368 {
1369     wantAgentInfo_ = wantAgentInfo_ == nullptr ? std::make_shared<WantAgentInfo>() : wantAgentInfo_;
1370     maxScreenWantAgentInfo_ =
1371         maxScreenWantAgentInfo_ == nullptr ? std::make_shared<MaxScreenAgentInfo>() : maxScreenWantAgentInfo_;
1372 }
1373 
IsAlerting() const1374 bool ReminderRequest::IsAlerting() const
1375 {
1376     return (state_ & REMINDER_STATUS_ALERTING) != 0;
1377 }
1378 
GetDurationSinceEpochInMilli(const time_t target)1379 uint64_t ReminderRequest::GetDurationSinceEpochInMilli(const time_t target)
1380 {
1381     auto tarEndTimePoint = std::chrono::system_clock::from_time_t(target);
1382     auto tarDuration = std::chrono::duration_cast<std::chrono::milliseconds>(tarEndTimePoint.time_since_epoch());
1383     int64_t tarDate = tarDuration.count();
1384     if (tarDate < 0) {
1385         ANSR_LOGW("tarDuration is less than 0.");
1386         return INVALID_LONG_LONG_VALUE;
1387     }
1388     return tarDate;
1389 }
1390 
GetDateTimeInfo(const time_t & timeInSecond) const1391 std::string ReminderRequest::GetDateTimeInfo(const time_t &timeInSecond) const
1392 {
1393     return GetTimeInfoInner(timeInSecond, TimeFormat::YMDHMS, true);
1394 }
1395 
SerializeButtonInfo() const1396 std::string ReminderRequest::SerializeButtonInfo() const
1397 {
1398     std::string info = "";
1399     bool isFirst = true;
1400     for (auto button : actionButtonMap_) {
1401         if (!isFirst) {
1402             info += SEP_BUTTON_MULTI;
1403         }
1404         ActionButtonInfo buttonInfo = button.second;
1405         nlohmann::json root;
1406         root["type"] = std::to_string(static_cast<uint8_t>(button.first));
1407         root["title"] = buttonInfo.title;
1408         root["resource"] = buttonInfo.resource;
1409         if (buttonInfo.wantAgent != nullptr) {
1410             nlohmann::json wantAgentfriends;
1411             wantAgentfriends["pkgName"] = buttonInfo.wantAgent->pkgName;
1412             wantAgentfriends["abilityName"] = buttonInfo.wantAgent->abilityName;
1413             root["wantAgent"]  = wantAgentfriends;
1414         }
1415 
1416         if (buttonInfo.dataShareUpdate != nullptr) {
1417             nlohmann::json dataShareUpdatefriends;
1418             dataShareUpdatefriends["uri"] = buttonInfo.dataShareUpdate->uri;
1419             dataShareUpdatefriends["equalTo"] = buttonInfo.dataShareUpdate->equalTo;
1420             dataShareUpdatefriends["valuesBucket"] = buttonInfo.dataShareUpdate->valuesBucket;
1421             root["dataShareUpdate"]  = dataShareUpdatefriends;
1422         }
1423         std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
1424         info += str;
1425         isFirst = false;
1426     }
1427     return info;
1428 }
1429 
GetNowInstantMilli() const1430 uint64_t ReminderRequest::GetNowInstantMilli() const
1431 {
1432     time_t now;
1433     (void)time(&now);  // unit is seconds.
1434     if (static_cast<int64_t>(now) < 0) {
1435         ANSR_LOGE("Get now time error");
1436         return 0;
1437     }
1438     return GetDurationSinceEpochInMilli(now);
1439 }
1440 
GetShowTime(const uint64_t showTime) const1441 std::string ReminderRequest::GetShowTime(const uint64_t showTime) const
1442 {
1443     if (reminderType_ == ReminderType::TIMER) {
1444         return "";
1445     }
1446     return GetTimeInfoInner(static_cast<time_t>(showTime / MILLI_SECONDS), TimeFormat::HM, false);
1447 }
1448 
GetTimeInfoInner(const time_t & timeInSecond,const TimeFormat & format,bool keep24Hour) const1449 std::string ReminderRequest::GetTimeInfoInner(const time_t &timeInSecond, const TimeFormat &format,
1450     bool keep24Hour) const
1451 {
1452     const uint8_t dateTimeLen = 80;
1453     char dateTimeBuffer[dateTimeLen];
1454     struct tm timeInfo;
1455     (void)localtime_r(&timeInSecond, &timeInfo);
1456     bool is24HourClock = OHOS::Global::I18n::LocaleConfig::Is24HourClock();
1457     if (!is24HourClock && timeInfo.tm_hour > TIME_HOUR_OFFSET && !keep24Hour) {
1458         timeInfo.tm_hour -= TIME_HOUR_OFFSET;
1459     }
1460     switch (format) {
1461         case TimeFormat::YMDHMS: {
1462             (void)strftime(dateTimeBuffer, dateTimeLen, "%Y-%m-%d %H:%M:%S", &timeInfo);
1463             break;
1464         }
1465         case TimeFormat::HM: {
1466             (void)strftime(dateTimeBuffer, dateTimeLen, "%H:%M", &timeInfo);
1467             break;
1468         }
1469         default: {
1470             ANSR_LOGW("Time format not support.");
1471             break;
1472         }
1473     }
1474     std::string dateTimeInfo(dateTimeBuffer);
1475     return dateTimeInfo;
1476 }
1477 
GetState(const uint8_t state) const1478 std::string ReminderRequest::GetState(const uint8_t state) const
1479 {
1480     std::string stateInfo = "'";
1481     if (state == REMINDER_STATUS_INACTIVE) {
1482         stateInfo += "Inactive";
1483     } else {
1484         bool hasSeparator = false;
1485         if ((state & REMINDER_STATUS_ACTIVE) != 0) {
1486             stateInfo += "Active";
1487             hasSeparator = true;
1488         }
1489         if ((state & REMINDER_STATUS_ALERTING) != 0) {
1490             if (hasSeparator) {
1491                 stateInfo += ",";
1492             }
1493             stateInfo += "Alerting";
1494             hasSeparator = true;
1495         }
1496         if ((state & REMINDER_STATUS_SHOWING) != 0) {
1497             if (hasSeparator) {
1498                 stateInfo += ",";
1499             }
1500             stateInfo += "Showing";
1501             hasSeparator = true;
1502         }
1503         if ((state & REMINDER_STATUS_SNOOZE) != 0) {
1504             if (hasSeparator) {
1505                 stateInfo += ",";
1506             }
1507             stateInfo += "Snooze";
1508         }
1509     }
1510     stateInfo += "'";
1511     return stateInfo;
1512 }
1513 
AddActionButtons(NotificationRequest & notificationRequest,const bool includeSnooze)1514 void ReminderRequest::AddActionButtons(NotificationRequest& notificationRequest, const bool includeSnooze)
1515 {
1516     int32_t requestCode = 10;
1517     std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
1518     flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
1519     for (auto button : actionButtonMap_) {
1520         auto want = std::make_shared<OHOS::AAFwk::Want>();
1521         auto type = button.first;
1522         switch (type) {
1523             case ActionButtonType::CLOSE:
1524                 want->SetAction(REMINDER_EVENT_CLOSE_ALERT);
1525                 break;
1526             case ActionButtonType::SNOOZE:
1527                 if (includeSnooze) {
1528                     want->SetAction(REMINDER_EVENT_SNOOZE_ALERT);
1529                 } else {
1530                     ANSR_LOGD("Not add action button, type is snooze, as includeSnooze is false");
1531                     continue;
1532                 }
1533                 break;
1534             case ActionButtonType::CUSTOM:
1535                 want->SetAction(REMINDER_EVENT_CUSTOM_ALERT);
1536                 if (button.second.wantAgent == nullptr) {
1537                     return;
1538                 }
1539                 want->SetParam("PkgName", button.second.wantAgent->pkgName);
1540                 want->SetParam("AbilityName", button.second.wantAgent->abilityName);
1541                 break;
1542             default:
1543                 break;
1544         }
1545         want->SetParam(PARAM_REMINDER_ID, reminderId_);
1546         want->SetParam(PARAM_REMINDER_SHARE, isShare_);
1547         std::vector<std::shared_ptr<AAFwk::Want>> wants;
1548         wants.push_back(want);
1549         auto title = static_cast<std::string>(button.second.title);
1550         AbilityRuntime::WantAgent::WantAgentInfo buttonWantAgentInfo(
1551             requestCode,
1552             AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1553             flags, wants, nullptr
1554         );
1555 
1556         std::string identity = IPCSkeleton::ResetCallingIdentity();
1557         std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> buttonWantAgent =
1558             AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(buttonWantAgentInfo, userId_);
1559         IPCSkeleton::SetCallingIdentity(identity);
1560 
1561         std::shared_ptr<NotificationActionButton> actionButton
1562             = NotificationActionButton::Create(nullptr, title, buttonWantAgent);
1563         notificationRequest.AddActionButton(actionButton);
1564     }
1565 }
1566 
UpdateNotificationAddRemovalWantAgent(NotificationRequest & notificationRequest)1567 void ReminderRequest::UpdateNotificationAddRemovalWantAgent(NotificationRequest& notificationRequest)
1568 {
1569     ANSR_LOGI("UpdateNotification removal_want_agent");
1570     int32_t requestCode = 10;
1571     std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
1572     flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
1573     auto want = std::make_shared<OHOS::AAFwk::Want>();
1574     want->SetAction(REMINDER_EVENT_REMOVE_NOTIFICATION);
1575     want->SetParam(PARAM_REMINDER_ID, reminderId_);
1576     want->SetParam(PARAM_REMINDER_SHARE, isShare_);
1577     std::vector<std::shared_ptr<AAFwk::Want>> wants;
1578     wants.push_back(want);
1579     AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
1580         requestCode,
1581         AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1582         flags,
1583         wants,
1584         nullptr
1585     );
1586 
1587     std::string identity = IPCSkeleton::ResetCallingIdentity();
1588     std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> wantAgent =
1589         AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo, userId_);
1590     IPCSkeleton::SetCallingIdentity(identity);
1591 
1592     notificationRequest.SetRemovalWantAgent(wantAgent);
1593 }
1594 
CreateWantAgent(AppExecFwk::ElementName & element) const1595 std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> ReminderRequest::CreateWantAgent(
1596     AppExecFwk::ElementName &element) const
1597 {
1598     int32_t requestCode = 10;
1599     std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> wantFlags;
1600     wantFlags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
1601     auto want = std::make_shared<OHOS::AAFwk::Want>();
1602     want->SetAction(REMINDER_EVENT_CLICK_ALERT);
1603     want->SetParam(PARAM_REMINDER_ID, reminderId_);
1604     want->SetParam(PARAM_REMINDER_SHARE, isShare_);
1605     std::vector<std::shared_ptr<AAFwk::Want>> wantes;
1606     wantes.push_back(want);
1607     AbilityRuntime::WantAgent::WantAgentInfo wantInfo(
1608         requestCode,
1609         AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
1610         wantFlags,
1611         wantes,
1612         nullptr
1613     );
1614     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
1615     auto wantAgent = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantInfo, userId_);
1616     IPCSkeleton::SetCallingIdentity(callingIdentity);
1617     return wantAgent;
1618 }
1619 
CreateMaxWantAgent(AppExecFwk::ElementName & element) const1620 std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> ReminderRequest::CreateMaxWantAgent(
1621     AppExecFwk::ElementName &element) const
1622 {
1623     int32_t requestCode = 10;
1624     std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
1625     flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
1626     auto want = std::make_shared<OHOS::AAFwk::Want>();
1627     want->SetElement(element);
1628     std::vector<std::shared_ptr<AAFwk::Want>> wants;
1629     wants.push_back(want);
1630     AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
1631         requestCode,
1632         AbilityRuntime::WantAgent::WantAgentConstant::OperationType::START_ABILITY,
1633         flags,
1634         wants,
1635         nullptr
1636     );
1637     std::string identity = IPCSkeleton::ResetCallingIdentity();
1638     auto wantAgent = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo, userId_);
1639     IPCSkeleton::SetCallingIdentity(identity);
1640     return wantAgent;
1641 }
1642 
SetState(bool deSet,const uint8_t newState,std::string function)1643 void ReminderRequest::SetState(bool deSet, const uint8_t newState, std::string function)
1644 {
1645     uint8_t oldState = state_;
1646     if (deSet) {
1647         state_ |= newState;
1648     } else {
1649         state_ &= static_cast<uint8_t>(~newState);
1650     }
1651     ANSR_LOGI("Switch the reminder(reminderId=%{public}d) state, from %{public}s to %{public}s, called by %{public}s",
1652         reminderId_, GetState(oldState).c_str(), GetState(state_).c_str(), function.c_str());
1653 }
1654 
SetStateToInActive()1655 void ReminderRequest::SetStateToInActive()
1656 {
1657     SetState(false, (REMINDER_STATUS_SHOWING | REMINDER_STATUS_ALERTING | REMINDER_STATUS_ACTIVE),
1658         "SetStateToInActive");
1659 }
1660 
UpdateActionButtons(NotificationRequest & notificationRequest,const bool & setSnooze)1661 void ReminderRequest::UpdateActionButtons(NotificationRequest& notificationRequest, const bool &setSnooze)
1662 {
1663     notificationRequest.ClearActionButtons();
1664     if (setSnooze) {
1665         AddActionButtons(notificationRequest, false);
1666     } else {
1667         AddActionButtons(notificationRequest, true);
1668     }
1669 }
1670 
UpdateNextReminder(const bool & force)1671 bool ReminderRequest::UpdateNextReminder(const bool &force)
1672 {
1673     bool result = true;
1674     if (force) {
1675         uint64_t nowInstantMilli = GetNowInstantMilli();
1676         if (nowInstantMilli == 0) {
1677             result = false;
1678         } else {
1679             if (timeIntervalInMilli_ != 0) {
1680                 triggerTimeInMilli_ = nowInstantMilli + timeIntervalInMilli_;
1681                 snoozeTimesDynamic_ = snoozeTimes_;
1682                 isExpired_ = false;
1683             }
1684         }
1685     } else {
1686         result = UpdateNextReminder();
1687     }
1688     std::string info = result ? "success" : "no next";
1689     ANSR_LOGI("updateNextReminder(id=%{public}d, %{public}s): force=%{public}d, trigger time is: %{public}s",
1690         reminderId_, info.c_str(), force,
1691         GetDateTimeInfo(static_cast<time_t>(triggerTimeInMilli_ / MILLI_SECONDS)).c_str());
1692     return result;
1693 }
1694 
UpdateNotificationCommon(NotificationRequest & notificationRequest,bool isSnooze)1695 void ReminderRequest::UpdateNotificationCommon(NotificationRequest& notificationRequest, bool isSnooze)
1696 {
1697     ANSR_LOGI("UpdateNotification common information");
1698     time_t now;
1699     (void)time(&now);  // unit is seconds.
1700     notificationRequest.SetDeliveryTime(GetDurationSinceEpochInMilli(now));
1701     notificationRequest.SetLabel(NOTIFICATION_LABEL);
1702     notificationRequest.SetShowDeliveryTime(true);
1703     if (isSnooze) {
1704         if (snoozeSlotType_ == NotificationConstant::SlotType::OTHER) {
1705             notificationRequest.SetSlotType(NotificationConstant::SlotType::CONTENT_INFORMATION);
1706         } else {
1707             notificationRequest.SetSlotType(snoozeSlotType_);
1708         }
1709     } else {
1710         notificationRequest.SetSlotType(slotType_);
1711     }
1712     notificationRequest.SetTapDismissed(tapDismissed_);
1713     notificationRequest.SetAutoDeletedTime(autoDeletedTime_);
1714     auto notificationNormalContent = std::make_shared<NotificationNormalContent>();
1715     notificationNormalContent->SetText(displayContent_);
1716     notificationNormalContent->SetTitle(title_);
1717     auto notificationContent = std::make_shared<NotificationContent>(notificationNormalContent);
1718     notificationRequest.SetContent(notificationContent);
1719     if ((reminderType_ == ReminderRequest::ReminderType::TIMER) ||
1720         (reminderType_ == ReminderRequest::ReminderType::ALARM)) {
1721         notificationRequest.SetUnremovable(true);
1722     }
1723 }
1724 
UpdateNotificationBundleInfo(NotificationRequest & notificationRequest)1725 void ReminderRequest::UpdateNotificationBundleInfo(NotificationRequest& notificationRequest)
1726 {
1727     notificationRequest.SetCreatorUid(uid_);
1728 }
1729 
UpdateNotificationContent(NotificationRequest & notificationRequest,const bool & setSnooze)1730 void ReminderRequest::UpdateNotificationContent(NotificationRequest& notificationRequest, const bool &setSnooze)
1731 {
1732     std::string extendContent = "";
1733     if (setSnooze) {
1734         if (timeIntervalInMilli_ != 0) {
1735             // snooze the reminder by manual
1736             extendContent = snoozeContent_;
1737             notificationRequest.SetTapDismissed(false);
1738         } else {
1739             // the reminder is expired now, when timeInterval is 0
1740             extendContent = expiredContent_;
1741         }
1742     } else if (IsAlerting()) {
1743         // the reminder is alerting, or ring duration is 0
1744         extendContent = "";
1745     } else if (snoozeTimesDynamic_ != snoozeTimes_) {
1746         // the reminder is snoozing by period artithmetic, when the ring duration is over.
1747         extendContent = snoozeContent_;
1748         notificationRequest.SetTapDismissed(false);
1749     } else {
1750         // the reminder has already snoozed by period arithmetic, when the ring duration is over.
1751         extendContent = expiredContent_;
1752     }
1753     if (extendContent == "") {
1754         displayContent_ = content_;
1755     } else {
1756         displayContent_ = extendContent;
1757     }
1758     ANSR_LOGD("Display content=%{public}s", displayContent_.c_str());
1759 }
1760 
UpdateNotificationStateForAlert(NotificationRequest & notificationRequest)1761 void ReminderRequest::UpdateNotificationStateForAlert(NotificationRequest& notificationRequest)
1762 {
1763     ANSR_LOGD("UpdateNotification content and buttons");
1764     UpdateNotificationContent(notificationRequest, false);
1765     UpdateActionButtons(notificationRequest, false);
1766 }
1767 
UpdateNotificationStateForSnooze(NotificationRequest & notificationRequest)1768 void ReminderRequest::UpdateNotificationStateForSnooze(NotificationRequest& notificationRequest)
1769 {
1770     ANSR_LOGD("UpdateNotification content and buttons");
1771     UpdateNotificationContent(notificationRequest, true);
1772     UpdateActionButtons(notificationRequest, true);
1773 }
1774 
GetActualTime(const TimeTransferType & type,int32_t cTime)1775 int32_t ReminderRequest::GetActualTime(const TimeTransferType &type, int32_t cTime)
1776 {
1777     switch (type) {
1778         case (TimeTransferType::YEAR):  // year
1779             return BASE_YEAR + cTime;
1780         case (TimeTransferType::MONTH):  // month
1781             return 1 + cTime;
1782         case (TimeTransferType::WEEK): {  // week
1783             return cTime == 0 ? SUNDAY : cTime;
1784         }
1785         default:
1786             return -1;
1787     }
1788 }
1789 
GetCTime(const TimeTransferType & type,int32_t actualTime)1790 int32_t ReminderRequest::GetCTime(const TimeTransferType &type, int32_t actualTime)
1791 {
1792     switch (type) {
1793         case (TimeTransferType::YEAR):  // year
1794             return actualTime - BASE_YEAR;
1795         case (TimeTransferType::MONTH):  // month
1796             return actualTime - 1;
1797         case (TimeTransferType::WEEK): {  // week
1798             return actualTime == SUNDAY ? 0 : actualTime;
1799         }
1800         default:
1801             return -1;
1802     }
1803 }
1804 
SerializeWantAgent(std::string & wantInfoStr,std::string & maxWantInfoStr)1805 void ReminderRequest::SerializeWantAgent(std::string& wantInfoStr, std::string& maxWantInfoStr)
1806 {
1807     std::string pkgName;
1808     std::string abilityName;
1809     std::string uri;
1810     std::string parameters;
1811     if (wantAgentInfo_ != nullptr) {
1812         pkgName = wantAgentInfo_->pkgName;
1813         abilityName = wantAgentInfo_->abilityName;
1814         uri = wantAgentInfo_->uri;
1815         AAFwk::WantParamWrapper wrapper(wantAgentInfo_->parameters);
1816         parameters = wrapper.ToString();
1817     }
1818     nlohmann::json wantInfo;
1819     wantInfo["pkgName"] = pkgName;
1820     wantInfo["abilityName"] = abilityName;
1821     wantInfo["uri"] = uri;
1822     wantInfo["parameters"] = parameters;
1823     wantInfoStr = wantInfo.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
1824 
1825     if (maxScreenWantAgentInfo_ != nullptr) {
1826         pkgName = maxScreenWantAgentInfo_->pkgName;
1827         abilityName = maxScreenWantAgentInfo_->abilityName;
1828         uri = "";
1829         parameters = "";
1830     }
1831     nlohmann::json maxWantInfo;
1832     maxWantInfo["pkgName"] = pkgName;
1833     maxWantInfo["abilityName"] = abilityName;
1834     maxWantInfo["uri"] = uri;
1835     maxWantInfo["parameters"] = parameters;
1836     maxWantInfoStr = maxWantInfo.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
1837 }
1838 
GetNextDaysOfWeek(const time_t now,const time_t target) const1839 int64_t ReminderRequest::GetNextDaysOfWeek(const time_t now, const time_t target) const
1840 {
1841     struct tm nowTime;
1842     (void)localtime_r(&now, &nowTime);
1843     int32_t today = GetActualTime(TimeTransferType::WEEK, nowTime.tm_wday);
1844     int32_t dayCount = now >= target ? 1 : 0;
1845     for (; dayCount <= DAYS_PER_WEEK; dayCount++) {
1846         int32_t day = (today + dayCount) % DAYS_PER_WEEK;
1847         day = (day == 0) ? SUNDAY : day;
1848         if (IsRepeatDaysOfWeek(day)) {
1849             break;
1850         }
1851     }
1852     ANSR_LOGI("NextDayInterval is %{public}d", dayCount);
1853     time_t nextTriggerTime = target + dayCount * HOURS_PER_DAY * SECONDS_PER_HOUR;
1854     return GetTriggerTime(now, nextTriggerTime);
1855 }
1856 
IsRepeatDaysOfWeek(int32_t day) const1857 bool ReminderRequest::IsRepeatDaysOfWeek(int32_t day) const
1858 {
1859     return (repeatDaysOfWeek_ & (1 << (day - 1))) > 0;
1860 }
1861 
GetTriggerTimeWithDST(const time_t now,const time_t nextTriggerTime) const1862 time_t ReminderRequest::GetTriggerTimeWithDST(const time_t now, const time_t nextTriggerTime) const
1863 {
1864     time_t triggerTime = nextTriggerTime;
1865     struct tm nowLocal;
1866     struct tm nextLocal;
1867     (void)localtime_r(&now, &nowLocal);
1868     (void)localtime_r(&nextTriggerTime, &nextLocal);
1869     if (nowLocal.tm_isdst == 0 && nextLocal.tm_isdst > 0) {
1870         triggerTime -= SECONDS_PER_HOUR;
1871     } else if (nowLocal.tm_isdst > 0 && nextLocal.tm_isdst == 0) {
1872         triggerTime += SECONDS_PER_HOUR;
1873     }
1874     return triggerTime;
1875 }
1876 
GetRepeatDaysOfWeek() const1877 uint8_t ReminderRequest::GetRepeatDaysOfWeek() const
1878 {
1879     return repeatDaysOfWeek_;
1880 }
1881 
SetRepeatDaysOfWeek(bool set,const std::vector<uint8_t> & daysOfWeek)1882 void ReminderRequest::SetRepeatDaysOfWeek(bool set, const std::vector<uint8_t> &daysOfWeek)
1883 {
1884     if (daysOfWeek.size() == 0) {
1885         return;
1886     }
1887     if (daysOfWeek.size() > DAYS_PER_WEEK) {
1888         ANSR_LOGE("The length of daysOfWeek should not larger than 7");
1889         return;
1890     }
1891     for (auto it = daysOfWeek.begin(); it != daysOfWeek.end(); ++it) {
1892         if (*it < MONDAY || *it > SUNDAY) {
1893             continue;
1894         }
1895         if (set) {
1896             repeatDaysOfWeek_ |= 1 << (*it - 1);
1897         } else {
1898             repeatDaysOfWeek_ &= ~(1 << (*it - 1));
1899         }
1900     }
1901 }
1902 
GetDaysOfWeek() const1903 std::vector<int32_t> ReminderRequest::GetDaysOfWeek() const
1904 {
1905     std::vector<int32_t> repeatDays;
1906     int32_t days[] = {1, 2, 3, 4, 5, 6, 7};
1907     int32_t len = sizeof(days) / sizeof(int32_t);
1908     for (int32_t i = 0; i < len; i++) {
1909         if (IsRepeatDaysOfWeek(days[i])) {
1910             repeatDays.push_back(days[i]);
1911         }
1912     }
1913     return repeatDays;
1914 }
1915 
GetTriggerTime(const time_t now,const time_t nextTriggerTime) const1916 uint64_t ReminderRequest::GetTriggerTime(const time_t now, const time_t nextTriggerTime) const
1917 {
1918     time_t triggerTime = GetTriggerTimeWithDST(now, nextTriggerTime);
1919     struct tm test;
1920     (void)localtime_r(&triggerTime, &test);
1921     ANSR_LOGI("NextTriggerTime: year=%{public}d, mon=%{public}d, day=%{public}d, hour=%{public}d, "
1922             "min=%{public}d, sec=%{public}d, week=%{public}d, nextTriggerTime=%{public}lld",
1923         GetActualTime(TimeTransferType::YEAR, test.tm_year),
1924         GetActualTime(TimeTransferType::MONTH, test.tm_mon),
1925         test.tm_mday,
1926         test.tm_hour,
1927         test.tm_min,
1928         test.tm_sec,
1929         GetActualTime(TimeTransferType::WEEK, test.tm_wday),
1930         (long long)triggerTime);
1931 
1932     if (static_cast<int64_t>(triggerTime) <= 0) {
1933         return 0;
1934     }
1935     return GetDurationSinceEpochInMilli(triggerTime);
1936 }
1937 
OnLanguageChange(const std::shared_ptr<Global::Resource::ResourceManager> & resMgr)1938 void ReminderRequest::OnLanguageChange(const std::shared_ptr<Global::Resource::ResourceManager> &resMgr)
1939 {
1940     if (resMgr == nullptr) {
1941         return;
1942     }
1943     // update action title
1944     for (auto &button : actionButtonMap_) {
1945         if (button.second.resource.empty()) {
1946             continue;
1947         }
1948         std::string title;
1949         resMgr->GetStringByName(button.second.resource.c_str(), title);
1950         if (title.empty()) {
1951             continue;
1952         }
1953         button.second.title = title;
1954     }
1955     // update title
1956     if (titleResourceId_ != 0) {
1957         std::string title;
1958         resMgr->GetStringById(titleResourceId_, title);
1959         if (!title.empty()) {
1960             title_ = title;
1961         }
1962     }
1963     // update content
1964     if (contentResourceId_ != 0) {
1965         std::string content;
1966         resMgr->GetStringById(contentResourceId_, content);
1967         if (!content.empty()) {
1968             content_ = content;
1969         }
1970     }
1971     // update expiredContent
1972     if (expiredContentResourceId_ != 0) {
1973         std::string expiredContent;
1974         resMgr->GetStringById(expiredContentResourceId_, expiredContent);
1975         if (!expiredContent.empty()) {
1976             expiredContent_ = expiredContent;
1977         }
1978     }
1979     // update snoozeContent
1980     if (snoozeContentResourceId_ != 0) {
1981         std::string snoozeContent;
1982         resMgr->GetStringById(snoozeContentResourceId_, snoozeContent);
1983         if (!snoozeContent.empty()) {
1984             snoozeContent_ = snoozeContent;
1985         }
1986     }
1987 }
1988 }
1989 }
1990