1/*
2 * Copyright (c) 2024 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 "notification_napi.h"
17#include "ans_inner_errors.h"
18#include "location_log.h"
19#include "js_native_api.h"
20#include "js_native_api_types.h"
21#include "napi_common.h"
22#include "napi_common_util.h"
23#include "notification_action_button.h"
24#include "notification_capsule.h"
25#include "notification_constant.h"
26#include "notification_local_live_view_content.h"
27#include "notification_progress.h"
28#include "notification_time.h"
29#include "pixel_map_napi.h"
30
31namespace OHOS {
32namespace Location {
33std::set<std::shared_ptr<AbilityRuntime::WantAgent::WantAgent>> NotificationNapi::wantAgent_;
34std::mutex NotificationNapi::mutex_;
35
36NotificationNapi::NotificationNapi()
37{}
38
39NotificationNapi::~NotificationNapi()
40{}
41
42napi_value NotificationNapi::GetNotificationSubscriberInfo(
43    const napi_env &env, const napi_value &value, NotificationSubscribeInfo &subscriberInfo)
44{
45    LBSLOGD(NAPI_UTILS, "enter");
46    uint32_t length = 0;
47    size_t strLen = 0;
48    bool hasProperty = false;
49    bool isArray = false;
50    napi_valuetype valuetype = napi_undefined;
51
52    // bundleNames?: Array<string>
53    NAPI_CALL(env, napi_has_named_property(env, value, "bundleNames", &hasProperty));
54    if (hasProperty) {
55        napi_value nBundleNames = nullptr;
56        napi_get_named_property(env, value, "bundleNames", &nBundleNames);
57        napi_is_array(env, nBundleNames, &isArray);
58        if (!isArray) {
59            LBSLOGE(NAPI_UTILS, "Property bundleNames is expected to be an array.");
60            return nullptr;
61        }
62        napi_get_array_length(env, nBundleNames, &length);
63        if (length == 0) {
64            LBSLOGE(NAPI_UTILS, "The array is empty.");
65            return nullptr;
66        }
67        for (uint32_t i = 0; i < length; ++i) {
68            napi_value nBundleName = nullptr;
69            char str[STR_MAX_SIZE] = {0};
70            napi_get_element(env, nBundleNames, i, &nBundleName);
71            NAPI_CALL(env, napi_typeof(env, nBundleName, &valuetype));
72            if (valuetype != napi_string) {
73                LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
74                return nullptr;
75            }
76            NAPI_CALL(env, napi_get_value_string_utf8(env, nBundleName, str, STR_MAX_SIZE - 1, &strLen));
77            subscriberInfo.bundleNames.emplace_back(str);
78            subscriberInfo.hasSubscribeInfo = true;
79        }
80    }
81
82    // userId?: number
83    NAPI_CALL(env, napi_has_named_property(env, value, "userId", &hasProperty));
84    if (hasProperty) {
85        napi_value nUserId = nullptr;
86        napi_get_named_property(env, value, "userId", &nUserId);
87        NAPI_CALL(env, napi_typeof(env, nUserId, &valuetype));
88        if (valuetype != napi_number) {
89            LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
90            return nullptr;
91        }
92        NAPI_CALL(env, napi_get_value_int32(env, nUserId, &subscriberInfo.userId));
93        subscriberInfo.hasSubscribeInfo = true;
94    }
95
96    return NapiGetNull(env);
97}
98
99napi_value NotificationNapi::GetNotificationUserInput(
100    const napi_env &env, const napi_value &actionButton, std::shared_ptr<NotificationActionButton> &pActionButton)
101{
102    LBSLOGD(NAPI_UTILS, "enter");
103    napi_valuetype valuetype = napi_undefined;
104    napi_value userInputResult = nullptr;
105    bool hasProperty = false;
106
107    // userInput?: NotificationUserInput
108    NAPI_CALL(env, napi_has_named_property(env, actionButton, "userInput", &hasProperty));
109    if (hasProperty) {
110        napi_get_named_property(env, actionButton, "userInput", &userInputResult);
111        NAPI_CALL(env, napi_typeof(env, userInputResult, &valuetype));
112        if (valuetype != napi_object) {
113            LBSLOGE(NAPI_UTILS, "Wrong argument type. Object expected.");
114            return nullptr;
115        }
116        std::shared_ptr<NotificationUserInput> userInput = nullptr;
117
118        if (!GetNotificationUserInputByInputKey(env, userInputResult, userInput)) {
119            return nullptr;
120        }
121        pActionButton->AddNotificationUserInput(userInput);
122    }
123
124    return NapiGetNull(env);
125}
126
127napi_value NotificationNapi::GetNotificationUserInputByInputKey(
128    const napi_env &env, const napi_value &userInputResult, std::shared_ptr<NotificationUserInput> &userInput)
129{
130    LBSLOGD(NAPI_UTILS, "enter");
131    napi_valuetype valuetype = napi_undefined;
132    napi_value value = nullptr;
133    bool hasProperty = false;
134    char str[STR_MAX_SIZE] = {0};
135    size_t strLen = 0;
136
137    // inputKey: string
138    NAPI_CALL(env, napi_has_named_property(env, userInputResult, "inputKey", &hasProperty));
139    if (!hasProperty) {
140        LBSLOGE(NAPI_UTILS, "Property inputKey expected.");
141        return nullptr;
142    }
143    napi_get_named_property(env, userInputResult, "inputKey", &value);
144    NAPI_CALL(env, napi_typeof(env, value, &valuetype));
145    if (valuetype != napi_string) {
146        LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
147        return nullptr;
148    }
149    NAPI_CALL(env, napi_get_value_string_utf8(env, value, str, STR_MAX_SIZE - 1, &strLen));
150    LBSLOGI(NAPI_UTILS, "NotificationUserInput::inputKey = %{public}s", str);
151    userInput = NotificationUserInput::Create(str);
152    if (!userInput) {
153        LBSLOGI(NAPI_UTILS, "Failed to create NotificationUserInput by inputKey=%{public}s", str);
154        return nullptr;
155    }
156
157    return NapiGetNull(env);
158}
159
160napi_value NotificationNapi::GetNotificationUserInputByTag(
161    const napi_env &env, const napi_value &userInputResult, std::shared_ptr<NotificationUserInput> &userInput)
162{
163    LBSLOGD(NAPI_UTILS, "enter");
164
165    napi_valuetype valuetype = napi_undefined;
166    napi_value value = nullptr;
167    bool hasProperty = false;
168    char str[STR_MAX_SIZE] = {0};
169    size_t strLen = 0;
170
171    if (!userInput) {
172        LBSLOGE(NAPI_UTILS, "userInput is nullptr");
173        return nullptr;
174    }
175    // tag: string
176    NAPI_CALL(env, napi_has_named_property(env, userInputResult, "tag", &hasProperty));
177    if (!hasProperty) {
178        LBSLOGE(NAPI_UTILS, "Property tag expected.");
179        return nullptr;
180    }
181    napi_get_named_property(env, userInputResult, "tag", &value);
182    NAPI_CALL(env, napi_typeof(env, value, &valuetype));
183    if (valuetype != napi_string) {
184        LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
185        return nullptr;
186    }
187    NAPI_CALL(env, napi_get_value_string_utf8(env, value, str, STR_MAX_SIZE - 1, &strLen));
188    userInput->SetTag(str);
189    LBSLOGI(NAPI_UTILS, "NotificationUserInput::tag = %{public}s", str);
190
191    return NapiGetNull(env);
192}
193
194napi_value NotificationNapi::GetNotificationUserInputByOptions(
195    const napi_env &env, const napi_value &userInputResult, std::shared_ptr<NotificationUserInput> &userInput)
196{
197    LBSLOGD(NAPI_UTILS, "enter");
198
199    napi_valuetype valuetype = napi_undefined;
200    napi_value value = nullptr;
201    bool hasProperty = false;
202    uint32_t length = 0;
203    size_t strLen = 0;
204    bool isArray = false;
205
206    if (!userInput) {
207        LBSLOGE(NAPI_UTILS, "userInput is nullptr");
208        return nullptr;
209    }
210
211    // options: Array<string>
212    NAPI_CALL(env, napi_has_named_property(env, userInputResult, "options", &hasProperty));
213
214    if (!hasProperty) {
215        LBSLOGE(NAPI_UTILS, "Property options expected.");
216        return nullptr;
217    }
218    napi_get_named_property(env, userInputResult, "options", &value);
219    napi_is_array(env, value, &isArray);
220    if (!isArray) {
221        LBSLOGE(NAPI_UTILS, "Property options is expected to be an array.");
222        return nullptr;
223    }
224    napi_get_array_length(env, value, &length);
225    if (length == 0) {
226        LBSLOGE(NAPI_UTILS, "The array is empty.");
227        return nullptr;
228    }
229    std::vector<std::string> options;
230    for (uint32_t i = 0; i < length; ++i) {
231        napi_value option = nullptr;
232        char str[STR_MAX_SIZE] = {0};
233        napi_get_element(env, value, i, &option);
234        NAPI_CALL(env, napi_typeof(env, option, &valuetype));
235        if (valuetype != napi_string) {
236            LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
237            return nullptr;
238        }
239        NAPI_CALL(env, napi_get_value_string_utf8(env, option, str, STR_MAX_SIZE - 1, &strLen));
240        options.emplace_back(str);
241    }
242    userInput->SetOptions(options);
243
244    return NapiGetNull(env);
245}
246
247napi_value NotificationNapi::GetNotificationUserInputByPermitMimeTypes(
248    const napi_env &env, const napi_value &userInputResult, std::shared_ptr<NotificationUserInput> &userInput)
249{
250    LBSLOGD(NAPI_UTILS, "enter");
251
252    napi_valuetype valuetype = napi_undefined;
253    napi_value value = nullptr;
254    bool hasProperty = false;
255    size_t strLen = 0;
256    uint32_t length = 0;
257    bool isArray = false;
258
259    if (!userInput) {
260        LBSLOGE(NAPI_UTILS, "userInput is nullptr");
261        return nullptr;
262    }
263
264    // permitMimeTypes?: Array<string>
265    NAPI_CALL(env, napi_has_named_property(env, userInputResult, "permitMimeTypes", &hasProperty));
266    if (hasProperty) {
267        napi_get_named_property(env, userInputResult, "permitMimeTypes", &value);
268        napi_is_array(env, value, &isArray);
269        if (!isArray) {
270            LBSLOGE(NAPI_UTILS, "Property permitMimeTypes is expected to be an array.");
271            return nullptr;
272        }
273        napi_get_array_length(env, value, &length);
274        if (length == 0) {
275            LBSLOGE(NAPI_UTILS, "The array is empty.");
276            return nullptr;
277        }
278        for (uint32_t i = 0; i < length; ++i) {
279            napi_value permitMimeType = nullptr;
280            char str[STR_MAX_SIZE] = {0};
281            napi_get_element(env, value, i, &permitMimeType);
282            NAPI_CALL(env, napi_typeof(env, permitMimeType, &valuetype));
283            if (valuetype != napi_string) {
284                LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
285                return nullptr;
286            }
287            NAPI_CALL(env, napi_get_value_string_utf8(env, permitMimeType, str, STR_MAX_SIZE - 1, &strLen));
288            userInput->SetPermitMimeTypes(str, true);
289        }
290    }
291
292    return NapiGetNull(env);
293}
294
295napi_value NotificationNapi::GetNotificationUserInputByPermitFreeFormInput(
296    const napi_env &env, const napi_value &userInputResult, std::shared_ptr<NotificationUserInput> &userInput)
297{
298    LBSLOGD(NAPI_UTILS, "enter");
299    napi_value value = nullptr;
300    napi_valuetype valuetype = napi_undefined;
301    bool hasProperty = false;
302
303    if (!userInput) {
304        LBSLOGE(NAPI_UTILS, "userInput is nullptr");
305        return nullptr;
306    }
307
308    // permitFreeFormInput?: boolean
309    NAPI_CALL(env, napi_has_named_property(env, userInputResult, "permitFreeFormInput", &hasProperty));
310    if (hasProperty) {
311        bool permitFreeFormInput = false;
312        napi_get_named_property(env, userInputResult, "permitFreeFormInput", &value);
313        NAPI_CALL(env, napi_typeof(env, value, &valuetype));
314        if (valuetype != napi_boolean) {
315            LBSLOGE(NAPI_UTILS, "Wrong argument type. Bool expected.");
316            return nullptr;
317        }
318        napi_get_value_bool(env, value, &permitFreeFormInput);
319        LBSLOGI(NAPI_UTILS, "permitFreeFormInput is: %{public}d", permitFreeFormInput);
320        userInput->SetPermitFreeFormInput(permitFreeFormInput);
321    }
322
323    return NapiGetNull(env);
324}
325
326napi_value NotificationNapi::GetNotificationUserInputByEditType(
327    const napi_env &env, const napi_value &userInputResult, std::shared_ptr<NotificationUserInput> &userInput)
328{
329    LBSLOGD(NAPI_UTILS, "enter");
330    napi_value value = nullptr;
331    napi_valuetype valuetype = napi_undefined;
332    bool hasProperty = false;
333    int32_t editType = 0;
334
335    if (!userInput) {
336        LBSLOGE(NAPI_UTILS, "userInput is nullptr");
337        return nullptr;
338    }
339
340    // editType?: number
341    NAPI_CALL(env, napi_has_named_property(env, userInputResult, "editType", &hasProperty));
342    if (hasProperty) {
343        napi_get_named_property(env, userInputResult, "editType", &value);
344        NAPI_CALL(env, napi_typeof(env, value, &valuetype));
345        if (valuetype != napi_number) {
346            LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
347            return nullptr;
348        }
349        napi_get_value_int32(env, value, &editType);
350        userInput->SetEditType(NotificationConstant::InputEditType(editType));
351    }
352    return NapiGetNull(env);
353}
354
355napi_value NotificationNapi::GetNotificationUserInputByAdditionalData(
356    const napi_env &env, const napi_value &userInputResult, std::shared_ptr<NotificationUserInput> &userInput)
357{
358    LBSLOGD(NAPI_UTILS, "enter");
359
360    napi_valuetype valuetype = napi_undefined;
361    napi_value result = nullptr;
362    bool hasProperty = false;
363
364    if (!userInput) {
365        LBSLOGE(NAPI_UTILS, "userInput is nullptr");
366        return nullptr;
367    }
368
369    // additionalData?: {[key: string]: Object}
370    NAPI_CALL(env, napi_has_named_property(env, userInputResult, "additionalData", &hasProperty));
371    if (hasProperty) {
372        napi_get_named_property(env, userInputResult, "additionalData", &result);
373        NAPI_CALL(env, napi_typeof(env, result, &valuetype));
374        if (valuetype != napi_object) {
375            LBSLOGE(NAPI_UTILS, "Wrong argument type. Object expected.");
376            return nullptr;
377        }
378        AAFwk::WantParams wantParams;
379        if (!OHOS::AppExecFwk::UnwrapWantParams(env, result, wantParams)) {
380            return nullptr;
381        }
382        userInput->AddAdditionalData(wantParams);
383    }
384
385    return NapiGetNull(env);
386}
387
388napi_value NotificationNapi::GetNotificationContentType(const napi_env &env, const napi_value &result, int32_t &type)
389{
390    LBSLOGD(NAPI_UTILS, "enter");
391
392    napi_value contentResult = nullptr;
393    napi_valuetype valuetype = napi_undefined;
394    bool hasNotificationContentType = false;
395    bool hasContentType = false;
396
397    NAPI_CALL(env, napi_has_named_property(env, result, "notificationContentType", &hasNotificationContentType));
398    if (hasNotificationContentType) {
399        napi_get_named_property(env, result, "notificationContentType", &contentResult);
400        NAPI_CALL(env, napi_typeof(env, contentResult, &valuetype));
401        if (valuetype != napi_number) {
402            LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
403            return nullptr;
404        }
405        napi_get_value_int32(env, contentResult, &type);
406
407        return NapiGetNull(env);
408    } else {
409        LBSLOGE(NAPI_UTILS, "Property notificationContentType expected.");
410    }
411
412    NAPI_CALL(env, napi_has_named_property(env, result, "contentType", &hasContentType));
413    if (hasContentType) {
414        napi_get_named_property(env, result, "contentType", &contentResult);
415        NAPI_CALL(env, napi_typeof(env, contentResult, &valuetype));
416        if (valuetype != napi_number) {
417            LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
418            return nullptr;
419        }
420        napi_get_value_int32(env, contentResult, &type);
421
422        return NapiGetNull(env);
423    } else {
424        LBSLOGE(NAPI_UTILS, "Property contentType expected.");
425        return nullptr;
426    }
427}
428
429napi_value NotificationNapi::GetNotificationSlot(const napi_env &env, const napi_value &value, NotificationSlot &slot)
430{
431    LBSLOGD(NAPI_UTILS, "enter");
432
433    napi_value nobj = nullptr;
434    napi_valuetype valuetype = napi_undefined;
435    bool hasType = false;
436    bool hasNotificationType = false;
437    int slotType = 0;
438
439    NAPI_CALL(env, napi_has_named_property(env, value, "notificationType", &hasNotificationType));
440    NAPI_CALL(env, napi_has_named_property(env, value, "type", &hasType));
441    if (hasNotificationType) {
442        napi_get_named_property(env, value, "notificationType", &nobj);
443        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
444        if (valuetype != napi_number) {
445            LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
446            return nullptr;
447        }
448    } else if (!hasNotificationType && hasType) {
449        napi_get_named_property(env, value, "type", &nobj);
450        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
451        if (valuetype != napi_number) {
452            LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
453            return nullptr;
454        }
455    } else {
456        LBSLOGE(NAPI_UTILS, "Property notificationType or type expected.");
457        return nullptr;
458    }
459
460    if (nobj != nullptr) {
461        napi_get_value_int32(env, nobj, &slotType);
462    }
463
464    NotificationConstant::SlotType outType = NotificationConstant::SlotType::OTHER;
465    if (!AnsEnumUtil::SlotTypeJSToC(SlotType(slotType), outType)) {
466        return nullptr;
467    }
468    slot.SetType(outType);
469
470    if (GetNotificationSlotByString(env, value, slot) == nullptr) {
471        return nullptr;
472    }
473    if (GetNotificationSlotByNumber(env, value, slot) == nullptr) {
474        return nullptr;
475    }
476    if (GetNotificationSlotByVibration(env, value, slot) == nullptr) {
477        return nullptr;
478    }
479    if (GetNotificationSlotByBool(env, value, slot) == nullptr) {
480        return nullptr;
481    }
482    return NapiGetNull(env);
483}
484
485napi_value NotificationNapi::GetNotificationSlotByString(
486    const napi_env &env, const napi_value &value, NotificationSlot &slot)
487{
488    LBSLOGD(NAPI_UTILS, "enter");
489
490    napi_value nobj = nullptr;
491    napi_valuetype valuetype = napi_undefined;
492    bool hasProperty = false;
493    size_t strLen = 0;
494
495    // desc?: string
496    NAPI_CALL(env, napi_has_named_property(env, value, "desc", &hasProperty));
497    if (hasProperty) {
498        std::string desc;
499        char str[STR_MAX_SIZE] = {0};
500        napi_get_named_property(env, value, "desc", &nobj);
501        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
502        if (valuetype != napi_string) {
503            LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
504            return nullptr;
505        }
506        NAPI_CALL(env, napi_get_value_string_utf8(env, nobj, str, STR_MAX_SIZE - 1, &strLen));
507        desc = str;
508        LBSLOGI(NAPI_UTILS, "desc is: %{public}s", desc.c_str());
509        slot.SetDescription(desc);
510    }
511
512    // sound?: string
513    NAPI_CALL(env, napi_has_named_property(env, value, "sound", &hasProperty));
514    if (hasProperty) {
515        std::string sound;
516        char str[STR_MAX_SIZE] = {0};
517        napi_get_named_property(env, value, "sound", &nobj);
518        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
519        if (valuetype != napi_string) {
520            LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
521            return nullptr;
522        }
523        NAPI_CALL(env, napi_get_value_string_utf8(env, nobj, str, STR_MAX_SIZE - 1, &strLen));
524        sound = str;
525        LBSLOGI(NAPI_UTILS, "sound is: %{public}s", sound.c_str());
526        slot.SetSound(Uri(sound));
527    }
528
529    return NapiGetNull(env);
530}
531
532napi_value NotificationNapi::GetNotificationSlotByBool(
533    const napi_env &env, const napi_value &value, NotificationSlot &slot)
534{
535    LBSLOGD(NAPI_UTILS, "enter");
536    napi_value nobj = nullptr;
537    napi_valuetype valuetype = napi_undefined;
538    bool hasProperty = false;
539
540    // badgeFlag?: boolean
541    NAPI_CALL(env, napi_has_named_property(env, value, "badgeFlag", &hasProperty));
542    if (hasProperty) {
543        bool badgeFlag = false;
544        napi_get_named_property(env, value, "badgeFlag", &nobj);
545        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
546        if (valuetype != napi_boolean) {
547            LBSLOGE(NAPI_UTILS, "Wrong argument type. Bool expected.");
548            return nullptr;
549        }
550        napi_get_value_bool(env, nobj, &badgeFlag);
551        LBSLOGI(NAPI_UTILS, "badgeFlag is: %{public}d", badgeFlag);
552        slot.EnableBadge(badgeFlag);
553    }
554
555    // bypassDnd?: boolean
556    NAPI_CALL(env, napi_has_named_property(env, value, "bypassDnd", &hasProperty));
557    if (hasProperty) {
558        bool bypassDnd = false;
559        napi_get_named_property(env, value, "bypassDnd", &nobj);
560        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
561        if (valuetype != napi_boolean) {
562            LBSLOGE(NAPI_UTILS, "Wrong argument type. Bool expected.");
563            return nullptr;
564        }
565        napi_get_value_bool(env, nobj, &bypassDnd);
566        LBSLOGI(NAPI_UTILS, "bypassDnd is: %{public}d", bypassDnd);
567        slot.EnableBypassDnd(bypassDnd);
568    }
569
570    // lightEnabled?: boolean
571    NAPI_CALL(env, napi_has_named_property(env, value, "lightEnabled", &hasProperty));
572    if (hasProperty) {
573        bool lightEnabled = false;
574        napi_get_named_property(env, value, "lightEnabled", &nobj);
575        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
576        if (valuetype != napi_boolean) {
577            LBSLOGE(NAPI_UTILS, "Wrong argument type. Bool expected.");
578            return nullptr;
579        }
580        napi_get_value_bool(env, nobj, &lightEnabled);
581        LBSLOGI(NAPI_UTILS, "lightEnabled is: %{public}d", lightEnabled);
582        slot.SetEnableLight(lightEnabled);
583    }
584
585    return NapiGetNull(env);
586}
587
588napi_value NotificationNapi::GetNotificationSlotByNumber(
589    const napi_env &env, const napi_value &value, NotificationSlot &slot)
590{
591    LBSLOGD(NAPI_UTILS, "enter");
592
593    napi_value nobj = nullptr;
594    napi_valuetype valuetype = napi_undefined;
595    bool hasProperty = false;
596
597    // level?: number
598    NAPI_CALL(env, napi_has_named_property(env, value, "level", &hasProperty));
599    if (hasProperty) {
600        int inLevel = 0;
601        napi_get_named_property(env, value, "level", &nobj);
602        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
603        if (valuetype != napi_number) {
604            LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
605            return nullptr;
606        }
607        napi_get_value_int32(env, nobj, &inLevel);
608        LBSLOGI(NAPI_UTILS, "level is: %{public}d", inLevel);
609
610        NotificationSlot::NotificationLevel outLevel {NotificationSlot::NotificationLevel::LEVEL_NONE};
611        if (!AnsEnumUtil::SlotLevelJSToC(SlotLevel(inLevel), outLevel)) {
612            return nullptr;
613        }
614        slot.SetLevel(outLevel);
615    }
616
617    // lockscreenVisibility?: number
618    NAPI_CALL(env, napi_has_named_property(env, value, "lockscreenVisibility", &hasProperty));
619    if (hasProperty) {
620        int lockscreenVisibility = 0;
621        napi_get_named_property(env, value, "lockscreenVisibility", &nobj);
622        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
623        if (valuetype != napi_number) {
624            LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
625            return nullptr;
626        }
627        napi_get_value_int32(env, nobj, &lockscreenVisibility);
628        LBSLOGI(NAPI_UTILS, "lockscreenVisibility is: %{public}d", lockscreenVisibility);
629        slot.SetLockscreenVisibleness(NotificationConstant::VisiblenessType(lockscreenVisibility));
630    }
631
632    // lightColor?: number
633    NAPI_CALL(env, napi_has_named_property(env, value, "lightColor", &hasProperty));
634    if (hasProperty) {
635        int lightColor = 0;
636        napi_get_named_property(env, value, "lightColor", &nobj);
637        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
638        if (valuetype != napi_number) {
639            LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
640            return nullptr;
641        }
642        napi_get_value_int32(env, nobj, &lightColor);
643        LBSLOGI(NAPI_UTILS, "lightColor is: %{public}d", lightColor);
644        slot.SetLedLightColor(lightColor);
645    }
646    return NapiGetNull(env);
647}
648
649napi_value NotificationNapi::GetNotificationSlotByVibration(
650    const napi_env &env, const napi_value &value, NotificationSlot &slot)
651{
652    LBSLOGD(NAPI_UTILS, "enter");
653    napi_value nobj = nullptr;
654    napi_valuetype valuetype = napi_undefined;
655    bool hasProperty = false;
656    uint32_t length = 0;
657
658    // vibrationEnabled?: boolean
659    bool vibrationEnabled = false;
660    NAPI_CALL(env, napi_has_named_property(env, value, "vibrationEnabled", &hasProperty));
661    if (hasProperty) {
662        napi_get_named_property(env, value, "vibrationEnabled", &nobj);
663        NAPI_CALL(env, napi_typeof(env, nobj, &valuetype));
664        if (valuetype != napi_boolean) {
665            LBSLOGE(NAPI_UTILS, "Wrong argument type. Bool expected.");
666            return nullptr;
667        }
668
669        napi_get_value_bool(env, nobj, &vibrationEnabled);
670        slot.SetEnableVibration(vibrationEnabled);
671    }
672
673    if (!vibrationEnabled) {
674        return NapiGetNull(env);
675    }
676
677    // vibrationValues?: Array<number>
678    NAPI_CALL(env, napi_has_named_property(env, value, "vibrationValues", &hasProperty));
679    if (hasProperty) {
680        bool isArray = false;
681        napi_get_named_property(env, value, "vibrationValues", &nobj);
682        napi_is_array(env, nobj, &isArray);
683        if (!isArray) {
684            LBSLOGE(NAPI_UTILS, "Property vibrationValues is expected to be an array.");
685            return nullptr;
686        }
687
688        napi_get_array_length(env, nobj, &length);
689        std::vector<int64_t> vibrationValues;
690        for (size_t i = 0; i < length; i++) {
691            napi_value nVibrationValue = nullptr;
692            int64_t vibrationValue = 0;
693            napi_get_element(env, nobj, i, &nVibrationValue);
694            NAPI_CALL(env, napi_typeof(env, nVibrationValue, &valuetype));
695            if (valuetype != napi_number) {
696                LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
697                return nullptr;
698            }
699            napi_get_value_int64(env, nVibrationValue, &vibrationValue);
700            vibrationValues.emplace_back(vibrationValue);
701        }
702        slot.SetVibrationStyle(vibrationValues);
703    }
704
705    return NapiGetNull(env);
706}
707
708napi_value NotificationNapi::GetBundleOption(
709    const napi_env &env, const napi_value &value, NotificationBundleOption &option)
710{
711    LBSLOGD(NAPI_UTILS, "enter");
712
713    bool hasProperty {false};
714    napi_valuetype valuetype = napi_undefined;
715    napi_value result = nullptr;
716
717    char str[STR_MAX_SIZE] = {0};
718    size_t strLen = 0;
719    // bundle: string
720    NAPI_CALL(env, napi_has_named_property(env, value, "bundle", &hasProperty));
721    if (!hasProperty) {
722        LBSLOGE(NAPI_UTILS, "Property bundle expected.");
723        return nullptr;
724    }
725    napi_get_named_property(env, value, "bundle", &result);
726    NAPI_CALL(env, napi_typeof(env, result, &valuetype));
727    if (valuetype != napi_string) {
728        LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
729        return nullptr;
730    }
731    NAPI_CALL(env, napi_get_value_string_utf8(env, result, str, STR_MAX_SIZE - 1, &strLen));
732    option.SetBundleName(str);
733
734    // uid?: number
735    NAPI_CALL(env, napi_has_named_property(env, value, "uid", &hasProperty));
736    if (hasProperty) {
737        int32_t uid = 0;
738        napi_get_named_property(env, value, "uid", &result);
739        NAPI_CALL(env, napi_typeof(env, result, &valuetype));
740        if (valuetype != napi_number) {
741            LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
742            return nullptr;
743        }
744        napi_get_value_int32(env, result, &uid);
745        option.SetUid(uid);
746    }
747
748    return NapiGetNull(env);
749}
750
751napi_value NotificationNapi::GetButtonOption(
752    const napi_env &env, const napi_value &value, NotificationButtonOption &option)
753{
754    LBSLOGD(NAPI_UTILS, "enter");
755
756    bool hasProperty {false};
757    napi_valuetype valuetype = napi_undefined;
758    napi_value result = nullptr;
759
760    char str[STR_MAX_SIZE] = {0};
761    size_t strLen = 0;
762    // buttonName: string
763    NAPI_CALL(env, napi_has_named_property(env, value, "buttonName", &hasProperty));
764    if (!hasProperty) {
765        LBSLOGE(NAPI_UTILS, "Property buttonName expected.");
766        return nullptr;
767    }
768    napi_get_named_property(env, value, "buttonName", &result);
769    NAPI_CALL(env, napi_typeof(env, result, &valuetype));
770    if (valuetype != napi_string) {
771        LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
772        return nullptr;
773    }
774    NAPI_CALL(env, napi_get_value_string_utf8(env, result, str, STR_MAX_SIZE - 1, &strLen));
775    option.SetButtonName(str);
776
777    return NapiGetNull(env);
778}
779
780napi_value NotificationNapi::GetHashCodes(
781    const napi_env &env, const napi_value &value, std::vector<std::string> &hashCodes)
782{
783    LBSLOGD(NAPI_UTILS, "enter");
784    uint32_t length = 0;
785    napi_get_array_length(env, value, &length);
786    if (length == 0) {
787        LBSLOGE(NAPI_UTILS, "The array is empty.");
788        return nullptr;
789    }
790    napi_valuetype valuetype = napi_undefined;
791    for (size_t i = 0; i < length; i++) {
792        napi_value hashCode = nullptr;
793        napi_get_element(env, value, i, &hashCode);
794        NAPI_CALL(env, napi_typeof(env, hashCode, &valuetype));
795        if (valuetype != napi_string) {
796            LBSLOGE(NAPI_UTILS, "Wrong argument type. Object expected.");
797            return nullptr;
798        }
799        char str[STR_MAX_SIZE] = {0};
800        size_t strLen = 0;
801        NAPI_CALL(env, napi_get_value_string_utf8(env, hashCode, str, STR_MAX_SIZE - 1, &strLen));
802        hashCodes.emplace_back(str);
803    }
804
805    return NapiGetNull(env);
806}
807
808napi_value NotificationNapi::GetNotificationKey(const napi_env &env, const napi_value &value, NotificationKey &key)
809{
810    LBSLOGD(NAPI_UTILS, "enter");
811
812    bool hasProperty {false};
813    napi_valuetype valuetype = napi_undefined;
814    napi_value result = nullptr;
815
816    // id: number
817    NAPI_CALL(env, napi_has_named_property(env, value, "id", &hasProperty));
818    if (!hasProperty) {
819        LBSLOGE(NAPI_UTILS, "Property id expected.");
820        return nullptr;
821    }
822    napi_get_named_property(env, value, "id", &result);
823    NAPI_CALL(env, napi_typeof(env, result, &valuetype));
824    if (valuetype != napi_number) {
825        LBSLOGE(NAPI_UTILS, "Wrong argument type. Number expected.");
826        return nullptr;
827    }
828    napi_get_value_int32(env, result, &key.id);
829
830    // label?: string
831    NAPI_CALL(env, napi_has_named_property(env, value, "label", &hasProperty));
832    if (hasProperty) {
833        char str[STR_MAX_SIZE] = {0};
834        size_t strLen = 0;
835        napi_get_named_property(env, value, "label", &result);
836        NAPI_CALL(env, napi_typeof(env, result, &valuetype));
837        if (valuetype != napi_string) {
838            LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
839            return nullptr;
840        }
841        NAPI_CALL(env, napi_get_value_string_utf8(env, result, str, STR_MAX_SIZE - 1, &strLen));
842        key.label = str;
843    }
844
845    return NapiGetNull(env);
846}
847
848bool NotificationNapi::IsValidRemoveReason(int32_t reasonType)
849{
850    if (reasonType == NotificationConstant::CLICK_REASON_DELETE ||
851        reasonType == NotificationConstant::CANCEL_REASON_DELETE) {
852        return true;
853    }
854    LBSLOGE(NAPI_UTILS, "Reason %{public}d is an invalid value", reasonType);
855    return false;
856}
857
858napi_value NotificationNapi::GetNotificationTemplate(
859    const napi_env &env, const napi_value &value, NotificationRequest &request)
860{
861    LBSLOGD(NAPI_UTILS, "enter");
862
863    napi_valuetype valuetype = napi_undefined;
864    napi_value result = nullptr;
865    bool hasProperty = false;
866
867    NAPI_CALL(env, napi_has_named_property(env, value, "template", &hasProperty));
868    if (hasProperty) {
869        napi_get_named_property(env, value, "template", &result);
870        NAPI_CALL(env, napi_typeof(env, result, &valuetype));
871        if (valuetype != napi_object) {
872            LBSLOGE(NAPI_UTILS, "Wrong argument type. Object expected.");
873            return nullptr;
874        }
875
876        std::shared_ptr<NotificationTemplate> templ = std::make_shared<NotificationTemplate>();
877        if (GetNotificationTemplateInfo(env, result, templ) == nullptr) {
878            return nullptr;
879        }
880
881        request.SetTemplate(templ);
882    }
883
884    return NapiGetNull(env);
885}
886
887napi_value NotificationNapi::GetNotificationBundleOption(
888    const napi_env &env, const napi_value &value, NotificationRequest &request)
889{
890    LBSLOGD(NAPI_UTILS, "Called.");
891
892    napi_valuetype valuetype = napi_undefined;
893    napi_value result = nullptr;
894    bool hasProperty = false;
895
896    NAPI_CALL(env, napi_has_named_property(env, value, "representativeBundle", &hasProperty));
897    if (hasProperty) {
898        napi_get_named_property(env, value, "representativeBundle", &result);
899        NAPI_CALL(env, napi_typeof(env, result, &valuetype));
900        if (valuetype != napi_object) {
901            LBSLOGE(NAPI_UTILS, "Wrong argument type. Object expected.");
902            return nullptr;
903        }
904
905        std::shared_ptr<NotificationBundleOption> bundleOption = std::make_shared<NotificationBundleOption>();
906        if (GetBundleOption(env, result, *bundleOption) == nullptr) {
907            return nullptr;
908        }
909
910        request.SetBundleOption(bundleOption);
911    }
912
913    return NapiGetNull(env);
914}
915
916napi_value NotificationNapi::GetNotificationTemplateInfo(const napi_env &env, const napi_value &value,
917    std::shared_ptr<NotificationTemplate> &templ)
918{
919    LBSLOGD(NAPI_UTILS, "enter");
920
921    napi_valuetype valuetype = napi_undefined;
922    napi_value result = nullptr;
923    bool hasProperty = false;
924    char str[STR_MAX_SIZE] = {0};
925    size_t strLen = 0;
926
927    // name: string
928    NAPI_CALL(env, napi_has_named_property(env, value, "name", &hasProperty));
929    if (!hasProperty) {
930        LBSLOGE(NAPI_UTILS, "Property name expected.");
931        return nullptr;
932    }
933    napi_get_named_property(env, value, "name", &result);
934    NAPI_CALL(env, napi_typeof(env, result, &valuetype));
935    if (valuetype != napi_string) {
936        LBSLOGE(NAPI_UTILS, "Wrong argument type. String expected.");
937        return nullptr;
938    }
939    NAPI_CALL(env, napi_get_value_string_utf8(env, result, str, STR_MAX_SIZE - 1, &strLen));
940    std::string strInput = str;
941    templ->SetTemplateName(strInput);
942
943    // data?: {[key: string]: object}
944    NAPI_CALL(env, napi_has_named_property(env, value, "data", &hasProperty));
945    if (hasProperty) {
946        napi_get_named_property(env, value, "data", &result);
947        NAPI_CALL(env, napi_typeof(env, result, &valuetype));
948        if (valuetype != napi_object) {
949            LBSLOGE(NAPI_UTILS, "Wrong argument type. Object expected.");
950            return nullptr;
951        }
952        AAFwk::WantParams wantParams;
953        if (!OHOS::AppExecFwk::UnwrapWantParams(env, result, wantParams)) {
954            return nullptr;
955        }
956
957        std::shared_ptr<AAFwk::WantParams> data = std::make_shared<AAFwk::WantParams>(wantParams);
958        templ->SetTemplateData(data);
959    }
960
961    return NapiGetNull(env);
962}
963}  // namespace Location
964}  // namespace OHOS
965