mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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:
parent
fdcef537c2
commit
ac3cb8cd7b
@ -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
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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); }
|
||||
|
||||
|
||||
@ -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() {}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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_;
|
||||
|
||||
|
||||
@ -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_
|
||||
Loading…
x
Reference in New Issue
Block a user