Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
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
31 changes: 27 additions & 4 deletions shell/platform/windows/flutter_windows.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,27 @@ static FlutterDesktopTextureRegistrarRef HandleForTextureRegistrar(
return reinterpret_cast<FlutterDesktopTextureRegistrarRef>(registrar);
}

FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
// Creates a view controller that might own the engine.
//
// If `owns_engine` is true, then the returned `FlutterDesktopViewControllerRef`
// owns `engine_ref` and will deallocate `engine_ref` upon its own destruction.
static FlutterDesktopViewControllerRef CreateViewController(
FlutterDesktopEngineRef engine_ref,
int width,
int height,
FlutterDesktopEngineRef engine_ref) {
bool owns_engine) {
flutter::FlutterWindowsEngine* engine_ptr = EngineFromHandle(engine_ref);
std::unique_ptr<flutter::WindowBindingHandler> window_wrapper =
std::make_unique<flutter::FlutterWindow>(
width, height, engine_ptr->windows_proc_table());

auto engine = std::unique_ptr<flutter::FlutterWindowsEngine>(engine_ptr);
std::unique_ptr<flutter::FlutterWindowsEngine> engine;
if (owns_engine) {
engine = std::unique_ptr<flutter::FlutterWindowsEngine>(engine_ptr);
}

std::unique_ptr<flutter::FlutterWindowsView> view =
engine->CreateView(std::move(window_wrapper));
engine_ptr->CreateView(std::move(window_wrapper));
auto controller = std::make_unique<flutter::FlutterWindowsViewController>(
std::move(engine), std::move(view));

Expand All @@ -105,6 +114,20 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
return HandleForViewController(controller.release());
}

FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
int width,
int height,
FlutterDesktopEngineRef engine) {
return CreateViewController(engine, width, height, /*owns_engine=*/true);
}

FlutterDesktopViewControllerRef FlutterDesktopEngineCreateViewController(
FlutterDesktopEngineRef engine,
const FlutterDesktopViewControllerProperties* properties) {
return CreateViewController(engine, properties->width, properties->height,
/*owns_engine=*/false);
}

void FlutterDesktopViewControllerDestroy(FlutterDesktopViewControllerRef ref) {
auto controller = ViewControllerFromHandle(ref);
delete controller;
Expand Down
25 changes: 25 additions & 0 deletions shell/platform/windows/flutter_windows_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,31 @@ extern "C" {
// Declare functions that are currently in-progress and shall be exposed to the
// public facing API upon completion.

// Properties for configuring a Flutter view controller.
typedef struct {
// The view's initial width.
int width;

// The view's initial height.
int height;
} FlutterDesktopViewControllerProperties;

// Creates a view for the given engine.
//
// The |engine| will be started if it is not already running.
//
// The caller owns the returned reference, and is responsible for calling
// |FlutterDesktopViewControllerDestroy|. Returns a null pointer in the event of
// an error.
//
// Unlike |FlutterDesktopViewControllerCreate|, this does *not* take ownership
Copy link
Contributor

Choose a reason for hiding this comment

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

We might want to add a similar paragraph to FlutterDesktopViewControllerCreate as well, so that they can refer to each other. And also we might want to mention that:

// In an app with multiple view controllers, it is highly recommend to use
// `FlutterDesktopEngineCreateViewController` for all view controllers and avoid
// `FlutterDesktopViewControllerCreate`.

Copy link
Member Author

@loic-sharma loic-sharma Mar 21, 2024

Choose a reason for hiding this comment

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

We'll definitely want a blurb like this eventually, however, FlutterDesktopEngineCreateViewController isn't in the public header yet. Adding this right now would be confusing to our customers as they can't use this API yet.

I'll make sure to add such a comment when we make this runner API public.

// of |engine| and |FlutterDesktopEngineDestroy| must be called to destroy
// the engine.
FLUTTER_EXPORT FlutterDesktopViewControllerRef
FlutterDesktopEngineCreateViewController(
FlutterDesktopEngineRef engine,
const FlutterDesktopViewControllerProperties* properties);

typedef int64_t PlatformViewId;

typedef struct {
Expand Down
21 changes: 21 additions & 0 deletions shell/platform/windows/flutter_windows_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,27 @@ TEST_F(WindowsTest, LaunchHeadlessEngine) {
ASSERT_NE(engine, nullptr);
}

// Verify that the engine can return to headless mode.
TEST_F(WindowsTest, EngineCanTransitionToHeadless) {
auto& context = GetContext();
WindowsConfigBuilder builder(context);
EnginePtr engine{builder.RunHeadless()};
ASSERT_NE(engine, nullptr);

// Create and then destroy a view controller that does not own its engine.
// This causes the engine to transition back to headless mode.
{
FlutterDesktopViewControllerProperties properties = {};
ViewControllerPtr controller{
FlutterDesktopEngineCreateViewController(engine.get(), &properties)};

ASSERT_NE(controller, nullptr);
}

// The engine is back in headless mode now.
ASSERT_NE(engine, nullptr);
}

// Verify that accessibility features are initialized when a view is created.
TEST_F(WindowsTest, LaunchRefreshesAccessibility) {
auto& context = GetContext();
Expand Down
13 changes: 12 additions & 1 deletion shell/platform/windows/flutter_windows_view_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,22 @@ class FlutterWindowsViewController {
std::unique_ptr<FlutterWindowsView> view)
: engine_(std::move(engine)), view_(std::move(view)) {}

FlutterWindowsEngine* engine() { return engine_.get(); }
FlutterWindowsEngine* engine() { return view_->GetEngine(); }
FlutterWindowsView* view() { return view_.get(); }

private:
// The engine owned by this view controller, if any.
//
// This is used only if the view controller was created
// using |FlutterDesktopViewControllerCreate| as that takes
// ownership of the engine. Destroying this view controller
// also destroys the engine.
//
// View controllers created using |FlutterDesktopEngineCreateViewController|
// do not take ownership of the engine and this will be null. Destroying
// this view controller does not destroy the engine.
std::unique_ptr<FlutterWindowsEngine> engine_;

std::unique_ptr<FlutterWindowsView> view_;
};

Expand Down
2 changes: 2 additions & 0 deletions shell/platform/windows/testing/windows_test_config_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ ViewControllerPtr WindowsConfigBuilder::Run() const {

int width = 600;
int height = 400;

// Create a view controller that owns the engine.
ViewControllerPtr controller{
FlutterDesktopViewControllerCreate(width, height, engine.release())};
if (!controller) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class WindowsConfigBuilder {
EnginePtr RunHeadless() const;

// Returns a configured and initialized view controller that runs the
// configured Dart entrypoint.
// configured Dart entrypoint and owns its engine.
//
// Returns null on failure.
ViewControllerPtr Run() const;
Expand Down