diff --git a/packages/webview_flutter/tizen/src/webview.cc b/packages/webview_flutter/tizen/src/webview.cc index 7746702b8..4c0990d7f 100644 --- a/packages/webview_flutter/tizen/src/webview.cc +++ b/packages/webview_flutter/tizen/src/webview.cc @@ -3,7 +3,6 @@ #include #include -#include #include #include @@ -58,27 +57,72 @@ double ExtractDoubleFromMap(const flutter::EncodableValue& arguments, WebView::WebView(flutter::PluginRegistrar* registrar, int viewId, FlutterTextureRegistrar* textureRegistrar, double width, - double height, const std::string initialUrl) + double height, flutter::EncodableMap& params) : PlatformView(registrar, viewId), textureRegistrar_(textureRegistrar), webViewInstance_(nullptr), - currentUrl_(initialUrl), width_(width), height_(height), tbmSurface_(nullptr) { SetTextureId(FlutterRegisterExternalTexture(textureRegistrar_)); InitWebView(); - auto channel = - std::make_unique>( - GetPluginRegistrar()->messenger(), GetChannelName(), - &flutter::StandardMethodCodec::GetInstance()); - channel->SetMethodCallHandler( + + channel_ = std::make_unique>( + GetPluginRegistrar()->messenger(), GetChannelName(), + &flutter::StandardMethodCodec::GetInstance()); + channel_->SetMethodCallHandler( [webview = this](const auto& call, auto result) { webview->HandleMethodCall(call, std::move(result)); }); + + auto initialUrl = params[flutter::EncodableValue("initialUrl")]; + if (std::holds_alternative(initialUrl)) { + currentUrl_ = std::get(initialUrl); + } else { + currentUrl_ = "about:blank"; + } + + auto names = params[flutter::EncodableValue("javascriptChannelNames")]; + if (std::holds_alternative(names)) { + auto nameList = std::get(names); + for (size_t i = 0; i < nameList.size(); i++) { + if (std::holds_alternative(nameList[i])) { + RegisterJavaScriptChannelName(std::get(nameList[i])); + } + } + } + webViewInstance_->LoadURL(currentUrl_); } +/** + * Added as a JavaScript interface to the WebView for any JavaScript channel + * that the Dart code sets up. + * + * Exposes a single method named `postMessage` to JavaScript, which sends a + * message over a method channel to the Dart code. + */ +void WebView::RegisterJavaScriptChannelName(const std::string& name) { + LOG_DEBUG("RegisterJavaScriptChannelName(channelName: %s)\n", name.c_str()); + + std::function cb = + [this, name](const std::string& message) -> std::string { + LOG_DEBUG("Invoke JavaScriptChannel(message: %s)\n", message.c_str()); + flutter::EncodableMap map; + map.insert(std::make_pair( + flutter::EncodableValue("channel"), flutter::EncodableValue(name))); + map.insert(std::make_pair( + flutter::EncodableValue("message"), flutter::EncodableValue(message))); + + std::unique_ptr args = + std::make_unique(map); + channel_->InvokeMethod("javascriptChannelMessage", std::move(args)); + return "success"; + }; + + webViewInstance_->AddJavaScriptInterface(name, "postMessage", cb); +} + WebView::~WebView() { Dispose(); } std::string WebView::GetChannelName() { @@ -543,7 +587,15 @@ void WebView::HandleMethodCall( result->Error("Invalid Arguments", "Invalid Arguments"); } } else if (methodName.compare("addJavascriptChannels") == 0) { - result->NotImplemented(); + if (std::holds_alternative(arguments)) { + auto nameList = std::get(arguments); + for (size_t i = 0; i < nameList.size(); i++) { + if (std::holds_alternative(nameList[i])) { + RegisterJavaScriptChannelName(std::get(nameList[i])); + } + } + } + result->Success(); } else if (methodName.compare("removeJavascriptChannels") == 0) { result->NotImplemented(); } else if (methodName.compare("clearCache") == 0) { diff --git a/packages/webview_flutter/tizen/src/webview.h b/packages/webview_flutter/tizen/src/webview.h index 59fc3e366..bed8aef24 100644 --- a/packages/webview_flutter/tizen/src/webview.h +++ b/packages/webview_flutter/tizen/src/webview.h @@ -1,6 +1,7 @@ #ifndef FLUTTER_PLUGIN_WEBVIEW_FLUTTER_TIZEN_WEVIEW_H_ #define FLUTTER_PLUGIN_WEBVIEW_FLUTTER_TIZEN_WEVIEW_H_ +#include #include #include #include @@ -21,7 +22,7 @@ class WebView : public PlatformView { public: WebView(flutter::PluginRegistrar* registrar, int viewId, FlutterTextureRegistrar* textureRegistrar, double width, - double height, const std::string initialUrl); + double height, flutter::EncodableMap& params); ~WebView(); virtual void Dispose() override; virtual void Resize(double width, double height) override; @@ -43,6 +44,9 @@ class WebView : public PlatformView { std::string GetChannelName(); const std::string& GetCurrentUrl() { return currentUrl_; } void InitWebView(); + + void RegisterJavaScriptChannelName(const std::string& name); + FlutterTextureRegistrar* textureRegistrar_; LWE::WebContainer* webViewInstance_; std::string currentUrl_; @@ -50,6 +54,7 @@ class WebView : public PlatformView { double height_; tbm_surface_h tbmSurface_; bool isMouseLButtonDown_; + std::unique_ptr> channel_; }; #endif // FLUTTER_PLUGIN_WEBVIEW_FLUTTER_TIZEN_WEVIEW_H_ diff --git a/packages/webview_flutter/tizen/src/webview_factory.cc b/packages/webview_flutter/tizen/src/webview_factory.cc index fc1dbf46f..83100d204 100644 --- a/packages/webview_flutter/tizen/src/webview_factory.cc +++ b/packages/webview_flutter/tizen/src/webview_factory.cc @@ -1,7 +1,9 @@ +#include "webview_factory.h" + #include #include -#include #include +#include #include #include @@ -11,9 +13,8 @@ #include #include "log.h" -#include "webview_flutter_tizen_plugin.h" -#include "webview_factory.h" #include "lwe/LWEWebView.h" +#include "webview_flutter_tizen_plugin.h" WebViewFactory::WebViewFactory(flutter::PluginRegistrar* registrar, FlutterTextureRegistrar* textureRegistrar) @@ -30,19 +31,13 @@ WebViewFactory::WebViewFactory(flutter::PluginRegistrar* registrar, PlatformView* WebViewFactory::Create(int viewId, double width, double height, const std::vector& createParams) { - std::string initialUrl = "about:blank"; - auto decoded_value = *GetCodec().DecodeMessage(createParams); - if (std::holds_alternative(decoded_value)) { - flutter::EncodableMap createParams = - std::get(decoded_value); - flutter::EncodableValue initialUrlValue = - createParams[flutter::EncodableValue("initialUrl")]; - if (std::holds_alternative(initialUrlValue)) { - initialUrl = std::get(initialUrlValue); - } + flutter::EncodableMap params; + auto decodedValue = *GetCodec().DecodeMessage(createParams); + if (std::holds_alternative(decodedValue)) { + params = std::get(decodedValue); } return new WebView(GetPluginRegistrar(), viewId, textureRegistrar_, width, - height, initialUrl); + height, params); } void WebViewFactory::Dispose() { LWE::LWE::Finalize(); }