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