diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 319388ffd..7b41a25d2 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.12.0 + +* Add `getCookies` to the cookie manager using the EWK and WV cookie getters. +* Add `setCookie` to the cookie manager on the WV backend. +* Apply `tizenEnginePolicy` before WV initialization. +* Fix cookie operations using a destroyed WebView. + ## 0.11.1 * Update minimum supported SDK version to Flutter 3.38/Dart 3.10. diff --git a/packages/webview_flutter/README.md b/packages/webview_flutter/README.md index 7991643ad..b7ad0e87a 100644 --- a/packages/webview_flutter/README.md +++ b/packages/webview_flutter/README.md @@ -23,7 +23,7 @@ This package is not an _endorsed_ implementation of `webview_flutter`. Therefore ```yaml dependencies: webview_flutter: ^4.14.1 - webview_flutter_tizen: ^0.11.1 + webview_flutter_tizen: ^0.12.0 ``` ## Example @@ -71,11 +71,13 @@ The plugin chooses a backend from the platform version reported by the device: | 10.1 | WV API, EWK wrapper mode | | 11.0 and later | WV API, standalone mode | -The WV backends are experimental. `WebViewController.tizenEnginePolicy` has no WV equivalent, so it is ignored (with a warning) on Tizen 10.1 and later. +The WV backends are experimental. `WebViewController.tizenEnginePolicy` calls `wv_set_version_policy()` before WV engine initialization. The first WV view's setting applies to the engine for its lifetime. ## Cookies -- `WebViewCookieManager.getCookies` throws `UnimplementedError`: neither backend can read cookies yet. On the EWK backend the web engine's cookie API returns nothing, a defect being fixed; on the WV backends that API is not yet in the platform library. +- `WebViewCookieManager.getCookies` calls the EWK or WV cookie getter. On the EWK backend (Tizen 10.0 and earlier), the getter currently returns no cookies because of an engine defect. +- `WebViewCookieManager.setCookie` uses the WV cookie manager. EWK has no cookie setter, so it throws `UnimplementedError` on the EWK backend. +- Cookie operations need a WebView that has been created, and fail before the first one is. ## Note diff --git a/packages/webview_flutter/lib/src/tizen_webview_cookie_manager.dart b/packages/webview_flutter/lib/src/tizen_webview_cookie_manager.dart index 3d502bfb5..1175062ea 100644 --- a/packages/webview_flutter/lib/src/tizen_webview_cookie_manager.dart +++ b/packages/webview_flutter/lib/src/tizen_webview_cookie_manager.dart @@ -22,11 +22,27 @@ class TizenWebViewCookieManager extends PlatformWebViewCookieManager { } @override - Future> getCookies(Uri url) { - throw UnimplementedError( - 'This version of `TizenWebViewCookieManager` currently has no ' - 'implementation for getCookies method.', + Future> getCookies(Uri url) async { + final String? cookies = await _cookieManagerChannel.invokeMethod( + 'getCookies', + url.toString(), ); + if (cookies == null || cookies.isEmpty) { + return []; + } + return cookies + .split(';') + .map((String cookie) => cookie.trim()) + .where((String cookie) => cookie.isNotEmpty) + .map((String cookie) { + final int separator = cookie.indexOf('='); + return WebViewCookie( + name: separator < 0 ? cookie : cookie.substring(0, separator), + value: separator < 0 ? '' : cookie.substring(separator + 1), + domain: url.host, + ); + }) + .toList(); } @override @@ -34,10 +50,21 @@ class TizenWebViewCookieManager extends PlatformWebViewCookieManager { if (!_isValidPath(cookie.path)) { throw ArgumentError('The path property for the provided cookie was not given a legal value.'); } - throw UnimplementedError( - 'This version of `TizenWebViewCookieManager` currently has no ' - 'implementation for setCookie method.', - ); + final String host = cookie.domain.startsWith('.') ? cookie.domain.substring(1) : cookie.domain; + final url = Uri(scheme: 'https', host: host, path: cookie.path).toString(); + final line = + '${Uri.encodeComponent(cookie.name)}=${Uri.encodeComponent(cookie.value)}; path=${cookie.path}'; + try { + await _cookieManagerChannel.invokeMethod('setCookie', { + 'url': url, + 'cookie': line, + }); + } on PlatformException catch (e) { + if (e.code == 'Unsupported') { + throw UnimplementedError('setCookie is not supported by this web engine.'); + } + rethrow; + } } bool _isValidPath(String path) { diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 84fa834cc..c80777ede 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_tizen description: Tizen implementation of the webview_flutter plugin. homepage: https://github.com/flutter-tizen/plugins repository: https://github.com/flutter-tizen/plugins/tree/main/packages/webview_flutter -version: 0.11.1 +version: 0.12.0 environment: sdk: ^3.10.0 diff --git a/packages/webview_flutter/tizen/inc/ftpw_webview_flutter.h b/packages/webview_flutter/tizen/inc/ftpw_webview_flutter.h index 366b1d08c..9997bcf78 100644 --- a/packages/webview_flutter/tizen/inc/ftpw_webview_flutter.h +++ b/packages/webview_flutter/tizen/inc/ftpw_webview_flutter.h @@ -164,6 +164,8 @@ void ftpw_webview_flutter_ewk_view_javascript_prompt_reply(void *o, const char *result); unsigned char ftpw_webview_flutter_ewk_view_main_frame_scrollbar_visible_set( void *obj, unsigned char enabled); +char *ftpw_webview_flutter_ewk_view_get_cookies_for_url(void *view, + const char *url); void ftpw_webview_flutter_ewk_set_arguments(int argc, char **argv); int ftpw_webview_flutter_ewk_set_version_policy(int preference); void ftpw_webview_flutter_ewk_settings_ime_panel_enabled_set( @@ -177,12 +179,15 @@ const char *ftpw_webview_flutter_ewk_console_message_text_get( int ftpw_webview_flutter_wv_init(void); int ftpw_webview_flutter_wv_shutdown(void); int ftpw_webview_flutter_wv_set_arguments(int argc, const char **argv); +int ftpw_webview_flutter_wv_set_version_policy(int preference); void *ftpw_webview_flutter_wv_view_create(void); void ftpw_webview_flutter_wv_view_destroy(void *view); void ftpw_webview_flutter_wv_view_resize(void *view, int w, int h); bool ftpw_webview_flutter_wv_view_focus_set(void *view, int focused); bool ftpw_webview_flutter_wv_view_url_set(void *view, const char *url); const char *ftpw_webview_flutter_wv_view_url_get(void *view); +char *ftpw_webview_flutter_wv_view_get_cookies_for_url(void *view, + const char *url); bool ftpw_webview_flutter_wv_view_url_request_set(void *view, const char *url, wv_http_method_e method, void *headers, @@ -263,6 +268,8 @@ int ftpw_webview_flutter_wv_context_web_storage_delete_all(void *context); int ftpw_webview_flutter_wv_context_cache_clear(void *context); int ftpw_webview_flutter_wv_cookie_manager_accept_policy_set(void *manager); int ftpw_webview_flutter_wv_cookie_manager_cookies_clear(void *manager); +void ftpw_webview_flutter_wv_cookie_manager_set_cookie_for_url( + void *manager, const char *cookie_line, const char *url); bool ftpw_webview_flutter_wv_settings_javascript_enabled_set(void *settings, bool enable); void ftpw_webview_flutter_wv_settings_ime_panel_enabled_set(void *settings, diff --git a/packages/webview_flutter/tizen/lib/aarch64/libftpw_webview_flutter.so b/packages/webview_flutter/tizen/lib/aarch64/libftpw_webview_flutter.so index d034714a9..acab9f36f 100755 Binary files a/packages/webview_flutter/tizen/lib/aarch64/libftpw_webview_flutter.so and b/packages/webview_flutter/tizen/lib/aarch64/libftpw_webview_flutter.so differ diff --git a/packages/webview_flutter/tizen/lib/armel/libftpw_webview_flutter.so b/packages/webview_flutter/tizen/lib/armel/libftpw_webview_flutter.so index 2b4827a9d..3dbd97e64 100755 Binary files a/packages/webview_flutter/tizen/lib/armel/libftpw_webview_flutter.so and b/packages/webview_flutter/tizen/lib/armel/libftpw_webview_flutter.so differ diff --git a/packages/webview_flutter/tizen/lib/i586/libftpw_webview_flutter.so b/packages/webview_flutter/tizen/lib/i586/libftpw_webview_flutter.so index 333851e0d..4c9021e25 100755 Binary files a/packages/webview_flutter/tizen/lib/i586/libftpw_webview_flutter.so and b/packages/webview_flutter/tizen/lib/i586/libftpw_webview_flutter.so differ diff --git a/packages/webview_flutter/tizen/lib/x86_64/libftpw_webview_flutter.so b/packages/webview_flutter/tizen/lib/x86_64/libftpw_webview_flutter.so index 8f4fe2ec3..d1c165a70 100755 Binary files a/packages/webview_flutter/tizen/lib/x86_64/libftpw_webview_flutter.so and b/packages/webview_flutter/tizen/lib/x86_64/libftpw_webview_flutter.so differ diff --git a/packages/webview_flutter/tizen/src/ewk_webview_backend.cc b/packages/webview_flutter/tizen/src/ewk_webview_backend.cc index ce782641a..0e468fc3f 100644 --- a/packages/webview_flutter/tizen/src/ewk_webview_backend.cc +++ b/packages/webview_flutter/tizen/src/ewk_webview_backend.cc @@ -520,6 +520,16 @@ bool EwkWebViewBackend::ClearCookies() { return false; } +std::string EwkWebViewBackend::GetCookies(const std::string& url) { + return TakeEngineString( + ftpw_webview_flutter_ewk_view_get_cookies_for_url(view_, url.c_str())); +} + +bool EwkWebViewBackend::SetCookie(const std::string& /*cookie_line*/, + const std::string& /*url*/) { + return false; +} + void EwkWebViewBackend::OnFrameRendered(void* data, Evas_Object* obj, void* event_info) { if (event_info) { diff --git a/packages/webview_flutter/tizen/src/ewk_webview_backend.h b/packages/webview_flutter/tizen/src/ewk_webview_backend.h index 8d141ffcf..c23c9f4dc 100644 --- a/packages/webview_flutter/tizen/src/ewk_webview_backend.h +++ b/packages/webview_flutter/tizen/src/ewk_webview_backend.h @@ -74,6 +74,9 @@ class EwkWebViewBackend : public WebViewBackend { void JavaScriptPromptReply(const std::string& result) override; void SetScrollbarVisible(bool visible) override; bool ClearCookies() override; + std::string GetCookies(const std::string& url) override; + bool SetCookie(const std::string& cookie_line, + const std::string& url) override; static void GlobalInitialize(); diff --git a/packages/webview_flutter/tizen/src/webview.cc b/packages/webview_flutter/tizen/src/webview.cc index a11fb07bd..0b2324e3a 100644 --- a/packages/webview_flutter/tizen/src/webview.cc +++ b/packages/webview_flutter/tizen/src/webview.cc @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -86,6 +87,8 @@ bool GetValueFromEncodableMap(const flutter::EncodableValue* arguments, } // namespace +std::vector WebView::webviews_; + WebView::WebView(flutter::PluginRegistrar* registrar, int view_id, flutter::TextureRegistrar* texture_registrar, double width, double height, const flutter::EncodableValue& params, @@ -96,11 +99,6 @@ WebView::WebView(flutter::PluginRegistrar* registrar, int view_id, height_(height), window_(window) { backend_ = WebViewBackendFactory::Create(this); - if (!backend_) { - LOG_ERROR("Failed to create a webview backend."); - return; - } - tbm_pool_ = std::make_shared(width, height); texture_variant_ = @@ -128,14 +126,7 @@ WebView::WebView(flutter::PluginRegistrar* registrar, int view_id, GetPluginRegistrar()->messenger(), GetNavigationDelegateChannelName(), &flutter::StandardMethodCodec::GetInstance()); - auto cookie_channel = std::make_unique( - GetPluginRegistrar()->messenger(), - "plugins.flutter.io/tizen_cookie_manager", - &flutter::StandardMethodCodec::GetInstance()); - cookie_channel->SetMethodCallHandler( - [webview = this](const auto& call, auto result) { - webview->HandleCookieMethodCall(call, std::move(result)); - }); + webviews_.push_back(this); } WebView::~WebView() { Dispose(); } @@ -164,9 +155,8 @@ void WebView::Dispose() { } *is_alive_ = false; - if (!backend_) { - return; - } + webviews_.erase(std::remove(webviews_.begin(), webviews_.end(), this), + webviews_.end()); std::shared_ptr pool; { @@ -200,17 +190,9 @@ void WebView::InitializeEngine() { WebViewBackendFactory::InitializeEngine(); } void WebView::ShutdownEngine() { WebViewBackendFactory::ShutdownEngine(); } -void WebView::Offset(double left, double top) { - if (!backend_) { - return; - } - backend_->Offset(left, top); -} +void WebView::Offset(double left, double top) { backend_->Offset(left, top); } void WebView::Resize(double width, double height) { - if (!backend_) { - return; - } width_ = width; height_ = height; @@ -224,36 +206,20 @@ void WebView::Resize(double width, double height) { void WebView::Touch(int event_type, int button_type, double x, double y, double dx, double dy) { - if (!backend_) { - return; - } backend_->Touch(event_type, button_type, x, y, dx, dy); } bool WebView::SendKey(const char* key, const char* string, const char* compose, uint32_t modifiers, uint32_t scan_code, bool is_down) { - if (!backend_) { - return false; - } if (!IsFocused()) { return false; } return backend_->SendKey(key, string, compose, modifiers, scan_code, is_down); } -void WebView::Resume() { - if (!backend_) { - return; - } - backend_->Resume(); -} +void WebView::Resume() { backend_->Resume(); } -void WebView::Stop() { - if (!backend_) { - return; - } - backend_->Stop(); -} +void WebView::Stop() { backend_->Stop(); } void WebView::SetDirection(int direction) { // TODO: Implement if necessary. @@ -289,7 +255,8 @@ void WebView::HandleWebViewMethodCall(const FlMethodCall& method_call, } if (!webview_created_) { - if (!backend_->Create(width_, height_, window_, engine_policy_)) { + if (!WebViewBackendFactory::EnsureEngineInitialized(engine_policy_) || + !backend_->Create(width_, height_, window_, engine_policy_)) { result->Error("Invalid operation", "The webview instance initialize failed."); return; @@ -523,20 +490,44 @@ void WebView::HandleWebViewMethodCall(const FlMethodCall& method_call, void WebView::HandleCookieMethodCall(const FlMethodCall& method_call, std::unique_ptr result) { - if (!webview_created_) { - result->Error("Invalid operation", - "The webview instance has not been initialized."); + auto it = std::find_if(webviews_.rbegin(), webviews_.rend(), + [](WebView* view) { return view->webview_created_; }); + if (it == webviews_.rend()) { + result->Error("Invalid operation", "No webview instance is available."); return; } + WebView* webview = *it; const std::string& method_name = method_call.method_name(); if (method_name == "clearCookies") { - if (backend_->ClearCookies()) { + if (webview->backend_->ClearCookies()) { result->Success(flutter::EncodableValue(true)); } else { result->Error("Operation failed", "Failed to get cookie manager"); } + } else if (method_name == "getCookies") { + const auto* url = std::get_if(method_call.arguments()); + if (!url) { + result->Error("Invalid argument", "The argument must be a string."); + return; + } + result->Success( + flutter::EncodableValue(webview->backend_->GetCookies(*url))); + } else if (method_name == "setCookie") { + std::string url; + std::string cookie; + if (!GetValueFromEncodableMap(method_call.arguments(), "url", &url) || + !GetValueFromEncodableMap(method_call.arguments(), "cookie", &cookie)) { + result->Error("Invalid argument", "The URL and cookie must be strings."); + return; + } + if (webview->backend_->SetCookie(cookie, url)) { + result->Success(); + } else { + result->Error("Unsupported", + "Setting cookies is not supported by this webview engine."); + } } else { result->NotImplemented(); } diff --git a/packages/webview_flutter/tizen/src/webview.h b/packages/webview_flutter/tizen/src/webview.h index efc0bebc5..c5c23df13 100644 --- a/packages/webview_flutter/tizen/src/webview.h +++ b/packages/webview_flutter/tizen/src/webview.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "webview_backend.h" @@ -60,11 +61,14 @@ class WebView : public PlatformView, public WebViewBackend::Delegate { // Must be called exactly once, after every WebView has been destroyed. static void ShutdownEngine(); + // NOTE: Cookies are shared by the web context, so calls go to the most + // recently created WebView that has been initialized. + static void HandleCookieMethodCall(const FlMethodCall& method_call, + std::unique_ptr result); + private: void HandleWebViewMethodCall(const FlMethodCall& method_call, std::unique_ptr result); - void HandleCookieMethodCall(const FlMethodCall& method_call, - std::unique_ptr result); template void SetBackgroundColor(const T& color); @@ -95,6 +99,9 @@ class WebView : public PlatformView, public WebViewBackend::Delegate { const std::string& default_text, const std::string& url) override; + // Live WebViews, in creation order. Only touched on the platform thread. + static std::vector webviews_; + std::unique_ptr backend_; bool webview_created_ = false; flutter::TextureRegistrar* texture_registrar_; diff --git a/packages/webview_flutter/tizen/src/webview_backend.cc b/packages/webview_flutter/tizen/src/webview_backend.cc index d5e878633..ff32128d9 100644 --- a/packages/webview_flutter/tizen/src/webview_backend.cc +++ b/packages/webview_flutter/tizen/src/webview_backend.cc @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -81,3 +82,13 @@ void WebViewBackend::FlushPendingTeardowns() { } } } + +std::string WebViewBackend::TakeEngineString(char* value) { + // The engine returns NULL when the URL has no cookies. + if (!value) { + return std::string(); + } + std::string result(value); + free(value); + return result; +} diff --git a/packages/webview_flutter/tizen/src/webview_backend.h b/packages/webview_flutter/tizen/src/webview_backend.h index 90360b86d..bf9a056d6 100644 --- a/packages/webview_flutter/tizen/src/webview_backend.h +++ b/packages/webview_flutter/tizen/src/webview_backend.h @@ -95,12 +95,17 @@ class WebViewBackend { virtual void JavaScriptPromptReply(const std::string& result) = 0; virtual void SetScrollbarVisible(bool visible) = 0; virtual bool ClearCookies() = 0; + virtual std::string GetCookies(const std::string& url) = 0; + virtual bool SetCookie(const std::string& cookie_line, + const std::string& url) = 0; protected: static std::function RegisterPendingTeardown( std::shared_ptr pool, std::function destroy); static void FlushPendingTeardowns(); + + static std::string TakeEngineString(char* value); }; #endif // FLUTTER_PLUGIN_WEBVIEW_BACKEND_H_ diff --git a/packages/webview_flutter/tizen/src/webview_backend_factory.cc b/packages/webview_flutter/tizen/src/webview_backend_factory.cc index ef65d5cca..6d5e23d84 100644 --- a/packages/webview_flutter/tizen/src/webview_backend_factory.cc +++ b/packages/webview_flutter/tizen/src/webview_backend_factory.cc @@ -49,7 +49,9 @@ BackendKind DetectBackend() { const BackendKind kSelectedBackend = DetectBackend(); -bool g_wv_engine_initialized = false; +enum class WvEngineState { kNotStarted, kInitialized, kFailed }; + +WvEngineState g_wv_engine_state = WvEngineState::kNotStarted; } // namespace @@ -57,34 +59,41 @@ std::unique_ptr WebViewBackendFactory::Create( WebViewBackend::Delegate* delegate) { BackendKind kind = kSelectedBackend; if (kind != BackendKind::kEwk) { - if (!g_wv_engine_initialized) { - LOG_ERROR("WV engine is not initialized; cannot create WebView."); - return nullptr; - } return std::make_unique(delegate); } return std::make_unique(delegate); } void WebViewBackendFactory::InitializeEngine() { - BackendKind kind = kSelectedBackend; - if (kind != BackendKind::kEwk) { - if (!WvWebViewBackend::GlobalInitialize(kind == - BackendKind::kWvStandalone)) { - LOG_ERROR("wv_init() failed; engine not started."); - return; - } - g_wv_engine_initialized = true; - return; + if (kSelectedBackend == BackendKind::kEwk) { + EwkWebViewBackend::GlobalInitialize(); + } +} + +bool WebViewBackendFactory::EnsureEngineInitialized(bool engine_policy) { + if (kSelectedBackend == BackendKind::kEwk || + g_wv_engine_state == WvEngineState::kInitialized) { + return true; + } + // Do not retry wv_init() on a possibly half-initialized engine. + if (g_wv_engine_state == WvEngineState::kFailed) { + return false; + } + if (!WvWebViewBackend::GlobalInitialize( + kSelectedBackend == BackendKind::kWvStandalone, engine_policy)) { + LOG_ERROR("wv_init() failed; engine not started."); + g_wv_engine_state = WvEngineState::kFailed; + return false; } - EwkWebViewBackend::GlobalInitialize(); + g_wv_engine_state = WvEngineState::kInitialized; + return true; } void WebViewBackendFactory::ShutdownEngine() { if (kSelectedBackend != BackendKind::kEwk) { - if (g_wv_engine_initialized) { + if (g_wv_engine_state == WvEngineState::kInitialized) { WvWebViewBackend::GlobalShutdown(); - g_wv_engine_initialized = false; + g_wv_engine_state = WvEngineState::kNotStarted; } return; } diff --git a/packages/webview_flutter/tizen/src/webview_backend_factory.h b/packages/webview_flutter/tizen/src/webview_backend_factory.h index 7d30759d2..47694e8c8 100644 --- a/packages/webview_flutter/tizen/src/webview_backend_factory.h +++ b/packages/webview_flutter/tizen/src/webview_backend_factory.h @@ -16,6 +16,8 @@ class WebViewBackendFactory { static void InitializeEngine(); + static bool EnsureEngineInitialized(bool engine_policy); + static void ShutdownEngine(); }; diff --git a/packages/webview_flutter/tizen/src/webview_flutter_tizen_plugin.cc b/packages/webview_flutter/tizen/src/webview_flutter_tizen_plugin.cc index 5c663991c..a929651b0 100644 --- a/packages/webview_flutter/tizen/src/webview_flutter_tizen_plugin.cc +++ b/packages/webview_flutter/tizen/src/webview_flutter_tizen_plugin.cc @@ -5,6 +5,7 @@ #include "webview_flutter_tizen_plugin.h" #include +#include #include #include @@ -15,19 +16,37 @@ namespace { constexpr char kViewType[] = "plugins.flutter.io/webview"; +constexpr char kCookieManagerChannelName[] = + "plugins.flutter.io/tizen_cookie_manager"; // Constructed/destroyed exactly once by flutter-tizen's engine start/stop, // not per-WebView. class WebviewFlutterTizenPlugin : public flutter::Plugin { public: static void RegisterWithRegistrar(flutter::PluginRegistrar* registrar) { - auto plugin = std::make_unique(); + auto plugin = std::make_unique(registrar); registrar->AddPlugin(std::move(plugin)); } - WebviewFlutterTizenPlugin() { WebView::InitializeEngine(); } + explicit WebviewFlutterTizenPlugin(flutter::PluginRegistrar* registrar) { + WebView::InitializeEngine(); - virtual ~WebviewFlutterTizenPlugin() { WebView::ShutdownEngine(); } + cookie_channel_ = std::make_unique( + registrar->messenger(), kCookieManagerChannelName, + &flutter::StandardMethodCodec::GetInstance()); + cookie_channel_->SetMethodCallHandler( + [](const FlMethodCall& call, std::unique_ptr result) { + WebView::HandleCookieMethodCall(call, std::move(result)); + }); + } + + virtual ~WebviewFlutterTizenPlugin() { + cookie_channel_->SetMethodCallHandler(nullptr); + WebView::ShutdownEngine(); + } + + private: + std::unique_ptr cookie_channel_; }; } // namespace diff --git a/packages/webview_flutter/tizen/src/wv_webview_backend.cc b/packages/webview_flutter/tizen/src/wv_webview_backend.cc index 3a2b86b61..85f49db89 100644 --- a/packages/webview_flutter/tizen/src/wv_webview_backend.cc +++ b/packages/webview_flutter/tizen/src/wv_webview_backend.cc @@ -77,7 +77,10 @@ std::map g_view_registry; WvWebViewBackend::WvWebViewBackend(Delegate* delegate) : delegate_(delegate) {} -bool WvWebViewBackend::GlobalInitialize(bool standalone) { +bool WvWebViewBackend::GlobalInitialize(bool standalone, bool engine_policy) { + if (engine_policy && ftpw_webview_flutter_wv_set_version_policy(1) <= 0) { + LOG_WARN("wv_set_version_policy() failed."); + } std::vector argv = { "--disable-pinch", "--js-flags=--expose-gc", @@ -508,6 +511,23 @@ bool WvWebViewBackend::ClearCookies() { return false; } +std::string WvWebViewBackend::GetCookies(const std::string& url) { + return TakeEngineString( + ftpw_webview_flutter_wv_view_get_cookies_for_url(view_, url.c_str())); +} + +bool WvWebViewBackend::SetCookie(const std::string& cookie_line, + const std::string& url) { + void* manager = ftpw_webview_flutter_wv_context_cookie_manager_get( + ftpw_webview_flutter_wv_view_context_get(view_)); + if (!manager) { + return false; + } + ftpw_webview_flutter_wv_cookie_manager_set_cookie_for_url( + manager, cookie_line.c_str(), url.c_str()); + return true; +} + void WvWebViewBackend::OnFrameRendered(void* obj, void* event_info, void* user_data) { if (event_info) { diff --git a/packages/webview_flutter/tizen/src/wv_webview_backend.h b/packages/webview_flutter/tizen/src/wv_webview_backend.h index d68fec686..6452cb4ba 100644 --- a/packages/webview_flutter/tizen/src/wv_webview_backend.h +++ b/packages/webview_flutter/tizen/src/wv_webview_backend.h @@ -69,8 +69,11 @@ class WvWebViewBackend : public WebViewBackend { void JavaScriptPromptReply(const std::string& result) override; void SetScrollbarVisible(bool visible) override; bool ClearCookies() override; + std::string GetCookies(const std::string& url) override; + bool SetCookie(const std::string& cookie_line, + const std::string& url) override; - static bool GlobalInitialize(bool standalone); + static bool GlobalInitialize(bool standalone, bool engine_policy); static void GlobalShutdown();