Add Platform View Manager to Windows shell (flutter/engine#50598)

Create a manager for platform views accessible to the compositor, handle
the methods that the framework will send.

Addresses https://github.com/flutter/flutter/issues/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>
This commit is contained in:
yaakovschectman 2024-02-26 10:13:46 -05:00 committed by GitHub
parent fdcef537c2
commit ac3cb8cd7b
16 changed files with 439 additions and 2 deletions

View File

@ -30012,6 +30012,7 @@ ORIGIN: ../../../flutter/shell/platform/windows/flutter_window.h + ../../../flut
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_engine.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_engine.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_internal.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_texture_registrar.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_texture_registrar.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/flutter_windows_view.cc + ../../../flutter/LICENSE
@ -30030,6 +30031,10 @@ ORIGIN: ../../../flutter/shell/platform/windows/keyboard_utils.cc + ../../../flu
ORIGIN: ../../../flutter/shell/platform/windows/keyboard_utils.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/platform_handler.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/platform_handler.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/platform_view_manager.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/platform_view_manager.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/platform_view_plugin.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/platform_view_plugin.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/public/flutter_windows.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/sequential_id_generator.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/sequential_id_generator.h + ../../../flutter/LICENSE
@ -32873,6 +32878,7 @@ FILE: ../../../flutter/shell/platform/windows/flutter_window.h
FILE: ../../../flutter/shell/platform/windows/flutter_windows.cc
FILE: ../../../flutter/shell/platform/windows/flutter_windows_engine.cc
FILE: ../../../flutter/shell/platform/windows/flutter_windows_engine.h
FILE: ../../../flutter/shell/platform/windows/flutter_windows_internal.h
FILE: ../../../flutter/shell/platform/windows/flutter_windows_texture_registrar.cc
FILE: ../../../flutter/shell/platform/windows/flutter_windows_texture_registrar.h
FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.cc
@ -32891,6 +32897,10 @@ FILE: ../../../flutter/shell/platform/windows/keyboard_utils.cc
FILE: ../../../flutter/shell/platform/windows/keyboard_utils.h
FILE: ../../../flutter/shell/platform/windows/platform_handler.cc
FILE: ../../../flutter/shell/platform/windows/platform_handler.h
FILE: ../../../flutter/shell/platform/windows/platform_view_manager.cc
FILE: ../../../flutter/shell/platform/windows/platform_view_manager.h
FILE: ../../../flutter/shell/platform/windows/platform_view_plugin.cc
FILE: ../../../flutter/shell/platform/windows/platform_view_plugin.h
FILE: ../../../flutter/shell/platform/windows/public/flutter_windows.h
FILE: ../../../flutter/shell/platform/windows/sequential_id_generator.cc
FILE: ../../../flutter/shell/platform/windows/sequential_id_generator.h

View File

@ -8,6 +8,7 @@ import("//flutter/shell/platform/glfw/config.gni")
import("//flutter/testing/testing.gni")
_public_headers = [ "public/flutter_windows.h" ]
_internal_headers = [ "flutter_windows_internal.h" ]
config("relative_angle_headers") {
include_dirs = [ "//third_party/angle/include" ]
@ -24,7 +25,7 @@ config("relative_flutter_windows_headers") {
# The headers are a separate source set since the client wrapper is allowed
# to depend on the public headers, but none of the rest of the code.
source_set("flutter_windows_headers") {
public = _public_headers
public = _public_headers + _internal_headers
public_deps = [ "//flutter/shell/platform/common:common_cpp_library_headers" ]
@ -98,6 +99,10 @@ source_set("flutter_windows_source") {
"keyboard_utils.h",
"platform_handler.cc",
"platform_handler.h",
"platform_view_manager.cc",
"platform_view_manager.h",
"platform_view_plugin.cc",
"platform_view_plugin.h",
"sequential_id_generator.cc",
"sequential_id_generator.h",
"settings_plugin.cc",
@ -218,6 +223,7 @@ executable("flutter_windows_unittests") {
"testing/flutter_windows_engine_builder.cc",
"testing/flutter_windows_engine_builder.h",
"testing/mock_direct_manipulation.h",
"testing/mock_platform_view_manager.h",
"testing/mock_text_input_manager.cc",
"testing/mock_text_input_manager.h",
"testing/mock_window.cc",

View File

@ -176,6 +176,16 @@ bool FlutterDesktopEngineProcessExternalWindowMessage(
return false;
}
void FlutterDesktopEngineRegisterPlatformViewType(
FlutterDesktopEngineRef engine,
const char* view_type_name,
FlutterPlatformViewTypeEntry view_type) {
if (s_stub_implementation) {
s_stub_implementation->EngineRegisterPlatformViewType(view_type_name,
view_type);
}
}
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(
FlutterDesktopPluginRegistrarRef controller) {
// The stub ignores this, so just return an arbitrary non-zero value.

View File

@ -7,6 +7,7 @@
#include <memory>
#include "flutter/shell/platform/windows/flutter_windows_internal.h"
#include "flutter/shell/platform/windows/public/flutter_windows.h"
namespace flutter {
@ -72,6 +73,11 @@ class StubFlutterWindowsApi {
// Called for FlutterDesktopEngineReloadSystemFonts.
virtual void EngineReloadSystemFonts() {}
// Called for FlutterDesktopEngineRegisterPlatformViewType.
virtual void EngineRegisterPlatformViewType(
const char* view_type_name,
FlutterPlatformViewTypeEntry view_type) {}
// Called for FlutterDesktopViewGetHWND.
virtual HWND ViewGetHWND() { return reinterpret_cast<HWND>(1); }

View File

@ -4,7 +4,7 @@
import 'dart:async';
import 'dart:io' as io;
import 'dart:typed_data' show ByteData, Uint8List;
import 'dart:typed_data' show ByteData, Endian, Uint8List;
import 'dart:ui' as ui;
import 'dart:convert';
@ -171,6 +171,37 @@ void enableLifecycleToFrom() async {
});
}
@pragma('vm:entry-point')
void sendCreatePlatformViewMethod() async {
// The platform view method channel uses the standard method codec.
// See https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/services/message_codecs.dart#L262
// for the implementation of the encoding and magic number identifiers.
const int valueString = 7;
const int valueMap = 13;
const int valueInt32 = 3;
const String method = 'create';
const String typeKey = 'viewType';
const String typeValue = 'type';
const String idKey = 'id';
final List<int> data = <int>[
// Method name
valueString, method.length, ...utf8.encode(method),
// Method arguments: {'type': 'type':, 'id': 0}
valueMap, 2,
valueString, typeKey.length, ...utf8.encode(typeKey),
valueString, typeValue.length, ...utf8.encode(typeValue),
valueString, idKey.length, ...utf8.encode(idKey),
valueInt32, 0, 0, 0, 0,
];
final Completer<ByteData?> completed = Completer<ByteData?>();
final ByteData bytes = ByteData.sublistView(Uint8List.fromList(data));
ui.PlatformDispatcher.instance.sendPlatformMessage('flutter/platform_views', bytes, (ByteData? response) {
completed.complete(response);
});
await completed.future;
}
@pragma('vm:entry-point')
void customEntrypoint() {}

View File

@ -245,6 +245,14 @@ bool FlutterDesktopEngineProcessExternalWindowMessage(
return lresult.has_value();
}
void FlutterDesktopEngineRegisterPlatformViewType(
FlutterDesktopEngineRef engine,
const char* view_type_name,
FlutterPlatformViewTypeEntry view_type) {
// TODO(schectman): forward to platform view manager.
// https://github.com/flutter/flutter/issues/143375
}
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(
FlutterDesktopPluginRegistrarRef registrar) {
// TODO(loicsharma): Add |FlutterDesktopPluginRegistrarGetViewById| and

View File

@ -383,11 +383,17 @@ bool FlutterWindowsEngine::Run(std::string_view entrypoint) {
args.custom_task_runners = &custom_task_runners;
if (!platform_view_plugin_) {
platform_view_plugin_ = std::make_unique<PlatformViewPlugin>(
messenger_wrapper_.get(), task_runner_.get());
}
if (egl_manager_) {
auto resolver = [](const char* name) -> void* {
return reinterpret_cast<void*>(::eglGetProcAddress(name));
};
// TODO(schectman) Pass the platform view manager to the compositor
// constructors: https://github.com/flutter/flutter/issues/143375
compositor_ = std::make_unique<CompositorOpenGL>(this, resolver);
} else {
compositor_ = std::make_unique<CompositorSoftware>(this);

View File

@ -32,6 +32,7 @@
#include "flutter/shell/platform/windows/keyboard_handler_base.h"
#include "flutter/shell/platform/windows/keyboard_key_embedder_handler.h"
#include "flutter/shell/platform/windows/platform_handler.h"
#include "flutter/shell/platform/windows/platform_view_plugin.h"
#include "flutter/shell/platform/windows/public/flutter_windows.h"
#include "flutter/shell/platform/windows/settings_plugin.h"
#include "flutter/shell/platform/windows/task_runner.h"
@ -144,6 +145,8 @@ class FlutterWindowsEngine {
TaskRunner* task_runner() { return task_runner_.get(); }
BinaryMessenger* messenger_wrapper() { return messenger_wrapper_.get(); }
FlutterWindowsTextureRegistrar* texture_registrar() {
return texture_registrar_.get();
}
@ -434,6 +437,8 @@ class FlutterWindowsEngine {
std::shared_ptr<egl::ProcTable> gl_;
std::unique_ptr<PlatformViewPlugin> platform_view_plugin_;
FML_DISALLOW_COPY_AND_ASSIGN(FlutterWindowsEngine);
};

View File

@ -12,6 +12,7 @@
#include "flutter/shell/platform/windows/testing/egl/mock_manager.h"
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
#include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
#include "flutter/shell/platform/windows/testing/mock_platform_view_manager.h"
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
#include "flutter/shell/platform/windows/testing/mock_windows_proc_table.h"
#include "flutter/shell/platform/windows/testing/test_keyboard.h"
@ -1170,5 +1171,30 @@ TEST_F(FlutterWindowsEngineTest, ChannelListenedTo) {
}
}
TEST_F(FlutterWindowsEngineTest, ReceivePlatformViewMessage) {
FlutterWindowsEngineBuilder builder{GetContext()};
builder.SetDartEntrypoint("sendCreatePlatformViewMethod");
auto engine = builder.Build();
EngineModifier modifier{engine.get()};
modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; };
bool received_call = false;
auto manager = std::make_unique<MockPlatformViewManager>(engine.get());
EXPECT_CALL(*manager, AddPlatformView)
.WillOnce([&](PlatformViewId id, std::string_view type_name) {
received_call = true;
return true;
});
modifier.SetPlatformViewPlugin(std::move(manager));
engine->Run();
while (!received_call) {
engine->task_runner()->ProcessTasks();
}
}
} // namespace testing
} // namespace flutter

View File

@ -0,0 +1,47 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_INTERNAL_H_
#define FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_INTERNAL_H_
#include "flutter/shell/platform/windows/public/flutter_windows.h"
#if defined(__cplusplus)
extern "C" {
#endif
// Declare functions that are currently in-progress and shall be exposed to the
// public facing API upon completion.
typedef int64_t PlatformViewId;
typedef struct {
size_t struct_size;
HWND parent_window;
const char* platform_view_type;
// user_data may hold any necessary additional information for creating a new
// platform view. For example, an instance of FlutterWindow.
void* user_data;
PlatformViewId platform_view_id;
} FlutterPlatformViewCreationParameters;
typedef HWND (*FlutterPlatformViewFactory)(
const FlutterPlatformViewCreationParameters*);
typedef struct {
size_t struct_size;
FlutterPlatformViewFactory factory;
void* user_data; // Arbitrary user data supplied to the creation struct.
} FlutterPlatformViewTypeEntry;
FLUTTER_EXPORT void FlutterDesktopEngineRegisterPlatformViewType(
FlutterDesktopEngineRef engine,
const char* view_type_name,
FlutterPlatformViewTypeEntry view_type);
#if defined(__cplusplus)
}
#endif
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_INTERNAL_H_

View File

@ -0,0 +1,84 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/windows/platform_view_manager.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h"
namespace flutter {
namespace {
constexpr char kChannelName[] = "flutter/platform_views";
constexpr char kCreateMethod[] = "create";
constexpr char kFocusMethod[] = "focus";
constexpr char kViewTypeParameter[] = "viewType";
constexpr char kIdParameter[] = "id";
constexpr char kDirectionParameter[] = "direction";
constexpr char kFocusParameter[] = "focus";
} // namespace
PlatformViewManager::PlatformViewManager(BinaryMessenger* binary_messenger)
: channel_(std::make_unique<MethodChannel<EncodableValue>>(
binary_messenger,
kChannelName,
&StandardMethodCodec::GetInstance())) {
channel_->SetMethodCallHandler(
[this](const MethodCall<EncodableValue>& call,
std::unique_ptr<MethodResult<EncodableValue>> result) {
const auto& args = std::get<EncodableMap>(*call.arguments());
if (call.method_name() == kCreateMethod) {
const auto& type_itr = args.find(EncodableValue(kViewTypeParameter));
const auto& id_itr = args.find(EncodableValue(kIdParameter));
if (type_itr == args.end()) {
result->Error("AddPlatformView", "Parameter viewType is required");
return;
}
if (id_itr == args.end()) {
result->Error("AddPlatformView", "Parameter id is required");
return;
}
const auto& type = std::get<std::string>(type_itr->second);
const auto& id = std::get<std::int32_t>(id_itr->second);
if (AddPlatformView(id, type)) {
result->Success();
} else {
result->Error("AddPlatformView", "Failed to add platform view");
}
return;
} else if (call.method_name() == kFocusMethod) {
const auto& id_itr = args.find(EncodableValue(kIdParameter));
const auto& direction_itr =
args.find(EncodableValue(kDirectionParameter));
const auto& focus_itr = args.find(EncodableValue(kFocusParameter));
if (id_itr == args.end()) {
result->Error("FocusPlatformView", "Parameter id is required");
return;
}
if (direction_itr == args.end()) {
result->Error("FocusPlatformView",
"Parameter direction is required");
return;
}
if (focus_itr == args.end()) {
result->Error("FocusPlatformView", "Parameter focus is required");
return;
}
const auto& id = std::get<std::int32_t>(id_itr->second);
const auto& direction = std::get<std::int32_t>(direction_itr->second);
const auto& focus = std::get<bool>(focus_itr->second);
if (FocusPlatformView(
id, static_cast<FocusChangeDirection>(direction), focus)) {
result->Success();
} else {
result->Error("FocusPlatformView", "Failed to focus platform view");
}
return;
}
result->NotImplemented();
});
}
PlatformViewManager::~PlatformViewManager() {}
} // namespace flutter

View File

@ -0,0 +1,52 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_PLATFORM_VIEW_MANAGER_H_
#define FLUTTER_SHELL_PLATFORM_WINDOWS_PLATFORM_VIEW_MANAGER_H_
#include <memory>
#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h"
#include "flutter/shell/platform/windows/flutter_windows_internal.h"
#include "flutter/shell/platform/windows/task_runner.h"
namespace flutter {
// Possible reasons for change of keyboard focus.
enum class FocusChangeDirection {
kProgrammatic, // Un-directed focus change.
kForward, // Keyboard focus moves forwards, e.g. TAB key.
kBackward // Keyboard focus moves backwards, e.g. Shift+TAB.
};
// The platform method handler for platform view related communication between
// the engine and the framework. This base class is derived by a concrete class
// (i.e. PlatformViewPlugin) to provide implementation of its abstract virtual
// methods.
class PlatformViewManager {
public:
PlatformViewManager(BinaryMessenger* binary_messenger);
virtual ~PlatformViewManager();
// Add a new platform view instance to be lazily instantiated when it is next
// composited. The manager will invoke Success when this method returns true,
// and invoke Error otherwise.
virtual bool AddPlatformView(PlatformViewId id,
std::string_view type_name) = 0;
// The framework may invoke this method when keyboard focus must be given to
// the platform view. The manager will invoke Success when this method returns
// true, and invoke Error otherwise.
virtual bool FocusPlatformView(PlatformViewId id,
FocusChangeDirection direction,
bool focus) = 0;
private:
std::unique_ptr<MethodChannel<EncodableValue>> channel_;
};
} // namespace flutter
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_PLATFORM_VIEW_MANAGER_H_

View File

@ -0,0 +1,47 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/windows/platform_view_plugin.h"
namespace flutter {
PlatformViewPlugin::PlatformViewPlugin(BinaryMessenger* messenger,
TaskRunner* task_runner)
: PlatformViewManager(messenger), task_runner_(task_runner) {}
PlatformViewPlugin::~PlatformViewPlugin() {}
// TODO(schectman): Impelement platform view lookup.
// https://github.com/flutter/flutter/issues/143375
std::optional<HWND> PlatformViewPlugin::GetNativeHandleForId(
PlatformViewId id) const {
return std::nullopt;
}
// TODO(schectman): Impelement platform view type registration.
// https://github.com/flutter/flutter/issues/143375
void PlatformViewPlugin::RegisterPlatformViewType(
std::string_view type_name,
const FlutterPlatformViewTypeEntry& type) {}
// TODO(schectman): Impelement platform view instantiation.
// https://github.com/flutter/flutter/issues/143375
void PlatformViewPlugin::InstantiatePlatformView(PlatformViewId id) {}
// TODO(schectman): Impelement platform view addition.
// https://github.com/flutter/flutter/issues/143375
bool PlatformViewPlugin::AddPlatformView(PlatformViewId id,
std::string_view type_name) {
return true;
}
// TODO(schectman): Impelement platform view focus request.
// https://github.com/flutter/flutter/issues/143375
bool PlatformViewPlugin::FocusPlatformView(PlatformViewId id,
FocusChangeDirection direction,
bool focus) {
return true;
}
} // namespace flutter

View File

@ -0,0 +1,67 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_PLATFORM_VIEW_PLUGIN_H_
#define FLUTTER_SHELL_PLATFORM_WINDOWS_PLATFORM_VIEW_PLUGIN_H_
#include "flutter/shell/platform/windows/platform_view_manager.h"
#include <functional>
#include <map>
#include <optional>
namespace flutter {
// The concrete implementation of PlatformViewManager that keeps track of
// existing platform view types and instances, and handles their instantiation.
class PlatformViewPlugin : public PlatformViewManager {
public:
PlatformViewPlugin(BinaryMessenger* messenger, TaskRunner* task_runner);
~PlatformViewPlugin();
// Find the HWND corresponding to a platform view id. Returns null if the id
// has no associated platform view.
std::optional<HWND> GetNativeHandleForId(PlatformViewId id) const;
// The runner-facing API calls this method to register a window type
// corresponding to a platform view identifier supplied to the widget tree.
void RegisterPlatformViewType(std::string_view type_name,
const FlutterPlatformViewTypeEntry& type);
// | PlatformViewManager |
// type_name must correspond to a string that has already been registered
// with RegisterPlatformViewType.
bool AddPlatformView(PlatformViewId id, std::string_view type_name) override;
// Create a queued platform view instance after it has been added.
// id must correspond to an identifier that has already been added with
// AddPlatformView.
// This method will create the platform view within a task queued to the
// engine's TaskRunner, which will run on the UI thread.
void InstantiatePlatformView(PlatformViewId id);
// | PlatformViewManager |
// id must correspond to an identifier that has already been added with
// AddPlatformView.
bool FocusPlatformView(PlatformViewId id,
FocusChangeDirection direction,
bool focus) override;
private:
std::unordered_map<std::string, FlutterPlatformViewTypeEntry>
platform_view_types_;
std::unordered_map<PlatformViewId, HWND> platform_views_;
std::unordered_map<PlatformViewId, std::function<HWND()>>
pending_platform_views_;
// Pointer to the task runner of the associated engine.
TaskRunner* task_runner_;
};
} // namespace flutter
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_PLATFORM_VIEW_PLUGIN_H_

View File

@ -76,6 +76,10 @@ class EngineModifier {
engine_->lifecycle_manager_ = std::move(handler);
}
void SetPlatformViewPlugin(std::unique_ptr<PlatformViewPlugin>&& manager) {
engine_->platform_view_plugin_ = std::move(manager);
}
private:
FlutterWindowsEngine* engine_;

View File

@ -0,0 +1,28 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_MOCK_PLATFORM_VIEW_MANAGER_H_
#define FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_MOCK_PLATFORM_VIEW_MANAGER_H_
#include "flutter/shell/platform/windows/platform_view_plugin.h"
#include "flutter/shell/platform/windows/flutter_windows_engine.h"
#include "gmock/gmock.h"
namespace flutter {
class MockPlatformViewManager : public PlatformViewPlugin {
public:
MockPlatformViewManager(FlutterWindowsEngine* engine)
: PlatformViewPlugin(engine->messenger_wrapper(), engine->task_runner()) {
}
~MockPlatformViewManager() {}
MOCK_METHOD(bool, AddPlatformView, (PlatformViewId id, std::string_view));
};
} // namespace flutter
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_MOCK_PLATFORM_VIEW_MANAGER_H_