• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "napi/native_api.h"
17 #include <ace/xcomponent/native_interface_xcomponent.h>
18 #include <arkui/native_animate.h>
19 #include <arkui/native_gesture.h>
20 #include <arkui/native_interface.h>
21 #include <arkui/native_key_event.h>
22 #include <arkui/native_node.h>
23 #include <arkui/native_node_napi.h>
24 #include <arkui/native_type.h>
25 #include <cstdint>
26 #include <cstdio>
27 #include <hilog/log.h>
28 #include <iostream>
29 #include <string>
30 
31 #include "manager.h"
32 
33 
34 namespace NativeXComponentSample {
35 Manager Manager::manager_;
36 ArkUI_NodeHandle refresh;
37 
~Manager()38 Manager::~Manager()
39 {
40     OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "~Manager");
41     for (auto iter = nativeXComponentMap_.begin(); iter != nativeXComponentMap_.end(); ++iter) {
42         if (iter->second != nullptr) {
43             iter->second = nullptr;
44         }
45     }
46     nativeXComponentMap_.clear();
47 
48     for (auto iter = containerMap_.begin(); iter != containerMap_.end(); ++iter) {
49         if (iter->second != nullptr) {
50             delete iter->second;
51             iter->second = nullptr;
52         }
53     }
54     containerMap_.clear();
55 }
56 
57 static ArkUI_AnimatorHandle animatorHandle = nullptr;
58 static ArkUI_AnimatorOption *animatorOption = nullptr;
59 static ArkUI_NativeAnimateAPI_1 *animateApi = nullptr;
60 static ArkUI_NativeNodeAPI_1 *nodeAPI = nullptr;
61 static ArkUI_NodeHandle showContent = nullptr;
62 static ArkUI_NodeHandle textInput = nullptr;
63 static ArkUI_NativeGestureAPI_1 *gestureApi = nullptr;
64 
65 struct AA {
66     int32_t a;
67 };
68 
69 static const int NUM_3 = 3;
70 
ConvertTypeToName(ArkUI_GestureRecognizerType type)71 const char *ConvertTypeToName(ArkUI_GestureRecognizerType type)
72 {
73     const char *name = "";
74     switch (type) {
75         case TAP_GESTURE: {
76             name = "TapGesture is preventBegin";
77             break;
78         }
79         case LONG_PRESS_GESTURE: {
80             name = "LongPressGesture is preventBegin";
81             break;
82         }
83         case PAN_GESTURE: {
84             name = "PanGesture is preventBegin";
85             break;
86         }
87         default: {
88             name = "default";
89         }
90     }
91     return name;
92 }
93 
SetTextAttribute(ArkUI_NodeHandle & node,const char * str)94 void SetTextAttribute(ArkUI_NodeHandle& node, const char* str)
95 {
96     if (!nodeAPI) {
97         return;
98     }
99     ArkUI_NumberValue marginValue[] = {5};
100     ArkUI_AttributeItem marginItem = {marginValue, 1};
101     ArkUI_AttributeItem text_valueItem = {.string = str};
102     nodeAPI->setAttribute(node, NODE_TEXT_CONTENT, &text_valueItem);
103     nodeAPI->setAttribute(node, NODE_MARGIN, &marginItem);
104 }
105 
SetColumnAttribute(ArkUI_NodeHandle & node,float width,float height,unsigned int color)106 void SetColumnAttribute(ArkUI_NodeHandle& node, float width, float height, unsigned int color)
107 {
108     if (!nodeAPI) {
109         return;
110     }
111     ArkUI_NumberValue widthValue[] = { width };
112     ArkUI_AttributeItem widthItem = {widthValue, 1};
113     ArkUI_NumberValue heightValue[] = { height };
114     ArkUI_AttributeItem heightItem = {heightValue, 1};
115     ArkUI_NumberValue colorValue[] = {{.u32 = color}};
116     ArkUI_AttributeItem colorItem = {colorValue, 1};
117     nodeAPI->setAttribute(node, NODE_WIDTH, &widthItem);
118     nodeAPI->setAttribute(node, NODE_HEIGHT, &heightItem);
119     nodeAPI->setAttribute(node, NODE_BACKGROUND_COLOR, &colorItem);
120 }
121 
CreateNode(ArkUI_NodeHandle & button,ArkUI_NodeHandle & buttonText,ArkUI_NodeHandle & textShow,ArkUI_NodeHandle & textShow2)122 void Manager::CreateNode(ArkUI_NodeHandle& button, ArkUI_NodeHandle& buttonText, ArkUI_NodeHandle& textShow,
123     ArkUI_NodeHandle& textShow2)
124 {
125     ArkUI_NumberValue marginValue[] = {5};
126     ArkUI_AttributeItem marginItem = {marginValue, 1};
127     ArkUI_AttributeItem textShow_valueItem = {.string = ConvertTypeToName(manager_.list_[manager_.index_])};
128     nodeAPI->setAttribute(textShow, NODE_TEXT_CONTENT, &textShow_valueItem);
129     nodeAPI->setAttribute(textShow, NODE_MARGIN, &marginItem);
130     manager_.textShow_ = textShow;
131 
132     ArkUI_NumberValue button_widthValue[] = {200};
133     ArkUI_AttributeItem button_widthItem = {button_widthValue, 1};
134     ArkUI_NumberValue button_heightValue1[] = {50};
135     ArkUI_AttributeItem button_heightItem = {button_heightValue1, 1};
136     nodeAPI->setAttribute(button, NODE_WIDTH, &button_widthItem);
137     nodeAPI->setAttribute(button, NODE_HEIGHT, &button_heightItem);
138     nodeAPI->setAttribute(button, NODE_MARGIN, &marginItem);
139 
140     ArkUI_AttributeItem buttonText_valueItem = {.string = "Click to change Type"};
141     nodeAPI->setAttribute(buttonText, NODE_TEXT_CONTENT, &buttonText_valueItem);
142     nodeAPI->addChild(button, buttonText);
143 
144     ArkUI_AttributeItem textShow2_valueItem = {.string = ""};
145     nodeAPI->setAttribute(textShow2, NODE_TEXT_CONTENT, &textShow2_valueItem);
146     nodeAPI->setAttribute(textShow2, NODE_MARGIN, &marginItem);
147     manager_.textShow2_ = textShow2;
148 
149     nodeAPI->registerNodeEvent(button, NODE_ON_CLICK, 0, nullptr);
150     nodeAPI->addNodeEventReceiver(button, [](ArkUI_NodeEvent *event) {
151         manager_.index_++;
152         manager_.index_ %= NUM_3;
153         ArkUI_AttributeItem textShow_valueItem = {.string = ConvertTypeToName(manager_.list_[manager_.index_])};
154         nodeAPI->setAttribute(manager_.textShow_, NODE_TEXT_CONTENT, &textShow_valueItem);
155     });
156 }
157 
SetTapGesture(ArkUI_GestureRecognizer * tapGesture,ArkUI_NodeHandle & column)158 void Manager::SetTapGesture(ArkUI_GestureRecognizer *tapGesture, ArkUI_NodeHandle &column)
159 {
160     if (!gestureApi) {
161         return;
162     }
163     gestureApi->setGestureEventTarget(
164         tapGesture, GESTURE_EVENT_ACTION_ACCEPT, column, [](ArkUI_GestureEvent *event, void *extraParams) {
165             ArkUI_AttributeItem valueItem = {.string = "tapGesture is called"};
166             nodeAPI->setAttribute(manager_.textShow2_, NODE_TEXT_CONTENT, &valueItem);
167             OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "touchTestDone", "column1 tapGesture is called");
168         });
169     gestureApi->addGestureToNode(column, tapGesture, ArkUI_GesturePriority::NORMAL,
170                                  ArkUI_GestureMask::NORMAL_GESTURE_MASK);
171 }
172 
SetPanGesture(ArkUI_GestureRecognizer * panGesture,ArkUI_NodeHandle & column)173 void Manager::SetPanGesture(ArkUI_GestureRecognizer *panGesture, ArkUI_NodeHandle &column)
174 {
175     if (!gestureApi) {
176         return;
177     }
178     gestureApi->setGestureEventTarget(
179         panGesture, GESTURE_EVENT_ACTION_ACCEPT, column, [](ArkUI_GestureEvent *event, void *extraParams) {
180             ArkUI_AttributeItem valueItem = {.string = "panGesture is called"};
181             nodeAPI->setAttribute(manager_.textShow2_, NODE_TEXT_CONTENT, &valueItem);
182             OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "touchTestDone", "column2 panGesture is called");
183         });
184     gestureApi->addGestureToNode(column, panGesture, ArkUI_GesturePriority::NORMAL,
185                                  ArkUI_GestureMask::NORMAL_GESTURE_MASK);
186 }
187 
SetLongPressGesture(ArkUI_GestureRecognizer * longPressGesture,ArkUI_NodeHandle & column)188 void Manager::SetLongPressGesture(ArkUI_GestureRecognizer *longPressGesture, ArkUI_NodeHandle &column)
189 {
190     if (!gestureApi) {
191         return;
192     }
193     gestureApi->setGestureEventTarget(
194         longPressGesture, GESTURE_EVENT_ACTION_ACCEPT, column,
195         [](ArkUI_GestureEvent *event, void *extraParams) {
196             ArkUI_AttributeItem valueItem = {.string = "longPressGesture is called"};
197             nodeAPI->setAttribute(manager_.textShow2_, NODE_TEXT_CONTENT, &valueItem);
198             OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "touchTestDone",
199                          "column longPressGesture is called");
200         });
201     gestureApi->addGestureToNode(column, longPressGesture, ArkUI_GesturePriority::NORMAL,
202                                  ArkUI_GestureMask::NORMAL_GESTURE_MASK);
203 }
204 
SetGestureBlocking(ArkUI_NodeHandle & stack,ArkUI_NodeHandle & column1,OH_NativeXComponent * component)205 void Manager::SetGestureBlocking(ArkUI_NodeHandle &stack, ArkUI_NodeHandle &column1, OH_NativeXComponent* component)
206 {
207     auto onTouchTestDoneCallback = [](ArkUI_GestureEvent *event, ArkUI_GestureRecognizerHandleArray recognizers,
208                                       int32_t count, void *userData) {
209         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "touchTestDone", "touchTestDone count is %{public}d",
210                      count);
211         for (int i = 0; i < count; i++) {
212             auto type = gestureApi->getGestureType(recognizers[i]);
213             if (type == manager_.list_[manager_.index_]) {
214                 OH_ArkUI_PreventGestureRecognizerBegin(recognizers[i]);
215             }
216         }
217     };
218     OH_ArkUI_SetTouchTestDoneCallback(column1, nullptr, onTouchTestDoneCallback);
219     nodeAPI->registerNodeEvent(stack, NODE_ON_CLICK, 0, nullptr);
220     nodeAPI->addNodeEventReceiver(stack, [](ArkUI_NodeEvent *event) {
221         ArkUI_AttributeItem valueItem = {.string = "stack click is called"};
222         nodeAPI->setAttribute(manager_.textShow2_, NODE_TEXT_CONTENT, &valueItem);
223         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "touchTestDone", "stack click tap is called");
224     });
225     OH_NativeXComponent_AttachNativeRootNode(component, stack);
226 }
227 
BindingGesture(napi_env env,napi_value arg,OH_NativeXComponent * component)228 void BindingGesture(napi_env env, napi_value arg, OH_NativeXComponent* component)
229 {
230     // 此场景为多层嵌套组件场景,stack绑定了onClick,column1 2 3分别绑定了tap手势
231     static ArkUI_ContextHandle context = nullptr;
232 
233     auto text1 = nodeAPI->createNode(ARKUI_NODE_TEXT);
234     SetTextAttribute(text1, "TapGesture");
235 
236     auto text2 = nodeAPI->createNode(ARKUI_NODE_TEXT);
237     SetTextAttribute(text2, "PanGesture");
238 
239     auto text3 = nodeAPI->createNode(ARKUI_NODE_TEXT);
240     SetTextAttribute(text3, "LongPressGesture");
241 
242     float stackWidth = 400;
243     float stackHeight = 800;
244     unsigned int stackColor = 0xFEF5F5F5;
245     auto stack = nodeAPI->createNode(ARKUI_NODE_COLUMN);
246     SetColumnAttribute(stack, stackWidth, stackHeight, stackColor);
247 
248     // column
249     float column1Width = 250;
250     float column1Height = 500;
251     unsigned int column1Color = 0xFF2FF3FF;
252     auto column1 = nodeAPI->createNode(ARKUI_NODE_COLUMN);
253     SetColumnAttribute(column1, column1Width, column1Height, column1Color);
254     nodeAPI->addChild(stack, column1);
255 
256     float column2Width = 200;
257     float column2Height = 400;
258     unsigned int column2Color = 0xFF20F30F;
259     auto column2 = nodeAPI->createNode(ARKUI_NODE_COLUMN);
260     SetColumnAttribute(column2, column2Width, column2Height, column2Color);
261     nodeAPI->addChild(column1, column2);
262     nodeAPI->addChild(column1, text1);
263 
264     float column3Width = 150;
265     float column3Height = 300;
266     unsigned int column3Color = 0xF2F2F3F0;
267     auto column3 = nodeAPI->createNode(ARKUI_NODE_COLUMN);
268     SetColumnAttribute(column3, column3Width, column3Height, column3Color);
269     nodeAPI->addChild(column2, column3);
270     nodeAPI->addChild(column2, text2);
271     nodeAPI->addChild(column3, text3);
272 
273     auto button = nodeAPI->createNode(ARKUI_NODE_BUTTON);
274     auto buttonText = nodeAPI->createNode(ARKUI_NODE_TEXT);
275     auto textShow = nodeAPI->createNode(ARKUI_NODE_TEXT);
276     auto textShow2 = nodeAPI->createNode(ARKUI_NODE_TEXT);
277     Manager::CreateNode(button, buttonText, textShow, textShow2);
278 
279     nodeAPI->addChild(stack, textShow);
280     nodeAPI->addChild(stack, button);
281     nodeAPI->addChild(stack, textShow2);
282 
283     auto tapGesture = gestureApi->createTapGesture(1, 1);
284     auto panGesture = gestureApi->createPanGesture(1, GESTURE_DIRECTION_ALL, 1);
285     auto longPressGesture = gestureApi->createLongPressGesture(1, false, 500);
286     Manager::SetTapGesture(tapGesture, column1);
287     Manager::SetPanGesture(panGesture, column2);
288     Manager::SetLongPressGesture(longPressGesture, column3);
289 
290     Manager::SetGestureBlocking(stack, column1, component);
291 }
292 
CreateNativeNode(napi_env env,napi_callback_info info)293 napi_value Manager::CreateNativeNode(napi_env env, napi_callback_info info)
294 {
295     if ((env == nullptr) || (info == nullptr)) {
296         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode env or info is null");
297         return nullptr;
298     }
299 
300     size_t argCnt = 2;
301     napi_value args[2] = {nullptr};
302     if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) {
303         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode napi_get_cb_info failed");
304     }
305 
306     if (argCnt < 1) {
307         napi_throw_type_error(env, NULL, "Wrong number of arguments");
308         return nullptr;
309     }
310 
311     napi_valuetype valuetype;
312     if (napi_typeof(env, args[0], &valuetype) != napi_ok) {
313         napi_throw_type_error(env, NULL, "napi_typeof failed");
314         return nullptr;
315     }
316 
317     if (valuetype != napi_string) {
318         napi_throw_type_error(env, NULL, "Wrong type of arguments");
319         return nullptr;
320     }
321 
322     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
323     constexpr uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
324     size_t length;
325     if (napi_get_value_string_utf8(env, args[0], idStr, idSize, &length) != napi_ok) {
326         napi_throw_type_error(env, NULL, "napi_get_value_int64 failed");
327         return nullptr;
328     }
329 
330     auto manager = Manager::GetInstance();
331     if (manager == nullptr) {
332         return nullptr;
333     }
334 
335     OH_NativeXComponent *component = manager->GetNativeXComponent(idStr);
336     if (component == nullptr) {
337         return nullptr;
338     }
339     OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nodeAPI);
340     OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_ANIMATE, ArkUI_NativeAnimateAPI_1, animateApi);
341     OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_GESTURE, ArkUI_NativeGestureAPI_1, gestureApi);
342 
343     if (nodeAPI != nullptr) {
344         if (nodeAPI->createNode != nullptr && nodeAPI->addChild != nullptr) {
345             BindingGesture(env, args[1], component);
346         }
347     }
348     return nullptr;
349 }
350 
UpdateNativeNode(napi_env env,napi_callback_info info)351 napi_value Manager::UpdateNativeNode(napi_env env, napi_callback_info info)
352 {
353     if ((env == nullptr) || (info == nullptr)) {
354         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "UpdateNativeNode env or info is null");
355         return nullptr;
356     }
357 
358     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "UpdateNativeNode  1111");
359 
360     size_t argCnt = 1;
361     napi_value args[1] = {nullptr};
362     if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) {
363         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "UpdateNativeNode napi_get_cb_info failed");
364     }
365 
366     if (argCnt != 1) {
367         napi_throw_type_error(env, NULL, "Wrong number of arguments");
368         return nullptr;
369     }
370 
371     napi_valuetype valuetype;
372     if (napi_typeof(env, args[0], &valuetype) != napi_ok) {
373         napi_throw_type_error(env, NULL, "napi_typeof failed");
374         return nullptr;
375     }
376 
377     if (valuetype != napi_string) {
378         napi_throw_type_error(env, NULL, "Wrong type of arguments");
379         return nullptr;
380     }
381 
382     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
383     constexpr uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
384     size_t length;
385     if (napi_get_value_string_utf8(env, args[0], idStr, idSize, &length) != napi_ok) {
386         napi_throw_type_error(env, NULL, "napi_get_value_int64 failed");
387         return nullptr;
388     }
389     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "CreateNativeNode %{public}s", idStr);
390 
391     auto manager = Manager::GetInstance();
392     if (manager == nullptr) {
393         return nullptr;
394     }
395 
396     OH_NativeXComponent *component = manager->GetNativeXComponent(idStr);
397     if (component == nullptr) {
398         return nullptr;
399     }
400 
401     if ((env == nullptr) || (info == nullptr || component == nullptr)) {
402         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "GetContext env or info is null");
403         return nullptr;
404     }
405     return nullptr;
406 }
407 
GetContext(napi_env env,napi_callback_info info)408 napi_value Manager::GetContext(napi_env env, napi_callback_info info)
409 {
410     if ((env == nullptr) || (info == nullptr)) {
411         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "GetContext env or info is null");
412         return nullptr;
413     }
414 
415     size_t argCnt = 1;
416     napi_value args[1] = {nullptr};
417     if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) {
418         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "GetContext napi_get_cb_info failed");
419     }
420 
421     if (argCnt != 1) {
422         napi_throw_type_error(env, NULL, "Wrong number of arguments");
423         return nullptr;
424     }
425 
426     napi_valuetype valuetype;
427     if (napi_typeof(env, args[0], &valuetype) != napi_ok) {
428         napi_throw_type_error(env, NULL, "napi_typeof failed");
429         return nullptr;
430     }
431 
432     if (valuetype != napi_number) {
433         napi_throw_type_error(env, NULL, "Wrong type of arguments");
434         return nullptr;
435     }
436 
437     int64_t value;
438     if (napi_get_value_int64(env, args[0], &value) != napi_ok) {
439         napi_throw_type_error(env, NULL, "napi_get_value_int64 failed");
440         return nullptr;
441     }
442 
443     napi_value exports;
444     if (napi_create_object(env, &exports) != napi_ok) {
445         napi_throw_type_error(env, NULL, "napi_create_object failed");
446         return nullptr;
447     }
448 
449     return exports;
450 }
451 
Export(napi_env env,napi_value exports)452 void Manager::Export(napi_env env, napi_value exports)
453 {
454     if ((env == nullptr) || (exports == nullptr)) {
455         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "Export: env or exports is null");
456         return;
457     }
458 
459     napi_value exportInstance = nullptr;
460     if (napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
461         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "Export: napi_get_named_property fail");
462         return;
463     }
464 
465     OH_NativeXComponent *nativeXComponent = nullptr;
466     if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
467         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "Export: napi_unwrap fail");
468         return;
469     }
470 
471     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
472     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
473     if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
474         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager",
475                      "Export: OH_NativeXComponent_GetXComponentId fail");
476         return;
477     }
478 
479     std::string id(idStr);
480     auto manager = Manager::GetInstance();
481     if ((manager != nullptr) && (nativeXComponent != nullptr)) {
482         manager->SetNativeXComponent(id, nativeXComponent);
483     }
484 }
485 
SetNativeXComponent(std::string & id,OH_NativeXComponent * nativeXComponent)486 void Manager::SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent)
487 {
488     if (nativeXComponent == nullptr) {
489         return;
490     }
491 
492     if (nativeXComponentMap_.find(id) == nativeXComponentMap_.end()) {
493         nativeXComponentMap_[id] = nativeXComponent;
494         return;
495     }
496 
497     if (nativeXComponentMap_[id] != nativeXComponent) {
498         OH_NativeXComponent *tmp = nativeXComponentMap_[id];
499         tmp = nullptr;
500         nativeXComponentMap_[id] = nativeXComponent;
501     }
502 }
503 
GetNativeXComponent(const std::string & id)504 OH_NativeXComponent *Manager::GetNativeXComponent(const std::string &id) { return nativeXComponentMap_[id]; }
505 
GetContainer(std::string & id)506 Container *Manager::GetContainer(std::string &id)
507 {
508     if (containerMap_.find(id) == containerMap_.end()) {
509         Container *instance = Container::GetInstance(id);
510         containerMap_[id] = instance;
511         return instance;
512     }
513 
514     return containerMap_[id];
515 }
516 } // namespace NativeXComponentSample