• 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 #include "../manager/plugin_manager.h"
16 #include "common/common.h"
17 #include "xcomponent_lifecycle_test.h"
18 #include "render/EGLRender.h"
19 #include <arkui/native_node.h>
20 #include <arkui/native_node_napi.h>
21 #include "napi/native_api.h"
22 #include <arkui/native_interface.h>
23 #include <hilog/log.h>
24 #include <ace/xcomponent/native_interface_xcomponent.h>
25 #include <unordered_map>
26 #include <string>
27 
28 namespace ArkUICapiTest {
29 static std::unordered_map<OH_ArkUI_SurfaceHolder*, EGLRender*> Renders;
30 static ArkUI_NativeNodeAPI_1* nodeAPI;
31 ArkUI_NodeHandle xcomponent_ = nullptr;
32 ArkUI_NodeContentHandle nodeContentHandle_ = nullptr;
33 OH_ArkUI_SurfaceHolder* holder_ = nullptr;
34 OH_ArkUI_SurfaceCallback* callback_;
35 OH_ArkUI_SurfaceCallback* tempCallback_;
36 uint64_t width_ = 0;
37 uint64_t height_ = 0;
38 
value2String(napi_env env,napi_value value)39 static std::string value2String(napi_env env, napi_value value){
40     size_t stringSize = 0;
41     napi_get_value_string_utf8(env, value, nullptr, 0, &stringSize);
42     std::string valueString;
43     valueString.resize(stringSize);
44     napi_get_value_string_utf8(env, value, &valueString[0], stringSize+1, &stringSize);
45     return valueString;
46 }
47 
onEvent(ArkUI_NodeEvent * event)48 void onEvent(ArkUI_NodeEvent* event) {
49     auto eventType = OH_ArkUI_NodeEvent_GetEventType(event);
50     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "wds on event");
51     if (eventType == NODE_TOUCH_EVENT) {
52         auto *uiInputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event);
53         float x = OH_ArkUI_PointerEvent_GetX(uiInputEvent);
54         float y = OH_ArkUI_PointerEvent_GetY(uiInputEvent);
55         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "wds on touch");
56     }
57 };
58 
OnSurfaceCreatedCB(OH_ArkUI_SurfaceHolder * holder)59 void OnSurfaceCreatedCB(OH_ArkUI_SurfaceHolder* holder)
60 {
61     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_OnSurfaceCreatedCB holder %{public}p", holder);
62     void* window = (void*)OH_ArkUI_XComponent_GetNativeWindow(holder_);
63     auto render = Renders[holder_];
64     if (window && render) {
65         render->SetUpEGLContext(window, 0);
66         int32_t width;
67         int32_t height;
68         auto *nativeWindow = reinterpret_cast<OHNativeWindow *>(window);
69         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, GET_BUFFER_GEOMETRY,&width, &height);
70         render->SetEGLWindowSize(width, height);
71     }
72 }
73 
OnSurfaceChangedCB(OH_ArkUI_SurfaceHolder * holder,uint64_t width,uint64_t height)74 void OnSurfaceChangedCB(OH_ArkUI_SurfaceHolder* holder, uint64_t width, uint64_t height)
75 {
76     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_OnSurfaceChangedCB width %{public}d height %{public}d", width, height);
77     width_ = width;
78     height_ = height;
79     auto render = Renders[holder_];
80     if (render != nullptr) {
81         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_OnSurfaceChangedCB 1");
82         render->SetEGLWindowSize(width, height);
83         render->DrawStar();
84     }
85 }
86 
OnSurfaceDestroyedCB(OH_ArkUI_SurfaceHolder * holder)87 void OnSurfaceDestroyedCB(OH_ArkUI_SurfaceHolder* holder)
88 {
89     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_OnSurfaceDestroyedCB");
90 }
91 
removeSurfaceCallback(napi_env env,napi_callback_info info)92 napi_value XComponentLifeCycleTest::removeSurfaceCallback(napi_env env, napi_callback_info info) {
93     auto status = OH_ArkUI_SurfaceHolder_RemoveSurfaceCallback(holder_, callback_);
94     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_removeSurfaceCallback status %{public}d", status);
95 
96     napi_value statusCode;
97     napi_status ret = napi_create_int32(env, status, &(statusCode));
98 
99     return statusCode;
100 }
101 
setUserData(napi_env env,napi_callback_info info)102 napi_value XComponentLifeCycleTest::setUserData(napi_env env, napi_callback_info info) {
103     auto status = OH_ArkUI_SurfaceHolder_SetUserData(holder_, new std::string("Hello World"));
104     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_setUserData status %{public}d data %{public}s", status, "Hello World");
105     return nullptr;
106 }
107 
getUserData(napi_env env,napi_callback_info info)108 napi_value XComponentLifeCycleTest::getUserData(napi_env env, napi_callback_info info) {
109     napi_value napiStr;
110     std::string* data = (std::string*)OH_ArkUI_SurfaceHolder_GetUserData(holder_);
111     if (data) {
112         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_getUserData data %{public}s", data->c_str());
113         napi_create_string_latin1(env, data->c_str(), data->size(), &napiStr);
114         return napiStr;
115     }
116     return nullptr;
117 }
118 
CreateNodeHandlePre()119 ArkUI_NodeHandle CreateNodeHandlePre() {
120     ArkUI_NodeHandle handle = nodeAPI->createNode(ARKUI_NODE_XCOMPONENT_TEXTURE);
121     //获取SurfaceHolder
122     holder_ = OH_ArkUI_SurfaceHolder_Create(handle);
123     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_CreateNodeHandlePre create surface holder %{public}p", holder_);
124     callback_ = OH_ArkUI_SurfaceCallback_Create();
125 
126     OH_ArkUI_SurfaceCallback_SetSurfaceCreatedEvent(callback_, OnSurfaceCreatedCB);
127     OH_ArkUI_SurfaceCallback_SetSurfaceChangedEvent(callback_, OnSurfaceChangedCB);
128     OH_ArkUI_SurfaceCallback_SetSurfaceDestroyedEvent(callback_, OnSurfaceDestroyedCB);
129 
130     //往SurfaceHolder里添加callback
131     if (holder_) {
132         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_preCreate get holder");
133         OH_ArkUI_SurfaceHolder_AddSurfaceCallback(holder_, callback_);
134         if (!Renders.count(holder_)) {
135             Renders[holder_] = new EGLRender();
136             auto render = Renders[holder_];
137         }
138     }
139     // 设置AutoInitial为false
140     if (OH_ArkUI_XComponent_SetAutoInitialize(handle, false) != ARKUI_ERROR_CODE_NO_ERROR) {
141         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_SetAutoInitialize failed.");
142     }
143 
144     // 获取isINitialized的值
145     bool isInitialized = false;
146     if (OH_ArkUI_XComponent_IsInitialized(handle, &isInitialized) != ARKUI_ERROR_CODE_NO_ERROR) {
147         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "GetIsInitialized failed.");
148     } else {
149         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "GetIsInitialized = %{public}d", isInitialized);
150     }
151 
152      //添加事件监听,返回成功码 0
153     auto ret = nodeAPI->addNodeEventReceiver(handle, onEvent);
154     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_addNodeEventReceiver ret=%{public}d", ret);
155 
156     // 用C接口注册touch事件,返回成功码 0
157     ret = nodeAPI->registerNodeEvent(handle, NODE_TOUCH_EVENT, 0, nullptr);
158     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_registerNodeEvent ret=%{public}d", ret);
159     ArkUI_NumberValue value[] = {{.i32 = static_cast<int>(true)}};
160     ArkUI_AttributeItem item = {value, 1};
161     auto ec = nodeAPI->setAttribute(handle, NODE_XCOMPONENT_ENABLE_ANALYZER, &item);
162     // 返回错误码
163     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_set attribute ret=%{public}d", ec);
164     xcomponent_ = handle;
165     return handle;
166 }
167 
CreateNodeHandle(const std::string & tag)168 ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
169     ArkUI_NodeHandle handle = nodeAPI->createNode(ARKUI_NODE_XCOMPONENT);
170 
171     //获取SurfaceHolder
172     holder_ = OH_ArkUI_SurfaceHolder_Create(handle);
173     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_CreateNodeHandle create surface holder %{public}p", holder_);
174 
175     OHNativeWindow* window = OH_ArkUI_XComponent_GetNativeWindow(holder_);
176     if (window) {
177         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_GetNativeWindow success");
178     }
179 
180     callback_ = OH_ArkUI_SurfaceCallback_Create();
181     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_CreateNodeHandle callback_ %{public}p", callback_);
182 
183     OH_ArkUI_SurfaceCallback_SetSurfaceCreatedEvent(callback_, OnSurfaceCreatedCB);
184     OH_ArkUI_SurfaceCallback_SetSurfaceChangedEvent(callback_, OnSurfaceChangedCB);
185     OH_ArkUI_SurfaceCallback_SetSurfaceDestroyedEvent(callback_, OnSurfaceDestroyedCB);
186     //往SurfaceHolder里添加callback
187     if (holder_) {
188         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_CreateNodeHandle get holder");
189         OH_ArkUI_SurfaceHolder_AddSurfaceCallback(holder_, callback_);
190         if (!Renders.count(holder_)) {
191             Renders[holder_] = new EGLRender();
192             auto render = Renders[holder_];
193         }
194     }
195     //设置AutoInitial为false
196     if (OH_ArkUI_XComponent_SetAutoInitialize(handle, true) != ARKUI_ERROR_CODE_NO_ERROR) {
197         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_SetAutoInitialize failed.");
198     }
199 //    //获取isINitialized的值
200     bool isInitialized = false;
201     if (OH_ArkUI_XComponent_IsInitialized(handle, &isInitialized) != ARKUI_ERROR_CODE_NO_ERROR) {
202         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "GetIsInitialized failed.");
203     } else {
204         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "GetIsInitialized = %{public}d", isInitialized);
205     }
206 
207     ArkUI_NumberValue value[] = {{.i32 = static_cast<int>(true)}};
208     ArkUI_AttributeItem item = {value, 1};
209     auto ec = nodeAPI->setAttribute(handle, NODE_XCOMPONENT_ENABLE_ANALYZER, &item);
210     ArkUI_NumberValue value1[] = {{.u32 = 0x12345678}};
211     ArkUI_AttributeItem item1 = {value1, 1};
212     nodeAPI->setAttribute(handle, NODE_BACKGROUND_COLOR, &item1);
213     // 返回错误码
214     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_set attribute ret=%{public}d", ec);
215     xcomponent_ = handle;
216     return handle;
217 }
218 
createNativeNode(napi_env env,napi_callback_info info)219 napi_value XComponentLifeCycleTest::createNativeNode(napi_env env, napi_callback_info info)
220 {
221     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "createNativeNode", "createNativeNode");
222     size_t argCnt = 3;
223     napi_value args[3] = { nullptr, nullptr, nullptr};
224     napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr);
225 
226     if (argCnt != 3) {
227         napi_throw_type_error(env, NULL, "Wrong number of arguments");
228         return nullptr;
229     }
230 
231     nodeContentHandle_ = nullptr;
232     OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &nodeContentHandle_);
233     nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1*> (
234         OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")
235     );
236 
237     std::string tag = value2String(env, args[1]);
238     if (tag == "preCreate") {
239         xcomponent_ = CreateNodeHandlePre();
240     } else {
241         xcomponent_ = CreateNodeHandle("cyc");
242     }
243     return nullptr;
244 }
245 
initialize(napi_env env,napi_callback_info info)246 napi_value XComponentLifeCycleTest::initialize(napi_env env, napi_callback_info info) {
247     auto status = OH_ArkUI_XComponent_Initialize(xcomponent_);
248     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_Initialize. Code: %{public}d", status);
249 
250     napi_value statusCode;
251     napi_status ret = napi_create_int32(env, status, &(statusCode));
252 
253     return statusCode;
254 }
255 
finalize(napi_env env,napi_callback_info info)256 napi_value XComponentLifeCycleTest::finalize(napi_env env, napi_callback_info info) {
257     auto status = OH_ArkUI_XComponent_Finalize(xcomponent_);
258     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_Finalize. Code: %{public}d", status);
259 
260     napi_value statusCode;
261     napi_status ret = napi_create_int32(env, status, &(statusCode));
262 
263     return statusCode;
264 }
265 
attachToMainTree(napi_env env,napi_callback_info info)266 napi_value XComponentLifeCycleTest::attachToMainTree(napi_env env, napi_callback_info info) {
267     OH_ArkUI_NodeContent_AddNode(nodeContentHandle_, xcomponent_);
268     return nullptr;
269 }
270 
detachFromMainTree(napi_env env,napi_callback_info info)271 napi_value XComponentLifeCycleTest::detachFromMainTree(napi_env env, napi_callback_info info) {
272     OH_ArkUI_NodeContent_RemoveNode(nodeContentHandle_, xcomponent_);
273     return nullptr;
274 }
275 
dispose(napi_env env,napi_callback_info info)276 napi_value XComponentLifeCycleTest::dispose(napi_env env, napi_callback_info info) {
277     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_CNode dispose");
278     OH_ArkUI_NodeContent_RemoveNode(nodeContentHandle_, xcomponent_);
279     nodeAPI->disposeNode(xcomponent_);
280     xcomponent_ = nullptr;
281     if (holder_) {
282         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "jyy CYC_SurfaceHolder dispose");
283         OH_ArkUI_SurfaceHolder_Dispose(holder_);
284     }
285     OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onbind", "CYC_dispose callback_ %{public}p", callback_);
286     if (callback_) {
287         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_SurfaceCallback dispose 2");
288         OH_ArkUI_SurfaceCallback_Dispose(callback_);
289     }
290     if (tempCallback_) {
291         OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "XComponent_Native", "CYC_SurfaceCallback dispose");
292         OH_ArkUI_SurfaceCallback_Dispose(tempCallback_);
293     }
294     return nullptr;
295 }
296 
297 } // ArkUICapiTest
298