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/publish.h"
17 
18 #include "ans_log_wrapper.h"
19 #include "common.h"
20 #include "napi_common.h"
21 #include "reminder_request.h"
22 #include "reminder_request_alarm.h"
23 #include "reminder_request_calendar.h"
24 #include "reminder_request_timer.h"
25 #include "securec.h"
26 
27 namespace OHOS {
28 namespace ReminderAgentNapi {
29 static const int32_t PUBLISH_PARAM_LEN = 2;
30 static const int32_t CANCEL_PARAM_LEN = 2;
31 static const int32_t CANCEL_ALL_PARAM_LEN = 1;
32 static const int32_t GET_VALID_PARAM_LEN = 1;
33 static const int32_t ADD_SLOT_PARAM_LEN = 2;
34 static constexpr int32_t ADD_EXCLUDE_DATE_PARAM_LEN = 2;
35 static constexpr int32_t DEL_EXCLUDE_DATE_PARAM_LEN = 1;
36 
37 struct AsyncCallbackInfo {
AsyncCallbackInfoOHOS::ReminderAgentNapi::AsyncCallbackInfo38     explicit AsyncCallbackInfo(napi_env napiEnv) : env(napiEnv) {}
~AsyncCallbackInfoOHOS::ReminderAgentNapi::AsyncCallbackInfo39     ~AsyncCallbackInfo()
40     {
41         if (asyncWork) {
42             napi_delete_async_work(env, asyncWork);
43             asyncWork = nullptr;
44         }
45         if (callback) {
46             napi_delete_reference(env, callback);
47             callback = nullptr;
48         }
49     }
50 
51     napi_env env = nullptr;
52     napi_async_work asyncWork = nullptr;
53     napi_ref callback = nullptr;
54     napi_value result = nullptr;
55     int32_t reminderId = -1;
56     uint64_t excludeDate = 0;
57     bool isThrow = false;
58     NotificationNapi::NotificationConstant::SlotType inType
59         = NotificationNapi::NotificationConstant::SlotType::CONTENT_INFORMATION;
60     std::shared_ptr<ReminderRequest> reminder = nullptr;
61     std::vector<sptr<ReminderRequest>> validReminders;
62     std::vector<uint64_t> excludeDates;
63     CallbackPromiseInfo info;
64 };
65 
66 struct Parameters {
67     int32_t reminderId = -1;
68     uint64_t excludeDate = 0;
69     int32_t errCode = ERR_OK;
70     NotificationNapi::NotificationConstant::SlotType inType
71         = NotificationNapi::NotificationConstant::SlotType::CONTENT_INFORMATION;
72     std::shared_ptr<ReminderRequest> reminder = nullptr;
73 };
74 
GetCallback(const napi_env &env, const napi_value &value, AsyncCallbackInfo &asyncCallbackInfo)75 napi_value GetCallback(const napi_env &env, const napi_value &value, AsyncCallbackInfo &asyncCallbackInfo)
76 {
77     napi_valuetype valuetype = napi_undefined;
78     NAPI_CALL(env, napi_typeof(env, value, &valuetype));
79     if (valuetype != napi_function) {
80         ANSR_LOGW("Wrong argument type. Function expected.");
81         return nullptr;
82     }
83     napi_create_reference(env, value, 1, &asyncCallbackInfo.callback);
84     return NotificationNapi::Common::NapiGetNull(env);
85 }
86 
SetAsynccallbackinfo(const napi_env &env, AsyncCallbackInfo& asynccallbackinfo, napi_value& promise)87 void SetAsynccallbackinfo(const napi_env &env, AsyncCallbackInfo& asynccallbackinfo, napi_value& promise)
88 {
89     ReminderCommon::PaddingCallbackPromiseInfo(
90         env, asynccallbackinfo.callback, asynccallbackinfo.info, promise);
91 }
92 
ParseParameters(const napi_env &env, const napi_callback_info &info, Parameters &params, AsyncCallbackInfo &asyncCallbackInfo, bool isThrow)93 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, Parameters &params,
94     AsyncCallbackInfo &asyncCallbackInfo, bool isThrow)
95 {
96     size_t argc = PUBLISH_PARAM_LEN;
97     napi_value argv[PUBLISH_PARAM_LEN] = {nullptr};
98     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
99     if (argc < 1) {
100         ANSR_LOGW("Wrong number of arguments");
101         if (isThrow) {
102             ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
103         }
104         return nullptr;
105     }
106 
107     // argv[1]: callback
108     if (argc >= PUBLISH_PARAM_LEN) {
109         if (GetCallback(env, argv[1], asyncCallbackInfo) == nullptr) {
110             ANSR_LOGW("[reminderAgent]GetCallbak returns nullptr");
111             if (isThrow) {
112                 ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
113             }
114             return nullptr;
115         }
116     }
117 
118     // argv[0] : reminderRequest
119     if (ReminderCommon::GetReminderRequest(env, argv[0], params.reminder) == nullptr) {
120         ANSR_LOGW("[reminderAgent]CreateReminder returns nullptr");
121         if (isThrow) {
122             ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
123         }
124         return nullptr;
125     }
126 
127     return NotificationNapi::Common::NapiGetNull(env);
128 }
129 
ParseSlotParameters(const napi_env &env, const napi_callback_info &info, Parameters &params, AsyncCallbackInfo &asyncCallbackInfo, bool isThrow)130 napi_value ParseSlotParameters(const napi_env &env, const napi_callback_info &info, Parameters &params,
131     AsyncCallbackInfo &asyncCallbackInfo, bool isThrow)
132 {
133     size_t argc = ADD_SLOT_PARAM_LEN;
134     napi_value argv[ADD_SLOT_PARAM_LEN] = {nullptr};
135     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
136     if (argc < 1) {
137         ANSR_LOGW("Wrong number of arguments");
138         if (isThrow) {
139             ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
140         }
141         return nullptr;
142     }
143 
144     // argv[1]: callback
145     if (argc >= ADD_SLOT_PARAM_LEN) {
146         if (GetCallback(env, argv[1], asyncCallbackInfo) == nullptr) {
147             ANSR_LOGW("GetCallbak returns nullptr");
148             if (isThrow) {
149                 ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
150             }
151             return nullptr;
152         }
153     }
154 
155     // argv[0] : notificationSlot
156     // slotType
157     const char* propertyKey = "type";
158     const char* propertyNewKey = "notificationType";
159     int32_t propertyVal = 0;
160     if (!ReminderCommon::GetInt32(env, argv[0], propertyKey, propertyVal, false) &&
161         !ReminderCommon::GetInt32(env, argv[0], propertyNewKey, propertyVal, false)) {
162         ANSR_LOGW("Failed to get valid slot type.");
163         params.errCode = ERR_REMINDER_INVALID_PARAM;
164         if (isThrow) {
165             ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
166         }
167         return nullptr;
168     }
169 
170     if (!NotificationNapi::AnsEnumUtil::SlotTypeJSToC(NotificationNapi::SlotType(propertyVal), params.inType)) {
171         ANSR_LOGW("Failed to get valid slot type");
172         if (isThrow) {
173             ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
174         }
175         return nullptr;
176     }
177     return NotificationNapi::Common::NapiGetNull(env);
178 }
179 
ParseCanCelParameter(const napi_env &env, const napi_callback_info &info, Parameters &params, AsyncCallbackInfo &asyncCallbackInfo, bool isThrow)180 napi_value ParseCanCelParameter(const napi_env &env, const napi_callback_info &info, Parameters &params,
181     AsyncCallbackInfo &asyncCallbackInfo, bool isThrow)
182 {
183     ANSR_LOGI("ParseCanCelParameter");
184     size_t argc = CANCEL_PARAM_LEN;
185     napi_value argv[CANCEL_PARAM_LEN] = {nullptr};
186     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
187     if (argc < 1) {
188         ANSR_LOGW("Wrong number of arguments");
189         if (isThrow) {
190             ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
191         }
192         return nullptr;
193     }
194 
195     // argv[1]: callback
196     if (argc >= CANCEL_PARAM_LEN) {
197         if (GetCallback(env, argv[1], asyncCallbackInfo) == nullptr) {
198             ANSR_LOGW("GetCallbak is nullptr");
199             if (isThrow) {
200                 ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
201             }
202             return nullptr;
203         }
204     }
205 
206     // argv[0]: reminder id
207     int32_t reminderId = -1;
208     if (!ReminderCommon::GetInt32(env, argv[0], nullptr, reminderId, true)) {
209         if (isThrow) {
210             ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
211         }
212         return nullptr;
213     }
214     if (reminderId < 0) {
215         ANSR_LOGW("Param id of cancels Reminder is illegal.");
216         if (isThrow) {
217             ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
218         }
219         return nullptr;
220     }
221     params.reminderId = reminderId;
222 
223     return NotificationNapi::Common::NapiGetNull(env);
224 }
225 
ParseCanCelAllParameter(const napi_env &env, const napi_callback_info &info, Parameters &params, AsyncCallbackInfo &asyncCallbackInfo, bool isThrow)226 napi_value ParseCanCelAllParameter(const napi_env &env, const napi_callback_info &info, Parameters &params,
227     AsyncCallbackInfo &asyncCallbackInfo, bool isThrow)
228 {
229     ANSR_LOGI("ParseCanCelAllParameter");
230     size_t argc = CANCEL_ALL_PARAM_LEN;
231     napi_value argv[CANCEL_ALL_PARAM_LEN] = {nullptr};
232     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
233 
234     // argv[0]: callback
235     if (argc >= CANCEL_ALL_PARAM_LEN) {
236         if (GetCallback(env, argv[0], asyncCallbackInfo) == nullptr) {
237             ANSR_LOGW("getCallbak is nullptr");
238             if (isThrow) {
239                 ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
240             }
241             return nullptr;
242         }
243     }
244     return NotificationNapi::Common::NapiGetNull(env);
245 }
246 
ParseGetValidParameter(const napi_env &env, const napi_callback_info &info, Parameters &params, AsyncCallbackInfo &asyncCallbackInfo, bool isThrow)247 napi_value ParseGetValidParameter(const napi_env &env, const napi_callback_info &info, Parameters &params,
248     AsyncCallbackInfo &asyncCallbackInfo, bool isThrow)
249 {
250     size_t argc = GET_VALID_PARAM_LEN;
251     napi_value argv[GET_VALID_PARAM_LEN] = {nullptr};
252     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
253 
254     // argv[0]: callback
255     if (argc >= GET_VALID_PARAM_LEN) {
256         if (GetCallback(env, argv[0], asyncCallbackInfo) == nullptr) {
257             ANSR_LOGW("getCallbak is nullptr");
258             if (isThrow) {
259                 ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
260             }
261             return nullptr;
262         }
263     }
264     return NotificationNapi::Common::NapiGetNull(env);
265 }
266 
DealErrorReturn(const napi_env &env, const napi_ref &callbackIn, const napi_value &result, bool isThrow)267 napi_value DealErrorReturn(const napi_env &env, const napi_ref &callbackIn, const napi_value &result, bool isThrow)
268 {
269     if (isThrow) {
270         return nullptr;
271     }
272     if (callbackIn) {
273         NotificationNapi::Common::SetCallback(env, callbackIn, ERR_REMINDER_INVALID_PARAM,
274             result, false);
275     }
276     return NotificationNapi::Common::JSParaError(env, callbackIn);
277 }
278 
CancelReminderInner(napi_env env, napi_callback_info info, bool isThrow)279 napi_value CancelReminderInner(napi_env env, napi_callback_info info, bool isThrow)
280 {
281     ANSR_LOGI("Cancel reminder");
282 
283     AsyncCallbackInfo *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfo(env);
284     if (!asynccallbackinfo) {
285         ANSR_LOGE("Low memory.");
286         return NotificationNapi::Common::NapiGetNull(env);
287     }
288     std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
289 
290     // param
291     Parameters params;
292     if (ParseCanCelParameter(env, info, params, *asynccallbackinfo, isThrow) == nullptr) {
293         return DealErrorReturn(env, asynccallbackinfo->callback, NotificationNapi::Common::NapiGetNull(env), isThrow);
294     }
295 
296     // promise
297     napi_value promise = nullptr;
298     SetAsynccallbackinfo(env, *asynccallbackinfo, promise);
299     asynccallbackinfo->reminderId = params.reminderId;
300     asynccallbackinfo->isThrow = isThrow;
301 
302     // resource name
303     napi_value resourceName = nullptr;
304     napi_create_string_latin1(env, "cancelReminder", NAPI_AUTO_LENGTH, &resourceName);
305 
306     // create and queue async work
307     napi_create_async_work(env,
308         nullptr,
309         resourceName,
310         [](napi_env env, void *data) {
311             ANSR_LOGI("Cancel napi_create_async_work start");
312             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfo *>(data);
313             if (asynccallbackinfo) {
314                 asynccallbackinfo->info.errorCode = ReminderHelper::CancelReminder(asynccallbackinfo->reminderId);
315             }
316         },
317         [](napi_env env, napi_status status, void *data) {
318             ANSR_LOGI("Cancel napi_create_async_work complete start");
319             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfo *>(data);
320             std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
321 
322             ReminderCommon::ReturnCallbackPromise(
323                 env, asynccallbackinfo->info, NotificationNapi::Common::NapiGetNull(env), asynccallbackinfo->isThrow);
324             ANSR_LOGI("Cancel napi_create_async_work complete end");
325         },
326         (void *)asynccallbackinfo,
327         &asynccallbackinfo->asyncWork);
328     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
329     callbackPtr.release();
330 
331     if (asynccallbackinfo->info.isCallback) {
332         return NotificationNapi::Common::NapiGetNull(env);
333     } else {
334         return promise;
335     }
336 }
337 
CancelReminderMgr(napi_env env, napi_callback_info info)338 napi_value CancelReminderMgr(napi_env env, napi_callback_info info)
339 {
340     return CancelReminderInner(env, info, true);
341 }
342 
CancelReminder(napi_env env, napi_callback_info info)343 napi_value CancelReminder(napi_env env, napi_callback_info info)
344 {
345     return CancelReminderInner(env, info, false);
346 }
347 
CancelAllRemindersInner(napi_env env, napi_callback_info info, bool isThrow)348 napi_value CancelAllRemindersInner(napi_env env, napi_callback_info info, bool isThrow)
349 {
350     ANSR_LOGI("Cancel all reminder");
351 
352     AsyncCallbackInfo *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfo(env);
353     if (!asynccallbackinfo) {
354         ANSR_LOGE("Low memory.");
355         return NotificationNapi::Common::NapiGetNull(env);
356     }
357     std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
358 
359     // param
360     Parameters params;
361     if (ParseCanCelAllParameter(env, info, params, *asynccallbackinfo, isThrow) == nullptr) {
362         return DealErrorReturn(env, asynccallbackinfo->callback, NotificationNapi::Common::NapiGetNull(env), isThrow);
363     }
364 
365     // promise
366     napi_value promise = nullptr;
367     SetAsynccallbackinfo(env, *asynccallbackinfo, promise);
368     asynccallbackinfo->isThrow = isThrow;
369 
370     // resource name
371     napi_value resourceName = nullptr;
372     napi_create_string_latin1(env, "cancelAllReminders", NAPI_AUTO_LENGTH, &resourceName);
373 
374     // create and queue async work
375     napi_create_async_work(env,
376         nullptr,
377         resourceName,
378         [](napi_env env, void *data) {
379             ANSR_LOGI("CancelAll napi_create_async_work start");
380             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfo *>(data);
381             if (asynccallbackinfo) {
382                 asynccallbackinfo->info.errorCode = ReminderHelper::CancelAllReminders();
383             }
384         },
385         [](napi_env env, napi_status status, void *data) {
386             ANSR_LOGD("CancelAll napi_create_async_work complete start");
387             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfo *>(data);
388             std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
389 
390             ReminderCommon::ReturnCallbackPromise(
391                 env, asynccallbackinfo->info, NotificationNapi::Common::NapiGetNull(env), asynccallbackinfo->isThrow);
392             ANSR_LOGD("CancelAll napi_create_async_work complete end");
393         },
394         (void *)asynccallbackinfo,
395         &asynccallbackinfo->asyncWork);
396     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
397     callbackPtr.release();
398 
399     if (asynccallbackinfo->info.isCallback) {
400         return NotificationNapi::Common::NapiGetNull(env);
401     } else {
402         return promise;
403     }
404 }
405 
CancelAllRemindersMgr(napi_env env, napi_callback_info info)406 napi_value CancelAllRemindersMgr(napi_env env, napi_callback_info info)
407 {
408     return CancelAllRemindersInner(env, info, true);
409 }
410 
CancelAllReminders(napi_env env, napi_callback_info info)411 napi_value CancelAllReminders(napi_env env, napi_callback_info info)
412 {
413     return CancelAllRemindersInner(env, info, false);
414 }
415 
ParseReminderTimer(const napi_env &env, const ReminderRequest &reminder, napi_value &result)416 void ParseReminderTimer(const napi_env &env, const ReminderRequest &reminder, napi_value &result)
417 {
418     napi_value value = nullptr;
419     ReminderRequestTimer& timer = (ReminderRequestTimer&)reminder;
420     napi_create_uint32(env, timer.GetInitInfo(), &value);
421     napi_set_named_property(env, result, TIMER_COUNT_DOWN_TIME, value);
422 }
423 
ParseReminderAlarm(const napi_env &env, const ReminderRequest &reminder, napi_value &result)424 void ParseReminderAlarm(const napi_env &env, const ReminderRequest &reminder, napi_value &result)
425 {
426     // hour
427     napi_value value = nullptr;
428     ReminderRequestAlarm& alarm = (ReminderRequestAlarm&)reminder;
429     napi_create_uint32(env, static_cast<uint32_t>(alarm.GetHour()), &value);
430     napi_set_named_property(env, result, ALARM_HOUR, value);
431 
432     // minute
433     napi_create_uint32(env, static_cast<uint32_t>(alarm.GetMinute()), &value);
434     napi_set_named_property(env, result, ALARM_MINUTE, value);
435 
436     // daysOfWeek
437     napi_create_array(env, &value);
438     napi_set_named_property(env, result, REPEAT_DAYS_OF_WEEK, value);
439     int32_t count = 0;
440     for (auto day : reminder.GetDaysOfWeek()) {
441         if (day) {
442             napi_value napiDay = nullptr;
443             napi_create_int32(env, day, &napiDay);
444             napi_set_element(env, value, count, napiDay);
445             count++;
446         }
447     }
448 }
449 
ParseReminderCalendar(const napi_env &env, const ReminderRequest &reminder, napi_value &result)450 void ParseReminderCalendar(const napi_env &env, const ReminderRequest &reminder, napi_value &result)
451 {
452     // dateTime
453     napi_value value = nullptr;
454     ReminderRequestCalendar& calendar = (ReminderRequestCalendar&)reminder;
455     napi_value dateTime = nullptr;
456     napi_create_object(env, &dateTime);
457     napi_set_named_property(env, result, CALENDAR_DATE_TIME, dateTime);
458 
459     napi_create_uint32(env, static_cast<uint32_t>(calendar.GetYear()), &value);
460     napi_set_named_property(env, dateTime, CALENDAR_YEAR, value);
461     napi_create_uint32(env, static_cast<uint32_t>(calendar.GetMonth()), &value);
462     napi_set_named_property(env, dateTime, CALENDAR_MONTH, value);
463     napi_create_uint32(env, static_cast<uint32_t>(calendar.GetDay()), &value);
464     napi_set_named_property(env, dateTime, CALENDAR_DAY, value);
465     napi_create_uint32(env, static_cast<uint32_t>(calendar.GetHour()), &value);
466     napi_set_named_property(env, dateTime, CALENDAR_HOUR, value);
467     napi_create_uint32(env, static_cast<uint32_t>(calendar.GetMinute()), &value);
468     napi_set_named_property(env, dateTime, CALENDAR_MINUTE, value);
469     napi_create_uint32(env, static_cast<uint32_t>(calendar.GetSecond()), &value);
470     napi_set_named_property(env, dateTime, CALENDAR_SECOND, value);
471 
472     // repeatMonths
473     napi_create_array(env, &value);
474     napi_set_named_property(env, result, CALENDAR_REPEAT_MONTHS, value);
475     int32_t count = 0;
476     for (auto month : calendar.GetRepeatMonths()) {
477         napi_value napiDay = nullptr;
478         napi_create_int32(env, month, &napiDay);
479         napi_set_element(env, value, count, napiDay);
480         count++;
481     }
482 
483     // repeatDays
484     napi_create_array(env, &value);
485     napi_set_named_property(env, result, CALENDAR_REPEAT_DAYS, value);
486     count = 0;
487     for (auto day : calendar.GetRepeatDays()) {
488         napi_value napiDay = nullptr;
489         napi_create_int32(env, day, &napiDay);
490         napi_set_element(env, value, count, napiDay);
491         count++;
492     }
493 
494     // daysOfWeek
495     napi_create_array(env, &value);
496     napi_set_named_property(env, result, REPEAT_DAYS_OF_WEEK, value);
497     count = 0;
498     for (auto day : reminder.GetDaysOfWeek()) {
499         if (day) {
500             napi_value napiDay = nullptr;
501             napi_create_int32(env, day, &napiDay);
502             napi_set_element(env, value, count, napiDay);
503             count++;
504         }
505     }
506 }
507 
ParseReminder( const napi_env &env, const ReminderRequest::ReminderType &type, const ReminderRequest &reminder, napi_value &result)508 void ParseReminder(
509     const napi_env &env, const ReminderRequest::ReminderType &type, const ReminderRequest &reminder, napi_value &result)
510 {
511     switch (type) {
512         case ReminderRequest::ReminderType::TIMER: {
513             ParseReminderTimer(env, reminder, result);
514             break;
515         }
516         case ReminderRequest::ReminderType::ALARM: {
517             ParseReminderAlarm(env, reminder, result);
518             break;
519         }
520         case ReminderRequest::ReminderType::CALENDAR: {
521             ParseReminderCalendar(env, reminder, result);
522             break;
523         }
524         default: {
525             break;
526         }
527     }
528 }
529 
ParseArray(const napi_env &env, std::vector<std::string>& temp, napi_value &jsObject)530 napi_status ParseArray(const napi_env &env, std::vector<std::string>& temp, napi_value &jsObject)
531 {
532     if (temp.size() <= INDEX_VALUE) {
533         return napi_invalid_arg;
534     }
535     // key
536     napi_value keyInfo = nullptr;
537     napi_create_string_utf8(env, temp[INDEX_KEY].c_str(), NAPI_AUTO_LENGTH, &keyInfo);
538     // value
539     napi_value valueInfo = nullptr;
540     napi_status status = napi_ok;
541     if (temp[INDEX_TYPE] == "string") {
542         napi_create_string_utf8(env, temp[INDEX_VALUE].c_str(), NAPI_AUTO_LENGTH, &valueInfo);
543     } else if (temp[INDEX_TYPE] == "double") {
544         napi_create_double(env, std::stod(temp[INDEX_VALUE]), &valueInfo);
545     } else if (temp[INDEX_TYPE] == "bool") {
546         bool valueBool = false;
547         if (temp[INDEX_VALUE] == "1" || temp[INDEX_VALUE] == "true" || temp[INDEX_VALUE] == "True") {
548             valueBool = true;
549         }
550         napi_get_boolean(env, valueBool, &valueInfo);
551     } else if (temp[INDEX_TYPE] == "null") {
552         napi_get_null(env, &valueInfo);
553     } else if (temp[INDEX_TYPE] == "vector") {
554         std::vector<std::string> arr = ReminderRequest::StringSplit(temp[INDEX_VALUE],
555             ReminderRequest::SEP_BUTTON_VALUE_BLOB);
556         std::vector<uint8_t> value;
557         for (auto &num : arr) {
558             value.push_back(static_cast<uint8_t>(std::stoi(num)));
559         }
560         // vector<uint8_t> to napi_value
561         if (value.size() <= 0) {
562             return napi_invalid_arg;
563         }
564         void* data = nullptr;
565         napi_value buffer = nullptr;
566         status = napi_create_arraybuffer(env, value.size(), &data, &buffer);
567         if (status != napi_ok) {
568             ANSR_LOGW("create array buffer failed!");
569             return napi_invalid_arg;
570         }
571         if (memcpy_s(data, value.size(), value.data(), value.size()) != EOK) {
572             ANSR_LOGW("memcpy_s not EOK");
573             return napi_invalid_arg;
574         }
575         status = napi_create_typedarray(env, napi_uint8_array, value.size(), buffer, 0, &valueInfo);
576         if (status != napi_ok) {
577             ANSR_LOGW("napi_create_typedarray failed!");
578             return napi_invalid_arg;
579         }
580     }
581     // write keyInfo and valueInfo
582     napi_set_property(env, jsObject, keyInfo, valueInfo);
583     return status;
584 }
585 
586 // parse equalTo,valueBucket
ParseValueBucket(const napi_env &env, std::vector<std::string> valueBucketVector, napi_value &result, const std::string &arrayName)587 void ParseValueBucket(const napi_env &env, std::vector<std::string> valueBucketVector,
588     napi_value &result, const std::string &arrayName)
589 {
590     // create array
591     napi_value array = nullptr;
592     napi_create_array(env, &array);
593     napi_set_named_property(env, result, arrayName.c_str(), array);
594     int32_t index = 0;
595     // write equalTo or valuesBucket
596     for (auto &str : valueBucketVector) {
597         std::vector<std::string> temp = ReminderRequest::StringSplit(str, ReminderRequest::SEP_BUTTON_VALUE);
598         if (temp.size() <= INDEX_VALUE) {
599             continue;
600         }
601         // key:value
602         napi_value jsObject = nullptr;
603         napi_create_object(env, &jsObject);
604         napi_status status = ParseArray(env, temp, jsObject);
605         if (status != napi_ok) {
606             continue;
607         }
608         // write object to array
609         napi_set_element(env, array, index++, jsObject);
610     }
611 }
612 
613 // parse uri,equalTo,valuesBucket  c++ -> js
ParseButtonDataShareUpdate(const napi_env &env, std::shared_ptr<ReminderRequest::ButtonDataShareUpdate> &dataShareUpdate, napi_value &result)614 void ParseButtonDataShareUpdate(const napi_env &env,
615     std::shared_ptr<ReminderRequest::ButtonDataShareUpdate> &dataShareUpdate, napi_value &result)
616 {
617     // create obj
618     napi_value buttonDataShareUpdate = nullptr;
619     napi_create_object(env, &buttonDataShareUpdate);
620     napi_set_named_property(env, result, BUTTON_DATA_SHARE_UPDATE, buttonDataShareUpdate);
621     // uri
622     napi_value uriInfo = nullptr;
623     napi_create_string_utf8(env, dataShareUpdate->uri.c_str(), NAPI_AUTO_LENGTH, &uriInfo);
624     napi_set_named_property(env, buttonDataShareUpdate, BUTTON_DATA_SHARE_UPDATE_URI, uriInfo);
625     // equalTo
626     std::vector<std::string> equalToVector = ReminderRequest::StringSplit(dataShareUpdate->equalTo,
627         ReminderRequest::SEP_BUTTON_VALUE_TYPE);
628     ParseValueBucket(env, equalToVector, buttonDataShareUpdate, BUTTON_DATA_SHARE_UPDATE_EQUALTO);
629     // valuesBucket
630     std::vector<std::string> valuesBucketVector = ReminderRequest::StringSplit(dataShareUpdate->valuesBucket,
631         ReminderRequest::SEP_BUTTON_VALUE_TYPE);
632     ParseValueBucket(env, valuesBucketVector, buttonDataShareUpdate, BUTTON_DATA_SHARE_UPDATE_VALUE);
633 }
634 
ParseActionButtons(const napi_env &env, ReminderRequest &reminder, napi_value &result)635 void ParseActionButtons(const napi_env &env, ReminderRequest &reminder, napi_value &result)
636 {
637     auto actionButtonsMap = reminder.GetActionButtons();
638 
639     // create array
640     napi_value array = nullptr;
641     napi_create_array(env, &array);
642     napi_set_named_property(env, result, ACTION_BUTTON, array);
643     int32_t index = 0;
644     for (std::map<ReminderRequest::ActionButtonType, ReminderRequest::ActionButtonInfo>::iterator it
645         = actionButtonsMap.begin(); it != actionButtonsMap.end(); ++it) {
646         // create obj
647         napi_value actionButton = nullptr;
648         napi_create_object(env, &actionButton);
649 
650         napi_value buttonInfo = nullptr;
651         napi_create_uint32(env, static_cast<int32_t>(it->second.type), &buttonInfo);
652         napi_set_named_property(env, actionButton, ACTION_BUTTON_TYPE, buttonInfo);
653         napi_create_string_utf8(env, (it->second.title).c_str(), NAPI_AUTO_LENGTH, &buttonInfo);
654         napi_set_named_property(env, actionButton, ACTION_BUTTON_TITLE, buttonInfo);
655         napi_create_string_utf8(env, (it->second.resource).c_str(), NAPI_AUTO_LENGTH, &buttonInfo);
656         napi_set_named_property(env, actionButton, ACTION_BUTTON_RESOURCE, buttonInfo);
657 
658         // create obj
659         napi_value wantAgentInfo = nullptr;
660         napi_create_object(env, &wantAgentInfo);
661         napi_set_named_property(env, actionButton, WANT_AGENT, wantAgentInfo);
662 
663         if (it->second.type == ReminderRequest::ActionButtonType::CUSTOM) {
664             napi_value info = nullptr;
665             napi_create_string_utf8(env, (it->second.wantAgent->pkgName).c_str(), NAPI_AUTO_LENGTH, &info);
666             napi_set_named_property(env, wantAgentInfo, WANT_AGENT_PKG, info);
667             napi_create_string_utf8(env, (it->second.wantAgent->abilityName).c_str(), NAPI_AUTO_LENGTH, &info);
668             napi_set_named_property(env, wantAgentInfo, WANT_AGENT_ABILITY, info);
669             napi_create_string_utf8(env, (reminder.GetCustomButtonUri()).c_str(), NAPI_AUTO_LENGTH, &info);
670             napi_set_named_property(env, wantAgentInfo, BUTTON_WANT_AGENT_URI, info);
671         }
672         // Parse ButtonDataShareUpdate
673         if (it->second.type != ReminderRequest::ActionButtonType::INVALID) {
674             ParseButtonDataShareUpdate(env, it->second.dataShareUpdate, actionButton);
675         }
676         // add obj to array
677         napi_set_element(env, array, index, actionButton);
678         index++;
679     }
680 }
681 
ParseWantAgent(const napi_env &env, ReminderRequest &reminder, napi_value &result)682 void ParseWantAgent(const napi_env &env, ReminderRequest &reminder, napi_value &result)
683 {
684     // create obj
685     napi_value wantAgentInfo = nullptr;
686     napi_create_object(env, &wantAgentInfo);
687     napi_set_named_property(env, result, WANT_AGENT, wantAgentInfo);
688 
689     napi_value info = nullptr;
690     napi_create_string_utf8(env, (reminder.GetWantAgentInfo()->pkgName).c_str(), NAPI_AUTO_LENGTH, &info);
691     napi_set_named_property(env, wantAgentInfo, WANT_AGENT_PKG, info);
692     napi_create_string_utf8(env, (reminder.GetWantAgentInfo()->abilityName).c_str(), NAPI_AUTO_LENGTH, &info);
693     napi_set_named_property(env, wantAgentInfo, WANT_AGENT_ABILITY, info);
694 
695     napi_create_string_utf8(env, (reminder.GetWantAgentInfo()->uri).c_str(), NAPI_AUTO_LENGTH, &info);
696     napi_set_named_property(env, wantAgentInfo, WANT_AGENT_URI, info);
697 
698     napi_value params = AppExecFwk::WrapWantParams(env, reminder.GetWantAgentInfo()->parameters);
699     napi_set_named_property(env, wantAgentInfo, WANT_AGENT_PARAMETERS, params);
700 }
701 
ParseMaxScreenWantAgent(const napi_env &env, ReminderRequest &reminder, napi_value &result)702 void ParseMaxScreenWantAgent(const napi_env &env, ReminderRequest &reminder, napi_value &result)
703 {
704     // create obj
705     napi_value maxScreenWantAgentInfo = nullptr;
706     napi_create_object(env, &maxScreenWantAgentInfo);
707     napi_set_named_property(env, result, MAX_SCREEN_WANT_AGENT, maxScreenWantAgentInfo);
708 
709     napi_value info = nullptr;
710     napi_create_string_utf8(env, (reminder.GetMaxScreenWantAgentInfo()->pkgName).c_str(), NAPI_AUTO_LENGTH, &info);
711     napi_set_named_property(env, maxScreenWantAgentInfo, MAX_SCREEN_WANT_AGENT_PKG, info);
712     napi_create_string_utf8(env, (reminder.GetMaxScreenWantAgentInfo()->abilityName).c_str(), NAPI_AUTO_LENGTH, &info);
713     napi_set_named_property(env, maxScreenWantAgentInfo, MAX_SCREEN_WANT_AGENT_ABILITY, info);
714 }
715 
SetValidReminder(const napi_env &env, ReminderRequest &reminder, napi_value &result)716 napi_value SetValidReminder(const napi_env &env, ReminderRequest &reminder, napi_value &result)
717 {
718     ANSR_LOGI("enter");
719     napi_value value = nullptr;
720 
721     napi_create_string_utf8(env, reminder.Dump().c_str(), NAPI_AUTO_LENGTH, &value);
722     napi_set_named_property(env, result, "reminder", value);
723 
724     // type
725     ReminderRequest::ReminderType type = reminder.GetReminderType();
726     napi_create_int32(env, static_cast<int32_t>(type), &value);
727     napi_set_named_property(env, result, REMINDER_TYPE, value);
728 
729     // reminder
730     ParseReminder(env, type, reminder, result);
731 
732     // title
733     napi_create_string_utf8(env, reminder.GetTitle().c_str(), NAPI_AUTO_LENGTH, &value);
734     napi_set_named_property(env, result, TITLE, value);
735 
736     // content
737     napi_create_string_utf8(env, reminder.GetContent().c_str(), NAPI_AUTO_LENGTH, &value);
738     napi_set_named_property(env, result, CONTENT, value);
739 
740     // expiredContent
741     napi_create_string_utf8(env, reminder.GetExpiredContent().c_str(), NAPI_AUTO_LENGTH, &value);
742     napi_set_named_property(env, result, EXPIRED_CONTENT, value);
743 
744     // snoozeContent
745     napi_create_string_utf8(env, reminder.GetSnoozeContent().c_str(), NAPI_AUTO_LENGTH, &value);
746     napi_set_named_property(env, result, SNOOZE_CONTENT, value);
747 
748     // ringDuration
749     napi_create_int64(env, reminder.GetRingDuration(), &value);
750     napi_set_named_property(env, result, RING_DURATION, value);
751 
752     // timeInterval
753     napi_create_int64(env, reminder.GetTimeInterval(), &value);
754     napi_set_named_property(env, result, TIME_INTERVAL, value);
755 
756     // notificationId
757     napi_create_int32(env, reminder.GetNotificationId(), &value);
758     napi_set_named_property(env, result, NOTIFICATION_ID, value);
759 
760     // snoozeTimes
761     napi_create_int32(env, reminder.GetSnoozeTimes(), &value);
762     napi_set_named_property(env, result, SNOOZE_TIMES, value);
763 
764     // tapDismissed
765     napi_get_boolean(env, reminder.IsTapDismissed(), &value);
766     napi_set_named_property(env, result, TAPDISMISSED, value);
767 
768     // autoDeletedTime
769     napi_create_int64(env, reminder.GetAutoDeletedTime(), &value);
770     napi_set_named_property(env, result, AUTODELETEDTIME, value);
771 
772     // slotType
773     NotificationNapi::SlotType jsSlotType;
774     if (reminder.GetSlotType() == NotificationConstant::SlotType::OTHER) {
775         NotificationNapi::AnsEnumUtil::SlotTypeCToJS(NotificationConstant::SlotType::SOCIAL_COMMUNICATION, jsSlotType);
776     } else {
777         NotificationNapi::AnsEnumUtil::SlotTypeCToJS(reminder.GetSlotType(), jsSlotType);
778     }
779     napi_create_int32(env, static_cast<int32_t>(jsSlotType), &value);
780     napi_set_named_property(env, result, SLOT_TYPE, value);
781 
782     // snoozeSlotType
783     NotificationNapi::SlotType jsSnoozeSlotType;
784     NotificationNapi::AnsEnumUtil::SlotTypeCToJS(reminder.GetSnoozeSlotType(), jsSnoozeSlotType);
785     napi_create_int32(env, static_cast<int32_t>(jsSnoozeSlotType), &value);
786     napi_set_named_property(env, result, SNOOZE_SLOT_TYPE, value);
787 
788     // group id
789     napi_create_string_utf8(env, reminder.GetGroupId().c_str(), NAPI_AUTO_LENGTH, &value);
790     napi_set_named_property(env, result, GROUP_ID, value);
791 
792     // custom ring uri
793     napi_create_string_utf8(env, reminder.GetCustomRingUri().c_str(), NAPI_AUTO_LENGTH, &value);
794     napi_set_named_property(env, result, CUSTOM_RING_URI, value);
795 
796     // wantAgent
797     ParseWantAgent(env, reminder, result);
798 
799     // maxScreenWantAgent
800     ParseMaxScreenWantAgent(env, reminder, result);
801 
802     // actionButtons
803     ParseActionButtons(env, reminder, result);
804 
805     return NotificationNapi::Common::NapiGetBoolean(env, true);
806 }
807 
GetValidRemindersInner(napi_env env, const std::vector<sptr<ReminderRequest>>& validReminders, napi_value& arr)808 void GetValidRemindersInner(napi_env env, const std::vector<sptr<ReminderRequest>>& validReminders, napi_value& arr)
809 {
810     int32_t count = 0;
811     napi_create_array(env, &arr);
812     for (auto reminder : validReminders) {
813         if (reminder == nullptr) {
814             ANSR_LOGW("reminder is null");
815             continue;
816         }
817         napi_value result = nullptr;
818         napi_create_object(env, &result);
819         if (!SetValidReminder(env, *reminder, result)) {
820             ANSR_LOGW("Set reminder object failed");
821             continue;
822         }
823         napi_set_element(env, arr, count, result);
824         count++;
825     }
826     ANSR_LOGI("GetValid reminders count = %{public}d", count);
827 }
828 
GetAllValidRemindersInner(napi_env env, const std::vector<sptr<ReminderRequest>>& validReminders, napi_value& arr)829 void GetAllValidRemindersInner(napi_env env, const std::vector<sptr<ReminderRequest>>& validReminders, napi_value& arr)
830 {
831     int32_t count = 0;
832     napi_create_array(env, &arr);
833     for (auto reminder : validReminders) {
834         if (reminder == nullptr) {
835             ANSR_LOGW("reminder is null");
836             continue;
837         }
838         napi_value result = nullptr;
839         napi_create_object(env, &result);
840         napi_value reminderReq = nullptr;
841         napi_create_object(env, &reminderReq);
842         napi_set_named_property(env, result, REMINDER_INFO_REMINDER_REQ, reminderReq);
843         if (!SetValidReminder(env, *reminder, reminderReq)) {
844             ANSR_LOGW("Set reminder object failed");
845             continue;
846         }
847         napi_value reminderId = nullptr;
848         napi_create_int32(env, reminder->GetReminderId(), &reminderId);
849         napi_set_named_property(env, result, REMINDER_INFO_REMINDER_ID, reminderId);
850         napi_set_element(env, arr, count, result);
851         count++;
852     }
853     ANSR_LOGI("GetAllValid reminders count = %{public}d", count);
854 }
855 
InnerGetValidReminders(napi_env env, napi_callback_info info, bool isThrow)856 napi_value InnerGetValidReminders(napi_env env, napi_callback_info info, bool isThrow)
857 {
858     ANSR_LOGI("Get valid reminders");
859 
860     AsyncCallbackInfo *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfo(env);
861     if (!asynccallbackinfo) {
862         ANSR_LOGE("Low memory.");
863         return NotificationNapi::Common::NapiGetNull(env);
864     }
865     std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
866 
867     // param
868     Parameters params;
869     if (ParseGetValidParameter(env, info, params, *asynccallbackinfo, isThrow) == nullptr) {
870         return DealErrorReturn(env, asynccallbackinfo->callback, NotificationNapi::Common::NapiGetNull(env), isThrow);
871     }
872 
873     // promise
874     napi_value promise = nullptr;
875     SetAsynccallbackinfo(env, *asynccallbackinfo, promise);
876     asynccallbackinfo->isThrow = isThrow;
877 
878     // resource name
879     napi_value resourceName = nullptr;
880     napi_create_string_latin1(env, "getValidReminders", NAPI_AUTO_LENGTH, &resourceName);
881 
882     // create and start async work
883     napi_create_async_work(env,
884         nullptr,
885         resourceName,
886         [](napi_env env, void *data) {
887             ANSR_LOGI("GetValid reminders napi_create_async_work start");
888             AsyncCallbackInfo *asynccallbackinfo = static_cast<AsyncCallbackInfo *>(data);
889             if (asynccallbackinfo) {
890                 asynccallbackinfo->info.errorCode = ReminderHelper::GetValidReminders(
891                     asynccallbackinfo->validReminders);
892             }
893         },
894         [](napi_env env, napi_status status, void *data) {
895             AsyncCallbackInfo *asynccallbackinfo = static_cast<AsyncCallbackInfo *>(data);
896             std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
897 
898             if (asynccallbackinfo) {
899                 if (asynccallbackinfo->info.errorCode != ERR_OK) {
900                     asynccallbackinfo->result = NotificationNapi::Common::NapiGetNull(env);
901                 } else {
902                     GetValidRemindersInner(env, asynccallbackinfo->validReminders, asynccallbackinfo->result);
903                 }
904 
905                 ReminderCommon::ReturnCallbackPromise(
906                     env, asynccallbackinfo->info, asynccallbackinfo->result, asynccallbackinfo->isThrow);
907             }
908         },
909         (void *)asynccallbackinfo,
910         &asynccallbackinfo->asyncWork);
911     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
912     callbackPtr.release();
913 
914     if (asynccallbackinfo->info.isCallback) {
915         return NotificationNapi::Common::NapiGetNull(env);
916     } else {
917         return promise;
918     }
919 }
920 
InnerGetAllValidReminders(napi_env env, napi_callback_info info, bool isThrow)921 napi_value InnerGetAllValidReminders(napi_env env, napi_callback_info info, bool isThrow)
922 {
923     ANSR_LOGI("Get all valid reminders");
924 
925     AsyncCallbackInfo *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfo(env);
926     if (!asynccallbackinfo) {
927         ANSR_LOGE("Low memory.");
928         return NotificationNapi::Common::NapiGetNull(env);
929     }
930     std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
931 
932     Parameters params;
933     if (ParseGetValidParameter(env, info, params, *asynccallbackinfo, isThrow) == nullptr) {
934         return DealErrorReturn(env, asynccallbackinfo->callback, NotificationNapi::Common::NapiGetNull(env), isThrow);
935     }
936 
937     napi_value promise = nullptr;
938     SetAsynccallbackinfo(env, *asynccallbackinfo, promise);
939     asynccallbackinfo->isThrow = isThrow;
940 
941     napi_value resourceName = nullptr;
942     napi_create_string_latin1(env, "getAllValidReminders", NAPI_AUTO_LENGTH, &resourceName);
943 
944     napi_create_async_work(env, nullptr, resourceName,
945         [](napi_env env, void *data) {
946             ANSR_LOGI("GetAllValid reminders napi_create_async_work start");
947             AsyncCallbackInfo *asynccallbackinfo = static_cast<AsyncCallbackInfo *>(data);
948             if (asynccallbackinfo) {
949                 asynccallbackinfo->info.errorCode = ReminderHelper::GetValidReminders(
950                     asynccallbackinfo->validReminders);
951             }
952         },
953         [](napi_env env, napi_status status, void *data) {
954             AsyncCallbackInfo *asynccallbackinfo = static_cast<AsyncCallbackInfo *>(data);
955             std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
956 
957             if (asynccallbackinfo) {
958                 if (asynccallbackinfo->info.errorCode != ERR_OK) {
959                     asynccallbackinfo->result = NotificationNapi::Common::NapiGetNull(env);
960                 } else {
961                     GetAllValidRemindersInner(env, asynccallbackinfo->validReminders, asynccallbackinfo->result);
962                 }
963 
964                 ReminderCommon::ReturnCallbackPromise(
965                     env, asynccallbackinfo->info, asynccallbackinfo->result, asynccallbackinfo->isThrow);
966             }
967         },
968         (void *)asynccallbackinfo,
969         &asynccallbackinfo->asyncWork);
970     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
971     callbackPtr.release();
972 
973     if (asynccallbackinfo->info.isCallback) {
974         return NotificationNapi::Common::NapiGetNull(env);
975     } else {
976         return promise;
977     }
978 }
979 
GetValidRemindersMgr(napi_env env, napi_callback_info info)980 napi_value GetValidRemindersMgr(napi_env env, napi_callback_info info)
981 {
982     return InnerGetValidReminders(env, info, true);
983 }
984 
GetAllValidRemindersMgr(napi_env env, napi_callback_info info)985 napi_value GetAllValidRemindersMgr(napi_env env, napi_callback_info info)
986 {
987     return InnerGetAllValidReminders(env, info, true);
988 }
989 
GetValidReminders(napi_env env, napi_callback_info info)990 napi_value GetValidReminders(napi_env env, napi_callback_info info)
991 {
992     return InnerGetValidReminders(env, info, false);
993 }
994 
GetAllValidReminders(napi_env env, napi_callback_info info)995 napi_value GetAllValidReminders(napi_env env, napi_callback_info info)
996 {
997     return InnerGetAllValidReminders(env, info, false);
998 }
999 
PublishReminderInner(napi_env env, napi_callback_info info, bool isThrow)1000 napi_value PublishReminderInner(napi_env env, napi_callback_info info, bool isThrow)
1001 {
1002     ANSR_LOGI("PublishReminder");
1003 
1004     AsyncCallbackInfo *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfo(env);
1005     if (!asynccallbackinfo) {
1006         ANSR_LOGE("Low memory.");
1007         return NotificationNapi::Common::NapiGetNull(env);
1008     }
1009     std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
1010 
1011     // param
1012     Parameters params;
1013     if (ParseParameters(env, info, params, *asynccallbackinfo, isThrow) == nullptr) {
1014         napi_create_int32(env, -1, &(asynccallbackinfo->result));
1015         return DealErrorReturn(env, asynccallbackinfo->callback, asynccallbackinfo->result, isThrow);
1016     }
1017 
1018     // promise
1019     napi_value promise = nullptr;
1020     SetAsynccallbackinfo(env, *asynccallbackinfo, promise);
1021     asynccallbackinfo->reminder = params.reminder;
1022     asynccallbackinfo->isThrow = isThrow;
1023 
1024     // resource name
1025     napi_value resourceName = nullptr;
1026     napi_create_string_latin1(env, "publishReminder", NAPI_AUTO_LENGTH, &resourceName);
1027 
1028     // create and start async work
1029     napi_create_async_work(env,
1030         nullptr,
1031         resourceName,
1032         [](napi_env env, void *data) {
1033             ANSR_LOGI("Publish napi_create_async_work start");
1034             AsyncCallbackInfo *asynccallbackinfo = static_cast<AsyncCallbackInfo *>(data);
1035             if (asynccallbackinfo) {
1036                 asynccallbackinfo->info.errorCode = ReminderHelper::PublishReminder(*(asynccallbackinfo->reminder));
1037                 ANSR_LOGD("Return reminderId=%{public}d", asynccallbackinfo->reminder->GetReminderId());
1038             }
1039         },
1040         [](napi_env env, napi_status status, void *data) {
1041             ANSR_LOGI("Publish napi_create_async_work complete start");
1042             AsyncCallbackInfo *asynccallbackinfo = static_cast<AsyncCallbackInfo *>(data);
1043             std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
1044 
1045             // reminderId
1046             if (asynccallbackinfo) {
1047                 if (asynccallbackinfo->info.errorCode == ERR_OK) {
1048                     napi_create_int32(env, asynccallbackinfo->reminder->GetReminderId(), &(asynccallbackinfo->result));
1049                 } else {
1050                     napi_create_int32(env, -1, &(asynccallbackinfo->result));
1051                 }
1052 
1053                 ReminderCommon::ReturnCallbackPromise(
1054                     env, asynccallbackinfo->info, asynccallbackinfo->result, asynccallbackinfo->isThrow);
1055                 ANSR_LOGI("Publish napi_create_async_work complete end");
1056             }
1057         },
1058         (void *)asynccallbackinfo,
1059         &asynccallbackinfo->asyncWork);
1060 
1061     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
1062     callbackPtr.release();
1063 
1064     if (asynccallbackinfo->info.isCallback) {
1065         return NotificationNapi::Common::NapiGetNull(env);
1066     } else {
1067         return promise;
1068     }
1069 }
1070 
PublishReminderMgr(napi_env env, napi_callback_info info)1071 napi_value PublishReminderMgr(napi_env env, napi_callback_info info)
1072 {
1073     return PublishReminderInner(env, info, true);
1074 }
1075 
PublishReminder(napi_env env, napi_callback_info info)1076 napi_value PublishReminder(napi_env env, napi_callback_info info)
1077 {
1078     return PublishReminderInner(env, info, false);
1079 }
1080 
AddSlotInner(napi_env env, napi_callback_info info, bool isThrow)1081 napi_value AddSlotInner(napi_env env, napi_callback_info info, bool isThrow)
1082 {
1083     ANSR_LOGI("AddSlot");
1084 
1085     AsyncCallbackInfo *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfo(env);
1086     if (!asynccallbackinfo) {
1087         ANSR_LOGE("Low memory.");
1088         return NotificationNapi::Common::NapiGetNull(env);
1089     }
1090     std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
1091 
1092     // param
1093     Parameters params;
1094     if (ParseSlotParameters(env, info, params, *asynccallbackinfo, isThrow) == nullptr) {
1095         return DealErrorReturn(env, asynccallbackinfo->callback, NotificationNapi::Common::NapiGetNull(env), isThrow);
1096     }
1097 
1098     // promise
1099     napi_value promise = nullptr;
1100     SetAsynccallbackinfo(env, *asynccallbackinfo, promise);
1101     asynccallbackinfo->inType = params.inType;
1102     asynccallbackinfo->info.errorCode = params.errCode;
1103     asynccallbackinfo->isThrow = isThrow;
1104 
1105     // resource name
1106     napi_value resourceName = nullptr;
1107     napi_create_string_latin1(env, "AddSlot", NAPI_AUTO_LENGTH, &resourceName);
1108 
1109     // create and start async work
1110     napi_create_async_work(env,
1111         nullptr,
1112         resourceName,
1113         [](napi_env env, void *data) {
1114             ANSR_LOGI("AddSlot napi_create_async_work start");
1115             AsyncCallbackInfo *asynccallbackinfo = static_cast<AsyncCallbackInfo *>(data);
1116             if (asynccallbackinfo && (asynccallbackinfo->info.errorCode == ERR_OK)) {
1117                 asynccallbackinfo->info.errorCode = NotificationHelper::AddSlotByType(asynccallbackinfo->inType);
1118             }
1119         },
1120         [](napi_env env, napi_status status, void *data) {
1121             AsyncCallbackInfo *asynccallbackinfo = static_cast<AsyncCallbackInfo *>(data);
1122             if (asynccallbackinfo) {
1123                 std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
1124                 ReminderCommon::ReturnCallbackPromise(env, asynccallbackinfo->info,
1125                     NotificationNapi::Common::NapiGetNull(env), asynccallbackinfo->isThrow);
1126                 ANSR_LOGD("AddSlot napi_create_async_work complete end.");
1127             }
1128         },
1129         (void *)asynccallbackinfo,
1130         &asynccallbackinfo->asyncWork);
1131 
1132     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
1133     callbackPtr.release();
1134 
1135     if (asynccallbackinfo->info.isCallback) {
1136         return NotificationNapi::Common::NapiGetNull(env);
1137     } else {
1138         return promise;
1139     }
1140 }
1141 
AddSlotMgr(napi_env env, napi_callback_info info)1142 napi_value AddSlotMgr(napi_env env, napi_callback_info info)
1143 {
1144     return AddSlotInner(env, info, true);
1145 }
1146 
AddSlot(napi_env env, napi_callback_info info)1147 napi_value AddSlot(napi_env env, napi_callback_info info)
1148 {
1149     return AddSlotInner(env, info, false);
1150 }
1151 
ParseAddExcludeDateParameter(const napi_env &env, const napi_callback_info &info, Parameters &params)1152 napi_value ParseAddExcludeDateParameter(const napi_env &env, const napi_callback_info &info, Parameters &params)
1153 {
1154     ANSR_LOGI("ParseAddExcludeDateParameter");
1155     size_t argc = ADD_EXCLUDE_DATE_PARAM_LEN;
1156     napi_value argv[ADD_EXCLUDE_DATE_PARAM_LEN] = {nullptr};
1157     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
1158     if (argc < ADD_EXCLUDE_DATE_PARAM_LEN) {
1159         ANSR_LOGW("Wrong number of arguments");
1160         ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
1161         return nullptr;
1162     }
1163 
1164     // argv[0]: reminder id
1165     int32_t reminderId = -1;
1166     if (!ReminderCommon::GetInt32(env, argv[0], nullptr, reminderId, true)) {
1167         ANSR_LOGW("Parse reminder id failed.");
1168         ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
1169         return nullptr;
1170     }
1171     if (reminderId < 0) {
1172         ANSR_LOGW("Param reminder id is illegal.");
1173         ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
1174         return nullptr;
1175     }
1176     params.reminderId = reminderId;
1177 
1178     // argv[1]: exclude date
1179     double date = 0.0;
1180     if (!ReminderCommon::GetDate(env, argv[1], nullptr, date)) {
1181         ANSR_LOGW("Parse exclude date failed.");
1182         ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
1183         return nullptr;
1184     }
1185     if (date < 0.0) {
1186         ANSR_LOGW("Param exclude date is illegal.");
1187         ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
1188         return nullptr;
1189     }
1190     params.excludeDate = static_cast<uint64_t>(date);
1191     return NotificationNapi::Common::NapiGetNull(env);
1192 }
1193 
AddExcludeDate(napi_env env, napi_callback_info info)1194 napi_value AddExcludeDate(napi_env env, napi_callback_info info)
1195 {
1196     ANSR_LOGD("Call AddExcludeDate");
1197 
1198     AsyncCallbackInfo *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfo(env);
1199     if (!asynccallbackinfo) {
1200         ANSR_LOGE("Low memory.");
1201         return NotificationNapi::Common::NapiGetNull(env);
1202     }
1203     std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
1204 
1205     // param
1206     Parameters params;
1207     if (ParseAddExcludeDateParameter(env, info, params) == nullptr) {
1208         return DealErrorReturn(env, asynccallbackinfo->callback, NotificationNapi::Common::NapiGetNull(env), true);
1209     }
1210 
1211     // promise
1212     napi_value promise = nullptr;
1213     SetAsynccallbackinfo(env, *asynccallbackinfo, promise);
1214     asynccallbackinfo->reminderId = params.reminderId;
1215     asynccallbackinfo->excludeDate = params.excludeDate;
1216     asynccallbackinfo->isThrow = true;
1217 
1218     // resource name
1219     napi_value resourceName = nullptr;
1220     napi_create_string_latin1(env, "addExcludeDate", NAPI_AUTO_LENGTH, &resourceName);
1221 
1222     bool isCallback = asynccallbackinfo->info.isCallback;
1223 
1224     // create and queue async work
1225     napi_create_async_work(env,
1226         nullptr,
1227         resourceName,
1228         [](napi_env env, void *data) {
1229             ANSR_LOGI("AddExcludeDate napi_create_async_work start");
1230             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfo *>(data);
1231             if (asynccallbackinfo) {
1232                 asynccallbackinfo->info.errorCode = ReminderHelper::AddExcludeDate(asynccallbackinfo->reminderId,
1233                     asynccallbackinfo->excludeDate);
1234             }
1235         },
1236         [](napi_env env, napi_status status, void *data) {
1237             ANSR_LOGI("AddExcludeDate napi_create_async_work complete start");
1238             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfo *>(data);
1239             std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
1240 
1241             ReminderCommon::ReturnCallbackPromise(
1242                 env, asynccallbackinfo->info, NotificationNapi::Common::NapiGetNull(env), asynccallbackinfo->isThrow);
1243             ANSR_LOGI("AddExcludeDate napi_create_async_work complete end");
1244         },
1245         (void *)asynccallbackinfo,
1246         &asynccallbackinfo->asyncWork);
1247     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
1248     callbackPtr.release();
1249 
1250     return isCallback ? NotificationNapi::Common::NapiGetNull(env) : promise;
1251 }
1252 
ParseReminderIdParameter(const napi_env &env, const napi_callback_info &info, Parameters &params)1253 napi_value ParseReminderIdParameter(const napi_env &env, const napi_callback_info &info, Parameters &params)
1254 {
1255     ANSR_LOGI("ParseReminderIdParameter");
1256     size_t argc = DEL_EXCLUDE_DATE_PARAM_LEN;
1257     napi_value argv[DEL_EXCLUDE_DATE_PARAM_LEN] = {nullptr};
1258     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
1259     if (argc < DEL_EXCLUDE_DATE_PARAM_LEN) {
1260         ANSR_LOGW("Wrong number of arguments");
1261         ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
1262         return nullptr;
1263     }
1264 
1265     // argv[0]: reminder id
1266     int32_t reminderId = -1;
1267     if (!ReminderCommon::GetInt32(env, argv[0], nullptr, reminderId, true)) {
1268         ANSR_LOGW("Parse reminder id failed.");
1269         ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
1270         return nullptr;
1271     }
1272     if (reminderId < 0) {
1273         ANSR_LOGW("Param reminder id is illegal.");
1274         ReminderCommon::HandleErrCode(env, ERR_REMINDER_INVALID_PARAM);
1275         return nullptr;
1276     }
1277     params.reminderId = reminderId;
1278     return NotificationNapi::Common::NapiGetNull(env);
1279 }
1280 
DelExcludeDates(napi_env env, napi_callback_info info)1281 napi_value DelExcludeDates(napi_env env, napi_callback_info info)
1282 {
1283     ANSR_LOGD("Call DelExcludeDates");
1284 
1285     AsyncCallbackInfo *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfo(env);
1286     if (!asynccallbackinfo) {
1287         ANSR_LOGE("Low memory.");
1288         return NotificationNapi::Common::NapiGetNull(env);
1289     }
1290     std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
1291 
1292     // param
1293     Parameters params;
1294     if (ParseReminderIdParameter(env, info, params) == nullptr) {
1295         return DealErrorReturn(env, asynccallbackinfo->callback, NotificationNapi::Common::NapiGetNull(env), true);
1296     }
1297 
1298     // promise
1299     napi_value promise = nullptr;
1300     SetAsynccallbackinfo(env, *asynccallbackinfo, promise);
1301     asynccallbackinfo->reminderId = params.reminderId;
1302     asynccallbackinfo->isThrow = true;
1303 
1304     // resource name
1305     napi_value resourceName = nullptr;
1306     napi_create_string_latin1(env, "deleteExcludeDates", NAPI_AUTO_LENGTH, &resourceName);
1307 
1308     bool isCallback = asynccallbackinfo->info.isCallback;
1309 
1310     // create and queue async work
1311     napi_create_async_work(env,
1312         nullptr,
1313         resourceName,
1314         [](napi_env env, void *data) {
1315             ANSR_LOGI("DelExcludeDates napi_create_async_work start");
1316             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfo *>(data);
1317             if (asynccallbackinfo) {
1318                 asynccallbackinfo->info.errorCode = ReminderHelper::DelExcludeDates(asynccallbackinfo->reminderId);
1319             }
1320         },
1321         [](napi_env env, napi_status status, void *data) {
1322             ANSR_LOGI("DelExcludeDates napi_create_async_work complete start");
1323             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfo *>(data);
1324             std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
1325 
1326             ReminderCommon::ReturnCallbackPromise(
1327                 env, asynccallbackinfo->info, NotificationNapi::Common::NapiGetNull(env), asynccallbackinfo->isThrow);
1328             ANSR_LOGI("DelExcludeDates napi_create_async_work complete end");
1329         },
1330         (void *)asynccallbackinfo,
1331         &asynccallbackinfo->asyncWork);
1332     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
1333     callbackPtr.release();
1334 
1335     return isCallback ? NotificationNapi::Common::NapiGetNull(env) : promise;
1336 }
1337 
GetExcludeDatesInner(napi_env env, const std::vector<uint64_t>& dates, napi_value& arr)1338 void GetExcludeDatesInner(napi_env env, const std::vector<uint64_t>& dates, napi_value& arr)
1339 {
1340     int32_t count = 0;
1341     napi_create_array(env, &arr);
1342     for (auto date : dates) {
1343         napi_value result = nullptr;
1344         napi_create_date(env, static_cast<double>(date), &result);
1345         napi_set_element(env, arr, count, result);
1346         count++;
1347     }
1348     ANSR_LOGI("GetExcludeDates count = %{public}d", count);
1349 }
1350 
GetExcludeDates(napi_env env, napi_callback_info info)1351 napi_value GetExcludeDates(napi_env env, napi_callback_info info)
1352 {
1353     AsyncCallbackInfo *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfo(env);
1354     if (!asynccallbackinfo) {
1355         ANSR_LOGE("Low memory.");
1356         return NotificationNapi::Common::NapiGetNull(env);
1357     }
1358     std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
1359 
1360     // param
1361     Parameters params;
1362     if (ParseReminderIdParameter(env, info, params) == nullptr) {
1363         return DealErrorReturn(env, asynccallbackinfo->callback, NotificationNapi::Common::NapiGetNull(env), true);
1364     }
1365 
1366     // promise
1367     napi_value promise = nullptr;
1368     SetAsynccallbackinfo(env, *asynccallbackinfo, promise);
1369     asynccallbackinfo->reminderId = params.reminderId;
1370     asynccallbackinfo->isThrow = true;
1371 
1372     // resource name
1373     napi_value resourceName = nullptr;
1374     napi_create_string_latin1(env, "getExcludeDates", NAPI_AUTO_LENGTH, &resourceName);
1375 
1376     bool isCallback = asynccallbackinfo->info.isCallback;
1377 
1378     // create and queue async work
1379     napi_create_async_work(env, nullptr, resourceName,
1380         [](napi_env env, void *data) {
1381             ANSR_LOGI("GetExcludeDates napi_create_async_work start");
1382             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfo *>(data);
1383             if (asynccallbackinfo) {
1384                 asynccallbackinfo->info.errorCode = ReminderHelper::GetExcludeDates(asynccallbackinfo->reminderId,
1385                     asynccallbackinfo->excludeDates);
1386             }
1387         },
1388         [](napi_env env, napi_status status, void *data) {
1389             ANSR_LOGI("GetExcludeDates napi_create_async_work complete start");
1390             auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfo *>(data);
1391             std::unique_ptr<AsyncCallbackInfo> callbackPtr { asynccallbackinfo };
1392 
1393             if (asynccallbackinfo) {
1394                 if (asynccallbackinfo->info.errorCode != ERR_OK) {
1395                     asynccallbackinfo->result = NotificationNapi::Common::NapiGetNull(env);
1396                 } else {
1397                     GetExcludeDatesInner(env, asynccallbackinfo->excludeDates, asynccallbackinfo->result);
1398                 }
1399 
1400                 ReminderCommon::ReturnCallbackPromise(
1401                     env, asynccallbackinfo->info, asynccallbackinfo->result, asynccallbackinfo->isThrow);
1402             }
1403             ANSR_LOGI("GetExcludeDates napi_create_async_work complete end");
1404         },
1405         (void *)asynccallbackinfo, &asynccallbackinfo->asyncWork);
1406     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
1407     callbackPtr.release();
1408 
1409     return isCallback ? NotificationNapi::Common::NapiGetNull(env) : promise;
1410 }
1411 }
1412 }
1413