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 #include "base/log/log.h"
20 #include "core/common/container.h"
21 #include "core/common/container_scope.h"
22 #include "core/components/web/resource/web_javascript_value.h"
23 
24 namespace OHOS::Ace {
25 using namespace OHOS::Ace::Framework;
26 using namespace OHOS::NWeb;
27 
GetWebJSValueHelper(std::shared_ptr<NWebValue> argument)28 std::shared_ptr<WebJSValue> GetWebJSValueHelper(std::shared_ptr<NWebValue> argument)
29 {
30     if (!argument) {
31         TAG_LOGE(AceLogTag::ACE_WEB, "GetWebJSValueHelper: argument is null");
32         return std::make_shared<WebJSValue>();
33     }
34     switch (argument->GetType()) {
35         case NWebValue::Type::INTEGER:
36             return std::make_shared<WebJSValue>(argument->GetInt());
37         case NWebValue::Type::DOUBLE:
38             return std::make_shared<WebJSValue>(argument->GetDouble());
39         case NWebValue::Type::BOOLEAN:
40             return std::make_shared<WebJSValue>(argument->GetBoolean());
41         case NWebValue::Type::STRING:
42             return std::make_shared<WebJSValue>(argument->GetString());
43         case NWebValue::Type::LIST: {
44             size_t length = argument->GetListValueSize();
45             std::vector<WebJSValue> vec;
46             for (size_t i = 0; i < length; ++i) {
47                 auto nPtr = std::make_shared<NWebValue>(argument->GetListValue(i));
48                 vec.push_back(*GetWebJSValueHelper(nPtr));
49             }
50             return std::make_shared<WebJSValue>(vec);
51         }
52         case NWebValue::Type::DICTIONARY: {
53             std::map<std::string, WebJSValue> map;
54             auto dict = argument->GetDictionaryValue();
55             for (auto& item : dict) {
56                 auto nPtr = std::make_shared<NWebValue>(item.second);
57                 map[item.first] = *GetWebJSValueHelper(nPtr);
58             }
59             return std::make_shared<WebJSValue>(map);
60         }
61         case NWebValue::Type::BINARY: {
62             auto size = argument->GetBinaryValueSize();
63             auto buff = argument->GetBinaryValue();
64             return std::make_shared<WebJSValue>(buff, size);
65         }
66         case NWebValue::Type::NONE:
67             return std::make_shared<WebJSValue>();
68         default:
69             LOGI("GetWebJSValueHelper: jsvalue type not support!");
70             break;
71     }
72     return std::make_shared<WebJSValue>();
73 }
74 
GetWebJSValue(const std::vector<std::shared_ptr<NWebValue>> & args)75 std::vector<std::shared_ptr<WebJSValue>> GetWebJSValue(const std::vector<std::shared_ptr<NWebValue>>& args)
76 {
77     std::vector<std::shared_ptr<WebJSValue>> webJSValues;
78     for (auto value : args) {
79         if (value == nullptr) {
80             continue;
81         }
82         webJSValues.push_back(GetWebJSValueHelper(value));
83     }
84     return webJSValues;
85 }
86 
GetBasicTypeWebViewValue(const std::shared_ptr<WebJSValue> & webJSValue,std::shared_ptr<NWebValue> & webViewValue)87 bool GetBasicTypeWebViewValue(const std::shared_ptr<WebJSValue>& webJSValue, std::shared_ptr<NWebValue>& webViewValue)
88 {
89     WebJSValue::Type type = webJSValue->GetType();
90     switch (type) {
91         case WebJSValue::Type::INTEGER:
92             webViewValue->SetType(NWebValue::Type::INTEGER);
93             webViewValue->SetInt(webJSValue->GetInt());
94             break;
95         case WebJSValue::Type::DOUBLE:
96             webViewValue->SetType(NWebValue::Type::DOUBLE);
97             webViewValue->SetDouble(webJSValue->GetDouble());
98             break;
99         case WebJSValue::Type::BOOLEAN:
100             webViewValue->SetType(NWebValue::Type::BOOLEAN);
101             webViewValue->SetBoolean(webJSValue->GetBoolean());
102             break;
103         case WebJSValue::Type::STRING:
104             webViewValue->SetType(NWebValue::Type::STRING);
105             webViewValue->SetString(webJSValue->GetString());
106             break;
107         default:
108             return false;
109     }
110     return true;
111 }
112 
GetWebViewValue(const std::shared_ptr<WebJSValue> & webJSValue)113 std::shared_ptr<NWebValue> GetWebViewValue(const std::shared_ptr<WebJSValue>& webJSValue)
114 {
115     if (!webJSValue) {
116         TAG_LOGE(AceLogTag::ACE_WEB, "GetWebViewValue: webJSValue is null");
117         return std::make_shared<NWebValue>(NWebValue::Type::NONE);
118     }
119     std::shared_ptr<NWebValue> webViewValue = std::make_shared<NWebValue>(NWebValue::Type::NONE);
120     WebJSValue::Type type = webJSValue->GetType();
121     if (GetBasicTypeWebViewValue(webJSValue, webViewValue)) {
122         return webViewValue;
123     }
124     switch (type) {
125         case WebJSValue::Type::LIST: {
126             size_t length = webJSValue->GetListValueSize();
127             std::vector<NWebValue> vec;
128             for (size_t i = 0; i < length; ++i) {
129                 auto nPtr = std::make_shared<WebJSValue>(webJSValue->GetListValue(i));
130                 vec.push_back(*GetWebViewValue(nPtr));
131             }
132             return std::make_shared<NWebValue>(vec);
133         }
134         case WebJSValue::Type::DICTIONARY: {
135             std::map<std::string, NWebValue> map;
136             auto dict = webJSValue->GetDictionaryValue();
137             for (auto& item : dict) {
138                 auto nPtr = std::make_shared<WebJSValue>(item.second);
139                 map[item.first] = *GetWebViewValue(nPtr);
140             }
141             return std::make_shared<NWebValue>(map);
142         }
143         case WebJSValue::Type::BINARY: {
144             auto size = webJSValue->GetBinaryValueSize();
145             auto buff = webJSValue->GetBinaryValue();
146             return std::make_shared<NWebValue>(buff, size);
147         }
148         case WebJSValue::Type::NONE:
149             break;
150         default:
151             LOGI("GetWebViewValue: jsvalue type not support!");
152             break;
153     }
154     return webViewValue;
155 }
156 
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)157 std::shared_ptr<NWebValue> WebJavaScriptResultCallBack::GetJavaScriptResult(
158     std::vector<std::shared_ptr<NWebValue>> args, const std::string& method, const std::string& object_name,
159     int32_t routing_id, int32_t object_id)
160 {
161     // webcontroller not support object, so the object_id and routing_id param is
162     // not used
163     (void)object_id;
164     (void)routing_id;
165     auto delegate = webDelegate_.Upgrade();
166     CHECK_NULL_RETURN(delegate, std::make_shared<NWebValue>(NWebValue::Type::NONE));
167     ContainerScope scope(delegate->GetInstanceId());
168     std::shared_ptr<WebJSValue> result;
169     auto jsArgs = GetWebJSValue(args);
170 
171     auto task = Container::CurrentTaskExecutor();
172     if (task == nullptr) {
173         LOGW("can't get task executor");
174         return std::make_shared<NWebValue>(NWebValue::Type::NONE);
175     }
176 
177     task->PostSyncTask(
178         [webJSCallBack = this, object_name, method, jsArgs, &result] {
179             if (webJSCallBack->javaScriptCallBackImpl_) {
180                 result = webJSCallBack->javaScriptCallBackImpl_(object_name, method, jsArgs);
181             }
182         },
183         OHOS::Ace::TaskExecutor::TaskType::JS, "ArkUIWebGetJavaScriptResult");
184 
185     return GetWebViewValue(result);
186 }
187 
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)188 std::shared_ptr<NWebValue> WebJavaScriptResultCallBack::GetJavaScriptResultFlowbuf(
189     std::vector<std::shared_ptr<NWebValue>> args, const std::string& method, const std::string& object_name,
190     int fd, int32_t routing_id, int32_t object_id)
191 {
192     // webcontroller not support object
193     // not supported
194     (void)object_id;
195     (void)routing_id;
196     LOGE("Flowbuf is not supported on the decrepted Webcontroller, use Webviewcontroller instead.");
197     return std::make_shared<NWebValue>(NWebValue::Type::NONE);
198 }
199 
HasJavaScriptObjectMethods(int32_t object_id,const std::string & method_name)200 bool WebJavaScriptResultCallBack::HasJavaScriptObjectMethods(int32_t object_id, const std::string& method_name)
201 {
202     (void)object_id;
203     (void)method_name;
204     // webcontroller not support object, so nothing to do
205     return false;
206 }
207 
GetJavaScriptObjectMethods(int32_t object_id)208 std::shared_ptr<NWebValue> WebJavaScriptResultCallBack::GetJavaScriptObjectMethods(int32_t object_id)
209 {
210     (void)object_id;
211     // webcontroller not support object, so nothing to do
212     return std::make_shared<NWebValue>();
213 }
214 
RemoveJavaScriptObjectHolder(int32_t holder,int32_t object_id)215 void WebJavaScriptResultCallBack::RemoveJavaScriptObjectHolder(int32_t holder, int32_t object_id)
216 {
217     (void)holder;
218     (void)object_id;
219     // webcontroller not support object, so nothing to do
220 }
221 
RemoveTransientJavaScriptObject()222 void WebJavaScriptResultCallBack::RemoveTransientJavaScriptObject()
223 {
224     // webcontroller not support object, so nothing to do
225 }
226 } // namespace OHOS::Ace
227