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