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