From c744b3dfff053308c522e29cb05542e13c679b9b Mon Sep 17 00:00:00 2001 From: Seungsoo Lee Date: Wed, 12 Aug 2026 18:20:03 +0900 Subject: [PATCH 1/2] [flutter_inappwebview] Fix SIGTRAP on TV app teardown ewk_init() and ewk_shutdown() were both commented out, guessing that OS-level EFL init and SetArguments() made ewk_init() unnecessary. In practice chromium-efl needs ewk_init()/ewk_shutdown() called exactly once per process: without ewk_init(), some engine state assumed initialized elsewhere is never set up, and on TV targets this surfaces as a SIGTRAP/SIGSEGV during app teardown. Call ewk_init() once from the plugin's constructor and ewk_shutdown() once from its destructor, via new WebView::InitializeEngine()/ShutdownEngine() static helpers. ShutdownEngine() waits (bounded, 2s) for the live WebView instance set to drain first, since ewk_shutdown() fatally CHECKs if any Ewk_View is still alive; normal teardown order (platform views destroyed before the plugin) already guarantees this, so the wait is defensive only. Verified with 3 clean drive runs each on the TV emulator and a real TV device, with no crash and no crash dumps. --- .../src/flutter_inappwebview_tizen_plugin.cc | 3 +- .../flutter_inappwebview/tizen/src/webview.cc | 44 ++++++++++++++----- .../flutter_inappwebview/tizen/src/webview.h | 6 +++ 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/packages/flutter_inappwebview/tizen/src/flutter_inappwebview_tizen_plugin.cc b/packages/flutter_inappwebview/tizen/src/flutter_inappwebview_tizen_plugin.cc index fd77a5be7..472cd0245 100644 --- a/packages/flutter_inappwebview/tizen/src/flutter_inappwebview_tizen_plugin.cc +++ b/packages/flutter_inappwebview/tizen/src/flutter_inappwebview_tizen_plugin.cc @@ -45,6 +45,7 @@ class FlutterInappwebviewTizenPlugin : public flutter::Plugin { cookie_channel) : manager_channel_(std::move(manager_channel)), cookie_channel_(std::move(cookie_channel)) { + WebView::InitializeEngine(); manager_channel_->SetMethodCallHandler( [this](const auto& call, auto result) { HandleManagerMethodCall(call, std::move(result)); @@ -55,7 +56,7 @@ class FlutterInappwebviewTizenPlugin : public flutter::Plugin { }); } - virtual ~FlutterInappwebviewTizenPlugin() {} + virtual ~FlutterInappwebviewTizenPlugin() { WebView::ShutdownEngine(); } private: void HandleManagerMethodCall( diff --git a/packages/flutter_inappwebview/tizen/src/webview.cc b/packages/flutter_inappwebview/tizen/src/webview.cc index 323947569..57966762c 100644 --- a/packages/flutter_inappwebview/tizen/src/webview.cc +++ b/packages/flutter_inappwebview/tizen/src/webview.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -212,6 +213,35 @@ bool WebView::ClearAllCookies() { return false; } +// static +void WebView::InitializeEngine() { ewk_init(); } + +// static +void WebView::ShutdownEngine() { + // WebView::Dispose() erases from instances_ synchronously, so by normal + // plugin teardown order (platform views destroyed before the plugin + // itself) this is already empty. Wait defensively anyway: ewk_shutdown() + // fatally CHECKs (SIGTRAP) if any Ewk_View is still alive. + constexpr gint64 kDeadlineUsec = 2 * G_USEC_PER_SEC; + const gint64 deadline = g_get_monotonic_time() + kDeadlineUsec; + for (;;) { + { + std::lock_guard lock(instances_mutex_); + if (instances_.empty()) { + break; + } + } + if (g_get_monotonic_time() >= deadline) { + LOG_WARN( + "ShutdownEngine: WebView instance(s) still alive past the " + "deadline; calling ewk_shutdown() anyway."); + break; + } + g_usleep(1000); + } + ewk_shutdown(); +} + std::string WebView::GetDefaultUserAgent() { std::lock_guard lock(instances_mutex_); for (auto* instance : instances_) { @@ -369,8 +399,6 @@ void WebView::Dispose() { } ecore_evas_ = nullptr; - - // ewk_shutdown(); } void WebView::Offset(double left, double top) { @@ -530,15 +558,9 @@ bool WebView::InitWebView() { chromium_argv); }); - // TODO(jsuya): ewk_init() and ewk_shutdown() are designed to be called only - // once in a process.(If ewk_init() is called after ewk_shutdown() is - // called, SIGTRAP is called internally.) ewk_init() initializes the efl - // modules and web engine's arguments data. The efl modules are initialized - // by default in OS, and arguments data is also initialized through - // SetArguments() API, so calling ewk_init() is not necessary. Therefore, - // temporarily comment out ewk_init() and ewk_shutdown(). It can be reverted - // depending on updates to chromium-efl. - // ewk_init(); + // ewk_init()/ewk_shutdown() are called once per process by + // WebView::InitializeEngine()/ShutdownEngine(), driven by the plugin's + // constructor/destructor. static Ecore_Evas* shared_ecore_evas = nullptr; if (!shared_ecore_evas) { shared_ecore_evas = ecore_evas_new("wayland_egl", 0, 0, 1, 1, 0); diff --git a/packages/flutter_inappwebview/tizen/src/webview.h b/packages/flutter_inappwebview/tizen/src/webview.h index cf42b38f0..7823d0fd7 100644 --- a/packages/flutter_inappwebview/tizen/src/webview.h +++ b/packages/flutter_inappwebview/tizen/src/webview.h @@ -70,6 +70,12 @@ class WebView : public PlatformView { static bool ClearAllCookies(); static std::string GetDefaultUserAgent(); + // Must be called exactly once, before any WebView is constructed. + static void InitializeEngine(); + // Must be called exactly once, after every WebView has been destroyed. + // ewk_shutdown() fatally CHECKs if any Ewk_View is still alive. + static void ShutdownEngine(); + private: void HandleWebViewMethodCall(const FlMethodCall& method_call, std::unique_ptr result); From 4211a8498d55d69e17ade187e46adfc370b5cfea Mon Sep 17 00:00:00 2001 From: Seungsoo Lee Date: Wed, 12 Aug 2026 18:20:51 +0900 Subject: [PATCH 2/2] [flutter_inappwebview] Bump flutter_inappwebview_tizen to 0.1.3 --- packages/flutter_inappwebview/CHANGELOG.md | 4 ++++ packages/flutter_inappwebview/README.md | 2 +- packages/flutter_inappwebview/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/flutter_inappwebview/CHANGELOG.md b/packages/flutter_inappwebview/CHANGELOG.md index 0ad08baff..3e0240bd7 100644 --- a/packages/flutter_inappwebview/CHANGELOG.md +++ b/packages/flutter_inappwebview/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.3 + +- Fix a SIGTRAP crash on TV app teardown by calling `ewk_init()`/`ewk_shutdown()` exactly once per process. + ## 0.1.2 * Update analysis_options.yaml for Flutter 3.47.0. diff --git a/packages/flutter_inappwebview/README.md b/packages/flutter_inappwebview/README.md index f932e7e1c..d81cd44f4 100644 --- a/packages/flutter_inappwebview/README.md +++ b/packages/flutter_inappwebview/README.md @@ -26,7 +26,7 @@ Add the internet privilege to the app manifest: ```yaml dependencies: flutter_inappwebview: ^6.1.5 - flutter_inappwebview_tizen: ^0.1.2 + flutter_inappwebview_tizen: ^0.1.3 ``` ```dart diff --git a/packages/flutter_inappwebview/pubspec.yaml b/packages/flutter_inappwebview/pubspec.yaml index ca70a4725..414f89400 100644 --- a/packages/flutter_inappwebview/pubspec.yaml +++ b/packages/flutter_inappwebview/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_inappwebview_tizen description: Tizen implementation of the flutter_inappwebview plugin. homepage: https://github.com/flutter-tizen/plugins repository: https://github.com/flutter-tizen/plugins/tree/main/packages/flutter_inappwebview -version: 0.1.2 +version: 0.1.3 environment: sdk: ">=3.8.0 <4.0.0"