1 /*
2 * Copyright (c) 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 "arkweb_interface.h"
17
18 #include "arkweb_type.h"
19 #include "nweb_helper.h"
20 #include "nweb_log.h"
21 #include "arkweb_error_code.h"
22
23 namespace {
24 #define ARKWEB_NATIVE_FOR_EACH_COMPONENT_API_FN(DO) \
25 DO(onControllerAttached, OH_ArkWeb_OnControllerAttached); \
26 DO(onPageBegin, OH_ArkWeb_OnPageBegin); \
27 DO(onPageEnd, OH_ArkWeb_OnPageEnd); \
28 DO(onDestroy, OH_ArkWeb_OnDestroy)
29
30 #define ARKWEB_NATIVE_FOR_EACH_COMPONENT_GLOBAL_API_FN(DO) \
31 DO(onScroll, OH_ArkWeb_OnScroll)
32
33 #define ARKWEB_NATIVE_FOR_EACH_CONTROLLER_API_FN(DO) \
34 DO(runJavaScript, OH_ArkWeb_RunJavaScript); \
35 DO(registerJavaScriptProxy, OH_ArkWeb_RegisterJavaScriptProxy); \
36 DO(deleteJavaScriptRegister, OH_ArkWeb_DeleteJavaScriptProxy); \
37 DO(refresh, OH_ArkWeb_Refresh); \
38 DO(registerAsyncJavaScriptProxy, OH_ArkWeb_RegisterAsyncJavaScriptProxy); \
39 DO(createWebMessagePorts, OH_ArkWeb_CreateWebMessagePorts); \
40 DO(destroyWebMessagePorts, OH_ArkWeb_DestroyWebMessagePorts); \
41 DO(postWebMessage, OH_ArkWeb_PostWebMessage); \
42 DO(getLastJavascriptProxyCallingFrameUrl, OH_ArkWeb_GetLastJavascriptProxyCallingFrameUrl)
43
44 #define ARKWEB_NATIVE_FOR_EACH_CONTROLLER_API_FN_2(DO) \
45 DO(registerJavaScriptProxyEx, \
46 OH_ArkWeb_RegisterJavaScriptProxyEx); \
47 DO(registerAsyncJavaScriptProxyEx, \
48 OH_ArkWeb_RegisterAsyncJavaScriptProxyEx)
49
50 #define ARKWEB_NATIVE_FOR_EACH_WEBMESSAGEPORT_API_FN(DO) \
51 DO(postMessage, OH_WebMessage_PostMessage); \
52 DO(close, OH_WebMessage_Close); \
53 DO(setMessageEventHandler, OH_WebMessage_SetMessageEventHandler)
54
55 #define ARKWEB_NATIVE_FOR_EACH_WEBMESSAGE_API_FN(DO) \
56 DO(createWebMessage, OH_WebMessage_CreateWebMessage); \
57 DO(destroyWebMessage, OH_WebMessage_DestroyWebMessage); \
58 DO(setType, OH_WebMessage_SetType); \
59 DO(getType, OH_WebMessage_GetType); \
60 DO(setData, OH_WebMessage_SetData); \
61 DO(getData, OH_WebMessage_GetData)
62
63 #define ARKWEB_NATIVE_FOR_EACH_WEBCOOKIEMANAGER_API_FN(DO) \
64 DO(fetchCookieSync, OH_CookieManager_FetchCookieSync); \
65 DO(configCookieSync, OH_CookieManager_ConfigCookieSync); \
66 DO(existCookies, OH_CookieManager_ExistCookies); \
67 DO(clearAllCookiesSync, OH_CookieManager_ClearAllCookiesSync); \
68 DO(clearSessionCookiesSync, OH_CookieManager_ClearSessionCookiesSync)
69
70 #define ARKWEB_NATIVE_FOR_EACH_JAVASCRIPTVALUE_API_FN(DO) \
71 DO(createJavaScriptValue, OH_JavaScript_CreateJavaScriptValue)
72
73 ArkWeb_ComponentAPI* g_ComponentImpl = nullptr;
74 ArkWeb_ControllerAPI* g_ControllerImpl = nullptr;
75 ArkWeb_WebMessagePortAPI* g_WebMessagePortImpl = nullptr;
76 ArkWeb_WebMessageAPI* g_WebMessageImpl = nullptr;
77 ArkWeb_CookieManagerAPI* g_CookieManagerImpl = nullptr;
78 ArkWeb_JavaScriptValueAPI* g_JavaScriptValueImpl = nullptr;
79
80 typedef struct {
81 /** The ArkWeb_ComponentGlobalAPI struct size. */
82 size_t size;
83 /** Register the onScroll callback. */
84 bool (*onScroll)(const char* webTag, ArkWeb_OnScrollCallback callback, void* userData);
85 } ArkWeb_ComponentGlobalAPI;
86
87 ArkWeb_ComponentGlobalAPI* g_ComponentGlobalImpl = nullptr;
88
89 } // namespace
90
91 template<typename Fn>
LoadFunction(const char * functionName,Fn * fnOut)92 static void LoadFunction(const char* functionName, Fn* fnOut)
93 {
94 void* fn = OHOS::NWeb::NWebHelper::Instance().LoadFuncSymbol(functionName);
95 if (!fn) {
96 WVLOG_E("%{public}s not found.", functionName);
97 return;
98 }
99 *fnOut = reinterpret_cast<Fn>(fn);
100 }
101
LoadComponentAPI()102 static bool LoadComponentAPI()
103 {
104 if (g_ComponentImpl) {
105 WVLOG_I("NativeArkWeb component api already loaded");
106 return true;
107 }
108 g_ComponentImpl = new (std::nothrow) ArkWeb_ComponentAPI();
109 if (!g_ComponentImpl) {
110 WVLOG_E("NativeArkWeb component api is nullptr");
111 return false;
112 }
113 g_ComponentImpl->size = sizeof(ArkWeb_ComponentAPI);
114
115 if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
116 WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
117 return false;
118 }
119 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_ComponentImpl->fn))
120 ARKWEB_NATIVE_FOR_EACH_COMPONENT_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
121 #undef ARKWEB_NATIVE_LOAD_FN_PTR
122
123 return true;
124 }
125
LoadComponentGlobalAPI()126 static bool LoadComponentGlobalAPI()
127 {
128 if (g_ComponentGlobalImpl) {
129 WVLOG_I("NativeArkWeb component api already loaded");
130 return true;
131 }
132
133 g_ComponentGlobalImpl = new (std::nothrow) ArkWeb_ComponentGlobalAPI();
134 if (!g_ComponentGlobalImpl) {
135 WVLOG_E("NativeArkWeb component global api is nullptr");
136 return false;
137 }
138 g_ComponentGlobalImpl->size = sizeof(ArkWeb_ComponentGlobalAPI);
139
140 if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
141 WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
142 return false;
143 }
144
145 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_ComponentGlobalImpl->fn))
146 ARKWEB_NATIVE_FOR_EACH_COMPONENT_GLOBAL_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
147 #undef ARKWEB_NATIVE_LOAD_FN_PTR
148
149 return true;
150 }
151
LoadControllerAPI()152 static bool LoadControllerAPI()
153 {
154 if (g_ControllerImpl) {
155 WVLOG_I("NativeArkWeb controller api already loaded");
156 return true;
157 }
158 g_ControllerImpl = new (std::nothrow) ArkWeb_ControllerAPI();
159 if (!g_ControllerImpl) {
160 WVLOG_E("NativeArkWeb controller api is nullptr");
161 return false;
162 }
163 g_ControllerImpl->size = sizeof(ArkWeb_ControllerAPI);
164
165 if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
166 WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
167 return false;
168 }
169 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_ControllerImpl->fn))
170 ARKWEB_NATIVE_FOR_EACH_CONTROLLER_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
171 #undef ARKWEB_NATIVE_LOAD_FN_PTR
172
173 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_ControllerImpl->fn))
174 ARKWEB_NATIVE_FOR_EACH_CONTROLLER_API_FN_2(ARKWEB_NATIVE_LOAD_FN_PTR);
175 #undef ARKWEB_NATIVE_LOAD_FN_PTR
176
177 return true;
178 }
179
LoadWebMessagePortAPI()180 static bool LoadWebMessagePortAPI()
181 {
182 if (g_WebMessagePortImpl) {
183 WVLOG_I("NativeArkWeb web message port api already loaded");
184 return true;
185 }
186 g_WebMessagePortImpl = new (std::nothrow) ArkWeb_WebMessagePortAPI();
187 if (!g_WebMessagePortImpl) {
188 WVLOG_E("NativeArkWeb web message port api is nullptr");
189 return false;
190 }
191 g_WebMessagePortImpl->size = sizeof(ArkWeb_WebMessagePortAPI);
192
193 if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
194 WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
195 return false;
196 }
197 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_WebMessagePortImpl->fn))
198 ARKWEB_NATIVE_FOR_EACH_WEBMESSAGEPORT_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
199 #undef ARKWEB_NATIVE_LOAD_FN_PTR
200
201 return true;
202 }
203
LoadWebMessageAPI()204 static bool LoadWebMessageAPI()
205 {
206 if (g_WebMessageImpl) {
207 WVLOG_I("NativeArkWeb web message api already loaded");
208 return true;
209 }
210 g_WebMessageImpl = new (std::nothrow) ArkWeb_WebMessageAPI();
211 if (!g_WebMessageImpl) {
212 WVLOG_E("NativeArkWeb web message api is nullptr");
213 return false;
214 }
215 g_WebMessageImpl->size = sizeof(ArkWeb_WebMessageAPI);
216
217 if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
218 WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
219 return false;
220 }
221 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_WebMessageImpl->fn))
222 ARKWEB_NATIVE_FOR_EACH_WEBMESSAGE_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
223 #undef ARKWEB_NATIVE_LOAD_FN_PTR
224
225 return true;
226 }
227
LoadCookieManagerAPI()228 static bool LoadCookieManagerAPI()
229 {
230 if (g_CookieManagerImpl) {
231 WVLOG_I("NativeArkWeb cookie manager api already loaded");
232 return true;
233 }
234
235 g_CookieManagerImpl = new ArkWeb_CookieManagerAPI();
236 if (!g_CookieManagerImpl) {
237 WVLOG_E("NativeArkWeb cookie manager api is nullptr");
238 return false;
239 }
240 g_CookieManagerImpl->size = sizeof(ArkWeb_CookieManagerAPI);
241
242 if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, true)) {
243 WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
244 return false;
245 }
246 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_CookieManagerImpl->fn))
247 ARKWEB_NATIVE_FOR_EACH_WEBCOOKIEMANAGER_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
248 #undef ARKWEB_NATIVE_LOAD_FN_PTR
249
250 return true;
251 }
252
LoadJavaScriptValueAPI()253 static bool LoadJavaScriptValueAPI()
254 {
255 if (g_JavaScriptValueImpl) {
256 WVLOG_I("NativeArkWeb javaScript value api already loaded");
257 return true;
258 }
259
260 g_JavaScriptValueImpl = new (std::nothrow) ArkWeb_JavaScriptValueAPI();
261 if (!g_JavaScriptValueImpl) {
262 WVLOG_E("NativeArkWeb javaScript value api is nullptr");
263 return false;
264 }
265 g_JavaScriptValueImpl->size = sizeof(ArkWeb_JavaScriptValueAPI);
266
267 if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
268 WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
269 return false;
270 }
271 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_JavaScriptValueImpl->fn))
272 ARKWEB_NATIVE_FOR_EACH_JAVASCRIPTVALUE_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
273 #undef ARKWEB_NATIVE_LOAD_FN_PTR
274
275 return true;
276 }
277
OH_ArkWeb_GetNativeAPI(ArkWeb_NativeAPIVariantKind type)278 ArkWeb_AnyNativeAPI* OH_ArkWeb_GetNativeAPI(ArkWeb_NativeAPIVariantKind type)
279 {
280 switch (type) {
281 case ARKWEB_NATIVE_COMPONENT: {
282 if (!LoadComponentAPI()) {
283 return nullptr;
284 }
285 return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_ComponentImpl);
286 }
287 case ARKWEB_NATIVE_CONTROLLER: {
288 if (!LoadControllerAPI()) {
289 return nullptr;
290 }
291 return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_ControllerImpl);
292 }
293 case ARKWEB_NATIVE_WEB_MESSAGE_PORT: {
294 if (!LoadWebMessagePortAPI()) {
295 return nullptr;
296 }
297 return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_WebMessagePortImpl);
298 }
299 case ARKWEB_NATIVE_WEB_MESSAGE: {
300 if (!LoadWebMessageAPI()) {
301 return nullptr;
302 }
303 return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_WebMessageImpl);
304 }
305 case ARKWEB_NATIVE_COOKIE_MANAGER: {
306 if (!LoadCookieManagerAPI()) {
307 return nullptr;
308 }
309 return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_CookieManagerImpl);
310 }
311 case ARKWEB_NATIVE_JAVASCRIPT_VALUE: {
312 if (!LoadJavaScriptValueAPI()) {
313 return nullptr;
314 }
315 return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_JavaScriptValueImpl);
316 }
317 default: {
318 WVLOG_E("fail to get %{public}d arkweb api family", type);
319 return nullptr;
320 }
321 }
322 }
323
OH_ArkWeb_RegisterScrollCallback(const char * webTag,ArkWeb_OnScrollCallback callback,void * userData)324 bool OH_ArkWeb_RegisterScrollCallback(
325 const char* webTag, ArkWeb_OnScrollCallback callback, void* userData)
326 {
327 if (!LoadComponentGlobalAPI()) {
328 return false;
329 }
330 if (!g_ComponentGlobalImpl->onScroll) {
331 return false;
332 }
333 return g_ComponentGlobalImpl->onScroll(webTag, callback, userData);
334 }
335
OH_ArkWeb_DestroyGlobalPointersForTest(void)336 [[maybe_unused]] void OH_ArkWeb_DestroyGlobalPointersForTest(void)
337 {
338 if (g_ComponentImpl != nullptr) {
339 delete g_ComponentImpl;
340 g_ComponentImpl = nullptr;
341 }
342
343 if (g_ControllerImpl != nullptr) {
344 delete g_ControllerImpl;
345 g_ControllerImpl = nullptr;
346 }
347
348 if (g_WebMessagePortImpl != nullptr) {
349 delete g_WebMessagePortImpl;
350 g_WebMessagePortImpl = nullptr;
351 }
352
353 if (g_WebMessageImpl != nullptr) {
354 delete g_WebMessageImpl;
355 g_WebMessageImpl = nullptr;
356 }
357
358 if (g_CookieManagerImpl != nullptr) {
359 delete g_CookieManagerImpl;
360 g_CookieManagerImpl = nullptr;
361 }
362
363 if (g_JavaScriptValueImpl != nullptr) {
364 delete g_JavaScriptValueImpl;
365 g_JavaScriptValueImpl = nullptr;
366 }
367
368 if (g_ComponentGlobalImpl != nullptr) {
369 delete g_ComponentGlobalImpl;
370 g_ComponentGlobalImpl = nullptr;
371 }
372 }
373