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 "napi_common.h"
21 #include "ipc_skeleton.h"
22 #include "reminder_request_alarm.h"
23 #include "reminder_request_calendar.h"
24 #include "reminder_request_timer.h"
25 #include "tokenid_kit.h"
26 #include "securec.h"
27
28 namespace OHOS {
29 namespace ReminderAgentNapi {
30 using namespace OHOS::Notification;
31 const uint32_t ASYNC_CALLBACK_PARAM_NUM = 2;
32
GetReminderRequest(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)33 napi_value ReminderCommon::GetReminderRequest(
34 const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
35 {
36 napi_valuetype valuetype = napi_undefined;
37 NAPI_CALL(env, napi_typeof(env, value, &valuetype));
38 if (valuetype != napi_object) {
39 ANSR_LOGE("Wrong argument type. Object expected.");
40 return nullptr;
41 }
42
43 // gen reminder
44 if (GenReminder(env, value, reminder) == nullptr) {
45 return nullptr;
46 }
47 return NotificationNapi::Common::NapiGetNull(env);
48 }
49
GenActionButtons(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder,bool isSysApp)50 bool ReminderCommon::GenActionButtons(
51 const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder, bool isSysApp)
52 {
53 char str[NotificationNapi::STR_MAX_SIZE] = {0};
54 napi_valuetype valuetype = napi_undefined;
55 napi_value actionButtons = nullptr;
56 if (!GetObject(env, value, ReminderAgentNapi::ACTION_BUTTON, actionButtons)) {
57 return true;
58 }
59 bool isArray = false;
60 napi_is_array(env, actionButtons, &isArray);
61 if (!isArray) {
62 ANSR_LOGE("Wrong argument type:%{public}s. array expected.", ACTION_BUTTON);
63 return false;
64 }
65
66 uint32_t length = 0;
67 napi_get_array_length(env, actionButtons, &length);
68 for (size_t i = 0; i < length; i++) {
69 napi_value actionButton = nullptr;
70 napi_get_element(env, actionButtons, i, &actionButton);
71 NAPI_CALL_BASE(env, napi_typeof(env, actionButton, &valuetype), false);
72 if (valuetype != napi_object) {
73 ANSR_LOGE("Wrong element type:%{public}s. object expected.", ACTION_BUTTON);
74 return false;
75 }
76
77 int32_t buttonType = static_cast<int32_t>(ReminderRequest::ActionButtonType::INVALID);
78 if (GetStringUtf8(env, actionButton,
79 ReminderAgentNapi::ACTION_BUTTON_TITLE, str, NotificationNapi::STR_MAX_SIZE) &&
80 GetInt32(env, actionButton, ReminderAgentNapi::ACTION_BUTTON_TYPE, buttonType, false)) {
81 if (!(ReminderRequest::ActionButtonType(buttonType) == ReminderRequest::ActionButtonType::CLOSE ||
82 ReminderRequest::ActionButtonType(buttonType) == ReminderRequest::ActionButtonType::SNOOZE ||
83 (ReminderRequest::ActionButtonType(buttonType) == ReminderRequest::ActionButtonType::CUSTOM &&
84 isSysApp))) {
85 ANSR_LOGE("Wrong argument type:%{public}s. buttonType not support.", ACTION_BUTTON);
86 return false;
87 }
88 HandleActionButtonTitle(env, actionButton, reminder, str, buttonType);
89 } else {
90 ANSR_LOGE("Parse action button error.");
91 return false;
92 }
93 }
94 return true;
95 }
96
GenRingChannel(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)97 bool ReminderCommon::GenRingChannel(const napi_env& env, const napi_value& value,
98 std::shared_ptr<ReminderRequest>& reminder)
99 {
100 int32_t ringChannel = static_cast<int32_t>(ReminderRequest::RingChannel::ALARM);
101 if (GetInt32(env, value, ReminderAgentNapi::RING_CHANNEL, ringChannel, false)) {
102 if (!(ReminderRequest::RingChannel(ringChannel) == ReminderRequest::RingChannel::ALARM ||
103 ReminderRequest::RingChannel(ringChannel) == ReminderRequest::RingChannel::MEDIA)) {
104 ANSR_LOGE("Wrong argument type:%{public}s. ringChannel not support.", RING_CHANNEL);
105 return false;
106 }
107 reminder->SetRingChannel(static_cast<ReminderRequest::RingChannel>(ringChannel));
108 }
109 return true;
110 }
111
HandleActionButtonTitle(const napi_env & env,const napi_value & actionButton,std::shared_ptr<ReminderRequest> & reminder,const char * str,int32_t buttonType)112 void ReminderCommon::HandleActionButtonTitle(const napi_env &env, const napi_value &actionButton,
113 std::shared_ptr<ReminderRequest>& reminder, const char* str, int32_t buttonType)
114 {
115 char res[NotificationNapi::STR_MAX_SIZE] = {0};
116 std::string resource = "";
117 if (GetStringUtf8(env, actionButton, ReminderAgentNapi::ACTION_BUTTON_RESOURCE, res,
118 NotificationNapi::STR_MAX_SIZE)) {
119 resource = std::string(res);
120 }
121
122 std::string title(str);
123 auto buttonWantAgent = std::make_shared<ReminderRequest::ButtonWantAgent>();
124 if (ReminderRequest::ActionButtonType(buttonType) == ReminderRequest::ActionButtonType::CUSTOM) {
125 GetButtonWantAgent(env, actionButton, reminder, buttonWantAgent);
126 }
127 // gen buttonDataShareUpdate
128 auto buttonDataShareUpdate = std::make_shared<ReminderRequest::ButtonDataShareUpdate>();
129 if (ReminderRequest::ActionButtonType(buttonType) != ReminderRequest::ActionButtonType::INVALID) {
130 GetButtonDataShareUpdate(env, actionButton, buttonDataShareUpdate);
131 }
132 reminder->SetActionButton(title, static_cast<ReminderRequest::ActionButtonType>(buttonType),
133 resource, buttonWantAgent, buttonDataShareUpdate);
134 ANSR_LOGD("button title=%{public}s, type=%{public}d, resource=%{public}s",
135 title.c_str(), buttonType, resource.c_str());
136 }
137
IsSelfSystemApp()138 bool ReminderCommon::IsSelfSystemApp()
139 {
140 auto selfToken = IPCSkeleton::GetSelfTokenID();
141 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
142 ANSR_LOGE("This application is not system-app, can not use system-api");
143 return false;
144 }
145 return true;
146 }
147
GetButtonWantAgent(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder,std::shared_ptr<ReminderRequest::ButtonWantAgent> & buttonWantAgent)148 void ReminderCommon::GetButtonWantAgent(const napi_env &env, const napi_value &value,
149 std::shared_ptr<ReminderRequest>& reminder, std::shared_ptr<ReminderRequest::ButtonWantAgent>& buttonWantAgent)
150 {
151 char str[NotificationNapi::STR_MAX_SIZE] = {0};
152 napi_value wantAgent = nullptr;
153 if (GetObject(env, value, ReminderAgentNapi::BUTTON_WANT_AGENT, wantAgent)) {
154 if (GetStringUtf8(env, wantAgent,
155 ReminderAgentNapi::BUTTON_WANT_AGENT_PKG, str, NotificationNapi::STR_MAX_SIZE)) {
156 buttonWantAgent->pkgName = str;
157 }
158 if (GetStringUtf8(env, wantAgent,
159 ReminderAgentNapi::BUTTON_WANT_AGENT_ABILITY, str, NotificationNapi::STR_MAX_SIZE)) {
160 buttonWantAgent->abilityName = str;
161 }
162 if (GetStringUtf8(env, wantAgent,
163 ReminderAgentNapi::BUTTON_WANT_AGENT_URI, str, NotificationNapi::STR_MAX_SIZE)) {
164 reminder->SetCustomButtonUri(str);
165 }
166 }
167 }
168
169 // uri:string equalTo{key:value} valuesBucket{key:value}
GetButtonDataShareUpdate(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest::ButtonDataShareUpdate> & buttonDataShareUpdate)170 void ReminderCommon::GetButtonDataShareUpdate(const napi_env &env, const napi_value &value,
171 std::shared_ptr<ReminderRequest::ButtonDataShareUpdate>& buttonDataShareUpdate)
172 {
173 napi_value dataShare = nullptr;
174 if (GetObject(env, value, BUTTON_DATA_SHARE_UPDATE, dataShare)) {
175 // dataShare uri
176 char str[NotificationNapi::STR_MAX_SIZE] = {0};
177 if (GetStringUtf8(env, dataShare, BUTTON_DATA_SHARE_UPDATE_URI, str, NotificationNapi::STR_MAX_SIZE)) {
178 ANSR_LOGD("gen dataShareUri success");
179 buttonDataShareUpdate->uri = str;
180 }
181 // dataShare equalTo
182 napi_value equalTo = nullptr;
183 std::string valueBucketString;
184 if (GetObject(env, dataShare, BUTTON_DATA_SHARE_UPDATE_EQUALTO, equalTo)) {
185 if (GetValueBucketObject(valueBucketString, env, equalTo)) {
186 ANSR_LOGD("gen dataShareEqualTo success");
187 buttonDataShareUpdate->equalTo = valueBucketString;
188 }
189 }
190 // dataShare valuesBucket
191 napi_value valuesBucket = nullptr;
192 valueBucketString.clear();
193 if (GetObject(env, dataShare, BUTTON_DATA_SHARE_UPDATE_VALUE, valuesBucket)) {
194 if (GetValueBucketObject(valueBucketString, env, valuesBucket)) {
195 ANSR_LOGD("gen dataShareValuesBucket success");
196 buttonDataShareUpdate->valuesBucket = valueBucketString;
197 }
198 }
199 }
200 }
201
202 // get {key:value} to string(key:type:value)
GetValueBucketObject(std::string & valueBucketString,const napi_env & env,const napi_value & arg)203 bool ReminderCommon::GetValueBucketObject(std::string &valueBucketString, const napi_env &env, const napi_value &arg)
204 {
205 // arrary
206 napi_value keys = 0;
207 napi_get_property_names(env, arg, &keys);
208 uint32_t arrlen = 0;
209 napi_status status = napi_get_array_length(env, keys, &arrlen);
210 if (status != napi_ok) {
211 ANSR_LOGE("get the valuesBucket length err");
212 return false;
213 }
214 for (size_t i = 0; i < arrlen; ++i) {
215 // key
216 napi_value key = 0;
217 status = napi_get_element(env, keys, i, &key);
218 if (status != napi_ok) {
219 ANSR_LOGW("get valuesBucket err");
220 continue;
221 }
222 std::string keyStr = GetStringFromJS(env, key);
223 if (!ValidateString(keyStr)) {
224 ANSR_LOGE("The key contains separator");
225 return false;
226 }
227 // value
228 napi_value value = 0;
229 napi_get_property(env, arg, key, &value);
230 bool ret;
231 std::string type;
232 std::string valueObject = Convert2Value(env, value, ret, type);
233 if (!ret) {
234 ANSR_LOGW("parse valuesBucket err");
235 continue;
236 }
237 if (!ValidateString(valueObject)) {
238 ANSR_LOGE("The value contains separator");
239 return false;
240 }
241 valueBucketString += keyStr + ReminderRequest::SEP_BUTTON_VALUE + type
242 + ReminderRequest::SEP_BUTTON_VALUE + valueObject;
243 if (i < arrlen - 1) {
244 valueBucketString += ReminderRequest::SEP_BUTTON_VALUE_TYPE;
245 }
246 }
247 return true;
248 }
249
250 // get string
GetStringFromJS(const napi_env & env,const napi_value & param,const std::string & defaultValue)251 std::string ReminderCommon::GetStringFromJS(const napi_env &env, const napi_value ¶m,
252 const std::string &defaultValue)
253 {
254 size_t size = 0;
255 if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
256 return defaultValue;
257 }
258 if (size == 0) {
259 return defaultValue;
260 }
261
262 char *buf = new (std::nothrow) char[size + 1];
263 std::string value("");
264 if (buf == nullptr) {
265 return value;
266 }
267 (void)memset_s(buf, size + 1, 0, size + 1);
268 bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
269 if (rev) {
270 value = buf;
271 } else {
272 value = defaultValue;
273 }
274
275 if (buf != nullptr) {
276 delete[] buf;
277 buf = nullptr;
278 }
279 return value;
280 }
281
282 // get type and value
Convert2Value(const napi_env & env,const napi_value & value,bool & status,std::string & type)283 std::string ReminderCommon::Convert2Value(const napi_env &env, const napi_value &value, bool &status, std::string &type)
284 {
285 // array type
286 napi_valuetype valueType = napi_undefined;
287 napi_typeof(env, value, &valueType);
288 status = true;
289 // gen value
290 std::string valueString;
291 std::vector<uint8_t> valueBlob;
292 switch (valueType) {
293 case napi_null: {
294 type = "null";
295 valueString = type;
296 break;
297 }
298 case napi_boolean: {
299 type = "bool";
300 bool valueBool = false;
301 napi_get_value_bool(env, value, &valueBool);
302 valueString = std::to_string(valueBool);
303 break;
304 }
305 case napi_number: {
306 type = "double";
307 double valueNumber = 0;
308 napi_get_value_double(env, value, &valueNumber);
309 valueString = std::to_string(valueNumber);
310 break;
311 }
312 case napi_string: {
313 type = "string";
314 valueString = GetStringFromJS(env, value);
315 break;
316 }
317 case napi_object: {
318 type = "vector";
319 valueBlob = Convert2U8Vector(env, value);
320 for (auto it = valueBlob.begin(); it != valueBlob.end(); ++it) {
321 valueString += std::to_string(*it);
322 if ((it + 1) != valueBlob.end()) {
323 valueString += ReminderRequest::SEP_BUTTON_VALUE_BLOB;
324 }
325 }
326 break;
327 }
328 default: {
329 ANSR_LOGE("Convert2Value err");
330 status = false;
331 break;
332 }
333 }
334 return valueString;
335 }
336
337 // get vector<uint8_t>
Convert2U8Vector(const napi_env & env,const napi_value & input_array)338 std::vector<uint8_t> ReminderCommon::Convert2U8Vector(const napi_env &env, const napi_value &input_array)
339 {
340 bool isTypedArray = false;
341 bool isArrayBuffer = false;
342 // type is array?
343 napi_is_typedarray(env, input_array, &isTypedArray);
344 if (!isTypedArray) {
345 // buffer whether or not it exists?
346 napi_is_arraybuffer(env, input_array, &isArrayBuffer);
347 if (!isArrayBuffer) {
348 ANSR_LOGE("unknow type");
349 return {};
350 }
351 }
352 size_t length = 0;
353 void *data = nullptr;
354 // get array
355 if (isTypedArray) {
356 napi_typedarray_type type;
357 napi_value input_buffer = nullptr;
358 size_t byte_offset = 0;
359 napi_get_typedarray_info(env, input_array, &type, &length, &data, &input_buffer, &byte_offset);
360 if (type != napi_uint8_array || data == nullptr) {
361 ANSR_LOGW("napi_get_typedarray_info err");
362 return {};
363 }
364 } else {
365 napi_get_arraybuffer_info(env, input_array, &data, &length);
366 if (data == nullptr || length == 0) {
367 ANSR_LOGW("napi_get_arraybuffer_info err");
368 return {};
369 }
370 }
371 return std::vector<uint8_t>((uint8_t *)data, ((uint8_t *)data) + length);
372 }
373
ValidateString(const std::string & str)374 bool ReminderCommon::ValidateString(const std::string &str)
375 {
376 if (str.find(ReminderRequest::SEP_BUTTON_VALUE_TYPE) != std::string::npos) {
377 ANSR_LOGW("The string contains SEP_BUTTON_VALUE_TYPE");
378 return false;
379 }
380 if (str.find(ReminderRequest::SEP_BUTTON_VALUE) != std::string::npos) {
381 ANSR_LOGW("The string contains SEP_BUTTON_VALUE");
382 return false;
383 }
384 if (str.find(ReminderRequest::SEP_BUTTON_VALUE_BLOB) != std::string::npos) {
385 ANSR_LOGW("The string contains SEP_BUTTON_VALUE_BLOB");
386 return false;
387 }
388 return true;
389 }
390
GenWantAgent(const napi_env & env,const napi_value & value,const char * name,std::shared_ptr<ReminderRequest::WantAgentInfo> & wantAgentInfo)391 bool ReminderCommon::GenWantAgent(
392 const napi_env &env, const napi_value &value, const char* name,
393 std::shared_ptr<ReminderRequest::WantAgentInfo>& wantAgentInfo)
394 {
395 char str[NotificationNapi::STR_MAX_SIZE] = {0};
396 napi_value wantAgent = nullptr;
397 if (GetObject(env, value, name, wantAgent)) {
398 wantAgentInfo = std::make_shared<ReminderRequest::WantAgentInfo>();
399 if (GetStringUtf8(env, wantAgent, ReminderAgentNapi::WANT_AGENT_PKG, str, NotificationNapi::STR_MAX_SIZE)) {
400 wantAgentInfo->pkgName = str;
401 }
402 if (GetStringUtf8(env, wantAgent,
403 ReminderAgentNapi::WANT_AGENT_ABILITY, str, NotificationNapi::STR_MAX_SIZE)) {
404 wantAgentInfo->abilityName = str;
405 }
406 if (GetStringUtf8(env, wantAgent,
407 ReminderAgentNapi::WANT_AGENT_URI, str, NotificationNapi::STR_MAX_SIZE)) {
408 wantAgentInfo->uri = str;
409 }
410 napi_value params = nullptr;
411 if (GetObject(env, wantAgent, ReminderAgentNapi::WANT_AGENT_PARAMETERS, params)) {
412 AAFwk::WantParams wantParams;
413 if (AppExecFwk::UnwrapWantParams(env, params, wantParams)) {
414 wantAgentInfo->parameters = wantParams;
415 }
416 }
417 }
418 return true;
419 }
420
GenMaxScreenWantAgent(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)421 void ReminderCommon::GenMaxScreenWantAgent(
422 const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
423 {
424 char str[NotificationNapi::STR_MAX_SIZE] = {0};
425 napi_value maxScreenWantAgent = nullptr;
426 if (GetObject(env, value, ReminderAgentNapi::MAX_SCREEN_WANT_AGENT, maxScreenWantAgent)) {
427 auto maxScreenWantAgentInfo = std::make_shared<ReminderRequest::MaxScreenAgentInfo>();
428 if (GetStringUtf8(env, maxScreenWantAgent,
429 ReminderAgentNapi::MAX_SCREEN_WANT_AGENT_PKG, str, NotificationNapi::STR_MAX_SIZE)) {
430 maxScreenWantAgentInfo->pkgName = str;
431 }
432 if (GetStringUtf8(env, maxScreenWantAgent,
433 ReminderAgentNapi::MAX_SCREEN_WANT_AGENT_ABILITY, str, NotificationNapi::STR_MAX_SIZE)) {
434 maxScreenWantAgentInfo->abilityName = str;
435 }
436 reminder->SetMaxScreenWantAgentInfo(maxScreenWantAgentInfo);
437 }
438 }
CreateReminder(const napi_env & env,const napi_value & value,const bool isSysApp,std::shared_ptr<ReminderRequest> & reminder)439 bool ReminderCommon::CreateReminder(
440 const napi_env &env, const napi_value &value, const bool isSysApp, std::shared_ptr<ReminderRequest>& reminder)
441 {
442 napi_value result = nullptr;
443 napi_get_named_property(env, value, ReminderAgentNapi::REMINDER_TYPE, &result);
444 int32_t reminderType = -1;
445 napi_get_value_int32(env, result, &reminderType);
446 switch (ReminderRequest::ReminderType(reminderType)) {
447 case ReminderRequest::ReminderType::TIMER:
448 CreateReminderTimer(env, value, reminder);
449 break;
450 case ReminderRequest::ReminderType::ALARM:
451 CreateReminderAlarm(env, value, reminder);
452 break;
453 case ReminderRequest::ReminderType::CALENDAR:
454 CreateReminderCalendar(env, value, isSysApp, reminder);
455 break;
456 default:
457 ANSR_LOGE("Reminder type is not support. (type:%{public}d)", reminderType);
458 break;
459 }
460 if (reminder == nullptr) {
461 ANSR_LOGE("Instance of reminder error.");
462 return false;
463 }
464 return true;
465 }
466
GenReminder(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)467 napi_value ReminderCommon::GenReminder(
468 const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
469 {
470 // reminderType
471 bool hasProperty = false;
472 NAPI_CALL(env, napi_has_named_property(env, value, ReminderAgentNapi::REMINDER_TYPE, &hasProperty));
473 if (!hasProperty) {
474 ANSR_LOGE("Property %{public}s expected.", ReminderAgentNapi::REMINDER_TYPE);
475 return nullptr;
476 }
477
478 // createReminder
479 bool isSysApp = IsSelfSystemApp();
480 if (!CreateReminder(env, value, isSysApp, reminder)) {
481 return nullptr;
482 }
483 reminder->SetSystemApp(isSysApp);
484 GenReminderStringInner(env, value, reminder);
485 if (!GenReminderIntInner(env, value, reminder)) {
486 return nullptr;
487 }
488 GenReminderBoolInner(env, value, reminder);
489
490 // snoozeSlotType
491 int32_t snoozeSlotType = 0;
492 if (GetInt32(env, value, ReminderAgentNapi::SNOOZE_SLOT_TYPE, snoozeSlotType, false)) {
493 enum NotificationConstant::SlotType actureSnoozeType = NotificationConstant::SlotType::OTHER;
494 if (!NotificationNapi::AnsEnumUtil::SlotTypeJSToC(
495 NotificationNapi::SlotType(snoozeSlotType), actureSnoozeType)) {
496 ANSR_LOGW("snooze slot type not support.");
497 return nullptr;
498 }
499 reminder->SetSnoozeSlotType(actureSnoozeType);
500 }
501
502 // wantAgent
503 std::shared_ptr<ReminderRequest::WantAgentInfo> wantAgentInfo;
504 if (!GenWantAgent(env, value, ReminderAgentNapi::WANT_AGENT, wantAgentInfo)) {
505 return nullptr;
506 }
507 reminder->SetWantAgentInfo(wantAgentInfo);
508
509 // maxScreenWantAgent
510 GenMaxScreenWantAgent(env, value, reminder);
511
512 // actionButtons
513 if (!GenActionButtons(env, value, reminder, isSysApp)) {
514 return nullptr;
515 }
516
517 // ringChannel
518 if (!GenRingChannel(env, value, reminder)) {
519 return nullptr;
520 }
521
522 return NotificationNapi::Common::NapiGetNull(env);
523 }
524
GenReminderStringInner(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)525 void ReminderCommon::GenReminderStringInner(
526 const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
527 {
528 char str[NotificationNapi::STR_MAX_SIZE] = {0};
529
530 // title
531 if (GetStringUtf8(env, value, ReminderAgentNapi::TITLE, str, NotificationNapi::STR_MAX_SIZE)) {
532 reminder->SetTitle(std::string(str));
533 }
534
535 // content
536 if (GetStringUtf8(env, value, ReminderAgentNapi::CONTENT, str, NotificationNapi::STR_MAX_SIZE)) {
537 reminder->SetContent(std::string(str));
538 }
539
540 // expiredContent
541 if (GetStringUtf8(env, value, ReminderAgentNapi::EXPIRED_CONTENT, str, NotificationNapi::STR_MAX_SIZE)) {
542 reminder->SetExpiredContent(std::string(str));
543 }
544
545 // snoozeContent
546 if (GetStringUtf8(env, value, ReminderAgentNapi::SNOOZE_CONTENT, str, NotificationNapi::STR_MAX_SIZE)) {
547 reminder->SetSnoozeContent(std::string(str));
548 }
549
550 // group id
551 if (GetStringUtf8(env, value, ReminderAgentNapi::GROUP_ID, str, NotificationNapi::STR_MAX_SIZE)) {
552 reminder->SetGroupId(std::string(str));
553 }
554
555 // custom ring uri
556 if (GetStringUtf8(env, value, ReminderAgentNapi::CUSTOM_RING_URI, str, NotificationNapi::STR_MAX_SIZE)) {
557 reminder->SetCustomRingUri(std::string(str));
558 }
559 }
560
GenReminderIntInner(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)561 bool ReminderCommon::GenReminderIntInner(
562 const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
563 {
564 // ringDuration
565 int64_t propVal = 0;
566 if (GetInt64(env, value, ReminderAgentNapi::RING_DURATION, propVal)) {
567 if (propVal < 0 || propVal > static_cast<int64_t>(
568 ReminderRequest::MAX_RING_DURATION / ReminderRequest::MILLI_SECONDS)) {
569 ANSR_LOGE("ring duration value is error!");
570 return false;
571 }
572 uint64_t ringDuration = static_cast<uint64_t>(propVal);
573 reminder->SetRingDuration(ringDuration);
574 }
575
576 // timeInterval
577 if (GetInt64(env, value, ReminderAgentNapi::TIME_INTERVAL, propVal)) {
578 if (propVal < 0) {
579 reminder->SetTimeInterval(0);
580 } else {
581 uint64_t timeInterval = static_cast<uint64_t>(propVal);
582 reminder->SetTimeInterval(timeInterval);
583 }
584 }
585
586 // notificationId
587 int32_t propertyVal = 0;
588 if (GetInt32(env, value, ReminderAgentNapi::NOTIFICATION_ID, propertyVal, false)) {
589 reminder->SetNotificationId(propertyVal);
590 }
591
592 // snoozeTimes
593 if (GetInt32(env, value, ReminderAgentNapi::SNOOZE_TIMES, propertyVal, false)) {
594 if (propertyVal < 0) {
595 reminder->SetSnoozeTimes(0);
596 } else {
597 uint8_t snoozeTimes = propertyVal > UINT8_MAX ? UINT8_MAX : static_cast<uint8_t>(propertyVal);
598 reminder->SetSnoozeTimes(static_cast<uint8_t>(snoozeTimes));
599 }
600 }
601
602 // slotType
603 int32_t slotType = 0;
604 if (GetInt32(env, value, ReminderAgentNapi::SLOT_TYPE, slotType, false)) {
605 enum NotificationConstant::SlotType actureType = NotificationConstant::SlotType::OTHER;
606 if (!NotificationNapi::AnsEnumUtil::SlotTypeJSToC(NotificationNapi::SlotType(slotType), actureType)) {
607 ANSR_LOGE("slot type not support.");
608 return false;
609 }
610 reminder->SetSlotType(actureType);
611 } else if (!reminder->IsSystemApp()) {
612 reminder->SetSlotType(NotificationConstant::SlotType::OTHER);
613 }
614
615 //autoDeletedTime
616 int64_t autoDeletedTime = 0;
617 if (GetInt64(env, value, ReminderAgentNapi::AUTODELETEDTIME, autoDeletedTime)) {
618 if (autoDeletedTime > 0) {
619 reminder->SetAutoDeletedTime(autoDeletedTime);
620 }
621 }
622 return GenReminderIntInnerOther(env, value, reminder);
623 }
624
GenReminderIntInnerOther(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)625 bool ReminderCommon::GenReminderIntInnerOther(
626 const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
627 {
628 int32_t resourceId = 0;
629 // title
630 if (GetInt32(env, value, ReminderAgentNapi::TITLE_RESOURCE_ID, resourceId, false)) {
631 reminder->SetTitleResourceId(resourceId);
632 }
633
634 // content
635 if (GetInt32(env, value, ReminderAgentNapi::CONTENT_RESOURCE_ID, resourceId, false)) {
636 reminder->SetContentResourceId(resourceId);
637 }
638
639 // expiredContent
640 if (GetInt32(env, value, ReminderAgentNapi::EXPIRED_CONTENT_RESOURCE_ID, resourceId, false)) {
641 reminder->SetExpiredContentResourceId(resourceId);
642 }
643
644 // snoozeContent
645 if (GetInt32(env, value, ReminderAgentNapi::SNOOZE_CONTENT_RESOURCE_ID, resourceId, false)) {
646 reminder->SetSnoozeContentResourceId(resourceId);
647 }
648 return true;
649 }
650
GenReminderBoolInner(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)651 void ReminderCommon::GenReminderBoolInner(
652 const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
653 {
654 // tapDismissed
655 bool tapDismissed = false;
656 if (GetBool(env, value, ReminderAgentNapi::TAPDISMISSED, tapDismissed)) {
657 reminder->SetTapDismissed(tapDismissed);
658 }
659 }
660
GetStringUtf8(const napi_env & env,const napi_value & value,const char * propertyName,char * propertyVal,const int32_t size)661 bool ReminderCommon::GetStringUtf8(const napi_env &env, const napi_value &value,
662 const char* propertyName, char* propertyVal, const int32_t size)
663 {
664 bool hasProperty = false;
665 napi_value result = nullptr;
666 napi_valuetype valuetype = napi_undefined;
667 size_t strLen = 0;
668
669 NAPI_CALL_BASE(env, napi_has_named_property(env, value, propertyName, &hasProperty), false);
670 if (hasProperty) {
671 napi_get_named_property(env, value, propertyName, &result);
672 NAPI_CALL_BASE(env, napi_typeof(env, result, &valuetype), false);
673 if (valuetype != napi_string) {
674 ANSR_LOGE("Wrong argument type:%{public}s. string expected.", propertyName);
675 return false;
676 }
677 NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, result, propertyVal, size - 1, &strLen), false);
678 }
679 return hasProperty;
680 }
681
GetBool(const napi_env & env,const napi_value & value,const char * propertyName,bool & propertyVal)682 bool ReminderCommon::GetBool(const napi_env &env, const napi_value &value,
683 const char* propertyName, bool& propertyVal)
684 {
685 bool hasProperty = false;
686 napi_value result = nullptr;
687 napi_valuetype valuetype = napi_undefined;
688 NAPI_CALL_BASE(env, napi_has_named_property(env, value, propertyName, &hasProperty), false);
689 if (!hasProperty) {
690 ANSR_LOGE("Does not have argument type:%{public}s.", propertyName);
691 return false;
692 }
693 napi_get_named_property(env, value, propertyName, &result);
694 NAPI_CALL_BASE(env, napi_typeof(env, result, &valuetype), false);
695 if (valuetype != napi_boolean) {
696 ANSR_LOGE("Wrong argument type:%{public}s. boolean expected.", propertyName);
697 return false;
698 }
699 napi_get_value_bool(env, result, &propertyVal);
700 return true;
701 }
702
GetInt32(const napi_env & env,const napi_value & value,const char * propertyName,int32_t & propertyVal,bool isNecessary)703 bool ReminderCommon::GetInt32(const napi_env &env, const napi_value &value,
704 const char* propertyName, int32_t& propertyVal, bool isNecessary)
705 {
706 napi_value result = nullptr;
707 if (!GetPropertyValIfExist(env, value, propertyName, result)) {
708 if (isNecessary) {
709 ANSR_LOGW("Correct property %{public}s expected.", propertyName);
710 }
711 return false;
712 }
713 napi_get_value_int32(env, result, &propertyVal);
714 return true;
715 }
716
GetInt64(const napi_env & env,const napi_value & value,const char * propertyName,int64_t & propertyVal)717 bool ReminderCommon::GetInt64(const napi_env &env, const napi_value &value,
718 const char* propertyName, int64_t& propertyVal)
719 {
720 napi_value result = nullptr;
721 if (!GetPropertyValIfExist(env, value, propertyName, result)) {
722 return false;
723 }
724 napi_get_value_int64(env, result, &propertyVal);
725 return true;
726 }
727
GetPropertyValIfExist(const napi_env & env,const napi_value & value,const char * propertyName,napi_value & propertyVal)728 bool ReminderCommon::GetPropertyValIfExist(const napi_env &env, const napi_value &value,
729 const char* propertyName, napi_value& propertyVal)
730 {
731 napi_valuetype valuetype = napi_undefined;
732 if (propertyName == nullptr) {
733 propertyVal = value;
734 } else {
735 bool hasProperty = false;
736 napi_status status = napi_has_named_property(env, value, propertyName, &hasProperty);
737 if (status != napi_ok || !hasProperty) {
738 return false;
739 }
740 napi_get_named_property(env, value, propertyName, &propertyVal);
741 }
742 napi_status status = napi_typeof(env, propertyVal, &valuetype);
743 if (status != napi_ok || valuetype != napi_number) {
744 if (propertyName == nullptr) {
745 ANSR_LOGW("Wrong argument type. number expected.");
746 } else {
747 ANSR_LOGW("Wrong argument type:%{public}s, number expected.", propertyName);
748 }
749 return false;
750 }
751 return true;
752 }
753
GetObject(const napi_env & env,const napi_value & value,const char * propertyName,napi_value & propertyVal)754 bool ReminderCommon::GetObject(const napi_env &env, const napi_value &value,
755 const char* propertyName, napi_value& propertyVal)
756 {
757 bool hasProperty = false;
758 napi_valuetype valuetype = napi_undefined;
759
760 NAPI_CALL_BASE(env, napi_has_named_property(env, value, propertyName, &hasProperty), false);
761 if (!hasProperty) {
762 return false;
763 }
764 napi_get_named_property(env, value, propertyName, &propertyVal);
765 NAPI_CALL_BASE(env, napi_typeof(env, propertyVal, &valuetype), false);
766 if (valuetype != napi_object) {
767 ANSR_LOGE("Wrong argument type:%{public}s. object expected.", propertyName);
768 return false;
769 }
770 return true;
771 }
772
GetDate(const napi_env & env,const napi_value & value,const char * propertyName,double & date)773 bool ReminderCommon::GetDate(const napi_env& env, const napi_value& value,
774 const char* propertyName, double& date)
775 {
776 napi_value propertyValue = nullptr;
777 if (propertyName == nullptr) {
778 propertyValue = value;
779 } else {
780 bool hasProperty = false;
781 NAPI_CALL_BASE(env, napi_has_named_property(env, value, propertyName, &hasProperty), false);
782 if (!hasProperty) {
783 ANSR_LOGE("");
784 return false;
785 }
786 napi_get_named_property(env, value, propertyName, &propertyValue);
787 }
788 bool isDate = false;
789 napi_is_date(env, propertyValue, &isDate);
790 if (!isDate) {
791 ANSR_LOGE("Wrong argument type. Date expected.");
792 return false;
793 }
794 napi_get_date_value(env, propertyValue, &date);
795 return true;
796 }
797
CreateReminderTimer(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)798 napi_value ReminderCommon::CreateReminderTimer(
799 const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
800 {
801 int64_t propertyCountDownTime = 0;
802 if (!GetInt64(env, value, ReminderAgentNapi::TIMER_COUNT_DOWN_TIME, propertyCountDownTime)) {
803 ANSR_LOGW("Correct property %{public}s expected.", ReminderAgentNapi::TIMER_COUNT_DOWN_TIME);
804 return nullptr;
805 }
806
807 auto countDownTimeInSeconds = static_cast<uint64_t>(propertyCountDownTime);
808 if (propertyCountDownTime <= 0 || countDownTimeInSeconds >= (UINT64_MAX / ReminderRequest::MILLI_SECONDS)) {
809 ANSR_LOGE("Create countDown reminder fail: designated %{public}s is illegal.",
810 ReminderAgentNapi::TIMER_COUNT_DOWN_TIME);
811 return nullptr;
812 }
813
814 reminder = std::make_shared<ReminderRequestTimer>(countDownTimeInSeconds);
815 return NotificationNapi::Common::NapiGetNull(env);
816 }
817
CreateReminderAlarm(const napi_env & env,const napi_value & value,std::shared_ptr<ReminderRequest> & reminder)818 napi_value ReminderCommon::CreateReminderAlarm(
819 const napi_env &env, const napi_value &value, std::shared_ptr<ReminderRequest>& reminder)
820 {
821 // hour
822 int32_t propertyHourVal = 0;
823 const int32_t maxHour = 23;
824 if (!GetInt32(env, value, ReminderAgentNapi::ALARM_HOUR, propertyHourVal, true)) {
825 return nullptr;
826 }
827
828 // minute
829 int32_t propertyMinuteVal = 0;
830 const int32_t maxMinute = 59;
831 if (!GetInt32(env, value, ReminderAgentNapi::ALARM_MINUTE, propertyMinuteVal, true)) {
832 return nullptr;
833 }
834
835 if ((propertyHourVal < 0) || (propertyHourVal > maxHour)) {
836 ANSR_LOGE("Create alarm reminder fail: designated %{public}s must between [0, 23].",
837 ReminderAgentNapi::ALARM_HOUR);
838 return nullptr;
839 }
840
841 if ((propertyMinuteVal < 0) || (propertyMinuteVal > maxMinute)) {
842 ANSR_LOGE("Create alarm reminder fail: designated %{public}s must between [0, 59].",
843 ReminderAgentNapi::ALARM_MINUTE);
844 return nullptr;
845 }
846
847 // daysOfWeek
848 std::vector<uint8_t> daysOfWeek;
849 uint8_t maxDaysOfWeek = 7;
850 if (ParseInt32Array(env, value, ReminderAgentNapi::REPEAT_DAYS_OF_WEEK, daysOfWeek, maxDaysOfWeek) == nullptr) {
851 return nullptr;
852 }
853 reminder = std::make_shared<ReminderRequestAlarm>(
854 static_cast<uint8_t>(propertyHourVal), static_cast<uint8_t>(propertyMinuteVal), daysOfWeek);
855 return NotificationNapi::Common::NapiGetNull(env);
856 }
857
CreateReminderCalendar(const napi_env & env,const napi_value & value,const bool isSysApp,std::shared_ptr<ReminderRequest> & reminder)858 napi_value ReminderCommon::CreateReminderCalendar(
859 const napi_env &env, const napi_value &value, const bool isSysApp, std::shared_ptr<ReminderRequest>& reminder)
860 {
861 struct tm dateTime;
862 napi_value dateTimeObj = nullptr;
863 if (!GetObject(env, value, ReminderAgentNapi::CALENDAR_DATE_TIME, dateTimeObj)) {
864 ANSR_LOGE("Create calendar reminder fail: dateTime must be setted.");
865 return nullptr;
866 }
867
868 if (!ParseLocalDateTime(env, dateTimeObj, dateTime)) {
869 ANSR_LOGE("Parce DateTime failed.");
870 return nullptr;
871 }
872
873 std::vector<uint8_t> repeatMonths;
874 std::vector<uint8_t> repeatDays;
875 std::vector<uint8_t> daysOfWeek;
876
877 if (!ParseCalendarParams(env, value, repeatMonths, repeatDays, daysOfWeek)) {
878 return nullptr;
879 }
880
881 // rruleWantAgent
882 std::shared_ptr<ReminderRequest::WantAgentInfo> wantAgentInfo;
883 if (!GenWantAgent(env, value, ReminderAgentNapi::RRULL_WANT_AGENT, wantAgentInfo)) {
884 return nullptr;
885 }
886 if (!isSysApp && wantAgentInfo != nullptr) {
887 ANS_LOGE("Not system app rrule want info not supported");
888 return nullptr;
889 }
890
891 auto reminderCalendar = std::make_shared<ReminderRequestCalendar>(dateTime, repeatMonths, repeatDays, daysOfWeek);
892 napi_value endDateTimeObj = nullptr;
893 if (GetObject(env, value, ReminderAgentNapi::CALENDAR_END_DATE_TIME, endDateTimeObj)) {
894 struct tm endDateTime;
895 if (!ParseLocalDateTime(env, endDateTimeObj, endDateTime)) {
896 return nullptr;
897 }
898 time_t endTime = mktime(&endDateTime);
899 if (endTime == -1) {
900 return nullptr;
901 }
902 if (!reminderCalendar->SetEndDateTime(ReminderRequest::GetDurationSinceEpochInMilli(endTime))) {
903 ANSR_LOGE("The end time must be greater than start time");
904 return nullptr;
905 }
906 }
907
908 if (!(reminderCalendar->InitTriggerTime())) {
909 return nullptr;
910 }
911 reminderCalendar->SetRRuleWantAgentInfo(wantAgentInfo);
912 reminder = reminderCalendar;
913 return NotificationNapi::Common::NapiGetNull(env);
914 }
915
CheckCalendarParams(const int32_t & year,const int32_t & month,const int32_t & day,const int32_t & hour,const int32_t & min)916 bool ReminderCommon::CheckCalendarParams(const int32_t &year, const int32_t &month, const int32_t &day,
917 const int32_t &hour, const int32_t &min)
918 {
919 if ((year < 0) || (year > UINT16_MAX)) {
920 ANSR_LOGE("Create calendar reminder fail: designated %{public}s must between [0, %{public}d]",
921 ReminderAgentNapi::CALENDAR_YEAR, UINT16_MAX);
922 return false;
923 }
924 if ((month < 1) || (month > ReminderRequestCalendar::MAX_MONTHS_OF_YEAR)) {
925 ANSR_LOGE("Create calendar reminder fail: designated %{public}s must between [1, %{public}hhu]",
926 ReminderAgentNapi::CALENDAR_MONTH, ReminderRequestCalendar::MAX_MONTHS_OF_YEAR);
927 return false;
928 }
929 uint8_t maxDaysOfMonth = ReminderRequestCalendar::GetDaysOfMonth(static_cast<uint16_t>(year), month);
930 if ((day < 1) || (day > maxDaysOfMonth)) {
931 ANSR_LOGE("Create calendar reminder fail: designated %{public}s must between [1, %{public}hhu]",
932 ReminderAgentNapi::CALENDAR_DAY, maxDaysOfMonth);
933 return false;
934 }
935 uint8_t maxHour = 23;
936 if (hour < 0 || hour > maxHour) {
937 ANSR_LOGE("Create calendar reminder fail: designated %{public}s must between [0, %{public}hhu]",
938 ReminderAgentNapi::CALENDAR_HOUR, maxHour);
939 return false;
940 }
941 uint8_t maxMinute = 59;
942 if (min < 0 || min > maxMinute) {
943 ANSR_LOGE("Create calendar reminder fail: designated %{public}s must between [0, %{public}hhu]",
944 ReminderAgentNapi::CALENDAR_MINUTE, maxMinute);
945 return false;
946 }
947 return true;
948 }
949
ParseCalendarParams(const napi_env & env,const napi_value & value,std::vector<uint8_t> & repeatMonths,std::vector<uint8_t> & repeatDays,std::vector<uint8_t> & daysOfWeek)950 bool ReminderCommon::ParseCalendarParams(const napi_env& env, const napi_value& value,
951 std::vector<uint8_t>& repeatMonths, std::vector<uint8_t>& repeatDays, std::vector<uint8_t>& daysOfWeek)
952 {
953 // repeatMonth
954 if (ParseInt32Array(env, value, ReminderAgentNapi::CALENDAR_REPEAT_MONTHS, repeatMonths,
955 ReminderRequestCalendar::MAX_MONTHS_OF_YEAR) == nullptr) {
956 return false;
957 }
958
959 // repeatDay
960 if (ParseInt32Array(env, value, ReminderAgentNapi::CALENDAR_REPEAT_DAYS, repeatDays,
961 ReminderRequestCalendar::MAX_DAYS_OF_MONTH) == nullptr) {
962 return false;
963 }
964
965 // daysOfWeek
966 uint8_t maxDaysOfWeek = 7;
967 if (ParseInt32Array(env, value, ReminderAgentNapi::REPEAT_DAYS_OF_WEEK, daysOfWeek, maxDaysOfWeek) == nullptr) {
968 return false;
969 }
970
971 return true;
972 }
973
ParseLocalDateTime(const napi_env & env,const napi_value & dateTimeObj,struct tm & dateTime)974 bool ReminderCommon::ParseLocalDateTime(const napi_env& env, const napi_value& dateTimeObj, struct tm& dateTime)
975 {
976 int32_t propertyYearVal = 0;
977 int32_t propertyMonthVal = 0;
978 int32_t propertyDayVal = 0;
979 int32_t propertyHourVal = 0;
980 int32_t propertyMinteVal = 0;
981 if (!GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_YEAR, propertyYearVal, true) ||
982 !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_MONTH, propertyMonthVal, true) ||
983 !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_DAY, propertyDayVal, true) ||
984 !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_HOUR, propertyHourVal, true) ||
985 !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_MINUTE, propertyMinteVal, true)) {
986 return false;
987 }
988
989 if (!CheckCalendarParams(propertyYearVal, propertyMonthVal, propertyDayVal,
990 propertyHourVal, propertyMinteVal)) {
991 return false;
992 }
993
994 dateTime.tm_year = ReminderRequest::GetCTime(ReminderRequest::TimeTransferType::YEAR, propertyYearVal);
995 dateTime.tm_mon = ReminderRequest::GetCTime(ReminderRequest::TimeTransferType::MONTH, propertyMonthVal);
996 dateTime.tm_mday = propertyDayVal;
997 dateTime.tm_hour = propertyHourVal;
998 dateTime.tm_min = propertyMinteVal;
999 dateTime.tm_sec = 0;
1000 dateTime.tm_isdst = -1;
1001 return true;
1002 }
1003
ParseInt32Array(const napi_env & env,const napi_value & value,const char * propertyName,std::vector<uint8_t> & propertyVal,uint8_t maxLen)1004 napi_value ReminderCommon::ParseInt32Array(const napi_env &env, const napi_value &value,
1005 const char* propertyName, std::vector<uint8_t> &propertyVal, uint8_t maxLen)
1006 {
1007 napi_value result = nullptr;
1008 if (!GetObject(env, value, propertyName, result)) {
1009 return NotificationNapi::Common::NapiGetNull(env);
1010 }
1011 if (result != nullptr) {
1012 bool isArray = false;
1013 napi_is_array(env, result, &isArray);
1014 if (!isArray) {
1015 ANSR_LOGE("Property %{public}s is expected to be an array.", propertyName);
1016 return nullptr;
1017 }
1018 uint32_t length = 0;
1019 napi_get_array_length(env, result, &length);
1020 if (length > maxLen) {
1021 ANSR_LOGE("The max length of array of %{public}s is %{public}hhu.", propertyName, maxLen);
1022 return nullptr;
1023 }
1024 napi_valuetype valuetype = napi_undefined;
1025 for (size_t i = 0; i < length; i++) {
1026 int32_t propertyDayVal = 10;
1027 napi_value repeatDayVal = nullptr;
1028 napi_get_element(env, result, i, &repeatDayVal);
1029 NAPI_CALL(env, napi_typeof(env, repeatDayVal, &valuetype));
1030 if (valuetype != napi_number) {
1031 ANSR_LOGE("%{public}s's element is expected to be number.", propertyName);
1032 return nullptr;
1033 }
1034 napi_get_value_int32(env, repeatDayVal, &propertyDayVal);
1035 if (propertyDayVal < 1 || propertyDayVal > static_cast<int32_t>(maxLen)) {
1036 ANSR_LOGE("%{public}s's element must between [1, %{public}d].", propertyName, maxLen);
1037 return nullptr;
1038 }
1039 propertyVal.push_back(static_cast<uint8_t>(propertyDayVal));
1040 }
1041 }
1042 return NotificationNapi::Common::NapiGetNull(env);
1043 }
1044
PaddingCallbackPromiseInfo(const napi_env & env,const napi_ref & callback,CallbackPromiseInfo & info,napi_value & promise)1045 void ReminderCommon::PaddingCallbackPromiseInfo(
1046 const napi_env &env, const napi_ref &callback, CallbackPromiseInfo &info, napi_value &promise)
1047 {
1048 if (callback) {
1049 info.callback = callback;
1050 info.isCallback = true;
1051 } else {
1052 napi_deferred deferred = nullptr;
1053 NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
1054 info.deferred = deferred;
1055 info.isCallback = false;
1056 }
1057 }
1058
HandleErrCode(const napi_env & env,int32_t errCode)1059 void ReminderCommon::HandleErrCode(const napi_env &env, int32_t errCode)
1060 {
1061 if (errCode == ERR_OK) {
1062 return;
1063 }
1064 std::string errCodeMsg = reminderErrCodeMsgMap[errCode];
1065 napi_throw_error(env, std::to_string(errCode).c_str(), errCodeMsg.c_str());
1066 }
1067
FindErrMsg(const napi_env & env,const int32_t errCode)1068 std::string ReminderCommon::FindErrMsg(const napi_env &env, const int32_t errCode)
1069 {
1070 auto findMsg = reminderErrCodeMsgMap.find(errCode);
1071 if (findMsg == reminderErrCodeMsgMap.end()) {
1072 ANSR_LOGI("Inner error.");
1073 return "Inner error.";
1074 }
1075 return reminderErrCodeMsgMap[errCode];
1076 }
1077
ReturnCallbackPromise(const napi_env & env,const CallbackPromiseInfo & info,const napi_value & result,bool isThrow)1078 void ReminderCommon::ReturnCallbackPromise(const napi_env &env, const CallbackPromiseInfo &info,
1079 const napi_value &result, bool isThrow)
1080 {
1081 ANSR_LOGD("start, errorCode=%{public}d", info.errorCode);
1082 if (info.isCallback) {
1083 if (isThrow) {
1084 SetCallback(env, info.callback, info.errorCode, result);
1085 } else {
1086 NotificationNapi::Common::SetCallback(env, info.callback, info.errorCode, result, false);
1087 }
1088 } else {
1089 SetPromise(env, info, result);
1090 }
1091 ANSR_LOGD("end");
1092 }
1093
SetCallback(const napi_env & env,const napi_ref & callbackIn,const int32_t & errCode,const napi_value & result)1094 void ReminderCommon::SetCallback(
1095 const napi_env &env, const napi_ref &callbackIn, const int32_t &errCode, const napi_value &result)
1096 {
1097 napi_value undefined = nullptr;
1098 napi_get_undefined(env, &undefined);
1099
1100 napi_value callback = nullptr;
1101 napi_value resultout = nullptr;
1102 napi_get_reference_value(env, callbackIn, &callback);
1103 napi_value results[ASYNC_CALLBACK_PARAM_NUM] = {nullptr};
1104 if (errCode == ERR_OK) {
1105 results[0] = NotificationNapi::Common::NapiGetNull(env);
1106 } else {
1107 std::string errMsg = FindErrMsg(env, errCode);
1108 results[0] = GetCallbackErrorValue(env, errCode, errMsg);
1109 }
1110 results[1] = result;
1111 NAPI_CALL_RETURN_VOID(env,
1112 napi_call_function(env, undefined, callback, ASYNC_CALLBACK_PARAM_NUM, &results[0], &resultout));
1113 }
1114
GetCallbackErrorValue(napi_env env,const int32_t errCode,const std::string errMsg)1115 napi_value ReminderCommon::GetCallbackErrorValue(napi_env env, const int32_t errCode, const std::string errMsg)
1116 {
1117 if (errCode == ERR_OK) {
1118 return NotificationNapi::Common::NapiGetNull(env);
1119 }
1120 napi_value error = nullptr;
1121 napi_value eCode = nullptr;
1122 napi_value eMsg = nullptr;
1123 NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
1124 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
1125 errMsg.length(), &eMsg));
1126 NAPI_CALL(env, napi_create_object(env, &error));
1127 NAPI_CALL(env, napi_set_named_property(env, error, "code", eCode));
1128 NAPI_CALL(env, napi_set_named_property(env, error, "message", eMsg));
1129 return error;
1130 }
1131
SetPromise(const napi_env & env,const CallbackPromiseInfo & info,const napi_value & result)1132 napi_value ReminderCommon::SetPromise(
1133 const napi_env &env, const CallbackPromiseInfo &info, const napi_value &result)
1134 {
1135 if (info.errorCode == ERR_OK) {
1136 napi_resolve_deferred(env, info.deferred, result);
1137 } else {
1138 std::string errMsg = FindErrMsg(env, info.errorCode);
1139 if (errMsg == "") {
1140 return nullptr;
1141 }
1142 napi_value error = nullptr;
1143 napi_value eCode = nullptr;
1144 napi_value eMsg = nullptr;
1145 NAPI_CALL(env, napi_create_int32(env, info.errorCode, &eCode));
1146 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
1147 errMsg.length(), &eMsg));
1148 NAPI_CALL(env, napi_create_object(env, &error));
1149 NAPI_CALL(env, napi_set_named_property(env, error, "data", eCode));
1150 NAPI_CALL(env, napi_set_named_property(env, error, "code", eCode));
1151 NAPI_CALL(env, napi_set_named_property(env, error, "message", eMsg));
1152 napi_reject_deferred(env, info.deferred, error);
1153 }
1154 return result;
1155 }
1156
JSParaError(const napi_env & env,const napi_ref & callback)1157 napi_value ReminderCommon::JSParaError(const napi_env &env, const napi_ref &callback)
1158 {
1159 if (callback) {
1160 SetCallback(env, callback, ERR_REMINDER_INVALID_PARAM, nullptr);
1161 return NotificationNapi::Common::NapiGetNull(env);
1162 } else {
1163 napi_value promise = nullptr;
1164 napi_deferred deferred = nullptr;
1165 napi_create_promise(env, &deferred, &promise);
1166
1167 napi_value res = nullptr;
1168 napi_value eCode = nullptr;
1169 napi_value eMsg = nullptr;
1170 std::string errMsg = FindErrMsg(env, ERR_REMINDER_INVALID_PARAM);
1171 NAPI_CALL(env, napi_create_int32(env, ERR_REMINDER_INVALID_PARAM, &eCode));
1172 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
1173 errMsg.length(), &eMsg));
1174 NAPI_CALL(env, napi_create_object(env, &res));
1175 NAPI_CALL(env, napi_set_named_property(env, res, "data", eCode));
1176 NAPI_CALL(env, napi_set_named_property(env, res, "code", eCode));
1177 NAPI_CALL(env, napi_set_named_property(env, res, "message", eMsg));
1178 napi_reject_deferred(env, deferred, res);
1179 return promise;
1180 }
1181 }
1182 }
1183 }
1184