• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 <cstdint>
17 #include <hilog/log.h>
18 #include <js_native_api.h>
19 #include <js_native_api_types.h>
20 #include <string>
21 
22 #include "../common/common.h"
23 #include "../manager/plugin_manager.h"
24 #include "plugin_render.h"
25 
26 namespace NativeXComponentSample {
27 namespace {
OnSurfaceCreatedCB(OH_NativeXComponent * component,void * window)28 void OnSurfaceCreatedCB(OH_NativeXComponent* component, void* window)
29 {
30     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceCreatedCB");
31     if ((component == nullptr) || (window == nullptr)) {
32         OH_LOG_Print(
33             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceCreatedCB: component or window is null");
34         return;
35     }
36 
37     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
38     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
39     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
40         OH_LOG_Print(
41             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceCreatedCB: Unable to get XComponent id");
42         return;
43     }
44 
45     std::string id(idStr);
46     auto render = PluginRender::GetInstance(id);
47     uint64_t width;
48     uint64_t height;
49     int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
50     if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) {
51         if (render->eglCore_->EglContextInit(window, width, height)) {
52             render->eglCore_->Background();
53         }
54     }
55 }
56 
OnSurfaceChangedCB(OH_NativeXComponent * component,void * window)57 void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window)
58 {
59     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChangedCB");
60     if ((component == nullptr) || (window == nullptr)) {
61         OH_LOG_Print(
62             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChangedCB: component or window is null");
63         return;
64     }
65 
66     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
67     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
68     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
69         OH_LOG_Print(
70             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChangedCB: Unable to get XComponent id");
71         return;
72     }
73 
74     std::string id(idStr);
75     auto render = PluginRender::GetInstance(id);
76     if (render != nullptr) {
77         render->OnSurfaceChanged(component, window);
78         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "surface changed");
79     }
80 }
81 
OnSurfaceDestroyedCB(OH_NativeXComponent * component,void * window)82 void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window)
83 {
84     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceDestroyedCB");
85     if ((component == nullptr) || (window == nullptr)) {
86         OH_LOG_Print(
87             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceDestroyedCB: component or window is null");
88         return;
89     }
90 
91     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
92     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
93     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
94         OH_LOG_Print(
95             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceDestroyedCB: Unable to get XComponent id");
96         return;
97     }
98 
99     std::string id(idStr);
100     PluginRender::Release(id);
101 }
102 
DispatchTouchEventCB(OH_NativeXComponent * component,void * window)103 void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
104 {
105     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB");
106     if ((component == nullptr) || (window == nullptr)) {
107         OH_LOG_Print(
108             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB: component or window is null");
109         return;
110     }
111 
112     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
113     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
114     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
115         OH_LOG_Print(
116             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB: Unable to get XComponent id");
117         return;
118     }
119 
120     std::string id(idStr);
121     PluginRender* render = PluginRender::GetInstance(id);
122     if (render != nullptr) {
123         render->OnTouchEvent(component, window);
124     }
125 }
126 
DispatchMouseEventCB(OH_NativeXComponent * component,void * window)127 void DispatchMouseEventCB(OH_NativeXComponent* component, void* window)
128 {
129     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "DispatchMouseEventCB");
130     int32_t ret;
131     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
132     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
133     ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
134     if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
135         return;
136     }
137 
138     std::string id(idStr);
139     auto render = PluginRender::GetInstance(id);
140     if (render != nullptr) {
141         render->OnMouseEvent(component, window);
142     }
143 }
144 
DispatchHoverEventCB(OH_NativeXComponent * component,bool isHover)145 void DispatchHoverEventCB(OH_NativeXComponent* component, bool isHover)
146 {
147     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "DispatchHoverEventCB");
148     int32_t ret;
149     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
150     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
151     ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
152     if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
153         return;
154     }
155 
156     std::string id(idStr);
157     auto render = PluginRender::GetInstance(id);
158     if (render != nullptr) {
159         render->OnHoverEvent(component, isHover);
160     }
161 }
162 
OnFocusEventCB(OH_NativeXComponent * component,void * window)163 void OnFocusEventCB(OH_NativeXComponent* component, void* window)
164 {
165     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnFocusEventCB");
166     int32_t ret;
167     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
168     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
169     ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
170     if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
171         return;
172     }
173 
174     std::string id(idStr);
175     auto render = PluginRender::GetInstance(id);
176     if (render != nullptr) {
177         render->OnFocusEvent(component, window);
178     }
179 }
180 
OnBlurEventCB(OH_NativeXComponent * component,void * window)181 void OnBlurEventCB(OH_NativeXComponent* component, void* window)
182 {
183     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnBlurEventCB");
184     int32_t ret;
185     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
186     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
187     ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
188     if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
189         return;
190     }
191 
192     std::string id(idStr);
193     auto render = PluginRender::GetInstance(id);
194     if (render != nullptr) {
195         render->OnBlurEvent(component, window);
196     }
197 }
198 
OnKeyEventCB(OH_NativeXComponent * component,void * window)199 void OnKeyEventCB(OH_NativeXComponent* component, void* window)
200 {
201     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnKeyEventCB");
202     int32_t ret;
203     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
204     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
205     ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
206     if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
207         return;
208     }
209     std::string id(idStr);
210     auto render = PluginRender::GetInstance(id);
211     if (render != nullptr) {
212         render->OnKeyEvent(component, window);
213     }
214 }
215 } // namespace
216 
217 std::unordered_map<std::string, PluginRender*> PluginRender::instance_;
218 int32_t PluginRender::hasDraw_ = 0;
219 int32_t PluginRender::hasChangeColor_ = 0;
220 
PluginRender(std::string & id)221 PluginRender::PluginRender(std::string& id)
222 {
223     this->id_ = id;
224     this->eglCore_ = new EGLCore();
225 }
226 
GetInstance(std::string & id)227 PluginRender* PluginRender::GetInstance(std::string& id)
228 {
229     if (instance_.find(id) == instance_.end()) {
230         PluginRender* instance = new PluginRender(id);
231         instance_[id] = instance;
232         return instance;
233     } else {
234         return instance_[id];
235     }
236 }
237 
Export(napi_env env,napi_value exports)238 void PluginRender::Export(napi_env env, napi_value exports)
239 {
240     if ((env == nullptr) || (exports == nullptr)) {
241         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "Export: env or exports is null");
242         return;
243     }
244 
245     napi_property_descriptor desc[] = {
246         {"drawPattern", nullptr, PluginRender::NapiDrawPattern, nullptr, nullptr,
247          nullptr, napi_default, nullptr},
248         {"getStatus", nullptr, PluginRender::TestGetXComponentStatus, nullptr, nullptr,
249          nullptr, napi_default, nullptr}};
250     if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
251         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "Export: napi_define_properties failed");
252     }
253 }
254 
255 // NAPI registration method type napi_callback. If no value is returned, nullptr is returned.
NapiDrawPattern(napi_env env,napi_callback_info info)256 napi_value PluginRender::NapiDrawPattern(napi_env env, napi_callback_info info)
257 {
258     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern");
259     if ((env == nullptr) || (info == nullptr)) {
260         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: env or info is null");
261         return nullptr;
262     }
263 
264     napi_value thisArg;
265     if (napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr) != napi_ok) {
266         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: napi_get_cb_info fail");
267         return nullptr;
268     }
269 
270     napi_value exportInstance;
271     if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
272         OH_LOG_Print(
273             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: napi_get_named_property fail");
274         return nullptr;
275     }
276 
277     OH_NativeXComponent* nativeXComponent = nullptr;
278     if (napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent)) != napi_ok) {
279         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: napi_unwrap fail");
280         return nullptr;
281     }
282 
283     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
284     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
285     if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
286         OH_LOG_Print(
287             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: Unable to get XComponent id");
288         return nullptr;
289     }
290 
291     std::string id(idStr);
292     PluginRender* render = PluginRender::GetInstance(id);
293     if (render != nullptr) {
294         render->eglCore_->Draw(hasDraw_);
295         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "render->eglCore_->Draw() executed");
296     }
297     return nullptr;
298 }
299 
Release(std::string & id)300 void PluginRender::Release(std::string& id)
301 {
302     PluginRender* render = PluginRender::GetInstance(id);
303     if (render != nullptr) {
304         render->eglCore_->Release();
305         delete render->eglCore_;
306         render->eglCore_ = nullptr;
307         instance_.erase(instance_.find(id));
308     }
309 }
310 
OnSurfaceChanged(OH_NativeXComponent * component,void * window)311 void PluginRender::OnSurfaceChanged(OH_NativeXComponent* component, void* window)
312 {
313     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
314     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
315     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
316         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChanged: Unable to get XComponent id");
317         return;
318     }
319 
320     std::string id(idStr);
321     PluginRender* render = PluginRender::GetInstance(id);
322     double offsetX;
323     double offsetY;
324     OH_NativeXComponent_GetXComponentOffset(component, window, &offsetX, &offsetY);
325     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "OH_NativeXComponent_GetXComponentOffset",
326         "offsetX = %{public}lf, offsetY = %{public}lf", offsetX, offsetY);
327     uint64_t width;
328     uint64_t height;
329     OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
330     if (render != nullptr) {
331         render->eglCore_->UpdateSize(width, height);
332     }
333 }
334 
OnTouchEvent(OH_NativeXComponent * component,void * window)335 void PluginRender::OnTouchEvent(OH_NativeXComponent* component, void* window)
336 {
337     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
338     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
339     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
340         OH_LOG_Print(
341             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB: Unable to get XComponent id");
342         return;
343     }
344     OH_NativeXComponent_TouchEvent touchEvent;
345     OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent);
346     std::string id(idStr);
347     PluginRender* render = PluginRender::GetInstance(id);
348     if (render != nullptr && touchEvent.type == OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UP) {
349         render->eglCore_->ChangeColor(hasChangeColor_);
350     }
351     float tiltX = 0.0f;
352     float tiltY = 0.0f;
353     OH_NativeXComponent_TouchPointToolType toolType =
354         OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN;
355     OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType);
356     OH_NativeXComponent_GetTouchPointTiltX(component, 0, &tiltX);
357     OH_NativeXComponent_GetTouchPointTiltY(component, 0, &tiltY);
358     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "OnTouchEvent",
359         "touch info: toolType = %{public}d, tiltX = %{public}lf, tiltY = %{public}lf", toolType, tiltX, tiltY);
360 }
361 
RegisterCallback(OH_NativeXComponent * nativeXComponent)362 void PluginRender::RegisterCallback(OH_NativeXComponent* nativeXComponent)
363 {
364     renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
365     renderCallback_.OnSurfaceChanged = OnSurfaceChangedCB;
366     renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
367     renderCallback_.DispatchTouchEvent = DispatchTouchEventCB;
368     OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);
369 
370     mouseCallback_.DispatchMouseEvent = DispatchMouseEventCB;
371     mouseCallback_.DispatchHoverEvent = DispatchHoverEventCB;
372     OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &mouseCallback_);
373 
374     OH_NativeXComponent_RegisterFocusEventCallback(nativeXComponent, OnFocusEventCB);
375     OH_NativeXComponent_RegisterKeyEventCallback(nativeXComponent, OnKeyEventCB);
376     OH_NativeXComponent_RegisterBlurEventCallback(nativeXComponent, OnBlurEventCB);
377 }
378 
OnMouseEvent(OH_NativeXComponent * component,void * window)379 void PluginRender::OnMouseEvent(OH_NativeXComponent* component, void* window)
380 {
381     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnMouseEvent");
382     OH_NativeXComponent_MouseEvent mouseEvent;
383     int32_t ret = OH_NativeXComponent_GetMouseEvent(component, window, &mouseEvent);
384     if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
385         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
386             "MouseEvent Info: x = %{public}f, y = %{public}f, action = %{public}d, button = %{public}d", mouseEvent.x,
387             mouseEvent.y, mouseEvent.action, mouseEvent.button);
388     } else {
389         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "GetMouseEvent error");
390     }
391 }
392 
OnHoverEvent(OH_NativeXComponent * component,bool isHover)393 void PluginRender::OnHoverEvent(OH_NativeXComponent* component, bool isHover)
394 {
395     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnHoverEvent isHover_ = %{public}d", isHover);
396 }
397 
OnFocusEvent(OH_NativeXComponent * component,void * window)398 void PluginRender::OnFocusEvent(OH_NativeXComponent* component, void* window)
399 {
400     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnFocusEvent");
401 }
402 
OnBlurEvent(OH_NativeXComponent * component,void * window)403 void PluginRender::OnBlurEvent(OH_NativeXComponent* component, void* window)
404 {
405     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnBlurEvent");
406 }
407 
OnKeyEvent(OH_NativeXComponent * component,void * window)408 void PluginRender::OnKeyEvent(OH_NativeXComponent* component, void* window)
409 {
410     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnKeyEvent");
411 
412     OH_NativeXComponent_KeyEvent* keyEvent = nullptr;
413     if (OH_NativeXComponent_GetKeyEvent(component, &keyEvent) >= 0) {
414         OH_NativeXComponent_KeyAction action;
415         OH_NativeXComponent_GetKeyEventAction(keyEvent, &action);
416         OH_NativeXComponent_KeyCode code;
417         OH_NativeXComponent_GetKeyEventCode(keyEvent, &code);
418         OH_NativeXComponent_EventSourceType sourceType;
419         OH_NativeXComponent_GetKeyEventSourceType(keyEvent, &sourceType);
420         int64_t deviceId;
421         OH_NativeXComponent_GetKeyEventDeviceId(keyEvent, &deviceId);
422         int64_t timeStamp;
423         OH_NativeXComponent_GetKeyEventTimestamp(keyEvent, &timeStamp);
424         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
425             "KeyEvent Info: action=%{public}d, code=%{public}d, sourceType=%{public}d, deviceId=%{public}ld, "
426             "timeStamp=%{public}ld",
427             action, code, sourceType, deviceId, timeStamp);
428     } else {
429         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "GetKeyEvent error");
430     }
431 }
432 
TestGetXComponentStatus(napi_env env,napi_callback_info info)433 napi_value PluginRender::TestGetXComponentStatus(napi_env env, napi_callback_info info)
434 {
435     napi_value hasDraw;
436     napi_value hasChangeColor;
437 
438     napi_status ret = napi_create_int32(env, hasDraw_, &(hasDraw));
439     if (ret != napi_ok) {
440         OH_LOG_Print(
441             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_create_int32 hasDraw_ error");
442         return nullptr;
443     }
444     ret = napi_create_int32(env, hasChangeColor_, &(hasChangeColor));
445     if (ret != napi_ok) {
446         OH_LOG_Print(
447             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_create_int32 hasChangeColor_ error");
448         return nullptr;
449     }
450 
451     napi_value obj;
452     ret = napi_create_object(env, &obj);
453     if (ret != napi_ok) {
454         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_create_object error");
455         return nullptr;
456     }
457     ret = napi_set_named_property(env, obj, "hasDraw", hasDraw);
458     if (ret != napi_ok) {
459         OH_LOG_Print(
460             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_set_named_property hasDraw error");
461         return nullptr;
462     }
463     ret = napi_set_named_property(env, obj, "hasChangeColor", hasChangeColor);
464     if (ret != napi_ok) {
465         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus",
466             "napi_set_named_property hasChangeColor error");
467         return nullptr;
468     }
469     return obj;
470 }
471 } // namespace NativeXComponentSample
472