1 /*
2  * Copyright (c) 2023-2023 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 "common.h"
17 #include "ans_inner_errors.h"
18 #include "ans_log_wrapper.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 
31 namespace OHOS {
32 using namespace Global::Resource;
33 namespace NotificationNapi {
SetNotificationLocalLiveViewContent(const napi_env & env,NotificationBasicContent * basicContent,napi_value & result)34 napi_value Common::SetNotificationLocalLiveViewContent(
35     const napi_env &env, NotificationBasicContent *basicContent, napi_value &result)
36 {
37     ANS_LOGD("enter");
38     napi_value value = nullptr;
39     if (basicContent == nullptr) {
40         ANS_LOGE("basicContent is null");
41         return NapiGetBoolean(env, false);
42     }
43     OHOS::Notification::NotificationLocalLiveViewContent *localLiveViewContent =
44         static_cast<OHOS::Notification::NotificationLocalLiveViewContent *>(basicContent);
45     if (localLiveViewContent == nullptr) {
46         ANS_LOGE("localLiveViewContent is null");
47         return NapiGetBoolean(env, false);
48     }
49 
50     if (!SetNotificationBasicContent(env, localLiveViewContent, result)) {
51         ANS_LOGE("SetNotificationBasicContent call failed");
52         return NapiGetBoolean(env, false);
53     }
54 
55     // typeCode: int32_t
56     napi_create_int32(env, localLiveViewContent->GetType(), &value);
57     napi_set_named_property(env, result, "typeCode", value);
58 
59     // capsule: NotificationCapsule
60     if (localLiveViewContent->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::CAPSULE)) {
61         napi_value capsule = nullptr;
62         napi_create_object(env, &capsule);
63         if (!SetCapsule(env, localLiveViewContent->GetCapsule(), capsule)) {
64             ANS_LOGE("SetCapsule call failed");
65             return NapiGetBoolean(env, false);
66         }
67         napi_set_named_property(env, result, "capsule", capsule);
68     }
69 
70     // button: NotificationLocalLiveViewButton
71     if (localLiveViewContent->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::BUTTON)) {
72         napi_value button = nullptr;
73         napi_create_object(env, &button);
74         if (!SetButton(env, localLiveViewContent->GetButton(), button)) {
75             ANS_LOGE("SetButton call failed");
76             return NapiGetBoolean(env, false);
77         }
78         napi_set_named_property(env, result, "button", button);
79     }
80 
81     // progress: NotificationProgress
82     if (localLiveViewContent->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::PROGRESS)) {
83         napi_value progress = nullptr;
84         napi_create_object(env, &progress);
85         if (!SetProgress(env, localLiveViewContent->GetProgress(), progress)) {
86             ANS_LOGE("SetProgress call failed");
87             return NapiGetBoolean(env, false);
88         }
89         napi_set_named_property(env, result, "progress", progress);
90     }
91 
92     // time: NotificationTime
93     if (localLiveViewContent->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::TIME)) {
94         napi_value time = nullptr;
95         napi_create_object(env, &time);
96         bool flag = localLiveViewContent->isFlagExist(
97             NotificationLocalLiveViewContent::LiveViewContentInner::INITIAL_TIME);
98         if (!SetTime(env, localLiveViewContent->GetTime(), time, flag)) {
99             ANS_LOGE("SetMessageUser call failed");
100             return NapiGetBoolean(env, false);
101         }
102         napi_set_named_property(env, result, "time", time);
103     }
104 
105     return NapiGetBoolean(env, true);
106 }
107 
SetCapsule(const napi_env & env,const NotificationCapsule & capsule,napi_value & result)108 napi_value Common::SetCapsule(const napi_env &env, const NotificationCapsule &capsule, napi_value &result)
109 {
110     ANS_LOGD("enter");
111 
112     napi_value value = nullptr;
113     // title: string
114     napi_create_string_utf8(env, capsule.GetTitle().c_str(), NAPI_AUTO_LENGTH, &value);
115     napi_set_named_property(env, result, "title", value);
116 
117     // backgroundColor: string
118     napi_create_string_utf8(env, capsule.GetBackgroundColor().c_str(), NAPI_AUTO_LENGTH, &value);
119     napi_set_named_property(env, result, "backgroundColor", value);
120 
121     // content: string
122     napi_create_string_utf8(env, capsule.GetContent().c_str(), NAPI_AUTO_LENGTH, &value);
123     napi_set_named_property(env, result, "content", value);
124 
125     // icon?: image.PixelMap
126     std::shared_ptr<Media::PixelMap> icon = capsule.GetIcon();
127     if (icon) {
128         napi_value iconResult = nullptr;
129         napi_valuetype valuetype = napi_undefined;
130         iconResult = Media::PixelMapNapi::CreatePixelMap(env, icon);
131         NAPI_CALL(env, napi_typeof(env, iconResult, &valuetype));
132         if (valuetype == napi_undefined) {
133             ANS_LOGW("iconResult is undefined");
134             napi_set_named_property(env, result, "icon", NapiGetNull(env));
135         } else {
136             napi_set_named_property(env, result, "icon", iconResult);
137         }
138     }
139     return NapiGetBoolean(env, true);
140 }
141 
SetProgress(const napi_env & env,const NotificationProgress & progress,napi_value & result)142 napi_value Common::SetProgress(const napi_env &env, const NotificationProgress &progress, napi_value &result)
143 {
144     ANS_LOGD("enter");
145 
146     napi_value value = nullptr;
147     // currentValue: int32_t
148     napi_create_int32(env, progress.GetCurrentValue(), &value);
149     napi_set_named_property(env, result, "currentValue", value);
150 
151     // maxValue: int32_t
152     napi_create_int32(env, progress.GetMaxValue(), &value);
153     napi_set_named_property(env, result, "maxValue", value);
154 
155     // isPercentage: bool
156     napi_get_boolean(env, progress.GetIsPercentage(), &value);
157     napi_set_named_property(env, result, "isPercentage", value);
158 
159     return NapiGetBoolean(env, true);
160 }
161 
SetTime(const napi_env & env,const NotificationTime & time,napi_value & result,bool isInitialTimeExist)162 napi_value Common::SetTime(const napi_env &env, const NotificationTime &time,
163     napi_value &result, bool isInitialTimeExist)
164 {
165     ANS_LOGD("enter");
166 
167     napi_value value = nullptr;
168     // initialTime: int32_t
169     if (isInitialTimeExist) {
170         napi_create_int32(env, time.GetInitialTime(), &value);
171         napi_set_named_property(env, result, "initialTime", value);
172     }
173 
174     // isCountDown: bool
175     napi_get_boolean(env, time.GetIsCountDown(), &value);
176     napi_set_named_property(env, result, "isCountDown", value);
177 
178     // isPaused: bool
179     napi_get_boolean(env, time.GetIsPaused(), &value);
180     napi_set_named_property(env, result, "isPaused", value);
181 
182     // isInTitle: bool
183     napi_get_boolean(env, time.GetIsInTitle(), &value);
184     napi_set_named_property(env, result, "isInTitle", value);
185 
186     return NapiGetBoolean(env, true);
187 }
188 
SetObjectStringProperty(const napi_env & env,napi_value & object,const std::string & key,const std::string & value)189 napi_value Common::SetObjectStringProperty(const napi_env& env, napi_value& object,
190     const std::string& key, const std::string& value)
191 {
192     napi_value property;
193     napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &property);
194     if (status != napi_ok) {
195         ANS_LOGE("Failed to create value.");
196         return nullptr;
197     }
198     status = napi_set_named_property(env, object, key.c_str(), property);
199     if (status != napi_ok) {
200         ANS_LOGE("Failed to set locale property");
201         return nullptr;
202     }
203     return NapiGetNull(env);
204 }
205 
SetObjectUint32Property(const napi_env & env,napi_value & object,const std::string & key,uint32_t value)206 napi_value Common::SetObjectUint32Property(const napi_env &env, napi_value& object,
207     const std::string& key, uint32_t value)
208 {
209     napi_value property;
210     napi_status status = napi_create_uint32(env, value, &property);
211     if (status != napi_ok) {
212         ANS_LOGE("Failed to create value.");
213         return nullptr;
214     }
215 
216     status = napi_set_named_property(env, object, key.c_str(), property);
217     if (status != napi_ok) {
218         ANS_LOGE("Failed to set locale property");
219         return nullptr;
220     }
221     return NapiGetNull(env);
222 }
223 
SetResourceObject(napi_env env,std::shared_ptr<ResourceManager::Resource> & resource,napi_value & object)224 napi_value Common::SetResourceObject(napi_env env, std::shared_ptr<ResourceManager::Resource> &resource,
225     napi_value &object)
226 {
227     if (SetObjectStringProperty(env, object, "bundleName", resource->bundleName) == nullptr) {
228         ANS_LOGE("Failed to set property bundleName");
229         return NapiGetBoolean(env, false);
230     }
231     if (SetObjectStringProperty(env, object, "moduleName", resource->moduleName) == nullptr) {
232         ANS_LOGE("Failed to set property moduleName");
233         return NapiGetBoolean(env, false);
234     }
235     if (SetObjectUint32Property(env, object, "id", resource->id) == nullptr) {
236         ANS_LOGE("Failed to set property id");
237         return NapiGetBoolean(env, false);
238     }
239     return NapiGetBoolean(env, true);
240 }
241 
SetButton(const napi_env & env,const NotificationLocalLiveViewButton & button,napi_value & result)242 napi_value Common::SetButton(const napi_env &env, const NotificationLocalLiveViewButton &button, napi_value &result)
243 {
244     ANS_LOGD("enter");
245 
246     napi_value value = nullptr;
247 
248     // buttonNames: Array<String>
249     napi_value arr = nullptr;
250     int count = 0;
251     napi_create_array(env, &arr);
252     for (auto vec : button.GetAllButtonNames()) {
253         napi_create_string_utf8(env, vec.c_str(), NAPI_AUTO_LENGTH, &value);
254         napi_set_element(env, arr, count, value);
255         count++;
256     }
257     napi_set_named_property(env, result, "names", arr);
258 
259     // buttonIcons: Array<PixelMap>
260     napi_value iconArr = nullptr;
261     int iconCount = 0;
262     napi_create_array(env, &iconArr);
263 
264     std::vector<std::shared_ptr<Media::PixelMap>> icons = button.GetAllButtonIcons();
265     for (auto vec : icons) {
266         if (!vec) {
267             continue;
268         }
269         // buttonIcon
270         napi_value iconResult = nullptr;
271         iconResult = Media::PixelMapNapi::CreatePixelMap(env, vec);
272         napi_set_element(env, iconArr, iconCount, iconResult);
273         iconCount++;
274     }
275     napi_set_named_property(env, result, "icons", iconArr);
276 
277     // buttonIcons: Array<Resource>
278     iconCount = 0;
279     napi_value resourceArr = nullptr;
280     napi_create_array(env, &resourceArr);
281     auto iconResources = button.GetAllButtonIconResource();
282     for (auto resource : iconResources) {
283         napi_value object;
284         napi_status status = napi_create_object(env, &object);
285         if (status != napi_ok) {
286             ANS_LOGE("Failed to create Configuration object");
287             return NapiGetBoolean(env, false);
288         }
289         if (!SetResourceObject(env, resource, object)) {
290             return NapiGetBoolean(env, false);
291         }
292         napi_set_element(env, resourceArr, iconCount, object);
293         iconCount++;
294     }
295     napi_set_named_property(env, result, "iconsResource", resourceArr);
296 
297     return NapiGetBoolean(env, true);
298 }
299 
SetNotificationLiveViewContent(const napi_env & env,NotificationBasicContent * basicContent,napi_value & result)300 napi_value Common::SetNotificationLiveViewContent(
301     const napi_env &env, NotificationBasicContent *basicContent, napi_value &result)
302 {
303     ANS_LOGD("enter");
304     napi_value value = nullptr;
305     if (basicContent == nullptr) {
306         ANS_LOGE("BasicContent is null");
307         return NapiGetBoolean(env, false);
308     }
309 
310     // lockScreenPicture?: pixelMap
311     if (!SetLockScreenPicture(env, basicContent, result)) {
312         ANS_LOGE("lockScreenPicture is null");
313         return NapiGetBoolean(env, false);
314     }
315 
316     auto liveViewContent = static_cast<NotificationLiveViewContent *>(basicContent);
317     if (liveViewContent == nullptr) {
318         ANS_LOGE("LiveViewContent is null");
319         return NapiGetBoolean(env, false);
320     }
321 
322     // status: LiveViewStatus
323     LiveViewStatus outType = LiveViewStatus::LIVE_VIEW_BUTT;
324     if (!AnsEnumUtil::LiveViewStatusCToJS(liveViewContent->GetLiveViewStatus(), outType)) {
325         ANS_LOGE("Liveview status is invalid");
326         return NapiGetBoolean(env, false);
327     }
328     napi_create_int32(env, static_cast<int32_t>(outType), &value);
329     napi_set_named_property(env, result, "status", value);
330 
331     // version?: uint32_t
332     napi_create_int32(env, static_cast<int32_t>(liveViewContent->GetVersion()), &value);
333     napi_set_named_property(env, result, "version", value);
334 
335     // extraInfo?: {[key:string] : any}
336     std::shared_ptr<AAFwk::WantParams> extraInfoData = liveViewContent->GetExtraInfo();
337     if (extraInfoData != nullptr) {
338         napi_value extraInfo = OHOS::AppExecFwk::WrapWantParams(env, *extraInfoData);
339         napi_set_named_property(env, result, "extraInfo", extraInfo);
340     }
341 
342     // pictureInfo?: {[key, string]: Array<image.pixelMap>}
343     if (liveViewContent->GetPicture().empty()) {
344         ANS_LOGD("No pictures in live view.");
345         return NapiGetBoolean(env, true);
346     }
347 
348     napi_value pictureMapObj = SetLiveViewPictureInfo(env, liveViewContent->GetPicture());
349     if (pictureMapObj == nullptr) {
350         ANS_LOGE("Set live view picture map failed.");
351         return NapiGetBoolean(env, false);
352     }
353     napi_set_named_property(env, result, "pictureInfo", pictureMapObj);
354 
355     return NapiGetBoolean(env, true);
356 }
357 
SetLiveViewPictureInfo(const napi_env & env,const std::map<std::string,std::vector<std::shared_ptr<Media::PixelMap>>> & pictureMap)358 napi_value Common::SetLiveViewPictureInfo(
359     const napi_env &env, const std::map<std::string, std::vector<std::shared_ptr<Media::PixelMap>>> &pictureMap)
360 {
361     ANS_LOGD("enter");
362 
363     napi_value pictureMapObj = nullptr;
364     NAPI_CALL(env, napi_create_object(env, &pictureMapObj));
365 
366     for (auto iter = pictureMap.begin(); iter != pictureMap.end(); iter++) {
367         int count = 0;
368         napi_value picturesObj = nullptr;
369         napi_create_array(env, &picturesObj);
370         for (auto picture : iter->second) {
371             napi_value pictureObj = Media::PixelMapNapi::CreatePixelMap(env, picture);
372             napi_set_element(env, picturesObj, count, pictureObj);
373             count++;
374         }
375 
376         if (count > 0) {
377             napi_set_named_property(env, pictureMapObj, iter->first.c_str(), picturesObj);
378         }
379     }
380 
381     return pictureMapObj;
382 }
383 
GetNotificationLocalLiveViewContent(const napi_env & env,const napi_value & result,NotificationRequest & request)384 napi_value Common::GetNotificationLocalLiveViewContent(
385     const napi_env &env, const napi_value &result, NotificationRequest &request)
386 {
387     ANS_LOGD("enter");
388 
389     napi_valuetype valuetype = napi_undefined;
390     napi_value contentResult = nullptr;
391     bool hasProperty = false;
392     NAPI_CALL(env, napi_has_named_property(env, result, "systemLiveView", &hasProperty));
393     if (!hasProperty) {
394         ANS_LOGE("Property localLiveView expected.");
395         return nullptr;
396     }
397     napi_get_named_property(env, result, "systemLiveView", &contentResult);
398     NAPI_CALL(env, napi_typeof(env, contentResult, &valuetype));
399     if (valuetype != napi_object) {
400         ANS_LOGE("Wrong argument type. Object expected.");
401         return nullptr;
402     }
403 
404     std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> localLiveViewContent =
405         std::make_shared<OHOS::Notification::NotificationLocalLiveViewContent>();
406     if (localLiveViewContent == nullptr) {
407         ANS_LOGE("localLiveViewContent is null");
408         return nullptr;
409     }
410 
411     if (GetNotificationLocalLiveViewContentDetailed(env, contentResult, localLiveViewContent) == nullptr) {
412         return nullptr;
413     }
414 
415     request.SetContent(std::make_shared<NotificationContent>(localLiveViewContent));
416 
417     // set isOnGoing of live view true
418     request.SetInProgress(true);
419 
420     return NapiGetNull(env);
421 }
422 
GetNotificationLocalLiveViewCapsule(const napi_env & env,const napi_value & contentResult,std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> content)423 napi_value Common::GetNotificationLocalLiveViewCapsule(
424     const napi_env &env, const napi_value &contentResult,
425     std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> content)
426 {
427     napi_value capsuleResult = nullptr;
428     napi_valuetype valuetype = napi_undefined;
429     bool hasProperty = false;
430     size_t strLen = 0;
431     char str[STR_MAX_SIZE] = {0};
432     std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
433     napi_value result = nullptr;
434 
435     ANS_LOGD("enter");
436 
437     NAPI_CALL(env, napi_has_named_property(env, contentResult, "capsule", &hasProperty));
438 
439     napi_get_named_property(env, contentResult, "capsule", &capsuleResult);
440     NAPI_CALL(env, napi_typeof(env, capsuleResult, &valuetype));
441     if (valuetype != napi_object) {
442         ANS_LOGE("Wrong argument type. Object expected.");
443         return nullptr;
444     }
445 
446     NotificationCapsule capsule;
447 
448     NAPI_CALL(env, napi_has_named_property(env, capsuleResult, "title", &hasProperty));
449     if (hasProperty) {
450         napi_get_named_property(env, capsuleResult, "title", &result);
451         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
452         if (valuetype != napi_string) {
453             ANS_LOGE("Wrong argument type. String expected.");
454             return nullptr;
455         }
456 
457         NAPI_CALL(env, napi_get_value_string_utf8(env, result, str, STR_MAX_SIZE - 1, &strLen));
458         capsule.SetTitle(str);
459         ANS_LOGD("capsule title = %{public}s", str);
460     }
461 
462     NAPI_CALL(env, napi_has_named_property(env, capsuleResult, "backgroundColor", &hasProperty));
463     if (hasProperty) {
464         napi_get_named_property(env, capsuleResult, "backgroundColor", &result);
465         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
466         if (valuetype != napi_string) {
467             ANS_LOGE("Wrong argument type. String expected.");
468             return nullptr;
469         }
470         NAPI_CALL(env, napi_get_value_string_utf8(env, result, str, STR_MAX_SIZE - 1, &strLen));
471         capsule.SetBackgroundColor(str);
472         ANS_LOGD("capsule backgroundColor = %{public}s", str);
473     }
474 
475     NAPI_CALL(env, napi_has_named_property(env, capsuleResult, "content", &hasProperty));
476     if (hasProperty) {
477         napi_get_named_property(env, capsuleResult, "content", &result);
478         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
479         if (valuetype != napi_string) {
480             ANS_LOGE("Wrong argument type. String expected.");
481             return nullptr;
482         }
483         NAPI_CALL(env, napi_get_value_string_utf8(env, result, str, STR_MAX_SIZE - 1, &strLen));
484         capsule.SetContent(str);
485         ANS_LOGD("capsule content = %{public}s", str);
486     }
487 
488     NAPI_CALL(env, napi_has_named_property(env, capsuleResult, "icon", &hasProperty));
489     if (hasProperty) {
490         napi_get_named_property(env, capsuleResult, "icon", &result);
491         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
492         if (valuetype != napi_object) {
493             ANS_LOGE("Wrong argument type. Object expected.");
494             return nullptr;
495         }
496         pixelMap = Media::PixelMapNapi::GetPixelMap(env, result);
497         if (pixelMap == nullptr) {
498             ANS_LOGE("Invalid object pixelMap");
499             return nullptr;
500         }
501         capsule.SetIcon(pixelMap);
502         ANS_LOGD("capsule icon = %{public}d", pixelMap->GetWidth());
503     }
504 
505     content->SetCapsule(capsule);
506     content->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::CAPSULE);
507 
508     return NapiGetNull(env);
509 }
510 
GetResourceObject(napi_env env,std::shared_ptr<ResourceManager::Resource> & resource,napi_value & value)511 napi_value Common::GetResourceObject(napi_env env,
512     std::shared_ptr<ResourceManager::Resource> &resource, napi_value &value)
513 {
514     napi_value name;
515     size_t strLen = 0;
516     char str[STR_MAX_SIZE] = {0};
517     std::vector<std::string> typeName = {"bundleName", "moduleName"};
518     for (const std::string& type: typeName) {
519         napi_status status = napi_get_named_property(env, value, type.c_str(), &name);
520         if (status != napi_ok || name == nullptr) {
521             ANS_LOGE("Failed to get resource name property");
522             return nullptr;
523         }
524         napi_valuetype valueType = napi_valuetype::napi_undefined;
525         NAPI_CALL(env, napi_typeof(env, name, &valueType));
526         if (valueType != napi_string) {
527             ANS_LOGE("Failed to get resource type %{public}d", valueType);
528             return nullptr;
529         }
530         NAPI_CALL(env, napi_get_value_string_utf8(env, name, str, STR_MAX_SIZE - 1, &strLen));
531         if (type == "bundleName") {
532             resource->bundleName = str;
533         } else if (type == "moduleName") {
534             resource->moduleName = str;
535         }
536     }
537 
538     napi_value id;
539     napi_status status = napi_get_named_property(env, value, "id", &id);
540     if (status != napi_ok || id == nullptr) {
541         ANS_LOGE("Failed to get resource id property");
542         return nullptr;
543     }
544     napi_valuetype valueType = napi_valuetype::napi_undefined;
545     napi_typeof(env, id, &valueType);
546     if (valueType != napi_number) {
547         ANS_LOGE("Failed to get resource name string");
548         return nullptr;
549     }
550     int32_t resId = 0;
551     status = napi_get_value_int32(env, id, &resId);
552     if (status != napi_ok) {
553         ANS_LOGE("Wrong argument type. Object expected.");
554         return nullptr;
555     }
556     resource->id = resId;
557     ANS_LOGE("Get to get resource bundleName %{public}s moduleName %{public}s id %{public}d",
558         resource->bundleName.c_str(), resource->moduleName.c_str(), resource->id);
559     return NapiGetNull(env);
560 }
561 
GetNotificationLocalLiveViewButton(const napi_env & env,const napi_value & contentResult,std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> content)562 napi_value Common::GetNotificationLocalLiveViewButton(
563     const napi_env &env, const napi_value &contentResult,
564     std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> content)
565 {
566     napi_value result = nullptr;
567     napi_valuetype valuetype = napi_undefined;
568     bool isArray = false;
569     uint32_t length = 0;
570     napi_value buttonResult = nullptr;
571     bool hasProperty = false;
572     char str[STR_MAX_SIZE] = {0};
573     size_t strLen = 0;
574 
575     ANS_LOGD("enter");
576 
577     napi_get_named_property(env, contentResult, "button", &buttonResult);
578     NAPI_CALL(env, napi_typeof(env, buttonResult, &valuetype));
579     if (valuetype != napi_object) {
580         ANS_LOGE("Wrong argument type. Object expected.");
581         return nullptr;
582     }
583 
584     NotificationLocalLiveViewButton button;
585 
586     NAPI_CALL(env, napi_has_named_property(env, buttonResult, "names", &hasProperty));
587     if (hasProperty) {
588         napi_get_named_property(env, buttonResult, "names", &result);
589         napi_is_array(env, result, &isArray);
590         if (!isArray) {
591             ANS_LOGE("Property names is expected to be an array.");
592             return nullptr;
593         }
594         napi_get_array_length(env, result, &length);
595         for (size_t i = 0; i < length; i++) {
596             napi_value buttonName = nullptr;
597             napi_get_element(env, result, i, &buttonName);
598             NAPI_CALL(env, napi_typeof(env, buttonName, &valuetype));
599             if (valuetype != napi_string) {
600                 ANS_LOGE("Wrong argument type. String expected.");
601                 return nullptr;
602             }
603             NAPI_CALL(env, napi_get_value_string_utf8(env, buttonName, str, STR_MAX_SIZE - 1, &strLen));
604             button.addSingleButtonName(str);
605             ANS_LOGD("button buttonName = %{public}s.", str);
606         }
607     }
608 
609     NAPI_CALL(env, napi_has_named_property(env, buttonResult, "icons", &hasProperty));
610     if (hasProperty) {
611         napi_get_named_property(env, buttonResult, "icons", &result);
612         napi_is_array(env, result, &isArray);
613         if (!isArray) {
614             ANS_LOGE("Property icons is expected to be an array.");
615             return nullptr;
616         }
617         napi_get_array_length(env, result, &length);
618         for (size_t i = 0; i < length; i++) {
619             napi_value buttonIcon = nullptr;
620             std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
621             napi_get_element(env, result, i, &buttonIcon);
622             NAPI_CALL(env, napi_typeof(env, buttonIcon, &valuetype));
623             if (valuetype != napi_object) {
624                 ANS_LOGE("Wrong argument type. Object expected.");
625                 return nullptr;
626             }
627             pixelMap = Media::PixelMapNapi::GetPixelMap(env, buttonIcon);
628             if (pixelMap != nullptr && static_cast<uint32_t>(pixelMap->GetByteCount()) <= MAX_ICON_SIZE) {
629                 button.addSingleButtonIcon(pixelMap);
630             } else {
631                 ANS_LOGE("Invalid pixelMap object or pixelMap is over size.");
632                 return nullptr;
633             }
634         }
635     }
636 
637     NAPI_CALL(env, napi_has_named_property(env, buttonResult, "iconsResource", &hasProperty));
638     if (hasProperty) {
639         napi_get_named_property(env, buttonResult, "iconsResource", &result);
640         napi_is_array(env, result, &isArray);
641         if (!isArray) {
642             ANS_LOGE("Property icon resource is expected to be an array.");
643             return nullptr;
644         }
645         napi_get_array_length(env, result, &length);
646         for (size_t i = 0; i < length; i++) {
647             napi_value iconResource = nullptr;
648             auto resource = std::make_shared<ResourceManager::Resource>();
649             napi_get_element(env, result, i, &iconResource);
650             NAPI_CALL(env, napi_typeof(env, iconResource, &valuetype));
651             if (valuetype != napi_object) {
652                 ANS_LOGE("Wrong argument type. Object expected.");
653                 return nullptr;
654             }
655             if (Common::GetResourceObject(env, resource, iconResource) == nullptr) {
656                 ANS_LOGW("Invalid icon resource object.");
657                 return nullptr;
658             } else {
659                 button.addSingleButtonIconResource(resource);
660             }
661         }
662     }
663 
664     ANS_LOGD("button buttonIcon = %{public}s", str);
665     content->SetButton(button);
666     content->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::BUTTON);
667 
668     return NapiGetNull(env);
669 }
670 
GetNotificationLocalLiveViewProgress(const napi_env & env,const napi_value & contentResult,std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> content)671 napi_value Common::GetNotificationLocalLiveViewProgress(const napi_env &env, const napi_value &contentResult,
672     std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> content)
673 {
674     napi_value result = nullptr;
675     napi_valuetype valuetype = napi_undefined;
676     bool hasProperty = false;
677     int32_t intValue = -1;
678     bool boolValue = false;
679     napi_value progressResult = nullptr;
680 
681     ANS_LOGD("enter");
682 
683     napi_get_named_property(env, contentResult, "progress", &progressResult);
684     NAPI_CALL(env, napi_typeof(env, progressResult, &valuetype));
685     if (valuetype != napi_object) {
686         ANS_LOGE("Wrong argument type. Object expected.");
687         return nullptr;
688     }
689 
690     NotificationProgress progress;
691 
692     NAPI_CALL(env, napi_has_named_property(env, progressResult, "maxValue", &hasProperty));
693     if (hasProperty) {
694         napi_get_named_property(env, progressResult, "maxValue", &result);
695         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
696         if (valuetype != napi_number) {
697             ANS_LOGE("Wrong argument type. Number expected.");
698             return nullptr;
699         }
700         napi_get_value_int32(env, result, &intValue);
701         progress.SetMaxValue(intValue);
702         ANS_LOGD("progress intValue = %{public}d", intValue);
703     }
704 
705     NAPI_CALL(env, napi_has_named_property(env, progressResult, "currentValue", &hasProperty));
706     if (hasProperty) {
707         napi_get_named_property(env, progressResult, "currentValue", &result);
708         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
709         if (valuetype != napi_number) {
710             ANS_LOGE("Wrong argument type. Number expected.");
711             return nullptr;
712         }
713         napi_get_value_int32(env, result, &intValue);
714         progress.SetCurrentValue(intValue);
715         ANS_LOGD("progress currentValue = %{public}d", intValue);
716     }
717 
718     NAPI_CALL(env, napi_has_named_property(env, progressResult, "isPercentage", &hasProperty));
719     if (hasProperty) {
720         napi_get_named_property(env, progressResult, "isPercentage", &result);
721         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
722         if (valuetype != napi_boolean) {
723             ANS_LOGE("Wrong argument type. bool expected.");
724             return nullptr;
725         }
726         napi_get_value_bool(env, result, &boolValue);
727         progress.SetIsPercentage(boolValue);
728         ANS_LOGD("progress isPercentage = %{public}d", boolValue);
729     }
730 
731     content->SetProgress(progress);
732     content->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::PROGRESS);
733 
734     return NapiGetNull(env);
735 }
736 
GetNotificationLocalLiveViewTime(const napi_env & env,const napi_value & contentResult,std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> content)737 napi_value Common::GetNotificationLocalLiveViewTime(const napi_env &env, const napi_value &contentResult,
738     std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> content)
739 {
740     napi_value result = nullptr;
741     napi_valuetype valuetype = napi_undefined;
742     bool hasProperty = false;
743     int32_t intValue = -1;
744     bool boolValue = false;
745     napi_value timeResult = nullptr;
746 
747     ANS_LOGD("enter");
748 
749     napi_get_named_property(env, contentResult, "time", &timeResult);
750     NAPI_CALL(env, napi_typeof(env, timeResult, &valuetype));
751     if (valuetype != napi_object) {
752         ANS_LOGE("Wrong argument type. Object expected.");
753         return nullptr;
754     }
755 
756     NotificationTime time;
757 
758     NAPI_CALL(env, napi_has_named_property(env, timeResult, "initialTime", &hasProperty));
759     if (hasProperty) {
760         napi_get_named_property(env, timeResult, "initialTime", &result);
761         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
762         if (valuetype != napi_number) {
763             ANS_LOGE("Wrong argument type. Number expected.");
764             return nullptr;
765         }
766         napi_get_value_int32(env, result, &intValue);
767         time.SetInitialTime(intValue);
768         content->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::INITIAL_TIME);
769         ANS_LOGD("time initialTime = %{public}d", intValue);
770     }
771 
772     NAPI_CALL(env, napi_has_named_property(env, timeResult, "isCountDown", &hasProperty));
773     if (hasProperty) {
774         napi_get_named_property(env, timeResult, "isCountDown", &result);
775         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
776         if (valuetype != napi_boolean) {
777             ANS_LOGE("Wrong argument type. bool expected.");
778             return nullptr;
779         }
780         napi_get_value_bool(env, result, &boolValue);
781         time.SetIsCountDown(boolValue);
782         ANS_LOGD("time isCountDown = %{public}d", boolValue);
783     }
784 
785     NAPI_CALL(env, napi_has_named_property(env, timeResult, "isPaused", &hasProperty));
786     if (hasProperty) {
787         napi_get_named_property(env, timeResult, "isPaused", &result);
788         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
789         if (valuetype != napi_boolean) {
790             ANS_LOGE("Wrong argument type. bool expected.");
791             return nullptr;
792         }
793         napi_get_value_bool(env, result, &boolValue);
794         time.SetIsPaused(boolValue);
795         ANS_LOGD("time isPaused = %{public}d", boolValue);
796     }
797 
798     NAPI_CALL(env, napi_has_named_property(env, timeResult, "isInTitle", &hasProperty));
799     if (hasProperty) {
800         napi_get_named_property(env, timeResult, "isInTitle", &result);
801         NAPI_CALL(env, napi_typeof(env, result, &valuetype));
802         if (valuetype != napi_boolean) {
803             ANS_LOGE("Wrong argument type. bool expected.");
804             return nullptr;
805         }
806         napi_get_value_bool(env, result, &boolValue);
807         time.SetIsInTitle(boolValue);
808         ANS_LOGD("time isInTitle = %{public}d", boolValue);
809     }
810 
811     content->SetTime(time);
812     content->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::TIME);
813 
814     return NapiGetNull(env);
815 }
816 
GetNotificationLocalLiveViewContentDetailed(const napi_env & env,const napi_value & contentResult,std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> content)817 napi_value Common::GetNotificationLocalLiveViewContentDetailed(
818     const napi_env &env, const napi_value &contentResult,
819     std::shared_ptr<OHOS::Notification::NotificationLocalLiveViewContent> content)
820 {
821     bool hasProperty = false;
822     int32_t type = -1;
823     napi_value result = nullptr;
824     napi_valuetype valuetype = napi_undefined;
825 
826     ANS_LOGD("enter");
827 
828     //title, text
829     if (GetNotificationBasicContentDetailed(env, contentResult, content) == nullptr) {
830         ANS_LOGE("Basic content get fail.");
831         return nullptr;
832     }
833 
834     // typeCode
835     NAPI_CALL(env, napi_has_named_property(env, contentResult, "typeCode", &hasProperty));
836     if (!hasProperty) {
837         ANS_LOGE("Property typeCode expected.");
838         return nullptr;
839     }
840     napi_get_named_property(env, contentResult, "typeCode", &result);
841     NAPI_CALL(env, napi_typeof(env, result, &valuetype));
842     if (valuetype != napi_number) {
843         ANS_LOGE("Wrong argument typeCode. Number expected.");
844         return nullptr;
845     }
846     napi_get_value_int32(env, result, &type);
847     content->SetType(type);
848     ANS_LOGD("localLiveView type = %{public}d", type);
849 
850     //capsule?
851     NAPI_CALL(env, napi_has_named_property(env, contentResult, "capsule", &hasProperty));
852     if (hasProperty && GetNotificationLocalLiveViewCapsule(env, contentResult, content) == nullptr) {
853         return nullptr;
854     }
855 
856     //button?
857     NAPI_CALL(env, napi_has_named_property(env, contentResult, "button", &hasProperty));
858     if (hasProperty && GetNotificationLocalLiveViewButton(env, contentResult, content) == nullptr) {
859         return nullptr;
860     }
861 
862     //progress?
863     NAPI_CALL(env, napi_has_named_property(env, contentResult, "progress", &hasProperty));
864     if (hasProperty && GetNotificationLocalLiveViewProgress(env, contentResult, content) == nullptr) {
865         return nullptr;
866     }
867 
868     //time?
869     NAPI_CALL(env, napi_has_named_property(env, contentResult, "time", &hasProperty));
870     if (hasProperty && GetNotificationLocalLiveViewTime(env, contentResult, content) == nullptr) {
871         return nullptr;
872     }
873 
874     return NapiGetNull(env);
875 }
876 
GetNotificationLiveViewContent(const napi_env & env,const napi_value & result,NotificationRequest & request)877 napi_value Common::GetNotificationLiveViewContent(
878     const napi_env &env, const napi_value &result, NotificationRequest &request)
879 {
880     ANS_LOGD("enter");
881 
882     napi_value contentResult = AppExecFwk::GetPropertyValueByPropertyName(env, result, "liveView", napi_object);
883     if (contentResult == nullptr) {
884         ANS_LOGE("Property liveView expected.");
885         return nullptr;
886     }
887 
888     std::shared_ptr<NotificationLiveViewContent> liveViewContent = std::make_shared<NotificationLiveViewContent>();
889     if (liveViewContent == nullptr) {
890         ANS_LOGE("LiveViewContent is null");
891         return nullptr;
892     }
893 
894     if (GetNotificationLiveViewContentDetailed(env, contentResult, liveViewContent) == nullptr) {
895         return nullptr;
896     }
897 
898     request.SetContent(std::make_shared<NotificationContent>(liveViewContent));
899 
900     return NapiGetNull(env);
901 }
902 
GetNotificationLiveViewContentDetailed(const napi_env & env,const napi_value & contentResult,std::shared_ptr<NotificationLiveViewContent> & liveViewContent)903 napi_value Common::GetNotificationLiveViewContentDetailed(
904     const napi_env &env, const napi_value &contentResult,
905     std::shared_ptr<NotificationLiveViewContent> &liveViewContent)
906 {
907     ANS_LOGD("enter");
908 
909     // lockScreenPicture?: pixelMap
910     if (GetLockScreenPicture(env, contentResult, liveViewContent) == nullptr) {
911         ANS_LOGE("Failed to get lockScreenPicture from liveView content.");
912         return nullptr;
913     }
914 
915     // status: NotificationLiveViewContent::LiveViewStatus
916     int32_t status = 0;
917     if (!AppExecFwk::UnwrapInt32ByPropertyName(env, contentResult, "status", status)) {
918         ANS_LOGE("Failed to get status from liveView content.");
919         return nullptr;
920     }
921     NotificationLiveViewContent::LiveViewStatus outType = NotificationLiveViewContent::LiveViewStatus::LIVE_VIEW_BUTT;
922     if (!AnsEnumUtil::LiveViewStatusJSToC(LiveViewStatus(status), outType)) {
923         ANS_LOGE("The liveview status is not valid.");
924         return nullptr;
925     }
926     liveViewContent->SetLiveViewStatus(outType);
927 
928     // version?: uint32_t
929     napi_value jsValue = AppExecFwk::GetPropertyValueByPropertyName(env, contentResult,
930         "version", napi_number);
931     if (jsValue != nullptr) {
932         int32_t version = NotificationLiveViewContent::MAX_VERSION;
933         NAPI_CALL(env, napi_get_value_int32(env, jsValue, &version));
934         liveViewContent->SetVersion(version);
935     }
936 
937     // extraInfo?: {[key:string] : any}
938     jsValue = AppExecFwk::GetPropertyValueByPropertyName(env, contentResult, "extraInfo", napi_object);
939     if (jsValue != nullptr) {
940         std::shared_ptr<AAFwk::WantParams> extras = std::make_shared<AAFwk::WantParams>();
941         if (!OHOS::AppExecFwk::UnwrapWantParams(env, jsValue, *extras)) {
942             return nullptr;
943         }
944         liveViewContent->SetExtraInfo(extras);
945     }
946 
947     //isOnlyLocalUpdate_?: boolean
948     bool isLocalUpdateOnly = false;
949     if (AppExecFwk::UnwrapBooleanByPropertyName(env, contentResult, "isLocalUpdateOnly", isLocalUpdateOnly)) {
950         liveViewContent->SetIsOnlyLocalUpdate(isLocalUpdateOnly);
951     }
952 
953     // pictureInfo?: {[key, string]: Array<image.pixelMap>}
954     jsValue = AppExecFwk::GetPropertyValueByPropertyName(env, contentResult, "pictureInfo", napi_object);
955     if (jsValue == nullptr) {
956         ANS_LOGI("No picture maps.");
957         return NapiGetNull(env);
958     }
959 
960     std::map<std::string, std::vector<std::shared_ptr<Media::PixelMap>>> pictureMap;
961     if (GetLiveViewPictureInfo(env, jsValue, pictureMap) == nullptr) {
962         ANS_LOGE("Failed to get picture map from liveView content.");
963         return nullptr;
964     }
965     liveViewContent->SetPicture(pictureMap);
966 
967     return NapiGetNull(env);
968 }
969 
GetLiveViewPictures(const napi_env & env,const napi_value & picturesObj,std::vector<std::shared_ptr<Media::PixelMap>> & pictures)970 napi_value Common::GetLiveViewPictures(
971     const napi_env &env, const napi_value &picturesObj,
972     std::vector<std::shared_ptr<Media::PixelMap>> &pictures)
973 {
974     ANS_LOGD("enter");
975 
976     bool isArray = false;
977     napi_is_array(env, picturesObj, &isArray);
978     if (!isArray) {
979         ANS_LOGE("The picture is not array.");
980         return nullptr;
981     }
982 
983     uint32_t length = 0;
984     napi_get_array_length(env, picturesObj, &length);
985     if (length == 0) {
986         ANS_LOGE("The array is empty.");
987         return nullptr;
988     }
989 
990     for (uint32_t i = 0; i < length; ++i) {
991         napi_value pictureObj = nullptr;
992         napi_get_element(env, picturesObj, i, &pictureObj);
993         if (!AppExecFwk::IsTypeForNapiValue(env, pictureObj, napi_object)) {
994             ANS_LOGE("Wrong argument type. object expected.");
995             break;
996         }
997 
998         std::shared_ptr<Media::PixelMap> pixelMap = Media::PixelMapNapi::GetPixelMap(env, pictureObj);
999         if (pixelMap == nullptr) {
1000             ANS_LOGE("Invalid pixelMap.");
1001             break;
1002         }
1003 
1004         pictures.emplace_back(pixelMap);
1005     }
1006 
1007     return NapiGetNull(env);
1008 }
1009 
GetLiveViewPictureInfo(const napi_env & env,const napi_value & pictureMapObj,std::map<std::string,std::vector<std::shared_ptr<Media::PixelMap>>> & pictureMap)1010 napi_value Common::GetLiveViewPictureInfo(
1011     const napi_env &env, const napi_value &pictureMapObj,
1012     std::map<std::string, std::vector<std::shared_ptr<Media::PixelMap>>> &pictureMap)
1013 {
1014     ANS_LOGD("enter");
1015 
1016     napi_value pictureNamesObj = nullptr;
1017     uint32_t length = 0;
1018     if (napi_get_property_names(env, pictureMapObj, &pictureNamesObj) != napi_ok) {
1019         ANS_LOGE("Get picture names failed.");
1020         return nullptr;
1021     }
1022     napi_get_array_length(env, pictureNamesObj, &length);
1023     if (length == 0) {
1024         ANS_LOGE("The pictures name is empty.");
1025         return nullptr;
1026     }
1027 
1028     napi_value pictureNameObj = nullptr;
1029     napi_value picturesObj = nullptr;
1030     for (uint32_t index = 0; index < length; index++) {
1031         napi_get_element(env, pictureNamesObj, index, &pictureNameObj);
1032         std::string pictureName = AppExecFwk::UnwrapStringFromJS(env, pictureNameObj);
1033         ANS_LOGD("%{public}s called, get pictures of %{public}s.", __func__, pictureName.c_str());
1034         napi_get_named_property(env, pictureMapObj, pictureName.c_str(), &picturesObj);
1035 
1036         std::vector<std::shared_ptr<Media::PixelMap>> pictures;
1037         if (!GetLiveViewPictures(env, picturesObj, pictures)) {
1038             ANS_LOGE("Get pictures of %{public}s failed.", pictureName.c_str());
1039             break;
1040         }
1041 
1042         pictureMap[pictureName] = pictures;
1043     }
1044 
1045     return NapiGetNull(env);
1046 }
1047 }
1048 }
1049