未验证 提交 92944f72 编写于 作者: A Amir Hardon 提交者: GitHub

Move FlutterPlatformViewsController into FlutterEngine. (#6709)

This PR breaks PlatformViewsController's construction dependency on FlutterView,
which allows making FlutterEngine its owner instead of
FlutterViewController.

Also renamed the FlutterScreenshotDelegate to FlutterViewEngineDelegate
which is FlutterView's delegate to the engine, and expanded it to
provide a view embedder.
上级 d34cb175
......@@ -44,12 +44,15 @@
fml::WeakPtr<FlutterViewController> _viewController;
fml::scoped_nsobject<FlutterObservatoryPublisher> _publisher;
std::unique_ptr<shell::FlutterPlatformViewsController> _platformViewsController;
// Channels
fml::scoped_nsobject<FlutterPlatformPlugin> _platformPlugin;
fml::scoped_nsobject<FlutterTextInputPlugin> _textInputPlugin;
fml::scoped_nsobject<FlutterMethodChannel> _localizationChannel;
fml::scoped_nsobject<FlutterMethodChannel> _navigationChannel;
fml::scoped_nsobject<FlutterMethodChannel> _platformChannel;
fml::scoped_nsobject<FlutterMethodChannel> _platformViewsChannel;
fml::scoped_nsobject<FlutterMethodChannel> _textInputChannel;
fml::scoped_nsobject<FlutterBasicMessageChannel> _lifecycleChannel;
fml::scoped_nsobject<FlutterBasicMessageChannel> _systemChannel;
......@@ -73,6 +76,7 @@
_pluginPublications = [NSMutableDictionary new];
_publisher.reset([[FlutterObservatoryPublisher alloc] init]);
_platformViewsController.reset(new shell::FlutterPlatformViewsController());
[self setupChannels];
......@@ -143,6 +147,9 @@
- (FlutterPlatformPlugin*)platformPlugin {
return _platformPlugin.get();
}
- (shell::FlutterPlatformViewsController*)platformViewsController {
return _platformViewsController.get();
}
- (FlutterTextInputPlugin*)textInputPlugin {
return _textInputPlugin.get();
}
......@@ -184,6 +191,11 @@
binaryMessenger:self
codec:[FlutterJSONMethodCodec sharedInstance]]);
_platformViewsChannel.reset([[FlutterMethodChannel alloc]
initWithName:@"flutter/platform_views"
binaryMessenger:self
codec:[FlutterStandardMethodCodec sharedInstance]]);
_textInputChannel.reset([[FlutterMethodChannel alloc]
initWithName:@"flutter/textinput"
binaryMessenger:self
......@@ -218,6 +230,11 @@
[_platformPlugin.get() handleMethodCall:call result:result];
}];
[_platformViewsChannel.get()
setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
_platformViewsController->OnMethodCall(call, result);
}];
[_textInputChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
[_textInputPlugin.get() handleMethodCall:call result:result];
}];
......@@ -379,6 +396,10 @@
return _shell->Screenshot(type, base64Encode);
}
- (flow::ExternalViewEmbedder*)externalViewEmbedder {
return _platformViewsController.get();
}
#pragma mark - FlutterBinaryMessenger
- (void)sendOnChannel:(NSString*)channel message:(NSData*)message {
......@@ -514,18 +535,7 @@
- (void)registerViewFactory:(NSObject<FlutterPlatformViewFactory>*)factory
withId:(NSString*)factoryId {
// TODO(amirh/dnfield): this shouldn't need to fail - PlatformViewsController should be
// independent. Dev builds of engine should just fail here. We don't want to fail in release mode
// because this shouldn't ordinarily happen.
FML_DCHECK([_flutterEngine viewController])
<< "Cannot register a view factory on a headless engine.";
if ([_flutterEngine viewController]) {
[[_flutterEngine viewController] platformViewsController]->RegisterViewFactory(factory,
factoryId);
} else {
// Shouldn't ordinarily happen, but at least give warning if it does.
FML_LOG(ERROR) << "Cannot register a view factory on a headless engine.";
}
[_flutterEngine platformViewsController] -> RegisterViewFactory(factory, factoryId);
}
@end
......@@ -7,6 +7,8 @@
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h"
#import "FlutterPlatformViews_Internal.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/fml/task_runner.h"
#include "flutter/lib/ui/window/pointer_data_packet.h"
......@@ -22,7 +24,7 @@
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h"
@interface FlutterEngine () <FlutterScreenshotDelegate>
@interface FlutterEngine () <FlutterViewEngineDelegate>
- (shell::Shell&)shell;
......@@ -37,6 +39,7 @@
base64Encode:(bool)base64Encode;
- (FlutterPlatformPlugin*)platformPlugin;
- (shell::FlutterPlatformViewsController*)platformViewsController;
- (FlutterTextInputPlugin*)textInputPlugin;
- (void)launchEngine:(NSString*)entrypoint libraryURI:(NSString*)libraryOrNil;
......
......@@ -14,17 +14,8 @@
namespace shell {
FlutterPlatformViewsController::FlutterPlatformViewsController(
NSObject<FlutterBinaryMessenger>* messenger,
FlutterView* flutter_view)
: flutter_view_([flutter_view retain]) {
channel_.reset([[FlutterMethodChannel alloc]
initWithName:@"flutter/platform_views"
binaryMessenger:messenger
codec:[FlutterStandardMethodCodec sharedInstance]]);
[channel_.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
OnMethodCall(call, result);
}];
void FlutterPlatformViewsController::SetFlutterView(UIView* flutter_view) {
flutter_view_.reset(flutter_view);
}
void FlutterPlatformViewsController::OnMethodCall(FlutterMethodCall* call, FlutterResult& result) {
......@@ -40,6 +31,15 @@ void FlutterPlatformViewsController::OnMethodCall(FlutterMethodCall* call, Flutt
}
void FlutterPlatformViewsController::OnCreate(FlutterMethodCall* call, FlutterResult& result) {
if (!flutter_view_.get()) {
// Right now we assume we have a reference to FlutterView when creating a new view.
// TODO(amirh): support this by setting the refernce to FlutterView when it becomes available.
// https://github.com/flutter/flutter/issues/23787
result([FlutterError errorWithCode:@"create_failed"
message:@"can't create a view on a headless engine"
details:nil]);
return;
}
NSDictionary<NSString*, id>* args = [call arguments];
long viewId = [args[@"id"] longValue];
......@@ -66,7 +66,7 @@ void FlutterPlatformViewsController::OnCreate(FlutterMethodCall* call, FlutterRe
flutterView:flutter_view_] autorelease];
views_[viewId] = fml::scoped_nsobject<FlutterTouchInterceptingView>([view retain]);
FlutterView* flutter_view = flutter_view_.get();
UIView* flutter_view = flutter_view_.get();
[flutter_view addSubview:views_[viewId].get()];
result(nil);
}
......
......@@ -5,7 +5,6 @@
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_
#include "FlutterView.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/common/shell.h"
......@@ -29,20 +28,22 @@ namespace shell {
class FlutterPlatformViewsController : public flow::ExternalViewEmbedder {
public:
FlutterPlatformViewsController(NSObject<FlutterBinaryMessenger>* messenger,
FlutterView* flutter_view);
FlutterPlatformViewsController() = default;
void SetFlutterView(UIView* flutter_view);
void RegisterViewFactory(NSObject<FlutterPlatformViewFactory>* factory, NSString* factoryId);
void CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params);
void OnMethodCall(FlutterMethodCall* call, FlutterResult& result);
private:
fml::scoped_nsobject<FlutterMethodChannel> channel_;
fml::scoped_nsobject<FlutterView> flutter_view_;
fml::scoped_nsobject<UIView> flutter_view_;
std::map<std::string, fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>> factories_;
std::map<int64_t, fml::scoped_nsobject<FlutterTouchInterceptingView>> views_;
void OnMethodCall(FlutterMethodCall* call, FlutterResult& result);
void OnCreate(FlutterMethodCall* call, FlutterResult& result);
void OnDispose(FlutterMethodCall* call, FlutterResult& result);
void OnAcceptGesture(FlutterMethodCall* call, FlutterResult& result);
......
......@@ -9,16 +9,20 @@
#include <memory>
#import "FlutterPlatformViews_Internal.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/platform/darwin/ios/ios_surface.h"
@protocol FlutterScreenshotDelegate <NSObject>
@protocol FlutterViewEngineDelegate <NSObject>
- (shell::Rasterizer::Screenshot)takeScreenshot:(shell::Rasterizer::ScreenshotType)type
asBase64Encoded:(BOOL)base64Encode;
- (flow::ExternalViewEmbedder*)externalViewEmbedder;
@end
@interface FlutterView : UIView
......@@ -27,7 +31,7 @@
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
- (instancetype)initWithDelegate:(id<FlutterScreenshotDelegate>)delegate
- (instancetype)initWithDelegate:(id<FlutterViewEngineDelegate>)delegate
opaque:(BOOL)opaque NS_DESIGNATED_INITIALIZER;
- (std::unique_ptr<shell::IOSSurface>)createSurface;
......
......@@ -23,7 +23,7 @@
@implementation FlutterView
id<FlutterScreenshotDelegate> _delegate;
id<FlutterViewEngineDelegate> _delegate;
- (instancetype)init {
@throw([NSException exceptionWithName:@"FlutterView must initWithDelegate"
......@@ -43,7 +43,7 @@ id<FlutterScreenshotDelegate> _delegate;
userInfo:nil]);
}
- (instancetype)initWithDelegate:(id<FlutterScreenshotDelegate>)delegate opaque:(BOOL)opaque {
- (instancetype)initWithDelegate:(id<FlutterViewEngineDelegate>)delegate opaque:(BOOL)opaque {
FML_DCHECK(delegate) << "Delegate must not be nil.";
self = [super initWithFrame:CGRectNull];
......@@ -55,23 +55,6 @@ id<FlutterScreenshotDelegate> _delegate;
return self;
}
- (FlutterViewController*)flutterViewController {
// Find the first view controller in the responder chain and see if it is a FlutterViewController.
for (UIResponder* responder = self.nextResponder; responder != nil;
responder = responder.nextResponder) {
if ([responder isKindOfClass:[UIViewController class]]) {
if ([responder isKindOfClass:[FlutterViewController class]]) {
return reinterpret_cast<FlutterViewController*>(responder);
} else {
// Should only happen if a non-FlutterViewController tries to somehow (via dynamic class
// resolution or reparenting) set a FlutterView as its view.
return nil;
}
}
}
return nil;
}
- (void)layoutSubviews {
if ([self.layer isKindOfClass:[CAEAGLLayer class]]) {
CAEAGLLayer* layer = reinterpret_cast<CAEAGLLayer*>(self.layer);
......@@ -93,16 +76,15 @@ id<FlutterScreenshotDelegate> _delegate;
}
- (std::unique_ptr<shell::IOSSurface>)createSurface {
::shell::GetExternalViewEmbedder get_view_embedder = [[^() {
return [[self flutterViewController] viewEmbedder];
} copy] autorelease];
if ([self.layer isKindOfClass:[CAEAGLLayer class]]) {
fml::scoped_nsobject<CAEAGLLayer> eagl_layer(
reinterpret_cast<CAEAGLLayer*>([self.layer retain]));
return std::make_unique<shell::IOSSurfaceGL>(std::move(eagl_layer), get_view_embedder);
return std::make_unique<shell::IOSSurfaceGL>(std::move(eagl_layer),
*[_delegate externalViewEmbedder]);
} else {
fml::scoped_nsobject<CALayer> layer(reinterpret_cast<CALayer*>([self.layer retain]));
return std::make_unique<shell::IOSSurfaceSoftware>(std::move(layer), get_view_embedder);
return std::make_unique<shell::IOSSurfaceSoftware>(std::move(layer),
*[_delegate externalViewEmbedder]);
}
}
......
......@@ -113,8 +113,6 @@
_statusBarStyle = UIStatusBarStyleDefault;
[self setupNotificationCenterObservers];
_platformViewsController.reset(
new shell::FlutterPlatformViewsController(_engine.get(), _flutterView.get()));
}
- (fml::scoped_nsobject<FlutterEngine>)engine {
......@@ -125,10 +123,6 @@
return _weakFactory->GetWeakPtr();
}
- (flow::ExternalViewEmbedder*)viewEmbedder {
return _platformViewsController.get();
}
- (void)setupNotificationCenterObservers {
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
[center addObserver:self
......@@ -364,10 +358,11 @@
// NotifyCreated/NotifyDestroyed are synchronous and require hops between the UI and GPU thread.
if (appeared) {
[self installSplashScreenViewCallback];
[_engine.get() platformViewsController] -> SetFlutterView(_flutterView.get());
[_engine.get() platformView] -> NotifyCreated();
} else {
[_engine.get() platformView] -> NotifyDestroyed();
[_engine.get() platformViewsController] -> SetFlutterView(nullptr);
}
}
......
......@@ -19,8 +19,6 @@
@property(readonly) fml::scoped_nsobject<FlutterEngine> engine;
- (flow::ExternalViewEmbedder*)viewEmbedder;
@end
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERVIEWCONTROLLER_INTERNAL_H_
......@@ -13,8 +13,6 @@
namespace shell {
typedef flow::ExternalViewEmbedder* (^GetExternalViewEmbedder)(void);
class IOSSurface {
public:
IOSSurface();
......
......@@ -18,7 +18,7 @@ namespace shell {
class IOSSurfaceGL : public IOSSurface, public GPUSurfaceGLDelegate {
public:
IOSSurfaceGL(fml::scoped_nsobject<CAEAGLLayer> layer,
::shell::GetExternalViewEmbedder get_view_embedder);
flow::ExternalViewEmbedder& external_view_embedder);
~IOSSurfaceGL() override;
......@@ -46,7 +46,7 @@ class IOSSurfaceGL : public IOSSurface, public GPUSurfaceGLDelegate {
private:
IOSGLContext context_;
fml::scoped_nsprotocol<::shell::GetExternalViewEmbedder> get_view_embedder_;
flow::ExternalViewEmbedder& external_view_embedder_;
FML_DISALLOW_COPY_AND_ASSIGN(IOSSurfaceGL);
};
......
......@@ -10,8 +10,8 @@
namespace shell {
IOSSurfaceGL::IOSSurfaceGL(fml::scoped_nsobject<CAEAGLLayer> layer,
::shell::GetExternalViewEmbedder get_view_embedder)
: context_(std::move(layer)), get_view_embedder_([get_view_embedder retain]) {}
flow::ExternalViewEmbedder& view_embedder)
: context_(std::move(layer)), external_view_embedder_(view_embedder) {}
IOSSurfaceGL::~IOSSurfaceGL() = default;
......@@ -59,7 +59,7 @@ bool IOSSurfaceGL::GLContextPresent() {
}
flow::ExternalViewEmbedder* IOSSurfaceGL::GetExternalViewEmbedder() {
return get_view_embedder_.get()();
return &external_view_embedder_;
}
} // namespace shell
......@@ -17,7 +17,7 @@ namespace shell {
class IOSSurfaceSoftware final : public IOSSurface, public GPUSurfaceSoftwareDelegate {
public:
IOSSurfaceSoftware(fml::scoped_nsobject<CALayer> layer,
::shell::GetExternalViewEmbedder get_view_embedder);
flow::ExternalViewEmbedder& view_embedder);
~IOSSurfaceSoftware() override;
......@@ -44,7 +44,7 @@ class IOSSurfaceSoftware final : public IOSSurface, public GPUSurfaceSoftwareDel
private:
fml::scoped_nsobject<CALayer> layer_;
fml::scoped_nsprotocol<::shell::GetExternalViewEmbedder> get_view_embedder_;
flow::ExternalViewEmbedder& external_view_embedder_;
sk_sp<SkSurface> sk_surface_;
FML_DISALLOW_COPY_AND_ASSIGN(IOSSurfaceSoftware);
......
......@@ -16,8 +16,8 @@
namespace shell {
IOSSurfaceSoftware::IOSSurfaceSoftware(fml::scoped_nsobject<CALayer> layer,
::shell::GetExternalViewEmbedder get_view_embedder)
: layer_(std::move(layer)), get_view_embedder_([get_view_embedder retain]) {
flow::ExternalViewEmbedder& view_embedder)
: layer_(std::move(layer)), external_view_embedder_(view_embedder) {
UpdateStorageSizeIfNecessary();
}
......@@ -127,7 +127,7 @@ bool IOSSurfaceSoftware::PresentBackingStore(sk_sp<SkSurface> backing_store) {
}
flow::ExternalViewEmbedder* IOSSurfaceSoftware::GetExternalViewEmbedder() {
return get_view_embedder_.get()();
return &external_view_embedder_;
}
} // namespace shell
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册