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

Commit 34a8b9b

Browse files
Add Platform View Manager to Windows shell (#50598)
Create a manager for platform views accessible to the compositor, handle the methods that the framework will send. Addresses flutter/flutter#143375 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making or feature I am adding, or the PR is [test-exempt]. See [testing the engine] for instructions on writing and running engine tests. - [x] I updated/added relevant documentation (doc comments with `///`). - [ ] I signed the [CLA]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat --------- Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
1 parent 7a573c2 commit 34a8b9b

16 files changed

+439
-2
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30012,6 +30012,7 @@ ORIGIN: ../../../flutter/shell/platform/windows/flutter_window.h + ../../../flut
3001230012
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows.cc + ../../../flutter/LICENSE
3001330013
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_engine.cc + ../../../flutter/LICENSE
3001430014
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_engine.h + ../../../flutter/LICENSE
30015+
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_internal.h + ../../../flutter/LICENSE
3001530016
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_texture_registrar.cc + ../../../flutter/LICENSE
3001630017
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_texture_registrar.h + ../../../flutter/LICENSE
3001730018
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_view.cc + ../../../flutter/LICENSE
@@ -30030,6 +30031,10 @@ ORIGIN: ../../../flutter/shell/platform/windows/keyboard_utils.cc + ../../../flu
3003030031
ORIGIN: ../../../flutter/shell/platform/windows/keyboard_utils.h + ../../../flutter/LICENSE
3003130032
ORIGIN: ../../../flutter/shell/platform/windows/platform_handler.cc + ../../../flutter/LICENSE
3003230033
ORIGIN: ../../../flutter/shell/platform/windows/platform_handler.h + ../../../flutter/LICENSE
30034+
ORIGIN: ../../../flutter/shell/platform/windows/platform_view_manager.cc + ../../../flutter/LICENSE
30035+
ORIGIN: ../../../flutter/shell/platform/windows/platform_view_manager.h + ../../../flutter/LICENSE
30036+
ORIGIN: ../../../flutter/shell/platform/windows/platform_view_plugin.cc + ../../../flutter/LICENSE
30037+
ORIGIN: ../../../flutter/shell/platform/windows/platform_view_plugin.h + ../../../flutter/LICENSE
3003330038
ORIGIN: ../../../flutter/shell/platform/windows/public/flutter_windows.h + ../../../flutter/LICENSE
3003430039
ORIGIN: ../../../flutter/shell/platform/windows/sequential_id_generator.cc + ../../../flutter/LICENSE
3003530040
ORIGIN: ../../../flutter/shell/platform/windows/sequential_id_generator.h + ../../../flutter/LICENSE
@@ -32873,6 +32878,7 @@ FILE: ../../../flutter/shell/platform/windows/flutter_window.h
3287332878
FILE: ../../../flutter/shell/platform/windows/flutter_windows.cc
3287432879
FILE: ../../../flutter/shell/platform/windows/flutter_windows_engine.cc
3287532880
FILE: ../../../flutter/shell/platform/windows/flutter_windows_engine.h
32881+
FILE: ../../../flutter/shell/platform/windows/flutter_windows_internal.h
3287632882
FILE: ../../../flutter/shell/platform/windows/flutter_windows_texture_registrar.cc
3287732883
FILE: ../../../flutter/shell/platform/windows/flutter_windows_texture_registrar.h
3287832884
FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.cc
@@ -32891,6 +32897,10 @@ FILE: ../../../flutter/shell/platform/windows/keyboard_utils.cc
3289132897
FILE: ../../../flutter/shell/platform/windows/keyboard_utils.h
3289232898
FILE: ../../../flutter/shell/platform/windows/platform_handler.cc
3289332899
FILE: ../../../flutter/shell/platform/windows/platform_handler.h
32900+
FILE: ../../../flutter/shell/platform/windows/platform_view_manager.cc
32901+
FILE: ../../../flutter/shell/platform/windows/platform_view_manager.h
32902+
FILE: ../../../flutter/shell/platform/windows/platform_view_plugin.cc
32903+
FILE: ../../../flutter/shell/platform/windows/platform_view_plugin.h
3289432904
FILE: ../../../flutter/shell/platform/windows/public/flutter_windows.h
3289532905
FILE: ../../../flutter/shell/platform/windows/sequential_id_generator.cc
3289632906
FILE: ../../../flutter/shell/platform/windows/sequential_id_generator.h

shell/platform/windows/BUILD.gn

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import("//flutter/shell/platform/glfw/config.gni")
88
import("//flutter/testing/testing.gni")
99

1010
_public_headers = [ "public/flutter_windows.h" ]
11+
_internal_headers = [ "flutter_windows_internal.h" ]
1112

1213
config("relative_angle_headers") {
1314
include_dirs = [ "//third_party/angle/include" ]
@@ -24,7 +25,7 @@ config("relative_flutter_windows_headers") {
2425
# The headers are a separate source set since the client wrapper is allowed
2526
# to depend on the public headers, but none of the rest of the code.
2627
source_set("flutter_windows_headers") {
27-
public = _public_headers
28+
public = _public_headers + _internal_headers
2829

2930
public_deps = [ "//flutter/shell/platform/common:common_cpp_library_headers" ]
3031

@@ -98,6 +99,10 @@ source_set("flutter_windows_source") {
9899
"keyboard_utils.h",
99100
"platform_handler.cc",
100101
"platform_handler.h",
102+
"platform_view_manager.cc",
103+
"platform_view_manager.h",
104+
"platform_view_plugin.cc",
105+
"platform_view_plugin.h",
101106
"sequential_id_generator.cc",
102107
"sequential_id_generator.h",
103108
"settings_plugin.cc",
@@ -218,6 +223,7 @@ executable("flutter_windows_unittests") {
218223
"testing/flutter_windows_engine_builder.cc",
219224
"testing/flutter_windows_engine_builder.h",
220225
"testing/mock_direct_manipulation.h",
226+
"testing/mock_platform_view_manager.h",
221227
"testing/mock_text_input_manager.cc",
222228
"testing/mock_text_input_manager.h",
223229
"testing/mock_window.cc",

shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@ bool FlutterDesktopEngineProcessExternalWindowMessage(
176176
return false;
177177
}
178178

179+
void FlutterDesktopEngineRegisterPlatformViewType(
180+
FlutterDesktopEngineRef engine,
181+
const char* view_type_name,
182+
FlutterPlatformViewTypeEntry view_type) {
183+
if (s_stub_implementation) {
184+
s_stub_implementation->EngineRegisterPlatformViewType(view_type_name,
185+
view_type);
186+
}
187+
}
188+
179189
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(
180190
FlutterDesktopPluginRegistrarRef controller) {
181191
// The stub ignores this, so just return an arbitrary non-zero value.

shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <memory>
99

10+
#include "flutter/shell/platform/windows/flutter_windows_internal.h"
1011
#include "flutter/shell/platform/windows/public/flutter_windows.h"
1112

1213
namespace flutter {
@@ -72,6 +73,11 @@ class StubFlutterWindowsApi {
7273
// Called for FlutterDesktopEngineReloadSystemFonts.
7374
virtual void EngineReloadSystemFonts() {}
7475

76+
// Called for FlutterDesktopEngineRegisterPlatformViewType.
77+
virtual void EngineRegisterPlatformViewType(
78+
const char* view_type_name,
79+
FlutterPlatformViewTypeEntry view_type) {}
80+
7581
// Called for FlutterDesktopViewGetHWND.
7682
virtual HWND ViewGetHWND() { return reinterpret_cast<HWND>(1); }
7783

shell/platform/windows/fixtures/main.dart

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import 'dart:async';
66
import 'dart:io' as io;
7-
import 'dart:typed_data' show ByteData, Uint8List;
7+
import 'dart:typed_data' show ByteData, Endian, Uint8List;
88
import 'dart:ui' as ui;
99
import 'dart:convert';
1010

@@ -171,6 +171,37 @@ void enableLifecycleToFrom() async {
171171
});
172172
}
173173

174+
@pragma('vm:entry-point')
175+
void sendCreatePlatformViewMethod() async {
176+
// The platform view method channel uses the standard method codec.
177+
// See https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/services/message_codecs.dart#L262
178+
// for the implementation of the encoding and magic number identifiers.
179+
const int valueString = 7;
180+
const int valueMap = 13;
181+
const int valueInt32 = 3;
182+
const String method = 'create';
183+
const String typeKey = 'viewType';
184+
const String typeValue = 'type';
185+
const String idKey = 'id';
186+
final List<int> data = <int>[
187+
// Method name
188+
valueString, method.length, ...utf8.encode(method),
189+
// Method arguments: {'type': 'type':, 'id': 0}
190+
valueMap, 2,
191+
valueString, typeKey.length, ...utf8.encode(typeKey),
192+
valueString, typeValue.length, ...utf8.encode(typeValue),
193+
valueString, idKey.length, ...utf8.encode(idKey),
194+
valueInt32, 0, 0, 0, 0,
195+
];
196+
197+
final Completer<ByteData?> completed = Completer<ByteData?>();
198+
final ByteData bytes = ByteData.sublistView(Uint8List.fromList(data));
199+
ui.PlatformDispatcher.instance.sendPlatformMessage('flutter/platform_views', bytes, (ByteData? response) {
200+
completed.complete(response);
201+
});
202+
await completed.future;
203+
}
204+
174205
@pragma('vm:entry-point')
175206
void customEntrypoint() {}
176207

shell/platform/windows/flutter_windows.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,14 @@ bool FlutterDesktopEngineProcessExternalWindowMessage(
245245
return lresult.has_value();
246246
}
247247

248+
void FlutterDesktopEngineRegisterPlatformViewType(
249+
FlutterDesktopEngineRef engine,
250+
const char* view_type_name,
251+
FlutterPlatformViewTypeEntry view_type) {
252+
// TODO(schectman): forward to platform view manager.
253+
// https://github.com/flutter/flutter/issues/143375
254+
}
255+
248256
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(
249257
FlutterDesktopPluginRegistrarRef registrar) {
250258
// TODO(loicsharma): Add |FlutterDesktopPluginRegistrarGetViewById| and

shell/platform/windows/flutter_windows_engine.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,11 +383,17 @@ bool FlutterWindowsEngine::Run(std::string_view entrypoint) {
383383

384384
args.custom_task_runners = &custom_task_runners;
385385

386+
if (!platform_view_plugin_) {
387+
platform_view_plugin_ = std::make_unique<PlatformViewPlugin>(
388+
messenger_wrapper_.get(), task_runner_.get());
389+
}
386390
if (egl_manager_) {
387391
auto resolver = [](const char* name) -> void* {
388392
return reinterpret_cast<void*>(::eglGetProcAddress(name));
389393
};
390394

395+
// TODO(schectman) Pass the platform view manager to the compositor
396+
// constructors: https://github.com/flutter/flutter/issues/143375
391397
compositor_ = std::make_unique<CompositorOpenGL>(this, resolver);
392398
} else {
393399
compositor_ = std::make_unique<CompositorSoftware>(this);

shell/platform/windows/flutter_windows_engine.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "flutter/shell/platform/windows/keyboard_handler_base.h"
3333
#include "flutter/shell/platform/windows/keyboard_key_embedder_handler.h"
3434
#include "flutter/shell/platform/windows/platform_handler.h"
35+
#include "flutter/shell/platform/windows/platform_view_plugin.h"
3536
#include "flutter/shell/platform/windows/public/flutter_windows.h"
3637
#include "flutter/shell/platform/windows/settings_plugin.h"
3738
#include "flutter/shell/platform/windows/task_runner.h"
@@ -144,6 +145,8 @@ class FlutterWindowsEngine {
144145

145146
TaskRunner* task_runner() { return task_runner_.get(); }
146147

148+
BinaryMessenger* messenger_wrapper() { return messenger_wrapper_.get(); }
149+
147150
FlutterWindowsTextureRegistrar* texture_registrar() {
148151
return texture_registrar_.get();
149152
}
@@ -434,6 +437,8 @@ class FlutterWindowsEngine {
434437

435438
std::shared_ptr<egl::ProcTable> gl_;
436439

440+
std::unique_ptr<PlatformViewPlugin> platform_view_plugin_;
441+
437442
FML_DISALLOW_COPY_AND_ASSIGN(FlutterWindowsEngine);
438443
};
439444

shell/platform/windows/flutter_windows_engine_unittests.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "flutter/shell/platform/windows/testing/egl/mock_manager.h"
1313
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
1414
#include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
15+
#include "flutter/shell/platform/windows/testing/mock_platform_view_manager.h"
1516
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
1617
#include "flutter/shell/platform/windows/testing/mock_windows_proc_table.h"
1718
#include "flutter/shell/platform/windows/testing/test_keyboard.h"
@@ -1170,5 +1171,30 @@ TEST_F(FlutterWindowsEngineTest, ChannelListenedTo) {
11701171
}
11711172
}
11721173

1174+
TEST_F(FlutterWindowsEngineTest, ReceivePlatformViewMessage) {
1175+
FlutterWindowsEngineBuilder builder{GetContext()};
1176+
builder.SetDartEntrypoint("sendCreatePlatformViewMethod");
1177+
auto engine = builder.Build();
1178+
1179+
EngineModifier modifier{engine.get()};
1180+
modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; };
1181+
1182+
bool received_call = false;
1183+
1184+
auto manager = std::make_unique<MockPlatformViewManager>(engine.get());
1185+
EXPECT_CALL(*manager, AddPlatformView)
1186+
.WillOnce([&](PlatformViewId id, std::string_view type_name) {
1187+
received_call = true;
1188+
return true;
1189+
});
1190+
modifier.SetPlatformViewPlugin(std::move(manager));
1191+
1192+
engine->Run();
1193+
1194+
while (!received_call) {
1195+
engine->task_runner()->ProcessTasks();
1196+
}
1197+
}
1198+
11731199
} // namespace testing
11741200
} // namespace flutter
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_INTERNAL_H_
6+
#define FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_INTERNAL_H_
7+
8+
#include "flutter/shell/platform/windows/public/flutter_windows.h"
9+
10+
#if defined(__cplusplus)
11+
extern "C" {
12+
#endif
13+
14+
// Declare functions that are currently in-progress and shall be exposed to the
15+
// public facing API upon completion.
16+
17+
typedef int64_t PlatformViewId;
18+
19+
typedef struct {
20+
size_t struct_size;
21+
HWND parent_window;
22+
const char* platform_view_type;
23+
// user_data may hold any necessary additional information for creating a new
24+
// platform view. For example, an instance of FlutterWindow.
25+
void* user_data;
26+
PlatformViewId platform_view_id;
27+
} FlutterPlatformViewCreationParameters;
28+
29+
typedef HWND (*FlutterPlatformViewFactory)(
30+
const FlutterPlatformViewCreationParameters*);
31+
32+
typedef struct {
33+
size_t struct_size;
34+
FlutterPlatformViewFactory factory;
35+
void* user_data; // Arbitrary user data supplied to the creation struct.
36+
} FlutterPlatformViewTypeEntry;
37+
38+
FLUTTER_EXPORT void FlutterDesktopEngineRegisterPlatformViewType(
39+
FlutterDesktopEngineRef engine,
40+
const char* view_type_name,
41+
FlutterPlatformViewTypeEntry view_type);
42+
43+
#if defined(__cplusplus)
44+
}
45+
#endif
46+
47+
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_INTERNAL_H_

0 commit comments

Comments
 (0)