1 /*
2 * Copyright (c) 2023 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 "native_interface_arkweb.h"
17
18 #include <memory>
19 #include <mutex>
20 #include <unordered_map>
21 #include <vector>
22
23 #include "arkweb_error_code.h"
24 #include "arkweb_type.h"
25 #include "native_arkweb_utils.h"
26 #include "native_javascript_execute_callback.h"
27 #include "nweb.h"
28 #include "nweb_helper.h"
29 #include "nweb_log.h"
30
31 namespace {
32 std::mutex g_mtxMap; // the mutex to protect the shared resource
33 std::unordered_map<std::string, NativeArkWeb_OnValidCallback> g_validMap;
34 std::unordered_map<std::string, NativeArkWeb_OnDestroyCallback> g_destroyMap;
35 } // namespace
36
37 namespace OHOS::NWeb {
38
39 class NWebJsProxyCallbackImpl : public NWebJsProxyCallback {
40 public:
NWebJsProxyCallbackImpl(const char * methodName,NativeArkWeb_OnJavaScriptProxyCallback methodCallback)41 NWebJsProxyCallbackImpl(const char *methodName, NativeArkWeb_OnJavaScriptProxyCallback methodCallback)
42 : methodName_(methodName), methodCallback_(methodCallback) {
43 }
44 ~NWebJsProxyCallbackImpl() = default;
45
GetMethodName()46 std::string GetMethodName() override
47 {
48 return methodName_;
49 }
50
GetMethodCallback()51 NativeArkWeb_OnJavaScriptProxyCallback GetMethodCallback() override
52 {
53 return methodCallback_;
54 }
55
56 private:
57 std::string methodName_;
58 NativeArkWeb_OnJavaScriptProxyCallback methodCallback_ = nullptr;
59 };
60
61 }; // namespace OHOS::NWeb
62
63 using namespace OHOS;
OH_NativeArkWeb_RunJavaScript(const char * webTag,const char * jsCode,NativeArkWeb_OnJavaScriptCallback callback)64 void OH_NativeArkWeb_RunJavaScript(const char* webTag, const char* jsCode, NativeArkWeb_OnJavaScriptCallback callback)
65 {
66 std::weak_ptr<OHOS::NWeb::NWeb> nwebWeak = OH_NativeArkWeb_GetWebInstanceByWebTag(webTag);
67 if (auto nweb = nwebWeak.lock()) {
68 auto callbackImpl = std::make_shared<OHOS::NWeb::NativeJavaScriptExecuteCallback>(callback);
69 WVLOG_I("native RunJavaScript webTag: %{public}s", webTag);
70 nweb->ExecuteJavaScript(jsCode, callbackImpl, false);
71 } else {
72 WVLOG_E("native RunJavaScript get nweb null: %{public}s", webTag);
73 }
74 }
75
OH_NativeArkWeb_RegisterJavaScriptProxy(const char * webTag,const char * objName,const char ** methodList,NativeArkWeb_OnJavaScriptProxyCallback * callback,int32_t size,bool isNeedRefresh)76 void OH_NativeArkWeb_RegisterJavaScriptProxy(const char* webTag, const char* objName, const char** methodList,
77 NativeArkWeb_OnJavaScriptProxyCallback* callback, int32_t size, bool isNeedRefresh)
78 {
79 WVLOG_I("native OH_NativeArkWeb_RegisterJavaScriptProxy webTag:%{public}s", webTag);
80 std::vector<std::shared_ptr<OHOS::NWeb::NWebJsProxyCallback>> proxyCallbacks;
81 for (int i = 0; i < size; i++) {
82 std::shared_ptr<OHOS::NWeb::NWebJsProxyCallback> proxyCallback =
83 std::make_shared<OHOS::NWeb::NWebJsProxyCallbackImpl>(methodList[i], callback[i]);
84 proxyCallbacks.push_back(proxyCallback);
85 }
86
87 std::weak_ptr<OHOS::NWeb::NWeb> nwebWeak = OH_NativeArkWeb_GetWebInstanceByWebTag(webTag);
88 if (auto nweb = nwebWeak.lock()) {
89 nweb->RegisterNativeArkJSFunction(objName, proxyCallbacks);
90 if (isNeedRefresh) {
91 nweb->Reload();
92 }
93 } else {
94 WVLOG_E("native RegisterJavaScriptProxy get nweb null: %{public}s", webTag);
95 }
96 }
97
OH_NativeArkWeb_UnregisterJavaScriptProxy(const char * webTag,const char * objName)98 void OH_NativeArkWeb_UnregisterJavaScriptProxy(const char* webTag, const char* objName)
99 {
100 WVLOG_I("native OH_NativeArkWeb_RegisterJavaScriptProxy: %{public}s", webTag);
101 std::weak_ptr<OHOS::NWeb::NWeb> nwebWeak = OH_NativeArkWeb_GetWebInstanceByWebTag(webTag);
102 if (auto nweb = nwebWeak.lock()) {
103 nweb->UnRegisterNativeArkJSFunction(objName);
104 } else {
105 WVLOG_E("native RegisterJavaScriptProxy get nweb null: %{public}s", webTag);
106 }
107 }
108
OH_NativeArkWeb_SetDestroyCallback(const char * webTag,NativeArkWeb_OnDestroyCallback callback)109 void OH_NativeArkWeb_SetDestroyCallback(const char* webTag, NativeArkWeb_OnDestroyCallback callback)
110 {
111 WVLOG_I("native RegisterDestroyCallback, webTag: %{public}s", webTag);
112 std::lock_guard<std::mutex> guard(g_mtxMap);
113 g_destroyMap[webTag] = callback;
114 std::weak_ptr<OHOS::NWeb::NWeb> nwebWeak = OH_NativeArkWeb_GetWebInstanceByWebTag(webTag);
115 if (auto nweb = nwebWeak.lock()) {
116 WVLOG_I("native RegisterNativeDestroyCallback call nweb");
117 nweb->RegisterNativeDestroyCallback(webTag, callback);
118 } else {
119 WVLOG_E("native RegisterDestroyCallback get nweb null: %{public}s", webTag);
120 }
121 }
122
OH_NativeArkWeb_GetDestroyCallback(const char * webTag)123 NativeArkWeb_OnDestroyCallback OH_NativeArkWeb_GetDestroyCallback(const char* webTag)
124 {
125 WVLOG_I("native OH_Web_GetDestroyCallback, webTag: %{public}s", webTag);
126 std::lock_guard<std::mutex> guard(g_mtxMap);
127 std::unordered_map<std::string, NativeArkWeb_OnDestroyCallback>::iterator iter;
128 if ((iter = g_destroyMap.find(webTag)) != g_destroyMap.end()) {
129 return iter->second;
130 }
131 return nullptr;
132 }
133
OH_NativeArkWeb_SetJavaScriptProxyValidCallback(const char * webTag,NativeArkWeb_OnValidCallback callback)134 void OH_NativeArkWeb_SetJavaScriptProxyValidCallback(const char* webTag, NativeArkWeb_OnValidCallback callback)
135 {
136 WVLOG_I("native RegisterValidCallback, webTag: %{public}s", webTag);
137 std::lock_guard<std::mutex> guard(g_mtxMap);
138 g_validMap[webTag] = callback;
139 std::weak_ptr<OHOS::NWeb::NWeb> nwebWeak = OH_NativeArkWeb_GetWebInstanceByWebTag(webTag);
140 if (auto nweb = nwebWeak.lock()) {
141 WVLOG_I("native OH_NativeArkWeb_SetJavaScriptProxyValidCallback call nweb");
142 nweb->RegisterNativeValideCallback(webTag, callback);
143 } else {
144 WVLOG_E("native RegisterDestroyCallback get nweb null: %{public}s", webTag);
145 }
146 }
147
OH_NativeArkWeb_GetJavaScriptProxyValidCallback(const char * webTag)148 NativeArkWeb_OnValidCallback OH_NativeArkWeb_GetJavaScriptProxyValidCallback(const char* webTag)
149 {
150 WVLOG_I("native OH_Web_GetValidCallback, webTag: %{public}s", webTag);
151 std::lock_guard<std::mutex> guard(g_mtxMap);
152 std::unordered_map<std::string, NativeArkWeb_OnValidCallback>::iterator iter;
153 if ((iter = g_validMap.find(webTag)) != g_validMap.end()) {
154 return iter->second;
155 }
156 return nullptr;
157 }
158
159 template<typename Fn>
LoadFunction(const char * functionName,Fn * fnOut)160 static bool LoadFunction(const char* functionName, Fn* fnOut)
161 {
162 void* fn = OHOS::NWeb::NWebHelper::Instance().LoadFuncSymbol(functionName);
163 if (!fn) {
164 WVLOG_E("%{public}s not found.", functionName);
165 return false;
166 }
167 *fnOut = reinterpret_cast<Fn>(fn);
168 return true;
169 }
170
OH_NativeArkWeb_LoadData(const char * webTag,const char * data,const char * mimeType,const char * encoding,const char * baseUrl,const char * historyUrl)171 ArkWeb_ErrorCode OH_NativeArkWeb_LoadData(const char* webTag,
172 const char* data,
173 const char* mimeType,
174 const char* encoding,
175 const char* baseUrl,
176 const char* historyUrl)
177 {
178 WVLOG_I("native OH_NativeArkWeb_LoadData, webTag: %{public}s", webTag);
179 if (!OHOS::NWeb::NWebHelper::Instance().LoadWebEngine(true, false)) {
180 WVLOG_E("NativeArkWeb webEngineHandle is nullptr");
181 return ArkWeb_ErrorCode::ARKWEB_LIBRARY_OPEN_FAILURE;
182 }
183
184 ArkWeb_ErrorCode (*loadData)(const char* webTag,
185 const char* data,
186 const char* mimeType,
187 const char* encoding,
188 const char* baseUrl,
189 const char* historyUrl) = nullptr;
190
191 #define ARKWEB_NATIVE_LOAD_FN_PTR(apiMember, funcImpl) LoadFunction(#funcImpl, &(apiMember))
192 ARKWEB_NATIVE_LOAD_FN_PTR(loadData, OH_NativeArkWeb_LoadData);
193 #undef ARKWEB_NATIVE_LOAD_FN_PTR
194 if (!loadData) {
195 WVLOG_E("OH_NativeArkWeb_LoadData failed to load function loadData");
196 return ArkWeb_ErrorCode::ARKWEB_LIBRARY_SYMBOL_NOT_FOUND;
197 }
198 return loadData(webTag, data, mimeType, encoding, baseUrl, historyUrl);
199 }
200