1 /*
2 * Copyright (c) 2022 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 "core/components/web/resource/web_delegate.h"
17 #include "core/components/web/resource/web_javascript_result_callback.h"
18
19 namespace OHOS::Ace {
20 using namespace OHOS::Ace::Framework;
21 using namespace OHOS::NWeb;
22
GetWebJSValueHelper(std::shared_ptr<NWebValue> argument)23 std::shared_ptr<WebJSValue> GetWebJSValueHelper(std::shared_ptr<NWebValue> argument)
24 {
25 if (!argument) {
26 TAG_LOGE(AceLogTag::ACE_WEB, "GetWebJSValueHelper: argument is null");
27 return std::make_shared<WebJSValue>();
28 }
29 switch (argument->GetType()) {
30 case NWebValue::Type::INTEGER:
31 return std::make_shared<WebJSValue>(argument->GetInt());
32 case NWebValue::Type::DOUBLE:
33 return std::make_shared<WebJSValue>(argument->GetDouble());
34 case NWebValue::Type::BOOLEAN:
35 return std::make_shared<WebJSValue>(argument->GetBoolean());
36 case NWebValue::Type::STRING:
37 return std::make_shared<WebJSValue>(argument->GetString());
38 case NWebValue::Type::LIST: {
39 size_t length = argument->GetListValueSize();
40 std::vector<WebJSValue> vec;
41 for (size_t i = 0; i < length; ++i) {
42 auto nPtr = std::make_shared<NWebValue>(argument->GetListValue(i));
43 vec.push_back(*GetWebJSValueHelper(nPtr));
44 }
45 return std::make_shared<WebJSValue>(vec);
46 }
47 case NWebValue::Type::DICTIONARY: {
48 std::map<std::string, WebJSValue> map;
49 auto dict = argument->GetDictionaryValue();
50 for (auto& item : dict) {
51 auto nPtr = std::make_shared<NWebValue>(item.second);
52 map[item.first] = *GetWebJSValueHelper(nPtr);
53 }
54 return std::make_shared<WebJSValue>(map);
55 }
56 case NWebValue::Type::BINARY: {
57 auto size = argument->GetBinaryValueSize();
58 auto buff = argument->GetBinaryValue();
59 return std::make_shared<WebJSValue>(buff, size);
60 }
61 case NWebValue::Type::NONE:
62 return std::make_shared<WebJSValue>();
63 default:
64 LOGI("GetWebJSValueHelper: jsvalue type not support!");
65 break;
66 }
67 return std::make_shared<WebJSValue>();
68 }
69
GetWebJSValue(const std::vector<std::shared_ptr<NWebValue>> & args)70 std::vector<std::shared_ptr<WebJSValue>> GetWebJSValue(const std::vector<std::shared_ptr<NWebValue>>& args)
71 {
72 std::vector<std::shared_ptr<WebJSValue>> webJSValues;
73 for (auto value : args) {
74 if (value == nullptr) {
75 continue;
76 }
77 webJSValues.push_back(GetWebJSValueHelper(value));
78 }
79 return webJSValues;
80 }
81
GetBasicTypeWebViewValue(const std::shared_ptr<WebJSValue> & webJSValue,std::shared_ptr<NWebValue> & webViewValue)82 bool GetBasicTypeWebViewValue(const std::shared_ptr<WebJSValue>& webJSValue, std::shared_ptr<NWebValue>& webViewValue)
83 {
84 WebJSValue::Type type = webJSValue->GetType();
85 switch (type) {
86 case WebJSValue::Type::INTEGER:
87 webViewValue->SetType(NWebValue::Type::INTEGER);
88 webViewValue->SetInt(webJSValue->GetInt());
89 break;
90 case WebJSValue::Type::DOUBLE:
91 webViewValue->SetType(NWebValue::Type::DOUBLE);
92 webViewValue->SetDouble(webJSValue->GetDouble());
93 break;
94 case WebJSValue::Type::BOOLEAN:
95 webViewValue->SetType(NWebValue::Type::BOOLEAN);
96 webViewValue->SetBoolean(webJSValue->GetBoolean());
97 break;
98 case WebJSValue::Type::STRING:
99 webViewValue->SetType(NWebValue::Type::STRING);
100 webViewValue->SetString(webJSValue->GetString());
101 break;
102 default:
103 return false;
104 }
105 return true;
106 }
107
GetWebViewValue(const std::shared_ptr<WebJSValue> & webJSValue)108 std::shared_ptr<NWebValue> GetWebViewValue(const std::shared_ptr<WebJSValue>& webJSValue)
109 {
110 if (!webJSValue) {
111 TAG_LOGE(AceLogTag::ACE_WEB, "GetWebViewValue: webJSValue is null");
112 return std::make_shared<NWebValue>(NWebValue::Type::NONE);
113 }
114 std::shared_ptr<NWebValue> webViewValue = std::make_shared<NWebValue>(NWebValue::Type::NONE);
115 WebJSValue::Type type = webJSValue->GetType();
116 if (GetBasicTypeWebViewValue(webJSValue, webViewValue)) {
117 return webViewValue;
118 }
119 switch (type) {
120 case WebJSValue::Type::LIST: {
121 size_t length = webJSValue->GetListValueSize();
122 std::vector<NWebValue> vec;
123 for (size_t i = 0; i < length; ++i) {
124 auto nPtr = std::make_shared<WebJSValue>(webJSValue->GetListValue(i));
125 vec.push_back(*GetWebViewValue(nPtr));
126 }
127 return std::make_shared<NWebValue>(vec);
128 }
129 case WebJSValue::Type::DICTIONARY: {
130 std::map<std::string, NWebValue> map;
131 auto dict = webJSValue->GetDictionaryValue();
132 for (auto& item : dict) {
133 auto nPtr = std::make_shared<WebJSValue>(item.second);
134 map[item.first] = *GetWebViewValue(nPtr);
135 }
136 return std::make_shared<NWebValue>(map);
137 }
138 case WebJSValue::Type::BINARY: {
139 auto size = webJSValue->GetBinaryValueSize();
140 auto buff = webJSValue->GetBinaryValue();
141 return std::make_shared<NWebValue>(buff, size);
142 }
143 case WebJSValue::Type::NONE:
144 break;
145 default:
146 LOGI("GetWebViewValue: jsvalue type not support!");
147 break;
148 }
149 return webViewValue;
150 }
151
GetJavaScriptResult(const std::vector<std::shared_ptr<WebJSValue>> & args,const std::string & method,const std::string & object_name)152 std::shared_ptr<WebJSValue> WebJavaScriptResultCallBack::GetJavaScriptResult(
153 const std::vector<std::shared_ptr<WebJSValue>>& args, const std::string& method, const std::string& object_name)
154 {
155 auto delegate = webDelegate_.Upgrade();
156 if (!delegate) {
157 return nullptr;
158 }
159
160 ContainerScope scope(delegate->GetInstanceId());
161 std::shared_ptr<WebJSValue> result;
162
163 auto task = Container::CurrentTaskExecutor();
164 if (task == nullptr) {
165 LOGW("can't get task executor");
166 return nullptr;
167 }
168
169 task->PostSyncTask(
170 [webJSCallBack = this, object_name, method, args, &result] {
171 if (webJSCallBack->javaScriptCallBackImpl_) {
172 result = webJSCallBack->javaScriptCallBackImpl_(object_name, method, args);
173 }
174 },
175 OHOS::Ace::TaskExecutor::TaskType::JS, "ArkUIWebGetJavaScriptResult");
176
177 return result;
178 }
179
GetJavaScriptResult(std::vector<std::shared_ptr<NWebValue>> args,const std::string & method,const std::string & object_name,int32_t routing_id,int32_t object_id)180 std::shared_ptr<NWebValue> WebJavaScriptResultCallBack::GetJavaScriptResult(
181 std::vector<std::shared_ptr<NWebValue>> args, const std::string& method, const std::string& object_name,
182 int32_t routing_id, int32_t object_id)
183 {
184 // webcontroller not support object, so the object_id and routing_id param is
185 // not used
186 (void)object_id;
187 (void)routing_id;
188
189 std::shared_ptr<WebJSValue> result = GetJavaScriptResult(GetWebJSValue(args), method, object_name);
190 return GetWebViewValue(result);
191 }
192
GetJavaScriptResultFlowbuf(std::vector<std::shared_ptr<NWebValue>> args,const std::string & method,const std::string & object_name,int fd,int32_t routing_id,int32_t object_id)193 std::shared_ptr<NWebValue> WebJavaScriptResultCallBack::GetJavaScriptResultFlowbuf(
194 std::vector<std::shared_ptr<NWebValue>> args, const std::string& method, const std::string& object_name,
195 int fd, int32_t routing_id, int32_t object_id)
196 {
197 // webcontroller not support object
198 // not supported
199 (void)object_id;
200 (void)routing_id;
201 LOGE("Flowbuf is not supported on the decrepted Webcontroller, use Webviewcontroller instead.");
202 return std::make_shared<NWebValue>(NWebValue::Type::NONE);
203 }
204
HasJavaScriptObjectMethods(int32_t object_id,const std::string & method_name)205 bool WebJavaScriptResultCallBack::HasJavaScriptObjectMethods(int32_t object_id, const std::string& method_name)
206 {
207 (void)object_id;
208 (void)method_name;
209 // webcontroller not support object, so nothing to do
210 return false;
211 }
212
GetJavaScriptObjectMethods(int32_t object_id)213 std::shared_ptr<NWebValue> WebJavaScriptResultCallBack::GetJavaScriptObjectMethods(int32_t object_id)
214 {
215 (void)object_id;
216 // webcontroller not support object, so nothing to do
217 return std::make_shared<NWebValue>();
218 }
219
RemoveJavaScriptObjectHolder(int32_t holder,int32_t object_id)220 void WebJavaScriptResultCallBack::RemoveJavaScriptObjectHolder(int32_t holder, int32_t object_id)
221 {
222 (void)holder;
223 (void)object_id;
224 // webcontroller not support object, so nothing to do
225 }
226
RemoveTransientJavaScriptObject()227 void WebJavaScriptResultCallBack::RemoveTransientJavaScriptObject()
228 {
229 // webcontroller not support object, so nothing to do
230 }
231
GetWebJSValueHelperV2(std::shared_ptr<NWebHapValue> argument)232 std::shared_ptr<WebJSValue> GetWebJSValueHelperV2(std::shared_ptr<NWebHapValue> argument)
233 {
234 if (!argument) {
235 TAG_LOGE(AceLogTag::ACE_WEB, "GetWebJSValueHelper: argument is null");
236 return std::make_shared<WebJSValue>();
237 }
238
239 switch (argument->GetType()) {
240 case NWebHapValue::Type::INTEGER:
241 return std::make_shared<WebJSValue>(argument->GetInt());
242 case NWebHapValue::Type::BOOLEAN:
243 return std::make_shared<WebJSValue>(argument->GetBool());
244 case NWebHapValue::Type::DOUBLE:
245 return std::make_shared<WebJSValue>(argument->GetDouble());
246 case NWebHapValue::Type::STRING:
247 return std::make_shared<WebJSValue>(argument->GetString());
248 case NWebHapValue::Type::BINARY: {
249 int length = 0;
250 auto buff = argument->GetBinary(length);
251 return std::make_shared<WebJSValue>(buff, length);
252 }
253 case NWebHapValue::Type::LIST: {
254 std::vector<WebJSValue> vec;
255 auto list = argument->GetListValue();
256 for (auto& item : list) {
257 vec.push_back(*GetWebJSValueHelperV2(item));
258 }
259 return std::make_shared<WebJSValue>(vec);
260 }
261 case NWebHapValue::Type::DICTIONARY: {
262 std::map<std::string, WebJSValue> map;
263 auto dict = argument->GetDictValue();
264 for (auto& item : dict) {
265 map[item.first] = *GetWebJSValueHelperV2(item.second);
266 }
267 return std::make_shared<WebJSValue>(map);
268 }
269 case NWebHapValue::Type::NONE:
270 return std::make_shared<WebJSValue>();
271 default:
272 LOGI("GetWebJSValueHelper: jsvalue type not support!");
273 break;
274 }
275 return std::make_shared<WebJSValue>();
276 }
277
GetWebJSValueV2(const std::vector<std::shared_ptr<NWebHapValue>> & args)278 std::vector<std::shared_ptr<WebJSValue>> GetWebJSValueV2(const std::vector<std::shared_ptr<NWebHapValue>>& args)
279 {
280 std::vector<std::shared_ptr<WebJSValue>> webJSValues;
281 for (auto value : args) {
282 if (value == nullptr) {
283 continue;
284 }
285 webJSValues.push_back(GetWebJSValueHelperV2(value));
286 }
287 return webJSValues;
288 }
289
GetBasicTypeWebViewValueV2(const std::shared_ptr<WebJSValue> & webJSValue,std::shared_ptr<NWebHapValue> & webHapValue)290 bool GetBasicTypeWebViewValueV2(
291 const std::shared_ptr<WebJSValue>& webJSValue, std::shared_ptr<NWebHapValue>& webHapValue)
292 {
293 WebJSValue::Type type = webJSValue->GetType();
294 switch (type) {
295 case WebJSValue::Type::NONE:
296 webHapValue->SetType(NWebHapValue::Type::NONE);
297 break;
298 case WebJSValue::Type::INTEGER:
299 webHapValue->SetType(NWebHapValue::Type::INTEGER);
300 webHapValue->SetInt(webJSValue->GetInt());
301 break;
302 case WebJSValue::Type::DOUBLE:
303 webHapValue->SetType(NWebHapValue::Type::DOUBLE);
304 webHapValue->SetDouble(webJSValue->GetDouble());
305 break;
306 case WebJSValue::Type::BOOLEAN:
307 webHapValue->SetType(NWebHapValue::Type::BOOLEAN);
308 webHapValue->SetBool(webJSValue->GetBoolean());
309 break;
310 case WebJSValue::Type::STRING:
311 webHapValue->SetType(NWebHapValue::Type::STRING);
312 webHapValue->SetString(webJSValue->GetString());
313 break;
314 case WebJSValue::Type::BINARY:
315 webHapValue->SetType(NWebHapValue::Type::BINARY);
316 webHapValue->SetBinary(webJSValue->GetBinaryValueSize(), webJSValue->GetBinaryValue());
317 break;
318 default:
319 return false;
320 }
321 return true;
322 }
323
GetWebViewValueV2(const std::shared_ptr<WebJSValue> & webJSValue,std::shared_ptr<NWebHapValue> webHapValue)324 void GetWebViewValueV2(const std::shared_ptr<WebJSValue>& webJSValue, std::shared_ptr<NWebHapValue> webHapValue)
325 {
326 if (!webJSValue) {
327 TAG_LOGE(AceLogTag::ACE_WEB, "GetWebViewValue: webJSValue is null");
328 return;
329 }
330
331 if (!webHapValue) {
332 return;
333 }
334
335 if (GetBasicTypeWebViewValueV2(webJSValue, webHapValue)) {
336 return;
337 }
338
339 WebJSValue::Type type = webJSValue->GetType();
340 switch (type) {
341 case WebJSValue::Type::LIST: {
342 webHapValue->SetType(NWebHapValue::Type::LIST);
343 size_t length = webJSValue->GetListValueSize();
344 for (size_t i = 0; i < length; ++i) {
345 GetWebViewValueV2(
346 std::make_shared<WebJSValue>(webJSValue->GetListValue(i)), webHapValue->NewChildValue());
347 webHapValue->SaveListChildValue();
348 }
349 return;
350 }
351 case WebJSValue::Type::DICTIONARY: {
352 webHapValue->SetType(NWebHapValue::Type::DICTIONARY);
353 auto dict = webJSValue->GetDictionaryValue();
354 for (auto& item : dict) {
355 GetWebViewValueV2(std::make_shared<WebJSValue>(item.second), webHapValue->NewChildValue());
356 webHapValue->SaveDictChildValue(item.first);
357 }
358 return;
359 }
360 default:
361 LOGI("GetWebViewValue: jsvalue type not support!");
362 break;
363 }
364 }
365
GetJavaScriptResultV2(const std::vector<std::shared_ptr<NWebHapValue>> & args,const std::string & method,const std::string & objectName,int32_t routingId,int32_t objectId,std::shared_ptr<NWebHapValue> result)366 void WebJavaScriptResultCallBack::GetJavaScriptResultV2(const std::vector<std::shared_ptr<NWebHapValue>>& args,
367 const std::string& method, const std::string& objectName, int32_t routingId, int32_t objectId,
368 std::shared_ptr<NWebHapValue> result)
369 {
370 // webcontroller not support object, so the object_id and routing_id param is
371 // not used
372 (void)objectId;
373 (void)routingId;
374
375 GetWebViewValueV2(GetJavaScriptResult(GetWebJSValueV2(args), method, objectName), result);
376 }
377
GetJavaScriptResultFlowbufV2(const std::vector<std::shared_ptr<NWebHapValue>> & args,const std::string & method,const std::string & objectName,int fd,int32_t routingId,int32_t objectId,std::shared_ptr<NWebHapValue> result)378 void WebJavaScriptResultCallBack::GetJavaScriptResultFlowbufV2(const std::vector<std::shared_ptr<NWebHapValue>>& args,
379 const std::string& method, const std::string& objectName, int fd, int32_t routingId, int32_t objectId,
380 std::shared_ptr<NWebHapValue> result)
381 {
382 (void)fd;
383 (void)args;
384 (void)method;
385 (void)result;
386 (void)objectId;
387 (void)routingId;
388 (void)objectName;
389 // webcontroller not support object, so nothing to do
390 }
391
GetJavaScriptObjectMethodsV2(int32_t objectId,std::shared_ptr<NWebHapValue> result)392 void WebJavaScriptResultCallBack::GetJavaScriptObjectMethodsV2(int32_t objectId, std::shared_ptr<NWebHapValue> result)
393 {
394 (void)result;
395 (void)objectId;
396 // webcontroller not support object, so nothing to do
397 }
398
399 } // namespace OHOS::Ace
400