• 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         delete render;
308         render = nullptr;
309         instance_.erase(instance_.find(id));
310     }
311 }
312 
OnSurfaceChanged(OH_NativeXComponent * component,void * window)313 void PluginRender::OnSurfaceChanged(OH_NativeXComponent* component, void* window)
314 {
315     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
316     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
317     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
318         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChanged: Unable to get XComponent id");
319         return;
320     }
321 
322     std::string id(idStr);
323     PluginRender* render = PluginRender::GetInstance(id);
324     double offsetX;
325     double offsetY;
326     OH_NativeXComponent_GetXComponentOffset(component, window, &offsetX, &offsetY);
327     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "OH_NativeXComponent_GetXComponentOffset",
328         "offsetX = %{public}lf, offsetY = %{public}lf", offsetX, offsetY);
329     uint64_t width;
330     uint64_t height;
331     OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
332     if (render != nullptr) {
333         render->eglCore_->UpdateSize(width, height);
334     }
335 }
336 
OnTouchEvent(OH_NativeXComponent * component,void * window)337 void PluginRender::OnTouchEvent(OH_NativeXComponent* component, void* window)
338 {
339     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
340     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
341     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
342         OH_LOG_Print(
343             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB: Unable to get XComponent id");
344         return;
345     }
346     OH_NativeXComponent_TouchEvent touchEvent;
347     OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent);
348     std::string id(idStr);
349     PluginRender* render = PluginRender::GetInstance(id);
350     if (render != nullptr && touchEvent.type == OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UP) {
351         render->eglCore_->ChangeColor(hasChangeColor_);
352     }
353     float tiltX = 0.0f;
354     float tiltY = 0.0f;
355     OH_NativeXComponent_TouchPointToolType toolType =
356         OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN;
357     OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType);
358     OH_NativeXComponent_GetTouchPointTiltX(component, 0, &tiltX);
359     OH_NativeXComponent_GetTouchPointTiltY(component, 0, &tiltY);
360     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "OnTouchEvent",
361         "touch info: toolType = %{public}d, tiltX = %{public}lf, tiltY = %{public}lf", toolType, tiltX, tiltY);
362 }
363 
RegisterCallback(OH_NativeXComponent * nativeXComponent)364 void PluginRender::RegisterCallback(OH_NativeXComponent* nativeXComponent)
365 {
366     renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
367     renderCallback_.OnSurfaceChanged = OnSurfaceChangedCB;
368     renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
369     renderCallback_.DispatchTouchEvent = DispatchTouchEventCB;
370     OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);
371 
372     mouseCallback_.DispatchMouseEvent = DispatchMouseEventCB;
373     mouseCallback_.DispatchHoverEvent = DispatchHoverEventCB;
374     OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &mouseCallback_);
375 
376     OH_NativeXComponent_RegisterFocusEventCallback(nativeXComponent, OnFocusEventCB);
377     OH_NativeXComponent_RegisterKeyEventCallback(nativeXComponent, OnKeyEventCB);
378     OH_NativeXComponent_RegisterBlurEventCallback(nativeXComponent, OnBlurEventCB);
379 }
380 
OnMouseEvent(OH_NativeXComponent * component,void * window)381 void PluginRender::OnMouseEvent(OH_NativeXComponent* component, void* window)
382 {
383     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnMouseEvent");
384     OH_NativeXComponent_MouseEvent mouseEvent;
385     int32_t ret = OH_NativeXComponent_GetMouseEvent(component, window, &mouseEvent);
386     if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
387         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
388             "MouseEvent Info: x = %{public}f, y = %{public}f, action = %{public}d, button = %{public}d", mouseEvent.x,
389             mouseEvent.y, mouseEvent.action, mouseEvent.button);
390     } else {
391         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "GetMouseEvent error");
392     }
393 }
394 
OnHoverEvent(OH_NativeXComponent * component,bool isHover)395 void PluginRender::OnHoverEvent(OH_NativeXComponent* component, bool isHover)
396 {
397     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnHoverEvent isHover_ = %{public}d", isHover);
398 }
399 
OnFocusEvent(OH_NativeXComponent * component,void * window)400 void PluginRender::OnFocusEvent(OH_NativeXComponent* component, void* window)
401 {
402     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnFocusEvent");
403 }
404 
OnBlurEvent(OH_NativeXComponent * component,void * window)405 void PluginRender::OnBlurEvent(OH_NativeXComponent* component, void* window)
406 {
407     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnBlurEvent");
408 }
409 
OnKeyEvent(OH_NativeXComponent * component,void * window)410 void PluginRender::OnKeyEvent(OH_NativeXComponent* component, void* window)
411 {
412     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnKeyEvent");
413 
414     OH_NativeXComponent_KeyEvent* keyEvent = nullptr;
415     if (OH_NativeXComponent_GetKeyEvent(component, &keyEvent) >= 0) {
416         OH_NativeXComponent_KeyAction action;
417         OH_NativeXComponent_GetKeyEventAction(keyEvent, &action);
418         OH_NativeXComponent_KeyCode code;
419         OH_NativeXComponent_GetKeyEventCode(keyEvent, &code);
420         OH_NativeXComponent_EventSourceType sourceType;
421         OH_NativeXComponent_GetKeyEventSourceType(keyEvent, &sourceType);
422         int64_t deviceId;
423         OH_NativeXComponent_GetKeyEventDeviceId(keyEvent, &deviceId);
424         int64_t timeStamp;
425         OH_NativeXComponent_GetKeyEventTimestamp(keyEvent, &timeStamp);
426         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
427             "KeyEvent Info: action=%{public}d, code=%{public}d, sourceType=%{public}d, deviceId=%{public}ld, "
428             "timeStamp=%{public}ld",
429             action, code, sourceType, deviceId, timeStamp);
430     } else {
431         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "GetKeyEvent error");
432     }
433 }
434 
TestGetXComponentStatus(napi_env env,napi_callback_info info)435 napi_value PluginRender::TestGetXComponentStatus(napi_env env, napi_callback_info info)
436 {
437     napi_value hasDraw;
438     napi_value hasChangeColor;
439 
440     napi_status ret = napi_create_int32(env, hasDraw_, &(hasDraw));
441     if (ret != napi_ok) {
442         OH_LOG_Print(
443             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_create_int32 hasDraw_ error");
444         return nullptr;
445     }
446     ret = napi_create_int32(env, hasChangeColor_, &(hasChangeColor));
447     if (ret != napi_ok) {
448         OH_LOG_Print(
449             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_create_int32 hasChangeColor_ error");
450         return nullptr;
451     }
452 
453     napi_value obj;
454     ret = napi_create_object(env, &obj);
455     if (ret != napi_ok) {
456         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_create_object error");
457         return nullptr;
458     }
459     ret = napi_set_named_property(env, obj, "hasDraw", hasDraw);
460     if (ret != napi_ok) {
461         OH_LOG_Print(
462             LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_set_named_property hasDraw error");
463         return nullptr;
464     }
465     ret = napi_set_named_property(env, obj, "hasChangeColor", hasChangeColor);
466     if (ret != napi_ok) {
467         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus",
468             "napi_set_named_property hasChangeColor error");
469         return nullptr;
470     }
471     return obj;
472 }
473 } // namespace NativeXComponentSample
474