Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e16a260

Browse files
authored
[Windows] Make the engine create the view (#50673)
This makes the Windows engine create views. Benefits: 1. This will allow the engine to assign IDs to views as it creates them. This will be added in a subsequent change 2. Previously views needed special logic to not crash if they were used before an engine was attached to them. Now, views are always attached to an engine. Part of flutter/flutter#137267 Part of flutter/flutter#142845 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 61839fa commit e16a260

16 files changed

+289
-297
lines changed

shell/platform/windows/accessibility_bridge_windows_unittests.cc

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace flutter {
2626
namespace testing {
2727

2828
namespace {
29+
using ::testing::NiceMock;
2930

3031
// A structure representing a Win32 MSAA event targeting a specified node.
3132
struct MsaaEvent {
@@ -88,8 +89,9 @@ class AccessibilityBridgeWindowsSpy : public AccessibilityBridgeWindows {
8889
// AccessibilityBridgeWindowsSpy.
8990
class FlutterWindowsViewSpy : public FlutterWindowsView {
9091
public:
91-
explicit FlutterWindowsViewSpy(std::unique_ptr<WindowBindingHandler> handler)
92-
: FlutterWindowsView(std::move(handler)) {}
92+
FlutterWindowsViewSpy(FlutterWindowsEngine* engine,
93+
std::unique_ptr<WindowBindingHandler> handler)
94+
: FlutterWindowsView(engine, std::move(handler)) {}
9395

9496
protected:
9597
virtual std::shared_ptr<AccessibilityBridgeWindows>
@@ -187,10 +189,10 @@ void ExpectWinEventFromAXEvent(int32_t node_id,
187189
ui::AXEventGenerator::Event ax_event,
188190
ax::mojom::Event expected_event) {
189191
auto engine = GetTestEngine();
190-
auto window_binding_handler =
191-
std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
192-
FlutterWindowsViewSpy view(std::move(window_binding_handler));
193-
view.SetEngine(engine.get());
192+
FlutterWindowsViewSpy view{
193+
engine.get(), std::make_unique<NiceMock<MockWindowBindingHandler>>()};
194+
EngineModifier modifier{engine.get()};
195+
modifier.SetImplicitView(&view);
194196
view.OnUpdateSemanticsEnabled(true);
195197

196198
auto bridge = GetAccessibilityBridgeSpy(view);
@@ -208,10 +210,10 @@ void ExpectWinEventFromAXEventOnFocusNode(int32_t node_id,
208210
ax::mojom::Event expected_event,
209211
int32_t focus_id) {
210212
auto engine = GetTestEngine();
211-
auto window_binding_handler =
212-
std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
213-
FlutterWindowsViewSpy view(std::move(window_binding_handler));
214-
view.SetEngine(engine.get());
213+
FlutterWindowsViewSpy view{
214+
engine.get(), std::make_unique<NiceMock<MockWindowBindingHandler>>()};
215+
EngineModifier modifier{engine.get()};
216+
modifier.SetImplicitView(&view);
215217
view.OnUpdateSemanticsEnabled(true);
216218

217219
auto bridge = GetAccessibilityBridgeSpy(view);
@@ -234,10 +236,10 @@ void ExpectWinEventFromAXEventOnFocusNode(int32_t node_id,
234236

235237
TEST(AccessibilityBridgeWindows, GetParent) {
236238
auto engine = GetTestEngine();
237-
auto window_binding_handler =
238-
std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
239-
FlutterWindowsViewSpy view(std::move(window_binding_handler));
240-
view.SetEngine(engine.get());
239+
FlutterWindowsViewSpy view{
240+
engine.get(), std::make_unique<NiceMock<MockWindowBindingHandler>>()};
241+
EngineModifier modifier{engine.get()};
242+
modifier.SetImplicitView(&view);
241243
view.OnUpdateSemanticsEnabled(true);
242244

243245
auto bridge = view.accessibility_bridge().lock();
@@ -251,10 +253,10 @@ TEST(AccessibilityBridgeWindows, GetParent) {
251253

252254
TEST(AccessibilityBridgeWindows, GetParentOnRootRetunsNullptr) {
253255
auto engine = GetTestEngine();
254-
auto window_binding_handler =
255-
std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
256-
FlutterWindowsViewSpy view(std::move(window_binding_handler));
257-
view.SetEngine(engine.get());
256+
FlutterWindowsViewSpy view{
257+
engine.get(), std::make_unique<NiceMock<MockWindowBindingHandler>>()};
258+
EngineModifier modifier{engine.get()};
259+
modifier.SetImplicitView(&view);
258260
view.OnUpdateSemanticsEnabled(true);
259261

260262
auto bridge = view.accessibility_bridge().lock();
@@ -266,17 +268,16 @@ TEST(AccessibilityBridgeWindows, GetParentOnRootRetunsNullptr) {
266268

267269
TEST(AccessibilityBridgeWindows, DispatchAccessibilityAction) {
268270
auto engine = GetTestEngine();
269-
auto window_binding_handler =
270-
std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
271-
FlutterWindowsViewSpy view(std::move(window_binding_handler));
272-
view.SetEngine(engine.get());
271+
FlutterWindowsViewSpy view{
272+
engine.get(), std::make_unique<NiceMock<MockWindowBindingHandler>>()};
273+
EngineModifier modifier{engine.get()};
274+
modifier.SetImplicitView(&view);
273275
view.OnUpdateSemanticsEnabled(true);
274276

275277
auto bridge = view.accessibility_bridge().lock();
276278
PopulateAXTree(bridge);
277279

278280
FlutterSemanticsAction actual_action = kFlutterSemanticsActionTap;
279-
EngineModifier modifier(view.GetEngine());
280281
modifier.embedder_api().DispatchSemanticsAction = MOCK_ENGINE_PROC(
281282
DispatchSemanticsAction,
282283
([&actual_action](FLUTTER_API_SYMBOL(FlutterEngine) engine, uint64_t id,
@@ -303,10 +304,10 @@ TEST(AccessibilityBridgeWindows, OnAccessibilityEventChildrenChanged) {
303304

304305
TEST(AccessibilityBridgeWindows, OnAccessibilityEventFocusChanged) {
305306
auto engine = GetTestEngine();
306-
auto window_binding_handler =
307-
std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
308-
FlutterWindowsViewSpy view(std::move(window_binding_handler));
309-
view.SetEngine(engine.get());
307+
FlutterWindowsViewSpy view{
308+
engine.get(), std::make_unique<NiceMock<MockWindowBindingHandler>>()};
309+
EngineModifier modifier{engine.get()};
310+
modifier.SetImplicitView(&view);
310311
view.OnUpdateSemanticsEnabled(true);
311312

312313
auto bridge = GetAccessibilityBridgeSpy(view);

shell/platform/windows/compositor_opengl_unittests.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class CompositorOpenGLTest : public WindowsTest {
8484
FlutterWindowsEngineBuilder builder{GetContext()};
8585

8686
engine_ = builder.Build();
87-
EngineModifier modifier(engine_.get());
87+
EngineModifier modifier{engine_.get()};
8888
modifier.SetEGLManager(std::move(egl_manager));
8989
}
9090

@@ -95,7 +95,8 @@ class CompositorOpenGLTest : public WindowsTest {
9595
EXPECT_CALL(*window.get(), SetView).Times(1);
9696
EXPECT_CALL(*window.get(), GetWindowHandle).WillRepeatedly(Return(nullptr));
9797

98-
view_ = std::make_unique<FlutterWindowsView>(std::move(window));
98+
view_ =
99+
std::make_unique<FlutterWindowsView>(engine_.get(), std::move(window));
99100

100101
if (add_surface) {
101102
auto surface = std::make_unique<egl::MockWindowSurface>();
@@ -107,7 +108,8 @@ class CompositorOpenGLTest : public WindowsTest {
107108
modifier.SetSurface(std::move(surface));
108109
}
109110

110-
engine_->SetView(view_.get());
111+
EngineModifier modifier{engine_.get()};
112+
modifier.SetImplicitView(view_.get());
111113
}
112114

113115
private:

shell/platform/windows/compositor_software_unittests.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ using ::testing::Return;
2222

2323
class MockFlutterWindowsView : public FlutterWindowsView {
2424
public:
25-
MockFlutterWindowsView(std::unique_ptr<WindowBindingHandler> window)
26-
: FlutterWindowsView(std::move(window)) {}
25+
MockFlutterWindowsView(FlutterWindowsEngine* engine,
26+
std::unique_ptr<WindowBindingHandler> window)
27+
: FlutterWindowsView(engine, std::move(window)) {}
2728
virtual ~MockFlutterWindowsView() = default;
2829

2930
MOCK_METHOD(bool,
@@ -59,9 +60,11 @@ class CompositorSoftwareTest : public WindowsTest {
5960
EXPECT_CALL(*window.get(), GetWindowHandle).WillRepeatedly(Return(nullptr));
6061

6162
engine_ = builder.Build();
62-
view_ = std::make_unique<MockFlutterWindowsView>(std::move(window));
63+
view_ = std::make_unique<MockFlutterWindowsView>(engine_.get(),
64+
std::move(window));
6365

64-
engine_->SetView(view_.get());
66+
EngineModifier modifier{engine_.get()};
67+
modifier.SetImplicitView(view_.get());
6568
}
6669

6770
private:

shell/platform/windows/cursor_handler_unittests.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h"
1212
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h"
1313
#include "flutter/shell/platform/windows/flutter_windows_view.h"
14+
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
1415
#include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
1516
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
1617
#include "flutter/shell/platform/windows/testing/test_binary_messenger.h"
@@ -73,14 +74,16 @@ class CursorHandlerTest : public WindowsTest {
7374
FlutterWindowsEngineBuilder builder{GetContext()};
7475

7576
auto window = std::make_unique<MockWindowBindingHandler>();
77+
EXPECT_CALL(*window.get(), SetView).Times(1);
78+
EXPECT_CALL(*window.get(), GetWindowHandle).WillRepeatedly(Return(nullptr));
7679

7780
window_ = window.get();
78-
EXPECT_CALL(*window_, SetView).Times(1);
79-
8081
engine_ = builder.Build();
81-
view_ = std::make_unique<FlutterWindowsView>(std::move(window));
82+
view_ =
83+
std::make_unique<FlutterWindowsView>(engine_.get(), std::move(window));
8284

83-
engine_->SetView(view_.get());
85+
EngineModifier modifier{engine_.get()};
86+
modifier.SetImplicitView(view_.get());
8487
}
8588

8689
private:

shell/platform/windows/flutter_window_unittests.cc

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "flutter/fml/macros.h"
66
#include "flutter/shell/platform/windows/flutter_window.h"
7+
#include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
78
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
89
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler_delegate.h"
910
#include "flutter/shell/platform/windows/testing/windows_test.h"
@@ -26,7 +27,7 @@ static constexpr int32_t kDefaultPointerDeviceId = 0;
2627
class MockFlutterWindow : public FlutterWindow {
2728
public:
2829
MockFlutterWindow(bool reset_view_on_exit = true)
29-
: FlutterWindow(), reset_view_on_exit_(reset_view_on_exit) {
30+
: reset_view_on_exit_(reset_view_on_exit) {
3031
ON_CALL(*this, GetDpiScale())
3132
.WillByDefault(Return(this->FlutterWindow::GetDpiScale()));
3233
}
@@ -95,8 +96,9 @@ class MockFlutterWindow : public FlutterWindow {
9596

9697
class MockFlutterWindowsView : public FlutterWindowsView {
9798
public:
98-
MockFlutterWindowsView(std::unique_ptr<WindowBindingHandler> window_binding)
99-
: FlutterWindowsView(std::move(window_binding)) {}
99+
MockFlutterWindowsView(FlutterWindowsEngine* engine,
100+
std::unique_ptr<WindowBindingHandler> window_binding)
101+
: FlutterWindowsView(engine, std::move(window_binding)) {}
100102
~MockFlutterWindowsView() {}
101103

102104
MOCK_METHOD(void,
@@ -313,12 +315,14 @@ TEST_F(FlutterWindowTest, AccessibilityNodeWithoutView) {
313315
// Ensure that announcing the alert propagates the message to the alert node.
314316
// Different screen readers use different properties for alerts.
315317
TEST_F(FlutterWindowTest, AlertNode) {
316-
std::unique_ptr<MockFlutterWindow> win32window =
317-
std::make_unique<MockFlutterWindow>();
318+
std::unique_ptr<FlutterWindowsEngine> engine =
319+
FlutterWindowsEngineBuilder{GetContext()}.Build();
320+
auto win32window = std::make_unique<MockFlutterWindow>();
318321
EXPECT_CALL(*win32window.get(), GetAxFragmentRootDelegate())
319322
.WillRepeatedly(Return(nullptr));
320323
EXPECT_CALL(*win32window.get(), OnWindowStateEvent).Times(AnyNumber());
321-
MockFlutterWindowsView view(std::move(win32window));
324+
EXPECT_CALL(*win32window.get(), GetWindowHandle).Times(AnyNumber());
325+
MockFlutterWindowsView view{engine.get(), std::move(win32window)};
322326
std::wstring message = L"Test alert";
323327
EXPECT_CALL(view, NotifyWinEventWrapper(_, ax::mojom::Event::kAlert))
324328
.Times(1);

shell/platform/windows/flutter_windows.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,11 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
8282
width, height, engine_ptr->windows_proc_table());
8383

8484
auto engine = std::unique_ptr<flutter::FlutterWindowsEngine>(engine_ptr);
85-
auto view = std::make_unique<flutter::FlutterWindowsView>(
86-
std::move(window_wrapper), engine_ptr->windows_proc_table());
85+
std::unique_ptr<flutter::FlutterWindowsView> view =
86+
engine->CreateView(std::move(window_wrapper));
8787
auto controller = std::make_unique<flutter::FlutterWindowsViewController>(
8888
std::move(engine), std::move(view));
8989

90-
controller->view()->SetEngine(controller->engine());
9190
controller->view()->CreateRenderSurface();
9291
if (!controller->engine()->running()) {
9392
if (!controller->engine()->Run()) {

shell/platform/windows/flutter_windows_engine.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,15 @@ bool FlutterWindowsEngine::Stop() {
483483
return false;
484484
}
485485

486-
void FlutterWindowsEngine::SetView(FlutterWindowsView* view) {
487-
view_ = view;
486+
std::unique_ptr<FlutterWindowsView> FlutterWindowsEngine::CreateView(
487+
std::unique_ptr<WindowBindingHandler> window) {
488+
auto view = std::make_unique<FlutterWindowsView>(this, std::move(window),
489+
windows_proc_table_);
490+
491+
view_ = view.get();
488492
InitializeKeyboard();
493+
494+
return std::move(view);
489495
}
490496

491497
void FlutterWindowsEngine::OnVsync(intptr_t baton) {

shell/platform/windows/flutter_windows_engine.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,9 @@ class FlutterWindowsEngine {
111111
// Returns false if stopping the engine fails, or if it was not running.
112112
virtual bool Stop();
113113

114-
// Sets the view that is displaying this engine's content.
115-
void SetView(FlutterWindowsView* view);
114+
// Create the view that is displaying this engine's content.
115+
std::unique_ptr<FlutterWindowsView> CreateView(
116+
std::unique_ptr<WindowBindingHandler> window);
116117

117118
// The view displaying this engine's content, if any. This will be null for
118119
// headless engines.

0 commit comments

Comments
 (0)