diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 2d40298c8be5d..c423e4797e776 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -11628,6 +11628,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 @@ -11646,6 +11647,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 @@ -14490,6 +14495,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 @@ -14508,6 +14514,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 diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index 0f0815cb261e8..fe72e926d48dd 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -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", diff --git a/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc b/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc index da0a8c57712d3..f01f895c728f5 100644 --- a/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc +++ b/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc @@ -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. diff --git a/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h b/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h index 19671159ea426..43eaa50074132 100644 --- a/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h +++ b/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h @@ -7,6 +7,7 @@ #include +#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(1); } diff --git a/shell/platform/windows/fixtures/main.dart b/shell/platform/windows/fixtures/main.dart index 3e1c25eb6da0e..4512c58e93b22 100644 --- a/shell/platform/windows/fixtures/main.dart +++ b/shell/platform/windows/fixtures/main.dart @@ -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'; @@ -159,6 +159,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 data = [ + // 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 completed = Completer(); + 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() {} diff --git a/shell/platform/windows/flutter_windows.cc b/shell/platform/windows/flutter_windows.cc index efd7ac309eca3..dfe9767f53529 100644 --- a/shell/platform/windows/flutter_windows.cc +++ b/shell/platform/windows/flutter_windows.cc @@ -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 diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index 7ccb66037874b..e1c23329d0d4e 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -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( + messenger_wrapper_.get(), task_runner_.get()); + } if (egl_manager_) { auto resolver = [](const char* name) -> void* { return reinterpret_cast(::eglGetProcAddress(name)); }; + // TODO(schectman) Pass the platform view manager to the compositor + // constructors: https://github.com/flutter/flutter/issues/143375 compositor_ = std::make_unique(this, resolver); } else { compositor_ = std::make_unique(this); diff --git a/shell/platform/windows/flutter_windows_engine.h b/shell/platform/windows/flutter_windows_engine.h index 53710b141e839..f0a3b2f864ba8 100644 --- a/shell/platform/windows/flutter_windows_engine.h +++ b/shell/platform/windows/flutter_windows_engine.h @@ -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 gl_; + std::unique_ptr platform_view_plugin_; + FML_DISALLOW_COPY_AND_ASSIGN(FlutterWindowsEngine); }; diff --git a/shell/platform/windows/flutter_windows_engine_unittests.cc b/shell/platform/windows/flutter_windows_engine_unittests.cc index d72a2e4e3dc46..bf09aaceded49 100644 --- a/shell/platform/windows/flutter_windows_engine_unittests.cc +++ b/shell/platform/windows/flutter_windows_engine_unittests.cc @@ -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" @@ -1171,5 +1172,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(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 diff --git a/shell/platform/windows/flutter_windows_internal.h b/shell/platform/windows/flutter_windows_internal.h new file mode 100644 index 0000000000000..47b98e983a48a --- /dev/null +++ b/shell/platform/windows/flutter_windows_internal.h @@ -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_ diff --git a/shell/platform/windows/platform_view_manager.cc b/shell/platform/windows/platform_view_manager.cc new file mode 100644 index 0000000000000..cb403673597b6 --- /dev/null +++ b/shell/platform/windows/platform_view_manager.cc @@ -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>( + binary_messenger, + kChannelName, + &StandardMethodCodec::GetInstance())) { + channel_->SetMethodCallHandler( + [this](const MethodCall& call, + std::unique_ptr> result) { + const auto& args = std::get(*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(type_itr->second); + const auto& id = std::get(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(id_itr->second); + const auto& direction = std::get(direction_itr->second); + const auto& focus = std::get(focus_itr->second); + if (FocusPlatformView( + id, static_cast(direction), focus)) { + result->Success(); + } else { + result->Error("FocusPlatformView", "Failed to focus platform view"); + } + return; + } + result->NotImplemented(); + }); +} + +PlatformViewManager::~PlatformViewManager() {} + +} // namespace flutter diff --git a/shell/platform/windows/platform_view_manager.h b/shell/platform/windows/platform_view_manager.h new file mode 100644 index 0000000000000..d4b736f9602fc --- /dev/null +++ b/shell/platform/windows/platform_view_manager.h @@ -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 + +#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> channel_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_PLATFORM_VIEW_MANAGER_H_ diff --git a/shell/platform/windows/platform_view_plugin.cc b/shell/platform/windows/platform_view_plugin.cc new file mode 100644 index 0000000000000..a54ebfebf1a64 --- /dev/null +++ b/shell/platform/windows/platform_view_plugin.cc @@ -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 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 diff --git a/shell/platform/windows/platform_view_plugin.h b/shell/platform/windows/platform_view_plugin.h new file mode 100644 index 0000000000000..490d21a8e0ba2 --- /dev/null +++ b/shell/platform/windows/platform_view_plugin.h @@ -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 +#include +#include + +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 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 + platform_view_types_; + + std::unordered_map platform_views_; + + std::unordered_map> + 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_ diff --git a/shell/platform/windows/testing/engine_modifier.h b/shell/platform/windows/testing/engine_modifier.h index d070dc10993fe..8244ca16e5125 100644 --- a/shell/platform/windows/testing/engine_modifier.h +++ b/shell/platform/windows/testing/engine_modifier.h @@ -76,6 +76,10 @@ class EngineModifier { engine_->lifecycle_manager_ = std::move(handler); } + void SetPlatformViewPlugin(std::unique_ptr&& manager) { + engine_->platform_view_plugin_ = std::move(manager); + } + private: FlutterWindowsEngine* engine_; diff --git a/shell/platform/windows/testing/mock_platform_view_manager.h b/shell/platform/windows/testing/mock_platform_view_manager.h new file mode 100644 index 0000000000000..a3c6922269932 --- /dev/null +++ b/shell/platform/windows/testing/mock_platform_view_manager.h @@ -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_