iOS: Migrate FlutterEngine to ARC (flutter/engine#55590)
Migrates `FlutterEnging` from manual reference counting to ARC. Migrates properties from `retain` to strong and `assign` to `weak` (where referencing an Obj-C object). No semantic changes, therefore no changes to tests. Issue: https://github.com/flutter/flutter/issues/137801 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
parent
e1a8f27e21
commit
a2ac734e10
@ -70,7 +70,9 @@ source_set("flutter_framework_source_arc") {
|
|||||||
"framework/Source/FlutterDartVMServicePublisher.mm",
|
"framework/Source/FlutterDartVMServicePublisher.mm",
|
||||||
"framework/Source/FlutterEmbedderKeyResponder.h",
|
"framework/Source/FlutterEmbedderKeyResponder.h",
|
||||||
"framework/Source/FlutterEmbedderKeyResponder.mm",
|
"framework/Source/FlutterEmbedderKeyResponder.mm",
|
||||||
|
"framework/Source/FlutterEngine.mm",
|
||||||
"framework/Source/FlutterEngineGroup.mm",
|
"framework/Source/FlutterEngineGroup.mm",
|
||||||
|
"framework/Source/FlutterEngine_Internal.h",
|
||||||
"framework/Source/FlutterHeadlessDartRunner.mm",
|
"framework/Source/FlutterHeadlessDartRunner.mm",
|
||||||
"framework/Source/FlutterKeyPrimaryResponder.h",
|
"framework/Source/FlutterKeyPrimaryResponder.h",
|
||||||
"framework/Source/FlutterKeySecondaryResponder.h",
|
"framework/Source/FlutterKeySecondaryResponder.h",
|
||||||
@ -186,8 +188,6 @@ source_set("flutter_framework_source") {
|
|||||||
# iOS embedder is migrating to ARC.
|
# iOS embedder is migrating to ARC.
|
||||||
# New files are highly encouraged to be in ARC.
|
# New files are highly encouraged to be in ARC.
|
||||||
# To add new files in ARC, add them to the `flutter_framework_source_arc` target.
|
# To add new files in ARC, add them to the `flutter_framework_source_arc` target.
|
||||||
"framework/Source/FlutterEngine.mm",
|
|
||||||
"framework/Source/FlutterEngine_Internal.h",
|
|
||||||
"framework/Source/FlutterViewController.mm",
|
"framework/Source/FlutterViewController.mm",
|
||||||
"framework/Source/FlutterViewController_Internal.h",
|
"framework/Source/FlutterViewController_Internal.h",
|
||||||
"platform_view_ios.h",
|
"platform_view_ios.h",
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
#import "flutter/shell/platform/darwin/ios/rendering_api_selection.h"
|
#import "flutter/shell/platform/darwin/ios/rendering_api_selection.h"
|
||||||
#include "flutter/shell/profiling/sampling_profiler.h"
|
#include "flutter/shell/profiling/sampling_profiler.h"
|
||||||
|
|
||||||
|
FLUTTER_ASSERT_ARC
|
||||||
|
|
||||||
/// Inheriting ThreadConfigurer and use iOS platform thread API to configure the thread priorities
|
/// Inheriting ThreadConfigurer and use iOS platform thread API to configure the thread priorities
|
||||||
/// Using iOS platform thread API to configure thread priority
|
/// Using iOS platform thread API to configure thread priority
|
||||||
static void IOSPlatformThreadConfigSetter(const fml::Thread::ThreadConfig& config) {
|
static void IOSPlatformThreadConfigSetter(const fml::Thread::ThreadConfig& config) {
|
||||||
@ -88,7 +90,7 @@ NSString* const kFlutterKeyDataChannel = @"flutter/keydata";
|
|||||||
static constexpr int kNumProfilerSamplesPerSec = 5;
|
static constexpr int kNumProfilerSamplesPerSec = 5;
|
||||||
|
|
||||||
@interface FlutterEngineRegistrar : NSObject <FlutterPluginRegistrar>
|
@interface FlutterEngineRegistrar : NSObject <FlutterPluginRegistrar>
|
||||||
@property(nonatomic, assign) FlutterEngine* flutterEngine;
|
@property(nonatomic, weak) FlutterEngine* flutterEngine;
|
||||||
- (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine*)flutterEngine;
|
- (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine*)flutterEngine;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@ -97,6 +99,14 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
FlutterTextInputDelegate,
|
FlutterTextInputDelegate,
|
||||||
FlutterBinaryMessenger,
|
FlutterBinaryMessenger,
|
||||||
FlutterTextureRegistry>
|
FlutterTextureRegistry>
|
||||||
|
|
||||||
|
#pragma mark - Properties
|
||||||
|
|
||||||
|
@property(nonatomic, readonly) FlutterDartProject* dartProject;
|
||||||
|
@property(nonatomic, readonly, copy) NSString* labelPrefix;
|
||||||
|
@property(nonatomic, readonly, assign) BOOL allowHeadlessExecution;
|
||||||
|
@property(nonatomic, readonly, assign) BOOL restorationEnabled;
|
||||||
|
|
||||||
// Maintains a dictionary of plugin names that have registered with the engine. Used by
|
// Maintains a dictionary of plugin names that have registered with the engine. Used by
|
||||||
// FlutterEngineRegistrar to implement a FlutterPluginRegistrar.
|
// FlutterEngineRegistrar to implement a FlutterPluginRegistrar.
|
||||||
@property(nonatomic, readonly) NSMutableDictionary* pluginPublications;
|
@property(nonatomic, readonly) NSMutableDictionary* pluginPublications;
|
||||||
@ -104,55 +114,53 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
|
|
||||||
@property(nonatomic, readwrite, copy) NSString* isolateId;
|
@property(nonatomic, readwrite, copy) NSString* isolateId;
|
||||||
@property(nonatomic, copy) NSString* initialRoute;
|
@property(nonatomic, copy) NSString* initialRoute;
|
||||||
@property(nonatomic, retain) id<NSObject> flutterViewControllerWillDeallocObserver;
|
@property(nonatomic, strong) id<NSObject> flutterViewControllerWillDeallocObserver;
|
||||||
|
@property(nonatomic, strong) FlutterDartVMServicePublisher* publisher;
|
||||||
|
@property(nonatomic, assign) int64_t nextTextureId;
|
||||||
|
|
||||||
|
#pragma mark - Channel properties
|
||||||
|
|
||||||
|
@property(nonatomic, strong) FlutterPlatformPlugin* platformPlugin;
|
||||||
|
@property(nonatomic, strong) FlutterTextInputPlugin* textInputPlugin;
|
||||||
|
@property(nonatomic, strong) FlutterUndoManagerPlugin* undoManagerPlugin;
|
||||||
|
@property(nonatomic, strong) FlutterSpellCheckPlugin* spellCheckPlugin;
|
||||||
|
@property(nonatomic, strong) FlutterRestorationPlugin* restorationPlugin;
|
||||||
|
@property(nonatomic, strong) FlutterMethodChannel* localizationChannel;
|
||||||
|
@property(nonatomic, strong) FlutterMethodChannel* navigationChannel;
|
||||||
|
@property(nonatomic, strong) FlutterMethodChannel* restorationChannel;
|
||||||
|
@property(nonatomic, strong) FlutterMethodChannel* platformChannel;
|
||||||
|
@property(nonatomic, strong) FlutterMethodChannel* platformViewsChannel;
|
||||||
|
@property(nonatomic, strong) FlutterMethodChannel* textInputChannel;
|
||||||
|
@property(nonatomic, strong) FlutterMethodChannel* undoManagerChannel;
|
||||||
|
@property(nonatomic, strong) FlutterMethodChannel* scribbleChannel;
|
||||||
|
@property(nonatomic, strong) FlutterMethodChannel* spellCheckChannel;
|
||||||
|
@property(nonatomic, strong) FlutterBasicMessageChannel* lifecycleChannel;
|
||||||
|
@property(nonatomic, strong) FlutterBasicMessageChannel* systemChannel;
|
||||||
|
@property(nonatomic, strong) FlutterBasicMessageChannel* settingsChannel;
|
||||||
|
@property(nonatomic, strong) FlutterBasicMessageChannel* keyEventChannel;
|
||||||
|
@property(nonatomic, strong) FlutterMethodChannel* screenshotChannel;
|
||||||
|
|
||||||
#pragma mark - Embedder API properties
|
#pragma mark - Embedder API properties
|
||||||
|
|
||||||
@property(nonatomic, assign) BOOL enableEmbedderAPI;
|
@property(nonatomic, assign) BOOL enableEmbedderAPI;
|
||||||
// Function pointers for interacting with the embedder.h API.
|
// Function pointers for interacting with the embedder.h API.
|
||||||
@property(nonatomic) FlutterEngineProcTable& embedderAPI;
|
@property(nonatomic) FlutterEngineProcTable& embedderAPI;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation FlutterEngine {
|
@implementation FlutterEngine {
|
||||||
fml::scoped_nsobject<FlutterDartProject> _dartProject;
|
|
||||||
std::shared_ptr<flutter::ThreadHost> _threadHost;
|
std::shared_ptr<flutter::ThreadHost> _threadHost;
|
||||||
std::unique_ptr<flutter::Shell> _shell;
|
std::unique_ptr<flutter::Shell> _shell;
|
||||||
NSString* _labelPrefix;
|
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory;
|
|
||||||
|
|
||||||
|
// TODO(cbracken): https://github.com/flutter/flutter/issues/155943
|
||||||
|
// Migrate to @property(nonatomic, weak).
|
||||||
fml::WeakNSObject<FlutterViewController> _viewController;
|
fml::WeakNSObject<FlutterViewController> _viewController;
|
||||||
fml::scoped_nsobject<FlutterDartVMServicePublisher> _publisher;
|
|
||||||
|
|
||||||
std::shared_ptr<flutter::PlatformViewsController> _platformViewsController;
|
std::shared_ptr<flutter::PlatformViewsController> _platformViewsController;
|
||||||
flutter::IOSRenderingAPI _renderingApi;
|
flutter::IOSRenderingAPI _renderingApi;
|
||||||
std::shared_ptr<flutter::ProfilerMetricsIOS> _profiler_metrics;
|
std::shared_ptr<flutter::ProfilerMetricsIOS> _profiler_metrics;
|
||||||
std::shared_ptr<flutter::SamplingProfiler> _profiler;
|
std::shared_ptr<flutter::SamplingProfiler> _profiler;
|
||||||
|
|
||||||
// Channels
|
|
||||||
fml::scoped_nsobject<FlutterPlatformPlugin> _platformPlugin;
|
|
||||||
fml::scoped_nsobject<FlutterTextInputPlugin> _textInputPlugin;
|
|
||||||
fml::scoped_nsobject<FlutterUndoManagerPlugin> _undoManagerPlugin;
|
|
||||||
fml::scoped_nsobject<FlutterSpellCheckPlugin> _spellCheckPlugin;
|
|
||||||
fml::scoped_nsobject<FlutterRestorationPlugin> _restorationPlugin;
|
|
||||||
fml::scoped_nsobject<FlutterMethodChannel> _localizationChannel;
|
|
||||||
fml::scoped_nsobject<FlutterMethodChannel> _navigationChannel;
|
|
||||||
fml::scoped_nsobject<FlutterMethodChannel> _restorationChannel;
|
|
||||||
fml::scoped_nsobject<FlutterMethodChannel> _platformChannel;
|
|
||||||
fml::scoped_nsobject<FlutterMethodChannel> _platformViewsChannel;
|
|
||||||
fml::scoped_nsobject<FlutterMethodChannel> _textInputChannel;
|
|
||||||
fml::scoped_nsobject<FlutterMethodChannel> _undoManagerChannel;
|
|
||||||
fml::scoped_nsobject<FlutterMethodChannel> _scribbleChannel;
|
|
||||||
fml::scoped_nsobject<FlutterMethodChannel> _spellCheckChannel;
|
|
||||||
fml::scoped_nsobject<FlutterBasicMessageChannel> _lifecycleChannel;
|
|
||||||
fml::scoped_nsobject<FlutterBasicMessageChannel> _systemChannel;
|
|
||||||
fml::scoped_nsobject<FlutterBasicMessageChannel> _settingsChannel;
|
|
||||||
fml::scoped_nsobject<FlutterBasicMessageChannel> _keyEventChannel;
|
|
||||||
fml::scoped_nsobject<FlutterMethodChannel> _screenshotChannel;
|
|
||||||
|
|
||||||
int64_t _nextTextureId;
|
|
||||||
|
|
||||||
BOOL _allowHeadlessExecution;
|
|
||||||
BOOL _restorationEnabled;
|
|
||||||
FlutterBinaryMessengerRelay* _binaryMessenger;
|
FlutterBinaryMessengerRelay* _binaryMessenger;
|
||||||
FlutterTextureRegistryRelay* _textureRegistry;
|
FlutterTextureRegistryRelay* _textureRegistry;
|
||||||
std::unique_ptr<flutter::ConnectionCollection> _connections;
|
std::unique_ptr<flutter::ConnectionCollection> _connections;
|
||||||
@ -190,29 +198,21 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
_restorationEnabled = restorationEnabled;
|
_restorationEnabled = restorationEnabled;
|
||||||
_allowHeadlessExecution = allowHeadlessExecution;
|
_allowHeadlessExecution = allowHeadlessExecution;
|
||||||
_labelPrefix = [labelPrefix copy];
|
_labelPrefix = [labelPrefix copy];
|
||||||
|
_dartProject = project ?: [[FlutterDartProject alloc] init];
|
||||||
|
|
||||||
_weakFactory = std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(self);
|
_enableEmbedderAPI = _dartProject.settings.enable_embedder_api;
|
||||||
|
|
||||||
if (project == nil) {
|
|
||||||
_dartProject.reset([[FlutterDartProject alloc] init]);
|
|
||||||
} else {
|
|
||||||
_dartProject.reset([project retain]);
|
|
||||||
}
|
|
||||||
|
|
||||||
_enableEmbedderAPI = _dartProject.get().settings.enable_embedder_api;
|
|
||||||
if (_enableEmbedderAPI) {
|
if (_enableEmbedderAPI) {
|
||||||
NSLog(@"============== iOS: enable_embedder_api is on ==============");
|
NSLog(@"============== iOS: enable_embedder_api is on ==============");
|
||||||
_embedderAPI.struct_size = sizeof(FlutterEngineProcTable);
|
_embedderAPI.struct_size = sizeof(FlutterEngineProcTable);
|
||||||
FlutterEngineGetProcAddresses(&_embedderAPI);
|
FlutterEngineGetProcAddresses(&_embedderAPI);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EnableTracingIfNecessary([_dartProject.get() settings])) {
|
if (!EnableTracingIfNecessary(_dartProject.settings)) {
|
||||||
NSLog(
|
NSLog(
|
||||||
@"Cannot create a FlutterEngine instance in debug mode without Flutter tooling or "
|
@"Cannot create a FlutterEngine instance in debug mode without Flutter tooling or "
|
||||||
@"Xcode.\n\nTo launch in debug mode in iOS 14+, run flutter run from Flutter tools, run "
|
@"Xcode.\n\nTo launch in debug mode in iOS 14+, run flutter run from Flutter tools, run "
|
||||||
@"from an IDE with a Flutter IDE plugin or run the iOS project from Xcode.\nAlternatively "
|
@"from an IDE with a Flutter IDE plugin or run the iOS project from Xcode.\nAlternatively "
|
||||||
@"profile and release mode apps can be launched from the home screen.");
|
@"profile and release mode apps can be launched from the home screen.");
|
||||||
[self release];
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,35 +292,22 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
object:self
|
object:self
|
||||||
userInfo:nil];
|
userInfo:nil];
|
||||||
|
|
||||||
// It will be destroyed and invalidate its weak pointers
|
// nil out weak references.
|
||||||
// before any other members are destroyed.
|
// TODO(cbracken): https://github.com/flutter/flutter/issues/156222
|
||||||
_weakFactory.reset();
|
// Ensure that FlutterEngineRegistrar is using weak pointers, then eliminate this code.
|
||||||
|
|
||||||
/// nil out weak references.
|
|
||||||
[_registrars
|
[_registrars
|
||||||
enumerateKeysAndObjectsUsingBlock:^(id key, FlutterEngineRegistrar* registrar, BOOL* stop) {
|
enumerateKeysAndObjectsUsingBlock:^(id key, FlutterEngineRegistrar* registrar, BOOL* stop) {
|
||||||
registrar.flutterEngine = nil;
|
registrar.flutterEngine = nil;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[_labelPrefix release];
|
|
||||||
[_initialRoute release];
|
|
||||||
[_pluginPublications release];
|
|
||||||
[_registrars release];
|
|
||||||
_binaryMessenger.parent = nil;
|
_binaryMessenger.parent = nil;
|
||||||
_textureRegistry.parent = nil;
|
_textureRegistry.parent = nil;
|
||||||
[_binaryMessenger release];
|
|
||||||
[_textureRegistry release];
|
|
||||||
_textureRegistry = nil;
|
|
||||||
[_isolateId release];
|
|
||||||
|
|
||||||
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||||
if (_flutterViewControllerWillDeallocObserver) {
|
if (_flutterViewControllerWillDeallocObserver) {
|
||||||
[center removeObserver:_flutterViewControllerWillDeallocObserver];
|
[center removeObserver:_flutterViewControllerWillDeallocObserver];
|
||||||
[_flutterViewControllerWillDeallocObserver release];
|
|
||||||
}
|
}
|
||||||
[center removeObserver:self];
|
[center removeObserver:self];
|
||||||
|
|
||||||
[super dealloc];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (flutter::Shell&)shell {
|
- (flutter::Shell&)shell {
|
||||||
@ -328,10 +315,6 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
return *_shell;
|
return *_shell;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (fml::WeakNSObject<FlutterEngine>)getWeakNSObject {
|
|
||||||
return _weakFactory->GetWeakNSObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)updateViewportMetrics:(flutter::ViewportMetrics)viewportMetrics {
|
- (void)updateViewportMetrics:(flutter::ViewportMetrics)viewportMetrics {
|
||||||
if (!self.platformView) {
|
if (!self.platformView) {
|
||||||
return;
|
return;
|
||||||
@ -429,16 +412,16 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
self.iosPlatformView->SetOwnerViewController(_viewController);
|
self.iosPlatformView->SetOwnerViewController(_viewController);
|
||||||
[self maybeSetupPlatformViewChannels];
|
[self maybeSetupPlatformViewChannels];
|
||||||
[self updateDisplays];
|
[self updateDisplays];
|
||||||
_textInputPlugin.get().viewController = viewController;
|
self.textInputPlugin.viewController = viewController;
|
||||||
|
|
||||||
if (viewController) {
|
if (viewController) {
|
||||||
__block FlutterEngine* blockSelf = self;
|
__weak __block FlutterEngine* weakSelf = self;
|
||||||
self.flutterViewControllerWillDeallocObserver =
|
self.flutterViewControllerWillDeallocObserver =
|
||||||
[[NSNotificationCenter defaultCenter] addObserverForName:FlutterViewControllerWillDealloc
|
[[NSNotificationCenter defaultCenter] addObserverForName:FlutterViewControllerWillDealloc
|
||||||
object:viewController
|
object:viewController
|
||||||
queue:[NSOperationQueue mainQueue]
|
queue:[NSOperationQueue mainQueue]
|
||||||
usingBlock:^(NSNotification* note) {
|
usingBlock:^(NSNotification* note) {
|
||||||
[blockSelf notifyViewControllerDeallocated];
|
[weakSelf notifyViewControllerDeallocated];
|
||||||
}];
|
}];
|
||||||
} else {
|
} else {
|
||||||
self.flutterViewControllerWillDeallocObserver = nil;
|
self.flutterViewControllerWillDeallocObserver = nil;
|
||||||
@ -455,16 +438,15 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
if (_flutterViewControllerWillDeallocObserver) {
|
if (_flutterViewControllerWillDeallocObserver) {
|
||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
removeObserver:_flutterViewControllerWillDeallocObserver];
|
removeObserver:_flutterViewControllerWillDeallocObserver];
|
||||||
[_flutterViewControllerWillDeallocObserver release];
|
|
||||||
}
|
}
|
||||||
_flutterViewControllerWillDeallocObserver = [observer retain];
|
_flutterViewControllerWillDeallocObserver = observer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)notifyViewControllerDeallocated {
|
- (void)notifyViewControllerDeallocated {
|
||||||
[[self lifecycleChannel] sendMessage:@"AppLifecycleState.detached"];
|
[self.lifecycleChannel sendMessage:@"AppLifecycleState.detached"];
|
||||||
_textInputPlugin.get().viewController = nil;
|
self.textInputPlugin.viewController = nil;
|
||||||
if (!_allowHeadlessExecution) {
|
if (!self.allowHeadlessExecution) {
|
||||||
[self destroyContext];
|
[self destroyContext];
|
||||||
} else if (_shell) {
|
} else if (_shell) {
|
||||||
flutter::PlatformViewIOS* platform_view = [self iosPlatformView];
|
flutter::PlatformViewIOS* platform_view = [self iosPlatformView];
|
||||||
@ -472,7 +454,7 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
platform_view->SetOwnerViewController({});
|
platform_view->SetOwnerViewController({});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[_textInputPlugin.get() resetViewResponder];
|
[self.textInputPlugin resetViewResponder];
|
||||||
_viewController.reset();
|
_viewController.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,88 +474,46 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
return _viewController.get();
|
return _viewController.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (FlutterPlatformPlugin*)platformPlugin {
|
|
||||||
return _platformPlugin.get();
|
|
||||||
}
|
|
||||||
- (std::shared_ptr<flutter::PlatformViewsController>&)platformViewsController {
|
- (std::shared_ptr<flutter::PlatformViewsController>&)platformViewsController {
|
||||||
return _platformViewsController;
|
return _platformViewsController;
|
||||||
}
|
}
|
||||||
- (FlutterTextInputPlugin*)textInputPlugin {
|
|
||||||
return _textInputPlugin.get();
|
|
||||||
}
|
|
||||||
- (FlutterUndoManagerPlugin*)undoManagerPlugin {
|
|
||||||
return _undoManagerPlugin.get();
|
|
||||||
}
|
|
||||||
- (FlutterRestorationPlugin*)restorationPlugin {
|
|
||||||
return _restorationPlugin.get();
|
|
||||||
}
|
|
||||||
- (FlutterMethodChannel*)localizationChannel {
|
|
||||||
return _localizationChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterMethodChannel*)navigationChannel {
|
|
||||||
return _navigationChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterMethodChannel*)restorationChannel {
|
|
||||||
return _restorationChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterMethodChannel*)platformChannel {
|
|
||||||
return _platformChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterMethodChannel*)textInputChannel {
|
|
||||||
return _textInputChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterMethodChannel*)undoManagerChannel {
|
|
||||||
return _undoManagerChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterMethodChannel*)scribbleChannel {
|
|
||||||
return _scribbleChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterMethodChannel*)spellCheckChannel {
|
|
||||||
return _spellCheckChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterBasicMessageChannel*)lifecycleChannel {
|
|
||||||
return _lifecycleChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterBasicMessageChannel*)systemChannel {
|
|
||||||
return _systemChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterBasicMessageChannel*)settingsChannel {
|
|
||||||
return _settingsChannel.get();
|
|
||||||
}
|
|
||||||
- (FlutterBasicMessageChannel*)keyEventChannel {
|
|
||||||
return _keyEventChannel.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSURL*)observatoryUrl {
|
- (NSURL*)observatoryUrl {
|
||||||
return [_publisher.get() url];
|
return self.publisher.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURL*)vmServiceUrl {
|
- (NSURL*)vmServiceUrl {
|
||||||
return [_publisher.get() url];
|
return self.publisher.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)resetChannels {
|
- (void)resetChannels {
|
||||||
_localizationChannel.reset();
|
self.localizationChannel = nil;
|
||||||
_navigationChannel.reset();
|
self.navigationChannel = nil;
|
||||||
_restorationChannel.reset();
|
self.restorationChannel = nil;
|
||||||
_platformChannel.reset();
|
self.platformChannel = nil;
|
||||||
_platformViewsChannel.reset();
|
self.platformViewsChannel = nil;
|
||||||
_textInputChannel.reset();
|
self.textInputChannel = nil;
|
||||||
_undoManagerChannel.reset();
|
self.undoManagerChannel = nil;
|
||||||
_scribbleChannel.reset();
|
self.scribbleChannel = nil;
|
||||||
_lifecycleChannel.reset();
|
self.lifecycleChannel = nil;
|
||||||
_systemChannel.reset();
|
self.systemChannel = nil;
|
||||||
_settingsChannel.reset();
|
self.settingsChannel = nil;
|
||||||
_keyEventChannel.reset();
|
self.keyEventChannel = nil;
|
||||||
_spellCheckChannel.reset();
|
self.spellCheckChannel = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startProfiler {
|
- (void)startProfiler {
|
||||||
FML_DCHECK(!_threadHost->name_prefix.empty());
|
FML_DCHECK(!_threadHost->name_prefix.empty());
|
||||||
_profiler_metrics = std::make_shared<flutter::ProfilerMetricsIOS>();
|
_profiler_metrics = std::make_shared<flutter::ProfilerMetricsIOS>();
|
||||||
|
__weak FlutterEngine* weakSelf = self;
|
||||||
_profiler = std::make_shared<flutter::SamplingProfiler>(
|
_profiler = std::make_shared<flutter::SamplingProfiler>(
|
||||||
_threadHost->name_prefix.c_str(), _threadHost->profiler_thread->GetTaskRunner(),
|
_threadHost->name_prefix.c_str(), _threadHost->profiler_thread->GetTaskRunner(),
|
||||||
[self]() { return self->_profiler_metrics->GenerateSample(); }, kNumProfilerSamplesPerSec);
|
[weakSelf]() {
|
||||||
|
FlutterEngine* strongSelf = weakSelf;
|
||||||
|
return strongSelf ? strongSelf->_profiler_metrics->GenerateSample()
|
||||||
|
: flutter::ProfileSample{};
|
||||||
|
},
|
||||||
|
kNumProfilerSamplesPerSec);
|
||||||
_profiler->Start();
|
_profiler->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,165 +523,155 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
- (void)setUpChannels {
|
- (void)setUpChannels {
|
||||||
// This will be invoked once the shell is done setting up and the isolate ID
|
// This will be invoked once the shell is done setting up and the isolate ID
|
||||||
// for the UI isolate is available.
|
// for the UI isolate is available.
|
||||||
fml::WeakNSObject<FlutterEngine> weakSelf = [self getWeakNSObject];
|
__weak FlutterEngine* weakSelf = self;
|
||||||
[_binaryMessenger setMessageHandlerOnChannel:@"flutter/isolate"
|
[_binaryMessenger setMessageHandlerOnChannel:@"flutter/isolate"
|
||||||
binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) {
|
binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) {
|
||||||
if (weakSelf) {
|
if (weakSelf) {
|
||||||
weakSelf.get().isolateId =
|
weakSelf.isolateId =
|
||||||
[[FlutterStringCodec sharedInstance] decode:message];
|
[[FlutterStringCodec sharedInstance] decode:message];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
_localizationChannel.reset([[FlutterMethodChannel alloc]
|
self.localizationChannel =
|
||||||
initWithName:@"flutter/localization"
|
[[FlutterMethodChannel alloc] initWithName:@"flutter/localization"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterJSONMethodCodec sharedInstance]]);
|
codec:[FlutterJSONMethodCodec sharedInstance]];
|
||||||
|
|
||||||
_navigationChannel.reset([[FlutterMethodChannel alloc]
|
self.navigationChannel =
|
||||||
initWithName:@"flutter/navigation"
|
[[FlutterMethodChannel alloc] initWithName:@"flutter/navigation"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterJSONMethodCodec sharedInstance]]);
|
codec:[FlutterJSONMethodCodec sharedInstance]];
|
||||||
|
|
||||||
if ([_initialRoute length] > 0) {
|
if ([_initialRoute length] > 0) {
|
||||||
// Flutter isn't ready to receive this method call yet but the channel buffer will cache this.
|
// Flutter isn't ready to receive this method call yet but the channel buffer will cache this.
|
||||||
[_navigationChannel invokeMethod:@"setInitialRoute" arguments:_initialRoute];
|
[self.navigationChannel invokeMethod:@"setInitialRoute" arguments:_initialRoute];
|
||||||
[_initialRoute release];
|
|
||||||
_initialRoute = nil;
|
_initialRoute = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
_restorationChannel.reset([[FlutterMethodChannel alloc]
|
self.restorationChannel =
|
||||||
initWithName:@"flutter/restoration"
|
[[FlutterMethodChannel alloc] initWithName:@"flutter/restoration"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterStandardMethodCodec sharedInstance]]);
|
codec:[FlutterStandardMethodCodec sharedInstance]];
|
||||||
|
|
||||||
_platformChannel.reset([[FlutterMethodChannel alloc]
|
self.platformChannel =
|
||||||
initWithName:@"flutter/platform"
|
[[FlutterMethodChannel alloc] initWithName:@"flutter/platform"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterJSONMethodCodec sharedInstance]]);
|
codec:[FlutterJSONMethodCodec sharedInstance]];
|
||||||
|
|
||||||
_platformViewsChannel.reset([[FlutterMethodChannel alloc]
|
self.platformViewsChannel =
|
||||||
initWithName:@"flutter/platform_views"
|
[[FlutterMethodChannel alloc] initWithName:@"flutter/platform_views"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterStandardMethodCodec sharedInstance]]);
|
codec:[FlutterStandardMethodCodec sharedInstance]];
|
||||||
|
|
||||||
_textInputChannel.reset([[FlutterMethodChannel alloc]
|
self.textInputChannel =
|
||||||
initWithName:@"flutter/textinput"
|
[[FlutterMethodChannel alloc] initWithName:@"flutter/textinput"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterJSONMethodCodec sharedInstance]]);
|
codec:[FlutterJSONMethodCodec sharedInstance]];
|
||||||
|
|
||||||
_undoManagerChannel.reset([[FlutterMethodChannel alloc]
|
self.undoManagerChannel =
|
||||||
initWithName:@"flutter/undomanager"
|
[[FlutterMethodChannel alloc] initWithName:@"flutter/undomanager"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterJSONMethodCodec sharedInstance]]);
|
codec:[FlutterJSONMethodCodec sharedInstance]];
|
||||||
|
|
||||||
_scribbleChannel.reset([[FlutterMethodChannel alloc]
|
self.scribbleChannel =
|
||||||
initWithName:@"flutter/scribble"
|
[[FlutterMethodChannel alloc] initWithName:@"flutter/scribble"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterJSONMethodCodec sharedInstance]]);
|
codec:[FlutterJSONMethodCodec sharedInstance]];
|
||||||
|
|
||||||
_spellCheckChannel.reset([[FlutterMethodChannel alloc]
|
self.spellCheckChannel =
|
||||||
initWithName:@"flutter/spellcheck"
|
[[FlutterMethodChannel alloc] initWithName:@"flutter/spellcheck"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterStandardMethodCodec sharedInstance]]);
|
codec:[FlutterStandardMethodCodec sharedInstance]];
|
||||||
|
|
||||||
_lifecycleChannel.reset([[FlutterBasicMessageChannel alloc]
|
self.lifecycleChannel =
|
||||||
initWithName:@"flutter/lifecycle"
|
[[FlutterBasicMessageChannel alloc] initWithName:@"flutter/lifecycle"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterStringCodec sharedInstance]]);
|
codec:[FlutterStringCodec sharedInstance]];
|
||||||
|
|
||||||
_systemChannel.reset([[FlutterBasicMessageChannel alloc]
|
self.systemChannel =
|
||||||
initWithName:@"flutter/system"
|
[[FlutterBasicMessageChannel alloc] initWithName:@"flutter/system"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterJSONMessageCodec sharedInstance]]);
|
codec:[FlutterJSONMessageCodec sharedInstance]];
|
||||||
|
|
||||||
_settingsChannel.reset([[FlutterBasicMessageChannel alloc]
|
self.settingsChannel =
|
||||||
initWithName:@"flutter/settings"
|
[[FlutterBasicMessageChannel alloc] initWithName:@"flutter/settings"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterJSONMessageCodec sharedInstance]]);
|
codec:[FlutterJSONMessageCodec sharedInstance]];
|
||||||
|
|
||||||
_keyEventChannel.reset([[FlutterBasicMessageChannel alloc]
|
self.keyEventChannel =
|
||||||
initWithName:@"flutter/keyevent"
|
[[FlutterBasicMessageChannel alloc] initWithName:@"flutter/keyevent"
|
||||||
binaryMessenger:self.binaryMessenger
|
binaryMessenger:self.binaryMessenger
|
||||||
codec:[FlutterJSONMessageCodec sharedInstance]]);
|
codec:[FlutterJSONMessageCodec sharedInstance]];
|
||||||
|
|
||||||
FlutterTextInputPlugin* textInputPlugin = [[FlutterTextInputPlugin alloc] initWithDelegate:self];
|
self.textInputPlugin = [[FlutterTextInputPlugin alloc] initWithDelegate:self];
|
||||||
_textInputPlugin.reset(textInputPlugin);
|
self.textInputPlugin.indirectScribbleDelegate = self;
|
||||||
textInputPlugin.indirectScribbleDelegate = self;
|
[self.textInputPlugin setUpIndirectScribbleInteraction:self.viewController];
|
||||||
[textInputPlugin setUpIndirectScribbleInteraction:self.viewController];
|
|
||||||
|
|
||||||
FlutterUndoManagerPlugin* undoManagerPlugin =
|
self.undoManagerPlugin = [[FlutterUndoManagerPlugin alloc] initWithDelegate:self];
|
||||||
[[FlutterUndoManagerPlugin alloc] initWithDelegate:self];
|
self.platformPlugin = [[FlutterPlatformPlugin alloc] initWithEngine:self];
|
||||||
_undoManagerPlugin.reset(undoManagerPlugin);
|
|
||||||
|
|
||||||
_platformPlugin.reset([[FlutterPlatformPlugin alloc] initWithEngine:[self getWeakNSObject]]);
|
self.restorationPlugin =
|
||||||
|
[[FlutterRestorationPlugin alloc] initWithChannel:self.restorationChannel
|
||||||
|
restorationEnabled:self.restorationEnabled];
|
||||||
|
self.spellCheckPlugin = [[FlutterSpellCheckPlugin alloc] init];
|
||||||
|
|
||||||
_restorationPlugin.reset([[FlutterRestorationPlugin alloc]
|
self.screenshotChannel =
|
||||||
initWithChannel:_restorationChannel.get()
|
[[FlutterMethodChannel alloc] initWithName:@"flutter/screenshot"
|
||||||
restorationEnabled:_restorationEnabled]);
|
binaryMessenger:self.binaryMessenger
|
||||||
_spellCheckPlugin.reset([[FlutterSpellCheckPlugin alloc] init]);
|
codec:[FlutterStandardMethodCodec sharedInstance]];
|
||||||
|
|
||||||
_screenshotChannel.reset([[FlutterMethodChannel alloc]
|
[self.screenshotChannel setMethodCallHandler:^(FlutterMethodCall* _Nonnull call,
|
||||||
initWithName:@"flutter/screenshot"
|
FlutterResult _Nonnull result) {
|
||||||
binaryMessenger:self.binaryMessenger
|
FlutterEngine* strongSelf = weakSelf;
|
||||||
codec:[FlutterStandardMethodCodec sharedInstance]]);
|
if (!(strongSelf && strongSelf->_shell && strongSelf->_shell->IsSetup())) {
|
||||||
|
return result([FlutterError
|
||||||
[_screenshotChannel.get()
|
errorWithCode:@"invalid_state"
|
||||||
setMethodCallHandler:^(FlutterMethodCall* _Nonnull call, FlutterResult _Nonnull result) {
|
message:@"Requesting screenshot while engine is not running."
|
||||||
if (!(weakSelf.get() && weakSelf.get()->_shell && weakSelf.get()->_shell->IsSetup())) {
|
details:nil]);
|
||||||
return result([FlutterError
|
}
|
||||||
errorWithCode:@"invalid_state"
|
flutter::Rasterizer::Screenshot screenshot =
|
||||||
message:@"Requesting screenshot while engine is not running."
|
[strongSelf screenshot:flutter::Rasterizer::ScreenshotType::SurfaceData base64Encode:NO];
|
||||||
details:nil]);
|
if (!screenshot.data) {
|
||||||
}
|
return result([FlutterError errorWithCode:@"failure"
|
||||||
flutter::Rasterizer::Screenshot screenshot =
|
message:@"Unable to get screenshot."
|
||||||
[weakSelf.get() screenshot:flutter::Rasterizer::ScreenshotType::SurfaceData
|
details:nil]);
|
||||||
base64Encode:NO];
|
}
|
||||||
if (!screenshot.data) {
|
// TODO(gaaclarke): Find way to eliminate this data copy.
|
||||||
return result([FlutterError errorWithCode:@"failure"
|
NSData* data = [NSData dataWithBytes:screenshot.data->writable_data()
|
||||||
message:@"Unable to get screenshot."
|
length:screenshot.data->size()];
|
||||||
details:nil]);
|
NSString* format = [NSString stringWithUTF8String:screenshot.format.c_str()];
|
||||||
}
|
NSNumber* width = @(screenshot.frame_size.fWidth);
|
||||||
// TODO(gaaclarke): Find way to eliminate this data copy.
|
NSNumber* height = @(screenshot.frame_size.fHeight);
|
||||||
NSData* data = [NSData dataWithBytes:screenshot.data->writable_data()
|
return result(@[ width, height, format ?: [NSNull null], data ]);
|
||||||
length:screenshot.data->size()];
|
}];
|
||||||
NSString* format = [NSString stringWithUTF8String:screenshot.format.c_str()];
|
|
||||||
NSNumber* width = @(screenshot.frame_size.fWidth);
|
|
||||||
NSNumber* height = @(screenshot.frame_size.fHeight);
|
|
||||||
return result(@[ width, height, format ?: [NSNull null], data ]);
|
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)maybeSetupPlatformViewChannels {
|
- (void)maybeSetupPlatformViewChannels {
|
||||||
if (_shell && self.shell.IsSetup()) {
|
if (_shell && self.shell.IsSetup()) {
|
||||||
FlutterPlatformPlugin* platformPlugin = _platformPlugin.get();
|
__weak FlutterEngine* weakSelf = self;
|
||||||
[_platformChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
|
|
||||||
[platformPlugin handleMethodCall:call result:result];
|
[self.platformChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
|
||||||
|
[weakSelf.platformPlugin handleMethodCall:call result:result];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
fml::WeakNSObject<FlutterEngine> weakSelf = [self getWeakNSObject];
|
[self.platformViewsChannel
|
||||||
[_platformViewsChannel.get()
|
|
||||||
setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
|
setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
|
||||||
if (weakSelf) {
|
if (weakSelf) {
|
||||||
weakSelf.get().platformViewsController->OnMethodCall(call, result);
|
weakSelf.platformViewsController->OnMethodCall(call, result);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
FlutterTextInputPlugin* textInputPlugin = _textInputPlugin.get();
|
[self.textInputChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
|
||||||
[_textInputChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
|
[weakSelf.textInputPlugin handleMethodCall:call result:result];
|
||||||
[textInputPlugin handleMethodCall:call result:result];
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
FlutterUndoManagerPlugin* undoManagerPlugin = _undoManagerPlugin.get();
|
[self.undoManagerChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
|
||||||
[_undoManagerChannel.get()
|
[weakSelf.undoManagerPlugin handleMethodCall:call result:result];
|
||||||
setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
|
}];
|
||||||
[undoManagerPlugin handleMethodCall:call result:result];
|
|
||||||
}];
|
|
||||||
|
|
||||||
FlutterSpellCheckPlugin* spellCheckPlugin = _spellCheckPlugin.get();
|
[self.spellCheckChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
|
||||||
[_spellCheckChannel.get()
|
[weakSelf.spellCheckPlugin handleMethodCall:call result:result];
|
||||||
setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
|
}];
|
||||||
[spellCheckPlugin handleMethodCall:call result:result];
|
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,9 +684,9 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
libraryURI:(NSString*)libraryOrNil
|
libraryURI:(NSString*)libraryOrNil
|
||||||
entrypointArgs:(NSArray<NSString*>*)entrypointArgs {
|
entrypointArgs:(NSArray<NSString*>*)entrypointArgs {
|
||||||
// Launch the Dart application with the inferred run configuration.
|
// Launch the Dart application with the inferred run configuration.
|
||||||
self.shell.RunEngine([_dartProject.get() runConfigurationForEntrypoint:entrypoint
|
self.shell.RunEngine([self.dartProject runConfigurationForEntrypoint:entrypoint
|
||||||
libraryOrNil:libraryOrNil
|
libraryOrNil:libraryOrNil
|
||||||
entrypointArgs:entrypointArgs]);
|
entrypointArgs:entrypointArgs]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setUpShell:(std::unique_ptr<flutter::Shell>)shell
|
- (void)setUpShell:(std::unique_ptr<flutter::Shell>)shell
|
||||||
@ -765,8 +695,8 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
|
|||||||
[self setUpChannels];
|
[self setUpChannels];
|
||||||
[self onLocaleUpdated:nil];
|
[self onLocaleUpdated:nil];
|
||||||
[self updateDisplays];
|
[self updateDisplays];
|
||||||
_publisher.reset([[FlutterDartVMServicePublisher alloc]
|
self.publisher = [[FlutterDartVMServicePublisher alloc]
|
||||||
initWithEnableVMServicePublication:doesVMServicePublication]);
|
initWithEnableVMServicePublication:doesVMServicePublication];
|
||||||
[self maybeSetupPlatformViewChannels];
|
[self maybeSetupPlatformViewChannels];
|
||||||
_shell->SetGpuAvailability(_isGpuDisabled ? flutter::GpuAvailability::kUnavailable
|
_shell->SetGpuAvailability(_isGpuDisabled ? flutter::GpuAvailability::kUnavailable
|
||||||
: flutter::GpuAvailability::kAvailable);
|
: flutter::GpuAvailability::kAvailable);
|
||||||
@ -845,7 +775,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
|
|
||||||
self.initialRoute = initialRoute;
|
self.initialRoute = initialRoute;
|
||||||
|
|
||||||
auto settings = [_dartProject.get() settings];
|
auto settings = [self.dartProject settings];
|
||||||
if (initialRoute != nil) {
|
if (initialRoute != nil) {
|
||||||
self.initialRoute = initialRoute;
|
self.initialRoute = initialRoute;
|
||||||
} else if (settings.route.empty() == false) {
|
} else if (settings.route.empty() == false) {
|
||||||
@ -854,24 +784,28 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
|
|
||||||
FlutterView.forceSoftwareRendering = settings.enable_software_rendering;
|
FlutterView.forceSoftwareRendering = settings.enable_software_rendering;
|
||||||
|
|
||||||
auto platformData = [_dartProject.get() defaultPlatformData];
|
auto platformData = [self.dartProject defaultPlatformData];
|
||||||
|
|
||||||
SetEntryPoint(&settings, entrypoint, libraryURI);
|
SetEntryPoint(&settings, entrypoint, libraryURI);
|
||||||
|
|
||||||
NSString* threadLabel = [FlutterEngine generateThreadLabel:_labelPrefix];
|
NSString* threadLabel = [FlutterEngine generateThreadLabel:self.labelPrefix];
|
||||||
_threadHost = std::make_shared<flutter::ThreadHost>();
|
_threadHost = std::make_shared<flutter::ThreadHost>();
|
||||||
*_threadHost = MakeThreadHost(threadLabel, settings);
|
*_threadHost = MakeThreadHost(threadLabel, settings);
|
||||||
|
|
||||||
// Lambda captures by pointers to ObjC objects are fine here because the
|
__weak FlutterEngine* weakSelf = self;
|
||||||
// create call is synchronous.
|
|
||||||
flutter::Shell::CreateCallback<flutter::PlatformView> on_create_platform_view =
|
flutter::Shell::CreateCallback<flutter::PlatformView> on_create_platform_view =
|
||||||
[self](flutter::Shell& shell) {
|
[weakSelf](flutter::Shell& shell) {
|
||||||
[self recreatePlatformViewController];
|
FlutterEngine* strongSelf = weakSelf;
|
||||||
self->_platformViewsController->SetTaskRunner(
|
if (!strongSelf) {
|
||||||
|
return std::unique_ptr<flutter::PlatformViewIOS>();
|
||||||
|
}
|
||||||
|
[strongSelf recreatePlatformViewController];
|
||||||
|
strongSelf->_platformViewsController->SetTaskRunner(
|
||||||
shell.GetTaskRunners().GetPlatformTaskRunner());
|
shell.GetTaskRunners().GetPlatformTaskRunner());
|
||||||
return std::make_unique<flutter::PlatformViewIOS>(
|
return std::make_unique<flutter::PlatformViewIOS>(
|
||||||
shell, self->_renderingApi, self->_platformViewsController, shell.GetTaskRunners(),
|
shell, strongSelf->_renderingApi, strongSelf->_platformViewsController,
|
||||||
shell.GetConcurrentWorkerTaskRunner(), shell.GetIsGpuDisabledSyncSwitch());
|
shell.GetTaskRunners(), shell.GetConcurrentWorkerTaskRunner(),
|
||||||
|
shell.GetIsGpuDisabledSyncSwitch());
|
||||||
};
|
};
|
||||||
|
|
||||||
flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer =
|
flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer =
|
||||||
@ -988,7 +922,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
if (_shell) {
|
if (_shell) {
|
||||||
_shell->NotifyLowMemoryWarning();
|
_shell->NotifyLowMemoryWarning();
|
||||||
}
|
}
|
||||||
[_systemChannel sendMessage:@{@"type" : @"memoryPressure"}];
|
[self.systemChannel sendMessage:@{@"type" : @"memoryPressure"}];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Text input delegate
|
#pragma mark - Text input delegate
|
||||||
@ -996,23 +930,23 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
||||||
updateEditingClient:(int)client
|
updateEditingClient:(int)client
|
||||||
withState:(NSDictionary*)state {
|
withState:(NSDictionary*)state {
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingState"
|
[self.textInputChannel invokeMethod:@"TextInputClient.updateEditingState"
|
||||||
arguments:@[ @(client), state ]];
|
arguments:@[ @(client), state ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
||||||
updateEditingClient:(int)client
|
updateEditingClient:(int)client
|
||||||
withState:(NSDictionary*)state
|
withState:(NSDictionary*)state
|
||||||
withTag:(NSString*)tag {
|
withTag:(NSString*)tag {
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingStateWithTag"
|
[self.textInputChannel invokeMethod:@"TextInputClient.updateEditingStateWithTag"
|
||||||
arguments:@[ @(client), @{tag : state} ]];
|
arguments:@[ @(client), @{tag : state} ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
||||||
updateEditingClient:(int)client
|
updateEditingClient:(int)client
|
||||||
withDelta:(NSDictionary*)delta {
|
withDelta:(NSDictionary*)delta {
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingStateWithDeltas"
|
[self.textInputChannel invokeMethod:@"TextInputClient.updateEditingStateWithDeltas"
|
||||||
arguments:@[ @(client), delta ]];
|
arguments:@[ @(client), delta ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
||||||
@ -1031,8 +965,8 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
stateString = @"FloatingCursorDragState.end";
|
stateString = @"FloatingCursorDragState.end";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.updateFloatingCursor"
|
[self.textInputChannel invokeMethod:@"TextInputClient.updateFloatingCursor"
|
||||||
arguments:@[ @(client), stateString, position ]];
|
arguments:@[ @(client), stateString, position ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
||||||
@ -1078,22 +1012,22 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
actionString = @"TextInputAction.newline";
|
actionString = @"TextInputAction.newline";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.performAction"
|
[self.textInputChannel invokeMethod:@"TextInputClient.performAction"
|
||||||
arguments:@[ @(client), actionString ]];
|
arguments:@[ @(client), actionString ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
||||||
showAutocorrectionPromptRectForStart:(NSUInteger)start
|
showAutocorrectionPromptRectForStart:(NSUInteger)start
|
||||||
end:(NSUInteger)end
|
end:(NSUInteger)end
|
||||||
withClient:(int)client {
|
withClient:(int)client {
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.showAutocorrectionPromptRect"
|
[self.textInputChannel invokeMethod:@"TextInputClient.showAutocorrectionPromptRect"
|
||||||
arguments:@[ @(client), @(start), @(end) ]];
|
arguments:@[ @(client), @(start), @(end) ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
||||||
willDismissEditMenuWithTextInputClient:(int)client {
|
willDismissEditMenuWithTextInputClient:(int)client {
|
||||||
[_platformChannel.get() invokeMethod:@"ContextMenu.onDismissSystemContextMenu"
|
[self.platformChannel invokeMethod:@"ContextMenu.onDismissSystemContextMenu"
|
||||||
arguments:@[ @(client) ]];
|
arguments:@[ @(client) ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - FlutterViewEngineDelegate
|
#pragma mark - FlutterViewEngineDelegate
|
||||||
@ -1102,7 +1036,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
||||||
// the framework has finished transitioning to the Scribble channel.
|
// the framework has finished transitioning to the Scribble channel.
|
||||||
// https://github.com/flutter/flutter/pull/115296
|
// https://github.com/flutter/flutter/pull/115296
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.showToolbar" arguments:@[ @(client) ]];
|
[self.textInputChannel invokeMethod:@"TextInputClient.showToolbar" arguments:@[ @(client) ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin
|
- (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin
|
||||||
@ -1112,7 +1046,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
||||||
// the framework has finished transitioning to the Scribble channel.
|
// the framework has finished transitioning to the Scribble channel.
|
||||||
// https://github.com/flutter/flutter/pull/115296
|
// https://github.com/flutter/flutter/pull/115296
|
||||||
[_textInputChannel.get()
|
[self.textInputChannel
|
||||||
invokeMethod:@"TextInputClient.focusElement"
|
invokeMethod:@"TextInputClient.focusElement"
|
||||||
arguments:@[ elementIdentifier, @(referencePoint.x), @(referencePoint.y) ]
|
arguments:@[ elementIdentifier, @(referencePoint.x), @(referencePoint.y) ]
|
||||||
result:callback];
|
result:callback];
|
||||||
@ -1124,7 +1058,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
||||||
// the framework has finished transitioning to the Scribble channel.
|
// the framework has finished transitioning to the Scribble channel.
|
||||||
// https://github.com/flutter/flutter/pull/115296
|
// https://github.com/flutter/flutter/pull/115296
|
||||||
[_textInputChannel.get()
|
[self.textInputChannel
|
||||||
invokeMethod:@"TextInputClient.requestElementsInRect"
|
invokeMethod:@"TextInputClient.requestElementsInRect"
|
||||||
arguments:@[ @(rect.origin.x), @(rect.origin.y), @(rect.size.width), @(rect.size.height) ]
|
arguments:@[ @(rect.origin.x), @(rect.origin.y), @(rect.size.width), @(rect.size.height) ]
|
||||||
result:callback];
|
result:callback];
|
||||||
@ -1134,15 +1068,14 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
||||||
// the framework has finished transitioning to the Scribble channel.
|
// the framework has finished transitioning to the Scribble channel.
|
||||||
// https://github.com/flutter/flutter/pull/115296
|
// https://github.com/flutter/flutter/pull/115296
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.scribbleInteractionBegan" arguments:nil];
|
[self.textInputChannel invokeMethod:@"TextInputClient.scribbleInteractionBegan" arguments:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputViewScribbleInteractionFinished:(FlutterTextInputView*)textInputView {
|
- (void)flutterTextInputViewScribbleInteractionFinished:(FlutterTextInputView*)textInputView {
|
||||||
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
||||||
// the framework has finished transitioning to the Scribble channel.
|
// the framework has finished transitioning to the Scribble channel.
|
||||||
// https://github.com/flutter/flutter/pull/115296
|
// https://github.com/flutter/flutter/pull/115296
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.scribbleInteractionFinished"
|
[self.textInputChannel invokeMethod:@"TextInputClient.scribbleInteractionFinished" arguments:nil];
|
||||||
arguments:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
||||||
@ -1151,8 +1084,8 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
||||||
// the framework has finished transitioning to the Scribble channel.
|
// the framework has finished transitioning to the Scribble channel.
|
||||||
// https://github.com/flutter/flutter/pull/115296
|
// https://github.com/flutter/flutter/pull/115296
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.insertTextPlaceholder"
|
[self.textInputChannel invokeMethod:@"TextInputClient.insertTextPlaceholder"
|
||||||
arguments:@[ @(client), @(size.width), @(size.height) ]];
|
arguments:@[ @(client), @(size.width), @(size.height) ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
||||||
@ -1160,8 +1093,8 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
// TODO(justinmc): Switch from the TextInputClient to Scribble channel when
|
||||||
// the framework has finished transitioning to the Scribble channel.
|
// the framework has finished transitioning to the Scribble channel.
|
||||||
// https://github.com/flutter/flutter/pull/115296
|
// https://github.com/flutter/flutter/pull/115296
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.removeTextPlaceholder"
|
[self.textInputChannel invokeMethod:@"TextInputClient.removeTextPlaceholder"
|
||||||
arguments:@[ @(client) ]];
|
arguments:@[ @(client) ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
|
||||||
@ -1169,8 +1102,8 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
// When flutter text input view resign first responder, send a message to
|
// When flutter text input view resign first responder, send a message to
|
||||||
// framework to ensure the focus state is correct. This is useful when close
|
// framework to ensure the focus state is correct. This is useful when close
|
||||||
// keyboard from platform side.
|
// keyboard from platform side.
|
||||||
[_textInputChannel.get() invokeMethod:@"TextInputClient.onConnectionClosed"
|
[self.textInputChannel invokeMethod:@"TextInputClient.onConnectionClosed"
|
||||||
arguments:@[ @(client) ]];
|
arguments:@[ @(client) ]];
|
||||||
|
|
||||||
// Platform view's first responder detection logic:
|
// Platform view's first responder detection logic:
|
||||||
//
|
//
|
||||||
@ -1197,7 +1130,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[_platformViewsChannel.get() invokeMethod:@"viewFocused" arguments:@(platform_view_id)];
|
[self.platformViewsChannel invokeMethod:@"viewFocused" arguments:@(platform_view_id)];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1205,7 +1138,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
|
|
||||||
- (void)handleUndoWithDirection:(FlutterUndoRedoDirection)direction {
|
- (void)handleUndoWithDirection:(FlutterUndoRedoDirection)direction {
|
||||||
NSString* action = (direction == FlutterUndoRedoDirectionUndo) ? @"undo" : @"redo";
|
NSString* action = (direction == FlutterUndoRedoDirectionUndo) ? @"undo" : @"redo";
|
||||||
[_undoManagerChannel.get() invokeMethod:@"UndoManagerClient.handleUndo" arguments:@[ action ]];
|
[self.undoManagerChannel invokeMethod:@"UndoManagerClient.handleUndo" arguments:@[ action ]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIView<UITextInput>*)activeTextInputView {
|
- (UIView<UITextInput>*)activeTextInputView {
|
||||||
@ -1244,8 +1177,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
// Discard the previous messenger and keep the new one.
|
// Discard the previous messenger and keep the new one.
|
||||||
if (binaryMessenger != _binaryMessenger) {
|
if (binaryMessenger != _binaryMessenger) {
|
||||||
_binaryMessenger.parent = nil;
|
_binaryMessenger.parent = nil;
|
||||||
[_binaryMessenger release];
|
_binaryMessenger = binaryMessenger;
|
||||||
_binaryMessenger = [binaryMessenger retain];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1317,7 +1249,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
#pragma mark - FlutterTextureRegistry
|
#pragma mark - FlutterTextureRegistry
|
||||||
|
|
||||||
- (int64_t)registerTexture:(NSObject<FlutterTexture>*)texture {
|
- (int64_t)registerTexture:(NSObject<FlutterTexture>*)texture {
|
||||||
int64_t textureId = _nextTextureId++;
|
int64_t textureId = self.nextTextureId++;
|
||||||
self.iosPlatformView->RegisterExternalTexture(textureId, texture);
|
self.iosPlatformView->RegisterExternalTexture(textureId, texture);
|
||||||
return textureId;
|
return textureId;
|
||||||
}
|
}
|
||||||
@ -1350,7 +1282,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
FlutterEngineRegistrar* result = [[FlutterEngineRegistrar alloc] initWithPlugin:pluginKey
|
FlutterEngineRegistrar* result = [[FlutterEngineRegistrar alloc] initWithPlugin:pluginKey
|
||||||
flutterEngine:self];
|
flutterEngine:self];
|
||||||
self.registrars[pluginKey] = result;
|
self.registrars[pluginKey] = result;
|
||||||
return [result autorelease];
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)hasPlugin:(NSString*)pluginKey {
|
- (BOOL)hasPlugin:(NSString*)pluginKey {
|
||||||
@ -1406,10 +1338,10 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
|
|
||||||
- (void)onLocaleUpdated:(NSNotification*)notification {
|
- (void)onLocaleUpdated:(NSNotification*)notification {
|
||||||
// Get and pass the user's preferred locale list to dart:ui.
|
// Get and pass the user's preferred locale list to dart:ui.
|
||||||
NSMutableArray<NSString*>* localeData = [[[NSMutableArray alloc] init] autorelease];
|
NSMutableArray<NSString*>* localeData = [[NSMutableArray alloc] init];
|
||||||
NSArray<NSString*>* preferredLocales = [NSLocale preferredLanguages];
|
NSArray<NSString*>* preferredLocales = [NSLocale preferredLanguages];
|
||||||
for (NSString* localeID in preferredLocales) {
|
for (NSString* localeID in preferredLocales) {
|
||||||
NSLocale* locale = [[[NSLocale alloc] initWithLocaleIdentifier:localeID] autorelease];
|
NSLocale* locale = [[NSLocale alloc] initWithLocaleIdentifier:localeID];
|
||||||
NSString* languageCode = [locale objectForKey:NSLocaleLanguageCode];
|
NSString* languageCode = [locale objectForKey:NSLocaleLanguageCode];
|
||||||
NSString* countryCode = [locale objectForKey:NSLocaleCountryCode];
|
NSString* countryCode = [locale objectForKey:NSLocaleCountryCode];
|
||||||
NSString* scriptCode = [locale objectForKey:NSLocaleScriptCode];
|
NSString* scriptCode = [locale objectForKey:NSLocaleScriptCode];
|
||||||
@ -1446,13 +1378,13 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
initialRoute:(/*nullable*/ NSString*)initialRoute
|
initialRoute:(/*nullable*/ NSString*)initialRoute
|
||||||
entrypointArgs:(/*nullable*/ NSArray<NSString*>*)entrypointArgs {
|
entrypointArgs:(/*nullable*/ NSArray<NSString*>*)entrypointArgs {
|
||||||
NSAssert(_shell, @"Spawning from an engine without a shell (possibly not run).");
|
NSAssert(_shell, @"Spawning from an engine without a shell (possibly not run).");
|
||||||
FlutterEngine* result = [[FlutterEngine alloc] initWithName:_labelPrefix
|
FlutterEngine* result = [[FlutterEngine alloc] initWithName:self.labelPrefix
|
||||||
project:_dartProject.get()
|
project:self.dartProject
|
||||||
allowHeadlessExecution:_allowHeadlessExecution];
|
allowHeadlessExecution:self.allowHeadlessExecution];
|
||||||
flutter::RunConfiguration configuration =
|
flutter::RunConfiguration configuration =
|
||||||
[_dartProject.get() runConfigurationForEntrypoint:entrypoint
|
[self.dartProject runConfigurationForEntrypoint:entrypoint
|
||||||
libraryOrNil:libraryURI
|
libraryOrNil:libraryURI
|
||||||
entrypointArgs:entrypointArgs];
|
entrypointArgs:entrypointArgs];
|
||||||
|
|
||||||
fml::WeakPtr<flutter::PlatformView> platform_view = _shell->GetPlatformView();
|
fml::WeakPtr<flutter::PlatformView> platform_view = _shell->GetPlatformView();
|
||||||
FML_DCHECK(platform_view);
|
FML_DCHECK(platform_view);
|
||||||
@ -1489,7 +1421,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
result->_profiler_metrics = _profiler_metrics;
|
result->_profiler_metrics = _profiler_metrics;
|
||||||
result->_isGpuDisabled = _isGpuDisabled;
|
result->_isGpuDisabled = _isGpuDisabled;
|
||||||
[result setUpShell:std::move(shell) withVMServicePublication:NO];
|
[result setUpShell:std::move(shell) withVMServicePublication:NO];
|
||||||
return [result autorelease];
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (const flutter::ThreadHost&)threadHost {
|
- (const flutter::ThreadHost&)threadHost {
|
||||||
@ -1497,7 +1429,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (FlutterDartProject*)project {
|
- (FlutterDartProject*)project {
|
||||||
return _dartProject.get();
|
return self.dartProject;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isUsingImpeller {
|
- (BOOL)isUsingImpeller {
|
||||||
@ -1518,11 +1450,6 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
|
||||||
[_pluginKey release];
|
|
||||||
[super dealloc];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSObject<FlutterBinaryMessenger>*)messenger {
|
- (NSObject<FlutterBinaryMessenger>*)messenger {
|
||||||
return _flutterEngine.binaryMessenger;
|
return _flutterEngine.binaryMessenger;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
@interface FlutterPlatformPlugin : NSObject
|
@interface FlutterPlatformPlugin : NSObject
|
||||||
- (instancetype)init NS_UNAVAILABLE;
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
+ (instancetype)new NS_UNAVAILABLE;
|
+ (instancetype)new NS_UNAVAILABLE;
|
||||||
- (instancetype)initWithEngine:(fml::WeakNSObject<FlutterEngine>)engine NS_DESIGNATED_INITIALIZER;
|
- (instancetype)initWithEngine:(FlutterEngine*)engine NS_DESIGNATED_INITIALIZER;
|
||||||
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result;
|
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -82,7 +82,7 @@ static void SetStatusBarStyleForSharedApplication(UIStatusBarStyle style) {
|
|||||||
|
|
||||||
@implementation FlutterPlatformPlugin
|
@implementation FlutterPlatformPlugin
|
||||||
|
|
||||||
- (instancetype)initWithEngine:(fml::WeakNSObject<FlutterEngine>)engine {
|
- (instancetype)initWithEngine:(FlutterEngine*)engine {
|
||||||
FML_DCHECK(engine) << "engine must be set";
|
FML_DCHECK(engine) << "engine must be set";
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
|
@ -37,15 +37,12 @@ FLUTTER_ASSERT_ARC
|
|||||||
OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
|
OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
|
||||||
|
|
||||||
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
[engine runWithEntrypoint:nil];
|
[engine runWithEntrypoint:nil];
|
||||||
|
|
||||||
XCTestExpectation* invokeExpectation =
|
XCTestExpectation* invokeExpectation =
|
||||||
[self expectationWithDescription:@"Web search launched with escaped search term"];
|
[self expectationWithDescription:@"Web search launched with escaped search term"];
|
||||||
|
|
||||||
FlutterPlatformPlugin* plugin =
|
FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine];
|
||||||
[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
|
|
||||||
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
||||||
|
|
||||||
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke"
|
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke"
|
||||||
@ -71,15 +68,12 @@ FLUTTER_ASSERT_ARC
|
|||||||
OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
|
OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
|
||||||
|
|
||||||
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
[engine runWithEntrypoint:nil];
|
[engine runWithEntrypoint:nil];
|
||||||
|
|
||||||
XCTestExpectation* invokeExpectation =
|
XCTestExpectation* invokeExpectation =
|
||||||
[self expectationWithDescription:@"Web search launched with non escaped search term"];
|
[self expectationWithDescription:@"Web search launched with non escaped search term"];
|
||||||
|
|
||||||
FlutterPlatformPlugin* plugin =
|
FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine];
|
||||||
[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
|
|
||||||
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
||||||
|
|
||||||
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke"
|
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke"
|
||||||
@ -103,8 +97,6 @@ FLUTTER_ASSERT_ARC
|
|||||||
- (void)testLookUpCallInitiated {
|
- (void)testLookUpCallInitiated {
|
||||||
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
||||||
[engine runWithEntrypoint:nil];
|
[engine runWithEntrypoint:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
|
|
||||||
XCTestExpectation* presentExpectation =
|
XCTestExpectation* presentExpectation =
|
||||||
[self expectationWithDescription:@"Look Up view controller presented"];
|
[self expectationWithDescription:@"Look Up view controller presented"];
|
||||||
@ -114,8 +106,7 @@ FLUTTER_ASSERT_ARC
|
|||||||
bundle:nil];
|
bundle:nil];
|
||||||
FlutterViewController* mockEngineViewController = OCMPartialMock(engineViewController);
|
FlutterViewController* mockEngineViewController = OCMPartialMock(engineViewController);
|
||||||
|
|
||||||
FlutterPlatformPlugin* plugin =
|
FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine];
|
||||||
[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
|
|
||||||
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
||||||
|
|
||||||
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"LookUp.invoke"
|
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"LookUp.invoke"
|
||||||
@ -134,8 +125,6 @@ FLUTTER_ASSERT_ARC
|
|||||||
- (void)testShareScreenInvoked {
|
- (void)testShareScreenInvoked {
|
||||||
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
||||||
[engine runWithEntrypoint:nil];
|
[engine runWithEntrypoint:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
|
|
||||||
XCTestExpectation* presentExpectation =
|
XCTestExpectation* presentExpectation =
|
||||||
[self expectationWithDescription:@"Share view controller presented"];
|
[self expectationWithDescription:@"Share view controller presented"];
|
||||||
@ -149,8 +138,7 @@ FLUTTER_ASSERT_ARC
|
|||||||
animated:YES
|
animated:YES
|
||||||
completion:nil]);
|
completion:nil]);
|
||||||
|
|
||||||
FlutterPlatformPlugin* plugin =
|
FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine];
|
||||||
[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
|
|
||||||
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
||||||
|
|
||||||
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke"
|
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke"
|
||||||
@ -169,8 +157,6 @@ FLUTTER_ASSERT_ARC
|
|||||||
- (void)testShareScreenInvokedOnIPad {
|
- (void)testShareScreenInvokedOnIPad {
|
||||||
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
||||||
[engine runWithEntrypoint:nil];
|
[engine runWithEntrypoint:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
|
|
||||||
XCTestExpectation* presentExpectation =
|
XCTestExpectation* presentExpectation =
|
||||||
[self expectationWithDescription:@"Share view controller presented on iPad"];
|
[self expectationWithDescription:@"Share view controller presented on iPad"];
|
||||||
@ -187,8 +173,7 @@ FLUTTER_ASSERT_ARC
|
|||||||
id mockTraitCollection = OCMClassMock([UITraitCollection class]);
|
id mockTraitCollection = OCMClassMock([UITraitCollection class]);
|
||||||
OCMStub([mockTraitCollection userInterfaceIdiom]).andReturn(UIUserInterfaceIdiomPad);
|
OCMStub([mockTraitCollection userInterfaceIdiom]).andReturn(UIUserInterfaceIdiomPad);
|
||||||
|
|
||||||
FlutterPlatformPlugin* plugin =
|
FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine];
|
||||||
[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
|
|
||||||
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
||||||
|
|
||||||
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke"
|
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke"
|
||||||
@ -207,10 +192,7 @@ FLUTTER_ASSERT_ARC
|
|||||||
- (void)testClipboardHasCorrectStrings {
|
- (void)testClipboardHasCorrectStrings {
|
||||||
[UIPasteboard generalPasteboard].string = nil;
|
[UIPasteboard generalPasteboard].string = nil;
|
||||||
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine];
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
FlutterPlatformPlugin* plugin =
|
|
||||||
[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
|
|
||||||
|
|
||||||
XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setString"];
|
XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setString"];
|
||||||
FlutterResult resultSet = ^(id result) {
|
FlutterResult resultSet = ^(id result) {
|
||||||
@ -246,10 +228,7 @@ FLUTTER_ASSERT_ARC
|
|||||||
- (void)testClipboardSetDataToNullDoNotCrash {
|
- (void)testClipboardSetDataToNullDoNotCrash {
|
||||||
[UIPasteboard generalPasteboard].string = nil;
|
[UIPasteboard generalPasteboard].string = nil;
|
||||||
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine];
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
FlutterPlatformPlugin* plugin =
|
|
||||||
[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
|
|
||||||
|
|
||||||
XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setData"];
|
XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setData"];
|
||||||
FlutterResult resultSet = ^(id result) {
|
FlutterResult resultSet = ^(id result) {
|
||||||
@ -280,10 +259,7 @@ FLUTTER_ASSERT_ARC
|
|||||||
[[UINavigationController alloc] initWithRootViewController:flutterViewController];
|
[[UINavigationController alloc] initWithRootViewController:flutterViewController];
|
||||||
UITabBarController* tabBarController = [[UITabBarController alloc] init];
|
UITabBarController* tabBarController = [[UITabBarController alloc] init];
|
||||||
tabBarController.viewControllers = @[ navigationController ];
|
tabBarController.viewControllers = @[ navigationController ];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine];
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
FlutterPlatformPlugin* plugin =
|
|
||||||
[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
|
|
||||||
|
|
||||||
id navigationControllerMock = OCMPartialMock(navigationController);
|
id navigationControllerMock = OCMPartialMock(navigationController);
|
||||||
OCMStub([navigationControllerMock popViewControllerAnimated:YES]);
|
OCMStub([navigationControllerMock popViewControllerAnimated:YES]);
|
||||||
@ -303,12 +279,9 @@ FLUTTER_ASSERT_ARC
|
|||||||
|
|
||||||
- (void)testWhetherDeviceHasLiveTextInputInvokeCorrectly {
|
- (void)testWhetherDeviceHasLiveTextInputInvokeCorrectly {
|
||||||
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
XCTestExpectation* invokeExpectation =
|
XCTestExpectation* invokeExpectation =
|
||||||
[self expectationWithDescription:@"isLiveTextInputAvailableInvoke"];
|
[self expectationWithDescription:@"isLiveTextInputAvailableInvoke"];
|
||||||
FlutterPlatformPlugin* plugin =
|
FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine];
|
||||||
[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
|
|
||||||
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
||||||
FlutterMethodCall* methodCall =
|
FlutterMethodCall* methodCall =
|
||||||
[FlutterMethodCall methodCallWithMethodName:@"LiveText.isLiveTextInputAvailable"
|
[FlutterMethodCall methodCallWithMethodName:@"LiveText.isLiveTextInputAvailable"
|
||||||
@ -331,8 +304,6 @@ FLUTTER_ASSERT_ARC
|
|||||||
[engine runWithEntrypoint:nil];
|
[engine runWithEntrypoint:nil];
|
||||||
FlutterViewController* flutterViewController =
|
FlutterViewController* flutterViewController =
|
||||||
[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
|
[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
|
XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
|
||||||
|
|
||||||
// Update to hidden.
|
// Update to hidden.
|
||||||
@ -371,8 +342,6 @@ FLUTTER_ASSERT_ARC
|
|||||||
[engine runWithEntrypoint:nil];
|
[engine runWithEntrypoint:nil];
|
||||||
FlutterViewController* flutterViewController =
|
FlutterViewController* flutterViewController =
|
||||||
[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
|
[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
|
XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
|
||||||
|
|
||||||
// Update to hidden.
|
// Update to hidden.
|
||||||
@ -420,8 +389,6 @@ FLUTTER_ASSERT_ARC
|
|||||||
[engine runWithEntrypoint:nil];
|
[engine runWithEntrypoint:nil];
|
||||||
FlutterViewController* flutterViewController =
|
FlutterViewController* flutterViewController =
|
||||||
[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
|
[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
|
|
||||||
// Update to hidden.
|
// Update to hidden.
|
||||||
FlutterPlatformPlugin* plugin = [engine platformPlugin];
|
FlutterPlatformPlugin* plugin = [engine platformPlugin];
|
||||||
@ -471,8 +438,6 @@ FLUTTER_ASSERT_ARC
|
|||||||
[engine runWithEntrypoint:nil];
|
[engine runWithEntrypoint:nil];
|
||||||
FlutterViewController* flutterViewController =
|
FlutterViewController* flutterViewController =
|
||||||
[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
|
[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
|
||||||
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
|
|
||||||
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
|
|
||||||
XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
|
XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
|
||||||
|
|
||||||
FlutterPlatformPlugin* plugin = [engine platformPlugin];
|
FlutterPlatformPlugin* plugin = [engine platformPlugin];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user