Skip to content
Merged
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
6 changes: 1 addition & 5 deletions engine/src/flutter/runtime/shorebird/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ source_set("patch_cache") {
deps = [
"//flutter/fml",
"//flutter/runtime:libdart",
"//flutter/shell/common/shorebird:updater",
]

# For shorebird_report_launch_start() in updater.h
# The include path "third_party/updater/library/include/updater.h" is relative
# to //flutter/, which is already in the default include path.
include_dirs = [ "//flutter" ]
}
5 changes: 3 additions & 2 deletions engine/src/flutter/runtime/shorebird/patch_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
#include "flutter/fml/logging.h"
#include "flutter/fml/mapping.h"
#include "flutter/runtime/shorebird/patch_mapping.h"
#include "third_party/updater/library/include/updater.h"
#include "flutter/shell/common/shorebird/updater.h"
#include "third_party/dart/runtime/include/dart_api.h"

namespace flutter {

Expand Down Expand Up @@ -161,7 +162,7 @@ std::shared_ptr<const fml::Mapping> TryLoadFromPatch(
if (symbol == kIsolateDataSymbol) {
std::call_once(launch_start_flag, []() {
FML_LOG(INFO) << "Reporting launch start for patch";
shorebird_report_launch_start();
shorebird::Updater::Instance().ReportLaunchStart();
});
return PatchMapping::CreateIsolateData(cache_entry);
} else {
Expand Down
29 changes: 2 additions & 27 deletions engine/src/flutter/shell/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,12 @@ source_set("common") {
"//flutter/lib/ui",
"//flutter/runtime",
"//flutter/shell/common:base64",
"//flutter/shell/common/shorebird:updater",
"//flutter/shell/geometry",
"//flutter/shell/profiling",
"//flutter/skia",
]

include_dirs = [ "//flutter/updater" ]

if (impeller_supports_rendering) {
sources += [
"snapshot_controller_impeller.cc",
Expand All @@ -163,31 +162,6 @@ source_set("common") {

deps += [ "//flutter/impeller" ]
}

# Needed to compile flutter_tester for macOS.
if (host_os == "mac" && target_os == "mac") {
if (target_cpu == "arm64") {
libs = [ "//flutter/third_party/updater/target/aarch64-apple-darwin/release/libupdater.a" ]
} else if (target_cpu == "x64") {
libs = [ "//flutter/third_party/updater/target/x86_64-apple-darwin/release/libupdater.a" ]
}
}

# Needed to compile flutter_tester for Windows.
if (host_os == "win" && target_os == "win") {
if (target_cpu == "x64") {
libs = [
"userenv.lib",
"//flutter/third_party/updater/target/x86_64-pc-windows-msvc/release/updater.lib",
]
}
}

if (host_os == "linux" && target_os == "linux") {
if (target_cpu == "x64") {
libs = [ "//flutter/third_party/updater/target/x86_64-unknown-linux-gnu/release/libupdater.a" ]
}
}
}

# These are in their own source_set to avoid a dependency cycle with //common/graphics
Expand Down Expand Up @@ -364,6 +338,7 @@ if (enable_unittests) {
"//flutter/common/graphics",
"//flutter/display_list/testing:display_list_testing",
"//flutter/shell/common:base64",
"//flutter/shell/common/shorebird:updater",
"//flutter/shell/profiling:profiling_unittests",
"//flutter/shell/version",
"//flutter/testing:fixture_test",
Expand Down
11 changes: 5 additions & 6 deletions engine/src/flutter/shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
#include "third_party/skia/include/core/SkGraphics.h"
#include "third_party/tonic/common/log.h"

#include "third_party/updater/library/include/updater.h"
#include "flutter/shell/common/shorebird/updater.h"

namespace flutter {

Expand Down Expand Up @@ -523,14 +523,13 @@ Shell::Shell(DartVMRef vm,
is_gpu_disabled_sync_switch_(new fml::SyncSwitch(is_gpu_disabled)),
weak_factory_gpu_(nullptr),
weak_factory_(this) {
// FIXME: This is probably the wrong place to hook into.
#if SHOREBIRD_PLATFORM_SUPPORTED
// Report launch status to Shorebird updater for crash recovery tracking.
// On unsupported platforms, NoOpUpdater handles these calls gracefully.
if (!vm_) {
shorebird_report_launch_failure();
shorebird::Updater::Instance().ReportLaunchFailure();
} else {
shorebird_report_launch_success();
shorebird::Updater::Instance().ReportLaunchSuccess();
}
#endif
FML_CHECK(!settings.enable_software_rendering || !settings.enable_impeller)
<< "Software rendering is incompatible with Impeller.";
if (!settings.enable_impeller && settings.warn_on_impeller_opt_out) {
Expand Down
62 changes: 62 additions & 0 deletions engine/src/flutter/shell/common/shell_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
#include "third_party/skia/include/codec/SkCodecAnimation.h"
#include "third_party/tonic/converter/dart_converter.h"

#include "flutter/shell/common/shorebird/updater.h"

#ifdef SHELL_ENABLE_VULKAN
#include "flutter/vulkan/vulkan_application.h" // nogncheck
#endif
Expand Down Expand Up @@ -5107,6 +5109,66 @@ TEST_F(ShellTest, ShoulDiscardLayerTreeIfFrameIsSizedIncorrectly) {
DestroyShell(std::move(shell), task_runners);
}

// Test that Shell creation triggers the Shorebird Updater's ReportLaunchSuccess
// call. This is important for the crash recovery mechanism to work correctly.
TEST_F(ShellTest, ShorebirdUpdaterReportLaunchSuccessOnShellCreation) {
// Install a mock updater before creating the shell
auto mock = std::make_unique<shorebird::MockUpdater>();
auto* mock_ptr = mock.get();
shorebird::Updater::SetInstanceForTesting(std::move(mock));

EXPECT_EQ(mock_ptr->launch_success_count(), 0);
EXPECT_EQ(mock_ptr->launch_failure_count(), 0);

auto settings = CreateSettingsForFixture();
auto task_runners = GetTaskRunnersForFixture();
auto shell = CreateShell(settings, task_runners);
ASSERT_TRUE(shell);

// Shell constructor should have called ReportLaunchSuccess
EXPECT_EQ(mock_ptr->launch_success_count(), 1);
EXPECT_EQ(mock_ptr->launch_failure_count(), 0);

// Verify the call was logged
const auto& log = mock_ptr->call_log();
EXPECT_TRUE(std::find(log.begin(), log.end(), "ReportLaunchSuccess") !=
log.end());

DestroyShell(std::move(shell), task_runners);

// Clean up - reset the updater instance
shorebird::Updater::ResetInstanceForTesting();
}

// Test that creating multiple shells only calls ReportLaunchSuccess for each
// shell. This verifies that each Shell reports its own launch status.
TEST_F(ShellTest, ShorebirdUpdaterReportLaunchSuccessForMultipleShells) {
auto mock = std::make_unique<shorebird::MockUpdater>();
auto* mock_ptr = mock.get();
shorebird::Updater::SetInstanceForTesting(std::move(mock));

EXPECT_EQ(mock_ptr->launch_success_count(), 0);

auto settings = CreateSettingsForFixture();

// Create first shell
auto task_runners1 = GetTaskRunnersForFixture();
auto shell1 = CreateShell(settings, task_runners1);
ASSERT_TRUE(shell1);
EXPECT_EQ(mock_ptr->launch_success_count(), 1);

// Create second shell
auto task_runners2 = GetTaskRunnersForFixture();
auto shell2 = CreateShell(settings, task_runners2);
ASSERT_TRUE(shell2);
EXPECT_EQ(mock_ptr->launch_success_count(), 2);

DestroyShell(std::move(shell1), task_runners1);
DestroyShell(std::move(shell2), task_runners2);

shorebird::Updater::ResetInstanceForTesting();
}

} // namespace testing
} // namespace flutter

Expand Down
57 changes: 53 additions & 4 deletions engine/src/flutter/shell/common/shorebird/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,56 @@ source_set("snapshots_data_handle") {
]
}

# C++ wrapper around the Rust updater C API.
# This provides a testable abstraction layer that can be mocked for testing.
source_set("updater") {
sources = [
"updater.cc",
"updater.h",
]

deps = [ "//flutter/fml" ]

# For the Rust updater C API (shorebird_report_launch_start, etc.)
include_dirs = [ "//flutter" ]

# Link the Rust updater static library based on target platform.
if (is_android) {
if (target_cpu == "arm") {
libs = [ "//flutter/third_party/updater/target/armv7-linux-androideabi/release/libupdater.a" ]
} else if (target_cpu == "arm64") {
libs = [ "//flutter/third_party/updater/target/aarch64-linux-android/release/libupdater.a" ]
} else if (target_cpu == "x64") {
libs = [ "//flutter/third_party/updater/target/x86_64-linux-android/release/libupdater.a" ]
} else if (target_cpu == "x86") {
libs = [ "//flutter/third_party/updater/target/i686-linux-android/release/libupdater.a" ]
}
} else if (is_ios) {
if (target_cpu == "arm64") {
libs = [ "//flutter/third_party/updater/target/aarch64-apple-ios/release/libupdater.a" ]
} else if (target_cpu == "x64") {
libs = [ "//flutter/third_party/updater/target/x86_64-apple-ios/release/libupdater.a" ]
}
} else if (is_mac) {
if (target_cpu == "arm64") {
libs = [ "//flutter/third_party/updater/target/aarch64-apple-darwin/release/libupdater.a" ]
} else if (target_cpu == "x64") {
libs = [ "//flutter/third_party/updater/target/x86_64-apple-darwin/release/libupdater.a" ]
}
} else if (is_win) {
if (target_cpu == "x64") {
libs = [
"userenv.lib",
"//flutter/third_party/updater/target/x86_64-pc-windows-msvc/release/updater.lib",
]
}
} else if (is_linux) {
if (target_cpu == "x64") {
libs = [ "//flutter/third_party/updater/target/x86_64-unknown-linux-gnu/release/libupdater.a" ]
}
}
}

source_set("shorebird") {
sources = [
"shorebird.cc",
Expand All @@ -23,14 +73,13 @@ source_set("shorebird") {

deps = [
":snapshots_data_handle",
":updater",
"//flutter/fml",
"//flutter/runtime",
"//flutter/runtime:libdart",
"//flutter/shell/common",
"//flutter/shell/platform/embedder:embedder_headers",
]

include_dirs = [ "//flutter/updater" ]
}

if (enable_unittests) {
Expand All @@ -45,14 +94,14 @@ if (enable_unittests) {
"patch_cache_unittests.cc",
"shorebird_unittests.cc",
"snapshots_data_handle_unittests.cc",
"updater_unittests.cc",
]

# This only includes snapshots_data_handle and not shorebird because
# shorebird fails to link due to a missing updater lib.
deps = [
":shorebird",
":shorebird_fixtures",
":snapshots_data_handle",
":updater",
"//flutter/runtime",
"//flutter/runtime/shorebird:patch_cache",
"//flutter/testing",
Expand Down
Loading
Loading