From c7f4822c1c445686d3a5df8ef7dd8b859dbbbac5 Mon Sep 17 00:00:00 2001 From: liuxiao_310 Date: Fri, 12 Sep 2025 17:56:34 +0800 Subject: [PATCH 1/2] web fix big function and mutil thread Signed-off-by: liuxiao_310 --- .../declarative_frontend/jsview/js_web.cpp | 12 +- .../components/web/resource/web_delegate.cpp | 144 ++++++++++++------ .../components/web/resource/web_delegate.h | 14 +- 3 files changed, 115 insertions(+), 55 deletions(-) diff --git a/frameworks/bridge/declarative_frontend/jsview/js_web.cpp b/frameworks/bridge/declarative_frontend/jsview/js_web.cpp index 6c89810db3d..e4b7ddaf056 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_web.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_web.cpp @@ -2046,13 +2046,11 @@ public: void OnConnect(const JSCallbackInfo &args) { - int connectid; - if ((args.Length() <= 0) || !(args[0]->IsNumber())) { TAG_LOGW(AceLogTag::ACE_WEB, "JSWebNativeMessageCallback OnConnect type error"); return; } - connectid = args[0]->ToNumber(); + int connectid = args[0]->ToNumber(); TAG_LOGI(AceLogTag::ACE_WEB, "JSWebNativeMessageCallback OnConnect, connectid=%{public}d", connectid); if (callback_) { @@ -2062,13 +2060,11 @@ public: void OnDisconnect(const JSCallbackInfo &args) { - int connectid; - if ((args.Length() <= 0) || !(args[0]->IsNumber())) { TAG_LOGW(AceLogTag::ACE_WEB, "JSWebNativeMessageCallback OnDisconnect type error"); return; } - connectid = args[0]->ToNumber(); + int connectid = args[0]->ToNumber(); if (callback_) { callback_->OnDisconnect(connectid); } @@ -2076,13 +2072,11 @@ public: void OnFailed(const JSCallbackInfo &args) { - int failedCode; - if ((args.Length() <= 0) || !(args[0]->IsNumber())) { TAG_LOGW(AceLogTag::ACE_WEB, "JSWebNativeMessageCallback failedCode type error"); return; } - failedCode = args[0]->ToNumber(); + int failedCode = args[0]->ToNumber(); TAG_LOGW(AceLogTag::ACE_WEB, "JSWebNativeMessageCallback OnFailed, failedCode is %{public}d", failedCode); if (callback_) { diff --git a/frameworks/core/components/web/resource/web_delegate.cpp b/frameworks/core/components/web/resource/web_delegate.cpp index 5e2d8c8350e..6b2d5636592 100644 --- a/frameworks/core/components/web/resource/web_delegate.cpp +++ b/frameworks/core/components/web/resource/web_delegate.cpp @@ -9191,57 +9191,111 @@ void WebDelegate::OnExtensionDisconnect(int32_t connectId) "ArkUIWebExtensionDisconnect"); } -std::string WebDelegate::OnWebNativeMessage(std::shared_ptr info, - std::shared_ptr callback) +bool WebDelegate::ValidateInputs( + std::shared_ptr callback, const RefPtr &context) { if (!callback) { - return std::string("error:-1"); + TAG_LOGE(AceLogTag::ACE_WEB, "web native message callback is nullptr"); + return false; } - auto context = context_.Upgrade(); - CHECK_NULL_RETURN(context, std::string("error:-1")); - auto pipelineContext = DynamicCast(context); - CHECK_NULL_RETURN(pipelineContext, std::string("error:-1")); + + if (!context) { + TAG_LOGE(AceLogTag::ACE_WEB, "context is nullptr"); + return false; + } + auto pipeline = NG::PipelineContext::GetCurrentContextSafely(); - std::mutex mtx; - std::condition_variable cv; - bool isCallbackDone = false; - std::string callbackResult; - bool isTimeout = false; - constexpr auto timeout = std::chrono::seconds(TIMEOUT_SECONDS); - auto jsTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::JS); - jsTaskExecutor.PostSyncTask( - [weak = WeakClaim(this), info, callback, &mtx, &cv, &isCallbackDone, &callbackResult, &isTimeout]() { - auto setResultAndNotify = [&](const std::string& result = "") { - std::unique_lock lock(mtx); - if (!isTimeout) { - callbackResult = result; - isCallbackDone = true; - } - cv.notify_one(); - }; - auto delegate = weak.Upgrade(); - if (!delegate) return setResultAndNotify(); - auto webPattern = delegate->webPattern_.Upgrade(); - if (!webPattern) return setResultAndNotify(); - auto webNativeMessageCallback = webPattern->GetWebNativeMessageConnectCallback(); - if (!webNativeMessageCallback) return setResultAndNotify(); - auto wrappedCallback = AceType::MakeRefPtr(callback); - wrappedCallback->SetCompletionHandler([&](const std::string &result) { setResultAndNotify(result); }); - webNativeMessageCallback(std::make_shared(info->GetBundleName(), - info->GetExtensionOrigin(), - info->GetMessageReadPipe(), - info->GetMessageWritePipe(), - wrappedCallback)); - }, "ArkUIWebNativeMessage"); - { - std::unique_lock lock(mtx); - if (!cv.wait_for(lock, timeout, [&]() { return isCallbackDone; })) { - isTimeout = true; - callbackResult = "error:4201"; - return callbackResult; + if (pipeline && pipeline->CheckThreadSafe()) { + TAG_LOGE(AceLogTag::ACE_WEB, "OnWebNativeMessage doesn't run on UI thread"); + return false; + } + + return true; +} + +void WebDelegate::ExecuteNativeMessageTask(WeakPtr weak, + std::shared_ptr info, + std::shared_ptr callback, std::shared_ptr sharedState) +{ + + std::lock_guard lock(sharedState->mtx); + if (sharedState->isTimeout) + return; + + auto delegate = weak.Upgrade(); + auto webPattern = delegate ? delegate->webPattern_.Upgrade() : nullptr; + auto webNativeMessageCallback = webPattern ? webPattern->GetWebNativeMessageConnectCallback() : nullptr; + + if (!webNativeMessageCallback) + return; + + auto wrappedCallback = AceType::MakeRefPtr(callback); + wrappedCallback->SetCompletionHandler([sharedState](const std::string &result) { + bool expected = false; + if (!sharedState->hasBeenCalled.compare_exchange_strong(expected, true)) { + TAG_LOGW(AceLogTag::ACE_WEB, "OnWebNativeMessage callback called multiple times, ignoring"); + return; + } + + std::unique_lock lock(sharedState->mtx); + if (sharedState->isTimeout) { + TAG_LOGW(AceLogTag::ACE_WEB, "OnWebNativeMessage callback after timeout"); + return; + } + + sharedState->callbackResult = result; + sharedState->isCallbackDone = true; + sharedState->cv.notify_one(); + }); + + webNativeMessageCallback(std::make_shared(info->GetBundleName(), + info->GetExtensionOrigin(), + info->GetMessageReadPipe(), + info->GetMessageWritePipe(), + wrappedCallback)); +} + +std::string WebDelegate::WaitForResult(std::shared_ptr sharedState) +{ + TAG_LOGI(AceLogTag::ACE_WEB, "OnWebNativeMessage waiting start"); + + std::unique_lock lock(sharedState->mtx); + if (!sharedState->cv.wait_for( + lock, std::chrono::seconds(TIMEOUT_SECONDS), [sharedState]() { return sharedState->isCallbackDone; })) { + + bool expected = false; + if (sharedState->hasBeenCalled.compare_exchange_strong(expected, true)) { + sharedState->isTimeout = true; + sharedState->callbackResult = "error:4204"; + TAG_LOGW(AceLogTag::ACE_WEB, "OnWebNativeMessage return by timeout"); + } else { + sharedState->cv.wait(lock, [sharedState]() { return sharedState->isCallbackDone; }); } } - return callbackResult; + + TAG_LOGI(AceLogTag::ACE_WEB, "OnWebNativeMessage return result"); + return sharedState->callbackResult; +} + +std::string WebDelegate::OnWebNativeMessage(std::shared_ptr info, + std::shared_ptr callback) +{ + + auto context = context_.Upgrade(); + if (!ValidateInputs(callback, context)) { + return "error:4201"; + } + + auto sharedState = std::make_shared(); + auto jsTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::JS); + + jsTaskExecutor.PostSyncTask( + [this, info, callback, sharedState]() { + ExecuteNativeMessageTask(WeakClaim(this), info, callback, sharedState); + }, + "ArkUIWebNativeMessage"); + + return WaitForResult(sharedState); } void WebDelegate::SetImeShow(bool visible) diff --git a/frameworks/core/components/web/resource/web_delegate.h b/frameworks/core/components/web/resource/web_delegate.h index f241e29876b..a6a6b420574 100644 --- a/frameworks/core/components/web/resource/web_delegate.h +++ b/frameworks/core/components/web/resource/web_delegate.h @@ -1434,7 +1434,19 @@ public: void OnLoadFinished(const std::string& param); void SetIsFileSelectorShow(bool isFileSelectorShow) { isFileSelectorShow_ = isFileSelectorShow; } bool IsFileSelectorShow() { return isFileSelectorShow_; } - + struct SharedState { + std::mutex mtx; + std::condition_variable cv; + bool isCallbackDone = false; + bool isTimeout = false; + std::string callbackResult; + std::atomic hasBeenCalled { false }; + }; + bool ValidateInputs( + std::shared_ptr callback, const RefPtr& context); + void ExecuteNativeMessageTask(WeakPtr weak, std::shared_ptr info, + std::shared_ptr callback, std::shared_ptr sharedState); + std::string WaitForResult(std::shared_ptr sharedState); void OnExtensionDisconnect(int32_t connectId); std::string OnWebNativeMessage(std::shared_ptr info, std::shared_ptr callback); -- Gitee From df68e5670b2acc6b71b33352312b264219481a9f Mon Sep 17 00:00:00 2001 From: liuxiao_now87 Date: Mon, 22 Sep 2025 14:08:32 +0000 Subject: [PATCH 2/2] =?UTF-8?q?update=20frameworks/core/components/web/res?= =?UTF-8?q?ource/web=5Fdelegate.cpp.=20=E6=B6=88=E9=99=A4codecheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liuxiao_now87 --- frameworks/core/components/web/resource/web_delegate.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/frameworks/core/components/web/resource/web_delegate.cpp b/frameworks/core/components/web/resource/web_delegate.cpp index 6b2d5636592..46e77a4b529 100644 --- a/frameworks/core/components/web/resource/web_delegate.cpp +++ b/frameworks/core/components/web/resource/web_delegate.cpp @@ -9217,7 +9217,6 @@ void WebDelegate::ExecuteNativeMessageTask(WeakPtr weak, std::shared_ptr info, std::shared_ptr callback, std::shared_ptr sharedState) { - std::lock_guard lock(sharedState->mtx); if (sharedState->isTimeout) return; @@ -9258,11 +9257,10 @@ void WebDelegate::ExecuteNativeMessageTask(WeakPtr weak, std::string WebDelegate::WaitForResult(std::shared_ptr sharedState) { TAG_LOGI(AceLogTag::ACE_WEB, "OnWebNativeMessage waiting start"); - std::unique_lock lock(sharedState->mtx); if (!sharedState->cv.wait_for( - lock, std::chrono::seconds(TIMEOUT_SECONDS), [sharedState]() { return sharedState->isCallbackDone; })) { - + lock, std::chrono::seconds(TIMEOUT_SECONDS), + [sharedState]() {State->isCallbackDone; })) { bool expected = false; if (sharedState->hasBeenCalled.compare_exchange_strong(expected, true)) { sharedState->isTimeout = true; @@ -9280,7 +9278,6 @@ std::string WebDelegate::WaitForResult(std::shared_ptr sharedState) std::string WebDelegate::OnWebNativeMessage(std::shared_ptr info, std::shared_ptr callback) { - auto context = context_.Upgrade(); if (!ValidateInputs(callback, context)) { return "error:4201"; -- Gitee