diff --git a/interfaces/kits/ani/webview/BUILD.gn b/interfaces/kits/ani/webview/BUILD.gn index 03803aa4a0f24e5b6e7071c4331a0d2de6cb7d7c..db0f3950b9599fe2e75a56e404c9c158226fcdd0 100644 --- a/interfaces/kits/ani/webview/BUILD.gn +++ b/interfaces/kits/ani/webview/BUILD.gn @@ -51,8 +51,8 @@ ohos_shared_library("webview_native") { #"native/webviewcontroller/web_download_item.h", #"native/webviewcontroller/web_download_manager.cpp", #"native/webviewcontroller/web_download_manager.h", - #"native/webviewcontroller/web_scheme_handler_request.cpp", - #"native/webviewcontroller/web_scheme_handler_request.h", + "native/webviewcontroller/web_scheme_handler_request.cpp", + "native/webviewcontroller/web_scheme_handler_request.h", "native/webviewcontroller/webview_controller.cpp", "native/webviewcontroller/webview_hasimage_callback.cpp", "native/webviewcontroller/webview_javascript_execute_callback.cpp", @@ -104,20 +104,30 @@ ohos_shared_library("webview_ani") { "./src/webadsblockmanager", "./src/webdatabase", "./src/webviewcontroller", + "./src/webfunction", ] sources = [ "./src/common/ani_business_error.cpp", "./src/common/ani_parse_utils.cpp", + "./src/common/ani_parse_utils.h", "./src/webstorage/ani_web_storage.cpp", "./src/webadsblockmanager/ani_web_adsblock_manager.h", "./src/webadsblockmanager/ani_web_adsblock_manager.cpp", "./src/webdatabase/ani_web_data_base.cpp", "./src/webdatabase/ani_geolocation_permission.cpp", "./src/webviewcontroller/ani_webview_controller.cpp", + "./src/webviewcontroller/ani_webview_controller.h", "./src/webviewcontroller/web_scheme_handler_response.cpp", "./src/webviewcontroller/web_scheme_handler_response.h", + "./src/webviewcontroller/ani_web_scheme_handler_request.cpp", + "./src/webviewcontroller/ani_web_scheme_handler_request.h", + "./src/webviewcontroller/ani_web_scheme_handler_resource.cpp", + "./src/webviewcontroller/ani_web_scheme_handler_resource.h", + "./src/webviewcontroller/ani_web_scheme_handler.cpp", + "./src/webviewcontroller/ani_web_scheme_handler.h", "./src/webviewcontroller/ani_web_scheme_handler_response.cpp", + "./src/webviewcontroller/ani_web_scheme_handler_response.h", "./src/webviewcontroller/ani_web_download_delegate.cpp", "./src/webviewcontroller/ani_web_download_item.cpp", "./src/webviewcontroller/ani_web_download_manager.cpp", @@ -136,7 +146,8 @@ ohos_shared_library("webview_ani") { "./src/proxycontroller/proxy_config.cpp", "./src/proxycontroller/proxy_config.h", "./src/proxycontroller/proxy_rule.cpp", - "./src/proxycontroller/proxy_rule.h", + "./src/webfunction/ani_webview_function.h", + "./src/webfunction/ani_webview_function.cpp", "./src/sts_web_webview.cpp", ] diff --git a/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets b/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets index 08960c9fe5939d4c04923e9e49221c5e9cc6e246..80cbf317996a01e7ef76fed72095ba68a47d3016 100644 --- a/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets +++ b/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets @@ -35,6 +35,11 @@ let destroyRegister = new FinalizationRegistry(CleanerCallback) let unregisterToken = new object() export default namespace webview { + static { + loadLibrary("webview_ani.z"); + } + export native function once(type: string, callback: Callback): void; + export enum ScrollType { EVENT } @@ -157,6 +162,29 @@ export default namespace webview { AUDIO = 1 } + export enum WebResourceType{ + MAIN_FRAME = 0, + SUB_FRAME = 1, + STYLE_SHEET = 2, + SCRIPT = 3, + IMAGE = 4, + FONT_RESOURCE = 5, + SUB_RESOURCE = 6, + OBJECT = 7, + MEDIA = 8, + WORKER = 9, + SHARED_WORKER = 10, + PREFETCH = 11, + FAVICON = 12, + XHR = 13, + PING = 14, + SERVICE_WORKER = 15, + CSP_REPORT = 16, + PLUGIN_RESOURCE = 17, + NAVIGATION_PRELOAD_MAIN_FRAME = 19, + NAVIGATION_PRELOAD_SUB_FRAME = 20, + } + export enum SourceType { URL = 0, MSE = 1 @@ -197,11 +225,16 @@ export default namespace webview { method: string; formData: string; } - + export interface WebHeader { headerKey: string; headerValue: string; } + + export class GetHeaderWebHeader implements WebHeader { + headerKey: string; + headerValue: string; + } export interface ScrollOffset { x: double; @@ -573,7 +606,12 @@ export default namespace webview { native removeCache(clearRom: boolean): void; native setNetworkAvailable(enable: boolean): void; native isIncognitoMode(): boolean; - native serializeWebState(): Uint8Array; + native serializeWebStateInternal(): ArrayBuffer; + serializeWebState(): Uint8Array{ + let buffer = this.serializeWebStateInternal(); + let uint8Array = new Uint8Array(buffer); + return uint8Array; + } native static trimMemoryByPressureLevel(level: PressureLevel): void; native setPathAllowingUniversalAccess(pathList: Array): void; native onCreateNativeMediaPlayer(callback: (handler: NativeMediaPlayerHandler, mediaInfo: MediaInfo) => NativeMediaPlayerBridge): void; @@ -660,8 +698,95 @@ export default namespace webview { * @since 20 */ native getUrl(): string; + native setMimeType(type: string): void; + native getMimeType(): string; + native setEncoding(encoding: string): void; + native getEncoding(): string; + native setStatusText(text: string): void; + native getStatusText(): string; + native setStatus(code: number): void; + native getStatus(): number; + native setHeaderByName(name: string, value: string, overwrite: boolean): void; + native getHeaderByName(name: string): string; } + + export class WebSchemeHandler { + private nativePtr: long = 0; + private cleaner?: Cleaner; + registerCleaner(ptr: long): void { + this.cleaner = new Cleaner(ptr, "WebSchemeHandler") + destroyRegister.register(this, this.cleaner!, unregisterToken); + } + unregisterCleaner(): void { + destroyRegister.unregister(unregisterToken); + } + + bindNativePtr(ptr: long): void { + if (this.nativePtr == 0) { + this.nativePtr = ptr; + this.registerCleaner(this.nativePtr) + } + } + + native constructor(); + native onRequestStart(callback: (request: WebSchemeHandlerRequest, handler: WebResourceHandler) => boolean): void; + } + + export class WebSchemeHandlerRequest { + private nativePtr: long = 0; + private cleaner?: Cleaner; + + registerCleaner(ptr: long): void { + this.cleaner = new Cleaner(ptr, "WebSchemeHandlerRequest") + destroyRegister.register(this, this.cleaner!, unregisterToken); + } + unregisterCleaner(): void { + destroyRegister.unregister(unregisterToken); + } + + bindNativePtr(ptr: long): void { + if (this.nativePtr == 0) { + this.nativePtr = ptr; + this.registerCleaner(this.nativePtr) + } + } + + native constructor(); + native hasGesture(): boolean; + native getReferrer(): string; + native getFrameUrl(): string; + native getHeader(): Array; + native getRequestResourceType(): WebResourceType; + native getRequestUrl(): string; + native isMainFrame(): boolean; + native getRequestMethod(): string; + } + + export class WebResourceHandler { + private nativePtr: long = 0; + private cleaner?: Cleaner; + + registerCleaner(ptr: long): void { + this.cleaner = new Cleaner(ptr, "WebResourceHandler") + destroyRegister.register(this, this.cleaner!, unregisterToken); + } + unregisterCleaner(): void { + destroyRegister.unregister(unregisterToken); + } + + bindNativePtr(ptr: long): void { + if (this.nativePtr == 0) { + this.nativePtr = ptr; + this.registerCleaner(this.nativePtr) + } + } + native constructor(); + + native didReceiveResponse(response: WebSchemeHandlerResponse): void; + native didFinish(): void; + } + export class WebDownloadItem { static { loadLibrary("webview_ani.z"); diff --git a/interfaces/kits/ani/webview/native/webfunction/webview_web_inited_callback.cpp b/interfaces/kits/ani/webview/native/webfunction/webview_web_inited_callback.cpp index 742e23ce2f057ddd060f8371c7091462ab39a73a..50a5bb7d12a53a8b830f9d90a8e28a24cdc25088 100644 --- a/interfaces/kits/ani/webview/native/webfunction/webview_web_inited_callback.cpp +++ b/interfaces/kits/ani/webview/native/webfunction/webview_web_inited_callback.cpp @@ -15,72 +15,79 @@ #include "webview_web_inited_callback.h" -#include "nweb_log.h" #include "uv.h" namespace OHOS::NWeb { +constexpr ani_size REFERENCES_MAX_NUMBER = 16; namespace { -void UvWebInitedCallbackThreadWoker(uv_work_t *work, int status) +void UvWebInitedCallbackThreadWoker(WebRunInitedCallbackImpl* obj) { - if (work == nullptr) { - WVLOG_E("uv work is null"); + WVLOG_I("enter UvWebInitedCallbackThreadWoker"); + if (!obj || !(obj->param_)) { + WVLOG_E("callback obj or param is nullptr"); return; } - WebInitedCallbackParam *data = reinterpret_cast(work->data); - if (data == nullptr) { - delete work; - work = nullptr; + + ani_size nr_refs = REFERENCES_MAX_NUMBER; + ani_env* env = obj->param_->GetEnv(); + if (!env) { + WVLOG_E("env is nullptr"); return; } - napi_handle_scope scope = nullptr; - napi_open_handle_scope(data->env_, &scope); - if (scope == nullptr) { - delete data; - data = nullptr; - delete work; - work = nullptr; + env->CreateLocalScope(nr_refs); + ani_status status; + if (obj->param_->webInitedCallback_) { + ani_ref fnReturnVal; + if ((status = env->FunctionalObject_Call( + static_cast(obj->param_->webInitedCallback_), 0, {}, &fnReturnVal)) != ANI_OK) { + WVLOG_E("UvWebInitedCallbackThreadWoker callback execute failed status : %{public}d", status); + return; + } else { + WVLOG_I("UvWebInitedCallbackThreadWoker callback execute success!"); + } + } else { + WVLOG_E("callback is nullptr"); + env->DestroyLocalScope(); return; } - napi_value webInitedResult = nullptr; - napi_value jsWebInitedCallback = nullptr; - napi_get_reference_value(data->env_, data->webInitedCallback_, &jsWebInitedCallback); - napi_call_function(data->env_, nullptr, jsWebInitedCallback, 0, {}, &webInitedResult); - - napi_close_handle_scope(data->env_, scope); - delete data; - data = nullptr; - delete work; - work = nullptr; + env->DestroyLocalScope(); + if (obj->param_) { + delete obj->param_; + } + return; } } // namespace -void WebRunInitedCallbackImpl::RunInitedCallback() +WebInitedCallbackParam::WebInitedCallbackParam(ani_env* env, ani_ref callback) { - uv_loop_s *loop = nullptr; - uv_work_t *work = nullptr; - napi_get_uv_event_loop(param_->env_, &loop); - - if (loop == nullptr) { - WVLOG_E("get uv event loop failed"); + WVLOG_I("enter WebInitedCallbackParam"); + if (!env || !callback) { + WVLOG_E("env or callback is nullptr"); return; } - work = new (std::nothrow) uv_work_t; - if (work == nullptr) { - WVLOG_E("new uv work failed"); - return; + env->GetVM(&vm_); + env->GlobalReference_Create(callback, &webInitedCallback_); +} + +WebInitedCallbackParam::~WebInitedCallbackParam() +{ + WVLOG_I("~WebInitedCallbackParam start"); + ani_env* env = GetEnv(); + if (env && webInitedCallback_) { + env->GlobalReference_Delete(webInitedCallback_); + } else { + WVLOG_E("~WebInitedCallbackParam delete ref error"); } - work->data = reinterpret_cast(param_); - int ret = uv_queue_work_with_qos( - loop, work, [](uv_work_t* work) {}, UvWebInitedCallbackThreadWoker, uv_qos_user_initiated); - if (ret != 0) { - if (param_ != nullptr) { - delete param_; - param_ = nullptr; - } - if (work != nullptr) { - delete work; - work = nullptr; - } +} + +void WebRunInitedCallbackImpl::RunInitedCallback() +{ + WVLOG_I("enter RunInitedCallback"); + if (!param_->webInitedCallback_) { + WVLOG_I("callback is null"); + return; } + UvWebInitedCallbackThreadWoker(this); + WVLOG_I("PostTask successful!"); } -} \ No newline at end of file +} // namespace OHOS::NWeb \ No newline at end of file diff --git a/interfaces/kits/ani/webview/native/webfunction/webview_web_inited_callback.h b/interfaces/kits/ani/webview/native/webfunction/webview_web_inited_callback.h index d0b687070c6369659e51c7d536897b517062c503..3e7c3502d984e234ef7dc2ebe9067f3cb411ab41 100644 --- a/interfaces/kits/ani/webview/native/webfunction/webview_web_inited_callback.h +++ b/interfaces/kits/ani/webview/native/webfunction/webview_web_inited_callback.h @@ -18,28 +18,40 @@ #include #include +#include "ani.h" #include "napi/native_api.h" #include "napi/native_node_api.h" #include "napi_parse_utils.h" +#include "nweb_log.h" #include "nweb_value_callback.h" #include "ohos_init_web_adapter.h" - namespace OHOS::NWeb { class WebInitedCallbackParam { public: - WebInitedCallbackParam(napi_env env, napi_ref callback) : env_(env), webInitedCallback_(callback) {} - - napi_env env_; - napi_ref webInitedCallback_; + WebInitedCallbackParam(ani_env* env, ani_ref callback); + ~WebInitedCallbackParam(); + ani_env* GetEnv() + { + ani_env* env = nullptr; + if (vm_) { + vm_->GetEnv(ANI_VERSION_1, &env); + } + return env; + } + ani_vm* vm_; + ani_ref webInitedCallback_; }; class WebRunInitedCallbackImpl : public WebRunInitedCallback { public: - explicit WebRunInitedCallbackImpl(WebInitedCallbackParam *param) : param_(param) {} - ~WebRunInitedCallbackImpl() override {} + explicit WebRunInitedCallbackImpl(WebInitedCallbackParam* param) : param_(param) {} + ~WebRunInitedCallbackImpl() override + { + WVLOG_I("~WebRunInitedCallbackImpl start"); + } void RunInitedCallback() override; - WebInitedCallbackParam *param_ = nullptr; + WebInitedCallbackParam* param_ = nullptr; }; -} +} // namespace OHOS::NWeb #endif diff --git a/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.cpp b/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a9913fd6d2255c92689aeab29adaaf09fb645424 --- /dev/null +++ b/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.cpp @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "web_scheme_handler_request.h" + +#include +#include +#include + +#include "business_error.h" +#include "nweb_log.h" +#include "web_errors.h" + +namespace OHOS::NWeb { +namespace { + +bool Wrap(ani_env* env, const ani_object& object, const char* className, const ani_long& thisVar) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return false; + } + ani_status status; + ani_class cls; + if ((status = env->FindClass(className, &cls)) != ANI_OK) { + WVLOG_E("AniUtils_Wrap FindClass status: %{public}d", status); + return false; + } + ani_method innerWrapMethod; + if ((status = env->Class_FindMethod(cls, "bindNativePtr", "J:V", &innerWrapMethod)) != ANI_OK) { + WVLOG_E("AniUtils_Wrap Class_FindMethod status: %{public}d", status); + return false; + } + if ((status = env->Object_CallMethod_Void(object, innerWrapMethod, thisVar)) != ANI_OK) { + WVLOG_E("AniUtils_Wrap Object_CallMethod_Void status: %{public}d", status); + return false; + } + return true; +} + +bool CreateObjectVoid(ani_env *env, const char *className, ani_object& object) +{ + ani_class cls; + ani_status status = env->FindClass(className, &cls); + if (status != ANI_OK) { + WVLOG_E("find %{public}s class failed, status: %{public}d", className, status); + return false; + } + ani_method ctor; + if ((status = env->Class_FindMethod(cls, "", nullptr, &ctor)) != ANI_OK) { + WVLOG_E("get %{public}s ctor method failed, status: %{public}d", className, status); + return false; + } + if ((status = env->Object_New(cls, ctor, &object)) != ANI_OK) { + WVLOG_E("new %{public}s failed, status: %{public}d", className, status); + return false; + } + return true; +} + +bool ParseBoolean(ani_env* env, ani_ref ref, bool& outValue) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return false; + } + ani_class booleanClass; + ani_status status; + status = env->FindClass("Lstd/core/Boolean;", &booleanClass); + if (status != ANI_OK) { + WVLOG_E("ParseBoolean FindClass status: %{public}d", status); + return false; + } + ani_boolean isBoolean; + if (env->Object_InstanceOf(static_cast(ref), booleanClass, &isBoolean) != ANI_OK || + isBoolean != ANI_TRUE) { + WVLOG_E("ParseBoolean failed - invalid boolean type"); + return false; + } + + ani_boolean boolValue; + env->Object_CallMethodByName_Boolean(static_cast(ref), "unboxed", ":Z", &boolValue); + outValue = static_cast(boolValue); + return true; +} + +void OnRequestStart(const ArkWeb_SchemeHandler* schemeHandler, ArkWeb_ResourceRequest* resourceRequest, + const ArkWeb_ResourceHandler* resourceHandler, bool* intercept) +{ + WVLOG_I("SchemeHandler OnRequestStart"); + if (!schemeHandler) { + WVLOG_E("OnRequestStart schemeHandler is nullptr"); + return; + } + WebSchemeHandler* handler = WebSchemeHandler::GetWebSchemeHandler(schemeHandler); + if (!handler) { + WVLOG_E("GetWebSchemeHandler failed"); + return; + } + handler->RequestStart(resourceRequest, resourceHandler, intercept); +} + +void OnRequestStop(const ArkWeb_SchemeHandler* schemeHandler, const ArkWeb_ResourceRequest* resourceRequest) +{ + WVLOG_I("SchemeHandler OnRequestStop"); + if (!schemeHandler) { + WVLOG_E("OnRequestStop schemeHandler is nullptr"); + return; + } + WebSchemeHandler* handler = WebSchemeHandler::GetWebSchemeHandler(schemeHandler); + if (!handler) { + WVLOG_E("GetWebSchemeHandler failed"); + return; + } + handler->RequestStop(resourceRequest); +} +} // namespace + +WebSchemeHandlerRequest::WebSchemeHandlerRequest(ani_env* env) : env_(env) +{ + if (env_->GetVM(&vm_) != ANI_OK) { + WVLOG_E("Failed to get VM from env"); + return; + } + WVLOG_I("WebSchemeHandlerRequest::WebSchemeHandlerRequest"); +} + +WebSchemeHandlerRequest::WebSchemeHandlerRequest(ani_env* env, const ArkWeb_ResourceRequest* request) : env_(env) +{ + WVLOG_I("WebSchemeHandlerRequest::WebSchemeHandlerRequest"); + OH_ArkWebResourceRequest_GetUrl(request, &url_); + OH_ArkWebResourceRequest_GetMethod(request, &method_); + OH_ArkWebResourceRequest_GetReferrer(request, &referrer_); + isRedirect_ = OH_ArkWebResourceRequest_IsRedirect(request); + isMainFrame_ = OH_ArkWebResourceRequest_IsMainFrame(request); + hasGesture_ = OH_ArkWebResourceRequest_HasGesture(request); + OH_ArkWebResourceRequest_GetHttpBodyStream(request, &stream_); + requestResourceType_ = OH_ArkWebResourceRequest_GetResourceType(request); + OH_ArkWebResourceRequest_GetFrameUrl(request, &frameUrl_); + + ArkWeb_RequestHeaderList* arkWebHeaderlist = nullptr; + OH_ArkWebResourceRequest_GetRequestHeaders(request, &arkWebHeaderlist); + if (!arkWebHeaderlist) { + WVLOG_E("OH_ArkWebRequestHeaderList_Create failed"); + return; + } + int32_t size = OH_ArkWebRequestHeaderList_GetSize(arkWebHeaderlist); + if (size <= 0) { + WVLOG_E("OH_ArkWebRequestHeaderList_GetSize:%{public}d", size); + return; + } + for (int32_t index = 0; index < size; index++) { + char* key; + char* value; + OH_ArkWebRequestHeaderList_GetHeader(arkWebHeaderlist, index, &key, &value); + if (!key || !value) { + continue; + } + std::string strKey(key); + std::string strValue(value); + headerList_.emplace_back(std::make_pair(strKey, strValue)); + OH_ArkWeb_ReleaseString(key); + OH_ArkWeb_ReleaseString(value); + } + OH_ArkWebRequestHeaderList_Destroy(arkWebHeaderlist); +} + +WebSchemeHandlerRequest::~WebSchemeHandlerRequest() +{ + WVLOG_I("WebSchemeHandlerRequest::~WebSchemeHandlerRequest"); + OH_ArkWeb_ReleaseString(url_); + OH_ArkWeb_ReleaseString(method_); + OH_ArkWeb_ReleaseString(referrer_); +} + +char* WebSchemeHandlerRequest::GetRequestUrl() +{ + return url_; +} + +char* WebSchemeHandlerRequest::GetMethod() +{ + return method_; +} + +char* WebSchemeHandlerRequest::GetReferrer() +{ + return referrer_; +} + +bool WebSchemeHandlerRequest::IsRedirect() +{ + return isRedirect_; +} + +bool WebSchemeHandlerRequest::IsMainFrame() +{ + return isMainFrame_; +} + +bool WebSchemeHandlerRequest::HasGesture() +{ + return hasGesture_; +} + +const WebHeaderList& WebSchemeHandlerRequest::GetHeader() +{ + return headerList_; +} + +ArkWeb_HttpBodyStream* WebSchemeHandlerRequest::GetHttpBodyStream() +{ + return stream_; +} + +int32_t WebSchemeHandlerRequest::GetRequestResourceType() +{ + return requestResourceType_; +} + +char* WebSchemeHandlerRequest::GetFrameUrl() +{ + return frameUrl_; +} + +std::unordered_map WebSchemeHandler::webSchemeHandlerMap_; +std::unordered_map WebSchemeHandler::arkWebSchemeHandlerMap_; + +const ArkWeb_SchemeHandler* WebSchemeHandler::GetArkWebSchemeHandler(WebSchemeHandler* handler) +{ + return WebSchemeHandler::webSchemeHandlerMap_.find(handler) != WebSchemeHandler::webSchemeHandlerMap_.end() + ? WebSchemeHandler::webSchemeHandlerMap_[handler] + : nullptr; +} + +WebSchemeHandler* WebSchemeHandler::GetWebSchemeHandler(const ArkWeb_SchemeHandler* handler) +{ + return WebSchemeHandler::arkWebSchemeHandlerMap_.find(handler) != WebSchemeHandler::arkWebSchemeHandlerMap_.end() + ? WebSchemeHandler::arkWebSchemeHandlerMap_[handler] + : nullptr; +} + +WebSchemeHandler::WebSchemeHandler(ani_env* env) : vm_(nullptr) +{ + WVLOG_E("create WebSchemeHandler"); + if (!env) { + WVLOG_E("create WebSchemeHandler env null"); + return; + } + env_ = env; + WVLOG_E("create WebSchemeHandler"); + ArkWeb_SchemeHandler* handler; + OH_ArkWeb_CreateSchemeHandler(&handler); + if (!handler) { + WVLOG_E("create WebSchemeHandler failed"); + return; + } + onRequestStart_ = &OnRequestStart; + onRequestStop_ = &OnRequestStop; + OH_ArkWebSchemeHandler_SetOnRequestStart(handler, onRequestStart_); + OH_ArkWebSchemeHandler_SetOnRequestStop(handler, onRequestStop_); + OH_ArkWebSchemeHandler_SetFromEts(handler, true); + webSchemeHandlerMap_.insert(std::make_pair(this, handler)); + arkWebSchemeHandlerMap_.insert(std::make_pair(handler, this)); +} + +WebSchemeHandler::~WebSchemeHandler() +{ + WVLOG_I("WebSchemeHandler::~WebSchemeHandler"); + GetEnv()->GlobalReference_Delete(request_start_callback_); + GetEnv()->GlobalReference_Delete(request_stop_callback_); + ArkWeb_SchemeHandler* handler = const_cast(GetArkWebSchemeHandler(this)); + if (!handler) { + WVLOG_E("~WebSchemeHandler not found ArkWeb_SchemeHandler"); + return; + } + webSchemeHandlerMap_.erase(this); + arkWebSchemeHandlerMap_.erase(handler); + OH_ArkWeb_DestroySchemeHandler(handler); +} + +void WebSchemeHandler::RequestStart( + ArkWeb_ResourceRequest* request, const ArkWeb_ResourceHandler* ArkWeb_ResourceHandler, bool* intercept) +{ + if (vm_ == nullptr) { + WVLOG_E("WebSchemeHandler::RequestStart nil vm"); + return; + } + + ani_env* env = GetEnv(); + if (!request_start_callback_ || !request) { + WVLOG_E("WebSchemeHandler request_start_callback_ or request is null."); + return; + } + if (!env_ || !env) { + WVLOG_E("WebSchemeHandler env is null."); + return; + } + ani_size nr_refs = REFERENCES_MAX_NUMBER; + env->CreateLocalScope(nr_refs); + WebSchemeHandlerRequest* schemeHandlerRequest = new (std::nothrow) WebSchemeHandlerRequest(env, request); + if (schemeHandlerRequest == nullptr) { + WVLOG_E("RequestStart, new schemeHandlerRequest failed"); + env->DestroyLocalScope(); + return; + } + sptr resourceHandler = new (std::nothrow) WebResourceHandler(env, ArkWeb_ResourceHandler); + if (resourceHandler == nullptr) { + WVLOG_E("RequestStart, new resourceHandler failed"); + delete schemeHandlerRequest; + resourceHandler->DecStrongRef(resourceHandler); + env->DestroyLocalScope(); + return; + } + + ani_object requestObject = {}; + if (!CreateObjectVoid(env, WEB_WEBSCHEME_HANDLER_REQUEST_CLASS_NAME, requestObject)) { + WVLOG_E("[SchemeHandler] CreaterequestObject failed"); + delete schemeHandlerRequest; + resourceHandler->DecStrongRef(resourceHandler); + env->DestroyLocalScope(); + return; + } + + ani_object resourceObject = {}; + if (!CreateObjectVoid(env, WEB_RESOURCE_HANDLER_CLASS_NAME, resourceObject)) { + WVLOG_E("[SchemeHandler] CreateresourceObject Failed"); + delete schemeHandlerRequest; + resourceHandler->DecStrongRef(resourceHandler); + env->DestroyLocalScope(); + return; + } + if (OH_ArkWebResourceRequest_SetUserData(request, resourceHandler.GetRefPtr()) != 0) { + WVLOG_E("OH_ArkWebResourceRequest_SetUserData failed"); + } else { + resourceHandler->IncStrongRef(nullptr); + } + if (!Wrap(env, requestObject, WEB_WEBSCHEME_HANDLER_REQUEST_CLASS_NAME, + reinterpret_cast(schemeHandlerRequest))) { + WVLOG_E("[SchemeHandler] WebSchemeHandlerRequest wrap failed"); + delete schemeHandlerRequest; + schemeHandlerRequest = nullptr; + env->DestroyLocalScope(); + return; + } + + if (!Wrap(env, resourceObject, WEB_RESOURCE_HANDLER_CLASS_NAME, + reinterpret_cast(resourceHandler.GetRefPtr()))) { + WVLOG_E("[SchemeHandler] WebResourceHandler wrap failed"); + resourceHandler->DecStrongRef(resourceHandler); + resourceHandler = nullptr; + env->DestroyLocalScope(); + return; + } + if (requestObject == nullptr || resourceObject == nullptr) { + WVLOG_E("requestObject or resourceRequest is null"); + env->DestroyLocalScope(); + return; + } + resourceHandler->IncStrongRef(nullptr); + std::vector vec; + vec.push_back(static_cast(requestObject)); + vec.push_back(static_cast(resourceObject)); + ani_ref fnReturnVal; + ani_status status; + status = env->FunctionalObject_Call( + reinterpret_cast(request_start_callback_), vec.size(), vec.data(), &fnReturnVal); + if (status != ANI_OK) { + WVLOG_E("scheme handler call onRequestStart failed."); + } + if (!ParseBoolean(env, fnReturnVal, *intercept)) { + WVLOG_E("scheme handler onRequestStart intercept parse failed"); + *intercept = false; + } + env->DestroyLocalScope(); + if (!*intercept) { + resourceHandler->SetFinishFlag(); + resourceHandler->DecStrongRef(resourceHandler); + } +} + +void WebSchemeHandler::RequestStop(const ArkWeb_ResourceRequest* resourceRequest) +{ + WVLOG_I("WebSchemeHandler::RequestStop"); + return; +} + +void WebSchemeHandler::PutRequestStart(ani_env* env, ani_vm* vm, ani_fn_object callback) +{ + WVLOG_I("WebSchemeHandler::PutRequestStart"); + if (!vm) { + WVLOG_E("PutRequestStart vm null"); + return; + } + vm_ = vm; + ani_status status = env->GlobalReference_Create(reinterpret_cast(callback), &request_start_callback_); + if (status != ANI_OK) { + WVLOG_E("PutRequestStart create reference failed."); + } +} +void WebSchemeHandler::PutRequestStop(ani_env* env, ani_vm* vm, ani_fn_object callback) +{ + WVLOG_I("WebSchemeHandler::PutRequestStop"); + if (!vm) { + WVLOG_E("PutRequestStop vm null"); + return; + } + vm_ = vm; + ani_status status = env->GlobalReference_Create(reinterpret_cast(callback), &request_stop_callback_); + if (status != ANI_OK) { + WVLOG_E("PutRequestStop create reference failed."); + } +} + +WebResourceHandler::WebResourceHandler(ani_env* env) +{ + WVLOG_I("create WebResourceHandler"); + if (env->GetVM(&vm_) != ANI_OK) { + WVLOG_E("Failed to get VM from env"); + return; + } +} + +WebResourceHandler::WebResourceHandler(ani_env* env, const ArkWeb_ResourceHandler* handler) + : handler_(const_cast(handler)) +{ + WVLOG_E("create WebResourceHandler"); + if (env->GetVM(&vm_) != ANI_OK) { + WVLOG_E("Failed to get VM from env"); + return; + } +} + +WebResourceHandler::~WebResourceHandler() +{ + WVLOG_E("~WebResourceHandler"); +} + +int32_t WebResourceHandler::DidReceiveResponse(const ArkWeb_Response* response) +{ + if (isFinished_) { + return ArkWeb_ErrorCode::ARKWEB_ERROR_UNKNOWN; + } + return OH_ArkWebResourceHandler_DidReceiveResponse(handler_, response); +} + +int32_t WebResourceHandler::DidReceiveResponseBody(const uint8_t* buffer, int64_t buflen) +{ + if (isFinished_) { + return ArkWeb_ErrorCode::ARKWEB_ERROR_UNKNOWN; + } + return OH_ArkWebResourceHandler_DidReceiveData(handler_, buffer, buflen); +} + +int32_t WebResourceHandler::DidFinish() +{ + if (isFinished_) { + return ArkWeb_ErrorCode::ARKWEB_ERROR_UNKNOWN; + } + int32_t ret = OH_ArkWebResourceHandler_DidFinish(handler_); + if (ret == 0) { + isFinished_ = true; + } + return ret; +} + +int32_t WebResourceHandler::DidFailWithError(ArkWeb_NetError errorCode) +{ + if (isFinished_) { + return ArkWeb_ErrorCode::ARKWEB_ERROR_UNKNOWN; + } + int32_t ret = OH_ArkWebResourceHandler_DidFailWithError(handler_, errorCode); + if (ret == 0) { + isFinished_ = true; + } + return ret; +} + +void WebResourceHandler::DestoryArkWebResourceHandler() +{ + if (handler_) { + OH_ArkWebResourceHandler_Destroy(handler_); + handler_ = nullptr; + } +} + +} // namespace OHOS::NWeb \ No newline at end of file diff --git a/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.h b/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.h new file mode 100644 index 0000000000000000000000000000000000000000..793b9cdba66ac30e874746df3c50d39c592b9281 --- /dev/null +++ b/interfaces/kits/ani/webview/native/webviewcontroller/web_scheme_handler_request.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_NWEB_SCHEME_HANDLER_REQUEST_H +#define OHOS_NWEB_SCHEME_HANDLER_REQUEST_H + +#include +#include +#include + +#include "arkweb_scheme_handler.h" +#include "refbase.h" + +namespace OHOS { +namespace NWeb { +namespace { +const char* WEB_WEBSCHEME_HANDLER_CLASS_NAME = "L@ohos/web/webview/webview/WebSchemeHandler;"; +const char* WEB_WEBSCHEME_HANDLER_REQUEST_CLASS_NAME = "L@ohos/web/webview/webview/WebSchemeHandlerRequest;"; +const char* WEB_RESOURCE_HANDLER_CLASS_NAME = "L@ohos/web/webview/webview/WebResourceHandler;"; +constexpr ani_size REFERENCES_MAX_NUMBER = 16; + +// ani_vm* g_vm = nullptr; +// constexpr ani_vm* g_vm; +} // namespace +using WebHeaderList = std::vector>; +class WebSchemeHandlerRequest { +public: + explicit WebSchemeHandlerRequest(ani_env* env); + WebSchemeHandlerRequest(ani_env* env, const ArkWeb_ResourceRequest* request); + ~WebSchemeHandlerRequest(); + + char* GetRequestUrl(); + char* GetMethod(); + char* GetReferrer(); + bool IsRedirect(); + bool IsMainFrame(); + bool HasGesture(); + const WebHeaderList& GetHeader(); + ArkWeb_HttpBodyStream* GetHttpBodyStream(); + int32_t GetRequestResourceType(); + char* GetFrameUrl(); + +private: + ani_vm* vm_ = nullptr; + ani_env* env_; + char* url_ = nullptr; + char* method_ = nullptr; + char* referrer_ = nullptr; + bool isRedirect_ = false; + bool isMainFrame_ = false; + bool hasGesture_ = false; + WebHeaderList headerList_; + ArkWeb_HttpBodyStream* stream_ = nullptr; + int32_t requestResourceType_ = -1; + char* frameUrl_ = nullptr; +}; + +class WebResourceHandler : public RefBase { +public: + explicit WebResourceHandler(ani_env* env); + WebResourceHandler(ani_env* env, const ArkWeb_ResourceHandler* handler); + ~WebResourceHandler(); + int32_t DidReceiveResponse(const ArkWeb_Response* response); + int32_t DidReceiveResponseBody(const uint8_t* buffer, int64_t buflen); + int32_t DidFinish(); + int32_t DidFailWithError(ArkWeb_NetError errorCode); + void DestoryArkWebResourceHandler(); + void SetFinishFlag() + { + isFinished_ = true; + } + +private: + // ani_env* env_ = nullptr; + ani_vm* vm_ = nullptr; + bool isFinished_ = false; + ArkWeb_ResourceHandler* handler_ = nullptr; + // ani_env* env_; +}; + +class WebSchemeHandler { +public: + explicit WebSchemeHandler(ani_env* env); + ~WebSchemeHandler(); + + static const ArkWeb_SchemeHandler* GetArkWebSchemeHandler(WebSchemeHandler* handler); + static WebSchemeHandler* GetWebSchemeHandler(const ArkWeb_SchemeHandler* handler); + + void RequestStart( + ArkWeb_ResourceRequest* request, const ArkWeb_ResourceHandler* ArkWeb_ResourceHandler, bool* intercept); + void RequestStop(const ArkWeb_ResourceRequest* resourceRequest); + + void PutRequestStart(ani_env* env, ani_vm* vm, ani_fn_object callback); + void PutRequestStop(ani_env* env, ani_vm* vm, ani_fn_object callback); + + ani_ref delegate_ = nullptr; + static std::unordered_map webSchemeHandlerMap_; + static std::unordered_map arkWebSchemeHandlerMap_; + ani_env* GetEnv() + { + ani_env* env = nullptr; + if (vm_) { + vm_->GetEnv(ANI_VERSION_1, &env); + } + return env; + } + +private: + typedef struct RequestStopParam { + ani_env* env_; + ani_ref callbackRef_; + WebSchemeHandlerRequest* request_; + const ArkWeb_ResourceRequest* arkWebRequest_; + } RequestStopParam; + + static void RequestStopAfterWorkCb(RequestStopParam* param); + ani_env* env_ = nullptr; + ani_vm* vm_ = nullptr; + ArkWeb_OnRequestStart onRequestStart_ = nullptr; + ArkWeb_OnRequestStop onRequestStop_ = nullptr; + ani_ref request_start_callback_ = nullptr; + ani_ref request_stop_callback_ = nullptr; +}; + +} // namespace NWeb +} // namespace OHOS +#endif // OHOS_NWEB_ANI_SCHEME_HANDLER_REQUEST_H \ No newline at end of file diff --git a/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.cpp b/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.cpp index fecd1e0f9d7b38e4544d1a541ea9b38a8f03d73d..04c69a89e15b7d580746b36906f38e0bea37ca44 100644 --- a/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.cpp +++ b/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.cpp @@ -1474,6 +1474,35 @@ void WebPrintWriteResultCallbackAdapter::WriteResultCallback(std::string jobId, cb_(jobId, code); } +bool WebviewController::SetWebSchemeHandler(const char* scheme, WebSchemeHandler* handler) const + +{ + if (!handler || !scheme) { + WVLOG_E("WebviewController::SetWebSchemeHandler handler or scheme is nullptr"); + return false; + } + + auto schemeHandler_ptr = WebSchemeHandler::GetArkWebSchemeHandler(handler); + if (!schemeHandler_ptr) { + WVLOG_E("WebviewController::SetWebSchemeHandler ArkWebSchemeHandler is nullptr"); + return false; + } + + ArkWeb_SchemeHandler* schemeHandler = const_cast(schemeHandler_ptr); + return OH_ArkWeb_SetSchemeHandler(scheme, webTag_.c_str(), schemeHandler); +} + +bool WebviewController::SetWebServiveWorkerSchemeHandler(const char* scheme, WebSchemeHandler* handler) +{ + auto schemeHandler_ptr = WebSchemeHandler::GetArkWebSchemeHandler(handler); + if (!schemeHandler_ptr) { + WVLOG_E("WebviewController::SetWebServiveWorkerSchemeHandler ArkWebSchemeHandler is nullptr"); + return false; + } + ArkWeb_SchemeHandler* schemeHandler = const_cast(schemeHandler_ptr); + return OH_ArkWebServiceWorker_SetSchemeHandler(scheme, schemeHandler); +} + int32_t WebviewController::ClearWebSchemeHandler() { return OH_ArkWeb_ClearSchemeHandlers(webTag_.c_str()); diff --git a/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.h b/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.h index 9afdaa4b751f5a01d639deaee2f9f94f25deca34..2cd2c8dd2f96fb321f6b021b8a0416c2d7b67fb4 100644 --- a/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.h +++ b/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.h @@ -32,6 +32,7 @@ #include "webview_javascript_result_callback.h" #include "print_manager_adapter.h" #include "arkweb_scheme_handler.h" +#include "web_scheme_handler_request.h" namespace OHOS { namespace NWeb { @@ -314,6 +315,10 @@ public: bool IsIntelligentTrackingPreventionEnabled() const; + bool SetWebSchemeHandler(const char* scheme, WebSchemeHandler* handler) const; + + static bool SetWebServiveWorkerSchemeHandler(const char* scheme, WebSchemeHandler* handler); + int32_t ClearWebSchemeHandler(); ErrCode StartCamera(); diff --git a/interfaces/kits/ani/webview/src/common/ani_class_name.h b/interfaces/kits/ani/webview/src/common/ani_class_name.h index de256cd85d0da5fa8b2644778592d29b46cdd5a4..13f5ab1839da5005157169128cba134e2e19915f 100644 --- a/interfaces/kits/ani/webview/src/common/ani_class_name.h +++ b/interfaces/kits/ani/webview/src/common/ani_class_name.h @@ -37,6 +37,7 @@ const char* ANI_WEB_MESSAGE_PORT_INNER_CLASS_NAME = "L@ohos/web/webview/webview/ const char* ANI_ENUM_MEDIA_PLAY_BACK_STATE = "L@ohos/web/webview/webview/MediaPlaybackState;"; const char* ANI_SNAPSHOT_RESULT_CLASS_NAME = "L@ohos/web/webview/webview/SnapshotResultClass;"; const char* ANI_PDF_DATA_CLASS_NAME = "L@ohos/web/webview/webview/PdfData;"; +const char* ANI_CLASS_WEB_RESOURCETYPE = "L@ohos/web/webview/webview/WebResourceType;"; } // namespace NWeb } // namespace OHOS diff --git a/interfaces/kits/ani/webview/src/common/ani_parse_utils.cpp b/interfaces/kits/ani/webview/src/common/ani_parse_utils.cpp index b6fd9475f97bf517bd7d97fc52d57b70106086c0..87e39cdb749060ac96f435b33afb009dee6c9cb7 100644 --- a/interfaces/kits/ani/webview/src/common/ani_parse_utils.cpp +++ b/interfaces/kits/ani/webview/src/common/ani_parse_utils.cpp @@ -574,7 +574,7 @@ ani_object AniParseUtils::CreateInt(ani_env *env, ani_int val) return obj; } -ani_string StringToAniStr(ani_env* env, const std::string& str) +ani_string AniParseUtils::StringToAniStr(ani_env* env, const std::string& str) { ani_string result {}; if (ANI_OK != env->String_NewUTF8(str.c_str(), str.size(), &result)) { @@ -607,7 +607,7 @@ ani_ref AniParseUtils::CreateAniStringArray(ani_env* env, const std::vectorArray_Set_Ref(array, i, item)) { return nullptr; } @@ -652,7 +652,7 @@ bool AniParseUtils::ParseInt64(ani_env* env, ani_ref ref, int64_t& outValue) } ani_boolean isLong; if (env->Object_InstanceOf(static_cast(ref), longClass, &isLong) != ANI_OK || isLong != ANI_TRUE) { - WVLOG_E("ParseInt64 failed - invalid double type"); + WVLOG_E("ParseInt64 failed - invalid long type"); return false; } diff --git a/interfaces/kits/ani/webview/src/common/ani_parse_utils.h b/interfaces/kits/ani/webview/src/common/ani_parse_utils.h index 93d0d0c27fec5bfc2ef994d112ef9c9de01aefe4..435c38f43812322de41688407bcd26233f0b3caa 100644 --- a/interfaces/kits/ani/webview/src/common/ani_parse_utils.h +++ b/interfaces/kits/ani/webview/src/common/ani_parse_utils.h @@ -54,6 +54,7 @@ public: static bool CreateBoolean(ani_env *env, bool src, ani_object& aniObj); static ani_object CreateDouble(ani_env *env, ani_double val); static ani_object CreateInt(ani_env *env, ani_int val); + static ani_string StringToAniStr(ani_env* env, const std::string& str); static ani_ref CreateAniStringArray(ani_env *env, const std::vector &paths); static bool ParseBoolean(ani_env* env, ani_ref ref, bool& outValue); static bool ParseInt64(ani_env* env, ani_ref ref, int64_t& outValue); diff --git a/interfaces/kits/ani/webview/src/sts_web_webview.cpp b/interfaces/kits/ani/webview/src/sts_web_webview.cpp index 5f7d847a473d2be04ab97dc5728d883d2f8bf408..3fe5440bf685e47f913abef80f8a4a715110ef7a 100644 --- a/interfaces/kits/ani/webview/src/sts_web_webview.cpp +++ b/interfaces/kits/ani/webview/src/sts_web_webview.cpp @@ -28,6 +28,10 @@ #include "nweb_log.h" #include "ani_geolocation_permission.h" #include "ani_web_adsblock_manager.h" +#include "ani_webview_function.h" +#include "ani_web_scheme_handler.h" +#include "ani_web_scheme_handler_resource.h" +#include "ani_web_scheme_handler_request.h" namespace OHOS { namespace NWeb { @@ -60,6 +64,10 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) StsWebDataBaseInit(env); StsPdfDataInit(env); StsGeolocationPermissionInit(env); + StsWebviewFunctionInit(env); + StsWebSchemeHandlerResourceInit(env); + StsWebSchemeHandlerRequestInit(env); + StsWebSchemeHandlerInit(env); *result = ANI_VERSION_1; return ANI_OK; } diff --git a/interfaces/kits/ani/webview/src/webfunction/ani_webview_function.cpp b/interfaces/kits/ani/webview/src/webfunction/ani_webview_function.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aec3194ce493b2788b195e262fe3a3aae10b49dd --- /dev/null +++ b/interfaces/kits/ani/webview/src/webfunction/ani_webview_function.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_webview_function.h" + +#include +#include + +#include "ani_business_error.h" +#include "ani_parse_utils.h" +#include "nweb.h" +#include "nweb_helper.h" +#include "nweb_log.h" +#include "web_errors.h" + +namespace OHOS { +namespace NWeb { +using namespace NWebError; + +namespace { +const char* WEB_WEBVIEW_NAMESPACE_NAME = "L@ohos/web/webview/webview;"; +} + +void RegisterWebInitedCallback(ani_env* env, ani_ref callback) +{ + WVLOG_I("enter RegisterWebInitedCallback"); + WebInitedCallbackParam* param = new (std::nothrow) WebInitedCallbackParam(env, callback); + if (param == nullptr) { + return; + } + + WebRunInitedCallback* runWebInitedCallbackObj = new (std::nothrow) WebRunInitedCallbackImpl(param); + if (runWebInitedCallbackObj == nullptr) { + delete param; + return; + } + WVLOG_I("success in RegisterWebInitedCallback"); + OhosAdapterHelper::GetInstance().GetInitWebAdapter()->SetRunWebInitedCallback(std::move(runWebInitedCallbackObj)); +} + +std::unordered_map> onceType = { + { "webInited", RegisterWebInitedCallback }, +}; + +// type:string +static void JsOnce(ani_env* env, ani_string type, ani_object callback) +{ + WVLOG_I("enter JsOnce"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + + std::string argvType = ""; + ani_class functionClass; + if (env->FindClass("Lstd/core/Function;", &functionClass) != ANI_OK) { + AniBusinessError::ThrowErrorByErrCode(env, PARAM_CHECK_ERROR); + return; + } + ani_boolean isFunction; + env->Object_InstanceOf(callback, functionClass, &isFunction); + + if (!(AniParseUtils::ParseString(env, type, argvType)) || !isFunction || + (onceType.find(argvType) == onceType.end())) { + WVLOG_I("JsOnce TypeError : %{public}s", argvType.c_str()); + AniBusinessError::ThrowErrorByErrCode(env, PARAM_CHECK_ERROR); + return; + } + WVLOG_I("JsOnce Type : %{public}s", argvType.c_str()); + + auto foundCallback = onceType.find(argvType); + if (foundCallback != onceType.end()) { + foundCallback->second(env, callback); + } else { + WVLOG_I("error"); + AniBusinessError::ThrowErrorByErrCode(env, TYPE_NOT_MATCH_WITCH_VALUE); + return; + } + WVLOG_I("exit JsOnce"); +} + +ani_status StsWebviewFunctionInit(ani_env* env) +{ + WVLOG_I("enter StsWebviewFunctionInit"); + ani_namespace ns; + if (ANI_OK != env->FindNamespace(WEB_WEBVIEW_NAMESPACE_NAME, &ns)) { + WVLOG_E("StsWebviewFunctionInit find namespace failed"); + return ANI_ERROR; + } + std::array methods = { + ani_native_function { "once", nullptr, reinterpret_cast(JsOnce) }, + }; + if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) { + WVLOG_E("StsWebviewFunctionInit bind native function failed"); + return ANI_ERROR; + } + WVLOG_I("exit StsWebviewFunctionInit"); + return ANI_OK; +} + +} // namespace NWeb +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webfunction/ani_webview_function.h b/interfaces/kits/ani/webview/src/webfunction/ani_webview_function.h new file mode 100644 index 0000000000000000000000000000000000000000..9c69cfd0c03c4299b233a744b5817aa03e0f46b5 --- /dev/null +++ b/interfaces/kits/ani/webview/src/webfunction/ani_webview_function.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_NWEB_ANI_WEBVIEW_FUNCTION_H +#define OHOS_NWEB_ANI_WEBVIEW_FUNCTION_H + +#include +#include + +#include "ani.h" +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "ohos_adapter_helper.h" +#include "webview_controller.h" +#include "webview_web_inited_callback.h" + +namespace OHOS { +namespace NWeb { + +ani_status StsWebviewFunctionInit(ani_env* env); + +} // namespace NWeb +} // namespace OHOS + +#endif // OHOS_NWEB_ANI_WEBVIEW_FUNCTION_H \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b8ed103305c589130d6f74600bc872995a84ce86 --- /dev/null +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include "ani_business_error.h" +#include "ani_native_media_player_handler.h" +#include "ani_parse_utils.h" +#include "ani_webview_controller.h" +#include "native_media_player_impl.h" +#include "nweb_helper.h" +#include "nweb_log.h" +#include "securec.h" +#include "web_errors.h" +#include "web_scheme_handler_request.h" + +namespace OHOS { +namespace NWeb { + +using namespace NWebError; +using NWebError::NO_ERROR; + +static void OnRequestStart(ani_env* env, ani_object object, ani_fn_object callback) +{ + WVLOG_I("SchemeHandler OnRequestStart"); + if (env == nullptr) { + WVLOG_E("[WebSchemeHandler] env is nullptr"); + return; + } + + auto* webSchemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!webSchemeHandler) { + WVLOG_E("[WebSchemeHandler] webSchemeHandler is null"); + return; + } + ani_vm* vm = nullptr; + env->GetVM(&vm); + webSchemeHandler->PutRequestStart(env, vm, callback); +} + +static void Constructor(ani_env* env, ani_object object) +{ + WVLOG_I("WebSchemeHandler native Constructor"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + + WebSchemeHandler* webSchemeHandler = new (std::nothrow) WebSchemeHandler(env); + if (webSchemeHandler == nullptr) { + WVLOG_E("new WebSchemeHandler failed"); + return; + } + if (!AniParseUtils::Wrap( + env, object, WEB_WEBSCHEME_HANDLER_CLASS_NAME, reinterpret_cast(webSchemeHandler))) { + WVLOG_E("WebDownloadDelegate wrap failed"); + delete webSchemeHandler; + webSchemeHandler = nullptr; + } +} + +ani_status StsWebSchemeHandlerInit(ani_env* env) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return ANI_ERROR; + } + + ani_class WebSchemeHandlerCls = nullptr; + ani_status status = env->FindClass(WEB_WEBSCHEME_HANDLER_CLASS_NAME, &WebSchemeHandlerCls); + if (status != ANI_OK || !WebSchemeHandlerCls) { + WVLOG_E("find %{public}s class failed, status: %{public}d", WEB_WEBSCHEME_HANDLER_CLASS_NAME, status); + return ANI_ERROR; + } + std::array allMethods = { + ani_native_function { "", nullptr, reinterpret_cast(Constructor) }, + ani_native_function { "onRequestStart", "Lstd/core/Function2;:V", reinterpret_cast(OnRequestStart) }, + }; + + status = env->Class_BindNativeMethods(WebSchemeHandlerCls, allMethods.data(), allMethods.size()); + if (status != ANI_OK) { + WVLOG_E("Class_BindNativeMethods failed status: %{public}d", status); + } + return ANI_OK; +} + +} // namespace NWeb +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler.h b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..dc08e3e9865fb00e742a814fc859a0c8a9db7c11 --- /dev/null +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_H +#define OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_H + +#include +extern ani_vm* g_vm; +namespace OHOS { +namespace NWeb { +ani_status StsWebSchemeHandlerInit(ani_env* env); +} // namespace NWeb +} // namespace OHOS +#endif // OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_H \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_request.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_request.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4ed86eec030fb2e83f37a328ab8fcc2b0cf7a41 --- /dev/null +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_request.cpp @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "ani_business_error.h" +#include "ani_native_media_player_handler.h" +#include "ani_parse_utils.h" +#include "ani_webview_controller.h" +#include "native_media_player_impl.h" +#include "nweb_helper.h" +#include "nweb_log.h" +#include "securec.h" +#include "web_errors.h" +#include "web_scheme_handler_request.h" + +namespace OHOS { +namespace NWeb { + +using namespace NWebError; +using NWebError::NO_ERROR; +namespace { +const char* ANI_CLASS_WEB_RESOURCETYPE = "L@ohos/web/webview/webview/WebResourceType;"; +} // namespace + +static ani_boolean JSHasGesture(ani_env* env, ani_object object) +{ + WVLOG_I("jSHasGesture start"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return ANI_FALSE; + } + auto* stream = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!stream) { + WVLOG_E("stream is null"); + return ANI_FALSE; + } + return stream->HasGesture() ? ANI_TRUE : ANI_FALSE; +} + +static ani_string GetRequestMethod(ani_env* env, ani_object object) +{ + WVLOG_I("getRequestMethod start"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return nullptr; + } + auto* request = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!request) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return nullptr; + } + char* referrer = request->GetMethod(); + if (referrer == nullptr) { + WVLOG_E("getRequestMethod: referrer is nullptr"); + return nullptr; + } + ani_string value; + if (env->String_NewUTF8(referrer, strlen(referrer), &value) != ANI_OK) { + WVLOG_E("getRequestMethod: failed to create ani_string value"); + return nullptr; + } + return value; +} + +static ani_boolean IsMainFrame(ani_env* env, ani_object object) +{ + WVLOG_I("isMainFrame start"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return ANI_TRUE; + } + auto* request = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!request) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return ANI_TRUE; + } + ani_boolean value = (request->IsMainFrame() ? 1 : 0); + return value; +} + +static ani_string GetReferrer(ani_env* env, ani_object object) +{ + WVLOG_I("getReferrer start"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return nullptr; + } + auto* request = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!request) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return nullptr; + } + char* referrer = request->GetReferrer(); + if (referrer == nullptr) { + WVLOG_E("GetReferrer: referrer is nullptr"); + return nullptr; + } + ani_string value; + if (env->String_NewUTF8(referrer, strlen(referrer), &value) != ANI_OK) { + WVLOG_E("GetReferrer: failed to create ani_string value"); + return nullptr; + } + return value; +} + +static ani_string GetFrameUrl(ani_env* env, ani_object object) +{ + WVLOG_I("GetFrameUrl start"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return nullptr; + } + auto* request = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!request) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return nullptr; + } + ani_string url = nullptr; + char* result = request->GetFrameUrl(); + env->String_NewUTF8(result, strlen(result), &url); + OH_ArkWeb_ReleaseString(result); + return url; +} + +static ani_object GetRequestResourceType(ani_env* env, ani_object object) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return nullptr; + } + ani_int resourceType = 0; + ani_enum enumType; + env->FindEnum(ANI_CLASS_WEB_RESOURCETYPE, &enumType); + auto* request = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!request) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return nullptr; + } + resourceType = static_cast(request->GetRequestResourceType()); + ani_enum_item state; + env->Enum_GetEnumItemByIndex(enumType, resourceType, &state); + return state; +} + +static ani_string GetRequestUrl(ani_env* env, ani_object object) +{ + WVLOG_I("getRequestUrl start"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return nullptr; + } + auto* request = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!request) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return nullptr; + } + char* referrer = request->GetRequestUrl(); + if (referrer == nullptr) { + WVLOG_E("getRequestUrl: referrer is nullptr"); + return nullptr; + } + ani_string value; + if (env->String_NewUTF8(referrer, strlen(referrer), &value) != ANI_OK) { + WVLOG_E("getRequestUrl: failed to create ani_string value"); + return nullptr; + } + return value; +} + +static ani_ref GetHeader(ani_env* env, ani_object object) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return nullptr; + } + auto* request = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!request) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return nullptr; + } + std::vector> values = request->GetHeader(); + ani_class stringCls; + if (ANI_OK != env->FindClass("L@ohos/web/webview/webview/GetHeaderWebHeader;", &stringCls)) { + WVLOG_E("getHeader find class failed."); + return nullptr; + } + ani_method personInfoCtor; + if (ANI_OK != env->Class_FindMethod(stringCls, "", nullptr, &personInfoCtor)) { + WVLOG_E("getHeader GetUndefined Failed."); + return nullptr; + } + ani_ref undefinedRef = nullptr; + if (ANI_OK != env->GetUndefined(&undefinedRef)) { + WVLOG_E("getHeader GetUndefined Failed."); + return nullptr; + } + ani_array_ref array = nullptr; + if (ANI_OK != env->Array_New_Ref(stringCls, values.size(), undefinedRef, &array)) { + WVLOG_E("getHeader new array ref error."); + return array; + } + for (size_t i = 0; i < values.size(); ++i) { + ani_string headerKey {}; + ani_string headerValue {}; + ani_object webHeaderObj = {}; + ani_status status; + status = env->Object_New(stringCls, personInfoCtor, &webHeaderObj); + if (status != ANI_OK) { + WVLOG_E("getHeader new object error."); + } + env->String_NewUTF8(values[i].first.c_str(), values[i].first.size(), &headerKey); + env->String_NewUTF8(values[i].second.c_str(), values[i].second.size(), &headerValue); + + if ((status = env->Object_SetPropertyByName_Ref(webHeaderObj, "headerKey", static_cast(headerKey))) != + ANI_OK) { + WVLOG_E("getHeader Set headerKey failed status = %{public}d", status); + return nullptr; + } + if (ANI_OK != env->Object_SetPropertyByName_Ref(webHeaderObj, "headerValue", headerValue)) { + WVLOG_E("getHeader Get headerValue failed"); + return nullptr; + } + env->Array_Set_Ref(array, i, webHeaderObj); + } + return array; +} + +static void Constructor(ani_env* env, ani_object object) +{ + WVLOG_I("WebSchemeHandlerRequest native Constructor"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } +} + +ani_status StsWebSchemeHandlerRequestInit(ani_env* env) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return ANI_ERROR; + } + + ani_class WebSchemeHandlerRequestCls = nullptr; + ani_status status = env->FindClass(WEB_WEBSCHEME_HANDLER_REQUEST_CLASS_NAME, &WebSchemeHandlerRequestCls); + if (status != ANI_OK || !WebSchemeHandlerRequestCls) { + WVLOG_E("find %{public}s class failed, status: %{public}d", WEB_WEBSCHEME_HANDLER_REQUEST_CLASS_NAME, status); + return ANI_ERROR; + } + std::array allMethods = { + ani_native_function { "", nullptr, reinterpret_cast(Constructor) }, + ani_native_function { "hasGesture", nullptr, reinterpret_cast(JSHasGesture) }, + ani_native_function { "getReferrer", nullptr, reinterpret_cast(GetReferrer) }, + ani_native_function { "getFrameUrl", nullptr, reinterpret_cast(GetFrameUrl) }, + ani_native_function { "getHeader", nullptr, reinterpret_cast(GetHeader) }, + ani_native_function { "getRequestResourceType", nullptr, reinterpret_cast(GetRequestResourceType) }, + ani_native_function { "getRequestUrl", nullptr, reinterpret_cast(GetRequestUrl) }, + ani_native_function { "isMainFrame", nullptr, reinterpret_cast(IsMainFrame) }, + ani_native_function { "getRequestMethod", nullptr, reinterpret_cast(GetRequestMethod) }, + }; + + status = env->Class_BindNativeMethods(WebSchemeHandlerRequestCls, allMethods.data(), allMethods.size()); + if (status != ANI_OK) { + WVLOG_E("Class_BindNativeMethods failed status: %{public}d", status); + } + return ANI_OK; +} + +} // namespace NWeb +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_request.h b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_request.h new file mode 100644 index 0000000000000000000000000000000000000000..c0276b257c43dd0e1909ec97a2e59f6037e4a913 --- /dev/null +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_request.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_REQUEST_H +#define OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_REQUEST_H + +#include + +namespace OHOS { +namespace NWeb { +ani_status StsWebSchemeHandlerRequestInit(ani_env* env); +} // namespace NWeb +} // namespace OHOS +#endif // OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_REQUEST_H \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_resource.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_resource.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6f5626d90f70d02c6aea0ca4d01348747d22f3ec --- /dev/null +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_resource.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include "ani_business_error.h" +#include "ani_native_media_player_handler.h" +#include "ani_parse_utils.h" +#include "native_media_player_impl.h" +#include "nweb_helper.h" +#include "nweb_log.h" +#include "securec.h" +#include "web_errors.h" +#include "web_scheme_handler_request.h" +#include "web_scheme_handler_response.h" + +namespace OHOS { +namespace NWeb { + +using namespace NWebError; +using NWebError::NO_ERROR; + +static void JSDidReceiveResponse(ani_env* env, ani_object object, ani_object response) +{ + WVLOG_I("Enter aniwebResourceHandler JSDidReceiveResponse"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + auto* resourceHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!resourceHandler) { + WVLOG_E("stream is nullptr"); + return; + } + + auto* receiveResponse = reinterpret_cast(AniParseUtils::Unwrap(env, response)); + if (!receiveResponse) { + WVLOG_E("stream is nullptr"); + return; + } + + ani_long thisVar; + ani_status status = env->Object_GetFieldByName_Long(response, "nativePtr", &thisVar); + if (status != ANI_OK) { + WVLOG_E("AniUtils_Unwrap Object_GetFieldByName_Long status: %{public}d", status); + return; + } + + int32_t ret = resourceHandler->DidReceiveResponse(receiveResponse->GetArkWebResponse()); + WVLOG_I("aniwebResourceHandler JSDidReceiveResponse ret = %{public}d", ret); + if (ret != 0) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + } + return; +} + +static void JsDidFinish(ani_env* env, ani_object object) +{ + WVLOG_I("Enter aniwebResourceHandler JsDidFinish"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + + auto* resourceHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!resourceHandler) { + WVLOG_E("stream is nullptr"); + return; + } + int32_t ret = resourceHandler->DidFinish(); + if (ret != 0) { + AniBusinessError::ThrowErrorByErrCode(env, RESOURCE_HANDLER_INVALID); + WVLOG_E("JsDidFinish ret=%{public}d", ret); + } + return; +} + +static void Constructor(ani_env* env, ani_object object) +{ + WVLOG_E("WebResourceHandler WebResourceHandler native Constructor"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } +} + +ani_status StsWebSchemeHandlerResourceInit(ani_env* env) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return ANI_ERROR; + } + + ani_class WebResourceCls = nullptr; + ani_status status = env->FindClass(WEB_RESOURCE_HANDLER_CLASS_NAME, &WebResourceCls); + if (status != ANI_OK || !WebResourceCls) { + WVLOG_E("find %{public}s class failed, status: %{public}d", WEB_RESOURCE_HANDLER_CLASS_NAME, status); + return ANI_ERROR; + } + std::array allMethods = { + ani_native_function { "", nullptr, reinterpret_cast(Constructor) }, + ani_native_function { "didFinish", nullptr, reinterpret_cast(JsDidFinish) }, + ani_native_function { "didReceiveResponse", nullptr, reinterpret_cast(JSDidReceiveResponse) }, + }; + + status = env->Class_BindNativeMethods(WebResourceCls, allMethods.data(), allMethods.size()); + if (status != ANI_OK) { + WVLOG_E("Class_BindNativeMethods failed status: %{public}d", status); + } + return ANI_OK; +} + +} // namespace NWeb +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_resource.h b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_resource.h new file mode 100644 index 0000000000000000000000000000000000000000..f00e70adba42e4f6040c305fd53e6ccafdf3514e --- /dev/null +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_resource.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_RESOURCE_H +#define OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_RESOURCE_H + +#include + +namespace OHOS { +namespace NWeb { +ani_status StsWebSchemeHandlerResourceInit(ani_env* env); +} // namespace NWeb +} // namespace OHOS +#endif // OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_RESOURCE_H \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.cpp index 9a41c005e9e4bd26d7612c02cce2c4b46cbb7853..9c2d90657b903b375c120c47b80d3f7943958fba 100644 --- a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.cpp +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.cpp @@ -87,6 +87,260 @@ static ani_string JsGetUrl(ani_env *env, ani_object object) return url; } +static void JsSetMimeType(ani_env* env, ani_object object, ani_object mimeTypeObject) +{ + WVLOG_D("WebSchemeHandlerResponse JsSetMimeType."); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return; + } + ani_boolean isUndefined = true; + if (env->Reference_IsUndefined(mimeTypeObject, &isUndefined) != ANI_OK || isUndefined) { + AniBusinessError::ThrowError(env, PARAM_CHECK_ERROR, + NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one")); + return; + } + if (!AniParseUtils::IsString(env, mimeTypeObject)) { + AniBusinessError::ThrowError( + env, PARAM_CHECK_ERROR, NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "type", "string")); + return; + } + std::string mimeType; + if (!AniParseUtils::ParseString(env, mimeTypeObject, mimeType)) { + WVLOG_E("ParseString fail"); + return; + } + schemeHandler->SetMimeType(mimeType.c_str()); +} + +static ani_string JsGetMimeType(ani_env* env, ani_object object) +{ + WVLOG_D("WebSchemeHandlerResponse JsGetMimeType."); + ani_string mimeType = nullptr; + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return mimeType; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return mimeType; + } + char* result = schemeHandler->GetMimeType(); + if (result == nullptr) { + return mimeType; + } + env->String_NewUTF8(result, strlen(result), &mimeType); + OH_ArkWeb_ReleaseString(result); + return mimeType; +} + +static void JsSetEncoding(ani_env* env, ani_object object, ani_object encodingObject) +{ + WVLOG_D("WebSchemeHandlerResponse JsSetEncoding."); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return; + } + ani_boolean isUndefined = true; + if (env->Reference_IsUndefined(encodingObject, &isUndefined) != ANI_OK || isUndefined) { + AniBusinessError::ThrowError(env, PARAM_CHECK_ERROR, + NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one")); + return; + } + if (!AniParseUtils::IsString(env, encodingObject)) { + AniBusinessError::ThrowError(env, PARAM_CHECK_ERROR, + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "encoding", "string")); + return; + } + std::string encoding; + if (!AniParseUtils::ParseString(env, encodingObject, encoding)) { + WVLOG_E("ParseString fail"); + return; + } + schemeHandler->SetEncoding(encoding.c_str()); +} + +static ani_string JsGetEncoding(ani_env* env, ani_object object) +{ + WVLOG_D("WebSchemeHandlerResponse JsGetEncoding."); + ani_string encoding = nullptr; + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return encoding; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return encoding; + } + char* result = schemeHandler->GetEncoding(); + if (result == nullptr) { + return encoding; + } + env->String_NewUTF8(result, strlen(result), &encoding); + OH_ArkWeb_ReleaseString(result); + return encoding; +} + +static void JsSetStatusText(ani_env* env, ani_object object, ani_object statusTextObject) +{ + WVLOG_D("WebSchemeHandlerResponse JsSetStatusText."); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return; + } + ani_boolean isUndefined = true; + if (env->Reference_IsUndefined(statusTextObject, &isUndefined) != ANI_OK || isUndefined) { + AniBusinessError::ThrowError(env, PARAM_CHECK_ERROR, + NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one")); + return; + } + if (!AniParseUtils::IsString(env, statusTextObject)) { + AniBusinessError::ThrowError( + env, PARAM_CHECK_ERROR, NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "text", "string")); + return; + } + std::string statusText; + if (!AniParseUtils::ParseString(env, statusTextObject, statusText)) { + WVLOG_E("ParseString fail"); + return; + } + schemeHandler->SetStatusText(statusText.c_str()); +} + +static ani_string JsGetStatusText(ani_env* env, ani_object object) +{ + WVLOG_D("WebSchemeHandlerResponse JsGetStatusText."); + ani_string statusText = nullptr; + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return statusText; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return statusText; + } + char* result = schemeHandler->GetStatusText(); + if (result == nullptr) { + return statusText; + } + env->String_NewUTF8(result, strlen(result), &statusText); + OH_ArkWeb_ReleaseString(result); + return statusText; +} + +static void JsSetStatus(ani_env* env, ani_object object, ani_double statusValue) +{ + WVLOG_D("WebSchemeHandlerResponse JsSetStatus."); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return; + } + schemeHandler->SetStatus(static_cast(statusValue)); +} + +static ani_double JsGetStatus(ani_env* env, ani_object object) +{ + WVLOG_D("WebSchemeHandlerResponse JsGetStatus."); + ani_double result = 0; + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return result; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return result; + } + double value = schemeHandler->GetStatus(); + result = static_cast(value); + return result; +} + +static void JsSetHeaderByName( + ani_env* env, ani_object object, ani_object nameObject, ani_object valueObject, ani_boolean overWriteObject) +{ + WVLOG_D("WebSchemeHandlerResponse JsSetHeaderByName."); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return; + } + if (!AniParseUtils::IsString(env, nameObject)) { + AniBusinessError::ThrowError( + env, PARAM_CHECK_ERROR, NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "name", "string")); + return; + } + if (!AniParseUtils::IsString(env, valueObject)) { + AniBusinessError::ThrowError( + env, PARAM_CHECK_ERROR, NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "value", "string")); + return; + } + std::string name; + std::string value; + if (!AniParseUtils::ParseString(env, nameObject, name)) { + WVLOG_E("ParseString fail"); + return; + } + if (!AniParseUtils::ParseString(env, valueObject, value)) { + WVLOG_E("ParseString fail"); + return; + } + schemeHandler->SetHeaderByName(name.c_str(), value.c_str(), static_cast(overWriteObject)); +} + +static ani_string JsGetHeaderByName(ani_env* env, ani_object object, ani_object nameObject) +{ + WVLOG_D("WebSchemeHandlerResponse JsGetHeaderByName."); + ani_string headerValue = nullptr; + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return headerValue; + } + auto* schemeHandler = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!schemeHandler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return headerValue; + } + std::string name; + if (!AniParseUtils::ParseString(env, nameObject, name)) { + return nullptr; + } + char* result = schemeHandler->GetHeaderByName(name.c_str()); + if (result == nullptr) { + return headerValue; + } + env->String_NewUTF8(result, strlen(result), &headerValue); + OH_ArkWeb_ReleaseString(result); + return headerValue; +} + static void Constructor(ani_env *env, ani_object object) { WVLOG_D("WebSchemeHandlerResponse native Constructor"); @@ -124,6 +378,19 @@ ani_status StsWebSchemeHandlerResponseInit(ani_env *env) ani_native_function { "", nullptr, reinterpret_cast(Constructor) }, ani_native_function { "setUrl", nullptr, reinterpret_cast(JsSetUrl) }, ani_native_function { "getUrl", nullptr, reinterpret_cast(JsGetUrl) }, + ani_native_function { "", nullptr, reinterpret_cast(Constructor) }, + ani_native_function { "setUrl", nullptr, reinterpret_cast(JsSetUrl) }, + ani_native_function { "getUrl", nullptr, reinterpret_cast(JsGetUrl) }, + ani_native_function { "setMimeType", nullptr, reinterpret_cast(JsSetMimeType) }, + ani_native_function { "getMimeType", nullptr, reinterpret_cast(JsGetMimeType) }, + ani_native_function { "setEncoding", nullptr, reinterpret_cast(JsSetEncoding) }, + ani_native_function { "getEncoding", nullptr, reinterpret_cast(JsGetEncoding) }, + ani_native_function { "setStatusText", nullptr, reinterpret_cast(JsSetStatusText) }, + ani_native_function { "getStatusText", nullptr, reinterpret_cast(JsGetStatusText) }, + ani_native_function { "setStatus", nullptr, reinterpret_cast(JsSetStatus) }, + ani_native_function { "getStatus", nullptr, reinterpret_cast(JsGetStatus) }, + ani_native_function { "setHeaderByName", nullptr, reinterpret_cast(JsSetHeaderByName) }, + ani_native_function { "getHeaderByName", nullptr, reinterpret_cast(JsGetHeaderByName) }, }; status = env->Class_BindNativeMethods(webSchemeHandlerResponseCls, allMethods.data(), allMethods.size()); diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.h b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.h new file mode 100644 index 0000000000000000000000000000000000000000..2ee4d1cfdbf25351654868f233bb1fc807aa7e6f --- /dev/null +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_web_scheme_handler_response.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_RESPONSE_H +#define OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_RESPONSE_H + +#include + +namespace OHOS { +namespace NWeb { +ani_status StsWebSchemeHandlerResponseInit(ani_env* env); +} // namespace NWeb +} // namespace OHOS +#endif // OHOS_NWEB_ANI_WEB_SCHEME_HANDLER_RESPONSE_H \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp index e9fea847ba4a888274393ffbbe0320ce657d8c9f..cd90ae1498f9332988bed52bf0eacc68c4a44602 100644 --- a/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp @@ -64,6 +64,9 @@ #include "web_scheme_handler_response.h" #include "web_download_item.h" #include "ani_webview_createpdf_execute_callback.h" +#include "ani_web_scheme_handler_request.h" +#include "web_scheme_handler_request.h" +#include "arkweb_scheme_handler.h" namespace OHOS { namespace NWeb { @@ -431,6 +434,12 @@ static void Clean(ani_env *env, ani_object object) delete reinterpret_cast(ptr); } else if (clsName == "WebMessagePort") { delete reinterpret_cast(ptr); + } else if (clsName == "WebSchemeHandler") { + delete reinterpret_cast(ptr); + } else if (clsName == "WebSchemeHandlerRequest") { + delete reinterpret_cast(ptr); + } else if (clsName == "WebResourceHandler") { + reinterpret_cast(ptr)->DecStrongRef(reinterpret_cast(ptr)); } else { WVLOG_E("Clean unsupport className: %{public}s", clsName.c_str()); } @@ -2010,6 +2019,78 @@ static void ClearHistory(ani_env *env, ani_object object) controller->ClearHistory(); } +void SetWebSchemeHandler(ani_env* env, ani_object object, ani_string scheme, ani_object handlerObject) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + auto* controller = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + if (!controller || !controller->IsInit()) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return; + } + std::string schemeStr = ""; + if (!AniParseUtils::ParseString(env, scheme, schemeStr)) { + AniBusinessError::ThrowError(env, PARAM_CHECK_ERROR, + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "scheme", "string")); + return; + } + WebSchemeHandler* handler = nullptr; + ani_long thisVar; + ani_status status = env->Object_GetFieldByName_Long(handlerObject, "nativePtr", &thisVar); + if (status != ANI_OK) { + WVLOG_E("AniUtils_Unwrap Object_GetFieldByName_Long status: %{public}d", status); + return; + } + handler = reinterpret_cast(thisVar); + if (!handler) { + WVLOG_E("AniWebviewController::SetWebSchemeHandler handler is null"); + return; + } + if (!controller->SetWebSchemeHandler(schemeStr.c_str(), handler)) { + WVLOG_E("AniWebviewController::SetWebSchemeHandler failed"); + } + return; +} + +static void SetServiceWorkerWebSchemeHandler( + ani_env* env, ani_object object, ani_string scheme, ani_object handlerObject) +{ + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + std::string schemePtr = ""; + if (!AniParseUtils::ParseString(env, scheme, schemePtr)) { + WVLOG_E("AniWebviewController::SetWebSchemeHandler parse scheme failed"); + AniBusinessError::ThrowError(env, PARAM_CHECK_ERROR, + NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "scheme", "string")); + return; + } + WebSchemeHandler* handler = nullptr; + ani_long thisVar; + ani_status status = env->Object_GetFieldByName_Long(handlerObject, "nativePtr", &thisVar); + if (status != ANI_OK) { + WVLOG_E("AniUtils_Unwrap Object_GetFieldByName_Long status: %{public}d", status); + return; + } + handler = reinterpret_cast(thisVar); + if (!handler) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + WVLOG_E("Unwrap WebSchemeHandler failed"); + return; + } + if (ANI_OK != env->GlobalReference_Create(handlerObject, &handler->delegate_)) { + WVLOG_E("SetServiceWorkerWebSchemeHandler failed to create reference for callback"); + return; + } + if (!WebviewController::SetWebServiveWorkerSchemeHandler(schemePtr.c_str(), handler)) { + WVLOG_E("AniWebviewController::SetWebSchemeHandler failed"); + } + return; +} + static void ClearWebSchemeHandler(ani_env *env, ani_object object) { if (env == nullptr) { @@ -2395,7 +2476,7 @@ static ani_enum_item GetRenderProcessMode(ani_env* env, ani_object object) { ani_int renderProcessMode = 0; ani_enum enumType; - env->FindEnum("Lani_enum/COLORINT;", &enumType); + env->FindEnum("L@ohos/web/webview/webview/RenderProcessMode;", &enumType); renderProcessMode = static_cast(NWebHelper::Instance().GetRenderProcessMode()); WVLOG_I("getRenderProcessMode mode = %{public}d", static_cast(renderProcessMode)); @@ -2497,7 +2578,6 @@ static ani_boolean IsIncognitoMode(ani_env *env, ani_object object) static ani_object SerializeWebState(ani_env* env, ani_object object) { ani_object result = nullptr; - if (env == nullptr) { WVLOG_E("env is nullptr"); return result; @@ -2520,19 +2600,7 @@ static ani_object SerializeWebState(ani_env* env, ani_object object) if (retCode != 0) { return result; } - - ani_class cls; - ani_method ctor; - if (env->FindClass("Lstd/core/ArrayBuffer;", &cls) != ANI_OK) { - return result; - } - if (env->Class_FindMethod(cls, "", "I:V", &ctor) != ANI_OK) { - return result; - } - - ani_object arrayObject; - env->Object_New(cls, ctor, &arrayObject, buffer); - return arrayObject; + return buffer; } static void TrimMemoryByPressureLevel(ani_env *env, ani_object object, ani_double level) @@ -3978,7 +4046,7 @@ ani_object ConvertToAniHandlerOfInt64Array(ani_env* env, std::shared_ptr(values[i]); + ani_long item = static_cast(values[i]); ani_class cls {}; if (ANI_OK != env->FindClass("Lstd/core/Long;", &cls)) { return nullptr; @@ -4103,6 +4171,9 @@ ani_status StsWebMessageExtInit(ani_env* env) ani_native_function { "getArrayBuffer", nullptr, reinterpret_cast(GetArrayBuffer) }, ani_native_function { "getArray", nullptr, reinterpret_cast(GetArray) }, ani_native_function { "getError", nullptr, reinterpret_cast(GetError) }, + ani_native_function { "setWebSchemeHandler", nullptr, reinterpret_cast(SetWebSchemeHandler) }, + ani_native_function { "setServiceWorkerWebSchemeHandler", nullptr, + reinterpret_cast(SetServiceWorkerWebSchemeHandler) }, }; status = env->Class_BindNativeMethods(webMessageExtCls, webMessageExtMethods.data(), webMessageExtMethods.size()); if (status != ANI_OK) { @@ -4213,7 +4284,7 @@ ani_status StsWebviewControllerInit(ani_env *env) ani_native_function { "removeCache", nullptr, reinterpret_cast(RemoveCache) }, ani_native_function { "setNetworkAvailable", nullptr, reinterpret_cast(SetNetworkAvailable) }, ani_native_function { "isIncognitoMode", nullptr, reinterpret_cast(IsIncognitoMode) }, - ani_native_function { "serializeWebState", nullptr, reinterpret_cast(SerializeWebState) }, + ani_native_function { "serializeWebStateInternal", nullptr, reinterpret_cast(SerializeWebState) }, ani_native_function { "trimMemoryByPressureLevel", nullptr, reinterpret_cast(TrimMemoryByPressureLevel) }, ani_native_function { "setPathAllowingUniversalAccess", nullptr, diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.h b/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.h index 68577cbc5fd76b05378b43a8527b322af95ba3d8..f158247ecc3bfe7d7353de09345f62e662070f8d 100644 --- a/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.h +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.h @@ -40,6 +40,9 @@ ani_status StsWebDownLoadItemInit(ani_env *env); ani_status StsWebDownloadManagerInit(ani_env *env); ani_status StsWebCookieManagerInit(ani_env *env); ani_status StsNativeMediaPlayerHandlerinnerInit(ani_env *env); +ani_status StsWebSchemeHandlerResourceInit(ani_env *env); +ani_status StsWebSchemeHandlerRequestInit(ani_env *env); +ani_status StsWebSchemeHandlerInit(ani_env *env); } // namespace NWeb } // namespace OHOS #endif // OHOS_NWEB_ANI_WEBVIEW_CONTROLLER_H \ No newline at end of file