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