Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/flutter_inappwebview/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_inappwebview/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_inappwebview/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Guard the EWK lifecycle process-wide

When a Flutter engine is destroyed and recreated in the same process, each new plugin instance calls ewk_init() and the previous instance has already called ewk_shutdown(). This is a per-plugin lifecycle rather than the promised process-wide once-only lifecycle, and the existing EWK constraint described by this change says reinitialization after shutdown triggers SIGTRAP; use process-wide ownership/once semantics instead of pairing the calls with every plugin instance.

Useful? React with 👍 / 👎.

manager_channel_->SetMethodCallHandler(
[this](const auto& call, auto result) {
HandleManagerMethodCall(call, std::move(result));
Expand All @@ -55,7 +56,7 @@ class FlutterInappwebviewTizenPlugin : public flutter::Plugin {
});
}

virtual ~FlutterInappwebviewTizenPlugin() {}
virtual ~FlutterInappwebviewTizenPlugin() { WebView::ShutdownEngine(); }

private:
void HandleManagerMethodCall(
Expand Down
44 changes: 33 additions & 11 deletions packages/flutter_inappwebview/tizen/src/webview.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <app_common.h>
#include <flutter/standard_method_codec.h>
#include <flutter_texture_registrar.h>
#include <glib.h>
#include <tbm_surface.h>

#include <atomic>
Expand Down Expand Up @@ -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<std::mutex> 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;
Comment on lines +234 to +238

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not shut EWK down while views remain

When a platform view is still registered after this deadline—for example, if plugin teardown begins before its platform-view teardown can run—the loop merely logs and then reaches ewk_shutdown() with a live Ewk_View. The comment immediately above documents that this condition fatally CHECKs with SIGTRAP, so this fallback deterministically reproduces the crash it is intended to prevent; teardown must either dispose/flush the remaining views or skip shutdown rather than continuing.

Useful? React with 👍 / 👎.

}
g_usleep(1000);
}
ewk_shutdown();
}

std::string WebView::GetDefaultUserAgent() {
std::lock_guard<std::mutex> lock(instances_mutex_);
for (auto* instance : instances_) {
Expand Down Expand Up @@ -369,8 +399,6 @@ void WebView::Dispose() {
}

ecore_evas_ = nullptr;

// ewk_shutdown();
}

void WebView::Offset(double left, double top) {
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions packages/flutter_inappwebview/tizen/src/webview.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<FlMethodResult> result);
Expand Down
Loading