Skip to content

Commit

Permalink
[webview_flutter_lwe] Fix "channel sent a message from native to Flut…
Browse files Browse the repository at this point in the history
…ter on a non-platform thread" error (#790)
  • Loading branch information
seungsoo47 authored Jan 7, 2025
1 parent 5b0f1ed commit 9398e21
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 16 deletions.
4 changes: 4 additions & 0 deletions packages/webview_flutter_lwe/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## NEXT

* Fix an issue where platform channel isn't called on the main thread.

## 0.3.4

* Update lightweight web engine(1.3.3).
Expand Down
20 changes: 20 additions & 0 deletions packages/webview_flutter_lwe/tizen/src/message_dispatcher.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "message_dispatcher.h"

#include <Ecore.h>

MessageDispatcher::MessageDispatcher() { ecore_init(); }
MessageDispatcher::~MessageDispatcher() { ecore_shutdown(); }

void MessageDispatcher::dispatchTaskOnMainThread(std::function<void()>&& fn) {
ecore_main_loop_thread_safe_call_sync(
[](void* data) -> void* {
auto fn = static_cast<std::function<void()>*>(data);
if (fn) (*fn)();
return nullptr;
},
&fn);
}
18 changes: 18 additions & 0 deletions packages/webview_flutter_lwe/tizen/src/message_dispatcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_PLUGIN_MESSAGE_DISPATCHER_H_
#define FLUTTER_PLUGIN_MESSAGE_DISPATCHER_H_

#include <functional>

class MessageDispatcher {
public:
MessageDispatcher();
~MessageDispatcher();

void dispatchTaskOnMainThread(std::function<void()>&& fn);
};

#endif // FLUTTER_PLUGIN_MESSAGE_DISPATCHER_H_
55 changes: 39 additions & 16 deletions packages/webview_flutter_lwe/tizen/src/webview.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ WebView::WebView(flutter::PluginRegistrar* registrar, int view_id,

InitWebView();

dispatcher_ = std::make_unique<MessageDispatcher>();

webview_channel_ = std::make_unique<FlMethodChannel>(
GetPluginRegistrar()->messenger(), GetWebViewChannelName(),
&flutter::StandardMethodCodec::GetInstance());
Expand All @@ -150,22 +152,32 @@ WebView::WebView(flutter::PluginRegistrar* registrar, int view_id,
[this](LWE::WebContainer* container, const std::string& url) {
flutter::EncodableMap args = {
{flutter::EncodableValue("url"), flutter::EncodableValue(url)}};
navigation_delegate_channel_->InvokeMethod(
"onPageStarted", std::make_unique<flutter::EncodableValue>(args));

dispatcher_->dispatchTaskOnMainThread([this, &args]() {
navigation_delegate_channel_->InvokeMethod(
"onPageStarted", std::make_unique<flutter::EncodableValue>(args));
});
});
webview_instance_->RegisterOnPageLoadedHandler(
[this](LWE::WebContainer* container, const std::string& url) {
flutter::EncodableMap args = {
{flutter::EncodableValue("url"), flutter::EncodableValue(url)}};
navigation_delegate_channel_->InvokeMethod(
"onPageFinished", std::make_unique<flutter::EncodableValue>(args));

dispatcher_->dispatchTaskOnMainThread([this, &args]() {
navigation_delegate_channel_->InvokeMethod(
"onPageFinished",
std::make_unique<flutter::EncodableValue>(args));
});
});
webview_instance_->RegisterOnProgressChangedHandler(
[this](LWE::WebContainer* container, int progress) {
flutter::EncodableMap args = {{flutter::EncodableValue("progress"),
flutter::EncodableValue(progress)}};
navigation_delegate_channel_->InvokeMethod(
"onProgress", std::make_unique<flutter::EncodableValue>(args));

dispatcher_->dispatchTaskOnMainThread([this, &args]() {
navigation_delegate_channel_->InvokeMethod(
"onProgress", std::make_unique<flutter::EncodableValue>(args));
});
});
webview_instance_->RegisterOnReceivedErrorHandler(
[this](LWE::WebContainer* container, LWE::ResourceError error) {
Expand All @@ -177,9 +189,12 @@ WebView::WebView(flutter::PluginRegistrar* registrar, int view_id,
{flutter::EncodableValue("failingUrl"),
flutter::EncodableValue(error.GetUrl())},
};
navigation_delegate_channel_->InvokeMethod(
"onWebResourceError",
std::make_unique<flutter::EncodableValue>(args));

dispatcher_->dispatchTaskOnMainThread([this, &args]() {
navigation_delegate_channel_->InvokeMethod(
"onWebResourceError",
std::make_unique<flutter::EncodableValue>(args));
});
});
webview_instance_->RegisterShouldOverrideUrlLoadingHandler(
[this](LWE::WebContainer* view, const std::string& url) -> bool {
Expand All @@ -191,10 +206,14 @@ WebView::WebView(flutter::PluginRegistrar* registrar, int view_id,
{flutter::EncodableValue("isForMainFrame"),
flutter::EncodableValue(true)},
};
auto result = std::make_unique<NavigationRequestResult>(url, this);
navigation_delegate_channel_->InvokeMethod(
"navigationRequest",
std::make_unique<flutter::EncodableValue>(args), std::move(result));

dispatcher_->dispatchTaskOnMainThread([this, &args, url]() {
auto result = std::make_unique<NavigationRequestResult>(url, this);
navigation_delegate_channel_->InvokeMethod(
"navigationRequest",
std::make_unique<flutter::EncodableValue>(args),
std::move(result));
});
return true;
});
}
Expand All @@ -212,9 +231,11 @@ void WebView::RegisterJavaScriptChannelName(const std::string& name) {
{flutter::EncodableValue("channel"), flutter::EncodableValue(name)},
{flutter::EncodableValue("message"), flutter::EncodableValue(message)},
};
webview_channel_->InvokeMethod(
"javaScriptChannelMessage",
std::make_unique<flutter::EncodableValue>(args));
dispatcher_->dispatchTaskOnMainThread([this, &args]() {
webview_channel_->InvokeMethod(
"javaScriptChannelMessage",
std::make_unique<flutter::EncodableValue>(args));
});
return "success";
};
webview_instance_->AddJavaScriptInterface(name, "postMessage", on_message);
Expand Down Expand Up @@ -622,7 +643,9 @@ void WebView::HandleWebViewMethodCall(const FlMethodCall& method_call,
delete result;
}
};

webview_instance_->EvaluateJavaScript(*javascript, on_result);

} else {
result->Error("Invalid argument", "The argument must be a string.");
}
Expand Down
3 changes: 3 additions & 0 deletions packages/webview_flutter_lwe/tizen/src/webview.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include <mutex>
#include <string>

#include "message_dispatcher.h"

typedef flutter::MethodCall<flutter::EncodableValue> FlMethodCall;
typedef flutter::MethodResult<flutter::EncodableValue> FlMethodResult;
typedef flutter::MethodChannel<flutter::EncodableValue> FlMethodChannel;
Expand Down Expand Up @@ -74,6 +76,7 @@ class WebView : public PlatformView {
BufferUnit* rendered_surface_ = nullptr;
bool is_mouse_lbutton_down_ = false;
bool has_navigation_delegate_ = false;
std::unique_ptr<MessageDispatcher> dispatcher_;
std::unique_ptr<FlMethodChannel> webview_channel_;
std::unique_ptr<FlMethodChannel> navigation_delegate_channel_;
std::unique_ptr<flutter::TextureVariant> texture_variant_;
Expand Down

0 comments on commit 9398e21

Please sign in to comment.