• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "js_drawable_descriptor.h"
17 
18 #include "napi/native_api.h"
19 #include "napi/native_common.h"
20 #include "napi/native_node_api.h"
21 #ifndef PREVIEW
22 #include "pixel_map_napi.h"
23 #else
24 #include "image_source_preview.h"
25 #endif
26 #include "resource_manager.h"
27 
28 #include "base/log.h"
29 
30 namespace {
31 constexpr char DRAWABLE_BASE[] = "DrawableDescriptor";
32 constexpr char DRAWABLE_LAYERED[] = "LayeredDrawableDescriptor";
33 constexpr char DRAWABLE_ANIMATED[] = "AnimatedDrawableDescriptor";
34 constexpr char DRAWABLE_PIXELMAP[] = "PixelMapDrawableDescriptor";
35 constexpr int32_t PARAMS_NUM_ONE = 1;
36 constexpr int32_t PARAMS_NUM_THREE = 3;
37 
38 constexpr int32_t FOREGROUND_INDEX = 0;
39 constexpr int32_t BACKGROUND_INDEX = 1;
40 constexpr int32_t MASK_INDEX = 2;
41 
UpdateLayeredParam(OHOS::Ace::Napi::LayeredDrawableDescriptor * layeredDrawable,int32_t pos,std::shared_ptr<OHOS::Media::PixelMap> pixelMap)42 void UpdateLayeredParam(OHOS::Ace::Napi::LayeredDrawableDescriptor* layeredDrawable, int32_t pos,
43     std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
44 {
45     if (!layeredDrawable || !pixelMap) {
46         return;
47     }
48     switch (pos) {
49         case FOREGROUND_INDEX:
50             layeredDrawable->SetForeground(pixelMap);
51             break;
52         case BACKGROUND_INDEX:
53             layeredDrawable->SetBackground(pixelMap);
54             break;
55         case MASK_INDEX:
56             layeredDrawable->SetMask(pixelMap);
57             break;
58         default:
59             HILOGW("Arg[%{public}d] index error", pos);
60     }
61 }
62 } // namespace
63 
64 namespace OHOS::Ace::Napi {
65 thread_local napi_ref JsDrawableDescriptor::baseConstructor_;
66 thread_local napi_ref JsDrawableDescriptor::layeredConstructor_;
67 thread_local napi_ref JsDrawableDescriptor::animatedConstructor_;
68 thread_local napi_ref JsDrawableDescriptor::pixelMapConstructor_;
69 
GetPixelMapArray(napi_env env,napi_value arg,std::vector<std::shared_ptr<Media::PixelMap>> & pixelMaps)70 static bool GetPixelMapArray(napi_env env, napi_value arg, std::vector<std::shared_ptr<Media::PixelMap>>& pixelMaps)
71 {
72     bool isArray = false;
73     uint32_t length = 0;
74     napi_is_array(env, arg, &isArray);
75     if (!isArray) {
76         return false;
77     }
78     napi_get_array_length(env, arg, &length);
79     if (length < 1) {
80         return false;
81     }
82     for (uint32_t i = 0; i < length; i++) {
83         napi_value pixelMapValue = nullptr;
84         napi_get_element(env, arg, i, &pixelMapValue);
85         if (pixelMapValue == nullptr) {
86             continue;
87         }
88         Media::PixelMapNapi* pixmapNapi = nullptr;
89         napi_unwrap(env, pixelMapValue, reinterpret_cast<void**>(&pixmapNapi));
90         if (pixmapNapi == nullptr) {
91             continue;
92         }
93         pixelMaps.push_back(*(pixmapNapi->GetPixelMap()));
94     }
95     if (pixelMaps.size() <= 0) {
96         return false;
97     }
98     return true;
99 }
100 
AnimatedConstructor(napi_env env,napi_callback_info info)101 napi_value JsDrawableDescriptor::AnimatedConstructor(napi_env env, napi_callback_info info)
102 {
103     napi_escapable_handle_scope scope = nullptr;
104     napi_open_escapable_handle_scope(env, &scope);
105 
106     size_t argc = 2;
107     napi_value argv[2] = { nullptr };
108     napi_value thisVar = nullptr;
109     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
110     if (status != napi_ok) {
111         GET_AND_THROW_LAST_ERROR((env));
112         napi_close_escapable_handle_scope(env, scope);
113         return nullptr;
114     }
115     if (argc < 1) {
116         napi_close_escapable_handle_scope(env, scope);
117         return nullptr;
118     }
119     std::vector<std::shared_ptr<Media::PixelMap>> pixelMaps;
120     if (!GetPixelMapArray(env, argv[0], pixelMaps)) {
121         napi_close_escapable_handle_scope(env, scope);
122         return nullptr;
123     }
124 
125     // napi_get_named_property
126     napi_value napiDuration;
127     napi_value napiIterations;
128     int32_t duration = -1;
129     int32_t iterations = 1;
130     if (argc > 1 && argv[1]) {
131         napi_get_named_property(env, argv[1], "duration", &napiDuration);
132         napi_get_named_property(env, argv[1], "iterations", &napiIterations);
133         napi_get_value_int32(env, napiDuration, &duration);
134         napi_get_value_int32(env, napiIterations, &iterations);
135     }
136     // create JsDrawable
137     auto* animatedDrawable = new AnimatedDrawableDescriptor(pixelMaps, duration, iterations);
138     // wrap to napi_value
139     napi_wrap(env, thisVar, animatedDrawable, Destructor, nullptr, nullptr);
140     napi_escape_handle(env, scope, thisVar, &thisVar);
141     napi_close_escapable_handle_scope(env, scope);
142     return thisVar;
143 }
144 
Constructor(napi_env env,napi_callback_info info)145 napi_value JsDrawableDescriptor::Constructor(napi_env env, napi_callback_info info)
146 {
147     napi_escapable_handle_scope scope = nullptr;
148     napi_open_escapable_handle_scope(env, &scope);
149     napi_value thisVar = nullptr;
150     napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
151     if (status != napi_ok) {
152         GET_AND_THROW_LAST_ERROR((env));
153         napi_close_escapable_handle_scope(env, scope);
154         return nullptr;
155     }
156     // create JsDrawable
157     auto* drawable = new DrawableDescriptor;
158     // wrap to napi_value
159     napi_wrap(env, thisVar, drawable, Destructor, nullptr, nullptr);
160     napi_escape_handle(env, scope, thisVar, &thisVar);
161     napi_close_escapable_handle_scope(env, scope);
162     return thisVar;
163 }
164 
PixelMapConstructor(napi_env env,napi_callback_info info)165 napi_value JsDrawableDescriptor::PixelMapConstructor(napi_env env, napi_callback_info info)
166 {
167     napi_escapable_handle_scope scope = nullptr;
168     napi_open_escapable_handle_scope(env, &scope);
169     size_t argc = PARAMS_NUM_ONE;
170     napi_value argv[argc];
171     napi_value thisVar = nullptr;
172     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
173     if (status != napi_ok) {
174         GET_AND_THROW_LAST_ERROR((env));
175         napi_close_escapable_handle_scope(env, scope);
176         return nullptr;
177     }
178     auto* drawable = new DrawableDescriptor;
179     if (argc == 0) {
180         HILOGW("JsDrawableDescriptor::PixelMapConstructor get null pixelMap param");
181         napi_wrap(env, thisVar, drawable, Destructor, nullptr, nullptr);
182         napi_escape_handle(env, scope, thisVar, &thisVar);
183         napi_close_escapable_handle_scope(env, scope);
184         return thisVar;
185     }
186     napi_value argPixelMap = argv[0];
187     napi_valuetype type;
188     napi_typeof(env, argPixelMap, &type);
189     if (type == napi_object) {
190         auto pixelMap = GetPixelMapFromNapi(env, argPixelMap);
191         if (pixelMap) {
192             drawable->SetPixelMap(pixelMap);
193         }
194     }
195 
196     // wrap to napi_value
197     napi_wrap(env, thisVar, drawable, Destructor, nullptr, nullptr);
198     napi_escape_handle(env, scope, thisVar, &thisVar);
199     napi_close_escapable_handle_scope(env, scope);
200     return thisVar;
201 }
202 
LayeredConstructor(napi_env env,napi_callback_info info)203 napi_value JsDrawableDescriptor::LayeredConstructor(napi_env env, napi_callback_info info)
204 {
205     napi_escapable_handle_scope scope = nullptr;
206     napi_open_escapable_handle_scope(env, &scope);
207     size_t argc = PARAMS_NUM_THREE;
208     napi_value argv[argc];
209     napi_value thisVar = nullptr;
210     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
211     if (status != napi_ok) {
212         GET_AND_THROW_LAST_ERROR((env));
213         napi_close_escapable_handle_scope(env, scope);
214         return nullptr;
215     }
216     auto pos = -1;
217     auto* layeredDrawable = new LayeredDrawableDescriptor;
218     if (argc == 0) {
219         napi_wrap(env, thisVar, layeredDrawable, Destructor, nullptr, nullptr);
220         napi_escape_handle(env, scope, thisVar, &thisVar);
221         napi_close_escapable_handle_scope(env, scope);
222         return thisVar;
223     }
224     std::shared_ptr<Media::PixelMap> foregroundPixelMap = nullptr;
225     auto updateUndefinedPixelMap = [&pos, &layeredDrawable, &foregroundPixelMap]() -> void {
226         if (pos == MASK_INDEX) {
227             std::shared_ptr<Global::Resource::ResourceManager> resMgr(Global::Resource::CreateResourceManager());
228             layeredDrawable->InitialMask(resMgr);
229         } else if (pos == BACKGROUND_INDEX && foregroundPixelMap) {
230             UpdateLayeredParam(layeredDrawable, pos, foregroundPixelMap);
231         }
232     };
233     napi_valuetype type;
234     for (const auto& arg : argv) {
235         pos++;
236         napi_typeof(env, arg, &type);
237         if (type == napi_undefined) {
238             updateUndefinedPixelMap();
239             continue;
240         }
241         auto pixelMap = GetPixelMapFromDrawableNapi(env, arg);
242         if (!pixelMap) {
243             updateUndefinedPixelMap();
244         } else {
245             UpdateLayeredParam(layeredDrawable, pos, pixelMap);
246             if (pos == FOREGROUND_INDEX)
247                 foregroundPixelMap = std::move(pixelMap);
248         }
249     }
250     napi_wrap(env, thisVar, layeredDrawable, Destructor, nullptr, nullptr);
251     napi_escape_handle(env, scope, thisVar, &thisVar);
252     napi_close_escapable_handle_scope(env, scope);
253     return thisVar;
254 }
255 
GetPixelMapFromNapi(napi_env env,napi_value napiValue)256 std::shared_ptr<Media::PixelMap> JsDrawableDescriptor::GetPixelMapFromNapi(napi_env env, napi_value napiValue)
257 {
258     Media::PixelMapNapi* pixelMapNapi = nullptr;
259     napi_unwrap(env, napiValue, reinterpret_cast<void**>(&pixelMapNapi));
260     if (pixelMapNapi == nullptr) {
261         HILOGI("JsDrawableDescriptor::GetPixelMapFromNapi Argv is invalid");
262         return nullptr;
263     }
264     auto pixelMap = *(pixelMapNapi->GetPixelMap());
265     if (pixelMap == nullptr) {
266         HILOGI("JsDrawableDescriptor::GetPixelMapFromNapi GetPixelNapiInner from media is nullptr");
267         return nullptr;
268     }
269     return pixelMap;
270 }
271 
GetPixelMapFromDrawableNapi(napi_env env,napi_value napiValue)272 std::shared_ptr<Media::PixelMap> JsDrawableDescriptor::GetPixelMapFromDrawableNapi(napi_env env, napi_value napiValue)
273 {
274     DrawableDescriptor* drawableNapi = nullptr;
275     napi_unwrap(env, napiValue, reinterpret_cast<void**>(&drawableNapi));
276     if (drawableNapi == nullptr) {
277         HILOGW("JsDrawableDescriptor::GetPixelMapFromDrawableNapi Argv is invalid");
278         return nullptr;
279     }
280     auto pixelMap = drawableNapi->GetPixelMap();
281     if (pixelMap == nullptr) {
282         HILOGW("JsDrawableDescriptor::GetPixelMapFromDrawableNapi GetPixelNapiInner from media is nullptr");
283         return nullptr;
284     }
285     return pixelMap;
286 }
287 
Destructor(napi_env,void * data,void *)288 void JsDrawableDescriptor::Destructor(napi_env /* env */, void* data, void* /* hint */)
289 {
290     auto* field = reinterpret_cast<DrawableDescriptor*>(data);
291     delete field;
292 }
293 
InitDrawable(napi_env env)294 napi_value JsDrawableDescriptor::InitDrawable(napi_env env)
295 {
296     napi_value cons = nullptr;
297     napi_property_descriptor baseDes[] = {
298         DECLARE_NAPI_FUNCTION("getPixelMap", GetPixelMap),
299     };
300     NAPI_CALL(env, napi_define_class(env, DRAWABLE_BASE, NAPI_AUTO_LENGTH, Constructor, nullptr,
301                        sizeof(baseDes) / sizeof(napi_property_descriptor), baseDes, &cons));
302     NAPI_CALL(env, napi_create_reference(env, cons, 1, &baseConstructor_));
303     return cons;
304 }
305 
InitPixelMapDrawable(napi_env env)306 napi_value JsDrawableDescriptor::InitPixelMapDrawable(napi_env env)
307 {
308     napi_value cons = nullptr;
309     napi_property_descriptor pixelDes[] = {
310         DECLARE_NAPI_FUNCTION("getPixelMap", GetPixelMap),
311     };
312     NAPI_CALL(env, napi_define_class(env, DRAWABLE_PIXELMAP, NAPI_AUTO_LENGTH, PixelMapConstructor, nullptr,
313                        sizeof(pixelDes) / sizeof(napi_property_descriptor), pixelDes, &cons));
314     NAPI_CALL(env, napi_create_reference(env, cons, 1, &pixelMapConstructor_));
315     return cons;
316 }
317 
InitLayeredDrawable(napi_env env)318 napi_value JsDrawableDescriptor::InitLayeredDrawable(napi_env env)
319 {
320     napi_value cons = nullptr;
321     napi_property_descriptor layeredDes[] = {
322         DECLARE_NAPI_FUNCTION("getPixelMap", GetPixelMap),
323         DECLARE_NAPI_FUNCTION("getForeground", GetForeground),
324         DECLARE_NAPI_FUNCTION("getBackground", GetBackground),
325         DECLARE_NAPI_FUNCTION("getMask", GetMask),
326         DECLARE_NAPI_STATIC_FUNCTION("getMaskClipPath", GetMaskClipPath),
327     };
328     NAPI_CALL(env, napi_define_class(env, DRAWABLE_LAYERED, NAPI_AUTO_LENGTH, LayeredConstructor, nullptr,
329                        sizeof(layeredDes) / sizeof(napi_property_descriptor), layeredDes, &cons));
330     NAPI_CALL(env, napi_create_reference(env, cons, 1, &layeredConstructor_));
331     return cons;
332 }
333 
InitAnimatedDrawable(napi_env env)334 napi_value JsDrawableDescriptor::InitAnimatedDrawable(napi_env env)
335 {
336     napi_value cons = nullptr;
337     napi_property_descriptor animatedDes[] = {
338         DECLARE_NAPI_FUNCTION("getPixelMap", GetPixelMap),
339     };
340     NAPI_CALL(env, napi_define_class(env, DRAWABLE_ANIMATED, NAPI_AUTO_LENGTH, AnimatedConstructor, nullptr,
341                        sizeof(animatedDes) / sizeof(napi_property_descriptor), animatedDes, &cons));
342     NAPI_CALL(env, napi_create_reference(env, cons, 1, &animatedConstructor_));
343     return cons;
344 }
345 
ToNapi(napi_env env,DrawableDescriptor * drawable,DrawableDescriptor::DrawableType type)346 napi_value JsDrawableDescriptor::ToNapi(
347     napi_env env, DrawableDescriptor* drawable, DrawableDescriptor::DrawableType type)
348 {
349     if (!drawable) {
350         return nullptr;
351     }
352     if (!baseConstructor_ || !layeredConstructor_ || !animatedConstructor_ || !pixelMapConstructor_) {
353         // init js class constructor by importing module manually
354         napi_value globalValue;
355         napi_get_global(env, &globalValue);
356         napi_value func;
357         napi_get_named_property(env, globalValue, "requireNapi", &func);
358 
359         napi_value module;
360         napi_create_string_utf8(env, MODULE_NAME, NAPI_AUTO_LENGTH, &module);
361         napi_value returnValue;
362         napi_call_function(env, globalValue, func, 1, &module, &returnValue);
363     }
364 
365     napi_value constructor = nullptr;
366     napi_value result = nullptr;
367     napi_status status;
368     switch (type) {
369         case DrawableDescriptor::DrawableType::ANIMATED:
370             status = napi_get_reference_value(env, animatedConstructor_, &constructor);
371             break;
372         case DrawableDescriptor::DrawableType::LAYERED:
373             status = napi_get_reference_value(env, layeredConstructor_, &constructor);
374             break;
375         case DrawableDescriptor::DrawableType::BASE:
376             status = napi_get_reference_value(env, baseConstructor_, &constructor);
377             break;
378         case DrawableDescriptor::DrawableType::PIXELMAP:
379             status = napi_get_reference_value(env, pixelMapConstructor_, &constructor);
380             break;
381         default:
382             status = napi_status::napi_invalid_arg;
383             break;
384     }
385     if (status == napi_status::napi_ok) {
386         NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
387         NAPI_CALL(env, napi_wrap(env, result, drawable, Destructor, nullptr, nullptr));
388     } else {
389         HILOGI("create reference failed, drawable constructor is null");
390     }
391 
392     return result;
393 }
394 
GetPixelMap(napi_env env,napi_callback_info info)395 napi_value JsDrawableDescriptor::GetPixelMap(napi_env env, napi_callback_info info)
396 {
397     napi_escapable_handle_scope scope = nullptr;
398     napi_open_escapable_handle_scope(env, &scope);
399     napi_value thisVar = nullptr;
400     napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
401     if (status != napi_ok) {
402         GET_AND_THROW_LAST_ERROR((env));
403         napi_close_escapable_handle_scope(env, scope);
404         return nullptr;
405     }
406     void* native = nullptr;
407     napi_unwrap(env, thisVar, &native);
408     auto* drawable = reinterpret_cast<DrawableDescriptor*>(native);
409     if (!drawable) {
410         napi_close_escapable_handle_scope(env, scope);
411         return nullptr;
412     }
413     auto pixmap = drawable->GetPixelMap();
414 
415     napi_value result = Media::PixelMapNapi::CreatePixelMap(env, pixmap);
416     napi_escape_handle(env, scope, result, &result);
417     napi_close_escapable_handle_scope(env, scope);
418     return result;
419 }
420 
GetForeground(napi_env env,napi_callback_info info)421 napi_value JsDrawableDescriptor::GetForeground(napi_env env, napi_callback_info info)
422 {
423     napi_escapable_handle_scope scope = nullptr;
424     napi_open_escapable_handle_scope(env, &scope);
425     napi_value thisVar = nullptr;
426     napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
427     if (status != napi_ok) {
428         GET_AND_THROW_LAST_ERROR((env));
429         napi_close_escapable_handle_scope(env, scope);
430         return nullptr;
431     }
432     void* native = nullptr;
433     napi_unwrap(env, thisVar, &native);
434     auto* drawable = reinterpret_cast<LayeredDrawableDescriptor*>(native);
435     if (!drawable) {
436         napi_close_escapable_handle_scope(env, scope);
437         return nullptr;
438     }
439 
440     auto foreground = drawable->GetForeground();
441     napi_value result = ToNapi(env, foreground.release(), DrawableDescriptor::DrawableType::BASE);
442     napi_escape_handle(env, scope, result, &result);
443     napi_close_escapable_handle_scope(env, scope);
444     return result;
445 }
446 
GetBackground(napi_env env,napi_callback_info info)447 napi_value JsDrawableDescriptor::GetBackground(napi_env env, napi_callback_info info)
448 {
449     napi_escapable_handle_scope scope = nullptr;
450     napi_open_escapable_handle_scope(env, &scope);
451     napi_value thisVar = nullptr;
452     napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
453     if (status != napi_ok) {
454         GET_AND_THROW_LAST_ERROR((env));
455         napi_close_escapable_handle_scope(env, scope);
456         return nullptr;
457     }
458     void* native = nullptr;
459     napi_unwrap(env, thisVar, &native);
460     auto* drawable = reinterpret_cast<LayeredDrawableDescriptor*>(native);
461     if (!drawable) {
462         napi_close_escapable_handle_scope(env, scope);
463         return nullptr;
464     }
465 
466     auto background = drawable->GetBackground();
467     napi_value result = ToNapi(env, background.release(), DrawableDescriptor::DrawableType::BASE);
468     napi_escape_handle(env, scope, result, &result);
469     napi_close_escapable_handle_scope(env, scope);
470     return result;
471 }
472 
GetMask(napi_env env,napi_callback_info info)473 napi_value JsDrawableDescriptor::GetMask(napi_env env, napi_callback_info info)
474 {
475     napi_escapable_handle_scope scope = nullptr;
476     napi_open_escapable_handle_scope(env, &scope);
477     napi_value thisVar = nullptr;
478     napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
479     if (status != napi_ok) {
480         GET_AND_THROW_LAST_ERROR((env));
481         napi_close_escapable_handle_scope(env, scope);
482         return nullptr;
483     }
484     void* native = nullptr;
485     napi_unwrap(env, thisVar, &native);
486     auto* drawable = reinterpret_cast<LayeredDrawableDescriptor*>(native);
487     if (!drawable) {
488         napi_close_escapable_handle_scope(env, scope);
489         return nullptr;
490     }
491 
492     auto mask = drawable->GetMask();
493     napi_value result = ToNapi(env, mask.release(), DrawableDescriptor::DrawableType::BASE);
494     napi_escape_handle(env, scope, result, &result);
495     napi_close_escapable_handle_scope(env, scope);
496     return result;
497 }
498 
GetMaskClipPath(napi_env env,napi_callback_info info)499 napi_value JsDrawableDescriptor::GetMaskClipPath(napi_env env, napi_callback_info info)
500 {
501     auto path = OHOS::Ace::Napi::LayeredDrawableDescriptor::GetStaticMaskClipPath();
502     napi_value result = nullptr;
503     if (napi_ok != napi_create_string_utf8(env, path.c_str(), NAPI_AUTO_LENGTH, &result)) {
504         HILOGI("JsDrawableDescriptor Failed");
505     }
506     return result;
507 }
508 
Export(napi_env env,napi_value exports)509 napi_value JsDrawableDescriptor::Export(napi_env env, napi_value exports)
510 {
511     // export base class
512     napi_value cons = InitDrawable(env);
513     NAPI_CALL(env, napi_set_named_property(env, exports, DRAWABLE_BASE, cons));
514 
515     cons = InitPixelMapDrawable(env);
516     NAPI_CALL(env, napi_set_named_property(env, exports, DRAWABLE_PIXELMAP, cons));
517 
518     // export child class
519     cons = InitLayeredDrawable(env);
520     NAPI_CALL(env, napi_set_named_property(env, exports, DRAWABLE_LAYERED, cons));
521 
522     // export child class
523     cons = InitAnimatedDrawable(env);
524     NAPI_CALL(env, napi_set_named_property(env, exports, DRAWABLE_ANIMATED, cons));
525 
526     return exports;
527 }
528 } // namespace OHOS::Ace::Napi
529