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 "webview_scheme_ffi.h" 17 18 #include "webview_utils.h" 19 #include "nweb_helper.h" 20 #include "nweb_init_params.h" 21 #include "web_errors.h" 22 #include "webview_log.h" 23 #include "parameters.h" 24 #include "cj_lambda.h" 25 #include "webview_utils.h" 26 #include "web_scheme_handler_request.h" 27 #include "web_scheme_handler_response_impl.h" 28 29 using namespace OHOS::FFI; 30 using namespace OHOS::NWeb; 31 32 namespace OHOS { 33 namespace Webview { 34 const int32_t MAX_HEADER_SIZE = 200; 35 extern "C" { 36 //WebHttpBodyStream FfiWebHttpBodyStreamConstructor()37 int64_t FfiWebHttpBodyStreamConstructor() 38 { 39 auto nativeWebHttpBodyStream = FFIData::Create<WebHttpBodyStreamImpl>(); 40 if (nativeWebHttpBodyStream == nullptr) { 41 WEBVIEWLOGE("new web http body stream failed"); 42 return -1; 43 } 44 return nativeWebHttpBodyStream->GetID(); 45 } 46 FfiWebHttpBodyStreaminitialize(int64_t id,int32_t * errCode)47 void FfiWebHttpBodyStreaminitialize(int64_t id, int32_t *errCode) 48 { 49 auto nativeWebHttpBodyStream = FFIData::GetData<WebHttpBodyStreamImpl>(id); 50 if (nativeWebHttpBodyStream == nullptr) { 51 *errCode = NWebError::INIT_ERROR; 52 return; 53 } 54 *errCode = nativeWebHttpBodyStream->initialize(); 55 } 56 FfiWebHttpBodyStreamRead(int32_t bufLen,int64_t id)57 int32_t FfiWebHttpBodyStreamRead(int32_t bufLen, int64_t id) 58 { 59 auto nativeWebHttpBodyStream = FFIData::GetData<WebHttpBodyStreamImpl>(id); 60 if (nativeWebHttpBodyStream == nullptr) { 61 return NWebError::INIT_ERROR; 62 } 63 if (bufLen <= 0) { 64 return NWebError::PARAM_CHECK_ERROR; 65 } 66 nativeWebHttpBodyStream->Read(bufLen); 67 return NWebError::NO_ERROR; 68 } 69 FfiWebHttpBodyStreamIsChunked(int64_t id,int32_t * errCode)70 bool FfiWebHttpBodyStreamIsChunked(int64_t id, int32_t *errCode) 71 { 72 auto nativeWebHttpBodyStream = FFIData::GetData<WebHttpBodyStreamImpl>(id); 73 if (nativeWebHttpBodyStream == nullptr) { 74 *errCode = NWebError::INIT_ERROR; 75 return false; 76 } 77 bool ischunked = nativeWebHttpBodyStream->IsChunked(); 78 *errCode = NWebError::NO_ERROR; 79 return ischunked; 80 } 81 FfiWebHttpBodyStreamIsEof(int64_t id,int32_t * errCode)82 bool FfiWebHttpBodyStreamIsEof(int64_t id, int32_t *errCode) 83 { 84 auto nativeWebHttpBodyStream = FFIData::GetData<WebHttpBodyStreamImpl>(id); 85 if (nativeWebHttpBodyStream == nullptr) { 86 *errCode = NWebError::INIT_ERROR; 87 return false; 88 } 89 bool isEof = nativeWebHttpBodyStream->IsEof(); 90 *errCode = NWebError::NO_ERROR; 91 return isEof; 92 } 93 FfiWebHttpBodyStreamIsInMemory(int64_t id,int32_t * errCode)94 bool FfiWebHttpBodyStreamIsInMemory(int64_t id, int32_t *errCode) 95 { 96 auto nativeWebHttpBodyStream = FFIData::GetData<WebHttpBodyStreamImpl>(id); 97 if (nativeWebHttpBodyStream == nullptr) { 98 *errCode = NWebError::INIT_ERROR; 99 return false; 100 } 101 bool isInMemory = nativeWebHttpBodyStream->IsInMemory(); 102 *errCode = NWebError::NO_ERROR; 103 return isInMemory; 104 } 105 FfiWebHttpBodyStreamGetPostion(int64_t id,int32_t * errCode)106 uint64_t FfiWebHttpBodyStreamGetPostion(int64_t id, int32_t *errCode) 107 { 108 auto nativeWebHttpBodyStream = FFIData::GetData<WebHttpBodyStreamImpl>(id); 109 if (nativeWebHttpBodyStream == nullptr) { 110 *errCode = NWebError::INIT_ERROR; 111 return -1; 112 } 113 int64_t postion = static_cast<int64_t>(nativeWebHttpBodyStream->GetPostion()); 114 *errCode = NWebError::NO_ERROR; 115 return postion; 116 } 117 FfiWebHttpBodyStreamGetSize(int64_t id,int32_t * errCode)118 uint64_t FfiWebHttpBodyStreamGetSize(int64_t id, int32_t *errCode) 119 { 120 auto nativeWebHttpBodyStream = FFIData::GetData<WebHttpBodyStreamImpl>(id); 121 if (nativeWebHttpBodyStream == nullptr) { 122 *errCode = NWebError::INIT_ERROR; 123 return -1; 124 } 125 int64_t size = static_cast<int64_t>(nativeWebHttpBodyStream->GetSize()); 126 *errCode = NWebError::NO_ERROR; 127 return size; 128 } 129 130 //WebSchemeHandlerRequest FfiWebSchemeHandlerRequestConstructor()131 int64_t FfiWebSchemeHandlerRequestConstructor() 132 { 133 auto nativeWebSchemeHandlerRequest = FFIData::Create<WebSchemeHandlerRequestImpl>(); 134 if (nativeWebSchemeHandlerRequest == nullptr) { 135 WEBVIEWLOGE("new Web Scheme Handler Request failed"); 136 return -1; 137 } 138 return nativeWebSchemeHandlerRequest->GetID(); 139 } 140 FfiWebSchemeHandlerRequestGetRequestResourceType(int64_t id,int32_t * errCode)141 int32_t FfiWebSchemeHandlerRequestGetRequestResourceType(int64_t id, int32_t *errCode) 142 { 143 auto nativeWebSchemeHandlerRequest = FFIData::GetData<WebSchemeHandlerRequestImpl>(id); 144 if (nativeWebSchemeHandlerRequest == nullptr) { 145 *errCode = NWebError::INIT_ERROR; 146 return -1; 147 } 148 int32_t requestResourceType = nativeWebSchemeHandlerRequest->GetRequestResourceType(); 149 *errCode = NWebError::NO_ERROR; 150 return requestResourceType; 151 } 152 FfiWebSchemeHandlerRequestHasGesture(int64_t id,int32_t * errCode)153 bool FfiWebSchemeHandlerRequestHasGesture(int64_t id, int32_t *errCode) 154 { 155 auto nativeWebSchemeHandlerRequest = FFIData::GetData<WebSchemeHandlerRequestImpl>(id); 156 if (nativeWebSchemeHandlerRequest == nullptr) { 157 *errCode = NWebError::INIT_ERROR; 158 return false; 159 } 160 bool hasGesture = nativeWebSchemeHandlerRequest->HasGesture(); 161 *errCode = NWebError::NO_ERROR; 162 return hasGesture; 163 } 164 FfiWebSchemeHandlerRequestIsMainFrame(int64_t id,int32_t * errCode)165 bool FfiWebSchemeHandlerRequestIsMainFrame(int64_t id, int32_t *errCode) 166 { 167 auto nativeWebSchemeHandlerRequest = FFIData::GetData<WebSchemeHandlerRequestImpl>(id); 168 if (nativeWebSchemeHandlerRequest == nullptr) { 169 *errCode = NWebError::INIT_ERROR; 170 return false; 171 } 172 bool isMainFrame = nativeWebSchemeHandlerRequest->IsMainFrame(); 173 *errCode = NWebError::NO_ERROR; 174 return isMainFrame; 175 } 176 FfiWebSchemeHandlerRequestIsRedirect(int64_t id,int32_t * errCode)177 bool FfiWebSchemeHandlerRequestIsRedirect(int64_t id, int32_t *errCode) 178 { 179 auto nativeWebSchemeHandlerRequest = FFIData::GetData<WebSchemeHandlerRequestImpl>(id); 180 if (nativeWebSchemeHandlerRequest == nullptr) { 181 *errCode = NWebError::INIT_ERROR; 182 return false; 183 } 184 bool isRedirect = nativeWebSchemeHandlerRequest->IsRedirect(); 185 *errCode = NWebError::NO_ERROR; 186 return isRedirect; 187 } 188 FfiWebSchemeHandlerRequestGetRequestUrl(int64_t id)189 RetDataCString FfiWebSchemeHandlerRequestGetRequestUrl(int64_t id) 190 { 191 RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr }; 192 auto nativeWebSchemeHandlerRequest = FFIData::GetData<WebSchemeHandlerRequestImpl>(id); 193 if (nativeWebSchemeHandlerRequest == nullptr) { 194 return ret; 195 } 196 std::string requestUrl = nativeWebSchemeHandlerRequest->GetRequestUrl(); 197 ret.code = NWebError::NO_ERROR; 198 ret.data = MallocCString(requestUrl); 199 return ret; 200 } 201 FfiWebSchemeHandlerRequestGetMethod(int64_t id)202 RetDataCString FfiWebSchemeHandlerRequestGetMethod(int64_t id) 203 { 204 RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr }; 205 auto nativeWebSchemeHandlerRequest = FFIData::GetData<WebSchemeHandlerRequestImpl>(id); 206 if (nativeWebSchemeHandlerRequest == nullptr) { 207 return ret; 208 } 209 std::string method = nativeWebSchemeHandlerRequest->GetMethod(); 210 ret.code = NWebError::NO_ERROR; 211 ret.data = MallocCString(method); 212 return ret; 213 } 214 FfiWebSchemeHandlerRequestGetReferrer(int64_t id)215 RetDataCString FfiWebSchemeHandlerRequestGetReferrer(int64_t id) 216 { 217 RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr }; 218 auto nativeWebSchemeHandlerRequest = FFIData::GetData<WebSchemeHandlerRequestImpl>(id); 219 if (nativeWebSchemeHandlerRequest == nullptr) { 220 return ret; 221 } 222 std::string referrer = nativeWebSchemeHandlerRequest->GetReferrer(); 223 ret.code = NWebError::NO_ERROR; 224 ret.data = MallocCString(referrer); 225 return ret; 226 } 227 FfiWebSchemeHandlerRequestGetFrameUrl(int64_t id)228 RetDataCString FfiWebSchemeHandlerRequestGetFrameUrl(int64_t id) 229 { 230 RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr }; 231 auto nativeWebSchemeHandlerRequest = FFIData::GetData<WebSchemeHandlerRequestImpl>(id); 232 if (nativeWebSchemeHandlerRequest == nullptr) { 233 return ret; 234 } 235 std::string frameUrl = nativeWebSchemeHandlerRequest->GetFrameUrl(); 236 ret.code = NWebError::NO_ERROR; 237 ret.data = MallocCString(frameUrl); 238 return ret; 239 } 240 FfiWebSchemeHandlerRequestGetHeader(int64_t id,int32_t * errCode)241 ArrWebHeader FfiWebSchemeHandlerRequestGetHeader(int64_t id, int32_t *errCode) 242 { 243 ArrWebHeader ret = { nullptr, 0 }; 244 auto nativeWebSchemeHandlerRequest = FFIData::GetData<WebSchemeHandlerRequestImpl>(id); 245 if (nativeWebSchemeHandlerRequest == nullptr) { 246 *errCode = NWebError::INIT_ERROR; 247 return ret; 248 } 249 std::vector<std::pair<std::string, std::string>> header = nativeWebSchemeHandlerRequest->GetHeader(); 250 *errCode = NWebError::NO_ERROR; 251 size_t headerSize = header.size(); 252 if (header.empty() || headerSize > MAX_HEADER_SIZE) { 253 return ret; 254 } 255 ret.size = headerSize; 256 ret.head = new RetWebHeader[headerSize]; 257 for (size_t index = 0; index < headerSize; index++) { 258 ret.head[index].headerKey = MallocCString(header[index].first.c_str()); 259 ret.head[index].headerValue = MallocCString(header[index].second.c_str()); 260 } 261 return ret; 262 } 263 FfiWebSchemeHandlerRequestGetHttpBodyStream(int64_t id,int32_t * errCode)264 int64_t FfiWebSchemeHandlerRequestGetHttpBodyStream(int64_t id, int32_t *errCode) 265 { 266 auto nativeWebSchemeHandlerRequest = FFIData::GetData<WebSchemeHandlerRequestImpl>(id); 267 if (nativeWebSchemeHandlerRequest == nullptr) { 268 *errCode = NWebError::INIT_ERROR; 269 return -1; 270 } 271 ArkWeb_HttpBodyStream* arkWebPostStream = nativeWebSchemeHandlerRequest->GetHttpBodyStream(); 272 if (!arkWebPostStream) { 273 *errCode = NWebError::INIT_ERROR; 274 return -1; 275 } 276 auto nativeWebHttpBodyStream = FFIData::Create<WebHttpBodyStreamImpl>(arkWebPostStream); 277 if (nativeWebHttpBodyStream == nullptr) { 278 *errCode = NWebError::INIT_ERROR; 279 WEBVIEWLOGE("new WebHttpBodyStream failed"); 280 return -1; 281 } 282 *errCode = NWebError::NO_ERROR; 283 return nativeWebHttpBodyStream->GetID(); 284 } 285 286 // WebResourceHandler FfiWebResourceHandlerConstructor()287 int64_t FfiWebResourceHandlerConstructor() 288 { 289 auto nativeWebResourceHandler = FFIData::Create<WebResourceHandlerImpl>(); 290 if (nativeWebResourceHandler == nullptr) { 291 WEBVIEWLOGE("new Web Resource Handler failed"); 292 return -1; 293 } 294 return nativeWebResourceHandler->GetID(); 295 } 296 FfiWebResourceHandlerDidReceiveResponse(int64_t id,int32_t * errCode,int64_t responceid)297 void FfiWebResourceHandlerDidReceiveResponse(int64_t id, int32_t *errCode, int64_t responceid) 298 { 299 auto nativeWebResourceHandler = FFIData::GetData<WebResourceHandlerImpl>(id); 300 if (nativeWebResourceHandler == nullptr) { 301 *errCode = NWebError::INIT_ERROR; 302 return; 303 } 304 auto nativeWebSchemeHandlerResponse = FFIData::GetData<WebSchemeHandlerResponseImpl>(responceid); 305 if (nativeWebSchemeHandlerResponse == nullptr) { 306 *errCode = NWebError::INIT_ERROR; 307 return; 308 } 309 int32_t ret = nativeWebResourceHandler->DidReceiveResponse( 310 nativeWebSchemeHandlerResponse->GetArkWebResponse()); 311 if (ret != 0) { 312 *errCode = NWebError::RESOURCE_HANDLER_INVALID; 313 } 314 return; 315 } 316 FfiWebResourceHandlerDidReceiveResponseBody(int64_t id,int32_t * errCode,CArrUI8 buffer,int64_t buflen)317 void FfiWebResourceHandlerDidReceiveResponseBody( 318 int64_t id, int32_t *errCode, CArrUI8 buffer, int64_t buflen) 319 { 320 auto nativeWebResourceHandler = FFIData::GetData<WebResourceHandlerImpl>(id); 321 if (nativeWebResourceHandler == nullptr) { 322 *errCode = NWebError::INIT_ERROR; 323 return; 324 } 325 int32_t ret = nativeWebResourceHandler->DidReceiveResponseBody( 326 buffer.head, static_cast<int64_t>(buflen)); 327 if (ret != 0) { 328 *errCode = NWebError::RESOURCE_HANDLER_INVALID; 329 } 330 return; 331 } 332 FfiWebResourceHandlerDidFinish(int64_t id,int32_t * errCode)333 void FfiWebResourceHandlerDidFinish(int64_t id, int32_t *errCode) 334 { 335 auto nativeWebResourceHandler = FFIData::GetData<WebResourceHandlerImpl>(id); 336 if (nativeWebResourceHandler == nullptr) { 337 *errCode = NWebError::INIT_ERROR; 338 return; 339 } 340 int32_t ret = nativeWebResourceHandler->DidFinish(); 341 if (ret != 0) { 342 *errCode = NWebError::RESOURCE_HANDLER_INVALID; 343 } 344 return; 345 } 346 FfiWebResourceHandlerDidFail(int64_t id,int32_t * errCode,int32_t errorcode)347 void FfiWebResourceHandlerDidFail(int64_t id, int32_t *errCode, int32_t errorcode) 348 { 349 auto nativeWebResourceHandler = FFIData::GetData<WebResourceHandlerImpl>(id); 350 if (nativeWebResourceHandler == nullptr) { 351 *errCode = NWebError::INIT_ERROR; 352 return; 353 } 354 int32_t ret = nativeWebResourceHandler->DidFailWithError( 355 static_cast<ArkWeb_NetError>(errorcode)); 356 if (ret != 0) { 357 *errCode = NWebError::RESOURCE_HANDLER_INVALID; 358 } 359 return; 360 } 361 362 // WebSchemeHandler FfiWebSchemeHandlerConstructor()363 int64_t FfiWebSchemeHandlerConstructor() 364 { 365 auto nativeWebSchemeHandler = FFIData::Create<WebSchemeHandlerImpl>(); 366 if (nativeWebSchemeHandler == nullptr) { 367 WEBVIEWLOGE("new Web Scheme Handler failed"); 368 return -1; 369 } 370 return nativeWebSchemeHandler->GetID(); 371 } 372 FfiWebSchemeHandlerOnRequestStart(int64_t id,bool (* callback)(int64_t,int64_t))373 void FfiWebSchemeHandlerOnRequestStart(int64_t id, bool (*callback)(int64_t, int64_t)) 374 { 375 auto nativeWebSchemeHandlerImpl = FFIData::GetData<WebSchemeHandlerImpl>(id); 376 if (!nativeWebSchemeHandlerImpl) { 377 WEBVIEWLOGE("[DOWNLOAD] WebSchemeHandler null"); 378 return; 379 } 380 nativeWebSchemeHandlerImpl->PutRequestStart(CJLambda::Create(callback)); 381 } 382 FfiWebSchemeHandlerOnRequestStop(int64_t id,void (* callback)(int64_t))383 void FfiWebSchemeHandlerOnRequestStop(int64_t id, void (*callback)(int64_t)) 384 { 385 auto nativeWebSchemeHandlerImpl = FFIData::GetData<WebSchemeHandlerImpl>(id); 386 if (!nativeWebSchemeHandlerImpl) { 387 WEBVIEWLOGE("[DOWNLOAD] WebSchemeHandler is null"); 388 return; 389 } 390 nativeWebSchemeHandlerImpl->PutRequestStop(CJLambda::Create(callback)); 391 } 392 } 393 } 394 }