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