• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/reminder_common.h"
17 
18 #include "ans_log_wrapper.h"
19 #include "common.h"
20 #include "reminder_request_alarm.h"
21 #include "reminder_request_calendar.h"
22 #include "reminder_request_timer.h"
23 
24 namespace OHOS {
25 namespace ReminderAgentNapi {
26 using namespace OHOS::Notification;
27 const uint32_t ASYNC_CALLBACK_PARAM_NUM = 2;
28 
GetReminderRequest(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)29 napi_value ReminderCommon::GetReminderRequest(
30     const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
31 {
32     napi_valuetype valuetype = napi_undefined;
33     NAPI_CALL(env, napi_typeof(env, value, &valuetype));
34     if (valuetype != napi_object) {
35         ANSR_LOGW("Wrong argument type. Object expected.");
36         return nullptr;
37     }
38 
39     // gen reminder
40     if (GenReminder(env, value, reminder) == nullptr) {
41         return nullptr;
42     }
43     return NotificationNapi::Common::NapiGetNull(env);
44 }
45 
GenActionButtons(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)46 bool ReminderCommon::GenActionButtons(
47     const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
48 {
49     char str[NotificationNapi::STR_MAX_SIZE] = {0};
50     napi_valuetype valuetype = napi_undefined;
51     napi_value actionButtons = nullptr;
52     if (!GetObject(env, value, ReminderAgentNapi::ACTION_BUTTON, actionButtons)) {
53         return true;
54     }
55     bool isArray = false;
56     napi_is_array(env, actionButtons, &isArray);
57     if (!isArray) {
58         ANSR_LOGW("Wrong argument type:%{public}s. array expected.", ACTION_BUTTON);
59         return false;
60     }
61 
62     uint32_t length = 0;
63     napi_get_array_length(env, actionButtons, &length);
64     for (size_t i = 0; i < length; i++) {
65         napi_value actionButton = nullptr;
66         napi_get_element(env, actionButtons, i, &actionButton);
67         NAPI_CALL_BASE(env, napi_typeof(env, actionButton, &valuetype), false);
68         if (valuetype != napi_object) {
69             ANSR_LOGW("Wrong element type:%{public}s. object expected.", ACTION_BUTTON);
70             return false;
71         }
72 
73         int32_t buttonType = static_cast<int32_t>(ReminderRequest::ActionButtonType::INVALID);
74         if (GetStringUtf8(env, actionButton,
75             ReminderAgentNapi::ACTION_BUTTON_TITLE, str, NotificationNapi::STR_MAX_SIZE) &&
76             GetInt32(env, actionButton, ReminderAgentNapi::ACTION_BUTTON_TYPE, buttonType, false)) {
77             if (ReminderRequest::ActionButtonType(buttonType) != ReminderRequest::ActionButtonType::CLOSE &&
78                 ReminderRequest::ActionButtonType(buttonType) != ReminderRequest::ActionButtonType::SNOOZE) {
79                 ANSR_LOGW("Wrong argument type:%{public}s. buttonType not support.", ACTION_BUTTON);
80                 return false;
81             }
82             std::string title(str);
83             reminder->SetActionButton(title, static_cast<ReminderRequest::ActionButtonType>(buttonType));
84             ANSR_LOGD("button title=%{public}s, type=%{public}d", title.c_str(), buttonType);
85         } else {
86             ANSR_LOGW("Parse action button error.");
87             return false;
88         }
89     }
90     return true;
91 }
92 
GenWantAgent(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)93 void ReminderCommon::GenWantAgent(
94     const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
95 {
96     char str[NotificationNapi::STR_MAX_SIZE] = {0};
97     napi_value wantAgent = nullptr;
98     if (GetObject(env, value, ReminderAgentNapi::WANT_AGENT, wantAgent)) {
99         auto wantAgentInfo = std::make_shared<ReminderRequest::WantAgentInfo>();
100         if (GetStringUtf8(env, wantAgent, ReminderAgentNapi::WANT_AGENT_PKG, str, NotificationNapi::STR_MAX_SIZE)) {
101             wantAgentInfo->pkgName = str;
102         }
103         if (GetStringUtf8(env, wantAgent,
104             ReminderAgentNapi::WANT_AGENT_ABILITY, str, NotificationNapi::STR_MAX_SIZE)) {
105             wantAgentInfo->abilityName = str;
106         }
107         reminder->SetWantAgentInfo(wantAgentInfo);
108     }
109 }
110 
GenMaxScreenWantAgent(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)111 void ReminderCommon::GenMaxScreenWantAgent(
112     const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
113 {
114     char str[NotificationNapi::STR_MAX_SIZE] = {0};
115     napi_value maxScreenWantAgent = nullptr;
116     if (GetObject(env, value, ReminderAgentNapi::MAX_SCREEN_WANT_AGENT, maxScreenWantAgent)) {
117         auto maxScreenWantAgentInfo = std::make_shared<ReminderRequest::MaxScreenAgentInfo>();
118         if (GetStringUtf8(env, maxScreenWantAgent,
119             ReminderAgentNapi::MAX_SCREEN_WANT_AGENT_PKG, str, NotificationNapi::STR_MAX_SIZE)) {
120             maxScreenWantAgentInfo->pkgName = str;
121         }
122         if (GetStringUtf8(env, maxScreenWantAgent,
123             ReminderAgentNapi::MAX_SCREEN_WANT_AGENT_ABILITY, str, NotificationNapi::STR_MAX_SIZE)) {
124             maxScreenWantAgentInfo->abilityName = str;
125         }
126         reminder->SetMaxScreenWantAgentInfo(maxScreenWantAgentInfo);
127     }
128 }
CreateReminder(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)129 bool ReminderCommon::CreateReminder(
130     const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
131 {
132     napi_value result = nullptr;
133     napi_get_named_property(env, value, ReminderAgentNapi::REMINDER_TYPE, &result);
134     int32_t reminderType = -1;
135     napi_get_value_int32(env, result, &reminderType);
136     switch (ReminderRequest::ReminderType(reminderType)) {
137         case ReminderRequest::ReminderType::TIMER:
138             CreateReminderTimer(env, value, reminder);
139             break;
140         case ReminderRequest::ReminderType::ALARM:
141             CreateReminderAlarm(env, value, reminder);
142             break;
143         case ReminderRequest::ReminderType::CALENDAR:
144             CreateReminderCalendar(env, value, reminder);
145             break;
146         default:
147             ANSR_LOGW("Reminder type is not support. (type:%{public}d)", reminderType);
148             break;
149     }
150     if (reminder == nullptr) {
151         ANSR_LOGW("Instance of reminder error.");
152         return false;
153     }
154     return true;
155 }
156 
GenReminder(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)157 napi_value ReminderCommon::GenReminder(
158     const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
159 {
160     // reminderType
161     bool hasProperty = false;
162     NAPI_CALL(env, napi_has_named_property(env, value, ReminderAgentNapi::REMINDER_TYPE, &hasProperty));
163     if (!hasProperty) {
164         ANSR_LOGW("Property %{public}s expected.", ReminderAgentNapi::REMINDER_TYPE);
165         return nullptr;
166     }
167 
168     // createReminder
169     if (!CreateReminder(env, value, reminder)) {
170         return nullptr;
171     }
172     char str[NotificationNapi::STR_MAX_SIZE] = {0};
173 
174     // title
175     if (GetStringUtf8(env, value, ReminderAgentNapi::TITLE, str, NotificationNapi::STR_MAX_SIZE)) {
176         reminder->SetTitle(std::string(str));
177     }
178 
179     // content
180     if (GetStringUtf8(env, value, ReminderAgentNapi::CONTENT, str, NotificationNapi::STR_MAX_SIZE)) {
181         reminder->SetContent(std::string(str));
182     }
183 
184     // expiredContent
185     if (GetStringUtf8(env, value, ReminderAgentNapi::EXPIRED_CONTENT, str, NotificationNapi::STR_MAX_SIZE)) {
186         reminder->SetExpiredContent(std::string(str));
187     }
188 
189     // snoozeContent
190     if (GetStringUtf8(env, value, ReminderAgentNapi::SNOOZE_CONTENT, str, NotificationNapi::STR_MAX_SIZE)) {
191         reminder->SetSnoozeContent(std::string(str));
192     }
193 
194     // ringDuration
195     int64_t propVal = 0;
196     if (GetInt64(env, value, ReminderAgentNapi::RING_DURATION, propVal)) {
197         if (propVal < 0) {
198             reminder->SetRingDuration(0);
199         } else {
200             uint64_t ringDuration = static_cast<uint64_t>(propVal);
201             reminder->SetRingDuration(ringDuration);
202         }
203     }
204 
205     // timeInterval
206     if (GetInt64(env, value, ReminderAgentNapi::TIME_INTERVAL, propVal)) {
207         if (propVal < 0) {
208             reminder->SetTimeInterval(0);
209         } else {
210             uint64_t timeInterval = static_cast<uint64_t>(propVal);
211             reminder->SetTimeInterval(timeInterval);
212         }
213     }
214 
215     // notificationId
216     int32_t propertyVal = 0;
217     if (GetInt32(env, value, ReminderAgentNapi::NOTIFICATION_ID, propertyVal, false)) {
218         reminder->SetNotificationId(propertyVal);
219     }
220 
221     // snoozeTimes
222     if (GetInt32(env, value, ReminderAgentNapi::SNOOZE_TIMES, propertyVal, false)) {
223         if (propertyVal < 0) {
224             reminder->SetSnoozeTimes(0);
225         } else {
226             uint8_t snoozeTimes = propertyVal > UINT8_MAX ? UINT8_MAX : static_cast<uint8_t>(propertyVal);
227             reminder->SetSnoozeTimes(static_cast<uint8_t>(snoozeTimes));
228         }
229     }
230 
231     // slotType
232     int32_t slotType = 0;
233     if (GetInt32(env, value, ReminderAgentNapi::SLOT_TYPE, slotType, false)) {
234         enum NotificationConstant::SlotType actureType = NotificationConstant::SlotType::OTHER;
235         if (!NotificationNapi::Common::SlotTypeJSToC(NotificationNapi::SlotType(slotType), actureType)) {
236             ANSR_LOGW("slot type not support.");
237             return nullptr;
238         }
239         reminder->SetSlotType(actureType);
240     }
241 
242     // wantAgent
243     GenWantAgent(env, value, reminder);
244 
245     // maxScreenWantAgent
246     GenMaxScreenWantAgent(env, value, reminder);
247 
248     // actionButtons
249     if (!GenActionButtons(env, value, reminder)) {
250         return nullptr;
251     }
252     return NotificationNapi::Common::NapiGetNull(env);
253 }
254 
GetStringUtf8(const napi_env & env,const napi_value & value,const char * propertyName,char * propertyVal,const int32_t size)255 bool ReminderCommon::GetStringUtf8(const napi_env &env, const napi_value &value,
256     const char* propertyName, char* propertyVal, const int32_t size)
257 {
258     bool hasProperty = false;
259     napi_value result = nullptr;
260     napi_valuetype valuetype = napi_undefined;
261     size_t strLen = 0;
262 
263     NAPI_CALL_BASE(env, napi_has_named_property(env, value, propertyName, &hasProperty), false);
264     if (hasProperty) {
265         napi_get_named_property(env, value, propertyName, &result);
266         NAPI_CALL_BASE(env, napi_typeof(env, result, &valuetype), false);
267         if (valuetype != napi_string) {
268             ANSR_LOGW("Wrong argument type:%{public}s. string expected.", propertyName);
269             return false;
270         }
271         NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, result, propertyVal, size - 1, &strLen), false);
272     }
273     return hasProperty;
274 }
275 
GetInt32(const napi_env & env,const napi_value & value,const char * propertyName,int32_t & propertyVal,bool isNecessary)276 bool ReminderCommon::GetInt32(const napi_env &env, const napi_value &value,
277     const char* propertyName, int32_t& propertyVal, bool isNecessary)
278 {
279     napi_value result = nullptr;
280     if (!GetPropertyValIfExist(env, value, propertyName, result)) {
281         if (isNecessary) {
282             ANSR_LOGW("Correct property %{public}s expected.", propertyName);
283         }
284         return false;
285     }
286     napi_get_value_int32(env, result, &propertyVal);
287     return true;
288 }
289 
GetInt64(const napi_env & env,const napi_value & value,const char * propertyName,int64_t & propertyVal)290 bool ReminderCommon::GetInt64(const napi_env &env, const napi_value &value,
291     const char* propertyName, int64_t& propertyVal)
292 {
293     napi_value result = nullptr;
294     if (!GetPropertyValIfExist(env, value, propertyName, result)) {
295         return false;
296     }
297     napi_get_value_int64(env, result, &propertyVal);
298     return true;
299 }
300 
GetPropertyValIfExist(const napi_env & env,const napi_value & value,const char * propertyName,napi_value & propertyVal)301 bool ReminderCommon::GetPropertyValIfExist(const napi_env &env, const napi_value &value,
302     const char* propertyName, napi_value& propertyVal)
303 {
304     napi_valuetype valuetype = napi_undefined;
305     if (propertyName == nullptr) {
306         propertyVal = value;
307     } else {
308         bool hasProperty = false;
309         NAPI_CALL_BASE(env, napi_has_named_property(env, value, propertyName, &hasProperty), false);
310         if (!hasProperty) {
311             return false;
312         }
313         napi_get_named_property(env, value, propertyName, &propertyVal);
314     }
315     NAPI_CALL_BASE(env, napi_typeof(env, propertyVal, &valuetype), false);
316     if (valuetype != napi_number) {
317         if (propertyName == nullptr) {
318             ANSR_LOGW("Wrong argument type. number expected.");
319         } else {
320             ANSR_LOGW("Wrong argument type:%{public}s, number expected.", propertyName);
321         }
322         return false;
323     }
324     return true;
325 }
326 
GetObject(const napi_env & env,const napi_value & value,const char * propertyName,napi_value & propertyVal)327 bool ReminderCommon::GetObject(const napi_env &env, const napi_value &value,
328     const char* propertyName, napi_value& propertyVal)
329 {
330     bool hasProperty = false;
331     napi_valuetype valuetype = napi_undefined;
332 
333     NAPI_CALL_BASE(env, napi_has_named_property(env, value, propertyName, &hasProperty), false);
334     if (!hasProperty) {
335         return false;
336     }
337     napi_get_named_property(env, value, propertyName, &propertyVal);
338     NAPI_CALL_BASE(env, napi_typeof(env, propertyVal, &valuetype), false);
339     if (valuetype != napi_object) {
340         ANSR_LOGW("Wrong argument type:%{public}s. object expected.", propertyName);
341         return false;
342     }
343     return true;
344 }
345 
CreateReminderTimer(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)346 napi_value ReminderCommon::CreateReminderTimer(
347     const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
348 {
349     int64_t propertyCountDownTime = 0;
350     if (!GetInt64(env, value, ReminderAgentNapi::TIMER_COUNT_DOWN_TIME, propertyCountDownTime)) {
351         ANSR_LOGW("Correct property %{public}s expected.", ReminderAgentNapi::TIMER_COUNT_DOWN_TIME);
352         return nullptr;
353     }
354 
355     auto countDownTimeInSeconds = static_cast<uint64_t>(propertyCountDownTime);
356     if (propertyCountDownTime <= 0 || countDownTimeInSeconds >= (UINT64_MAX / ReminderRequest::MILLI_SECONDS)) {
357         ANSR_LOGW("Create countDown reminder fail: designated %{public}s is illegal.",
358             ReminderAgentNapi::TIMER_COUNT_DOWN_TIME);
359         return nullptr;
360     }
361 
362     reminder = std::make_shared<ReminderRequestTimer>(countDownTimeInSeconds);
363     return NotificationNapi::Common::NapiGetNull(env);
364 }
365 
CreateReminderAlarm(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)366 napi_value ReminderCommon::CreateReminderAlarm(
367     const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
368 {
369     // hour
370     int32_t propertyHourVal = 0;
371     const int32_t maxHour = 23;
372     if (!GetInt32(env, value, ReminderAgentNapi::ALARM_HOUR, propertyHourVal, true)) {
373         return nullptr;
374     }
375 
376     // minute
377     int32_t propertyMinuteVal = 0;
378     const int32_t maxMinute = 59;
379     if (!GetInt32(env, value, ReminderAgentNapi::ALARM_MINUTE, propertyMinuteVal, true)) {
380         return nullptr;
381     }
382 
383     if ((propertyHourVal < 0) || (propertyHourVal > maxHour)) {
384         ANSR_LOGW("Create alarm reminder fail: designated %{public}s must between [0, 23].",
385             ReminderAgentNapi::ALARM_HOUR);
386         return nullptr;
387     }
388     if ((propertyMinuteVal < 0) || (propertyMinuteVal > maxMinute)) {
389         ANSR_LOGW("Create alarm reminder fail: designated %{public}s must between [0, 59].",
390             ReminderAgentNapi::ALARM_MINUTE);
391         return nullptr;
392     }
393 
394     // daysOfWeek
395     std::vector<uint8_t> daysOfWeek;
396     uint8_t maxDaysOfWeek = 7;
397     if (ParseInt32Array(env, value, ReminderAgentNapi::ALARM_DAYS_OF_WEEK, daysOfWeek, maxDaysOfWeek) == nullptr) {
398         return nullptr;
399     }
400     reminder = std::make_shared<ReminderRequestAlarm>(
401         static_cast<uint8_t>(propertyHourVal), static_cast<uint8_t>(propertyMinuteVal), daysOfWeek);
402     return NotificationNapi::Common::NapiGetNull(env);
403 }
404 
CreateReminderCalendar(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)405 napi_value ReminderCommon::CreateReminderCalendar(
406     const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
407 {
408     napi_value dateTimeObj = nullptr;
409     if (!GetObject(env, value, ReminderAgentNapi::CALENDAR_DATE_TIME, dateTimeObj)) {
410         ANSR_LOGW("Create calendar reminder fail: dateTime must be setted.");
411         return nullptr;
412     }
413 
414     // year month day hour minute second
415     int32_t propertyYearVal = 0;
416     int32_t propertyMonthVal = 0;
417     int32_t propertyDayVal = 0;
418     int32_t propertyHourVal = 0;
419     int32_t propertyMinteVal = 0;
420     if (!GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_YEAR, propertyYearVal, true) ||
421         !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_MONTH, propertyMonthVal, true) ||
422         !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_DAY, propertyDayVal, true) ||
423         !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_HOUR, propertyHourVal, true) ||
424         !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_MINUTE, propertyMinteVal, true)) {
425         return nullptr;
426     }
427     if (!CheckCalendarParams(propertyYearVal, propertyMonthVal, propertyDayVal,
428         propertyHourVal, propertyMinteVal)) {
429         return nullptr;
430     }
431 
432     // repeatMonth
433     std::vector<uint8_t> repeatMonths;
434     if (ParseInt32Array(env, value, ReminderAgentNapi::CALENDAR_REPEAT_MONTHS, repeatMonths,
435         ReminderRequestCalendar::MAX_MONTHS_OF_YEAR) == nullptr) {
436         return nullptr;
437     }
438 
439     // repeatDay
440     std::vector<uint8_t> repeatDays;
441     if (ParseInt32Array(env, value, ReminderAgentNapi::CALENDAR_REPEAT_DAYS, repeatDays,
442         ReminderRequestCalendar::MAX_DAYS_OF_MONTH) == nullptr) {
443         return nullptr;
444     }
445 
446     tm dateTime;
447     dateTime.tm_year = ReminderRequest::GetCTime(ReminderRequest::TimeTransferType::YEAR, propertyYearVal);
448     dateTime.tm_mon = ReminderRequest::GetCTime(ReminderRequest::TimeTransferType::MONTH, propertyMonthVal);
449     dateTime.tm_mday = propertyDayVal;
450     dateTime.tm_hour = propertyHourVal;
451     dateTime.tm_min = propertyMinteVal;
452     dateTime.tm_sec = 0;
453     dateTime.tm_isdst = -1;
454     reminder = std::make_shared<ReminderRequestCalendar>(dateTime, repeatMonths, repeatDays);
455     if (!(reminder->SetNextTriggerTime())) {
456         return nullptr;
457     }
458     return NotificationNapi::Common::NapiGetNull(env);
459 }
460 
CheckCalendarParams(const int32_t & year,const int32_t & month,const int32_t & day,const int32_t & hour,const int32_t & min)461 bool ReminderCommon::CheckCalendarParams(const int32_t &year, const int32_t &month, const int32_t &day,
462     const int32_t &hour, const int32_t &min)
463 {
464     if ((year < 0) || (year > UINT16_MAX)) {
465         ANSR_LOGW("Create calendar reminder fail: designated %{public}s must between [0, %{public}d]",
466             ReminderAgentNapi::CALENDAR_YEAR, UINT16_MAX);
467         return false;
468     }
469     if ((month < 1) || (month > ReminderRequestCalendar::MAX_MONTHS_OF_YEAR)) {
470         ANSR_LOGW("Create calendar reminder fail: designated %{public}s must between [1, %{public}hhu]",
471             ReminderAgentNapi::CALENDAR_MONTH, ReminderRequestCalendar::MAX_MONTHS_OF_YEAR);
472         return false;
473     }
474     uint8_t maxDaysOfMonth = ReminderRequestCalendar::GetDaysOfMonth(static_cast<uint16_t>(year), month);
475     if ((day < 1) || (day > maxDaysOfMonth)) {
476         ANSR_LOGW("Create calendar reminder fail: designated %{public}s must between [1, %{public}hhu]",
477             ReminderAgentNapi::CALENDAR_DAY, maxDaysOfMonth);
478         return false;
479     }
480     uint8_t maxHour = 23;
481     if (hour < 0 || hour > maxHour) {
482         ANSR_LOGW("Create calendar reminder fail: designated %{public}s must between [0, %{public}hhu]",
483             ReminderAgentNapi::CALENDAR_HOUR, maxHour);
484         return false;
485     }
486     uint8_t maxMinute = 59;
487     if (min < 0 || min > maxMinute) {
488         ANSR_LOGW("Create calendar reminder fail: designated %{public}s must between [0, %{public}hhu]",
489             ReminderAgentNapi::CALENDAR_MINUTE, maxMinute);
490         return false;
491     }
492     return true;
493 }
494 
ParseInt32Array(const napi_env & env,const napi_value & value,const char * propertyName,std::vector<uint8_t> & propertyVal,uint8_t maxLen)495 napi_value ReminderCommon::ParseInt32Array(const napi_env &env, const napi_value &value,
496     const char* propertyName, std::vector<uint8_t> &propertyVal, uint8_t maxLen)
497 {
498     napi_value result = nullptr;
499     if (!GetObject(env, value, propertyName, result)) {
500         return NotificationNapi::Common::NapiGetNull(env);
501     }
502     if (result != nullptr) {
503         bool isArray = false;
504         napi_is_array(env, result, &isArray);
505         if (!isArray) {
506             ANSR_LOGW("Property %{public}s is expected to be an array.", propertyName);
507             return nullptr;
508         }
509         uint32_t length = 0;
510         napi_get_array_length(env, result, &length);
511         if (length > maxLen) {
512             ANSR_LOGW("The max length of array of %{public}s is %{public}hhu.", propertyName, maxLen);
513             return nullptr;
514         }
515         napi_valuetype valuetype = napi_undefined;
516         for (size_t i = 0; i < length; i++) {
517             int32_t propertyDayVal = 10;
518             napi_value repeatDayVal = nullptr;
519             napi_get_element(env, result, i, &repeatDayVal);
520             NAPI_CALL(env, napi_typeof(env, repeatDayVal, &valuetype));
521             if (valuetype != napi_number) {
522                 ANSR_LOGW("%{public}s's element is expected to be number.", propertyName);
523                 return nullptr;
524             }
525             napi_get_value_int32(env, repeatDayVal, &propertyDayVal);
526             if (propertyDayVal < 1 || propertyDayVal > static_cast<int32_t>(maxLen)) {
527                 ANSR_LOGW("%{public}s's element must between [1, %{public}d].", propertyName, maxLen);
528                 return nullptr;
529             }
530             propertyVal.push_back(static_cast<uint8_t>(propertyDayVal));
531         }
532     }
533     return NotificationNapi::Common::NapiGetNull(env);
534 }
535 
PaddingCallbackPromiseInfo(const napi_env & env,const napi_ref & callback,CallbackPromiseInfo & info,napi_value & promise)536 void ReminderCommon::PaddingCallbackPromiseInfo(
537     const napi_env &env, const napi_ref &callback, CallbackPromiseInfo &info, napi_value &promise)
538 {
539     if (callback) {
540         info.callback = callback;
541         info.isCallback = true;
542     } else {
543         napi_deferred deferred = nullptr;
544         NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
545         info.deferred = deferred;
546         info.isCallback = false;
547     }
548 }
549 
HandleErrCode(const napi_env & env,int32_t errCode)550 void ReminderCommon::HandleErrCode(const napi_env &env, int32_t errCode)
551 {
552     if (errCode == ERR_OK) {
553         return;
554     }
555     std::string errCodeMsg = reminderErrCodeMsgMap[errCode];
556     napi_throw_error(env, std::to_string(errCode).c_str(), errCodeMsg.c_str());
557 }
558 
FindErrMsg(const napi_env & env,const int32_t errCode)559 std::string ReminderCommon::FindErrMsg(const napi_env &env, const int32_t errCode)
560 {
561     auto findMsg = reminderErrCodeMsgMap.find(errCode);
562     if (findMsg == reminderErrCodeMsgMap.end()) {
563         ANSR_LOGI("Inner error.");
564         return "Inner error.";
565     }
566     return reminderErrCodeMsgMap[errCode];
567 }
568 
ReturnCallbackPromise(const napi_env & env,const CallbackPromiseInfo & info,const napi_value & result,bool isThrow)569 void ReminderCommon::ReturnCallbackPromise(const napi_env &env, const CallbackPromiseInfo &info,
570     const napi_value &result, bool isThrow)
571 {
572     ANSR_LOGI("enter errorCode=%{public}d", info.errorCode);
573     if (info.isCallback) {
574         if (isThrow) {
575             SetCallback(env, info.callback, info.errorCode, result);
576         } else {
577             NotificationNapi::Common::SetCallback(env, info.callback, info.errorCode, result, false);
578         }
579     } else {
580         SetPromise(env, info, result);
581     }
582     ANSR_LOGI("end");
583 }
584 
SetCallback(const napi_env & env,const napi_ref & callbackIn,const int32_t & errCode,const napi_value & result)585 void ReminderCommon::SetCallback(
586     const napi_env &env, const napi_ref &callbackIn, const int32_t &errCode, const napi_value &result)
587 {
588     napi_value undefined = nullptr;
589     napi_get_undefined(env, &undefined);
590 
591     napi_value callback = nullptr;
592     napi_value resultout = nullptr;
593     napi_get_reference_value(env, callbackIn, &callback);
594     napi_value results[ASYNC_CALLBACK_PARAM_NUM] = {nullptr};
595     if (errCode == ERR_OK) {
596         results[0] = NotificationNapi::Common::NapiGetNull(env);
597     } else {
598         std::string errMsg = FindErrMsg(env, errCode);
599         results[0] = GetCallbackErrorValue(env, errCode, errMsg);
600     }
601     results[1] = result;
602     NAPI_CALL_RETURN_VOID(env,
603         napi_call_function(env, undefined, callback, ASYNC_CALLBACK_PARAM_NUM, &results[0], &resultout));
604 }
605 
GetCallbackErrorValue(napi_env env,const int32_t errCode,const std::string errMsg)606 napi_value ReminderCommon::GetCallbackErrorValue(napi_env env, const int32_t errCode, const std::string errMsg)
607 {
608     if (errCode == ERR_OK) {
609         return NotificationNapi::Common::NapiGetNull(env);
610     }
611     napi_value error = nullptr;
612     napi_value eCode = nullptr;
613     napi_value eMsg = nullptr;
614     NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
615     NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
616         errMsg.length(), &eMsg));
617     NAPI_CALL(env, napi_create_object(env, &error));
618     NAPI_CALL(env, napi_set_named_property(env, error, "code", eCode));
619     NAPI_CALL(env, napi_set_named_property(env, error, "message", eMsg));
620     return error;
621 }
622 
SetPromise(const napi_env & env,const CallbackPromiseInfo & info,const napi_value & result)623 napi_value  ReminderCommon::SetPromise(
624     const napi_env &env, const CallbackPromiseInfo &info, const napi_value &result)
625 {
626     if (info.errorCode == ERR_OK) {
627         napi_resolve_deferred(env, info.deferred, result);
628     } else {
629         std::string errMsg = FindErrMsg(env, info.errorCode);
630         if (errMsg == "") {
631             return nullptr;
632         }
633         napi_value error = nullptr;
634         napi_value eCode = nullptr;
635         napi_value eMsg = nullptr;
636         NAPI_CALL(env, napi_create_int32(env, info.errorCode, &eCode));
637         NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
638             errMsg.length(), &eMsg));
639         NAPI_CALL(env, napi_create_object(env, &error));
640         NAPI_CALL(env, napi_set_named_property(env, error, "data", eCode));
641         NAPI_CALL(env, napi_set_named_property(env, error, "code", eCode));
642         NAPI_CALL(env, napi_set_named_property(env, error, "message", eMsg));
643         napi_reject_deferred(env, info.deferred, error);
644     }
645     return result;
646 }
647 
JSParaError(const napi_env & env,const napi_ref & callback)648 napi_value ReminderCommon::JSParaError(const napi_env &env, const napi_ref &callback)
649 {
650     if (callback) {
651         SetCallback(env, callback, ERR_REMINDER_INVALID_PARAM, nullptr);
652         return NotificationNapi::Common::NapiGetNull(env);
653     } else {
654         napi_value promise = nullptr;
655         napi_deferred deferred = nullptr;
656         napi_create_promise(env, &deferred, &promise);
657 
658         napi_value res = nullptr;
659         napi_value eCode = nullptr;
660         napi_value eMsg = nullptr;
661         std::string errMsg = FindErrMsg(env, ERR_REMINDER_INVALID_PARAM);
662         NAPI_CALL(env, napi_create_int32(env, ERR_REMINDER_INVALID_PARAM, &eCode));
663         NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
664             errMsg.length(), &eMsg));
665         NAPI_CALL(env, napi_create_object(env, &res));
666         NAPI_CALL(env, napi_set_named_property(env, res, "data", eCode));
667         NAPI_CALL(env, napi_set_named_property(env, res, "code", eCode));
668         NAPI_CALL(env, napi_set_named_property(env, res, "message", eMsg));
669         napi_reject_deferred(env, deferred, res);
670         return promise;
671     }
672 }
673 }
674 }