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 #ifndef BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_REMINDER_REQUEST_CALENDAR_H
17 #define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_REMINDER_REQUEST_CALENDAR_H
18 
19 #include "reminder_request.h"
20 
21 namespace OHOS {
22 namespace Notification {
23 class ReminderRequestCalendar : public ReminderRequest {
24 public:
25     /**
26      * @brief A {@link ReminderRequest} child class used for creating reminders of calendar clocks.
27      *
28      * @note The params must meet the following conditions.
29      * otherwise the application may crash due to an illegal parameter exception.
30      * <ul>
31      * <li> The length of repeatMonths vectory cannot exceed 12. </li>
32      * <li> The length of repeateDays vectory cannot exceed 31. </li>
33      * <li> There must be at least one valid reminder time. Ensure that the time specified by dateTime
34      * does not expired, or repeatMonths and repeateDays are valid. </li>
35      * </ul>
36      *
37      * The repeateMonths and repeatDays must both be set to implements repeated reminders.
38      * By default, this reminder is not snoozed. You can call {@link SetTimeInterval} to
39      * set the snooze interval.
40      *
41      * @param dateTime Indicates the date and time when this calendar event reminder will be triggered.
42      *                 The time is accurate to minute. For example, the value
43      *                 {@link LocalDateTime(2021, 3, 3, 16, 15)} indicates that the reminder will be
44      *                 triggered at 16:15 on March 3, 2021.
45      * @param repeatMonths Indicates the months in which this reminder will be repeated. For example,
46      *                     the value {2, 4} indicates that the reminder will be triggered on particular
47      *                     days in February and April.
48      * @param repeatDays Indicates the days in a month when this reminder will be repeated. For example,
49      *                   the value {2, 4} indicates that the reminder will be triggered on the second
50      *                   and fourth day of the specific months.
51      */
52     ReminderRequestCalendar(const tm &dateTime, const std::vector<uint8_t> &repeatMonths,
53         const std::vector<uint8_t> &repeatDays, const std::vector<uint8_t> &daysOfWeek);
54 
55     /**
56      * @brief This constructor should only be used in background proxy service process
57      * when reminder instance recovery from database.
58      *
59      * @param reminderId Indicates reminder id.
60      */
ReminderRequestCalendar(int32_t reminderId)61     explicit ReminderRequestCalendar(int32_t reminderId) : ReminderRequest(reminderId) {};
62 
63     explicit ReminderRequestCalendar(const ReminderRequestCalendar &other);
64     ReminderRequestCalendar& operator = (const ReminderRequestCalendar &other);
~ReminderRequestCalendar()65     ~ReminderRequestCalendar() override {}
66 
67     void SetRRuleWantAgentInfo(const std::shared_ptr<WantAgentInfo> &wantAgentInfo);
68 
69     std::shared_ptr<ReminderRequest::WantAgentInfo> GetRRuleWantAgentInfo();
70 
71     void AddExcludeDate(const uint64_t date);
72     void DelExcludeDates();
73     std::vector<uint64_t> GetExcludeDates() const;
74     bool IsInExcludeDate() const;
75 
GetYear()76     inline uint16_t GetYear() const
77     {
78         return year_;
79     }
80 
GetMonth()81     inline uint8_t GetMonth() const
82     {
83         return month_;
84     }
85 
GetDay()86     inline uint8_t GetDay() const
87     {
88         return day_;
89     }
90 
GetHour()91     inline uint8_t GetHour() const
92     {
93         return hour_;
94     }
95 
GetMinute()96     inline uint8_t GetMinute() const
97     {
98         return minute_;
99     }
100 
GetSecond()101     inline uint8_t GetSecond() const
102     {
103         return second_;
104     }
105 
GetFirstDesignateYear()106     inline uint16_t GetFirstDesignateYear() const
107     {
108         return firstDesignateYear_;
109     }
110 
GetFirstDesignageMonth()111     inline uint16_t GetFirstDesignageMonth() const
112     {
113         return firstDesignateMonth_;
114     }
115 
GetFirstDesignateDay()116     inline uint16_t GetFirstDesignateDay() const
117     {
118         return firstDesignateDay_;
119     }
120 
121     /**
122      * @brief Gets the repeat day.
123      */
GetRepeatDay()124     uint32_t GetRepeatDay() const
125     {
126         return repeatDay_;
127     }
128 
129     /**
130      * @brief Gets the repeat month.
131      */
GetRepeatMonth()132     uint16_t GetRepeatMonth() const
133     {
134         return repeatMonth_;
135     }
136 
137     /**
138      * @brief Gets the start date time.
139      */
140     uint64_t GetDateTime() const;
141 
142     /**
143      * @brief Gets the end date time.
144      */
145     uint64_t GetEndDateTime() const;
146 
147     /**
148      * @brief Sets the year.
149      *
150      * @param year Indicates the year.
151      */
152     void SetYear(const uint16_t year);
153 
154     /**
155      * @brief Sets the month.
156      *
157      * @param month Indicates the month.
158      */
159     void SetMonth(const uint8_t month);
160 
161     /**
162      * @brief Sets the day.
163      *
164      * @param day Indicates the day.
165      */
166     void SetDay(const uint8_t day);
167 
168     /**
169      * @brief Sets the hour.
170      *
171      * @param hour Indicates the hour.
172      */
173     void SetHour(const uint8_t hour);
174 
175     /**
176      * @brief Sets the minute.
177      *
178      * @param minute Indicates the minute.
179      */
180     void SetMinute(const uint8_t minute);
181 
182     /**
183      * @brief Sets the repeat day.
184      *
185      * @param repeatDay Indicates the repeat day.
186      */
187     void SetRepeatDay(const uint32_t repeatDay);
188 
189     /**
190      * @brief Sets the repeat month.
191      *
192      * @param repeatMonth Indicates the repeat month.
193      */
194     void SetRepeatMonth(const uint16_t repeatMonth);
195 
196     /**
197      * @brief Sets the first designate year.
198      *
199      * @param firstDesignateYear Indicates the first designate year.
200      */
201     void SetFirstDesignateYear(const uint16_t firstDesignateYear);
202 
203     /**
204      * @brief Sets the first designate month.
205      *
206      * @param firstDesignateMonth Indicates the first designate month.
207      */
208     void SetFirstDesignageMonth(const uint16_t firstDesignateMonth);
209 
210     /**
211      * @brief Sets the first designate day.
212      *
213      * @param firstDesignateDay Indicates the first designate day.
214      */
215     void SetFirstDesignateDay(const uint16_t firstDesignateDay);
216 
217     /**
218      * @brief Sets the hour.
219      *
220      * @param hour Indicates the hour.
221      */
222     void SetDateTime(const uint64_t time);
223 
224     /**
225      * @brief Serialize the rrule to string.
226      * Persist to the rdb.
227      */
228     std::string SerializationRRule();
229 
230     /**
231      * @brief Deserialize the rrule from string.
232      * Recover from the rdb.
233      */
234     void DeserializationRRule(const std::string& str);
235 
236     /**
237      * @brief Serialize the exclude date to string.
238      * Persist to the rdb.
239      */
240     std::string SerializationExcludeDates();
241 
242     /**
243      * @brief Deserialize the exclude date from string.
244      * Recover from the rdb.
245      */
246     void DeserializationExcludeDates(const std::string& str);
247 
248     bool InitTriggerTime();
249 
250     std::vector<uint8_t> GetRepeatMonths() const;
251     std::vector<uint8_t> GetRepeatDays() const;
252 
253     virtual bool UpdateNextReminder() override;
254     virtual bool OnDateTimeChange() override;
255 
256     /**
257      * @brief Check reminder request is repeat
258      */
259     bool IsRepeat() const override;
260 
261     /**
262      * @brief Check reminder request is in exclude date
263      */
264     bool CheckExcludeDate() override;
265 
266     /**
267      * @brief Check rrule want agent, pull up service extension
268      */
269     bool IsPullUpService() override;
270 
271     /**
272      * @brief Check need notification reminder. due to system timer.
273      * When change system time to later, more than the trigger time, system timer must trigger.
274      */
275     bool IsNeedNotification() override;
276 
277     /**
278      * Marshal a reminder object into a Parcel.
279      *
280      * @param parcel Indicates the Parcel.
281      */
282     virtual bool Marshalling(Parcel &parcel) const override;
283 
284     /**
285      * Unmarshal object from a Parcel.
286      *
287      * @param parcel Indicates the Parcel.
288      * @return reminder object.
289      */
290     static ReminderRequestCalendar *Unmarshalling(Parcel &parcel);
291 
292     /**
293      * Unmarshal unique properties of alarm from a Parcel.
294      *
295      * @param parcel Indicates the Parcel.
296      * @return true if read parcel success.
297      */
298     bool ReadFromParcel(Parcel &parcel) override;
299     bool SetNextTriggerTime() override;
300 
301     static uint8_t GetDaysOfMonth(const uint16_t &year, const uint8_t &month);
302     bool SetEndDateTime(const uint64_t time);
303 
304     /**
305      * @brief Sets the start time when the notification was last displayed in the notification bar.
306      * When OnDateTimeChange or OnClose, the time will change to next start time if the reminder
307      * is repeat, otherwise not changed.
308      */
309     void SetLastStartDateTime(const uint64_t time);
310 
311     /**
312      * @brief Get the start time when the notification was last displayed in the notification bar.
313      */
314     uint64_t GetLastStartDateTime() const;
315 
316 public:
317     static constexpr uint8_t MAX_MONTHS_OF_YEAR = 12;
318     static constexpr uint8_t MAX_DAYS_OF_MONTH = 31;
319 
320 protected:
321     virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) override;
322 
323 private:
ReminderRequestCalendar()324     ReminderRequestCalendar() : ReminderRequest() {}
325 
326     uint8_t GetNextDay(const uint16_t &settedYear, const uint8_t &settedMonth, const tm &now, const tm &target) const;
327     uint64_t GetNextTriggerTime(const bool updateLast = false);
328     uint64_t GetNextTriggerTimeAsRepeatReminder(const tm &nowTime, const tm &tarTime) const;
329     uint64_t GetTimeInstantMilli(
330         uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) const;
331 
332     /**
333      * @brief Init dateTime_ when read from parcel.
334      */
335     void InitDateTime();
336     void InitDateTime(const tm &dateTime);
337     bool IsRepeatReminder() const;
338     bool IsRepeatMonth(uint8_t month) const;
339     bool IsRepeatDay(uint8_t day) const;
340     void SetDay(const uint8_t &day, const bool &isSet);
341     void SetMonth(const uint8_t &month, const bool &isSet);
342     void SetRepeatMonths(const std::vector<uint8_t> &repeatMonths);
343     void SetRepeatDaysOfMonth(const std::vector<uint8_t> &repeatDays);
344     bool CheckCalenderIsExpired(const uint64_t now);
345 
346     /**
347      * @brief When OnShow or OnSnooze, need calculate the start time of this alert
348      */
349     void CalcLastStartDateTime();
350 
351     static const uint8_t DEFAULT_SNOOZE_TIMES;
352 
353     tm dateTime_ = {
354         .tm_sec = 0,
355         .tm_min = 0,
356         .tm_hour = 0,
357         .tm_mday = 1,
358         .tm_mon = 0,
359         .tm_year = 0,
360         .tm_wday = 0,
361         .tm_yday = 0,
362         .tm_isdst = -1
363     };
364     uint16_t firstDesignateYear_ {1};
365     uint8_t firstDesignateMonth_ {1};
366     uint8_t firstDesignateDay_ {1};
367     uint16_t year_ {1};
368     uint8_t month_ {1};
369     uint8_t day_ {1};
370     uint8_t hour_ {1};
371     uint8_t minute_ {1};
372     uint8_t second_ {0};
373     uint16_t repeatMonth_ {0};
374     uint32_t repeatDay_ {0};
375 
376     uint64_t startDateTime_{0};
377     uint64_t endDateTime_{0};
378     uint64_t durationTime_{0};
379     uint64_t lastStartDateTime_{0};
380 
381     std::set<uint64_t> excludeDates_;
382 
383     // repeat calendar
384     std::shared_ptr<WantAgentInfo> rruleWantAgentInfo_ = nullptr;
385 
386 private:
387     static const uint8_t DAY_ARRAY[12];
388     static constexpr uint8_t JANUARY = 1;
389     static constexpr uint8_t DECEMBER = 12;
390     // if startDateTime < now and now < endDateTime, triggerTime = now + DELAY
391     static constexpr uint64_t DEFAULT_DELAY_TIME = 3000;
392 
393     // for check leap year
394     static constexpr uint8_t FEBRUARY = 2;
395     static constexpr uint8_t LEAP_MONTH = 29;
396     static constexpr uint8_t NON_LEAP_MONTH = 28;
397     static constexpr uint16_t SOLAR_YEAR = 400;
398     static constexpr uint8_t LEAP_PARAM_MIN = 4;
399     static constexpr uint8_t LEAP_PARAM_MAX = 100;
400 };
401 }
402 }
403 #endif  // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_REMINDER_REQUEST_CALENDAR_H