• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "hilog/log.h"
17 #include "napi/native_api.h"
18 #include <chrono>
19 #include <string>
20 #include "common/native_common.h"
21 #include "web/native_interface_arkweb.h"
22 #include "web/arkweb_interface.h"
23 #include "jsbridgeObject.h"
24 #include <thread>
25 
26 
27 constexpr unsigned int LOG_PRINT_DOMAIN = 0xFF00;
28 ArkWeb_ControllerAPI *controller = nullptr;
29 ArkWeb_JavaScriptValueAPI *javaScriptValueApi = nullptr;
30 std::shared_ptr<JSBridgeObject> jsbridge_object_ptr = nullptr;
31 
32 std::chrono::time_point<std::chrono::high_resolution_clock> start;
33 
34 int g_funcOnePid = -1;
35 int g_funcTwoPid = -1;
36 
37 std::thread::id g_thisId = std::this_thread::get_id();
38 std::size_t g_hashValueCur = std::hash<std::thread::id>()(g_thisId);
39 int g_mPid = static_cast<int>(g_hashValueCur);
40 
GetStringValue(napi_env env,napi_value value)41 char *GetStringValue(napi_env env, napi_value value)
42 {
43     size_t size = 0;
44     napi_get_value_string_utf8(env, value, nullptr, 0, &size);
45     char *paramValue = new (std::nothrow) char[size + 1];
46     size_t paramLength = 0;
47     napi_get_value_string_utf8(env, value, paramValue, size + 1, &paramLength);
48     return paramValue;
49 }
50 
51 // 发送JS脚本到H5侧执行,执行结果的回调
RunJavaScriptCallback(const char * result)52 static void RunJavaScriptCallback(const char *result)
53 {
54     std::chrono::duration<double, std::milli> elapsed_ms = std::chrono::high_resolution_clock::now() - start;
55 }
56 
57 // 示例代码 ,注册了1个对象,2个方法
ProxyMethod1(const char ** argv,int argc)58 static char *ProxyMethod1(const char **argv, int argc)
59 {
60     return nullptr;
61 }
62 
ProxyMethod2(const char ** argv,int argc)63 static char *ProxyMethod2(const char **argv, int argc)
64 {
65     char *ret = "ygz hello from native ProxyMethod2";
66     return ret;
67 }
68 
ProxyMethod3(const char ** argv,int argc)69 static char *ProxyMethod3(const char **argv, int argc)
70 {
71     char *ret = "ygz hello from native ProxyMethod3";
72     return ret;
73 }
74 
ValidCallback(const char * webName)75 void ValidCallback(const char *webName)
76 {
77     const char *methodName[2] = {"method1", "method2"};
78     NativeArkWeb_OnJavaScriptProxyCallback callback[2] = {ProxyMethod1, ProxyMethod2};
79     // 如此注册的情况下,在H5页面就可以使用proxy.method1、proxy.method1调用此文件下的ProxyMethod1和ProxyMethod2方法了
80     int32_t size = 2;
81     OH_NativeArkWeb_RegisterJavaScriptProxy(webName, "ndkProxy", methodName, callback, size, false);
82 }
83 
DestroyCallback(const char * webName)84 void DestroyCallback(const char *webName)
85 {
86 }
87 
NativeWebInit(napi_env env,napi_callback_info info)88 static napi_value NativeWebInit(napi_env env, napi_callback_info info)
89 {
90     size_t argc = 1;
91     napi_value args[1] = {nullptr};
92     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
93     // 获取第一个参数 webName
94     size_t webNameSize = 0;
95     napi_get_value_string_utf8(env, args[0], nullptr, 0, &webNameSize);
96     char *webNameValue = new (std::nothrow) char[webNameSize + 1];
97     size_t webNameLength = 0;
98     napi_get_value_string_utf8(env, args[0], webNameValue, webNameSize + 1, &webNameLength);
99 
100     // 注js proxy册回调函数
101     NativeArkWeb_OnValidCallback ptr = ValidCallback;
102     OH_NativeArkWeb_SetJavaScriptProxyValidCallback(webNameValue, ptr);
103     OH_NativeArkWeb_GetJavaScriptProxyValidCallback(webNameValue);
104     // 注册destroy回调函数
105     OH_NativeArkWeb_SetDestroyCallback(webNameValue, DestroyCallback);
106     OH_NativeArkWeb_GetDestroyCallback(webNameValue);
107     napi_value output;
108     NAPI_CALL(env, napi_create_string_utf8(env, "RunSuccess", NAPI_AUTO_LENGTH, &output));
109     return output;
110 }
111 
112 // 发送JS脚本到H5侧执行
RunJavaScript(napi_env env,napi_callback_info info)113 static napi_value RunJavaScript(napi_env env, napi_callback_info info)
114 {
115     size_t argc = 2;
116     napi_value args[2] = {nullptr};
117     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
118 
119     // 获取第一个参数 webName
120     size_t webNameSize = 0;
121     napi_get_value_string_utf8(env, args[0], nullptr, 0, &webNameSize);
122     char *webNameValue = new (std::nothrow) char[webNameSize + 1];
123     size_t webNameLength = 0;
124     napi_get_value_string_utf8(env, args[0], webNameValue, webNameSize + 1, &webNameLength);
125 
126     // 获取第二个参数 jsCode
127     size_t bufferSize = 0;
128     napi_get_value_string_utf8(env, args[1], nullptr, 0, &bufferSize);
129     char *jsCode = new (std::nothrow) char[bufferSize + 1];
130     size_t byteLength = 0;
131     napi_get_value_string_utf8(env, args[1], jsCode, bufferSize + 1, &byteLength);
132     start = std::chrono::high_resolution_clock::now();
133 
134     // 调用ndk接口
135     OH_NativeArkWeb_RunJavaScript(webNameValue, jsCode, RunJavaScriptCallback);
136     napi_value output;
137     NAPI_CALL(env, napi_create_string_utf8(env, "RunSuccess", NAPI_AUTO_LENGTH, &output));
138     return output;
139 }
140 
RegisterJavaScriptProxy(napi_env env,napi_callback_info info)141 static napi_value RegisterJavaScriptProxy(napi_env env, napi_callback_info info)
142 {
143     size_t argc = 1;
144     napi_value args[1] = {nullptr};
145     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
146     // 获取第一个参数 webName
147     size_t webNameSize = 0;
148     napi_get_value_string_utf8(env, args[0], nullptr, 0, &webNameSize);
149     char *webNameValue = new (std::nothrow) char[webNameSize + 1];
150     size_t webNameLength = 0;
151     napi_get_value_string_utf8(env, args[0], webNameValue, webNameSize + 1, &webNameLength);
152     const char *methodName[3] = {"method1", "method2", "method3"};
153     NativeArkWeb_OnJavaScriptProxyCallback callback[3] = {ProxyMethod1, ProxyMethod2, ProxyMethod3};
154     // 如此注册的情况下,在H5页面就可以使用proxy.method1、proxy.method1调用此文件下的ProxyMethod1和ProxyMethod2方法了
155     int32_t size = 3;
156     OH_NativeArkWeb_RegisterJavaScriptProxy(webNameValue, "ndkProxy", methodName, callback, size, false);
157     napi_value output;
158     NAPI_CALL(env, napi_create_string_utf8(env, "RunSuccess", NAPI_AUTO_LENGTH, &output));
159     return output;
160 }
161 
UnregisterJavaScriptProxy(napi_env env,napi_callback_info info)162 static napi_value UnregisterJavaScriptProxy(napi_env env, napi_callback_info info)
163 {
164     size_t argc = 1;
165     napi_value args[1] = {nullptr};
166     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
167     // 获取第一个参数 webName
168     size_t webNameSize = 0;
169     napi_get_value_string_utf8(env, args[0], nullptr, 0, &webNameSize);
170     char *webNameValue = new (std::nothrow) char[webNameSize + 1];
171     size_t webNameLength = 0;
172     napi_get_value_string_utf8(env, args[0], webNameValue, webNameSize + 1, &webNameLength);
173     NativeArkWeb_OnJavaScriptProxyCallback callback[3] = {ProxyMethod1, ProxyMethod2, ProxyMethod3};
174     // 如此注册的情况下,在H5页面就可以使用proxy.method1、proxy.method1调用此文件下的ProxyMethod1和ProxyMethod2方法了
175     OH_NativeArkWeb_UnregisterJavaScriptProxy(webNameValue, "ndkProxy");
176     napi_value output;
177     NAPI_CALL(env, napi_create_string_utf8(env, "RunSuccess", NAPI_AUTO_LENGTH, &output));
178     return output;
179 }
180 
ArkWebProxyMethodOne(const char * webTag,const ArkWeb_JavaScriptBridgeData * dataArray,size_t arraySize,void * userData)181 ArkWeb_JavaScriptValuePtr ArkWebProxyMethodOne(const char *webTag, const ArkWeb_JavaScriptBridgeData *dataArray,
182     size_t arraySize, void *userData)
183 {
184     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
185         "ArkWebProxyMethodOne webTag:%{public}s userData:%{public}s",
186         webTag,
187         (char *)userData);
188     std::size_t hashValue = std::hash<std::thread::id>()(std::this_thread::get_id());
189     g_funcOnePid = static_cast<int>(hashValue);
190     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
191         "ArkWebProxyMethodOne PID:%{public}d, Fid:%{public}d",
192         g_mPid,
193         g_funcOnePid);
194     jsbridge_object_ptr->ProxyMethod(dataArray, arraySize);
195     std::string str = std::string((char *)userData);
196     return javaScriptValueApi->createJavaScriptValue(ArkWeb_JavaScriptValueType::ARKWEB_JAVASCRIPT_STRING,
197         (void *)str.c_str(),
198         str.length() + 1);
199 }
200 
ArkWebProxyMethodTwo(const char * webTag,const ArkWeb_JavaScriptBridgeData * dataArray,size_t arraySize,void * userData)201 ArkWeb_JavaScriptValuePtr ArkWebProxyMethodTwo(const char *webTag, const ArkWeb_JavaScriptBridgeData *dataArray,
202     size_t arraySize, void *userData)
203 {
204     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
205         "ArkWebProxyMethodTwo webTag:%{public}s userData:%{public}s",
206         webTag,
207         (char *)userData);
208     std::size_t hashValue = std::hash<std::thread::id>()(std::this_thread::get_id());
209     g_funcTwoPid = static_cast<int>(hashValue);
210     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
211         "ArkWebProxyMethodTwo PID:%{public}d, Fid:%{public}d",
212         g_mPid,
213         g_funcTwoPid);
214     jsbridge_object_ptr->ProxyMethod(dataArray, arraySize);
215     bool boolValue = true;
216     return javaScriptValueApi->createJavaScriptValue(ArkWeb_JavaScriptValueType::ARKWEB_JAVASCRIPT_BOOL,
217         (void *)(&boolValue),
218         1);
219 }
220 
ArkWebProxyMethodThree(const char * webTag,const ArkWeb_JavaScriptBridgeData * dataArray,size_t arraySize,void * userData)221 ArkWeb_JavaScriptValuePtr ArkWebProxyMethodThree(const char *webTag, const ArkWeb_JavaScriptBridgeData *dataArray,
222     size_t arraySize, void *userData)
223 {
224     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
225         "ArkWebProxyMethodThree webTag:%{public}s userData:%{public}s",
226         webTag,
227         (char *)userData);
228     jsbridge_object_ptr->ProxyMethod(dataArray, arraySize);
229     return javaScriptValueApi->createJavaScriptValue(ArkWeb_JavaScriptValueType::ARKWEB_JAVASCRIPT_NONE,
230         (void *)nullptr,
231         1);
232 }
233 
GetProxyObjectWithResult(napi_env env,napi_value args[])234 ArkWeb_ProxyObjectWithResult GetProxyObjectWithResult(napi_env env, napi_value args[])
235 {
236     ArkWeb_ProxyMethodWithResult *methodList = new ArkWeb_ProxyMethodWithResult[3];
237     const char *userDataOne = "method1";
238     const char *userDataTwo = "method2";
239     const char *userDataThree = "method3";
240     const int indexOne = 0;
241     const int indexTwo = 1;
242     const int indexThree = 2;
243     methodList[indexOne] = {"method1", ArkWebProxyMethodOne, (void *)userDataOne};
244     methodList[indexTwo] = {"method2", ArkWebProxyMethodTwo, (void *)userDataTwo};
245     methodList[indexThree] = {"method3", ArkWebProxyMethodThree, (void *)userDataThree};
246 
247     int32_t size = 3;
248     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "AsyncRegister", "methodSize:%{public}d", size);
249     ArkWeb_ProxyObjectWithResult proxyObject = {"ndkProxy", methodList, (size_t)size};
250     return proxyObject;
251 }
252 
253 
254 
NativeWebInitTwo(napi_env env,napi_callback_info info)255 static napi_value NativeWebInitTwo(napi_env env, napi_callback_info info)
256 {
257     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "NativeWebInitTwo start");
258     size_t argc = 1;
259     napi_value args[1] = {nullptr};
260     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
261     // 获取第一个参数 webName
262     size_t webTagSize = 0;
263     napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);
264     char *webTagValue = new (std::nothrow) char[webTagSize + 1];
265     size_t webTagLength = 0;
266     napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);
267     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
268         "NativeWebInitTwo webTag:%{public}s",
269         webTagValue);
270 
271     jsbridge_object_ptr = std::make_shared<JSBridgeObject>(webTagValue);
272     if (jsbridge_object_ptr) {
273         jsbridge_object_ptr->Init();
274     }
275 
276     controller = reinterpret_cast<ArkWeb_ControllerAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_CONTROLLER));
277     javaScriptValueApi =
278         reinterpret_cast<ArkWeb_JavaScriptValueAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_JAVASCRIPT_VALUE));
279     if (javaScriptValueApi) {
280         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ArkWeb_JavaScriptValueAPI success");
281     }
282 
283     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "NativeWebInitTwo end");
284 
285     napi_value output;
286     NAPI_CALL(env, napi_create_string_utf8(env, "RunSuccess", NAPI_AUTO_LENGTH, &output));
287     return output;
288 }
289 
RegisterAsyncThreadJavaScriptProxy(napi_env env,napi_callback_info info)290 static napi_value RegisterAsyncThreadJavaScriptProxy(napi_env env, napi_callback_info info)
291 {
292     size_t argc = 2;
293     napi_value args[2] = {nullptr};
294     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
295 
296     char *webTagValue = GetStringValue(env, args[0]);
297     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "AsyncRegister",
298         "RegisterAsyncThreadJavaScriptProxy webTag:%{public}s",
299         webTagValue);
300 
301     char *permission = GetStringValue(env, args[1]);
302     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "AsyncRegister",
303         "RegisterAsyncThreadJavaScriptProxy permissionStr:%{public}s",
304         permission);
305 
306     if (strcmp(permission, "null") == 0) {
307         permission = nullptr;
308     }
309     if (strcmp(webTagValue, "null") == 0) {
310         webTagValue = nullptr;
311     }
312 
313     ArkWeb_ProxyObjectWithResult proxyObjectWithResult = GetProxyObjectWithResult(env, args);
314     OH_NativeArkWeb_RegisterAsyncThreadJavaScriptProxy(webTagValue, &proxyObjectWithResult, permission);
315     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "AsyncRegister",
316         "RegisterAsyncThreadJavaScriptProxy success");
317 
318     napi_value output;
319     NAPI_CALL(env, napi_create_string_utf8(env, "RunSuccess", NAPI_AUTO_LENGTH, &output));
320     return output;
321 }
322 
GetPidResult(napi_env env,napi_callback_info info)323 static napi_value GetPidResult(napi_env env, napi_callback_info info)
324 {
325     napi_value result;
326     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "GetPidResult g_mPid:%{public}d", g_mPid);
327     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "GetPidResult funcOnePid:%{public}d", g_funcOnePid);
328     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "GetPidResult funcTwoPid:%{public}d", g_funcTwoPid);
329     int32_t testResult = 0;
330     if (g_mPid != g_funcOnePid && g_mPid != g_funcTwoPid && g_funcOnePid == g_funcTwoPid) {
331         testResult = 1;
332     }
333     napi_create_int32(env, testResult, &result);
334     return result;
335 }
336 
337 
338 
339 EXTERN_C_START
Init(napi_env env,napi_value exports)340 static napi_value Init(napi_env env, napi_value exports)
341 {
342     napi_property_descriptor desc[] = {
343         {"nativeWebInit", nullptr, NativeWebInit, nullptr, nullptr, nullptr, napi_default, nullptr},
344         {"runJavaScript", nullptr, RunJavaScript, nullptr, nullptr, nullptr, napi_default, nullptr},
345         {"registerJavaScriptProxy", nullptr, RegisterJavaScriptProxy, nullptr, nullptr, nullptr, napi_default, nullptr},
346         {"unregisterJavaScriptProxy", nullptr, UnregisterJavaScriptProxy, nullptr, nullptr, nullptr, napi_default, nullptr},
347         {"nativeWebInitTwo", nullptr, NativeWebInitTwo, nullptr, nullptr, nullptr, napi_default, nullptr},
348         {"registerAsyncThreadJavaScriptProxy", nullptr, RegisterAsyncThreadJavaScriptProxy, nullptr, nullptr, nullptr,
349             napi_default,
350             nullptr},
351         {"getPidResult", nullptr, GetPidResult, nullptr, nullptr, nullptr, napi_default, nullptr},
352     };
353     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
354     return exports;
355 }
356 EXTERN_C_END
357 
358 static napi_module demoModule = {
359     .nm_version = 1,
360     .nm_flags = 0,
361     .nm_filename = nullptr,
362     .nm_register_func = Init,
363     .nm_modname = "entry",
364     .nm_priv = ((void *)0),
365     .reserved = {0},
366 };
367 
RegisterEntryModule(void)368 extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
369 {
370     napi_module_register(&demoModule);
371 }