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_CONTROLLER_API_FN(DO)                          \
31     DO(runJavaScript, OH_ArkWeb_RunJavaScript);                               \
32     DO(registerJavaScriptProxy, OH_ArkWeb_RegisterJavaScriptProxy);           \
33     DO(deleteJavaScriptRegister, OH_ArkWeb_DeleteJavaScriptProxy);            \
34     DO(refresh, OH_ArkWeb_Refresh);                                           \
35     DO(registerAsyncJavaScriptProxy, OH_ArkWeb_RegisterAsyncJavaScriptProxy); \
36     DO(createWebMessagePorts, OH_ArkWeb_CreateWebMessagePorts);               \
37     DO(destroyWebMessagePorts, OH_ArkWeb_DestroyWebMessagePorts);             \
38     DO(postWebMessage, OH_ArkWeb_PostWebMessage)
39 
40 #define ARKWEB_NATIVE_FOR_EACH_WEBMESSAGEPORT_API_FN(DO) \
41     DO(postMessage, OH_WebMessage_PostMessage);          \
42     DO(close, OH_WebMessage_Close);                      \
43     DO(setMessageEventHandler, OH_WebMessage_SetMessageEventHandler)
44 
45 #define ARKWEB_NATIVE_FOR_EACH_WEBMESSAGE_API_FN(DO)        \
46     DO(createWebMessage, OH_WebMessage_CreateWebMessage);   \
47     DO(destroyWebMessage, OH_WebMessage_DestroyWebMessage); \
48     DO(setType, OH_WebMessage_SetType);                     \
49     DO(getType, OH_WebMessage_GetType);                     \
50     DO(setData, OH_WebMessage_SetData);                     \
51     DO(getData, OH_WebMessage_GetData)
52 
53 #define ARKWEB_NATIVE_FOR_EACH_WEBCOOKIEMANAGER_API_FN(DO)                \
54     DO(fetchCookieSync, OH_CookieManager_FetchCookieSync);                \
55     DO(configCookieSync, OH_CookieManager_ConfigCookieSync);              \
56     DO(existCookies, OH_CookieManager_ExistCookies);                      \
57     DO(clearAllCookiesSync, OH_CookieManager_ClearAllCookiesSync);        \
58     DO(clearSessionCookiesSync, OH_CookieManager_ClearSessionCookiesSync)
59 
60 ArkWeb_ComponentAPI* g_ComponentImpl = nullptr;
61 ArkWeb_ControllerAPI* g_ControllerImpl = nullptr;
62 ArkWeb_WebMessagePortAPI* g_WebMessagePortImpl = nullptr;
63 ArkWeb_WebMessageAPI* g_WebMessageImpl = nullptr;
64 ArkWeb_CookieManagerAPI* g_CookieManagerImpl = nullptr;
65 
66 } // namespace
67 
68 template<typename Fn>
LoadFunction(const char* functionName, Fn* fnOut)69 static void LoadFunction(const char* functionName, Fn* fnOut)
70 {
71     void* fn = OHOS::NWeb::NWebHelper::Instance().LoadFuncSymbol(functionName);
72     if (!fn) {
73         WVLOG_E("%{public}s not found.", functionName);
74         return;
75     }
76     *fnOut = reinterpret_cast<Fn>(fn);
77 }
78 
LoadComponentAPI()79 static bool LoadComponentAPI()
80 {
81     if (g_ComponentImpl) {
82         WVLOG_I("NativeArkWeb component api already loaded");
83         return true;
84     }
85     g_ComponentImpl = new (std::nothrow) ArkWeb_ComponentAPI();
86     if (!g_ComponentImpl) {
87         WVLOG_E("NativeArkWeb component api is nullptr");
88         return false;
89     }
90     g_ComponentImpl->size = sizeof(ArkWeb_ComponentAPI);
91 
92     if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
93         WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
94         return false;
95     }
96 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_ComponentImpl->fn))
97     ARKWEB_NATIVE_FOR_EACH_COMPONENT_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
98 #undef ARKWEB_NATIVE_LOAD_FN_PTR
99 
100     return true;
101 }
102 
LoadControllerAPI()103 static bool LoadControllerAPI()
104 {
105     if (g_ControllerImpl) {
106         WVLOG_I("NativeArkWeb controller api already loaded");
107         return true;
108     }
109     g_ControllerImpl = new (std::nothrow) ArkWeb_ControllerAPI();
110     if (!g_ControllerImpl) {
111         WVLOG_E("NativeArkWeb controller api is nullptr");
112         return false;
113     }
114     g_ControllerImpl->size = sizeof(ArkWeb_ControllerAPI);
115 
116     if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
117         WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
118         return false;
119     }
120 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_ControllerImpl->fn))
121     ARKWEB_NATIVE_FOR_EACH_CONTROLLER_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
122 #undef ARKWEB_NATIVE_LOAD_FN_PTR
123 
124     return true;
125 }
126 
LoadWebMessagePortAPI()127 static bool LoadWebMessagePortAPI()
128 {
129     if (g_WebMessagePortImpl) {
130         WVLOG_I("NativeArkWeb web message port api already loaded");
131         return true;
132     }
133     g_WebMessagePortImpl = new (std::nothrow) ArkWeb_WebMessagePortAPI();
134     if (!g_WebMessagePortImpl) {
135         WVLOG_E("NativeArkWeb web message port api is nullptr");
136         return false;
137     }
138     g_WebMessagePortImpl->size = sizeof(ArkWeb_WebMessagePortAPI);
139 
140     if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
141         WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
142         return false;
143     }
144 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_WebMessagePortImpl->fn))
145     ARKWEB_NATIVE_FOR_EACH_WEBMESSAGEPORT_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
146 #undef ARKWEB_NATIVE_LOAD_FN_PTR
147 
148     return true;
149 }
150 
LoadWebMessageAPI()151 static bool LoadWebMessageAPI()
152 {
153     if (g_WebMessageImpl) {
154         WVLOG_I("NativeArkWeb web message api already loaded");
155         return true;
156     }
157     g_WebMessageImpl = new (std::nothrow) ArkWeb_WebMessageAPI();
158     if (!g_WebMessageImpl) {
159         WVLOG_E("NativeArkWeb web message api is nullptr");
160         return false;
161     }
162     g_WebMessageImpl->size = sizeof(ArkWeb_WebMessageAPI);
163 
164     if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
165         WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
166         return false;
167     }
168 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_WebMessageImpl->fn))
169     ARKWEB_NATIVE_FOR_EACH_WEBMESSAGE_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
170 #undef ARKWEB_NATIVE_LOAD_FN_PTR
171 
172     return true;
173 }
174 
LoadCookieManagerAPI()175 static bool LoadCookieManagerAPI()
176 {
177     if (g_CookieManagerImpl) {
178         WVLOG_I("NativeArkWeb cookie manager api already loaded");
179         return true;
180     }
181 
182     g_CookieManagerImpl = new ArkWeb_CookieManagerAPI();
183     if (!g_CookieManagerImpl) {
184         WVLOG_E("NativeArkWeb cookie manager api is nullptr");
185         return false;
186     }
187     g_CookieManagerImpl->size = sizeof(ArkWeb_CookieManagerAPI);
188 
189     if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, true)) {
190         WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
191         return false;
192     }
193 #define ARKWEB_NATIVE_LOAD_FN_PTR(fn, ndkFn) LoadFunction(#ndkFn, &(g_CookieManagerImpl->fn))
194     ARKWEB_NATIVE_FOR_EACH_WEBCOOKIEMANAGER_API_FN(ARKWEB_NATIVE_LOAD_FN_PTR);
195 #undef ARKWEB_NATIVE_LOAD_FN_PTR
196 
197     return true;
198 }
199 
OH_ArkWeb_GetNativeAPI(ArkWeb_NativeAPIVariantKind type)200 ArkWeb_AnyNativeAPI* OH_ArkWeb_GetNativeAPI(ArkWeb_NativeAPIVariantKind type)
201 {
202     switch (type) {
203         case ARKWEB_NATIVE_COMPONENT: {
204             if (!LoadComponentAPI()) {
205                 return nullptr;
206             }
207             return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_ComponentImpl);
208         }
209         case ARKWEB_NATIVE_CONTROLLER: {
210             if (!LoadControllerAPI()) {
211                 return nullptr;
212             }
213             return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_ControllerImpl);
214         }
215         case ARKWEB_NATIVE_WEB_MESSAGE_PORT: {
216             if (!LoadWebMessagePortAPI()) {
217                 return nullptr;
218             }
219             return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_WebMessagePortImpl);
220         }
221         case ARKWEB_NATIVE_WEB_MESSAGE: {
222             if (!LoadWebMessageAPI()) {
223                 return nullptr;
224             }
225             return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_WebMessageImpl);
226         }
227         case ARKWEB_NATIVE_COOKIE_MANAGER: {
228             if (!LoadCookieManagerAPI()) {
229                 return nullptr;
230             }
231             return reinterpret_cast<ArkWeb_AnyNativeAPI*>(g_CookieManagerImpl);
232         }
233         default: {
234             WVLOG_E("fail to get %{public}d arkweb api family", type);
235             return nullptr;
236         }
237     }
238 }
239