From b9f469217850cd28251c17e8b2ef00f0602b2dd1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 2 Oct 2018 16:28:24 -0700 Subject: [PATCH 01/31] Initial implementation for embedding refactor --- ci/licenses_golden/licenses_flutter | 6 +- shell/platform/darwin/ios/BUILD.gn | 5 +- .../darwin/ios/framework/Headers/Flutter.h | 1 + .../ios/framework/Headers/FlutterEngine.h | 64 +++ .../Headers/FlutterHeadlessDartRunner.h | 7 +- .../framework/Headers/FlutterViewController.h | 33 +- .../framework/Source/FlutterDartProject.mm | 19 +- .../Source/FlutterDartProject_Internal.h | 3 + .../ios/framework/Source/FlutterEngine.mm | 489 ++++++++++++++++++ .../framework/Source/FlutterEngine_Internal.h | 43 ++ .../Source/FlutterHeadlessDartRunner.mm | 113 +--- .../framework/Source/FlutterPlatformPlugin.h | 2 +- .../framework/Source/FlutterPlatformPlugin.mm | 7 +- .../ios/framework/Source/FlutterView.mm | 8 +- .../framework/Source/FlutterViewController.mm | 412 +++------------ .../Source/FlutterViewController_Internal.h | 7 +- .../darwin/ios/headless_platform_view_ios.h | 38 -- .../darwin/ios/headless_platform_view_ios.mm | 20 - shell/platform/darwin/ios/platform_view_ios.h | 19 +- .../platform/darwin/ios/platform_view_ios.mm | 51 +- 20 files changed, 797 insertions(+), 550 deletions(-) create mode 100644 shell/platform/darwin/ios/framework/Headers/FlutterEngine.h create mode 100644 shell/platform/darwin/ios/framework/Source/FlutterEngine.mm create mode 100644 shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h delete mode 100644 shell/platform/darwin/ios/headless_platform_view_ios.h delete mode 100644 shell/platform/darwin/ios/headless_platform_view_ios.mm diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 1fb930253571f..516cd68e4b25f 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -203,7 +203,6 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/JSONUtil. FILE: ../../../flutter/shell/platform/darwin/ios/framework/Flutter.podspec FILE: ../../../flutter/shell/platform/darwin/ios/framework/Info.plist FILE: ../../../flutter/shell/platform/darwin/ios/framework/module.modulemap -FILE: ../../../flutter/shell/platform/darwin/ios/headless_platform_view_ios.mm FILE: ../../../flutter/shell/platform/embedder/assets/EmbedderInfo.plist FILE: ../../../flutter/shell/platform/embedder/assets/embedder.modulemap FILE: ../../../flutter/shell/platform/embedder/fixtures/simple_main.dart @@ -270,7 +269,6 @@ FILE: ../../../flutter/shell/common/thread_host.cc FILE: ../../../flutter/shell/common/thread_host.h FILE: ../../../flutter/shell/platform/darwin/common/command_line.h FILE: ../../../flutter/shell/platform/darwin/common/command_line.mm -FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h FILE: ../../../flutter/shell/platform/embedder/embedder.h FILE: ../../../flutter/shell/platform/embedder/embedder_engine.cc FILE: ../../../flutter/shell/platform/embedder/embedder_engine.h @@ -499,7 +497,6 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterCallbac FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.mm -FILE: ../../../flutter/shell/platform/darwin/ios/headless_platform_view_ios.h ---------------------------------------------------------------------------------------------------- Copyright 2018 The Chromium Authors. All rights reserved. @@ -574,7 +571,10 @@ FILE: ../../../flutter/shell/platform/android/android_shell_holder.cc FILE: ../../../flutter/shell/platform/android/android_shell_holder.h FILE: ../../../flutter/shell/platform/android/platform_message_response_android.cc FILE: ../../../flutter/shell/platform/android/platform_message_response_android.h +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate_Internal.h +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_internal.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.mm FILE: ../../../flutter/shell/platform/embedder/embedder_surface.cc diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index 3de4e258a7d75..ce0b98129db5c 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -26,6 +26,7 @@ _flutter_framework_headers = [ "framework/Headers/FlutterChannels.h", "framework/Headers/FlutterCodecs.h", "framework/Headers/FlutterDartProject.h", + "framework/Headers/FlutterEngine.h", "framework/Headers/FlutterHeadlessDartRunner.h", "framework/Headers/FlutterMacros.h", "framework/Headers/FlutterNavigationController.h", @@ -51,6 +52,8 @@ shared_library("create_flutter_framework_dylib") { "framework/Source/FlutterCodecs.mm", "framework/Source/FlutterDartProject.mm", "framework/Source/FlutterDartProject_Internal.h", + "framework/Source/FlutterEngine.mm", + "framework/Source/FlutterEngine_Internal.h", "framework/Source/FlutterHeadlessDartRunner.mm", "framework/Source/FlutterNavigationController.mm", "framework/Source/FlutterPlatformPlugin.h", @@ -77,8 +80,6 @@ shared_library("create_flutter_framework_dylib") { "framework/Source/platform_message_router.mm", "framework/Source/vsync_waiter_ios.h", "framework/Source/vsync_waiter_ios.mm", - "headless_platform_view_ios.h", - "headless_platform_view_ios.mm", "ios_external_texture_gl.h", "ios_external_texture_gl.mm", "ios_gl_context.h", diff --git a/shell/platform/darwin/ios/framework/Headers/Flutter.h b/shell/platform/darwin/ios/framework/Headers/Flutter.h index 49464e40dc06b..1e2f9d4d3ade0 100644 --- a/shell/platform/darwin/ios/framework/Headers/Flutter.h +++ b/shell/platform/darwin/ios/framework/Headers/Flutter.h @@ -47,6 +47,7 @@ #include "FlutterChannels.h" #include "FlutterCodecs.h" #include "FlutterDartProject.h" +#include "FlutterEngine.h" #include "FlutterHeadlessDartRunner.h" #include "FlutterMacros.h" #include "FlutterNavigationController.h" diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h new file mode 100644 index 0000000000000..40b85b62f013b --- /dev/null +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -0,0 +1,64 @@ +// Copyright 2018 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_FLUTTERENGINE_H_ +#define FLUTTER_FLUTTERENGINE_H_ + +#import +#import + +#include "FlutterBinaryMessenger.h" +#include "FlutterDartProject.h" +#include "FlutterMacros.h" +#include "FlutterPlugin.h" +#include "FlutterTexture.h" + +@class FlutterViewController; + +FLUTTER_EXPORT +@interface FlutterEngine + : NSObject +/** + Iniitalize this FlutterEngine with a FlutterDartProject. +*/ +- (instancetype)initWithName:(NSString*)labelPrefix + andProject:(FlutterDartProject*)projectOrNil NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + +- (void)run; + +/** + Runs a Dart function on an Isolate. + The first call will create a new Isolate. Subsequent calls will return + immediately. + + - Parameter entrypoint: The name of a top-level function from the same Dart + library that contains the app's main() function. +*/ +- (bool)runWithEntrypoint:(NSString*)entrypoint; + +/** + Runs a Dart function on an Isolate. + The first call will create a new Isolate. Subsequent calls will return + immediately. + + - Parameter entrypoint: The name of a top-level function from a Dart library. + - Parameter uri: The URI of the Dart library which contains entrypoint. +*/ +- (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri; + +- (void)setViewController:(FlutterViewController*)viewController; +- (FlutterViewController*)getViewController; + +- (FlutterMethodChannel*)localizationChannel; +- (FlutterMethodChannel*)navigationChannel; +- (FlutterMethodChannel*)platformChannel; +- (FlutterMethodChannel*)textInputChannel; +- (FlutterBasicMessageChannel*)lifecycleChannel; +- (FlutterBasicMessageChannel*)systemChannel; +- (FlutterBasicMessageChannel*)settingsChannel; + +@end + +#endif // FLUTTER_FLUTTERENGINE_H_ diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h b/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h index f6f37248364ed..f105a75db3535 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h @@ -9,6 +9,7 @@ #include "FlutterBinaryMessenger.h" #include "FlutterDartProject.h" +#include "FlutterEngine.h" #include "FlutterMacros.h" /** @@ -26,7 +27,7 @@ typedef void (^FlutterHeadlessDartRunnerCallback)(BOOL success); code e.g. in the background from a plugin. */ FLUTTER_EXPORT -@interface FlutterHeadlessDartRunner : NSObject +@interface FlutterHeadlessDartRunner : FlutterEngine /** Runs a Dart function on an Isolate that is not the main application's Isolate. @@ -36,7 +37,7 @@ FLUTTER_EXPORT - Parameter entrypoint: The name of a top-level function from the same Dart library that contains the app's main() function. */ -- (void)runWithEntrypoint:(NSString*)entrypoint; +- (bool)runWithEntrypoint:(NSString*)entrypoint; /** Runs a Dart function on an Isolate that is not the main application's Isolate. @@ -46,7 +47,7 @@ FLUTTER_EXPORT - Parameter entrypoint: The name of a top-level function from a Dart library. - Parameter uri: The URI of the Dart library which contains entrypoint. */ -- (void)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri; +- (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri; @end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index 2e8b02d05195f..20b45ba18e38a 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -10,13 +10,20 @@ #include "FlutterBinaryMessenger.h" #include "FlutterDartProject.h" +#include "FlutterEngine.h" #include "FlutterMacros.h" #include "FlutterPlugin.h" #include "FlutterTexture.h" +@class FlutterEngine; + FLUTTER_EXPORT @interface FlutterViewController - : UIViewController + : UIViewController + +- (instancetype)initWithEngine:(FlutterEngine*)engine + nibName:(NSString*)nibNameOrNil + bundle:(NSBundle*)nibBundleOrNil NS_DESIGNATED_INITIALIZER; - (instancetype)initWithProject:(FlutterDartProject*)projectOrNil nibName:(NSString*)nibNameOrNil @@ -26,7 +33,8 @@ FLUTTER_EXPORT /** Returns the file name for the given asset. - The returned file name can be used to access the asset in the application's main bundle. + The returned file name can be used to access the asset in the application's + main bundle. - Parameter asset: The name of the asset. The name can be hierarchical. - Returns: the file name to be used for lookup in the main bundle. @@ -34,8 +42,10 @@ FLUTTER_EXPORT - (NSString*)lookupKeyForAsset:(NSString*)asset; /** - Returns the file name for the given asset which originates from the specified package. - The returned file name can be used to access the asset in the application's main bundle. + Returns the file name for the given asset which originates from the specified + package. + The returned file name can be used to access the asset in the application's + main bundle. - Parameters: - asset: The name of the asset. The name can be hierarchical. @@ -72,15 +82,20 @@ FLUTTER_EXPORT - (id)pluginRegistry; /** - Specifies the view to use as a splash screen. Flutter's rendering is asynchronous, so the first - frame rendered by the Flutter application might not immediately appear when the Flutter view is - initially placed in the view hierarchy. The splash screen view will be used as a replacement + Specifies the view to use as a splash screen. Flutter's rendering is + asynchronous, so the first + frame rendered by the Flutter application might not immediately appear when the + Flutter view is + initially placed in the view hierarchy. The splash screen view will be used as + a replacement until the first frame is rendered. - The view used should be appropriate for multiple sizes; an autoresizing mask to have a flexible + The view used should be appropriate for multiple sizes; an autoresizing mask to + have a flexible width and height will be applied automatically. - If not specified, uses a view generated from `UILaunchStoryboardName` from the main bundle's + If not specified, uses a view generated from `UILaunchStoryboardName` from the + main bundle's `Info.plist` file. */ @property(strong, nonatomic) UIView* splashScreenView; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm index 22d39950d93f1..24ad9d97ff7a4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm @@ -193,7 +193,24 @@ - (instancetype)initWithFlutterAssetsWithScriptSnapshot:(NSURL*)flutterAssetsURL } - (shell::RunConfiguration)runConfiguration { - return shell::RunConfiguration::InferFromSettings(_settings); + return [self runConfigurationForEntrypoint:nil]; +} + +- (shell::RunConfiguration)runConfigurationForEntrypoint:(NSString*)entrypointOrNil { + return [self runConfigurationForEntrypoint:entrypointOrNil libraryOrNil:nil]; +} + +- (shell::RunConfiguration)runConfigurationForEntrypoint:(NSString*)entrypointOrNil + libraryOrNil:(NSString*)dartLibraryOrNil { + shell::RunConfiguration config = shell::RunConfiguration::InferFromSettings(_settings); + if (dartLibraryOrNil && entrypointOrNil) { + config.SetEntrypointAndLibrary(std::string([entrypointOrNil UTF8String]), + std::string([dartLibraryOrNil UTF8String])); + + } else if (entrypointOrNil) { + config.SetEntrypoint(std::string([entrypointOrNil UTF8String])); + } + return config; } #pragma mark - Assets-related utilities diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h index 155f3c8ef4533..2972b5febe47d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h @@ -14,6 +14,9 @@ - (const blink::Settings&)settings; - (shell::RunConfiguration)runConfiguration; +- (shell::RunConfiguration)runConfigurationForEntrypoint:(NSString*)entrypointOrNil; +- (shell::RunConfiguration)runConfigurationForEntrypoint:(NSString*)entrypointOrNil + libraryOrNil:(NSString*)dartLibraryOrNil; + (NSString*)flutterAssetsName:(NSBundle*)bundle; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm new file mode 100644 index 0000000000000..baed0755e8d5c --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -0,0 +1,489 @@ +// Copyright 2018 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#define FML_USED_ON_EMBEDDER + +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h" + +#include + +#include "flutter/fml/message_loop.h" +#include "flutter/fml/platform/darwin/platform_version.h" +#include "flutter/shell/common/engine.h" +#include "flutter/shell/common/platform_view.h" +#include "flutter/shell/common/shell.h" +#include "flutter/shell/common/switches.h" +#include "flutter/shell/common/thread_host.h" +#include "flutter/shell/platform/darwin/common/command_line.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/flutter_touch_mapper.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" +#include "flutter/shell/platform/darwin/ios/platform_view_ios.h" + +static NSString* CreateShellLabel(NSString* label) { + static size_t shell_count = 1; + return [NSString stringWithFormat:@"%@.%zu", label, shell_count++]; +} + +@interface FlutterEngine () +@property(nonatomic, readonly) NSMutableDictionary* pluginPublications; +@end + +@interface FlutterEngineRegistrar : NSObject +- (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine*)flutterEngine; +@end + +@implementation FlutterEngine { + fml::scoped_nsobject _dartProject; + std::unique_ptr _shell; + NSString* _labelPrefix; + NSString* _dartEntrypoint; + NSString* _dartLibrary; + + // Channels + fml::scoped_nsobject _platformPlugin; + fml::scoped_nsobject _textInputPlugin; + fml::scoped_nsobject _localizationChannel; + fml::scoped_nsobject _navigationChannel; + fml::scoped_nsobject _platformChannel; + fml::scoped_nsobject _textInputChannel; + fml::scoped_nsobject _lifecycleChannel; + fml::scoped_nsobject _systemChannel; + fml::scoped_nsobject _settingsChannel; + + int64_t _nextTextureId; +} + +- (instancetype)initWithName:(NSString*)labelPrefix andProject:(FlutterDartProject*)projectOrNil { + self = [super init]; + NSAssert(self, @"Super init cannot be nil"); + NSAssert(labelPrefix, @"labelPrefix is required"); + _labelPrefix = labelPrefix; + if (projectOrNil == nil) + _dartProject.reset([[FlutterDartProject alloc] init]); + else + _dartProject.reset([projectOrNil retain]); + + _pluginPublications = [NSMutableDictionary new]; + + [self setupChannels]; + + return self; +} + +- (void)dealloc { + [_pluginPublications release]; + [super dealloc]; +} + +- (shell::Shell&)shell { + FML_DCHECK(_shell); + return *_shell; +} + +- (void)updateViewportMetrics:(blink::ViewportMetrics)viewportMetrics { + self.shell.GetTaskRunners().GetUITaskRunner()->PostTask( + [engine = self.shell.GetEngine(), metrics = viewportMetrics]() { + if (engine) { + engine->SetViewportMetrics(std::move(metrics)); + } + }); +} + +- (void)dispatchPointerDataPacket:(std::unique_ptr)packet { + self.shell.GetTaskRunners().GetUITaskRunner()->PostTask( + fml::MakeCopyable([engine = self.shell.GetEngine(), packet = std::move(packet)] { + if (engine) { + engine->DispatchPointerDataPacket(*packet); + } + })); +} + +- (fml::WeakPtr)platformView { + return _shell->GetPlatformView(); +} + +- (shell::PlatformViewIOS*)iosPlatformView { + return static_cast(_shell->GetPlatformView().get()); +} + +- (fml::RefPtr)platformTaskRunner { + return _shell->GetTaskRunners().GetPlatformTaskRunner(); +} + +- (void)setViewController:(FlutterViewController*)viewController { + FML_DCHECK(self.iosPlatformView); + self.iosPlatformView->SetOwnerViewController(viewController); +} + +- (FlutterViewController*)getViewController { + if (!self.iosPlatformView) { + return nil; + } + return self.iosPlatformView->GetOwnerViewController(); +} + +- (FlutterPlatformPlugin*)platformPlugin { + return _platformPlugin.get(); +} +- (FlutterTextInputPlugin*)textInputPlugin { + return _textInputPlugin.get(); +} +- (FlutterMethodChannel*)localizationChannel { + return _localizationChannel.get(); +} +- (FlutterMethodChannel*)navigationChannel { + return _navigationChannel.get(); +} +- (FlutterMethodChannel*)platformChannel { + return _platformChannel.get(); +} +- (FlutterMethodChannel*)textInputChannel { + return _textInputChannel.get(); +} +- (FlutterBasicMessageChannel*)lifecycleChannel { + return _lifecycleChannel.get(); +} +- (FlutterBasicMessageChannel*)systemChannel { + return _systemChannel.get(); +} +- (FlutterBasicMessageChannel*)settingsChannel { + return _settingsChannel.get(); +} + +- (void)setupChannels { + _localizationChannel.reset([[FlutterMethodChannel alloc] + initWithName:@"flutter/localization" + binaryMessenger:self + codec:[FlutterJSONMethodCodec sharedInstance]]); + + _navigationChannel.reset([[FlutterMethodChannel alloc] + initWithName:@"flutter/navigation" + binaryMessenger:self + codec:[FlutterJSONMethodCodec sharedInstance]]); + + _platformChannel.reset([[FlutterMethodChannel alloc] + initWithName:@"flutter/platform" + binaryMessenger:self + codec:[FlutterJSONMethodCodec sharedInstance]]); + + _textInputChannel.reset([[FlutterMethodChannel alloc] + initWithName:@"flutter/textinput" + binaryMessenger:self + codec:[FlutterJSONMethodCodec sharedInstance]]); + + _lifecycleChannel.reset([[FlutterBasicMessageChannel alloc] + initWithName:@"flutter/lifecycle" + binaryMessenger:self + codec:[FlutterStringCodec sharedInstance]]); + + _systemChannel.reset([[FlutterBasicMessageChannel alloc] + initWithName:@"flutter/system" + binaryMessenger:self + codec:[FlutterJSONMessageCodec sharedInstance]]); + + _settingsChannel.reset([[FlutterBasicMessageChannel alloc] + initWithName:@"flutter/settings" + binaryMessenger:self + codec:[FlutterJSONMessageCodec sharedInstance]]); + + auto flutterViewController = self.iosPlatformView->GetOwnerViewController(); + if (flutterViewController) { + auto weakPtr = flutterViewController.getWeakPtr; + _platformPlugin.reset([[FlutterPlatformPlugin alloc] initWithViewController:weakPtr]); + } else { + _platformPlugin.reset([[FlutterPlatformPlugin alloc] init]); + } + + [_platformChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + [_platformPlugin.get() handleMethodCall:call result:result]; + }]; + + _textInputPlugin.reset([[FlutterTextInputPlugin alloc] init]); + _textInputPlugin.get().textInputDelegate = self; + [_textInputChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + [_textInputPlugin.get() handleMethodCall:call result:result]; + }]; + self.iosPlatformView->SetTextInputPlugin(_textInputPlugin); +} + +- (shell::Rasterizer::Screenshot)screenshot:(shell::Rasterizer::ScreenshotType)type + base64Encode:(bool)base64Encode { + return self.shell.Screenshot(type, base64Encode); +} + +- (void)run { + // Launch the Dart application with the inferred run configuration. + self.shell.GetTaskRunners().GetUITaskRunner()->PostTask(fml::MakeCopyable( + [engine = _shell->GetEngine(), // + config = [_dartProject.get() runConfigurationForEntrypoint:_dartEntrypoint + libraryOrNil:_dartLibrary] // + ]() mutable { + if (engine) { + auto result = engine->Run(std::move(config)); + if (result == shell::Engine::RunStatus::Failure) { + FML_LOG(ERROR) << "Could not launch engine with configuration."; + } + } + })); +} + +- (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)libraryUri { + if (_shell != nullptr) { + FML_LOG(ERROR) << "This FlutterEngine was already invoked."; + return false; + } + + if (!entrypoint) { + entrypoint = @"main"; + } + if (!libraryUri) { + libraryUri = @"main.dart"; + } + + _dartEntrypoint = entrypoint; + _dartLibrary = libraryUri; + + const auto threadLabel = CreateShellLabel(_labelPrefix); + + auto settings = shell::SettingsFromCommandLine(shell::CommandLineFromNSProcessInfo()); + + // These values set the name of the isolate for debugging. + settings.advisory_script_entrypoint = entrypoint.UTF8String; + settings.advisory_script_uri = libraryUri.UTF8String; + + // The current thread will be used as the platform thread. Ensure that the + // message loop is + // initialized. + fml::MessageLoop::EnsureInitializedForCurrentThread(); + + shell::ThreadHost threadHost = { + threadLabel.UTF8String, // label + shell::ThreadHost::Type::UI | shell::ThreadHost::Type::GPU | shell::ThreadHost::Type::IO}; + + blink::TaskRunners task_runners(threadLabel.UTF8String, // label + fml::MessageLoop::GetCurrent().GetTaskRunner(), // platform + threadHost.gpu_thread->GetTaskRunner(), // gpu + threadHost.ui_thread->GetTaskRunner(), // ui + threadHost.io_thread->GetTaskRunner() // io + ); + + // Lambda captures by pointers to ObjC objects are fine here because the + // create call is + // synchronous. + shell::Shell::CreateCallback on_create_platform_view = + [](shell::Shell& shell) { + return std::make_unique(shell, shell.GetTaskRunners()); + }; + + shell::Shell::CreateCallback on_create_rasterizer = [](shell::Shell& shell) { + return std::make_unique(shell.GetTaskRunners()); + }; + + // Create the shell. This is a blocking operation. + _shell = shell::Shell::Create(std::move(task_runners), // task runners + std::move(settings), // settings + on_create_platform_view, // platform view creation + on_create_rasterizer // rasterzier creation + ); + + if (_shell == nullptr) { + FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " + << entrypoint.UTF8String; + } + return _shell != nullptr; +} + +- (bool)runWithEntrypoint:(NSString*)entrypoint { + return [self runWithEntrypointAndLibraryUri:entrypoint libraryUri:nil]; +} + +#pragma mark - Text input delegate + +- (void)updateEditingClient:(int)client withState:(NSDictionary*)state { + [_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingState" + arguments:@[ @(client), state ]]; +} + +- (void)performAction:(FlutterTextInputAction)action withClient:(int)client { + NSString* actionString; + switch (action) { + case FlutterTextInputActionUnspecified: + // Where did the term "unspecified" come from? iOS has a "default" and Android + // has "unspecified." These 2 terms seem to mean the same thing but we need + // to pick just one. "unspecified" was chosen because "default" is often a + // reserved word in languages with switch statements (dart, java, etc). + actionString = @"TextInputAction.unspecified"; + break; + case FlutterTextInputActionDone: + actionString = @"TextInputAction.done"; + break; + case FlutterTextInputActionGo: + actionString = @"TextInputAction.go"; + break; + case FlutterTextInputActionSend: + actionString = @"TextInputAction.send"; + break; + case FlutterTextInputActionSearch: + actionString = @"TextInputAction.search"; + break; + case FlutterTextInputActionNext: + actionString = @"TextInputAction.next"; + break; + case FlutterTextInputActionContinue: + actionString = @"TextInputAction.continue"; + break; + case FlutterTextInputActionJoin: + actionString = @"TextInputAction.join"; + break; + case FlutterTextInputActionRoute: + actionString = @"TextInputAction.route"; + break; + case FlutterTextInputActionEmergencyCall: + actionString = @"TextInputAction.emergencyCall"; + break; + case FlutterTextInputActionNewline: + actionString = @"TextInputAction.newline"; + break; + } + [_textInputChannel.get() invokeMethod:@"TextInputClient.performAction" + arguments:@[ @(client), actionString ]]; +} + +#pragma mark - FlutterBinaryMessenger + +- (void)sendOnChannel:(NSString*)channel message:(NSData*)message { + [self sendOnChannel:channel message:message binaryReply:nil]; +} + +- (void)sendOnChannel:(NSString*)channel + message:(NSData*)message + binaryReply:(FlutterBinaryReply)callback { + NSAssert(channel, @"The channel must not be null"); + fml::RefPtr response = + (callback == nil) ? nullptr + : fml::MakeRefCounted( + ^(NSData* reply) { + callback(reply); + }, + _shell->GetTaskRunners().GetPlatformTaskRunner()); + fml::RefPtr platformMessage = + (message == nil) ? fml::MakeRefCounted(channel.UTF8String, response) + : fml::MakeRefCounted( + channel.UTF8String, shell::GetVectorFromNSData(message), response); + + _shell->GetPlatformView()->DispatchPlatformMessage(platformMessage); +} + +- (void)setMessageHandlerOnChannel:(NSString*)channel + binaryMessageHandler:(FlutterBinaryMessageHandler)handler { + NSAssert(channel, @"The channel must not be null"); + self.iosPlatformView->GetPlatformMessageRouter().SetMessageHandler(channel.UTF8String, handler); +} + +#pragma mark - FlutterTextureRegistry + +- (int64_t)registerTexture:(NSObject*)texture { + int64_t textureId = _nextTextureId++; + self.iosPlatformView->RegisterExternalTexture(textureId, texture); + return textureId; +} + +- (void)unregisterTexture:(int64_t)textureId { + _shell->GetPlatformView()->UnregisterTexture(textureId); +} + +- (void)textureFrameAvailable:(int64_t)textureId { + _shell->GetPlatformView()->MarkTextureFrameAvailable(textureId); +} + +- (NSString*)lookupKeyForAsset:(NSString*)asset { + return [FlutterDartProject lookupKeyForAsset:asset]; +} + +- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package { + return [FlutterDartProject lookupKeyForAsset:asset fromPackage:package]; +} + +- (id)pluginRegistry { + return self; +} + +#pragma mark - FlutterPluginRegistry + +- (NSObject*)registrarForPlugin:(NSString*)pluginKey { + NSAssert(self.pluginPublications[pluginKey] == nil, @"Duplicate plugin key: %@", pluginKey); + self.pluginPublications[pluginKey] = [NSNull null]; + return [[FlutterEngineRegistrar alloc] initWithPlugin:pluginKey flutterEngine:self]; +} + +- (BOOL)hasPlugin:(NSString*)pluginKey { + return _pluginPublications[pluginKey] != nil; +} + +- (NSObject*)valuePublishedByPlugin:(NSString*)pluginKey { + return _pluginPublications[pluginKey]; +} + +@end + +@implementation FlutterEngineRegistrar { + NSString* _pluginKey; + FlutterEngine* _flutterEngine; +} + +- (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine*)flutterEngine { + self = [super init]; + NSAssert(self, @"Super init cannot be nil"); + _pluginKey = [pluginKey retain]; + _flutterEngine = [flutterEngine retain]; + return self; +} + +- (void)dealloc { + [_pluginKey release]; + [_flutterEngine release]; + [super dealloc]; +} + +- (NSObject*)messenger { + return _flutterEngine; +} + +- (NSObject*)textures { + return _flutterEngine; +} + +- (void)publish:(NSObject*)value { + _flutterEngine.pluginPublications[_pluginKey] = value; +} + +- (void)addMethodCallDelegate:(NSObject*)delegate + channel:(FlutterMethodChannel*)channel { + [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + [delegate handleMethodCall:call result:result]; + }]; +} + +- (void)addApplicationDelegate:(NSObject*)delegate { + id appDelegate = [[UIApplication sharedApplication] delegate]; + if ([appDelegate conformsToProtocol:@protocol(FlutterAppLifeCycleProvider)]) { + id lifeCycleProvider = + (id)appDelegate; + [lifeCycleProvider addApplicationLifeCycleDelegate:delegate]; + } +} + +- (NSString*)lookupKeyForAsset:(NSString*)asset { + return [_flutterEngine lookupKeyForAsset:asset]; +} + +- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package { + return [_flutterEngine lookupKeyForAsset:asset fromPackage:package]; +} + +@end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h new file mode 100644 index 0000000000000..ad6c5f8cb2271 --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h @@ -0,0 +1,43 @@ +// Copyright 2018 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERENGINE_INTERNAL_H_ +#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERENGINE_INTERNAL_H_ + +#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h" + +#include "flutter/fml/task_runner.h" +#include "flutter/lib/ui/window/pointer_data_packet.h" +#include "flutter/lib/ui/window/viewport_metrics.h" +#include "flutter/shell/common/platform_view.h" +#include "flutter/shell/common/rasterizer.h" +#include "flutter/shell/common/shell.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h" +#include "flutter/shell/platform/darwin/ios/platform_view_ios.h" + +#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h" + +@interface FlutterEngine () + +- (shell::Shell&)shell; + +- (void)updateViewportMetrics:(blink::ViewportMetrics)viewportMetrics; +- (void)dispatchPointerDataPacket:(std::unique_ptr)packet; + +- (fml::RefPtr)platformTaskRunner; + +- (fml::WeakPtr)platformView; + +- (shell::Rasterizer::Screenshot)screenshot:(shell::Rasterizer::ScreenshotType)type + base64Encode:(bool)base64Encode; + +- (FlutterPlatformPlugin*)platformPlugin; +- (FlutterTextInputPlugin*)textInputPlugin; + +@end + +#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERENGINE_INTERNAL_H_ diff --git a/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm b/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm index 5d0f42af6c1e0..5d0866dbe7332 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm @@ -4,11 +4,11 @@ #define FML_USED_ON_EMBEDDER +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h" + #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h" -#include #include -#include #include "flutter/fml/make_copyable.h" #include "flutter/fml/message_loop.h" @@ -22,73 +22,17 @@ #include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h" #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h" #include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" -#include "flutter/shell/platform/darwin/ios/headless_platform_view_ios.h" #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" -static std::unique_ptr CreateHeadlessPlatformView( - shell::Shell& shell) { - return std::make_unique(shell, shell.GetTaskRunners()); -} - -static std::unique_ptr CreateHeadlessRasterizer(shell::Shell& shell) { - return std::make_unique(shell.GetTaskRunners()); -} - -static std::string CreateShellLabel() { - static size_t count = 1; - std::stringstream stream; - stream << "io.flutter.headless."; - stream << count++; - return stream.str(); -} - @implementation FlutterHeadlessDartRunner { - shell::ThreadHost _threadHost; - std::unique_ptr _shell; } -- (void)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri { - if (_shell != nullptr || entrypoint.length == 0) { - FML_LOG(ERROR) << "This headless dart runner was already used to run some code."; - return; - } - - const auto label = CreateShellLabel(); - - // Create the threads to run the shell on. - _threadHost = { - label, // native thread label - shell::ThreadHost::Type::UI // managed threads to create - }; - - // Configure shell task runners. - auto current_task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner(); - auto single_task_runner = _threadHost.ui_thread->GetTaskRunner(); - blink::TaskRunners task_runners(label, // dart thread label - current_task_runner, // platform - single_task_runner, // gpu - single_task_runner, // ui - single_task_runner // io - ); - - auto settings = shell::SettingsFromCommandLine(shell::CommandLineFromNSProcessInfo()); - - // These values set the name of the isolate for debugging. - settings.advisory_script_entrypoint = entrypoint.UTF8String; - settings.advisory_script_uri = uri.UTF8String; - - // Create the shell. This is a blocking operation. - _shell = shell::Shell::Create( - std::move(task_runners), // task runners - std::move(settings), // settings - std::bind(&CreateHeadlessPlatformView, std::placeholders::_1), // platform view creation - std::bind(&CreateHeadlessRasterizer, std::placeholders::_1) // rasterzier creation - ); - - if (_shell == nullptr) { - FML_LOG(ERROR) << "Could not start a shell for the headless dart runner with entrypoint: " - << entrypoint.UTF8String; - return; +- (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri { + bool shellCreated = [super runWithEntrypointAndLibraryUri:entrypoint libraryUri:uri]; + if (!shellCreated || entrypoint.length == 0) { + FML_LOG(ERROR) + << "FlutterHeadlessDartRunner requires on proper setup of shell and a valid entrypoint."; + return false; } FlutterDartProject* project = [[[FlutterDartProject alloc] init] autorelease]; @@ -97,8 +41,8 @@ - (void)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin config.SetEntrypointAndLibrary(entrypoint.UTF8String, uri.UTF8String); // Override the default run configuration with the specified entrypoint. - _shell->GetTaskRunners().GetUITaskRunner()->PostTask( - fml::MakeCopyable([engine = _shell->GetEngine(), config = std::move(config)]() mutable { + self.shell.GetTaskRunners().GetUITaskRunner()->PostTask( + fml::MakeCopyable([engine = self.shell.GetEngine(), config = std::move(config)]() mutable { BOOL success = NO; FML_LOG(INFO) << "Attempting to launch background engine configuration..."; if (!engine || engine->Run(std::move(config)) == shell::Engine::RunStatus::Failure) { @@ -108,42 +52,11 @@ - (void)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin success = YES; } })); + return true; } -- (void)runWithEntrypoint:(NSString*)entrypoint { - [self runWithEntrypointAndLibraryUri:entrypoint libraryUri:nil]; -} - -#pragma mark - FlutterBinaryMessenger - -- (void)sendOnChannel:(NSString*)channel message:(NSData*)message { - [self sendOnChannel:channel message:message binaryReply:nil]; -} - -- (void)sendOnChannel:(NSString*)channel - message:(NSData*)message - binaryReply:(FlutterBinaryReply)callback { - NSAssert(channel, @"The channel must not be null"); - fml::RefPtr response = - (callback == nil) ? nullptr - : fml::MakeRefCounted( - ^(NSData* reply) { - callback(reply); - }, - _shell->GetTaskRunners().GetPlatformTaskRunner()); - fml::RefPtr platformMessage = - (message == nil) ? fml::MakeRefCounted(channel.UTF8String, response) - : fml::MakeRefCounted( - channel.UTF8String, shell::GetVectorFromNSData(message), response); - - _shell->GetPlatformView()->DispatchPlatformMessage(platformMessage); -} - -- (void)setMessageHandlerOnChannel:(NSString*)channel - binaryMessageHandler:(FlutterBinaryMessageHandler)handler { - reinterpret_cast(_shell->GetPlatformView().get()) - ->GetPlatformMessageRouter() - .SetMessageHandler(channel.UTF8String, handler); +- (bool)runWithEntrypoint:(NSString*)entrypoint { + return [self runWithEntrypointAndLibraryUri:entrypoint libraryUri:nil]; } @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h index 09bdfa8b0ea47..543727335a315 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h @@ -11,7 +11,7 @@ #include @interface FlutterPlatformPlugin : NSObject -- (instancetype)init NS_UNAVAILABLE; +- (instancetype)init NS_DESIGNATED_INITIALIZER; - (instancetype)initWithViewController:(fml::WeakPtr)viewController NS_DESIGNATED_INITIALIZER; - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm index 54873532ae18b..e646b915c16aa 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm @@ -37,13 +37,10 @@ @implementation FlutterPlatformPlugin { } - (instancetype)init { - @throw([NSException exceptionWithName:@"FlutterPlatformPlugin must initWithViewController" - reason:nil - userInfo:nil]); + return [super init]; } - (instancetype)initWithViewController:(fml::WeakPtr)viewController { - FML_DCHECK(viewController) << "viewController must be set"; self = [super init]; if (self) { @@ -203,7 +200,7 @@ - (void)popSystemNavigator { UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController; if ([viewController isKindOfClass:[UINavigationController class]]) { [((UINavigationController*)viewController) popViewControllerAnimated:NO]; - } else if (viewController != _viewController.get()) { + } else if (_viewController && viewController != _viewController.get()) { [_viewController.get() dismissViewControllerAnimated:NO completion:nil]; } } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterView.mm b/shell/platform/darwin/ios/framework/Source/FlutterView.mm index 32c54f632992f..2fcbbbc235e7d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterView.mm @@ -13,6 +13,7 @@ #include "flutter/shell/common/platform_view.h" #include "flutter/shell/common/rasterizer.h" #include "flutter/shell/common/shell.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h" #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h" #include "flutter/shell/platform/darwin/ios/ios_surface_gl.h" #include "flutter/shell/platform/darwin/ios/ios_surface_software.h" @@ -90,10 +91,9 @@ - (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context { return; } - auto& shell = [controller shell]; - - auto screenshot = shell.Screenshot(shell::Rasterizer::ScreenshotType::UncompressedImage, - false /* base64 encode */); + auto screenshot = + [controller.engine screenshot:shell::Rasterizer::ScreenshotType::UncompressedImage + base64Encode:false]; if (!screenshot.data || screenshot.data->isEmpty() || screenshot.frame_size.isEmpty()) { return; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 2c42c14911e57..ab822e3ae0b5c 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -4,7 +4,7 @@ #define FML_USED_ON_EMBEDDER -#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h" +#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" #include @@ -13,7 +13,7 @@ #include "flutter/fml/platform/darwin/platform_version.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" #include "flutter/shell/common/thread_host.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h" #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h" #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h" @@ -22,31 +22,10 @@ #include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" -@interface FlutterViewController () -@property(nonatomic, readonly) NSMutableDictionary* pluginPublications; -@end - -@interface FlutterViewControllerRegistrar : NSObject -- (instancetype)initWithPlugin:(NSString*)pluginKey - flutterViewController:(FlutterViewController*)flutterViewController; -@end - @implementation FlutterViewController { fml::scoped_nsobject _dartProject; - shell::ThreadHost _threadHost; - std::unique_ptr _shell; std::unique_ptr> _weakFactory; - - // Channels - fml::scoped_nsobject _platformPlugin; - fml::scoped_nsobject _textInputPlugin; - fml::scoped_nsobject _localizationChannel; - fml::scoped_nsobject _navigationChannel; - fml::scoped_nsobject _platformChannel; - fml::scoped_nsobject _textInputChannel; - fml::scoped_nsobject _lifecycleChannel; - fml::scoped_nsobject _systemChannel; - fml::scoped_nsobject _settingsChannel; + fml::scoped_nsobject _engine; // We keep a separate reference to this and create it ahead of time because we want to be able to // setup a shell along with its platform view before the view has to appear. @@ -56,12 +35,24 @@ @implementation FlutterViewController { UIStatusBarStyle _statusBarStyle; blink::ViewportMetrics _viewportMetrics; shell::TouchMapper _touchMapper; - int64_t _nextTextureId; BOOL _initialized; } #pragma mark - Manage and override all designated initializers +- (instancetype)initWithEngine:(FlutterEngine*)engine + nibName:(NSString*)nibNameOrNil + bundle:(NSBundle*)nibBundleOrNil { + NSAssert(engine != nil, @"Engine is required"); + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + _engine.reset(engine); + [self performCommonViewControllerInitialization]; + } + + return self; +} + - (instancetype)initWithProject:(FlutterDartProject*)projectOrNil nibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil { @@ -73,6 +64,7 @@ - (instancetype)initWithProject:(FlutterDartProject*)projectOrNil else _dartProject.reset([projectOrNil retain]); + _engine.reset([[FlutterEngine alloc] initWithName:@"io.flutter" andProject:projectOrNil]); [self performCommonViewControllerInitialization]; } @@ -102,129 +94,15 @@ - (void)performCommonViewControllerInitialization { _orientationPreferences = UIInterfaceOrientationMaskAll; _statusBarStyle = UIStatusBarStyleDefault; - if ([self setupShell]) { - [self setupChannels]; - [self setupNotificationCenterObservers]; - - _pluginPublications = [NSMutableDictionary new]; - } -} - -- (shell::Shell&)shell { - FML_DCHECK(_shell); - return *_shell; + [self setupNotificationCenterObservers]; } -- (fml::WeakPtr)iosPlatformView { - FML_DCHECK(_shell); - return _shell->GetPlatformView(); +- (fml::scoped_nsobject)engine { + return _engine; } -- (BOOL)setupShell { - FML_DCHECK(_shell == nullptr); - - static size_t shell_count = 1; - - auto threadLabel = [NSString stringWithFormat:@"io.flutter.%zu", shell_count++]; - - _threadHost = { - threadLabel.UTF8String, // label - shell::ThreadHost::Type::UI | shell::ThreadHost::Type::GPU | shell::ThreadHost::Type::IO}; - - // The current thread will be used as the platform thread. Ensure that the message loop is - // initialized. - fml::MessageLoop::EnsureInitializedForCurrentThread(); - - blink::TaskRunners task_runners(threadLabel.UTF8String, // label - fml::MessageLoop::GetCurrent().GetTaskRunner(), // platform - _threadHost.gpu_thread->GetTaskRunner(), // gpu - _threadHost.ui_thread->GetTaskRunner(), // ui - _threadHost.io_thread->GetTaskRunner() // io - ); - - _flutterView.reset([[FlutterView alloc] init]); - - // Lambda captures by pointers to ObjC objects are fine here because the create call is - // synchronous. - shell::Shell::CreateCallback on_create_platform_view = - [flutter_view_controller = self, flutter_view = _flutterView.get()](shell::Shell& shell) { - auto platform_view_ios = std::make_unique( - shell, // delegate - shell.GetTaskRunners(), // task runners - flutter_view_controller, // flutter view controller owner - flutter_view // flutter view owner - ); - return platform_view_ios; - }; - - shell::Shell::CreateCallback on_create_rasterizer = [](shell::Shell& shell) { - return std::make_unique(shell.GetTaskRunners()); - }; - - // Create the shell. - _shell = shell::Shell::Create(std::move(task_runners), // - [_dartProject settings], // - on_create_platform_view, // - on_create_rasterizer // - ); - - if (!_shell) { - FML_LOG(ERROR) << "Could not setup a shell to run the Dart application."; - return false; - } - - return true; -} - -- (void)setupChannels { - _localizationChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/localization" - binaryMessenger:self - codec:[FlutterJSONMethodCodec sharedInstance]]); - - _navigationChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/navigation" - binaryMessenger:self - codec:[FlutterJSONMethodCodec sharedInstance]]); - - _platformChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/platform" - binaryMessenger:self - codec:[FlutterJSONMethodCodec sharedInstance]]); - - _textInputChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/textinput" - binaryMessenger:self - codec:[FlutterJSONMethodCodec sharedInstance]]); - - _lifecycleChannel.reset([[FlutterBasicMessageChannel alloc] - initWithName:@"flutter/lifecycle" - binaryMessenger:self - codec:[FlutterStringCodec sharedInstance]]); - - _systemChannel.reset([[FlutterBasicMessageChannel alloc] - initWithName:@"flutter/system" - binaryMessenger:self - codec:[FlutterJSONMessageCodec sharedInstance]]); - - _settingsChannel.reset([[FlutterBasicMessageChannel alloc] - initWithName:@"flutter/settings" - binaryMessenger:self - codec:[FlutterJSONMessageCodec sharedInstance]]); - - _platformPlugin.reset( - [[FlutterPlatformPlugin alloc] initWithViewController:_weakFactory->GetWeakPtr()]); - [_platformChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { - [_platformPlugin.get() handleMethodCall:call result:result]; - }]; - - _textInputPlugin.reset([[FlutterTextInputPlugin alloc] init]); - _textInputPlugin.get().textInputDelegate = self; - [_textInputChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { - [_textInputPlugin.get() handleMethodCall:call result:result]; - }]; - static_cast(_shell->GetPlatformView().get()) - ->SetTextInputPlugin(_textInputPlugin); +- (fml::WeakPtr)getWeakPtr { + return _weakFactory->GetWeakPtr(); } - (void)setupNotificationCenterObservers { @@ -316,15 +194,15 @@ - (void)setupNotificationCenterObservers { } - (void)setInitialRoute:(NSString*)route { - [_navigationChannel.get() invokeMethod:@"setInitialRoute" arguments:route]; + [[_engine.get() navigationChannel] invokeMethod:@"setInitialRoute" arguments:route]; } - (void)popRoute { - [_navigationChannel.get() invokeMethod:@"popRoute" arguments:nil]; + [[_engine.get() navigationChannel] invokeMethod:@"popRoute" arguments:nil]; } - (void)pushRoute:(NSString*)route { - [_navigationChannel.get() invokeMethod:@"pushRoute" arguments:route]; + [[_engine.get() navigationChannel] invokeMethod:@"pushRoute" arguments:route]; } #pragma mark - Loading the view @@ -373,33 +251,36 @@ - (void)removeSplashScreenViewIfPresent { } - (void)installSplashScreenViewCallback { - if (!_shell || !_splashScreenView) { + if (!_splashScreenView) { return; } - auto weak_platform_view = _shell->GetPlatformView(); + auto weak_platform_view = [_engine.get() platformView]; if (!weak_platform_view) { return; } __unsafe_unretained auto weak_flutter_view_controller = self; // This is on the platform thread. - weak_platform_view->SetNextFrameCallback( - [weak_platform_view, weak_flutter_view_controller, - task_runner = _shell->GetTaskRunners().GetPlatformTaskRunner()]() { - // This is on the GPU thread. - task_runner->PostTask([weak_platform_view, weak_flutter_view_controller]() { - // We check if the weak platform view is alive. If it is alive, then the view controller - // also has to be alive since the view controller owns the platform view via the shell - // association. Thus, we are not convinced that the unsafe unretained weak object is in - // fact alive. - if (weak_platform_view) { - [weak_flutter_view_controller removeSplashScreenViewIfPresent]; - } - }); - }); + weak_platform_view->SetNextFrameCallback([weak_platform_view, weak_flutter_view_controller, + task_runner = [_engine.get() platformTaskRunner]]() { + // This is on the GPU thread. + task_runner->PostTask([weak_platform_view, weak_flutter_view_controller]() { + // We check if the weak platform view is alive. If it is alive, then the view controller + // also has to be alive since the view controller owns the platform view via the shell + // association. Thus, we are not convinced that the unsafe unretained weak object is in + // fact alive. + if (weak_platform_view) { + [weak_flutter_view_controller removeSplashScreenViewIfPresent]; + } + }); + }); } #pragma mark - Properties +- (FlutterView*)flutterView { + return _flutterView; +} + - (UIView*)splashScreenView { if (_splashScreenView == nullptr) { NSString* launchscreenName = @@ -451,10 +332,10 @@ - (void)surfaceUpdated:(BOOL)appeared { // NotifyCreated/NotifyDestroyed are synchronous and require hops between the UI and GPU thread. if (appeared) { [self installSplashScreenViewCallback]; - _shell->GetPlatformView()->NotifyCreated(); + [_engine.get() platformView] -> NotifyCreated(); } else { - _shell->GetPlatformView()->NotifyDestroyed(); + [_engine.get() platformView] -> NotifyDestroyed(); } } @@ -463,24 +344,13 @@ - (void)surfaceUpdated:(BOOL)appeared { - (void)viewWillAppear:(BOOL)animated { TRACE_EVENT0("flutter", "viewWillAppear"); - // Launch the Dart application with the inferred run configuration. - _shell->GetTaskRunners().GetUITaskRunner()->PostTask( - fml::MakeCopyable([engine = _shell->GetEngine(), // - config = [_dartProject.get() runConfiguration] // - ]() mutable { - if (engine) { - auto result = engine->Run(std::move(config)); - if (result == shell::Engine::RunStatus::Failure) { - FML_LOG(ERROR) << "Could not launch engine with configuration."; - } - } - })); + [_engine.get() run]; // Only recreate surface on subsequent appearances when viewport metrics are known. // First time surface creation is done on viewDidLayoutSubviews. if (_viewportMetrics.physical_width) [self surfaceUpdated:YES]; - [_lifecycleChannel.get() sendMessage:@"AppLifecycleState.inactive"]; + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.inactive"]; [super viewWillAppear:animated]; } @@ -490,14 +360,14 @@ - (void)viewDidAppear:(BOOL)animated { [self onLocaleUpdated:nil]; [self onUserSettingsChanged:nil]; [self onAccessibilityStatusChanged:nil]; - [_lifecycleChannel.get() sendMessage:@"AppLifecycleState.resumed"]; + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.resumed"]; [super viewDidAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { TRACE_EVENT0("flutter", "viewWillDisappear"); - [_lifecycleChannel.get() sendMessage:@"AppLifecycleState.inactive"]; + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.inactive"]; [super viewWillDisappear:animated]; } @@ -505,14 +375,13 @@ - (void)viewWillDisappear:(BOOL)animated { - (void)viewDidDisappear:(BOOL)animated { TRACE_EVENT0("flutter", "viewDidDisappear"); [self surfaceUpdated:NO]; - [_lifecycleChannel.get() sendMessage:@"AppLifecycleState.paused"]; + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.paused"]; [super viewDidDisappear:animated]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [_pluginPublications release]; [super dealloc]; } @@ -520,25 +389,25 @@ - (void)dealloc { - (void)applicationBecameActive:(NSNotification*)notification { TRACE_EVENT0("flutter", "applicationBecameActive"); - [_lifecycleChannel.get() sendMessage:@"AppLifecycleState.resumed"]; + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.resumed"]; } - (void)applicationWillResignActive:(NSNotification*)notification { TRACE_EVENT0("flutter", "applicationWillResignActive"); - [_lifecycleChannel.get() sendMessage:@"AppLifecycleState.inactive"]; + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.inactive"]; } - (void)applicationDidEnterBackground:(NSNotification*)notification { TRACE_EVENT0("flutter", "applicationDidEnterBackground"); [self surfaceUpdated:NO]; - [_lifecycleChannel.get() sendMessage:@"AppLifecycleState.paused"]; + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.paused"]; } - (void)applicationWillEnterForeground:(NSNotification*)notification { TRACE_EVENT0("flutter", "applicationWillEnterForeground"); if (_viewportMetrics.physical_width) [self surfaceUpdated:YES]; - [_lifecycleChannel.get() sendMessage:@"AppLifecycleState.inactive"]; + [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.inactive"]; } #pragma mark - Touch event handling @@ -684,12 +553,7 @@ - (void)dispatchTouches:(NSSet*)touches phase:(UITouchPhase)phase { packet->SetPointerData(i++, pointer_data); } - _shell->GetTaskRunners().GetUITaskRunner()->PostTask( - fml::MakeCopyable([engine = _shell->GetEngine(), packet = std::move(packet)] { - if (engine) { - engine->DispatchPointerDataPacket(*packet); - } - })); + [_engine.get() dispatchPointerDataPacket:std::move(packet)]; } - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { @@ -711,12 +575,7 @@ - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { #pragma mark - Handle view resizing - (void)updateViewportMetrics { - _shell->GetTaskRunners().GetUITaskRunner()->PostTask( - [engine = _shell->GetEngine(), metrics = _viewportMetrics]() { - if (engine) { - engine->SetViewportMetrics(std::move(metrics)); - } - }); + [_engine.get() updateViewportMetrics:_viewportMetrics]; } - (CGFloat)statusBarPadding { @@ -796,58 +655,6 @@ - (void)keyboardWillBeHidden:(NSNotification*)notification { [self updateViewportMetrics]; } -#pragma mark - Text input delegate - -- (void)updateEditingClient:(int)client withState:(NSDictionary*)state { - [_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingState" - arguments:@[ @(client), state ]]; -} - -- (void)performAction:(FlutterTextInputAction)action withClient:(int)client { - NSString* actionString; - switch (action) { - case FlutterTextInputActionUnspecified: - // Where did the term "unspecified" come from? iOS has a "default" and Android - // has "unspecified." These 2 terms seem to mean the same thing but we need - // to pick just one. "unspecified" was chosen because "default" is often a - // reserved word in languages with switch statements (dart, java, etc). - actionString = @"TextInputAction.unspecified"; - break; - case FlutterTextInputActionDone: - actionString = @"TextInputAction.done"; - break; - case FlutterTextInputActionGo: - actionString = @"TextInputAction.go"; - break; - case FlutterTextInputActionSend: - actionString = @"TextInputAction.send"; - break; - case FlutterTextInputActionSearch: - actionString = @"TextInputAction.search"; - break; - case FlutterTextInputActionNext: - actionString = @"TextInputAction.next"; - break; - case FlutterTextInputActionContinue: - actionString = @"TextInputAction.continue"; - break; - case FlutterTextInputActionJoin: - actionString = @"TextInputAction.join"; - break; - case FlutterTextInputActionRoute: - actionString = @"TextInputAction.route"; - break; - case FlutterTextInputActionEmergencyCall: - actionString = @"TextInputAction.emergencyCall"; - break; - case FlutterTextInputActionNewline: - actionString = @"TextInputAction.newline"; - break; - } - [_textInputChannel.get() invokeMethod:@"TextInputClient.performAction" - arguments:@[ @(client), actionString ]]; -} - #pragma mark - Orientation updates - (void)onOrientationPreferencesUpdated:(NSNotification*)notification { @@ -881,7 +688,7 @@ - (NSUInteger)supportedInterfaceOrientations { #pragma mark - Accessibility - (void)onAccessibilityStatusChanged:(NSNotification*)notification { - auto platformView = _shell->GetPlatformView(); + auto platformView = [_engine.get() platformView]; int32_t flags = 0; if (UIAccessibilityIsInvertColorsEnabled()) flags ^= static_cast(blink::AccessibilityFeatureFlag::kInvertColors); @@ -907,7 +714,7 @@ - (void)onAccessibilityStatusChanged:(NSNotification*)notification { #pragma mark - Memory Notifications - (void)onMemoryWarning:(NSNotification*)notification { - [_systemChannel.get() sendMessage:@{@"type" : @"memoryPressure"}]; + [[_engine.get() systemChannel] sendMessage:@{@"type" : @"memoryPressure"}]; } #pragma mark - Locale updates @@ -917,13 +724,14 @@ - (void)onLocaleUpdated:(NSNotification*)notification { NSString* languageCode = [currentLocale objectForKey:NSLocaleLanguageCode]; NSString* countryCode = [currentLocale objectForKey:NSLocaleCountryCode]; if (languageCode && countryCode) - [_localizationChannel.get() invokeMethod:@"setLocale" arguments:@[ languageCode, countryCode ]]; + [[_engine.get() localizationChannel] invokeMethod:@"setLocale" + arguments:@[ languageCode, countryCode ]]; } #pragma mark - Set user settings - (void)onUserSettingsChanged:(NSNotification*)notification { - [_settingsChannel.get() sendMessage:@{ + [[_engine.get() settingsChannel] sendMessage:@{ @"textScaleFactor" : @([self textScaleFactor]), @"alwaysUse24HourFormat" : @([self isAlwaysUse24HourFormat]), }]; @@ -1061,49 +869,34 @@ - (void)onPreferredStatusBarStyleUpdated:(NSNotification*)notification { #pragma mark - FlutterBinaryMessenger - (void)sendOnChannel:(NSString*)channel message:(NSData*)message { - [self sendOnChannel:channel message:message binaryReply:nil]; + [_engine.get() sendOnChannel:channel message:message]; } - (void)sendOnChannel:(NSString*)channel message:(NSData*)message binaryReply:(FlutterBinaryReply)callback { NSAssert(channel, @"The channel must not be null"); - fml::RefPtr response = - (callback == nil) ? nullptr - : fml::MakeRefCounted( - ^(NSData* reply) { - callback(reply); - }, - _shell->GetTaskRunners().GetPlatformTaskRunner()); - fml::RefPtr platformMessage = - (message == nil) ? fml::MakeRefCounted(channel.UTF8String, response) - : fml::MakeRefCounted( - channel.UTF8String, shell::GetVectorFromNSData(message), response); - - _shell->GetPlatformView()->DispatchPlatformMessage(platformMessage); + [_engine.get() sendOnChannel:channel message:message binaryReply:callback]; } - (void)setMessageHandlerOnChannel:(NSString*)channel binaryMessageHandler:(FlutterBinaryMessageHandler)handler { NSAssert(channel, @"The channel must not be null"); - [self iosPlatformView] -> GetPlatformMessageRouter().SetMessageHandler(channel.UTF8String, - handler); + [_engine.get() setMessageHandlerOnChannel:channel binaryMessageHandler:handler]; } #pragma mark - FlutterTextureRegistry - (int64_t)registerTexture:(NSObject*)texture { - int64_t textureId = _nextTextureId++; - [self iosPlatformView] -> RegisterExternalTexture(textureId, texture); - return textureId; + return [_engine.get() registerTexture:texture]; } - (void)unregisterTexture:(int64_t)textureId { - _shell->GetPlatformView()->UnregisterTexture(textureId); + [_engine.get() unregisterTexture:textureId]; } - (void)textureFrameAvailable:(int64_t)textureId { - _shell->GetPlatformView()->MarkTextureFrameAvailable(textureId); + [_engine.get() textureFrameAvailable:textureId]; } - (NSString*)lookupKeyForAsset:(NSString*)asset { @@ -1115,81 +908,20 @@ - (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package { } - (id)pluginRegistry { - return self; + return _engine; } #pragma mark - FlutterPluginRegistry - (NSObject*)registrarForPlugin:(NSString*)pluginKey { - NSAssert(self.pluginPublications[pluginKey] == nil, @"Duplicate plugin key: %@", pluginKey); - self.pluginPublications[pluginKey] = [NSNull null]; - return [[FlutterViewControllerRegistrar alloc] initWithPlugin:pluginKey - flutterViewController:self]; + return [_engine.get() registrarForPlugin:pluginKey]; } - (BOOL)hasPlugin:(NSString*)pluginKey { - return _pluginPublications[pluginKey] != nil; + return [_engine.get() hasPlugin:pluginKey]; } - (NSObject*)valuePublishedByPlugin:(NSString*)pluginKey { - return _pluginPublications[pluginKey]; -} -@end - -@implementation FlutterViewControllerRegistrar { - NSString* _pluginKey; - FlutterViewController* _flutterViewController; -} - -- (instancetype)initWithPlugin:(NSString*)pluginKey - flutterViewController:(FlutterViewController*)flutterViewController { - self = [super init]; - NSAssert(self, @"Super init cannot be nil"); - _pluginKey = [pluginKey retain]; - _flutterViewController = [flutterViewController retain]; - return self; -} - -- (void)dealloc { - [_pluginKey release]; - [_flutterViewController release]; - [super dealloc]; -} - -- (NSObject*)messenger { - return _flutterViewController; + return [_engine.get() valuePublishedByPlugin:pluginKey]; } - -- (NSObject*)textures { - return _flutterViewController; -} - -- (void)publish:(NSObject*)value { - _flutterViewController.pluginPublications[_pluginKey] = value; -} - -- (void)addMethodCallDelegate:(NSObject*)delegate - channel:(FlutterMethodChannel*)channel { - [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { - [delegate handleMethodCall:call result:result]; - }]; -} - -- (void)addApplicationDelegate:(NSObject*)delegate { - id appDelegate = [[UIApplication sharedApplication] delegate]; - if ([appDelegate conformsToProtocol:@protocol(FlutterAppLifeCycleProvider)]) { - id lifeCycleProvider = - (id)appDelegate; - [lifeCycleProvider addApplicationLifeCycleDelegate:delegate]; - } -} - -- (NSString*)lookupKeyForAsset:(NSString*)asset { - return [_flutterViewController lookupKeyForAsset:asset]; -} - -- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package { - return [_flutterViewController lookupKeyForAsset:asset fromPackage:package]; -} - @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h index 482379c8f17eb..3031adbf46baa 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h @@ -5,12 +5,15 @@ #ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERVIEWCONTROLLER_INTERNAL_H_ #define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERVIEWCONTROLLER_INTERNAL_H_ -#include "flutter/shell/common/shell.h" +#include "flutter/fml/memory/weak_ptr.h" +#include "flutter/fml/platform/darwin/scoped_nsobject.h" #include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" @interface FlutterViewController () -- (shell::Shell&)shell; +- (fml::WeakPtr)getWeakPtr; + +@property(readonly) fml::scoped_nsobject engine; @end diff --git a/shell/platform/darwin/ios/headless_platform_view_ios.h b/shell/platform/darwin/ios/headless_platform_view_ios.h deleted file mode 100644 index 940e2ade4af58..0000000000000 --- a/shell/platform/darwin/ios/headless_platform_view_ios.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SHELL_PLATFORM_IOS_HEADLESS_PLATFORM_VIEW_IOS_H_ -#define SHELL_PLATFORM_IOS_HEADLESS_PLATFORM_VIEW_IOS_H_ - -#include - -#include "flutter/fml/closure.h" -#include "flutter/fml/macros.h" -#include "flutter/fml/memory/weak_ptr.h" -#include "flutter/fml/platform/darwin/scoped_nsobject.h" -#include "flutter/shell/common/platform_view.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h" - -namespace shell { - -class HeadlessPlatformViewIOS : public PlatformView { - public: - explicit HeadlessPlatformViewIOS(Delegate& delegate, - blink::TaskRunners task_runners); - virtual ~HeadlessPlatformViewIOS(); - - PlatformMessageRouter& GetPlatformMessageRouter(); - - private: - PlatformMessageRouter platform_message_router_; - - // |shell::PlatformView| - void HandlePlatformMessage(fml::RefPtr message); - - FML_DISALLOW_COPY_AND_ASSIGN(HeadlessPlatformViewIOS); -}; - -} // namespace shell - -#endif // SHELL_PLATFORM_IOS_HEADLESS_PLATFORM_VIEW_IOS_H_ diff --git a/shell/platform/darwin/ios/headless_platform_view_ios.mm b/shell/platform/darwin/ios/headless_platform_view_ios.mm deleted file mode 100644 index c496253494398..0000000000000 --- a/shell/platform/darwin/ios/headless_platform_view_ios.mm +++ /dev/null @@ -1,20 +0,0 @@ - -#include "flutter/shell/platform/darwin/ios/headless_platform_view_ios.h" - -namespace shell { - -HeadlessPlatformViewIOS::HeadlessPlatformViewIOS(PlatformView::Delegate& delegate, - blink::TaskRunners task_runners) - : PlatformView(delegate, std::move(task_runners)) {} - -HeadlessPlatformViewIOS::~HeadlessPlatformViewIOS() = default; - -PlatformMessageRouter& HeadlessPlatformViewIOS::GetPlatformMessageRouter() { - return platform_message_router_; -} - -// |shell::PlatformView| -void HeadlessPlatformViewIOS::HandlePlatformMessage(fml::RefPtr message) { - platform_message_router_.HandlePlatformMessage(std::move(message)); -} -} diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index 014f045f70c77..b188c993421f3 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -16,21 +16,24 @@ #include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h" #include "flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h" -#include "flutter/shell/platform/darwin/ios/headless_platform_view_ios.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h" #include "flutter/shell/platform/darwin/ios/ios_surface.h" +@class FlutterViewController; + namespace shell { -class PlatformViewIOS final : public HeadlessPlatformViewIOS { +class PlatformViewIOS final : public PlatformView { public: explicit PlatformViewIOS(PlatformView::Delegate& delegate, - blink::TaskRunners task_runners, - FlutterViewController* owner_controller_, - FlutterView* owner_view_); + blink::TaskRunners task_runners); + + ~PlatformViewIOS(); - ~PlatformViewIOS() override; + PlatformMessageRouter& GetPlatformMessageRouter(); FlutterViewController* GetOwnerViewController() const; + void SetOwnerViewController(FlutterViewController* owner_controller); void RegisterExternalTexture(int64_t id, NSObject* texture); @@ -41,13 +44,15 @@ class PlatformViewIOS final : public HeadlessPlatformViewIOS { private: FlutterViewController* owner_controller_; // weak reference. - FlutterView* owner_view_; // weak reference. std::unique_ptr ios_surface_; PlatformMessageRouter platform_message_router_; std::unique_ptr accessibility_bridge_; fml::scoped_nsprotocol text_input_plugin_; fml::closure firstFrameCallback_; + // |shell::PlatformView| + void HandlePlatformMessage(fml::RefPtr message) override; + // |shell::PlatformView| std::unique_ptr CreateRenderingSurface() override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 7bf0895589346..771ce158b5062 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -17,25 +17,35 @@ namespace shell { -PlatformViewIOS::PlatformViewIOS(PlatformView::Delegate& delegate, - blink::TaskRunners task_runners, - FlutterViewController* owner_controller, - FlutterView* owner_view) - : HeadlessPlatformViewIOS(delegate, std::move(task_runners)), - owner_controller_(owner_controller), - owner_view_(owner_view), - ios_surface_(owner_view_.createSurface) { - FML_DCHECK(ios_surface_ != nullptr); - FML_DCHECK(owner_controller_ != nullptr); - FML_DCHECK(owner_view_ != nullptr); -} +PlatformViewIOS::PlatformViewIOS(PlatformView::Delegate& delegate, blink::TaskRunners task_runners) + : PlatformView(delegate, std::move(task_runners)) {} PlatformViewIOS::~PlatformViewIOS() = default; +PlatformMessageRouter& PlatformViewIOS::GetPlatformMessageRouter() { + return platform_message_router_; +} + +// |shell::PlatformView| +void PlatformViewIOS::HandlePlatformMessage(fml::RefPtr message) { + platform_message_router_.HandlePlatformMessage(std::move(message)); +} + FlutterViewController* PlatformViewIOS::GetOwnerViewController() const { return owner_controller_; } +void PlatformViewIOS::SetOwnerViewController(FlutterViewController* owner_controller) { + owner_controller_ = owner_controller; + ios_surface_ = static_cast(owner_controller_.view).createSurface; + FML_DCHECK(ios_surface_ != nullptr); + FML_DCHECK(owner_controller_ != nullptr); + + if (accessibility_bridge_) { + accessibility_bridge_.reset(new AccessibilityBridge(static_cast(owner_controller_.view), this)); + } +} + void PlatformViewIOS::RegisterExternalTexture(int64_t texture_id, NSObject* texture) { RegisterTexture(std::make_shared(texture_id, texture)); @@ -43,13 +53,19 @@ // |shell::PlatformView| std::unique_ptr PlatformViewIOS::CreateRenderingSurface() { + if (!ios_surface_) { + FML_DLOG(INFO) << "Could not CreateRenderingSurface, this PlatformViewIOS " + "has no ViewController."; + return nullptr; + } return ios_surface_->CreateGPUSurface(); } // |shell::PlatformView| sk_sp PlatformViewIOS::CreateResourceContext() const { - if (!ios_surface_->ResourceContextMakeCurrent()) { - FML_DLOG(INFO) << "Could not make resource context current on IO thread. Async texture uploads " + if (!ios_surface_ || !ios_surface_->ResourceContextMakeCurrent()) { + FML_DLOG(INFO) << "Could not make resource context current on IO thread. " + "Async texture uploads " "will be disabled."; return nullptr; } @@ -59,8 +75,13 @@ // |shell::PlatformView| void PlatformViewIOS::SetSemanticsEnabled(bool enabled) { + if (!owner_controller_) { + FML_DLOG(INFO) << "Could not set semantics to enabled, this " + "PlatformViewIOS has no ViewController."; + } if (enabled && !accessibility_bridge_) { - accessibility_bridge_ = std::make_unique(owner_view_, this); + accessibility_bridge_ = + std::make_unique(static_cast(owner_controller_.view), this); } else if (!enabled && accessibility_bridge_) { accessibility_bridge_.reset(); } From cb0dd1ef5996504b2d2d65a2d358366e4372004d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 2 Oct 2018 16:57:51 -0700 Subject: [PATCH 02/31] license update --- ci/licenses_golden/licenses_flutter | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index a13a6abe9b6e5..c378cfba568d2 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -269,6 +269,7 @@ FILE: ../../../flutter/shell/common/thread_host.cc FILE: ../../../flutter/shell/common/thread_host.h FILE: ../../../flutter/shell/platform/darwin/common/command_line.h FILE: ../../../flutter/shell/platform/darwin/common/command_line.mm +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h FILE: ../../../flutter/shell/platform/embedder/embedder.h FILE: ../../../flutter/shell/platform/embedder/embedder_engine.cc FILE: ../../../flutter/shell/platform/embedder/embedder_engine.h From bde9e9f2538fe2d2de20532f05a1e2a850d14466 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 2 Oct 2018 23:24:26 -0700 Subject: [PATCH 03/31] cleanup --- .../ios/framework/Source/FlutterEngine.mm | 45 ++++++++++++------- .../framework/Source/FlutterViewController.mm | 10 ++--- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index baed0755e8d5c..e8dd2ad0bc68e 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -63,6 +63,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix andProject:(FlutterDartProje NSAssert(self, @"Super init cannot be nil"); NSAssert(labelPrefix, @"labelPrefix is required"); _labelPrefix = labelPrefix; + if (projectOrNil == nil) _dartProject.reset([[FlutterDartProject alloc] init]); else @@ -70,8 +71,6 @@ - (instancetype)initWithName:(NSString*)labelPrefix andProject:(FlutterDartProje _pluginPublications = [NSMutableDictionary new]; - [self setupChannels]; - return self; } @@ -104,20 +103,24 @@ - (void)dispatchPointerDataPacket:(std::unique_ptr)pac } - (fml::WeakPtr)platformView { + FML_DCHECK(_shell); return _shell->GetPlatformView(); } - (shell::PlatformViewIOS*)iosPlatformView { + FML_DCHECK(_shell); return static_cast(_shell->GetPlatformView().get()); } - (fml::RefPtr)platformTaskRunner { + FML_DCHECK(_shell); return _shell->GetTaskRunners().GetPlatformTaskRunner(); } - (void)setViewController:(FlutterViewController*)viewController { FML_DCHECK(self.iosPlatformView); self.iosPlatformView->SetOwnerViewController(viewController); + [self setupPlatformChannel]; } - (FlutterViewController*)getViewController { @@ -191,17 +194,7 @@ - (void)setupChannels { binaryMessenger:self codec:[FlutterJSONMessageCodec sharedInstance]]); - auto flutterViewController = self.iosPlatformView->GetOwnerViewController(); - if (flutterViewController) { - auto weakPtr = flutterViewController.getWeakPtr; - _platformPlugin.reset([[FlutterPlatformPlugin alloc] initWithViewController:weakPtr]); - } else { - _platformPlugin.reset([[FlutterPlatformPlugin alloc] init]); - } - - [_platformChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { - [_platformPlugin.get() handleMethodCall:call result:result]; - }]; + [self setupPlatformChannel]; _textInputPlugin.reset([[FlutterTextInputPlugin alloc] init]); _textInputPlugin.get().textInputDelegate = self; @@ -211,12 +204,29 @@ - (void)setupChannels { self.iosPlatformView->SetTextInputPlugin(_textInputPlugin); } +- (void)setupPlatformChannel { + if (_shell && self.shell.IsSetup()) { + auto flutterViewController = self.iosPlatformView->GetOwnerViewController(); + if (flutterViewController) { + auto weakPtr = flutterViewController.getWeakPtr; + _platformPlugin.reset([[FlutterPlatformPlugin alloc] initWithViewController:weakPtr]); + } + [_platformChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + [_platformPlugin.get() handleMethodCall:call result:result]; + }]; + + } else { + _platformPlugin.reset([[FlutterPlatformPlugin alloc] init]); + } +} + - (shell::Rasterizer::Screenshot)screenshot:(shell::Rasterizer::ScreenshotType)type base64Encode:(bool)base64Encode { return self.shell.Screenshot(type, base64Encode); } - (void)run { + [self runWithEntrypointAndLibraryUri:_dartEntrypoint libraryUri:_dartLibrary]; // Launch the Dart application with the inferred run configuration. self.shell.GetTaskRunners().GetUITaskRunner()->PostTask(fml::MakeCopyable( [engine = _shell->GetEngine(), // @@ -234,7 +244,7 @@ - (void)run { - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)libraryUri { if (_shell != nullptr) { - FML_LOG(ERROR) << "This FlutterEngine was already invoked."; + FML_LOG(WARNING) << "This FlutterEngine was already invoked."; return false; } @@ -250,7 +260,8 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin const auto threadLabel = CreateShellLabel(_labelPrefix); - auto settings = shell::SettingsFromCommandLine(shell::CommandLineFromNSProcessInfo()); + auto settings = [_dartProject + settings]; // shell::SettingsFromCommandLine(shell::CommandLineFromNSProcessInfo()); // These values set the name of the isolate for debugging. settings.advisory_script_entrypoint = entrypoint.UTF8String; @@ -294,7 +305,10 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin if (_shell == nullptr) { FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " << entrypoint.UTF8String; + } else { + [self setupChannels]; } + return _shell != nullptr; } @@ -382,6 +396,7 @@ - (void)sendOnChannel:(NSString*)channel - (void)setMessageHandlerOnChannel:(NSString*)channel binaryMessageHandler:(FlutterBinaryMessageHandler)handler { NSAssert(channel, @"The channel must not be null"); + FML_DCHECK(_shell && _shell->IsSetup()); self.iosPlatformView->GetPlatformMessageRouter().SetMessageHandler(channel.UTF8String, handler); } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index ab822e3ae0b5c..5452a1b9b3588 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -23,7 +23,6 @@ #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" @implementation FlutterViewController { - fml::scoped_nsobject _dartProject; std::unique_ptr> _weakFactory; fml::scoped_nsobject _engine; @@ -47,6 +46,7 @@ - (instancetype)initWithEngine:(FlutterEngine*)engine self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { _engine.reset(engine); + _weakFactory = std::make_unique>(self); [self performCommonViewControllerInitialization]; } @@ -59,12 +59,8 @@ - (instancetype)initWithProject:(FlutterDartProject*)projectOrNil self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { _weakFactory = std::make_unique>(self); - if (projectOrNil == nil) - _dartProject.reset([[FlutterDartProject alloc] init]); - else - _dartProject.reset([projectOrNil retain]); - _engine.reset([[FlutterEngine alloc] initWithName:@"io.flutter" andProject:projectOrNil]); + [_engine.get() runWithEntrypoint:nil]; [self performCommonViewControllerInitialization]; } @@ -91,6 +87,8 @@ - (void)performCommonViewControllerInitialization { _initialized = YES; + _flutterView.reset([[FlutterView alloc] init]); + _orientationPreferences = UIInterfaceOrientationMaskAll; _statusBarStyle = UIStatusBarStyleDefault; From 85f6214f537624a3a4211419ffd76f2b113d45ce Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 3 Oct 2018 15:40:22 -0700 Subject: [PATCH 04/31] bug fixes --- .../ios/framework/Headers/FlutterEngine.h | 2 +- .../ios/framework/Source/FlutterEngine.mm | 37 ++++++++----------- .../framework/Source/FlutterViewController.mm | 8 ++-- .../platform/darwin/ios/platform_view_ios.mm | 26 +++++++++---- 4 files changed, 40 insertions(+), 33 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 40b85b62f013b..6ed4d3eb3469c 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -26,7 +26,7 @@ FLUTTER_EXPORT andProject:(FlutterDartProject*)projectOrNil NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; -- (void)run; +- (void)launchEngine; /** Runs a Dart function on an Isolate. diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index e8dd2ad0bc68e..8de052d9c0386 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -24,11 +24,6 @@ #include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" -static NSString* CreateShellLabel(NSString* label) { - static size_t shell_count = 1; - return [NSString stringWithFormat:@"%@.%zu", label, shell_count++]; -} - @interface FlutterEngine () @property(nonatomic, readonly) NSMutableDictionary* pluginPublications; @end @@ -44,6 +39,8 @@ @implementation FlutterEngine { NSString* _dartEntrypoint; NSString* _dartLibrary; + fml::WeakPtr _viewController; + // Channels fml::scoped_nsobject _platformPlugin; fml::scoped_nsobject _textInputPlugin; @@ -62,7 +59,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix andProject:(FlutterDartProje self = [super init]; NSAssert(self, @"Super init cannot be nil"); NSAssert(labelPrefix, @"labelPrefix is required"); - _labelPrefix = labelPrefix; + _labelPrefix = [labelPrefix copy]; if (projectOrNil == nil) _dartProject.reset([[FlutterDartProject alloc] init]); @@ -119,15 +116,16 @@ - (void)dispatchPointerDataPacket:(std::unique_ptr)pac - (void)setViewController:(FlutterViewController*)viewController { FML_DCHECK(self.iosPlatformView); + _viewController = [viewController getWeakPtr]; self.iosPlatformView->SetOwnerViewController(viewController); [self setupPlatformChannel]; } - (FlutterViewController*)getViewController { - if (!self.iosPlatformView) { + if (!_viewController) { return nil; } - return self.iosPlatformView->GetOwnerViewController(); + return _viewController.get(); } - (FlutterPlatformPlugin*)platformPlugin { @@ -206,15 +204,10 @@ - (void)setupChannels { - (void)setupPlatformChannel { if (_shell && self.shell.IsSetup()) { - auto flutterViewController = self.iosPlatformView->GetOwnerViewController(); - if (flutterViewController) { - auto weakPtr = flutterViewController.getWeakPtr; - _platformPlugin.reset([[FlutterPlatformPlugin alloc] initWithViewController:weakPtr]); - } + _platformPlugin.reset([[FlutterPlatformPlugin alloc] initWithViewController:_viewController]); [_platformChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { [_platformPlugin.get() handleMethodCall:call result:result]; }]; - } else { _platformPlugin.reset([[FlutterPlatformPlugin alloc] init]); } @@ -225,13 +218,12 @@ - (void)setupPlatformChannel { return self.shell.Screenshot(type, base64Encode); } -- (void)run { - [self runWithEntrypointAndLibraryUri:_dartEntrypoint libraryUri:_dartLibrary]; +- (void)launchEngine { + // [self runWithEntrypointAndLibraryUri:_dartEntrypoint libraryUri:_dartLibrary]; // Launch the Dart application with the inferred run configuration. - self.shell.GetTaskRunners().GetUITaskRunner()->PostTask(fml::MakeCopyable( - [engine = _shell->GetEngine(), // - config = [_dartProject.get() runConfigurationForEntrypoint:_dartEntrypoint - libraryOrNil:_dartLibrary] // + self.shell.GetTaskRunners().GetUITaskRunner()->PostTask( + fml::MakeCopyable([engine = _shell->GetEngine(), // + config = [_dartProject.get() runConfiguration] // ]() mutable { if (engine) { auto result = engine->Run(std::move(config)); @@ -248,6 +240,8 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin return false; } + static size_t shellCount = 1; + if (!entrypoint) { entrypoint = @"main"; } @@ -258,7 +252,7 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin _dartEntrypoint = entrypoint; _dartLibrary = libraryUri; - const auto threadLabel = CreateShellLabel(_labelPrefix); + const auto threadLabel = [NSString stringWithFormat:@"%@.%zu", _labelPrefix, shellCount++]; auto settings = [_dartProject settings]; // shell::SettingsFromCommandLine(shell::CommandLineFromNSProcessInfo()); @@ -306,6 +300,7 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " << entrypoint.UTF8String; } else { + [self launchEngine]; [self setupChannels]; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 5452a1b9b3588..42123031c6adf 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -45,6 +45,7 @@ - (instancetype)initWithEngine:(FlutterEngine*)engine NSAssert(engine != nil, @"Engine is required"); self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { + _flutterView.reset([[FlutterView alloc] init]); _engine.reset(engine); _weakFactory = std::make_unique>(self); [self performCommonViewControllerInitialization]; @@ -58,9 +59,12 @@ - (instancetype)initWithProject:(FlutterDartProject*)projectOrNil bundle:(NSBundle*)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { + _flutterView.reset([[FlutterView alloc] init]); _weakFactory = std::make_unique>(self); _engine.reset([[FlutterEngine alloc] initWithName:@"io.flutter" andProject:projectOrNil]); [_engine.get() runWithEntrypoint:nil]; + [_engine.get() setViewController:self]; + [self performCommonViewControllerInitialization]; } @@ -87,8 +91,6 @@ - (void)performCommonViewControllerInitialization { _initialized = YES; - _flutterView.reset([[FlutterView alloc] init]); - _orientationPreferences = UIInterfaceOrientationMaskAll; _statusBarStyle = UIStatusBarStyleDefault; @@ -342,7 +344,7 @@ - (void)surfaceUpdated:(BOOL)appeared { - (void)viewWillAppear:(BOOL)animated { TRACE_EVENT0("flutter", "viewWillAppear"); - [_engine.get() run]; + [_engine.get() launchEngine]; // Only recreate surface on subsequent appearances when viewport metrics are known. // First time surface creation is done on viewDidLayoutSubviews. diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 771ce158b5062..bc004d3f71bc7 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -37,12 +37,22 @@ void PlatformViewIOS::SetOwnerViewController(FlutterViewController* owner_controller) { owner_controller_ = owner_controller; - ios_surface_ = static_cast(owner_controller_.view).createSurface; - FML_DCHECK(ios_surface_ != nullptr); - FML_DCHECK(owner_controller_ != nullptr); - - if (accessibility_bridge_) { - accessibility_bridge_.reset(new AccessibilityBridge(static_cast(owner_controller_.view), this)); + if (owner_controller_) { + ios_surface_ = static_cast(owner_controller_.view).createSurface; + FML_DCHECK(ios_surface_ != nullptr); + + if (accessibility_bridge_) { + accessibility_bridge_.reset( + new AccessibilityBridge(static_cast(owner_controller_.view), this)); + } + NotifyCreated(); + + } else { + ios_surface_ = nullptr; + if (accessibility_bridge_) { + accessibility_bridge_.reset(); + } + NotifyDestroyed(); } } @@ -80,8 +90,8 @@ "PlatformViewIOS has no ViewController."; } if (enabled && !accessibility_bridge_) { - accessibility_bridge_ = - std::make_unique(static_cast(owner_controller_.view), this); + accessibility_bridge_ = std::make_unique( + static_cast(owner_controller_.view), this); } else if (!enabled && accessibility_bridge_) { accessibility_bridge_.reset(); } From c7993993b9b23ad0ababe7cabfbc712d5047fb7c Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 3 Oct 2018 23:30:19 -0700 Subject: [PATCH 05/31] retain threads, rework engine/vc for platformplugin --- .../framework/Headers/FlutterViewController.h | 2 + .../ios/framework/Source/FlutterEngine.mm | 78 ++++++++++--------- .../framework/Source/FlutterEngine_Internal.h | 1 + .../framework/Source/FlutterPlatformPlugin.h | 8 +- .../framework/Source/FlutterPlatformPlugin.mm | 20 +++-- .../framework/Source/FlutterViewController.mm | 2 - .../platform/darwin/ios/platform_view_ios.mm | 12 +-- 7 files changed, 69 insertions(+), 54 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index 20b45ba18e38a..4126c3bc2003a 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -21,6 +21,8 @@ FLUTTER_EXPORT @interface FlutterViewController : UIViewController +/** +*/ - (instancetype)initWithEngine:(FlutterEngine*)engine nibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil NS_DESIGNATED_INITIALIZER; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 8de052d9c0386..c37a0eaadbca8 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -36,8 +36,8 @@ @implementation FlutterEngine { fml::scoped_nsobject _dartProject; std::unique_ptr _shell; NSString* _labelPrefix; - NSString* _dartEntrypoint; - NSString* _dartLibrary; + shell::ThreadHost _threadHost; + std::unique_ptr> _weakFactory; fml::WeakPtr _viewController; @@ -61,6 +61,8 @@ - (instancetype)initWithName:(NSString*)labelPrefix andProject:(FlutterDartProje NSAssert(labelPrefix, @"labelPrefix is required"); _labelPrefix = [labelPrefix copy]; + _weakFactory = std::make_unique>(self); + if (projectOrNil == nil) _dartProject.reset([[FlutterDartProject alloc] init]); else @@ -68,6 +70,8 @@ - (instancetype)initWithName:(NSString*)labelPrefix andProject:(FlutterDartProje _pluginPublications = [NSMutableDictionary new]; + [self setupChannels]; + return self; } @@ -81,6 +85,10 @@ - (void)dealloc { return *_shell; } +- (fml::WeakPtr)getWeakPtr { + return _weakFactory->GetWeakPtr(); +} + - (void)updateViewportMetrics:(blink::ViewportMetrics)viewportMetrics { self.shell.GetTaskRunners().GetUITaskRunner()->PostTask( [engine = self.shell.GetEngine(), metrics = viewportMetrics]() { @@ -118,7 +126,7 @@ - (void)setViewController:(FlutterViewController*)viewController { FML_DCHECK(self.iosPlatformView); _viewController = [viewController getWeakPtr]; self.iosPlatformView->SetOwnerViewController(viewController); - [self setupPlatformChannel]; + [self maybeSetupPlatformViewChannels]; } - (FlutterViewController*)getViewController { @@ -192,24 +200,24 @@ - (void)setupChannels { binaryMessenger:self codec:[FlutterJSONMessageCodec sharedInstance]]); - [self setupPlatformChannel]; - _textInputPlugin.reset([[FlutterTextInputPlugin alloc] init]); _textInputPlugin.get().textInputDelegate = self; - [_textInputChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { - [_textInputPlugin.get() handleMethodCall:call result:result]; - }]; - self.iosPlatformView->SetTextInputPlugin(_textInputPlugin); + + _platformPlugin.reset([[FlutterPlatformPlugin alloc] initWithEngine:[self getWeakPtr]]); + + [self maybeSetupPlatformViewChannels]; } -- (void)setupPlatformChannel { +- (void)maybeSetupPlatformViewChannels { if (_shell && self.shell.IsSetup()) { - _platformPlugin.reset([[FlutterPlatformPlugin alloc] initWithViewController:_viewController]); [_platformChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { [_platformPlugin.get() handleMethodCall:call result:result]; }]; - } else { - _platformPlugin.reset([[FlutterPlatformPlugin alloc] init]); + + [_textInputChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + [_textInputPlugin.get() handleMethodCall:call result:result]; + }]; + self.iosPlatformView->SetTextInputPlugin(_textInputPlugin); } } @@ -219,7 +227,6 @@ - (void)setupPlatformChannel { } - (void)launchEngine { - // [self runWithEntrypointAndLibraryUri:_dartEntrypoint libraryUri:_dartLibrary]; // Launch the Dart application with the inferred run configuration. self.shell.GetTaskRunners().GetUITaskRunner()->PostTask( fml::MakeCopyable([engine = _shell->GetEngine(), // @@ -242,39 +249,38 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin static size_t shellCount = 1; - if (!entrypoint) { - entrypoint = @"main"; - } - if (!libraryUri) { - libraryUri = @"main.dart"; + auto config = [_dartProject.get() runConfiguration]; + auto settings = [_dartProject.get() settings]; + + if (libraryUri) { + FML_DCHECK(entrypoint) << "Must specify entrypoint if specifying library"; + config.SetEntrypointAndLibrary(entrypoint.UTF8String, libraryUri.UTF8String); + settings.advisory_script_entrypoint = entrypoint.UTF8String; + settings.advisory_script_uri = libraryUri.UTF8String; + } else if (entrypoint) { + config.SetEntrypoint(std::string(entrypoint.UTF8String)); + settings.advisory_script_entrypoint = entrypoint.UTF8String; + settings.advisory_script_entrypoint = std::string("main.dart"); + } else { + settings.advisory_script_entrypoint = std::string("main"); + settings.advisory_script_entrypoint = std::string("main.dart"); } - _dartEntrypoint = entrypoint; - _dartLibrary = libraryUri; - const auto threadLabel = [NSString stringWithFormat:@"%@.%zu", _labelPrefix, shellCount++]; - auto settings = [_dartProject - settings]; // shell::SettingsFromCommandLine(shell::CommandLineFromNSProcessInfo()); - - // These values set the name of the isolate for debugging. - settings.advisory_script_entrypoint = entrypoint.UTF8String; - settings.advisory_script_uri = libraryUri.UTF8String; - - // The current thread will be used as the platform thread. Ensure that the - // message loop is + // The current thread will be used as the platform thread. Ensure that the message loop is // initialized. fml::MessageLoop::EnsureInitializedForCurrentThread(); - shell::ThreadHost threadHost = { + _threadHost = { threadLabel.UTF8String, // label shell::ThreadHost::Type::UI | shell::ThreadHost::Type::GPU | shell::ThreadHost::Type::IO}; blink::TaskRunners task_runners(threadLabel.UTF8String, // label fml::MessageLoop::GetCurrent().GetTaskRunner(), // platform - threadHost.gpu_thread->GetTaskRunner(), // gpu - threadHost.ui_thread->GetTaskRunner(), // ui - threadHost.io_thread->GetTaskRunner() // io + _threadHost.gpu_thread->GetTaskRunner(), // gpu + _threadHost.ui_thread->GetTaskRunner(), // ui + _threadHost.io_thread->GetTaskRunner() // io ); // Lambda captures by pointers to ObjC objects are fine here because the @@ -300,8 +306,8 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " << entrypoint.UTF8String; } else { + [self maybeSetupPlatformViewChannels]; [self launchEngine]; - [self setupChannels]; } return _shell != nullptr; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h index ad6c5f8cb2271..e691af60c13b3 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h @@ -7,6 +7,7 @@ #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h" +#include "flutter/fml/memory/weak_ptr.h" #include "flutter/fml/task_runner.h" #include "flutter/lib/ui/window/pointer_data_packet.h" #include "flutter/lib/ui/window/viewport_metrics.h" diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h index 543727335a315..23d86c04c299f 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h @@ -7,13 +7,11 @@ #include "flutter/fml/memory/weak_ptr.h" #include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h" - -#include +#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h" @interface FlutterPlatformPlugin : NSObject -- (instancetype)init NS_DESIGNATED_INITIALIZER; -- (instancetype)initWithViewController:(fml::WeakPtr)viewController - NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithEngine:(fml::WeakPtr)engine NS_DESIGNATED_INITIALIZER; - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result; @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm index e646b915c16aa..4ab5e1cd42307 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm @@ -33,18 +33,21 @@ using namespace shell; @implementation FlutterPlatformPlugin { - fml::WeakPtr _viewController; + fml::WeakPtr _engine; } - (instancetype)init { - return [super init]; + @throw([NSException exceptionWithName:@"FlutterPlatformPlugin must initWithEngine" + reason:nil + userInfo:nil]); } -- (instancetype)initWithViewController:(fml::WeakPtr)viewController { +- (instancetype)initWithEngine:(fml::WeakPtr)engine { + FML_DCHECK(engine) << "engine must be set"; self = [super init]; if (self) { - _viewController = viewController; + _engine = engine; } return self; @@ -200,8 +203,13 @@ - (void)popSystemNavigator { UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController; if ([viewController isKindOfClass:[UINavigationController class]]) { [((UINavigationController*)viewController) popViewControllerAnimated:NO]; - } else if (_viewController && viewController != _viewController.get()) { - [_viewController.get() dismissViewControllerAnimated:NO completion:nil]; + [_engine.get() setViewController:nil]; + } else { + auto engineViewController = static_cast([_engine.get() getViewController]); + if (engineViewController != viewController) { + [engineViewController dismissViewControllerAnimated:NO completion:nil]; + [_engine.get() setViewController:nil]; + } } } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 42123031c6adf..e2e8d0b05a275 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -344,8 +344,6 @@ - (void)surfaceUpdated:(BOOL)appeared { - (void)viewWillAppear:(BOOL)animated { TRACE_EVENT0("flutter", "viewWillAppear"); - [_engine.get() launchEngine]; - // Only recreate surface on subsequent appearances when viewport metrics are known. // First time surface creation is done on viewDidLayoutSubviews. if (_viewportMetrics.physical_width) diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index bc004d3f71bc7..0e3bd5649cf51 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -36,6 +36,11 @@ } void PlatformViewIOS::SetOwnerViewController(FlutterViewController* owner_controller) { + if (ios_surface_) { + FML_LOG(WARNING) << "Already had ios_surface when setting owner view controller, tearing down."; + NotifyDestroyed(); + ios_surface_.release(); + } owner_controller_ = owner_controller; if (owner_controller_) { ios_surface_ = static_cast(owner_controller_.view).createSurface; @@ -46,12 +51,9 @@ new AccessibilityBridge(static_cast(owner_controller_.view), this)); } NotifyCreated(); - } else { - ios_surface_ = nullptr; - if (accessibility_bridge_) { - accessibility_bridge_.reset(); - } + ios_surface_.release(); + accessibility_bridge_.release(); NotifyDestroyed(); } } From 6dd1f3e297c15189ac7f771db01d652db40852f1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 4 Oct 2018 00:59:30 -0700 Subject: [PATCH 06/31] cleanup --- .../platform/darwin/ios/framework/Source/FlutterEngine.mm | 2 +- shell/platform/darwin/ios/platform_view_ios.mm | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index c37a0eaadbca8..09e7f9de83996 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -267,7 +267,7 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin } const auto threadLabel = [NSString stringWithFormat:@"%@.%zu", _labelPrefix, shellCount++]; - + FML_DLOG(INFO) << "Creating threadHost for " << threadLabel.UTF8String; // The current thread will be used as the platform thread. Ensure that the message loop is // initialized. fml::MessageLoop::EnsureInitializedForCurrentThread(); diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 0e3bd5649cf51..513570b857528 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -36,10 +36,10 @@ } void PlatformViewIOS::SetOwnerViewController(FlutterViewController* owner_controller) { - if (ios_surface_) { - FML_LOG(WARNING) << "Already had ios_surface when setting owner view controller, tearing down."; + if (ios_surface_ || !owner_controller) { NotifyDestroyed(); ios_surface_.release(); + accessibility_bridge_.release(); } owner_controller_ = owner_controller; if (owner_controller_) { @@ -51,10 +51,6 @@ new AccessibilityBridge(static_cast(owner_controller_.view), this)); } NotifyCreated(); - } else { - ios_surface_.release(); - accessibility_bridge_.release(); - NotifyDestroyed(); } } From 2a5ef8f6c0224be9616fad92027f46837c2bac42 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 4 Oct 2018 22:42:33 -0700 Subject: [PATCH 07/31] Doc updates; WeakPtr update; Create Surface on GPU Thread --- ci/licenses_golden/licenses_flutter | 2 - shell/platform/darwin/ios/BUILD.gn | 2 - .../darwin/ios/framework/Headers/Flutter.h | 7 +- .../framework/Headers/FlutterAppDelegate.h | 6 +- .../Headers/FlutterBinaryMessenger.h | 95 ++-- .../framework/Headers/FlutterCallbackCache.h | 39 +- .../ios/framework/Headers/FlutterChannels.h | 451 +++++++++--------- .../ios/framework/Headers/FlutterCodecs.h | 360 +++++++------- .../framework/Headers/FlutterDartProject.h | 43 +- .../ios/framework/Headers/FlutterEngine.h | 108 ++++- .../Headers/FlutterHeadlessDartRunner.h | 44 +- .../ios/framework/Headers/FlutterMacros.h | 18 +- .../Headers/FlutterNavigationController.h | 9 - .../FlutterPluginAppLifeCycleDelegate.h | 103 ++-- .../framework/Headers/FlutterViewController.h | 118 +++-- .../ios/framework/Source/FlutterEngine.mm | 6 +- .../framework/Source/FlutterEngine_Internal.h | 1 + .../Source/FlutterNavigationController.mm | 14 - .../framework/Source/FlutterViewController.mm | 5 +- .../framework/Source/accessibility_bridge.mm | 2 +- shell/platform/darwin/ios/ios_gl_context.mm | 2 + shell/platform/darwin/ios/platform_view_ios.h | 10 +- .../platform/darwin/ios/platform_view_ios.mm | 24 +- 23 files changed, 780 insertions(+), 689 deletions(-) delete mode 100644 shell/platform/darwin/ios/framework/Headers/FlutterNavigationController.h delete mode 100644 shell/platform/darwin/ios/framework/Source/FlutterNavigationController.mm diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index c378cfba568d2..90228fd9e6169 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -118,13 +118,11 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterBinary FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h -FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterNavigationController.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterChannels.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterCodecs.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm -FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterNavigationController.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterStandardCodec.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterStandardCodec_Internal.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterUmbrellaImport.m diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index ce0b98129db5c..155d5579ffb27 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -29,7 +29,6 @@ _flutter_framework_headers = [ "framework/Headers/FlutterEngine.h", "framework/Headers/FlutterHeadlessDartRunner.h", "framework/Headers/FlutterMacros.h", - "framework/Headers/FlutterNavigationController.h", "framework/Headers/FlutterPlugin.h", "framework/Headers/FlutterPluginAppLifeCycleDelegate.h", "framework/Headers/FlutterTexture.h", @@ -55,7 +54,6 @@ shared_library("create_flutter_framework_dylib") { "framework/Source/FlutterEngine.mm", "framework/Source/FlutterEngine_Internal.h", "framework/Source/FlutterHeadlessDartRunner.mm", - "framework/Source/FlutterNavigationController.mm", "framework/Source/FlutterPlatformPlugin.h", "framework/Source/FlutterPlatformPlugin.mm", "framework/Source/FlutterPluginAppLifeCycleDelegate.mm", diff --git a/shell/platform/darwin/ios/framework/Headers/Flutter.h b/shell/platform/darwin/ios/framework/Headers/Flutter.h index 1e2f9d4d3ade0..dc9fa127f0300 100644 --- a/shell/platform/darwin/ios/framework/Headers/Flutter.h +++ b/shell/platform/darwin/ios/framework/Headers/Flutter.h @@ -8,6 +8,12 @@ /** BREAKING CHANGES: + October 5, 2018: + - Removed FlutterNavigationController.h/.mm + - Changed return signature of `FlutterDartHeadlessCodeRunner.run*` from void to bool + - Removed HeadlessPlatformViewIOS + - Marked FlutterDartHeadlessCodeRunner deprecated + August 31, 2018: Marked -[FlutterDartProject initFromDefaultSourceForConfiguration] and FlutterStandardBigInteger as unavailable. @@ -50,7 +56,6 @@ #include "FlutterEngine.h" #include "FlutterHeadlessDartRunner.h" #include "FlutterMacros.h" -#include "FlutterNavigationController.h" #include "FlutterPlugin.h" #include "FlutterPluginAppLifeCycleDelegate.h" #include "FlutterTexture.h" diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h b/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h index f175ea2925826..8f6f24b654b6b 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h @@ -11,11 +11,11 @@ #include "FlutterPlugin.h" /** - * UIApplicationDelegate subclass for simple apps that want default behavior. + * `UIApplicationDelegate` subclass for simple apps that want default behavior. * - * This class provides the following behaviors: + * This class implements the following behaviors: * * Status bar touches are forwarded to the key window's root view - * FlutterViewController, in order to trigger scroll to top. + * `FlutterViewController`, in order to trigger scroll to top. * * Keeps the Flutter connection open in debug mode when the phone screen * locks. * diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterBinaryMessenger.h b/shell/platform/darwin/ios/framework/Headers/FlutterBinaryMessenger.h index 606c131349cc4..33dfb7bb9abea 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterBinaryMessenger.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterBinaryMessenger.h @@ -11,73 +11,68 @@ NS_ASSUME_NONNULL_BEGIN /** - A message reply callback. - - Used for submitting a binary reply back to a Flutter message sender. Also used - in the dual capacity for handling a binary message reply received from Flutter. - - - Parameters: - - reply: The reply. - */ +* A message reply callback. +* +* Used for submitting a binary reply back to a Flutter message sender. Also used +* in for handling a binary message reply received from Flutter. +* +* @param reply The reply. +*/ typedef void (^FlutterBinaryReply)(NSData* _Nullable reply); /** - A strategy for handling incoming binary messages from Flutter and to send - asynchronous replies back to Flutter. - - - Parameters: - - message: The message. - - reply: A callback for submitting a reply to the sender. - */ +* A strategy for handling incoming binary messages from Flutter and to send +* asynchronous replies back to Flutter. +* +* @param message The message. +* @param reply A callback for submitting an asynchronous reply to the sender. +*/ typedef void (^FlutterBinaryMessageHandler)(NSData* _Nullable message, FlutterBinaryReply reply); /** - A facility for communicating with the Flutter side using asynchronous message - passing with binary messages. - - - SeeAlso: - - `FlutterBasicMessageChannel`, which supports communication using structured - messages. - - `FlutterMethodChannel`, which supports communication using asynchronous - method calls. - - `FlutterEventChannel`, which supports commuication using event streams. - */ +* A facility for communicating with the Flutter side using asynchronous message +* passing with binary messages. +* +* Implementated by: +* - `FlutterBasicMessageChannel`, which supports communication using structured +* messages. +* - `FlutterMethodChannel`, which supports communication using asynchronous +* method calls. +* - `FlutterEventChannel`, which supports commuication using event streams. +*/ FLUTTER_EXPORT @protocol FlutterBinaryMessenger /** - Sends a binary message to the Flutter side on the specified channel, expecting - no reply. - - - Parameters: - - channel: The channel name. - - message: The message. - */ +* Sends a binary message to the Flutter side on the specified channel, expecting +* no reply. +* +* @param channel The channel name. +* @param message The message. +*/ - (void)sendOnChannel:(NSString*)channel message:(NSData* _Nullable)message; /** - Sends a binary message to the Flutter side on the specified channel, expecting - an asynchronous reply. - - - Parameters: - - channel: The channel name. - - message: The message. - - callback: A callback for receiving a reply. - */ +* Sends a binary message to the Flutter side on the specified channel, expecting +* an asynchronous reply. +* +* @param channel The channel name. +* @param message The message. +* @param callback A callback for receiving a reply. +*/ - (void)sendOnChannel:(NSString*)channel message:(NSData* _Nullable)message binaryReply:(FlutterBinaryReply _Nullable)callback; /** - Registers a message handler for incoming binary messages from the Flutter side - on the specified channel. - - Replaces any existing handler. Use a `nil` handler for unregistering the - existing handler. - - - Parameters: - - channel: The channel name. - - handler: The message handler. - */ +* Registers a message handler for incoming binary messages from the Flutter side +* on the specified channel. +* +* Replaces any existing handler. Use a `nil` handler for unregistering the +* existing handler. +* +* @param channel The channel name. +* @param handler The message handler. +*/ - (void)setMessageHandlerOnChannel:(NSString*)channel binaryMessageHandler:(FlutterBinaryMessageHandler _Nullable)handler; @end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h b/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h index 7150838fafbb3..6db9f5753496a 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h @@ -9,27 +9,44 @@ #include "FlutterMacros.h" +/** + * An object containing the result of `FlutterCallbackCache`'s `lookupCallbackInformation` + * method. + */ FLUTTER_EXPORT @interface FlutterCallbackInformation : NSObject +/** + * The name of the callback. + */ @property(retain) NSString* callbackName; +/** + * The class name of the callback. + */ @property(retain) NSString* callbackClassName; +/** + * The library path of the callback. + */ @property(retain) NSString* callbackLibraryPath; @end +/** + * The cache containing callback information for spawning a + * `FlutterHeadlessDartRunner`. + */ FLUTTER_EXPORT @interface FlutterCallbackCache : NSObject /** - Returns the callback information for the given callback handle. - This callback information can be used when spawning a - FlutterHeadlessDartRunner. - - - Parameter handle: The handle for a callback, provided by the - Dart method `PluginUtilities.getCallbackHandle`. - - Returns: A FlutterCallbackInformation object which contains the name of the - callback, the name of the class in which the callback is defined, and the - path of the library which contains the callback. If the provided handle is - invalid, nil is returned. - */ +* Returns the callback information for the given callback handle. +* This callback information can be used when spawning a +* `FlutterHeadlessDartRunner`. +* +* @param handle The handle for a callback, provided by the +* Dart method `PluginUtilities.getCallbackHandle`. +* @return A `FlutterCallbackInformation` object which contains the name of the +* callback, the name of the class in which the callback is defined, and the +* path of the library which contains the callback. If the provided handle is +* invalid, nil is returned. +*/ + (FlutterCallbackInformation*)lookupCallbackInformation:(int64_t)handle; @end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h b/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h index 2e6cf4a4fd825..2b2ee9ec12f6c 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h @@ -10,373 +10,358 @@ NS_ASSUME_NONNULL_BEGIN /** - A message reply callback. - - Used for submitting a reply back to a Flutter message sender. Also used in - the dual capacity for handling a message reply received from Flutter. - - - Parameter reply: The reply. + * A message reply callback. + * + * Used for submitting a reply back to a Flutter message sender. Also used in + * the dual capacity for handling a message reply received from Flutter. + * + * @param reply The reply. */ typedef void (^FlutterReply)(id _Nullable reply); /** - A strategy for handling incoming messages from Flutter and to send - asynchronous replies back to Flutter. - - - Parameters: - - message: The message. - - reply: A callback for submitting a reply to the sender. + * A strategy for handling incoming messages from Flutter and to send + * asynchronous replies back to Flutter. + * + * @param message The message. + * @param reply A callback for submitting a reply to the sender. */ typedef void (^FlutterMessageHandler)(id _Nullable message, FlutterReply callback); /** - A channel for communicating with the Flutter side using basic, asynchronous - message passing. + * A channel for communicating with the Flutter side using basic, asynchronous + * message passing. */ FLUTTER_EXPORT @interface FlutterBasicMessageChannel : NSObject /** - Creates a `FlutterBasicMessageChannel` with the specified name and binary - messenger. - - The channel name logically identifies the channel; identically named channels - interfere with each other's communication. - - The binary messenger is a facility for sending raw, binary messages to the - Flutter side. This protocol is implemented by `FlutterViewController`. - - The channel uses `FlutterStandardMessageCodec` to encode and decode messages. - - - Parameters: - - name: The channel name. - - messenger: The binary messenger. + * Creates a `FlutterBasicMessageChannel` with the specified name and binary + * messenger. + * + * The channel name logically identifies the channel; identically named channels + * interfere with each other's communication. + * + * The binary messenger is a facility for sending raw, binary messages to the + * Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`. + * + * The channel uses `FlutterStandardMessageCodec` to encode and decode messages. + * + * @param name The channel name. + * @param messenger The binary messenger. */ + (instancetype)messageChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger; /** - Creates a `FlutterBasicMessageChannel` with the specified name, binary - messenger, - and message codec. - - The channel name logically identifies the channel; identically named channels - interfere with each other's communication. - - The binary messenger is a facility for sending raw, binary messages to the - Flutter side. This protocol is implemented by `FlutterViewController`. - - - Parameters: - - name: The channel name. - - messenger: The binary messenger. - - codec: The message codec. + * Creates a `FlutterBasicMessageChannel` with the specified name, binary + * messenger, and message codec. + * + * The channel name logically identifies the channel; identically named channels + * interfere with each other's communication. + * + * The binary messenger is a facility for sending raw, binary messages to the + * Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`. + * + * @param name The channel name. + * @param messenger The binary messenger. + * @param codec The message codec. */ + (instancetype)messageChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec; /** - Initializes a `FlutterBasicMessageChannel` with the specified name, binary - messenger, and message codec. - - The channel name logically identifies the channel; identically named channels - interfere with each other's communication. - - The binary messenger is a facility for sending raw, binary messages to the - Flutter side. This protocol is implemented by `FlutterViewController`. - - - Parameters: - - name: The channel name. - - messenger: The binary messenger. - - codec: The message codec. + * Initializes a `FlutterBasicMessageChannel` with the specified name, binary + * messenger, and message codec. + * + * The channel name logically identifies the channel; identically named channels + * interfere with each other's communication. + * + * The binary messenger is a facility for sending raw, binary messages to the + * Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`. + * + * @param name The channel name. + * @param messenger The binary messenger. + * @param codec The message codec. */ - (instancetype)initWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec; /** - Sends the specified message to the Flutter side, ignoring any reply. - - - Parameter message: The message. Must be supported by the codec of this - channel. + * Sends the specified message to the Flutter side, ignoring any reply. + * + * @param message The message. Must be supported by the codec of this + * channel. */ - (void)sendMessage:(id _Nullable)message; /** - Sends the specified message to the Flutter side, expecting an asynchronous - reply. - - - Parameters: - - message: The message. Must be supported by the codec of this channel. - - callback: A callback to be invoked with the message reply from Flutter. + * Sends the specified message to the Flutter side, expecting an asynchronous + * reply. + * + * @param message The message. Must be supported by the codec of this channel. + * @param callback A callback to be invoked with the message reply from Flutter. */ - (void)sendMessage:(id _Nullable)message reply:(FlutterReply _Nullable)callback; /** - Registers a message handler with this channel. - - Replaces any existing handler. Use a `nil` handler for unregistering the - existing handler. - - - Parameter handler: The message handler. + * Registers a message handler with this channel. + * + * Replaces any existing handler. Use a `nil` handler for unregistering the + * existing handler. + * + * @param handler The message handler. */ - (void)setMessageHandler:(FlutterMessageHandler _Nullable)handler; @end /** - A method call result callback. - - Used for submitting a method call result back to a Flutter caller. Also used in - the dual capacity for handling a method call result received from Flutter. - - - Parameter result: The result. + * A method call result callback. + * + * Used for submitting a method call result back to a Flutter caller. Also used in + * the dual capacity for handling a method call result received from Flutter. + * + * @param result The result. */ typedef void (^FlutterResult)(id _Nullable result); /** - A strategy for handling method calls. - - - Parameters: - - call: The incoming method call. - - result: A callback to asynchronously submit the result of the call. - Invoke the callback with a `FlutterError` to indicate that the call failed. - Invoke the callback with `FlutterMethodNotImplemented` to indicate that the - method was unknown. Any other values, including `nil`, are interpreted as - successful results. + * A strategy for handling method calls. + * + * @param call The incoming method call. + * @param result A callback to asynchronously submit the result of the call. + * Invoke the callback with a `FlutterError` to indicate that the call failed. + * Invoke the callback with `FlutterMethodNotImplemented` to indicate that the + * method was unknown. Any other values, including `nil`, are interpreted as + * successful results. */ typedef void (^FlutterMethodCallHandler)(FlutterMethodCall* call, FlutterResult result); /** - A constant used with `FlutterMethodCallHandler` to respond to the call of an - unknown method. + * A constant used with `FlutterMethodCallHandler` to respond to the call of an + * unknown method. */ FLUTTER_EXPORT extern NSObject const* FlutterMethodNotImplemented; /** - A channel for communicating with the Flutter side using invocation of - asynchronous methods. + * A channel for communicating with the Flutter side using invocation of + * asynchronous methods. */ FLUTTER_EXPORT @interface FlutterMethodChannel : NSObject /** - Creates a `FlutterMethodChannel` with the specified name and binary messenger. - - The channel name logically identifies the channel; identically named channels - interfere with each other's communication. - - The binary messenger is a facility for sending raw, binary messages to the - Flutter side. This protocol is implemented by `FlutterViewController`. - - The channel uses `FlutterStandardMethodCodec` to encode and decode method calls - and result envelopes. - - - Parameters: - - name: The channel name. - - messenger: The binary messenger. + * Creates a `FlutterMethodChannel` with the specified name and binary messenger. + * + * The channel name logically identifies the channel; identically named channels + * interfere with each other's communication. + * + * The binary messenger is a facility for sending raw, binary messages to the + * Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`. + * + * The channel uses `FlutterStandardMethodCodec` to encode and decode method calls + * and result envelopes. + * + * @param name The channel name. + * @param messenger The binary messenger. */ + (instancetype)methodChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger; /** - Creates a `FlutterMethodChannel` with the specified name, binary messenger, and - method codec. - - The channel name logically identifies the channel; identically named channels - interfere with each other's communication. - - The binary messenger is a facility for sending raw, binary messages to the - Flutter side. This protocol is implemented by `FlutterViewController`. - - - Parameters: - - name: The channel name. - - messenger: The binary messenger. - - codec: The method codec. + * Creates a `FlutterMethodChannel` with the specified name, binary messenger, and + * method codec. + * + * The channel name logically identifies the channel; identically named channels + * interfere with each other's communication. + * + * The binary messenger is a facility for sending raw, binary messages to the + * Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`. + * + * @param name The channel name. + * @param messenger The binary messenger. + * @param codec The method codec. */ + (instancetype)methodChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec; /** - Initializes a `FlutterMethodChannel` with the specified name, binary messenger, - and method codec. - - The channel name logically identifies the channel; identically named channels - interfere with each other's communication. - - The binary messenger is a facility for sending raw, binary messages to the - Flutter side. This protocol is implemented by `FlutterViewController`. - - - Parameters: - - name: The channel name. - - messenger: The binary messenger. - - codec: The method codec. + * Initializes a `FlutterMethodChannel` with the specified name, binary messenger, + * and method codec. + * + * The channel name logically identifies the channel; identically named channels + * interfere with each other's communication. + * + * The binary messenger is a facility for sending raw, binary messages to the + * Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`. + * + * @param name The channel name. + * @param messenger The binary messenger. + * @param codec The method codec. */ - (instancetype)initWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec; /** - Invokes the specified Flutter method with the specified arguments, expecting - no results. See - [MethodChannel.setMethodCallHandler](https://docs.flutter.io/flutter/services/MethodChannel/setMethodCallHandler.html). - - - Parameters: - - method: The name of the method to invoke. - - arguments: The arguments. Must be a value supported by the codec of this - channel. + * Invokes the specified Flutter method with the specified arguments, expecting + * no results. + * + * @see [MethodChannel.setMethodCallHandler](https://docs.flutter.io/flutter/services/MethodChannel/setMethodCallHandler.html). + * + * @param method The name of the method to invoke. + * @param arguments The arguments. Must be a value supported by the codec of this + * channel. */ - (void)invokeMethod:(NSString*)method arguments:(id _Nullable)arguments; /** - Invokes the specified Flutter method with the specified arguments, expecting - an asynchronous result. - - - Parameters: - - method: The name of the method to invoke. - - arguments: The arguments. Must be a value supported by the codec of this - channel. - - result: A callback that will be invoked with the asynchronous result. - The result will be a `FlutterError` instance, if the method call resulted - in an error on the Flutter side. Will be `FlutterMethodNotImplemented`, if - the method called was not implemented on the Flutter side. Any other value, - including `nil`, should be interpreted as successful results. + * Invokes the specified Flutter method with the specified arguments, expecting + * an asynchronous result. + * + * @param method The name of the method to invoke. + * @param arguments The arguments. Must be a value supported by the codec of this + * channel. + * @param result A callback that will be invoked with the asynchronous result. + * The result will be a `FlutterError` instance, if the method call resulted + * in an error on the Flutter side. Will be `FlutterMethodNotImplemented`, if + * the method called was not implemented on the Flutter side. Any other value, + * including `nil`, should be interpreted as successful results. */ - (void)invokeMethod:(NSString*)method arguments:(id _Nullable)arguments result:(FlutterResult _Nullable)callback; /** - Registers a handler for method calls from the Flutter side. - - Replaces any existing handler. Use a `nil` handler for unregistering the - existing handler. - - - Parameter handler: The method call handler. + * Registers a handler for method calls from the Flutter side. + * + * Replaces any existing handler. Use a `nil` handler for unregistering the + * existing handler. + * + * @param handler The method call handler. */ - (void)setMethodCallHandler:(FlutterMethodCallHandler _Nullable)handler; @end /** - An event sink callback. - - - Parameter event: The event. + * An event sink callback. + * + * @param event The event. */ typedef void (^FlutterEventSink)(id _Nullable event); /** - A strategy for exposing an event stream to the Flutter side. + * A strategy for exposing an event stream to the Flutter side. */ FLUTTER_EXPORT @protocol FlutterStreamHandler /** - Sets up an event stream and begin emitting events. - - Invoked when the first listener is registered with the Stream associated to - this channel on the Flutter side. - - - Parameters: - - arguments: Arguments for the stream. - - events: A callback to asynchronously emit events. Invoke the - callback with a `FlutterError` to emit an error event. Invoke the - callback with `FlutterEndOfEventStream` to indicate that no more - events will be emitted. Any other value, including `nil` are emitted as - successful events. - - Returns: A FlutterError instance, if setup fails. + * Sets up an event stream and begin emitting events. + * + * Invoked when the first listener is registered with the Stream associated to + * this channel on the Flutter side. + * + * @param arguments Arguments for the stream. + * @param events A callback to asynchronously emit events. Invoke the + * callback with a `FlutterError` to emit an error event. Invoke the + * callback with `FlutterEndOfEventStream` to indicate that no more + * events will be emitted. Any other value, including `nil` are emitted as + * successful events. + * @return A FlutterError instance, if setup fails. */ - (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(FlutterEventSink)events; /** - Tears down an event stream. - - Invoked when the last listener is deregistered from the Stream associated to - this channel on the Flutter side. - - The channel implementation may call this method with `nil` arguments - to separate a pair of two consecutive set up requests. Such request pairs - may occur during Flutter hot restart. - - - Parameter arguments: Arguments for the stream. - - Returns: A FlutterError instance, if teardown fails. + * Tears down an event stream. + * + * Invoked when the last listener is deregistered from the Stream associated to + * this channel on the Flutter side. + * + * The channel implementation may call this method with `nil` arguments + * to separate a pair of two consecutive set up requests. Such request pairs + * may occur during Flutter hot restart. + * + * @param arguments Arguments for the stream. + * @return A FlutterError instance, if teardown fails. */ - (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments; @end /** - A constant used with `FlutterEventChannel` to indicate end of stream. + * A constant used with `FlutterEventChannel` to indicate end of stream. */ FLUTTER_EXPORT extern NSObject const* FlutterEndOfEventStream; /** - A channel for communicating with the Flutter side using event streams. + * A channel for communicating with the Flutter side using event streams. */ FLUTTER_EXPORT @interface FlutterEventChannel : NSObject /** - Creates a `FlutterEventChannel` with the specified name and binary messenger. - - The channel name logically identifies the channel; identically named channels - interfere with each other's communication. - - The binary messenger is a facility for sending raw, binary messages to the - Flutter side. This protocol is implemented by `FlutterViewController`. - - The channel uses `FlutterStandardMethodCodec` to decode stream setup and - teardown requests, and to encode event envelopes. - - - Parameters: - - name: The channel name. - - messenger: The binary messenger. - - codec: The method codec. + * Creates a `FlutterEventChannel` with the specified name and binary messenger. + * + * The channel name logically identifies the channel; identically named channels + * interfere with each other's communication. + * + * The binary messenger is a facility for sending raw, binary messages to the + * Flutter side. This protocol is implemented by `FlutterViewController`. + * + * The channel uses `FlutterStandardMethodCodec` to decode stream setup and + * teardown requests, and to encode event envelopes. + * + * @param name The channel name. + * @param messenger The binary messenger. + * @param codec The method codec. */ + (instancetype)eventChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger; /** - Creates a `FlutterEventChannel` with the specified name, binary messenger, - and method codec. - - The channel name logically identifies the channel; identically named channels - interfere with each other's communication. - - The binary messenger is a facility for sending raw, binary messages to the - Flutter side. This protocol is implemented by `FlutterViewController`. - - - Parameters: - - name: The channel name. - - messenger: The binary messenger. - - codec: The method codec. + * Creates a `FlutterEventChannel` with the specified name, binary messenger, + * and method codec. + * + * The channel name logically identifies the channel; identically named channels + * interfere with each other's communication. + * + * The binary messenger is a facility for sending raw, binary messages to the + * Flutter side. This protocol is implemented by `FlutterViewController`. + * + * @param name The channel name. + * @param messenger The binary messenger. + * @param codec The method codec. */ + (instancetype)eventChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec; /** - Initializes a `FlutterEventChannel` with the specified name, binary messenger, - and method codec. - - The channel name logically identifies the channel; identically named channels - interfere with each other's communication. - - The binary messenger is a facility for sending raw, binary messages to the - Flutter side. This protocol is implemented by `FlutterViewController`. - - - Parameters: - - name: The channel name. - - messenger: The binary messenger. - - codec: The method codec. + * Initializes a `FlutterEventChannel` with the specified name, binary messenger, + * and method codec. + * + * The channel name logically identifies the channel; identically named channels + * interfere with each other's communication. + * + * The binary messenger is a facility for sending raw, binary messages to the + * Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`. + * + * @param name The channel name. + * @param messenger The binary messenger. + * @param codec The method codec. */ - (instancetype)initWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec; /** - Registers a handler for stream setup requests from the Flutter side. - - Replaces any existing handler. Use a `nil` handler for unregistering the - existing handler. - - - Parameter handler: The stream handler. + * Registers a handler for stream setup requests from the Flutter side. + * + * Replaces any existing handler. Use a `nil` handler for unregistering the + * existing handler. + * + * @param handler The stream handler. */ - (void)setStreamHandler:(NSObject* _Nullable)handler; @end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h b/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h index 54d7eeca54fda..2f25624203a89 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h @@ -16,76 +16,76 @@ NS_ASSUME_NONNULL_BEGIN FLUTTER_EXPORT @protocol FlutterMessageCodec /** - Returns a shared instance of this `FlutterMessageCodec`. + * Returns a shared instance of this `FlutterMessageCodec`. */ + (instancetype)sharedInstance; /** - Encodes the specified message into binary. - - - Parameter message: The message. - - Returns: The binary encoding, or `nil`, if `message` was `nil`. + * Encodes the specified message into binary. + * + * @param message The message. + * @return The binary encoding, or `nil`, if `message` was `nil`. */ - (NSData* _Nullable)encode:(id _Nullable)message; /** - Decodes the specified message from binary. - - - Parameter message: The message. - - Returns: The decoded message, or `nil`, if `message` was `nil`. + * Decodes the specified message from binary. + * + * @param message The message. + * @return The decoded message, or `nil`, if `message` was `nil`. */ - (id _Nullable)decode:(NSData* _Nullable)message; @end /** - A `FlutterMessageCodec` using unencoded binary messages, represented as - `NSData` instances. - - This codec is guaranteed to be compatible with the corresponding - [BinaryCodec](https://docs.flutter.io/flutter/services/BinaryCodec-class.html) - on the Dart side. These parts of the Flutter SDK are evolved synchronously. - - On the Dart side, messages are represented using `ByteData`. + * A `FlutterMessageCodec` using unencoded binary messages, represented as + * `NSData` instances. + * + * This codec is guaranteed to be compatible with the corresponding + * [BinaryCodec](https://docs.flutter.io/flutter/services/BinaryCodec-class.html) + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + * On the Dart side, messages are represented using `ByteData`. */ FLUTTER_EXPORT -@interface FlutterBinaryCodec : NSObject +@interface FlutterBinaryCodec : NSObject @end /** - A `FlutterMessageCodec` using UTF-8 encoded `NSString` messages. - - This codec is guaranteed to be compatible with the corresponding - [StringCodec](https://docs.flutter.io/flutter/services/StringCodec-class.html) - on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * A `FlutterMessageCodec` using UTF-8 encoded `NSString` messages. + * + * This codec is guaranteed to be compatible with the corresponding + * [StringCodec](https://docs.flutter.io/flutter/services/StringCodec-class.html) + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. */ FLUTTER_EXPORT -@interface FlutterStringCodec : NSObject +@interface FlutterStringCodec : NSObject @end /** - A `FlutterMessageCodec` using UTF-8 encoded JSON messages. - - This codec is guaranteed to be compatible with the corresponding - [JSONMessageCodec](https://docs.flutter.io/flutter/services/JSONMessageCodec-class.html) - on the Dart side. These parts of the Flutter SDK are evolved synchronously. - - Supports values accepted by `NSJSONSerialization` plus top-level - `nil`, `NSNumber`, and `NSString`. - - On the Dart side, JSON messages are handled by the JSON facilities of the - [`dart:convert`](https://api.dartlang.org/stable/dart-convert/JSON-constant.html) - package. + * A `FlutterMessageCodec` using UTF-8 encoded JSON messages. + * + * This codec is guaranteed to be compatible with the corresponding + * [JSONMessageCodec](https://docs.flutter.io/flutter/services/JSONMessageCodec-class.html) + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + * Supports values accepted by `NSJSONSerialization` plus top-level + * `nil`, `NSNumber`, and `NSString`. + * + * On the Dart side, JSON messages are handled by the JSON facilities of the + * [`dart:convert`](https://api.dartlang.org/stable/dart-convert/JSON-constant.html) + * package. */ FLUTTER_EXPORT -@interface FlutterJSONMessageCodec : NSObject +@interface FlutterJSONMessageCodec : NSObject @end /** - A writer of the Flutter standard binary encoding. - - See `FlutterStandardMessageCodec` for details on the encoding. - - The encoding is extensible via subclasses overriding `writeValue`. + * A writer of the Flutter standard binary encoding. + * + * See `FlutterStandardMessageCodec` for details on the encoding. + * + * The encoding is extensible via subclasses overriding `writeValue`. */ FLUTTER_EXPORT @interface FlutterStandardWriter : NSObject @@ -100,11 +100,11 @@ FLUTTER_EXPORT @end /** - A reader of the Flutter standard binary encoding. - - See `FlutterStandardMessageCodec` for details on the encoding. - - The encoding is extensible via subclasses overriding `readValueOfType`. + * A reader of the Flutter standard binary encoding. + * + * See `FlutterStandardMessageCodec` for details on the encoding. + * + * The encoding is extensible via subclasses overriding `readValueOfType`. */ FLUTTER_EXPORT @interface FlutterStandardReader : NSObject @@ -121,8 +121,8 @@ FLUTTER_EXPORT @end /** - A factory of compatible reader/writer instances using the Flutter standard - binary encoding or extensions thereof. + * A factory of compatible reader/writer instances using the Flutter standard + * binary encoding or extensions thereof. */ FLUTTER_EXPORT @interface FlutterStandardReaderWriter : NSObject @@ -131,32 +131,32 @@ FLUTTER_EXPORT @end /** - A `FlutterMessageCodec` using the Flutter standard binary encoding. - - This codec is guaranteed to be compatible with the corresponding - [StandardMessageCodec](https://docs.flutter.io/flutter/services/StandardMessageCodec-class.html) - on the Dart side. These parts of the Flutter SDK are evolved synchronously. - - Supported messages are acyclic values of these forms: - - - `nil` or `NSNull` - - `NSNumber` (including their representation of Boolean values) - - `NSString` - - `FlutterStandardTypedData` - - `NSArray` of supported values - - `NSDictionary` with supported keys and values - - On the Dart side, these values are represented as follows: - - - `nil` or `NSNull`: null - - `NSNumber`: `bool`, `int`, or `double`, depending on the contained value. - - `NSString`: `String` - - `FlutterStandardTypedData`: `Uint8List`, `Int32List`, `Int64List`, or `Float64List` - - `NSArray`: `List` - - `NSDictionary`: `Map` + * A `FlutterMessageCodec` using the Flutter standard binary encoding. + * + * This codec is guaranteed to be compatible with the corresponding + * [StandardMessageCodec](https://docs.flutter.io/flutter/services/StandardMessageCodec-class.html) + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + * Supported messages are acyclic values of these forms: + * + * - `nil` or `NSNull` + * - `NSNumber` (including their representation of Boolean values) + * - `NSString` + * - `FlutterStandardTypedData` + * - `NSArray` of supported values + * - `NSDictionary` with supported keys and values + * + * On the Dart side, these values are represented as follows: + * + * - `nil` or `NSNull`: null + * - `NSNumber`: `bool`, `int`, or `double`, depending on the contained value. + * - `NSString`: `String` + * - `FlutterStandardTypedData`: `Uint8List`, `Int32List`, `Int64List`, or `Float64List` + * - `NSArray`: `List` + * - `NSDictionary`: `Map` */ FLUTTER_EXPORT -@interface FlutterStandardMessageCodec : NSObject +@interface FlutterStandardMessageCodec : NSObject + (instancetype)codecWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter; @end @@ -166,39 +166,37 @@ FLUTTER_EXPORT FLUTTER_EXPORT @interface FlutterMethodCall : NSObject /** - Creates a method call for invoking the specified named method with the - specified arguments. - - - Parameters: - - method: the name of the method to call. - - arguments: the arguments value. + * Creates a method call for invoking the specified named method with the + * specified arguments. + * + * @param method the name of the method to call. + * @param arguments the arguments value. */ + (instancetype)methodCallWithMethodName:(NSString*)method arguments:(id _Nullable)arguments; /** - The method name. + * The method name. */ @property(readonly, nonatomic) NSString* method; /** - The arguments. + * The arguments. */ @property(readonly, nonatomic, nullable) id arguments; @end /** - Error object representing an unsuccessful outcome of invoking a method - on a `FlutterMethodChannel`, or an error event on a `FlutterEventChannel`. + * Error object representing an unsuccessful outcome of invoking a method + * on a `FlutterMethodChannel`, or an error event on a `FlutterEventChannel`. */ FLUTTER_EXPORT @interface FlutterError : NSObject /** - Creates a `FlutterError` with the specified error code, message, and details. - - - Parameters: - - code: An error code string for programmatic use. - - message: A human-readable error message. - - details: Custom error details. + * Creates a `FlutterError` with the specified error code, message, and details. + * + * @param code An error code string for programmatic use. + * @param message A human-readable error message. + * @param details Custom error details. */ + (instancetype)errorWithCode:(NSString*)code message:(NSString* _Nullable)message @@ -220,12 +218,12 @@ FLUTTER_EXPORT @end /** - Type of numeric data items encoded in a `FlutterStandardDataType`. - - - FlutterStandardDataTypeUInt8: plain bytes - - FlutterStandardDataTypeInt32: 32-bit signed integers - - FlutterStandardDataTypeInt64: 64-bit signed integers - - FlutterStandardDataTypeFloat64: 64-bit floats + * Type of numeric data items encoded in a `FlutterStandardDataType`. + * + * - FlutterStandardDataTypeUInt8: plain bytes + * - FlutterStandardDataTypeInt32: 32-bit signed integers + * - FlutterStandardDataTypeInt64: 64-bit signed integers + * - FlutterStandardDataTypeFloat64: 64-bit floats */ typedef NS_ENUM(NSInteger, FlutterStandardDataType) { FlutterStandardDataTypeUInt8, @@ -235,71 +233,71 @@ typedef NS_ENUM(NSInteger, FlutterStandardDataType) { }; /** - A byte buffer holding `UInt8`, `SInt32`, `SInt64`, or `Float64` values, used - with `FlutterStandardMessageCodec` and `FlutterStandardMethodCodec`. - - Two's complement encoding is used for signed integers. IEEE754 - double-precision representation is used for floats. The platform's native - endianness is assumed. + * A byte buffer holding `UInt8`, `SInt32`, `SInt64`, or `Float64` values, used + * with `FlutterStandardMessageCodec` and `FlutterStandardMethodCodec`. + * + * Two's complement encoding is used for signed integers. IEEE754 + * double-precision representation is used for floats. The platform's native + * endianness is assumed. */ FLUTTER_EXPORT @interface FlutterStandardTypedData : NSObject /** - Creates a `FlutterStandardTypedData` which interprets the specified data - as plain bytes. - - - Parameter data: the byte data. + * Creates a `FlutterStandardTypedData` which interprets the specified data + * as plain bytes. + * + * @param data the byte data. */ + (instancetype)typedDataWithBytes:(NSData*)data; /** - Creates a `FlutterStandardTypedData` which interprets the specified data - as 32-bit signed integers. - - - Parameter data: the byte data. The length must be divisible by 4. + * Creates a `FlutterStandardTypedData` which interprets the specified data + * as 32-bit signed integers. + * + * @param data the byte data. The length must be divisible by 4. */ + (instancetype)typedDataWithInt32:(NSData*)data; /** - Creates a `FlutterStandardTypedData` which interprets the specified data - as 64-bit signed integers. - - - Parameter data: the byte data. The length must be divisible by 8. + * Creates a `FlutterStandardTypedData` which interprets the specified data + * as 64-bit signed integers. + * + * @param data the byte data. The length must be divisible by 8. */ + (instancetype)typedDataWithInt64:(NSData*)data; /** - Creates a `FlutterStandardTypedData` which interprets the specified data - as 64-bit floats. - - - Parameter data: the byte data. The length must be divisible by 8. + * Creates a `FlutterStandardTypedData` which interprets the specified data + * as 64-bit floats. + * + * @param data the byte data. The length must be divisible by 8. */ + (instancetype)typedDataWithFloat64:(NSData*)data; /** - The raw underlying data buffer. + * The raw underlying data buffer. */ @property(readonly, nonatomic) NSData* data; /** - The type of the encoded values. + * The type of the encoded values. */ @property(readonly, nonatomic) FlutterStandardDataType type; /** - The number of value items encoded. + * The number of value items encoded. */ @property(readonly, nonatomic) UInt32 elementCount; /** - The number of bytes used by the encoding of a single value item. + * The number of bytes used by the encoding of a single value item. */ @property(readonly, nonatomic) UInt8 elementSize; @end /** - An arbitrarily large integer value, used with `FlutterStandardMessageCodec` - and `FlutterStandardMethodCodec`. + * An arbitrarily large integer value, used with `FlutterStandardMessageCodec` + * and `FlutterStandardMethodCodec`. */ FLUTTER_EXPORT FLUTTER_UNAVAILABLE( @@ -312,100 +310,100 @@ FLUTTER_UNAVAILABLE( @end /** - A codec for method calls and enveloped results. - - Method calls are encoded as binary messages with enough structure that the - codec can extract a method name `NSString` and an arguments `NSObject`, - possibly `nil`. These data items are used to populate a `FlutterMethodCall`. - - Result envelopes are encoded as binary messages with enough structure that - the codec can determine whether the result was successful or an error. In - the former case, the codec can extract the result `NSObject`, possibly `nil`. - In the latter case, the codec can extract an error code `NSString`, a - human-readable `NSString` error message (possibly `nil`), and a custom - error details `NSObject`, possibly `nil`. These data items are used to - populate a `FlutterError`. + * A codec for method calls and enveloped results. + * + * Method calls are encoded as binary messages with enough structure that the + * codec can extract a method name `NSString` and an arguments `NSObject`, + * possibly `nil`. These data items are used to populate a `FlutterMethodCall`. + * + * Result envelopes are encoded as binary messages with enough structure that + * the codec can determine whether the result was successful or an error. In + * the former case, the codec can extract the result `NSObject`, possibly `nil`. + * In the latter case, the codec can extract an error code `NSString`, a + * human-readable `NSString` error message (possibly `nil`), and a custom + * error details `NSObject`, possibly `nil`. These data items are used to + * populate a `FlutterError`. */ FLUTTER_EXPORT @protocol FlutterMethodCodec /** - Provides access to a shared instance this codec. - - - Returns: The shared instance. + * Provides access to a shared instance this codec. + * + * @return The shared instance. */ + (instancetype)sharedInstance; /** - Encodes the specified method call into binary. - - - Parameter methodCall: The method call. The arguments value - must be supported by this codec. - - Returns: The binary encoding. + * Encodes the specified method call into binary. + * + * @param methodCall The method call. The arguments value + * must be supported by this codec. + * @return The binary encoding. */ - (NSData*)encodeMethodCall:(FlutterMethodCall*)methodCall; /** - Decodes the specified method call from binary. - - - Parameter methodCall: The method call to decode. - - Returns: The decoded method call. + * Decodes the specified method call from binary. + * + * @param methodCall The method call to decode. + * @return The decoded method call. */ - (FlutterMethodCall*)decodeMethodCall:(NSData*)methodCall; /** - Encodes the specified successful result into binary. - - - Parameter result: The result. Must be a value supported by this codec. - - Returns: The binary encoding. + * Encodes the specified successful result into binary. + * + * @param result The result. Must be a value supported by this codec. + * @return The binary encoding. */ - (NSData*)encodeSuccessEnvelope:(id _Nullable)result; /** - Encodes the specified error result into binary. - - - Parameter error: The error object. The error details value must be supported - by this codec. - - Returns: The binary encoding. + * Encodes the specified error result into binary. + * + * @param error The error object. The error details value must be supported + * by this codec. + * @return The binary encoding. */ - (NSData*)encodeErrorEnvelope:(FlutterError*)error; /** - Deccodes the specified result envelope from binary. - - - Parameter error: The error object. - - Returns: The result value, if the envelope represented a successful result, - or a `FlutterError` instance, if not. + * Deccodes the specified result envelope from binary. + * + * @param error The error object. + * @return The result value, if the envelope represented a successful result, + * or a `FlutterError` instance, if not. */ - (id _Nullable)decodeEnvelope:(NSData*)envelope; @end /** - A `FlutterMethodCodec` using UTF-8 encoded JSON method calls and result - envelopes. - - This codec is guaranteed to be compatible with the corresponding - [JSONMethodCodec](https://docs.flutter.io/flutter/services/JSONMethodCodec-class.html) - on the Dart side. These parts of the Flutter SDK are evolved synchronously. - - Values supported as methods arguments and result payloads are - those supported as top-level or leaf values by `FlutterJSONMessageCodec`. + * A `FlutterMethodCodec` using UTF-8 encoded JSON method calls and result + * envelopes. + * + * This codec is guaranteed to be compatible with the corresponding + * [JSONMethodCodec](https://docs.flutter.io/flutter/services/JSONMethodCodec-class.html) + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + * Values supported as methods arguments and result payloads are + * those supported as top-level or leaf values by `FlutterJSONMessageCodec`. */ FLUTTER_EXPORT -@interface FlutterJSONMethodCodec : NSObject +@interface FlutterJSONMethodCodec : NSObject @end /** - A `FlutterMethodCodec` using the Flutter standard binary encoding. - - This codec is guaranteed to be compatible with the corresponding - [StandardMethodCodec](https://docs.flutter.io/flutter/services/StandardMethodCodec-class.html) - on the Dart side. These parts of the Flutter SDK are evolved synchronously. - - Values supported as method arguments and result payloads are those supported by - `FlutterStandardMessageCodec`. + * A `FlutterMethodCodec` using the Flutter standard binary encoding. + * + * This codec is guaranteed to be compatible with the corresponding + * [StandardMethodCodec](https://docs.flutter.io/flutter/services/StandardMethodCodec-class.html) + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + * Values supported as method arguments and result payloads are those supported by + * `FlutterStandardMessageCodec`. */ FLUTTER_EXPORT -@interface FlutterStandardMethodCodec : NSObject +@interface FlutterStandardMethodCodec : NSObject + (instancetype)codecWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter; @end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h b/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h index bef67aa04a937..1bf7454301435 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h @@ -9,43 +9,58 @@ #include "FlutterMacros.h" +/** + * A set of Flutter and Dart assets used by a `FlutterEngine` to initialize execution. + */ FLUTTER_EXPORT @interface FlutterDartProject : NSObject +/** + * Initializes with a specific + */ - (instancetype)initWithPrecompiledDartBundle:(NSBundle*)bundle NS_DESIGNATED_INITIALIZER; +/** + * Initializes with a specific set of Flutter Assets, with a specified location of + * main() and Dart packages. + */ - (instancetype)initWithFlutterAssets:(NSURL*)flutterAssetsURL dartMain:(NSURL*)dartMainURL packages:(NSURL*)dartPackages NS_DESIGNATED_INITIALIZER; +/** + * Initializes from a specific set of Flutter Assets. + */ - (instancetype)initWithFlutterAssetsWithScriptSnapshot:(NSURL*)flutterAssetsURL NS_DESIGNATED_INITIALIZER; +/** + * Unavailable - use `init` instead. + */ - (instancetype)initFromDefaultSourceForConfiguration FLUTTER_UNAVAILABLE("Use -init instead."); /** - Returns the file name for the given asset. - The returned file name can be used to access the asset in the application's main bundle. - - - Parameter asset: The name of the asset. The name can be hierarchical. - - Returns: the file name to be used for lookup in the main bundle. + * Returns the file name for the given asset. + * The returned file name can be used to access the asset in the application's main bundle. + * + * @param asset The name of the asset. The name can be hierarchical. + * @return the file name to be used for lookup in the main bundle. */ + (NSString*)lookupKeyForAsset:(NSString*)asset; /** - Returns the file name for the given asset which originates from the specified package. - The returned file name can be used to access the asset in the application's main bundle. - - - Parameters: - - asset: The name of the asset. The name can be hierarchical. - - package: The name of the package from which the asset originates. - - Returns: the file name to be used for lookup in the main bundle. + * Returns the file name for the given asset which originates from the specified package. + * The returned file name can be used to access the asset in the application's main bundle. + * + * @param asset The name of the asset. The name can be hierarchical. + * @param package The name of the package from which the asset originates. + * @return the file name to be used for lookup in the main bundle. */ + (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package; /** - Returns the default identifier for the bundle where we expect to find the Flutter Dart - application. + * Returns the default identifier for the bundle where we expect to find the Flutter Dart + * application. */ + (NSString*)defaultBundleIdentifier; diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 6ed4d3eb3469c..8df23c0b4d651 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -16,47 +16,119 @@ @class FlutterViewController; +/** + * The FlutterEngine class coordinates a single instance of execution for a + * `FlutterDartProject`. It may have one `FlutterViewController` at any given + * time, which can be `-setViewController:` or with `FlutterViewController`'s + * `initWithEngine` initializer. + * + * A FlutterEngine can be created independently of a `FlutterViewController` for + * headless execution. It can also persist across the lifespan of multiple + * `FlutterViewController` instances to maintain state and/or asynchronous tasks + * (such as downloading a large file). Alternatively, you can + */ FLUTTER_EXPORT @interface FlutterEngine : NSObject /** - Iniitalize this FlutterEngine with a FlutterDartProject. -*/ + * Iniitalize this FlutterEngine with a `FlutterDartProject`. + * + * If the FlutterDartProject is not specified, the FlutterEngine will attempt to locate + * the project in a default location. + * + * @param labelPrefix The label prefix used to identify threads for this instance. Should + * be unique across FlutterEngine instances + * @param project The `FlutterDartProject` to run. + */ - (instancetype)initWithName:(NSString*)labelPrefix - andProject:(FlutterDartProject*)projectOrNil NS_DESIGNATED_INITIALIZER; -- (instancetype)init NS_UNAVAILABLE; - -- (void)launchEngine; + project:(FlutterDartProject*)projectOrNil NS_DESIGNATED_INITIALIZER; /** - Runs a Dart function on an Isolate. - The first call will create a new Isolate. Subsequent calls will return - immediately. + * The default initializer is not available for this object. + * Callers must use `-[FlutterEngine initWithName:project:]`. + */ +- (instancetype)init NS_UNAVAILABLE; - - Parameter entrypoint: The name of a top-level function from the same Dart - library that contains the app's main() function. -*/ +/** + * Runs a Dart program on an Isolate. + * + * The first call will create a new Isolate. Subsequent calls will return immediately. + * + * @param entrypoint The name of a top-level function from the same Dart + * library that contains the app's main() function. + * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. + */ - (bool)runWithEntrypoint:(NSString*)entrypoint; /** - Runs a Dart function on an Isolate. - The first call will create a new Isolate. Subsequent calls will return - immediately. - - - Parameter entrypoint: The name of a top-level function from a Dart library. - - Parameter uri: The URI of the Dart library which contains entrypoint. +* Runs a Dart program on an Isolate. +* +* The first call will create a new Isolate. Subsequent calls will return immediately. +* +* @param entrypoint The name of a top-level function from a Dart library. +* @param libraryUri The URI of the Dart library which contains the entrypoint method. +* @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. */ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri; +/** + * Sets the `FlutterViewController` for this instance; callers may pass nil to + * remove the viewController and have the engine run headless in the current process. + * + * A FlutterEngine can only have one `FlutterViewController` at a time. If there is + * already a `FlutterViewController` associated with this instance, this method will replace + * the engine's current viewController with the newly specified one. + * + * @param viewController The `FlutterViewController` (or nil) to set. Kept as a weak reference. + */ - (void)setViewController:(FlutterViewController*)viewController; +/** + * Gets the `FlutterViewController` (may be nil) currently used by this instance. + */ - (FlutterViewController*)getViewController; +/** + * The `FlutterMethodChannel` used for localization related platform messages, such as + * setting the locale. + */ - (FlutterMethodChannel*)localizationChannel; +/** + * The `FlutterMethodChannel` used for navigation related platform messages. + * + * @see [Navigation Channel](https://docs.flutter.io/flutter/services/SystemChannels/navigation-constant.html) + * @see [Navigator Widget](https://docs.flutter.io/flutter/widgets/Navigator-class.html) + */ - (FlutterMethodChannel*)navigationChannel; +/** + * The `FlutterMethodChannel` used for core platform messages, such as + * information about the screen orientation. + */ - (FlutterMethodChannel*)platformChannel; +/** + * The `FlutterMethodChannel` used to communicate text input events to the + * Dart Isolate. + * + * @see [Text Input Channel](https://docs.flutter.io/flutter/services/SystemChannels/textInput-constant.html) + */ - (FlutterMethodChannel*)textInputChannel; +/** + * The `FlutterBasicMessageChannel` used to communicate app lifecycle events + * to the Dart Isolate. + * + * @see [Lifecycle Channel](https://docs.flutter.io/flutter/services/SystemChannels/lifecycle-constant.html) + */ - (FlutterBasicMessageChannel*)lifecycleChannel; +/** + * The `FlutterBasicMessageChannel` used for communicating system events, such as + * memory pressure events. + * + * @see [System Channel](https://docs.flutter.io/flutter/services/SystemChannels/system-constant.html) + */ - (FlutterBasicMessageChannel*)systemChannel; +/** + * The `FlutterBasicMessageChannel` used for communicating user settings such as + * clock format and text scale. + */ - (FlutterBasicMessageChannel*)settingsChannel; @end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h b/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h index f105a75db3535..18ece954b7165 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h @@ -13,42 +13,26 @@ #include "FlutterMacros.h" /** -A callback for when FlutterHeadlessDartRunner has attempted to start a Dart -Isolate in the background. - -- Parameter success: YES if the Isolate was started and run successfully, NO - otherwise. -*/ + * A callback for when FlutterHeadlessDartRunner has attempted to start a Dart + * Isolate in the background. + * + * @param success YES if the Isolate was started and run successfully, NO + * otherwise. + */ typedef void (^FlutterHeadlessDartRunnerCallback)(BOOL success); /** - The FlutterHeadlessDartRunner runs Flutter Dart code with a null rasterizer, - and no native drawing surface. It is appropriate for use in running Dart - code e.g. in the background from a plugin. -*/ + * The FlutterHeadlessDartRunner runs Flutter Dart code with a null rasterizer, + * and no native drawing surface. It is appropriate for use in running Dart + * code e.g. in the background from a plugin. + * + * Most callers should prefer using `FlutterEngine` directly; this interface exists + * for legacy support. + */ FLUTTER_EXPORT +FLUTTER_DEPRECATED("FlutterEngine should be used rather than FlutterHeadlessDartRunner") @interface FlutterHeadlessDartRunner : FlutterEngine -/** - Runs a Dart function on an Isolate that is not the main application's Isolate. - The first call will create a new Isolate. Subsequent calls will return - immediately. - - - Parameter entrypoint: The name of a top-level function from the same Dart - library that contains the app's main() function. -*/ -- (bool)runWithEntrypoint:(NSString*)entrypoint; - -/** - Runs a Dart function on an Isolate that is not the main application's Isolate. - The first call will create a new Isolate. Subsequent calls will return - immediately. - - - Parameter entrypoint: The name of a top-level function from a Dart library. - - Parameter uri: The URI of the Dart library which contains entrypoint. -*/ -- (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri; - @end #endif // FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_ diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterMacros.h b/shell/platform/darwin/ios/framework/Headers/FlutterMacros.h index e3050963192e1..d950856c73c5b 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterMacros.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterMacros.h @@ -21,19 +21,19 @@ #endif // defined(NS_ASSUME_NONNULL_BEGIN) /** - Indicates that the API has been deprecated for the specified reason. Code that - uses the deprecated API will continue to work as before. However, the API will - soon become unavailable and users are encouraged to immediately take the - appropriate action mentioned in the deprecation message and the BREAKING - CHANGES section present in the Flutter.h umbrella header. + * Indicates that the API has been deprecated for the specified reason. Code + * that uses the deprecated API will continue to work as before. However, the + * API will soon become unavailable and users are encouraged to immediately take + * the appropriate action mentioned in the deprecation message and the BREAKING + * CHANGES section present in the Flutter.h umbrella header. */ #define FLUTTER_DEPRECATED(msg) __attribute__((__deprecated__(msg))) /** - Indicates that the previously deprecated API is now unavailable. Code that - uses the API will not work and the declaration of the API is only a stub meant - to display the given message detailing the actions for the user to take - immediately. + * Indicates that the previously deprecated API is now unavailable. Code that + * uses the API will not work and the declaration of the API is only a stub + * meant to display the given message detailing the actions for the user to take + * immediately. */ #define FLUTTER_UNAVAILABLE(msg) __attribute__((__unavailable__(msg))) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterNavigationController.h b/shell/platform/darwin/ios/framework/Headers/FlutterNavigationController.h deleted file mode 100644 index 1ff0911bd685d..0000000000000 --- a/shell/platform/darwin/ios/framework/Headers/FlutterNavigationController.h +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import - -@interface FlutterNavigationController : UINavigationController - -@end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h b/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h index 8c9c0358669ed..aa93e905cb2b9 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h @@ -10,139 +10,140 @@ NS_ASSUME_NONNULL_BEGIN /** - Propagates `UIAppDelegate` callbacks to registered plugins. -*/ + * Propagates `UIAppDelegate` callbacks to registered plugins. + */ FLUTTER_EXPORT @interface FlutterPluginAppLifeCycleDelegate : NSObject /** - Registers `delegate` to receive life cycle callbacks via this FlutterPluginAppLifecycleDelegate as - long as it is alive. - - `delegate` will only referenced weakly. -*/ + * Registers `delegate` to receive life cycle callbacks via this FlutterPluginAppLifecycleDelegate + * as long as it is alive. + * + * `delegate` will only referenced weakly. + */ - (void)addDelegate:(NSObject*)delegate; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks. - - - Returns: `NO` if any plugin vetoes application launch. + * Calls all plugins registered for `UIApplicationDelegate` callbacks. + * + * @return `NO` if any plugin vetoes application launch. */ - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks. - - - Returns: `NO` if any plugin vetoes application launch. + * Calls all plugins registered for `UIApplicationDelegate` callbacks. + * + * @return `NO` if any plugin vetoes application launch. */ - (BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary*)launchOptions; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks. + * Calls all plugins registered for `UIApplicationDelegate` callbacks. */ - (void)applicationDidBecomeActive:(UIApplication*)application; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks. + * Calls all plugins registered for `UIApplicationDelegate` callbacks. */ - (void)applicationWillResignActive:(UIApplication*)application; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks. + * Calls all plugins registered for `UIApplicationDelegate` callbacks. */ - (void)applicationDidEnterBackground:(UIApplication*)application; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks. + * Calls all plugins registered for `UIApplicationDelegate` callbacks. */ - (void)applicationWillEnterForeground:(UIApplication*)application; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks. + * Calls all plugins registered for `UIApplicationDelegate` callbacks. */ - (void)applicationWillTerminate:(UIApplication*)application; /** - Called if this plugin has been registered for `UIApplicationDelegate` callbacks. + * Called if this plugin has been registered for `UIApplicationDelegate` callbacks. */ - (void)application:(UIApplication*)application didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks. + * Calls all plugins registered for `UIApplicationDelegate` callbacks. */ - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks. + * Calls all plugins registered for `UIApplicationDelegate` callbacks. */ - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until - some plugin handles the request. - - - Returns: `YES` if any plugin handles the request. -*/ + * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until + * some plugin handles the request. + * + * @return `YES` if any plugin handles the request. + */ - (BOOL)application:(UIApplication*)application openURL:(NSURL*)url options:(NSDictionary*)options; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until - some plugin handles the request. - - - Returns: `YES` if any plugin handles the request. + * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until + * some plugin handles the request. + * + * @return `YES` if any plugin handles the request. */ - (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until - some plugin handles the request. - - - Returns: `YES` if any plugin handles the request. -*/ + * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until + * some plugin handles the request. + * + * @return `YES` if any plugin handles the request. + */ - (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks. -*/ + * Calls all plugins registered for `UIApplicationDelegate` callbacks. + */ - (void)application:(UIApplication*)application performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem completionHandler:(void (^)(BOOL succeeded))completionHandler API_AVAILABLE(ios(9.0)); /** - Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until - some plugin handles the request. - - - Returns: `YES` if any plugin handles the request. -*/ + * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until + * some plugin handles the request. + * + * @return `YES` if any plugin handles the request. + */ - (BOOL)application:(UIApplication*)application handleEventsForBackgroundURLSession:(nonnull NSString*)identifier completionHandler:(nonnull void (^)(void))completionHandler; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until - some plugin handles the request. - - - Returns: `YES` if any plugin handles the request. -*/ + * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until + * some plugin handles the request. + * + * @returns `YES` if any plugin handles the request. + */ - (BOOL)application:(UIApplication*)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler; /** - Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until - some plugin handles the request. - - Returns: `YES` if any plugin handles the request. -*/ + * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until + * some plugin handles the request. + * + * @return `YES` if any plugin handles the request. + */ - (BOOL)application:(UIApplication*)application continueUserActivity:(NSUserActivity*)userActivity restorationHandler:(void (^)(NSArray*))restorationHandler; diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index 4126c3bc2003a..b26075f63de79 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -17,16 +17,45 @@ @class FlutterEngine; +/** + * A `UIViewController` implementation for Flutter views. + * + * Dart execution, channel communication, texture registration, and plugin registration + * are all handled by `FlutterEngine`. Calls on this class to those members all proxy + * through to the `FlutterEngine` that manages this FlutterViewController. + * + * A FlutterViewController can be initialized either with an already-running `FlutterEngine`, + * or it can be initialized with a `FlutterDartProject` that will be used to spin up + * a new `FlutterEngine`. Developers looking to present and hide FlutterViewControllers + * in native iOS applications will usually want to maintain the `FlutterEngine` instance + * so as not to lose state or asynchronous tasks when navigating back and forth between a + * FlutterViewController and other `UIViewController`s. + */ FLUTTER_EXPORT @interface FlutterViewController - : UIViewController + : UIViewController /** -*/ + * Initializes this FlutterViewController with the specified `FlutterEngine`. + * + * The initialized viewcontroller will attach itself to the engine as part of this process. + * + * @param engine The `FlutterEngine` instance to attach to. + * @param nibName The NIB name to initialize this UIViewController with. + * @param bundle The NIB bundle + */ - (instancetype)initWithEngine:(FlutterEngine*)engine nibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil NS_DESIGNATED_INITIALIZER; +/** + * Initializes a new FlutterViewController and `FlutterEngine` with the specified + * `FlutterDartProject`. + * + * @param projectOrNil The `FlutterDartProject` to initialize the `FlutterEngine` with. + * @param nibName The NIB name to initialize this UIViewController with. + * @param bundle The NIB bundle + */ - (instancetype)initWithProject:(FlutterDartProject*)projectOrNil nibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil NS_DESIGNATED_INITIALIZER; @@ -34,71 +63,70 @@ FLUTTER_EXPORT - (void)handleStatusBarTouches:(UIEvent*)event; /** - Returns the file name for the given asset. - The returned file name can be used to access the asset in the application's - main bundle. - - - Parameter asset: The name of the asset. The name can be hierarchical. - - Returns: the file name to be used for lookup in the main bundle. + * Returns the file name for the given asset. + * The returned file name can be used to access the asset in the application's + * main bundle. + * + * @param asset The name of the asset. The name can be hierarchical. + * @return The file name to be used for lookup in the main bundle. */ - (NSString*)lookupKeyForAsset:(NSString*)asset; /** - Returns the file name for the given asset which originates from the specified - package. - The returned file name can be used to access the asset in the application's - main bundle. - - - Parameters: - - asset: The name of the asset. The name can be hierarchical. - - package: The name of the package from which the asset originates. - - Returns: the file name to be used for lookup in the main bundle. + * Returns the file name for the given asset which originates from the specified + * package. + * The returned file name can be used to access the asset in the application's + * main bundle. + * + * @param asset The name of the asset. The name can be hierarchical. + * @param package The name of the package from which the asset originates. + * @returns: The file name to be used for lookup in the main bundle. */ - (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package; /** - Sets the first route that the Flutter app shows. The default is "/". - This method will guarnatee that the initial route is delivered, even if the - Flutter window hasn't been created yet when called. It cannot be used to update - the current route being shown in a visible FlutterViewController (see pushRoute - and popRoute). - - - Parameter route: The name of the first route to show. + * Sets the first route that the Flutter app shows. The default is "/". + * This method will guarnatee that the initial route is delivered, even if the + * Flutter window hasn't been created yet when called. It cannot be used to update + * the current route being shown in a visible FlutterViewController (see pushRoute + * and popRoute). + * + * @param route The name of the first route to show. */ - (void)setInitialRoute:(NSString*)route; /** - Instructs the Flutter Navigator (if any) to go back. + * Instructs the Flutter Navigator (if any) to go back. */ - (void)popRoute; /** - Instructs the Flutter Navigator (if any) to push a route on to the navigation - stack. The setInitialRoute method should be prefered if this is called before the - FlutterViewController has come into view. - - - Parameter route: The name of the route to push to the navigation stack. + * Instructs the Flutter Navigator (if any) to push a route on to the navigation + * stack. The setInitialRoute method should be prefered if this is called before the + * FlutterViewController has come into view. + * + * @param route The name of the route to push to the navigation stack. */ - (void)pushRoute:(NSString*)route; +/** + * The `FlutterPluginRegistry` used by this FlutterViewController. + */ - (id)pluginRegistry; /** - Specifies the view to use as a splash screen. Flutter's rendering is - asynchronous, so the first - frame rendered by the Flutter application might not immediately appear when the - Flutter view is - initially placed in the view hierarchy. The splash screen view will be used as - a replacement - until the first frame is rendered. - - The view used should be appropriate for multiple sizes; an autoresizing mask to - have a flexible - width and height will be applied automatically. - - If not specified, uses a view generated from `UILaunchStoryboardName` from the - main bundle's - `Info.plist` file. + * Specifies the view to use as a splash screen. Flutter's rendering is asynchronous, so the first + * frame rendered by the Flutter application might not immediately appear when theFlutter view is + * initially placed in the view hierarchy. The splash screen view will be used as + * a replacement until the first frame is rendered. + * + * The view used should be appropriate for multiple sizes; an autoresizing mask to + * have a flexible + * width and height will be applied automatically. + * + * If not specified, uses a view generated from `UILaunchStoryboardName` from the + * main bundle's + * `Info.plist` file. */ @property(strong, nonatomic) UIView* splashScreenView; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 09e7f9de83996..ecf7ef102bfda 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -34,9 +34,9 @@ - (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine @implementation FlutterEngine { fml::scoped_nsobject _dartProject; + shell::ThreadHost _threadHost; std::unique_ptr _shell; NSString* _labelPrefix; - shell::ThreadHost _threadHost; std::unique_ptr> _weakFactory; fml::WeakPtr _viewController; @@ -55,7 +55,7 @@ @implementation FlutterEngine { int64_t _nextTextureId; } -- (instancetype)initWithName:(NSString*)labelPrefix andProject:(FlutterDartProject*)projectOrNil { +- (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)projectOrNil { self = [super init]; NSAssert(self, @"Super init cannot be nil"); NSAssert(labelPrefix, @"labelPrefix is required"); @@ -125,7 +125,7 @@ - (void)dispatchPointerDataPacket:(std::unique_ptr)pac - (void)setViewController:(FlutterViewController*)viewController { FML_DCHECK(self.iosPlatformView); _viewController = [viewController getWeakPtr]; - self.iosPlatformView->SetOwnerViewController(viewController); + self.iosPlatformView->SetOwnerViewController(_viewController); [self maybeSetupPlatformViewChannels]; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h index e691af60c13b3..684da45973fb8 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h @@ -38,6 +38,7 @@ - (FlutterPlatformPlugin*)platformPlugin; - (FlutterTextInputPlugin*)textInputPlugin; +- (void)launchEngine; @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterNavigationController.mm b/shell/platform/darwin/ios/framework/Source/FlutterNavigationController.mm deleted file mode 100644 index 2ca2978a548f1..0000000000000 --- a/shell/platform/darwin/ios/framework/Source/FlutterNavigationController.mm +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterNavigationController.h" - -@implementation FlutterNavigationController - -- (void)viewWillAppear:(BOOL)animated { - [self setNavigationBarHidden:YES]; - [super viewWillAppear:animated]; -} - -@end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index e2e8d0b05a275..32cb8b1bf02f9 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -46,9 +46,10 @@ - (instancetype)initWithEngine:(FlutterEngine*)engine self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { _flutterView.reset([[FlutterView alloc] init]); - _engine.reset(engine); + _engine.reset([engine retain]); _weakFactory = std::make_unique>(self); [self performCommonViewControllerInitialization]; + [engine setViewController:self]; } return self; @@ -61,7 +62,7 @@ - (instancetype)initWithProject:(FlutterDartProject*)projectOrNil if (self) { _flutterView.reset([[FlutterView alloc] init]); _weakFactory = std::make_unique>(self); - _engine.reset([[FlutterEngine alloc] initWithName:@"io.flutter" andProject:projectOrNil]); + _engine.reset([[FlutterEngine alloc] initWithName:@"io.flutter" project:projectOrNil]); [_engine.get() runWithEntrypoint:nil]; [_engine.get() setViewController:self]; diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm index 6b60bc6b3ba68..a4682a36f14eb 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm @@ -498,7 +498,7 @@ - (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction { previous_routes_({}) { accessibility_channel_.reset([[FlutterBasicMessageChannel alloc] initWithName:@"flutter/accessibility" - binaryMessenger:platform_view->GetOwnerViewController() + binaryMessenger:platform_view->GetOwnerViewController().get() codec:[FlutterStandardMessageCodec sharedInstance]]); [accessibility_channel_.get() setMessageHandler:^(id message, FlutterReply reply) { HandleEvent((NSDictionary*)message); diff --git a/shell/platform/darwin/ios/ios_gl_context.mm b/shell/platform/darwin/ios/ios_gl_context.mm index 765e3c3650589..b3debd6f64372 100644 --- a/shell/platform/darwin/ios/ios_gl_context.mm +++ b/shell/platform/darwin/ios/ios_gl_context.mm @@ -127,6 +127,8 @@ TRACE_EVENT_INSTANT0("flutter", "IOSGLContext::UpdateStorageSizeIfNecessary"); FML_DLOG(INFO) << "Updating render buffer storage size."; + FML_DCHECK(glGetError() == GL_NO_ERROR); + if (![EAGLContext setCurrentContext:context_]) { return false; } diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index b188c993421f3..6e8e37184162a 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -32,8 +32,9 @@ class PlatformViewIOS final : public PlatformView { PlatformMessageRouter& GetPlatformMessageRouter(); - FlutterViewController* GetOwnerViewController() const; - void SetOwnerViewController(FlutterViewController* owner_controller); + fml::WeakPtr GetOwnerViewController() const; + void SetOwnerViewController( + fml::WeakPtr owner_controller); void RegisterExternalTexture(int64_t id, NSObject* texture); @@ -43,7 +44,7 @@ class PlatformViewIOS final : public PlatformView { fml::scoped_nsprotocol plugin); private: - FlutterViewController* owner_controller_; // weak reference. + fml::WeakPtr owner_controller_; std::unique_ptr ios_surface_; PlatformMessageRouter platform_message_router_; std::unique_ptr accessibility_bridge_; @@ -51,7 +52,8 @@ class PlatformViewIOS final : public PlatformView { fml::closure firstFrameCallback_; // |shell::PlatformView| - void HandlePlatformMessage(fml::RefPtr message) override; + void HandlePlatformMessage( + fml::RefPtr message) override; // |shell::PlatformView| std::unique_ptr CreateRenderingSurface() override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 513570b857528..ac12b894e96d2 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -31,11 +31,11 @@ platform_message_router_.HandlePlatformMessage(std::move(message)); } -FlutterViewController* PlatformViewIOS::GetOwnerViewController() const { +fml::WeakPtr PlatformViewIOS::GetOwnerViewController() const { return owner_controller_; } -void PlatformViewIOS::SetOwnerViewController(FlutterViewController* owner_controller) { +void PlatformViewIOS::SetOwnerViewController(fml::WeakPtr owner_controller) { if (ios_surface_ || !owner_controller) { NotifyDestroyed(); ios_surface_.release(); @@ -43,12 +43,12 @@ } owner_controller_ = owner_controller; if (owner_controller_) { - ios_surface_ = static_cast(owner_controller_.view).createSurface; + ios_surface_ = static_cast(owner_controller_.get().view).createSurface; FML_DCHECK(ios_surface_ != nullptr); if (accessibility_bridge_) { accessibility_bridge_.reset( - new AccessibilityBridge(static_cast(owner_controller_.view), this)); + new AccessibilityBridge(static_cast(owner_controller_.get().view), this)); } NotifyCreated(); } @@ -66,7 +66,19 @@ "has no ViewController."; return nullptr; } - return ios_surface_->CreateGPUSurface(); + + fml::AutoResetWaitableEvent latch; + std::unique_ptr surface; + auto gpu_task = [ios_surface = ios_surface_.get(), &surface, &latch]() { + if (ios_surface) { + surface = ios_surface->CreateGPUSurface(); + } + latch.Signal(); + }; + + fml::TaskRunner::RunNowOrPostTask(task_runners_.GetGPUTaskRunner(), gpu_task); + latch.Wait(); + return surface; } // |shell::PlatformView| @@ -89,7 +101,7 @@ } if (enabled && !accessibility_bridge_) { accessibility_bridge_ = std::make_unique( - static_cast(owner_controller_.view), this); + static_cast(owner_controller_.get().view), this); } else if (!enabled && accessibility_bridge_) { accessibility_bridge_.reset(); } From 3a3cdde672339a23ecb1d293be22b8bb210e651e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 4 Oct 2018 22:50:23 -0700 Subject: [PATCH 08/31] remove file from licenses --- ci/licenses_golden/licenses_flutter | 1 - 1 file changed, 1 deletion(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 491a80e996cb8..044a5e07fe01a 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -585,7 +585,6 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterCallbac FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.mm -FILE: ../../../flutter/shell/platform/darwin/ios/headless_platform_view_ios.h ---------------------------------------------------------------------------------------------------- Copyright 2018 The Chromium Authors. All rights reserved. From aeaa6aa24bbebc95fe640105ce7a1b13be01ae15 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 4 Oct 2018 22:59:53 -0700 Subject: [PATCH 09/31] Finish missing doc on FlutterEngine --- .../platform/darwin/ios/framework/Headers/FlutterEngine.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 8df23c0b4d651..b6817c76ea1a6 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -25,7 +25,12 @@ * A FlutterEngine can be created independently of a `FlutterViewController` for * headless execution. It can also persist across the lifespan of multiple * `FlutterViewController` instances to maintain state and/or asynchronous tasks - * (such as downloading a large file). Alternatively, you can + * (such as downloading a large file). + * + * Alternatively, you can simply create a new `FlutterViewController` with only a + * `FlutterDartProject`. That `FlutterViewController` will internally manage its + * own instance of a FlutterEngine, but will not guarantee survival of the engine + * beyond the life of the ViewController. */ FLUTTER_EXPORT @interface FlutterEngine From 10d1dbc93e34be064b05a018e130db1ce8cfb4d3 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Oct 2018 09:04:14 -0700 Subject: [PATCH 10/31] remove unused code, merge-o --- .../ios/framework/Source/FlutterEngine.mm | 1 - .../Source/FlutterHeadlessDartRunner.mm | 32 ------------------- 2 files changed, 33 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index ecf7ef102bfda..7354fc4e295c4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -20,7 +20,6 @@ #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h" #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/flutter_touch_mapper.h" #include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" diff --git a/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm b/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm index 5d0866dbe7332..64ca7dde4c346 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm @@ -27,36 +27,4 @@ @implementation FlutterHeadlessDartRunner { } -- (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri { - bool shellCreated = [super runWithEntrypointAndLibraryUri:entrypoint libraryUri:uri]; - if (!shellCreated || entrypoint.length == 0) { - FML_LOG(ERROR) - << "FlutterHeadlessDartRunner requires on proper setup of shell and a valid entrypoint."; - return false; - } - - FlutterDartProject* project = [[[FlutterDartProject alloc] init] autorelease]; - - auto config = project.runConfiguration; - config.SetEntrypointAndLibrary(entrypoint.UTF8String, uri.UTF8String); - - // Override the default run configuration with the specified entrypoint. - self.shell.GetTaskRunners().GetUITaskRunner()->PostTask( - fml::MakeCopyable([engine = self.shell.GetEngine(), config = std::move(config)]() mutable { - BOOL success = NO; - FML_LOG(INFO) << "Attempting to launch background engine configuration..."; - if (!engine || engine->Run(std::move(config)) == shell::Engine::RunStatus::Failure) { - FML_LOG(ERROR) << "Could not launch engine with configuration."; - } else { - FML_LOG(INFO) << "Background Isolate successfully started and run."; - success = YES; - } - })); - return true; -} - -- (bool)runWithEntrypoint:(NSString*)entrypoint { - return [self runWithEntrypointAndLibraryUri:entrypoint libraryUri:nil]; -} - @end From 1fe3af84e56e3a7d739584ec3c527b33070caae8 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Oct 2018 09:11:34 -0700 Subject: [PATCH 11/31] format --- .../darwin/ios/framework/Headers/Flutter.h | 5 +- .../framework/Headers/FlutterAppDelegate.h | 3 +- .../Headers/FlutterBinaryMessenger.h | 92 +++++++++---------- .../framework/Headers/FlutterCallbackCache.h | 22 ++--- .../ios/framework/Headers/FlutterChannels.h | 4 +- .../ios/framework/Headers/FlutterCodecs.h | 23 +++-- .../framework/Headers/FlutterDartProject.h | 2 +- .../ios/framework/Headers/FlutterEngine.h | 54 ++++++----- .../ios/framework/Headers/FlutterTexture.h | 4 +- .../framework/Headers/FlutterViewController.h | 4 +- .../ios/framework/Source/FlutterChannels.mm | 22 ++--- .../Source/FlutterDartProject_Internal.h | 2 +- .../Source/FlutterTextInputDelegate.h | 2 +- .../framework/Source/FlutterTextInputPlugin.h | 2 +- .../framework/Source/accessibility_bridge.mm | 14 +-- .../Source/accessibility_text_entry.h | 4 +- .../Source/accessibility_text_entry.mm | 9 +- .../Source/flutter_codecs_unittest.mm | 2 +- .../darwin/ios/ios_external_texture_gl.h | 7 +- .../darwin/ios/ios_surface_software.h | 3 +- shell/platform/darwin/ios/platform_view_ios.h | 17 ++-- .../platform/darwin/ios/platform_view_ios.mm | 2 +- 22 files changed, 149 insertions(+), 150 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/Flutter.h b/shell/platform/darwin/ios/framework/Headers/Flutter.h index dc9fa127f0300..da3c1b1914c03 100644 --- a/shell/platform/darwin/ios/framework/Headers/Flutter.h +++ b/shell/platform/darwin/ios/framework/Headers/Flutter.h @@ -10,10 +10,11 @@ October 5, 2018: - Removed FlutterNavigationController.h/.mm - - Changed return signature of `FlutterDartHeadlessCodeRunner.run*` from void to bool + - Changed return signature of `FlutterDartHeadlessCodeRunner.run*` from void + to bool - Removed HeadlessPlatformViewIOS - Marked FlutterDartHeadlessCodeRunner deprecated - + August 31, 2018: Marked -[FlutterDartProject initFromDefaultSourceForConfiguration] and FlutterStandardBigInteger as unavailable. diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h b/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h index 8f6f24b654b6b..05c934b072c72 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h @@ -24,7 +24,8 @@ * code as necessary from FlutterAppDelegate.mm. */ FLUTTER_EXPORT -@interface FlutterAppDelegate : UIResponder +@interface FlutterAppDelegate + : UIResponder @property(strong, nonatomic) UIWindow* window; diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterBinaryMessenger.h b/shell/platform/darwin/ios/framework/Headers/FlutterBinaryMessenger.h index 33dfb7bb9abea..341aae91cdc5f 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterBinaryMessenger.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterBinaryMessenger.h @@ -11,68 +11,68 @@ NS_ASSUME_NONNULL_BEGIN /** -* A message reply callback. -* -* Used for submitting a binary reply back to a Flutter message sender. Also used -* in for handling a binary message reply received from Flutter. -* -* @param reply The reply. -*/ + * A message reply callback. + * + * Used for submitting a binary reply back to a Flutter message sender. Also used + * in for handling a binary message reply received from Flutter. + * + * @param reply The reply. + */ typedef void (^FlutterBinaryReply)(NSData* _Nullable reply); /** -* A strategy for handling incoming binary messages from Flutter and to send -* asynchronous replies back to Flutter. -* -* @param message The message. -* @param reply A callback for submitting an asynchronous reply to the sender. -*/ + * A strategy for handling incoming binary messages from Flutter and to send + * asynchronous replies back to Flutter. + * + * @param message The message. + * @param reply A callback for submitting an asynchronous reply to the sender. + */ typedef void (^FlutterBinaryMessageHandler)(NSData* _Nullable message, FlutterBinaryReply reply); /** -* A facility for communicating with the Flutter side using asynchronous message -* passing with binary messages. -* -* Implementated by: -* - `FlutterBasicMessageChannel`, which supports communication using structured -* messages. -* - `FlutterMethodChannel`, which supports communication using asynchronous -* method calls. -* - `FlutterEventChannel`, which supports commuication using event streams. -*/ + * A facility for communicating with the Flutter side using asynchronous message + * passing with binary messages. + * + * Implementated by: + * - `FlutterBasicMessageChannel`, which supports communication using structured + * messages. + * - `FlutterMethodChannel`, which supports communication using asynchronous + * method calls. + * - `FlutterEventChannel`, which supports commuication using event streams. + */ FLUTTER_EXPORT -@protocol FlutterBinaryMessenger +@protocol FlutterBinaryMessenger /** -* Sends a binary message to the Flutter side on the specified channel, expecting -* no reply. -* -* @param channel The channel name. -* @param message The message. -*/ + * Sends a binary message to the Flutter side on the specified channel, expecting + * no reply. + * + * @param channel The channel name. + * @param message The message. + */ - (void)sendOnChannel:(NSString*)channel message:(NSData* _Nullable)message; /** -* Sends a binary message to the Flutter side on the specified channel, expecting -* an asynchronous reply. -* -* @param channel The channel name. -* @param message The message. -* @param callback A callback for receiving a reply. -*/ + * Sends a binary message to the Flutter side on the specified channel, expecting + * an asynchronous reply. + * + * @param channel The channel name. + * @param message The message. + * @param callback A callback for receiving a reply. + */ - (void)sendOnChannel:(NSString*)channel message:(NSData* _Nullable)message binaryReply:(FlutterBinaryReply _Nullable)callback; /** -* Registers a message handler for incoming binary messages from the Flutter side -* on the specified channel. -* -* Replaces any existing handler. Use a `nil` handler for unregistering the -* existing handler. -* -* @param channel The channel name. -* @param handler The message handler. -*/ + * Registers a message handler for incoming binary messages from the Flutter side + * on the specified channel. + * + * Replaces any existing handler. Use a `nil` handler for unregistering the + * existing handler. + * + * @param channel The channel name. + * @param handler The message handler. + */ - (void)setMessageHandlerOnChannel:(NSString*)channel binaryMessageHandler:(FlutterBinaryMessageHandler _Nullable)handler; @end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h b/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h index 6db9f5753496a..8931d7e7b19fc 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h @@ -36,17 +36,17 @@ FLUTTER_EXPORT FLUTTER_EXPORT @interface FlutterCallbackCache : NSObject /** -* Returns the callback information for the given callback handle. -* This callback information can be used when spawning a -* `FlutterHeadlessDartRunner`. -* -* @param handle The handle for a callback, provided by the -* Dart method `PluginUtilities.getCallbackHandle`. -* @return A `FlutterCallbackInformation` object which contains the name of the -* callback, the name of the class in which the callback is defined, and the -* path of the library which contains the callback. If the provided handle is -* invalid, nil is returned. -*/ + * Returns the callback information for the given callback handle. + * This callback information can be used when spawning a + * `FlutterHeadlessDartRunner`. + * + * @param handle The handle for a callback, provided by the + * Dart method `PluginUtilities.getCallbackHandle`. + * @return A `FlutterCallbackInformation` object which contains the name of the + * callback, the name of the class in which the callback is defined, and the + * path of the library which contains the callback. If the provided handle is + * invalid, nil is returned. + */ + (FlutterCallbackInformation*)lookupCallbackInformation:(int64_t)handle; @end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h b/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h index 2b2ee9ec12f6c..bd80d6426377e 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h @@ -205,16 +205,18 @@ FLUTTER_EXPORT binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec; +// clang-format off /** * Invokes the specified Flutter method with the specified arguments, expecting * no results. * - * @see [MethodChannel.setMethodCallHandler](https://docs.flutter.io/flutter/services/MethodChannel/setMethodCallHandler.html). + * @see [MethodChannel.setMethodCallHandler](https://docs.flutter.io/flutter/services/MethodChannel/setMethodCallHandler.html) * * @param method The name of the method to invoke. * @param arguments The arguments. Must be a value supported by the codec of this * channel. */ +// clang-format on - (void)invokeMethod:(NSString*)method arguments:(id _Nullable)arguments; /** diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h b/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h index 2f25624203a89..6f6719c0f6665 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h @@ -48,7 +48,7 @@ FLUTTER_EXPORT * On the Dart side, messages are represented using `ByteData`. */ FLUTTER_EXPORT -@interface FlutterBinaryCodec : NSObject +@interface FlutterBinaryCodec : NSObject @end /** @@ -59,7 +59,7 @@ FLUTTER_EXPORT * on the Dart side. These parts of the Flutter SDK are evolved synchronously. */ FLUTTER_EXPORT -@interface FlutterStringCodec : NSObject +@interface FlutterStringCodec : NSObject @end /** @@ -77,7 +77,7 @@ FLUTTER_EXPORT * package. */ FLUTTER_EXPORT -@interface FlutterJSONMessageCodec : NSObject +@interface FlutterJSONMessageCodec : NSObject @end /** @@ -156,7 +156,7 @@ FLUTTER_EXPORT * - `NSDictionary`: `Map` */ FLUTTER_EXPORT -@interface FlutterStandardMessageCodec : NSObject +@interface FlutterStandardMessageCodec : NSObject + (instancetype)codecWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter; @end @@ -300,12 +300,11 @@ FLUTTER_EXPORT * and `FlutterStandardMethodCodec`. */ FLUTTER_EXPORT -FLUTTER_UNAVAILABLE( - "Unavailable on 2018-08-31. Deprecated on 2018-01-09. " - "FlutterStandardBigInteger was needed because the Dart 1.0 int type had no " - "size limit. With Dart 2.0, the int type is a fixed-size, 64-bit signed " - "integer. If you need to communicate larger integers, use NSString encoding " - "instead.") +FLUTTER_UNAVAILABLE("Unavailable on 2018-08-31. Deprecated on 2018-01-09. " + "FlutterStandardBigInteger was needed because the Dart 1.0 int type had no " + "size limit. With Dart 2.0, the int type is a fixed-size, 64-bit signed " + "integer. If you need to communicate larger integers, use NSString encoding " + "instead.") @interface FlutterStandardBigInteger : NSObject @end @@ -389,7 +388,7 @@ FLUTTER_EXPORT * those supported as top-level or leaf values by `FlutterJSONMessageCodec`. */ FLUTTER_EXPORT -@interface FlutterJSONMethodCodec : NSObject +@interface FlutterJSONMethodCodec : NSObject @end /** @@ -403,7 +402,7 @@ FLUTTER_EXPORT * `FlutterStandardMessageCodec`. */ FLUTTER_EXPORT -@interface FlutterStandardMethodCodec : NSObject +@interface FlutterStandardMethodCodec : NSObject + (instancetype)codecWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter; @end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h b/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h index 1bf7454301435..de491405fe601 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h @@ -16,7 +16,7 @@ FLUTTER_EXPORT @interface FlutterDartProject : NSObject /** - * Initializes with a specific + * Initializes with a specific */ - (instancetype)initWithPrecompiledDartBundle:(NSBundle*)bundle NS_DESIGNATED_INITIALIZER; diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index b6817c76ea1a6..f027bf59f44b4 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -19,22 +19,22 @@ /** * The FlutterEngine class coordinates a single instance of execution for a * `FlutterDartProject`. It may have one `FlutterViewController` at any given - * time, which can be `-setViewController:` or with `FlutterViewController`'s + * time, which can be `-setViewController:` or with `FlutterViewController`'s * `initWithEngine` initializer. - * + * * A FlutterEngine can be created independently of a `FlutterViewController` for - * headless execution. It can also persist across the lifespan of multiple + * headless execution. It can also persist across the lifespan of multiple * `FlutterViewController` instances to maintain state and/or asynchronous tasks * (such as downloading a large file). - * + * * Alternatively, you can simply create a new `FlutterViewController` with only a - * `FlutterDartProject`. That `FlutterViewController` will internally manage its + * `FlutterDartProject`. That `FlutterViewController` will internally manage its * own instance of a FlutterEngine, but will not guarantee survival of the engine * beyond the life of the ViewController. */ FLUTTER_EXPORT @interface FlutterEngine - : NSObject + : NSObject /** * Iniitalize this FlutterEngine with a `FlutterDartProject`. * @@ -66,24 +66,24 @@ FLUTTER_EXPORT - (bool)runWithEntrypoint:(NSString*)entrypoint; /** -* Runs a Dart program on an Isolate. -* -* The first call will create a new Isolate. Subsequent calls will return immediately. -* -* @param entrypoint The name of a top-level function from a Dart library. -* @param libraryUri The URI of the Dart library which contains the entrypoint method. -* @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. -*/ + * Runs a Dart program on an Isolate. + * + * The first call will create a new Isolate. Subsequent calls will return immediately. + * + * @param entrypoint The name of a top-level function from a Dart library. + * @param libraryUri The URI of the Dart library which contains the entrypoint method. + * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. + */ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri; /** * Sets the `FlutterViewController` for this instance; callers may pass nil to * remove the viewController and have the engine run headless in the current process. - * - * A FlutterEngine can only have one `FlutterViewController` at a time. If there is + * + * A FlutterEngine can only have one `FlutterViewController` at a time. If there is * already a `FlutterViewController` associated with this instance, this method will replace * the engine's current viewController with the newly specified one. - * + * * @param viewController The `FlutterViewController` (or nil) to set. Kept as a weak reference. */ - (void)setViewController:(FlutterViewController*)viewController; @@ -99,8 +99,9 @@ FLUTTER_EXPORT - (FlutterMethodChannel*)localizationChannel; /** * The `FlutterMethodChannel` used for navigation related platform messages. - * - * @see [Navigation Channel](https://docs.flutter.io/flutter/services/SystemChannels/navigation-constant.html) + * + * @see [Navigation + * Channel](https://docs.flutter.io/flutter/services/SystemChannels/navigation-constant.html) * @see [Navigator Widget](https://docs.flutter.io/flutter/widgets/Navigator-class.html) */ - (FlutterMethodChannel*)navigationChannel; @@ -112,22 +113,25 @@ FLUTTER_EXPORT /** * The `FlutterMethodChannel` used to communicate text input events to the * Dart Isolate. - * - * @see [Text Input Channel](https://docs.flutter.io/flutter/services/SystemChannels/textInput-constant.html) + * + * @see [Text Input + * Channel](https://docs.flutter.io/flutter/services/SystemChannels/textInput-constant.html) */ - (FlutterMethodChannel*)textInputChannel; /** * The `FlutterBasicMessageChannel` used to communicate app lifecycle events * to the Dart Isolate. - * - * @see [Lifecycle Channel](https://docs.flutter.io/flutter/services/SystemChannels/lifecycle-constant.html) + * + * @see [Lifecycle + * Channel](https://docs.flutter.io/flutter/services/SystemChannels/lifecycle-constant.html) */ - (FlutterBasicMessageChannel*)lifecycleChannel; /** * The `FlutterBasicMessageChannel` used for communicating system events, such as * memory pressure events. - * - * @see [System Channel](https://docs.flutter.io/flutter/services/SystemChannels/system-constant.html) + * + * @see [System + * Channel](https://docs.flutter.io/flutter/services/SystemChannels/system-constant.html) */ - (FlutterBasicMessageChannel*)systemChannel; /** diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h b/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h index f2b8670a8a9e2..9fe5887593b73 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h @@ -13,12 +13,12 @@ NS_ASSUME_NONNULL_BEGIN FLUTTER_EXPORT -@protocol FlutterTexture +@protocol FlutterTexture - (CVPixelBufferRef _Nullable)copyPixelBuffer; @end FLUTTER_EXPORT -@protocol FlutterTextureRegistry +@protocol FlutterTextureRegistry - (int64_t)registerTexture:(NSObject*)texture; - (void)textureFrameAvailable:(int64_t)textureId; - (void)unregisterTexture:(int64_t)textureId; diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index b26075f63de79..5a391db5d463d 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -19,11 +19,11 @@ /** * A `UIViewController` implementation for Flutter views. - * + * * Dart execution, channel communication, texture registration, and plugin registration * are all handled by `FlutterEngine`. Calls on this class to those members all proxy * through to the `FlutterEngine` that manages this FlutterViewController. - * + * * A FlutterViewController can be initialized either with an already-running `FlutterEngine`, * or it can be initialized with a `FlutterDartProject` that will be used to spin up * a new `FlutterEngine`. Developers looking to present and hide FlutterViewControllers diff --git a/shell/platform/darwin/ios/framework/Source/FlutterChannels.mm b/shell/platform/darwin/ios/framework/Source/FlutterChannels.mm index c9a75b0f49c67..9f0f9cc2f62c8 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterChannels.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterChannels.mm @@ -21,9 +21,9 @@ + (instancetype)messageChannelWithName:(NSString*)name + (instancetype)messageChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - return - [[[FlutterBasicMessageChannel alloc] initWithName:name binaryMessenger:messenger codec:codec] - autorelease]; + return [[[FlutterBasicMessageChannel alloc] initWithName:name + binaryMessenger:messenger + codec:codec] autorelease]; } - (instancetype)initWithName:(NSString*)name @@ -162,8 +162,8 @@ + (instancetype)methodChannelWithName:(NSString*)name + (instancetype)methodChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - return [[[FlutterMethodChannel alloc] initWithName:name binaryMessenger:messenger codec:codec] - autorelease]; + return [[[FlutterMethodChannel alloc] initWithName:name binaryMessenger:messenger + codec:codec] autorelease]; } - (instancetype)initWithName:(NSString*)name @@ -185,15 +185,15 @@ - (void)dealloc { } - (void)invokeMethod:(NSString*)method arguments:(id)arguments { - FlutterMethodCall* methodCall = - [FlutterMethodCall methodCallWithMethodName:method arguments:arguments]; + FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:method + arguments:arguments]; NSData* message = [_codec encodeMethodCall:methodCall]; [_messenger sendOnChannel:_name message:message]; } - (void)invokeMethod:(NSString*)method arguments:(id)arguments result:(FlutterResult)callback { - FlutterMethodCall* methodCall = - [FlutterMethodCall methodCallWithMethodName:method arguments:arguments]; + FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:method + arguments:arguments]; NSData* message = [_codec encodeMethodCall:methodCall]; FlutterBinaryReply reply = ^(NSData* data) { if (callback) { @@ -241,8 +241,8 @@ + (instancetype)eventChannelWithName:(NSString*)name + (instancetype)eventChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - return [[[FlutterEventChannel alloc] initWithName:name binaryMessenger:messenger codec:codec] - autorelease]; + return [[[FlutterEventChannel alloc] initWithName:name binaryMessenger:messenger + codec:codec] autorelease]; } - (instancetype)initWithName:(NSString*)name diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h index 2972b5febe47d..32a2c50c1d80f 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h @@ -16,7 +16,7 @@ - (shell::RunConfiguration)runConfiguration; - (shell::RunConfiguration)runConfigurationForEntrypoint:(NSString*)entrypointOrNil; - (shell::RunConfiguration)runConfigurationForEntrypoint:(NSString*)entrypointOrNil - libraryOrNil:(NSString*)dartLibraryOrNil; + libraryOrNil:(NSString*)dartLibraryOrNil; + (NSString*)flutterAssetsName:(NSBundle*)bundle; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h b/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h index 3136eb08ccafe..4c3cea566fc76 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h @@ -21,7 +21,7 @@ typedef NS_ENUM(NSInteger, FlutterTextInputAction) { FlutterTextInputActionNewline, }; -@protocol FlutterTextInputDelegate +@protocol FlutterTextInputDelegate - (void)updateEditingClient:(int)client withState:(NSDictionary*)state; - (void)performAction:(FlutterTextInputAction)action withClient:(int)client; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h index 198381e4ebbce..06e5b68b69ed2 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h @@ -36,7 +36,7 @@ @end /** A range of text in the buffer of a Flutter text editing widget. */ -@interface FlutterTextRange : UITextRange +@interface FlutterTextRange : UITextRange @property(nonatomic, readonly) NSRange range; diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm index a4682a36f14eb..b094579c9f408 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm @@ -257,7 +257,7 @@ - (CGRect)globalRect { // `rect` is in the physical pixel coordinate system. iOS expects the accessibility frame in // the logical pixel coordinate system. Therefore, we divide by the `scale` (pixel ratio) to // convert. - CGFloat scale = [[[self bridge] -> view() window] screen].scale; + CGFloat scale = [[[self bridge]->view() window] screen].scale; auto result = CGRectMake(rect.x() / scale, rect.y() / scale, rect.width() / scale, rect.height() / scale); return UIAccessibilityConvertFrameToScreenCoordinates(result, [self bridge] -> view()); @@ -268,8 +268,8 @@ - (CGRect)globalRect { - (id)accessibilityContainer { if ([self hasChildren] || [self uid] == kRootNodeId) { if (_container == nil) - _container = - [[SemanticsObjectContainer alloc] initWithSemanticsObject:self bridge:[self bridge]]; + _container = [[SemanticsObjectContainer alloc] initWithSemanticsObject:self + bridge:[self bridge]]; return _container; } if ([self parent] == nil) { @@ -654,11 +654,11 @@ - (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction { [objects_ removeObjectForKey:@(node.id)]; if (isTextField) { // Text fields are backed by objects that implement UITextInput. - object = - [[[TextInputSemanticsObject alloc] initWithBridge:GetWeakPtr() uid:uid] autorelease]; + object = [[[TextInputSemanticsObject alloc] initWithBridge:GetWeakPtr() + uid:uid] autorelease]; } else { - object = - [[[FlutterSemanticsObject alloc] initWithBridge:GetWeakPtr() uid:uid] autorelease]; + object = [[[FlutterSemanticsObject alloc] initWithBridge:GetWeakPtr() + uid:uid] autorelease]; } [object.parent.children replaceObjectAtIndex:positionInChildlist withObject:object]; objects_.get()[@(node.id)] = object; diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h b/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h index bcdebfc689deb..ecc26a240a159 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h +++ b/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h @@ -11,7 +11,7 @@ * * This class is used by `TextInputSemanticsObject`. */ -@interface FlutterInactiveTextInput : UIView +@interface FlutterInactiveTextInput : UIView @property(nonatomic, copy) NSString* text; @property(nonatomic, readonly) NSMutableString* markedText; @@ -30,7 +30,7 @@ * field that currently owns input focus. Delegates to * `FlutterInactiveTextInput` otherwise. */ -@interface TextInputSemanticsObject : SemanticsObject +@interface TextInputSemanticsObject : SemanticsObject @end #endif // SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_ACCESSIBILITY_TEXT_ENTRY_H_ diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.mm b/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.mm index ec98c5d003204..c5b63d3d39644 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.mm @@ -343,8 +343,9 @@ - (UITextPosition*)positionFromPosition:(UITextPosition*)position offset:(NSInte - (UITextPosition*)positionFromPosition:(UITextPosition*)position inDirection:(UITextLayoutDirection)direction offset:(NSInteger)offset { - return - [[self textInputSurrogate] positionFromPosition:position inDirection:direction offset:offset]; + return [[self textInputSurrogate] positionFromPosition:position + inDirection:direction + offset:offset]; } - (NSComparisonResult)comparePosition:(UITextPosition*)position toPosition:(UITextPosition*)other { @@ -362,8 +363,8 @@ - (UITextPosition*)positionWithinRange:(UITextRange*)range - (UITextRange*)characterRangeByExtendingPosition:(UITextPosition*)position inDirection:(UITextLayoutDirection)direction { - return - [[self textInputSurrogate] characterRangeByExtendingPosition:position inDirection:direction]; + return [[self textInputSurrogate] characterRangeByExtendingPosition:position + inDirection:direction]; } - (UITextWritingDirection)baseWritingDirectionForPosition:(UITextPosition*)position diff --git a/shell/platform/darwin/ios/framework/Source/flutter_codecs_unittest.mm b/shell/platform/darwin/ios/framework/Source/flutter_codecs_unittest.mm index b94793d39e812..502df4b55ee80 100644 --- a/shell/platform/darwin/ios/framework/Source/flutter_codecs_unittest.mm +++ b/shell/platform/darwin/ios/framework/Source/flutter_codecs_unittest.mm @@ -56,7 +56,7 @@ } TEST(FlutterJSONCodec, CanEncodeAndDecodeDictionary) { - NSDictionary* value = @{ @"a" : @3.14, @"b" : @47, @"c" : [NSNull null], @"d" : @[ @"nested" ] }; + NSDictionary* value = @{@"a" : @3.14, @"b" : @47, @"c" : [NSNull null], @"d" : @[ @"nested" ]}; FlutterJSONMessageCodec* codec = [FlutterJSONMessageCodec sharedInstance]; NSData* encoded = [codec encode:value]; NSDictionary* decoded = [codec decode:encoded]; diff --git a/shell/platform/darwin/ios/ios_external_texture_gl.h b/shell/platform/darwin/ios/ios_external_texture_gl.h index 0ad69483385f2..1a1fa997f8f4b 100644 --- a/shell/platform/darwin/ios/ios_external_texture_gl.h +++ b/shell/platform/darwin/ios/ios_external_texture_gl.h @@ -13,15 +13,12 @@ namespace shell { class IOSExternalTextureGL : public flow::Texture { public: - IOSExternalTextureGL(int64_t textureId, - NSObject* externalTexture); + IOSExternalTextureGL(int64_t textureId, NSObject* externalTexture); ~IOSExternalTextureGL() override; // Called from GPU thread. - virtual void Paint(SkCanvas& canvas, - const SkRect& bounds, - bool freeze) override; + virtual void Paint(SkCanvas& canvas, const SkRect& bounds, bool freeze) override; virtual void OnGrContextCreated() override; diff --git a/shell/platform/darwin/ios/ios_surface_software.h b/shell/platform/darwin/ios/ios_surface_software.h index 154f057489f48..25ab355b91cf2 100644 --- a/shell/platform/darwin/ios/ios_surface_software.h +++ b/shell/platform/darwin/ios/ios_surface_software.h @@ -14,8 +14,7 @@ namespace shell { -class IOSSurfaceSoftware final : public IOSSurface, - public GPUSurfaceSoftwareDelegate { +class IOSSurfaceSoftware final : public IOSSurface, public GPUSurfaceSoftwareDelegate { public: IOSSurfaceSoftware(fml::scoped_nsobject layer); diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index 6e8e37184162a..50e8fa7a1ec35 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -25,23 +25,20 @@ namespace shell { class PlatformViewIOS final : public PlatformView { public: - explicit PlatformViewIOS(PlatformView::Delegate& delegate, - blink::TaskRunners task_runners); + explicit PlatformViewIOS(PlatformView::Delegate& delegate, blink::TaskRunners task_runners); ~PlatformViewIOS(); PlatformMessageRouter& GetPlatformMessageRouter(); fml::WeakPtr GetOwnerViewController() const; - void SetOwnerViewController( - fml::WeakPtr owner_controller); + void SetOwnerViewController(fml::WeakPtr owner_controller); void RegisterExternalTexture(int64_t id, NSObject* texture); fml::scoped_nsprotocol GetTextInputPlugin() const; - void SetTextInputPlugin( - fml::scoped_nsprotocol plugin); + void SetTextInputPlugin(fml::scoped_nsprotocol plugin); private: fml::WeakPtr owner_controller_; @@ -52,8 +49,7 @@ class PlatformViewIOS final : public PlatformView { fml::closure firstFrameCallback_; // |shell::PlatformView| - void HandlePlatformMessage( - fml::RefPtr message) override; + void HandlePlatformMessage(fml::RefPtr message) override; // |shell::PlatformView| std::unique_ptr CreateRenderingSurface() override; @@ -68,9 +64,8 @@ class PlatformViewIOS final : public PlatformView { void SetAccessibilityFeatures(int32_t flags) override; // |shell::PlatformView| - void UpdateSemantics( - blink::SemanticsNodeUpdates update, - blink::CustomAccessibilityActionUpdates actions) override; + void UpdateSemantics(blink::SemanticsNodeUpdates update, + blink::CustomAccessibilityActionUpdates actions) override; // |shell::PlatformView| std::unique_ptr CreateVSyncWaiter() override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index ac12b894e96d2..9dac5fc46b9c0 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -66,7 +66,7 @@ "has no ViewController."; return nullptr; } - + fml::AutoResetWaitableEvent latch; std::unique_ptr surface; auto gpu_task = [ios_surface = ios_surface_.get(), &surface, &latch]() { From 270bd0f72a3e3ac975a733751a42c932324e7c0a Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Oct 2018 09:34:16 -0700 Subject: [PATCH 12/31] fix license on flutterengine --- shell/platform/darwin/ios/framework/Source/FlutterEngine.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 7354fc4e295c4..f0cdc16c58a6d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2018 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. From a03a78c127125742acd2639995af178b7f4a68bf Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Oct 2018 09:36:11 -0700 Subject: [PATCH 13/31] Fix casing in license --- ci/licenses_golden/licenses_flutter | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 044a5e07fe01a..d9fabf4546313 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -513,7 +513,7 @@ FILE: ../../../flutter/shell/platform/android/platform_message_response_android. FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate_Internal.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm -FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_internal.h +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.mm FILE: ../../../flutter/shell/platform/embedder/embedder_surface.cc From 021dac6acddd95996a617ce4f3078c24426fac50 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Oct 2018 11:35:02 -0700 Subject: [PATCH 14/31] reset, not release --- shell/platform/darwin/ios/platform_view_ios.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 9dac5fc46b9c0..40399aff558c5 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -38,8 +38,8 @@ void PlatformViewIOS::SetOwnerViewController(fml::WeakPtr owner_controller) { if (ios_surface_ || !owner_controller) { NotifyDestroyed(); - ios_surface_.release(); - accessibility_bridge_.release(); + ios_surface_.reset(); + accessibility_bridge_.reset(); } owner_controller_ = owner_controller; if (owner_controller_) { From 4d95721e986549be33a35c042c7c92dd1131b61b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Oct 2018 14:34:44 -0700 Subject: [PATCH 15/31] return if no vc for setSemanticsEnabled; create surface on GPU thread --- .../darwin/ios/framework/Source/FlutterView.h | 4 ++- .../ios/framework/Source/FlutterView.mm | 27 ++++++++++++------- .../platform/darwin/ios/platform_view_ios.mm | 8 +++--- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterView.h b/shell/platform/darwin/ios/framework/Source/FlutterView.h index 5e3d303401725..2e784e563f602 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterView.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterView.h @@ -9,11 +9,13 @@ #include +#include "flutter/fml/synchronization/waitable_event.h" +#include "flutter/fml/task_runner.h" #include "flutter/shell/platform/darwin/ios/ios_surface.h" @interface FlutterView : UIView -- (std::unique_ptr)createSurface; +- (std::unique_ptr)createSurface:(fml::RefPtr)gpuTaskRunner; @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterView.mm b/shell/platform/darwin/ios/framework/Source/FlutterView.mm index 2fcbbbc235e7d..3ba70f10c5c76 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterView.mm @@ -63,15 +63,24 @@ + (Class)layerClass { #endif // TARGET_IPHONE_SIMULATOR } -- (std::unique_ptr)createSurface { - if ([self.layer isKindOfClass:[CAEAGLLayer class]]) { - fml::scoped_nsobject eagl_layer( - reinterpret_cast([self.layer retain])); - return std::make_unique(std::move(eagl_layer)); - } else { - fml::scoped_nsobject layer(reinterpret_cast([self.layer retain])); - return std::make_unique(std::move(layer)); - } +- (std::unique_ptr)createSurface:(fml::RefPtr)gpuTaskRunner { + fml::AutoResetWaitableEvent latch; + std::unique_ptr ios_surface; + auto gpu_task = [layer = self.layer, &ios_surface, &latch]() { + if ([layer isKindOfClass:[CAEAGLLayer class]]) { + fml::scoped_nsobject eagl_layer(reinterpret_cast([layer retain])); + ios_surface = std::make_unique(std::move(eagl_layer)); + } else { + fml::scoped_nsobject layer(reinterpret_cast([layer retain])); + ios_surface = std::make_unique(std::move(layer)); + } + latch.Signal(); + }; + + fml::TaskRunner::RunNowOrPostTask(gpuTaskRunner, gpu_task); + + latch.Wait(); + return ios_surface; } - (BOOL)enableInputClicksWhenVisible { diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 40399aff558c5..e51e2e419613e 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -43,7 +43,8 @@ } owner_controller_ = owner_controller; if (owner_controller_) { - ios_surface_ = static_cast(owner_controller_.get().view).createSurface; + ios_surface_ = [static_cast(owner_controller.get().view) + createSurface:task_runners_.GetGPUTaskRunner()]; FML_DCHECK(ios_surface_ != nullptr); if (accessibility_bridge_) { @@ -96,8 +97,9 @@ // |shell::PlatformView| void PlatformViewIOS::SetSemanticsEnabled(bool enabled) { if (!owner_controller_) { - FML_DLOG(INFO) << "Could not set semantics to enabled, this " - "PlatformViewIOS has no ViewController."; + FML_DLOG(WARNING) << "Could not set semantics to enabled, this " + "PlatformViewIOS has no ViewController."; + return; } if (enabled && !accessibility_bridge_) { accessibility_bridge_ = std::make_unique( From f06e46bc2ece756cef266e5ea02d603b4ec28156 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Oct 2018 16:25:15 -0700 Subject: [PATCH 16/31] Documentation updates --- .../ios/framework/Headers/FlutterEngine.h | 47 ++++++++++++++----- .../framework/Headers/FlutterViewController.h | 6 +-- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index f027bf59f44b4..18225fb36973d 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -18,9 +18,10 @@ /** * The FlutterEngine class coordinates a single instance of execution for a - * `FlutterDartProject`. It may have one `FlutterViewController` at any given - * time, which can be `-setViewController:` or with `FlutterViewController`'s - * `initWithEngine` initializer. + * `FlutterDartProject`. It may have zero or one `FlutterViewController` at a + * time, which can be specified via `-setViewController:`. + * `FlutterViewController`'s `initWithEngine` initializer will automatically call + * `-setViewController:` for itself. * * A FlutterEngine can be created independently of a `FlutterViewController` for * headless execution. It can also persist across the lifespan of multiple @@ -31,6 +32,10 @@ * `FlutterDartProject`. That `FlutterViewController` will internally manage its * own instance of a FlutterEngine, but will not guarantee survival of the engine * beyond the life of the ViewController. + * + * A newly initialized FlutterEngine will not actually run a Dart Isolate until + * either `-runWithEntrypoint:` or `-runWithEntrypointAndLibraryUri:` is invoked. + * One of these methods must be invoked before calling `-setViewController:`. */ FLUTTER_EXPORT @interface FlutterEngine @@ -41,6 +46,9 @@ FLUTTER_EXPORT * If the FlutterDartProject is not specified, the FlutterEngine will attempt to locate * the project in a default location. * + * A newly initialized engine will not run the `FlutterDartProject` until either + * `-runWithEntrypoint:` or `-runWithEntrypointAndLibraryUri:` is called. + * * @param labelPrefix The label prefix used to identify threads for this instance. Should * be unique across FlutterEngine instances * @param project The `FlutterDartProject` to run. @@ -55,34 +63,47 @@ FLUTTER_EXPORT - (instancetype)init NS_UNAVAILABLE; /** - * Runs a Dart program on an Isolate. + * Runs a Dart program on an Isolate from the main Dart library (i.e. the library that + * contains `main()`). * - * The first call will create a new Isolate. Subsequent calls will return immediately. + * The first call to this method will create a new Isolate. Subsequent calls will return + * immediately. * * @param entrypoint The name of a top-level function from the same Dart - * library that contains the app's main() function. + * library that contains the app's main() function. If this is nil, it will + * default to `main()`. * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. */ - (bool)runWithEntrypoint:(NSString*)entrypoint; /** - * Runs a Dart program on an Isolate. - * - * The first call will create a new Isolate. Subsequent calls will return immediately. + * Runs a Dart program on an Isolate using the specified entrypoint and Dart library, + * which may not be the same as the library containing the Dart program's `main()` function. + * + * The first call to this method will create a new Isolate. Subsequent calls will return + * immediately. * - * @param entrypoint The name of a top-level function from a Dart library. - * @param libraryUri The URI of the Dart library which contains the entrypoint method. + * @param entrypoint The name of a top-level function from a Dart library. If nil, this will + * default to `main()`. + * @param libraryUri The URI of the Dart library which contains the entrypoint method. IF nil, + * this will default to the same library as the `main()` function in the Dart program. * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. */ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri; /** - * Sets the `FlutterViewController` for this instance; callers may pass nil to - * remove the viewController and have the engine run headless in the current process. + * Sets the `FlutterViewController` for this instance. The FlutterEngine must be + * running (e.g. a successful call to `-runWithEntrypoint:` or `-runWithEntrypointAndLibraryUri`) + * before calling this method. Callers may pass nil to remove the viewController + * and have the engine run headless in the current process. * * A FlutterEngine can only have one `FlutterViewController` at a time. If there is * already a `FlutterViewController` associated with this instance, this method will replace * the engine's current viewController with the newly specified one. + * + * Setting the viewController will signal the engine to start animations and drawing, and unsetting it + * will signal the engine to stop animations and drawing. However, neither will + * impact the state of the Dart program's execution. * * @param viewController The `FlutterViewController` (or nil) to set. Kept as a weak reference. */ diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index 5a391db5d463d..e523763fcd6ea 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -22,14 +22,14 @@ * * Dart execution, channel communication, texture registration, and plugin registration * are all handled by `FlutterEngine`. Calls on this class to those members all proxy - * through to the `FlutterEngine` that manages this FlutterViewController. + * through to the `FlutterEngine` attached FlutterViewController. * * A FlutterViewController can be initialized either with an already-running `FlutterEngine`, * or it can be initialized with a `FlutterDartProject` that will be used to spin up * a new `FlutterEngine`. Developers looking to present and hide FlutterViewControllers * in native iOS applications will usually want to maintain the `FlutterEngine` instance - * so as not to lose state or asynchronous tasks when navigating back and forth between a - * FlutterViewController and other `UIViewController`s. + * so as not to lose Dart-related state and asynchronous tasks when navigating back and + * forth between a FlutterViewController and other `UIViewController`s. */ FLUTTER_EXPORT @interface FlutterViewController From 4ef18f92214cb9e0f7bf14ada5cfd554e68386fe Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Oct 2018 16:31:41 -0700 Subject: [PATCH 17/31] doc --- .../darwin/ios/framework/Headers/FlutterEngine.h | 10 +++++----- .../ios/framework/Headers/FlutterViewController.h | 2 +- .../darwin/ios/framework/Source/FlutterEngine.mm | 2 ++ 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 18225fb36973d..06ddab7781065 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -79,7 +79,7 @@ FLUTTER_EXPORT /** * Runs a Dart program on an Isolate using the specified entrypoint and Dart library, * which may not be the same as the library containing the Dart program's `main()` function. - * + * * The first call to this method will create a new Isolate. Subsequent calls will return * immediately. * @@ -100,10 +100,10 @@ FLUTTER_EXPORT * A FlutterEngine can only have one `FlutterViewController` at a time. If there is * already a `FlutterViewController` associated with this instance, this method will replace * the engine's current viewController with the newly specified one. - * - * Setting the viewController will signal the engine to start animations and drawing, and unsetting it - * will signal the engine to stop animations and drawing. However, neither will - * impact the state of the Dart program's execution. + * + * Setting the viewController will signal the engine to start animations and drawing, and unsetting + * it will signal the engine to stop animations and drawing. However, neither will impact the state + * of the Dart program's execution. * * @param viewController The `FlutterViewController` (or nil) to set. Kept as a weak reference. */ diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index e523763fcd6ea..2446df6f4c11e 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -28,7 +28,7 @@ * or it can be initialized with a `FlutterDartProject` that will be used to spin up * a new `FlutterEngine`. Developers looking to present and hide FlutterViewControllers * in native iOS applications will usually want to maintain the `FlutterEngine` instance - * so as not to lose Dart-related state and asynchronous tasks when navigating back and + * so as not to lose Dart-related state and asynchronous tasks when navigating back and * forth between a FlutterViewController and other `UIViewController`s. */ FLUTTER_EXPORT diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index f0cdc16c58a6d..9b18856983de4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -24,6 +24,8 @@ #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" @interface FlutterEngine () +// Maintains a dictionary of plugin names that have registered with the engine. Used by +// FlutterEngineRegistrar to implement a FlutterPluginRegistrar. @property(nonatomic, readonly) NSMutableDictionary* pluginPublications; @end From d48984de3307278026e1e3dbe96ef87ea5ef306e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Oct 2018 22:46:07 -0700 Subject: [PATCH 18/31] Revert unnecessary GPU schedule; mark lambda mutable --- .../darwin/ios/framework/Source/FlutterView.h | 4 +-- .../ios/framework/Source/FlutterView.mm | 27 +++++++------------ .../platform/darwin/ios/platform_view_ios.mm | 7 +++-- 3 files changed, 13 insertions(+), 25 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterView.h b/shell/platform/darwin/ios/framework/Source/FlutterView.h index 2e784e563f602..5e3d303401725 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterView.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterView.h @@ -9,13 +9,11 @@ #include -#include "flutter/fml/synchronization/waitable_event.h" -#include "flutter/fml/task_runner.h" #include "flutter/shell/platform/darwin/ios/ios_surface.h" @interface FlutterView : UIView -- (std::unique_ptr)createSurface:(fml::RefPtr)gpuTaskRunner; +- (std::unique_ptr)createSurface; @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterView.mm b/shell/platform/darwin/ios/framework/Source/FlutterView.mm index 3ba70f10c5c76..2fcbbbc235e7d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterView.mm @@ -63,24 +63,15 @@ + (Class)layerClass { #endif // TARGET_IPHONE_SIMULATOR } -- (std::unique_ptr)createSurface:(fml::RefPtr)gpuTaskRunner { - fml::AutoResetWaitableEvent latch; - std::unique_ptr ios_surface; - auto gpu_task = [layer = self.layer, &ios_surface, &latch]() { - if ([layer isKindOfClass:[CAEAGLLayer class]]) { - fml::scoped_nsobject eagl_layer(reinterpret_cast([layer retain])); - ios_surface = std::make_unique(std::move(eagl_layer)); - } else { - fml::scoped_nsobject layer(reinterpret_cast([layer retain])); - ios_surface = std::make_unique(std::move(layer)); - } - latch.Signal(); - }; - - fml::TaskRunner::RunNowOrPostTask(gpuTaskRunner, gpu_task); - - latch.Wait(); - return ios_surface; +- (std::unique_ptr)createSurface { + if ([self.layer isKindOfClass:[CAEAGLLayer class]]) { + fml::scoped_nsobject eagl_layer( + reinterpret_cast([self.layer retain])); + return std::make_unique(std::move(eagl_layer)); + } else { + fml::scoped_nsobject layer(reinterpret_cast([self.layer retain])); + return std::make_unique(std::move(layer)); + } } - (BOOL)enableInputClicksWhenVisible { diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index e51e2e419613e..768a4b0696dc4 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -43,8 +43,7 @@ } owner_controller_ = owner_controller; if (owner_controller_) { - ios_surface_ = [static_cast(owner_controller.get().view) - createSurface:task_runners_.GetGPUTaskRunner()]; + ios_surface_ = static_cast(owner_controller.get().view).createSurface; FML_DCHECK(ios_surface_ != nullptr); if (accessibility_bridge_) { @@ -70,14 +69,14 @@ fml::AutoResetWaitableEvent latch; std::unique_ptr surface; - auto gpu_task = [ios_surface = ios_surface_.get(), &surface, &latch]() { + auto gpu_task = [ios_surface = ios_surface_.get(), &surface, &latch]() mutable { if (ios_surface) { surface = ios_surface->CreateGPUSurface(); } latch.Signal(); }; - fml::TaskRunner::RunNowOrPostTask(task_runners_.GetGPUTaskRunner(), gpu_task); + task_runners_.GetGPUTaskRunner()->PostTask(gpu_task); latch.Wait(); return surface; } From 7d9750bc46cfd207c067e253802721ad4cf52765 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Oct 2018 23:11:07 -0700 Subject: [PATCH 19/31] Fix race! --- shell/platform/darwin/ios/platform_view_ios.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 768a4b0696dc4..0d8da582f3b3c 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -50,7 +50,10 @@ accessibility_bridge_.reset( new AccessibilityBridge(static_cast(owner_controller_.get().view), this)); } - NotifyCreated(); + // Do not call `NotifyCreated()` here - let FlutterViewController take care + // of that when its Viewport is sized. If `NotifyCreated()` is called here, + // it can occasionally get invoked before the viewport is sized resulting in + // a framebuffer that will not be able to completely attach. } } From d3c5b3034abea48ec58535c674e8b16289879279 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 6 Oct 2018 12:21:50 -0700 Subject: [PATCH 20/31] Unbreak legacy support for FlutterHeadlessDartRunner --- .../Headers/FlutterHeadlessDartRunner.h | 22 +++++++++++++++++++ .../Source/FlutterHeadlessDartRunner.mm | 6 +++++ 2 files changed, 28 insertions(+) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h b/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h index 18ece954b7165..665f95977c470 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h @@ -33,6 +33,28 @@ FLUTTER_EXPORT FLUTTER_DEPRECATED("FlutterEngine should be used rather than FlutterHeadlessDartRunner") @interface FlutterHeadlessDartRunner : FlutterEngine +/** + * Iniitalize this FlutterHeadlessDartRunner with a `FlutterDartProject`. + * + * If the FlutterDartProject is not specified, the FlutterHeadlessDartRunner will attempt to locate + * the project in a default location. + * + * A newly initialized engine will not run the `FlutterDartProject` until either + * `-runWithEntrypoint:` or `-runWithEntrypointAndLibraryUri:` is called. + * + * @param labelPrefix The label prefix used to identify threads for this instance. Should + * be unique across FlutterEngine instances + * @param project The `FlutterDartProject` to run. + */ +- (instancetype)initWithName:(NSString*)labelPrefix + project:(FlutterDartProject*)projectOrNil NS_DESIGNATED_INITIALIZER; + +/** + * Not recommended for use - will initialize with a default label ("io.flutter.headless") + * and the default FlutterDartProject. + */ +- (instancetype)init; + @end #endif // FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_ diff --git a/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm b/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm index 64ca7dde4c346..34c854ada5885 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm @@ -27,4 +27,10 @@ @implementation FlutterHeadlessDartRunner { } +- (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)projectOrNil { + return [super initWithName:labelPrefix project:projectOrNil]; +} +- (instancetype)init { + return [self initWithName:@"io.flutter.headless" project:nil]; +} @end From 434184f97af58d513e09a82805fd26f524b6b2e9 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 6 Oct 2018 14:08:05 -0700 Subject: [PATCH 21/31] make sure to use config properly --- .../darwin/ios/framework/Source/FlutterEngine.mm | 14 ++++++-------- .../ios/framework/Source/FlutterEngine_Internal.h | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 9b18856983de4..66b5cdcaefc87 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -227,11 +227,12 @@ - (void)maybeSetupPlatformViewChannels { return self.shell.Screenshot(type, base64Encode); } -- (void)launchEngine { +- (void)launchEngine:(NSString*)entrypoint libraryUri:(NSString*)libraryOrNil { // Launch the Dart application with the inferred run configuration. - self.shell.GetTaskRunners().GetUITaskRunner()->PostTask( - fml::MakeCopyable([engine = _shell->GetEngine(), // - config = [_dartProject.get() runConfiguration] // + self.shell.GetTaskRunners().GetUITaskRunner()->PostTask(fml::MakeCopyable( + [engine = _shell->GetEngine(), + config = [_dartProject.get() runConfigurationForEntrypoint:entrypoint + libraryOrNil:libraryOrNil] // ]() mutable { if (engine) { auto result = engine->Run(std::move(config)); @@ -250,16 +251,13 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin static size_t shellCount = 1; - auto config = [_dartProject.get() runConfiguration]; auto settings = [_dartProject.get() settings]; if (libraryUri) { FML_DCHECK(entrypoint) << "Must specify entrypoint if specifying library"; - config.SetEntrypointAndLibrary(entrypoint.UTF8String, libraryUri.UTF8String); settings.advisory_script_entrypoint = entrypoint.UTF8String; settings.advisory_script_uri = libraryUri.UTF8String; } else if (entrypoint) { - config.SetEntrypoint(std::string(entrypoint.UTF8String)); settings.advisory_script_entrypoint = entrypoint.UTF8String; settings.advisory_script_entrypoint = std::string("main.dart"); } else { @@ -308,7 +306,7 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin << entrypoint.UTF8String; } else { [self maybeSetupPlatformViewChannels]; - [self launchEngine]; + [self launchEngine:entrypoint libraryUri:libraryUri]; } return _shell != nullptr; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h index 684da45973fb8..1b2e0eef0a6d4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h @@ -38,7 +38,7 @@ - (FlutterPlatformPlugin*)platformPlugin; - (FlutterTextInputPlugin*)textInputPlugin; -- (void)launchEngine; +- (void)launchEngine:(NSString*)entrypoint libraryUri:(NSString*)libraryOrNil; @end From c8cdbb33446a73804f75cd0a2de68985837c185f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 8 Oct 2018 09:08:59 -0700 Subject: [PATCH 22/31] Doc updates --- .../darwin/ios/framework/Headers/FlutterEngine.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 06ddab7781065..1f4ce060e6424 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -41,16 +41,18 @@ FLUTTER_EXPORT @interface FlutterEngine : NSObject /** - * Iniitalize this FlutterEngine with a `FlutterDartProject`. + * Initialize this FlutterEngine with a `FlutterDartProject`. * * If the FlutterDartProject is not specified, the FlutterEngine will attempt to locate - * the project in a default location. + * the project in a default location (the flutter_assets folder in the iOS application + * bundle). * * A newly initialized engine will not run the `FlutterDartProject` until either * `-runWithEntrypoint:` or `-runWithEntrypointAndLibraryUri:` is called. * * @param labelPrefix The label prefix used to identify threads for this instance. Should - * be unique across FlutterEngine instances + * be unique across FlutterEngine instances, and is used in instrumentation to label + * the threads used by this FlutterEngine. * @param project The `FlutterDartProject` to run. */ - (instancetype)initWithName:(NSString*)labelPrefix @@ -84,9 +86,9 @@ FLUTTER_EXPORT * immediately. * * @param entrypoint The name of a top-level function from a Dart library. If nil, this will - * default to `main()`. + * default to `main()`. * @param libraryUri The URI of the Dart library which contains the entrypoint method. IF nil, - * this will default to the same library as the `main()` function in the Dart program. + * this will default to the same library as the `main()` function in the Dart program. * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. */ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri; From 9793d246c3b7543e1a71e70e63f0e80b969fad44 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 9 Oct 2018 12:41:41 -0700 Subject: [PATCH 23/31] clarify entrypoint doc --- .../platform/darwin/ios/framework/Headers/FlutterEngine.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 1f4ce060e6424..8e01bb68b25f4 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -73,7 +73,9 @@ FLUTTER_EXPORT * * @param entrypoint The name of a top-level function from the same Dart * library that contains the app's main() function. If this is nil, it will - * default to `main()`. + * default to `main()`. If it is not the app's main() function, that function + * must be decorated with `@pragma(vm:entry-point)` to ensure the method is not + * tree-shaken by the Dart compiler. * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. */ - (bool)runWithEntrypoint:(NSString*)entrypoint; @@ -86,7 +88,9 @@ FLUTTER_EXPORT * immediately. * * @param entrypoint The name of a top-level function from a Dart library. If nil, this will - * default to `main()`. + * default to `main()`. If it is not the app's main() function, that function + * must be decorated with `@pragma(vm:entry-point)` to ensure the method is not + * tree-shaken by the Dart compiler. * @param libraryUri The URI of the Dart library which contains the entrypoint method. IF nil, * this will default to the same library as the `main()` function in the Dart program. * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. From 5a53454aaffc848859450d4f375c6885ca7cb03d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 15 Oct 2018 17:29:09 -0700 Subject: [PATCH 24/31] mergeo --- .../ios/framework/Source/FlutterViewController.mm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 103b5ec71b85b..3396a424d502d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -714,11 +714,12 @@ - (void)onLocaleUpdated:(NSNotification*)notification { if (languageCode && countryCode) // We pass empty strings for undefined scripts and variants to ensure the JSON encoder/decoder // functions properly. - [_localizationChannel.get() invokeMethod:@"setLocale" - arguments:@[ - languageCode, countryCode, scriptCode ? scriptCode : @"", - variantCode ? variantCode : @"" - ]]; + [[_engine.get() localizationChannel] + invokeMethod:@"setLocale" + arguments:@[ + languageCode, countryCode, scriptCode ? scriptCode : @"", + variantCode ? variantCode : @"" + ]]; } #pragma mark - Set user settings From 2be98746e442df002d684f40cf535b1834c18883 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 24 Oct 2018 10:33:11 -0700 Subject: [PATCH 25/31] fix setter for viewOpaque --- .../darwin/ios/framework/Source/FlutterViewController.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index eeab410c37a0a..3f7422d8df119 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -187,7 +187,7 @@ - (BOOL)isViewOpaque { return _viewOpaque; } -- (void)viewOpaque:(BOOL)value { +- (void)setViewOpaque:(BOOL)value { _viewOpaque = value; if (_flutterView.get().layer.opaque != value) { _flutterView.get().layer.opaque = value; From bd5ee237f9162c3ac37f337798b8431a92b3ac3d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 24 Oct 2018 12:54:33 -0700 Subject: [PATCH 26/31] format --- .../darwin/ios/framework/Source/FlutterViewController.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index af556f7123984..08fb3baf957c6 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -117,7 +117,6 @@ - (void)performCommonViewControllerInitialization { return _engine; } - - (fml::WeakPtr)getWeakPtr { return _weakFactory->GetWeakPtr(); } From 62e74f82a34a25928490f65f990810ade0102fa4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 24 Oct 2018 23:51:20 -0700 Subject: [PATCH 27/31] property/name refactoring --- .../ios/framework/Headers/FlutterEngine.h | 39 +++++++++---------- .../Headers/FlutterHeadlessDartRunner.h | 2 +- .../ios/framework/Source/FlutterEngine.mm | 14 +++---- .../framework/Source/FlutterEngine_Internal.h | 2 +- .../framework/Source/FlutterPlatformPlugin.mm | 2 +- 5 files changed, 29 insertions(+), 30 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 8e01bb68b25f4..a532635e49320 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -34,12 +34,12 @@ * beyond the life of the ViewController. * * A newly initialized FlutterEngine will not actually run a Dart Isolate until - * either `-runWithEntrypoint:` or `-runWithEntrypointAndLibraryUri:` is invoked. + * either `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI` is invoked. * One of these methods must be invoked before calling `-setViewController:`. */ FLUTTER_EXPORT @interface FlutterEngine - : NSObject + : NSObject /** * Initialize this FlutterEngine with a `FlutterDartProject`. * @@ -48,7 +48,7 @@ FLUTTER_EXPORT * bundle). * * A newly initialized engine will not run the `FlutterDartProject` until either - * `-runWithEntrypoint:` or `-runWithEntrypointAndLibraryUri:` is called. + * `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI:` is called. * * @param labelPrefix The label prefix used to identify threads for this instance. Should * be unique across FlutterEngine instances, and is used in instrumentation to label @@ -91,15 +91,15 @@ FLUTTER_EXPORT * default to `main()`. If it is not the app's main() function, that function * must be decorated with `@pragma(vm:entry-point)` to ensure the method is not * tree-shaken by the Dart compiler. - * @param libraryUri The URI of the Dart library which contains the entrypoint method. IF nil, + * @param libraryURI The URI of the Dart library which contains the entrypoint method. IF nil, * this will default to the same library as the `main()` function in the Dart program. * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. */ -- (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)uri; +- (bool)runWithEntrypoint:(NSString*)entrypoint libraryURI:(NSString*)uri; /** * Sets the `FlutterViewController` for this instance. The FlutterEngine must be - * running (e.g. a successful call to `-runWithEntrypoint:` or `-runWithEntrypointAndLibraryUri`) + * running (e.g. a successful call to `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI`) * before calling this method. Callers may pass nil to remove the viewController * and have the engine run headless in the current process. * @@ -110,20 +110,14 @@ FLUTTER_EXPORT * Setting the viewController will signal the engine to start animations and drawing, and unsetting * it will signal the engine to stop animations and drawing. However, neither will impact the state * of the Dart program's execution. - * - * @param viewController The `FlutterViewController` (or nil) to set. Kept as a weak reference. - */ -- (void)setViewController:(FlutterViewController*)viewController; -/** - * Gets the `FlutterViewController` (may be nil) currently used by this instance. */ -- (FlutterViewController*)getViewController; +@property(nonatomic, weak) FlutterViewController* viewController; /** * The `FlutterMethodChannel` used for localization related platform messages, such as * setting the locale. */ -- (FlutterMethodChannel*)localizationChannel; +@property(nonatomic, readonly) FlutterMethodChannel* localizationChannel; /** * The `FlutterMethodChannel` used for navigation related platform messages. * @@ -131,12 +125,14 @@ FLUTTER_EXPORT * Channel](https://docs.flutter.io/flutter/services/SystemChannels/navigation-constant.html) * @see [Navigator Widget](https://docs.flutter.io/flutter/widgets/Navigator-class.html) */ -- (FlutterMethodChannel*)navigationChannel; +@property(nonatomic, readonly) FlutterMethodChannel* navigationChannel; + /** * The `FlutterMethodChannel` used for core platform messages, such as * information about the screen orientation. */ -- (FlutterMethodChannel*)platformChannel; +@property(nonatomic, readonly) FlutterMethodChannel* platformChannel; + /** * The `FlutterMethodChannel` used to communicate text input events to the * Dart Isolate. @@ -144,7 +140,8 @@ FLUTTER_EXPORT * @see [Text Input * Channel](https://docs.flutter.io/flutter/services/SystemChannels/textInput-constant.html) */ -- (FlutterMethodChannel*)textInputChannel; +@property(nonatomic, readonly) FlutterMethodChannel* textInputChannel; + /** * The `FlutterBasicMessageChannel` used to communicate app lifecycle events * to the Dart Isolate. @@ -152,7 +149,8 @@ FLUTTER_EXPORT * @see [Lifecycle * Channel](https://docs.flutter.io/flutter/services/SystemChannels/lifecycle-constant.html) */ -- (FlutterBasicMessageChannel*)lifecycleChannel; +@property(nonatomic, readonly) FlutterBasicMessageChannel* lifecycleChannel; + /** * The `FlutterBasicMessageChannel` used for communicating system events, such as * memory pressure events. @@ -160,12 +158,13 @@ FLUTTER_EXPORT * @see [System * Channel](https://docs.flutter.io/flutter/services/SystemChannels/system-constant.html) */ -- (FlutterBasicMessageChannel*)systemChannel; +@property(nonatomic, readonly) FlutterBasicMessageChannel* systemChannel; + /** * The `FlutterBasicMessageChannel` used for communicating user settings such as * clock format and text scale. */ -- (FlutterBasicMessageChannel*)settingsChannel; +@property(nonatomic, readonly) FlutterBasicMessageChannel* settingsChannel; @end diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h b/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h index 665f95977c470..9df00af3da7ff 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h @@ -40,7 +40,7 @@ FLUTTER_DEPRECATED("FlutterEngine should be used rather than FlutterHeadlessDart * the project in a default location. * * A newly initialized engine will not run the `FlutterDartProject` until either - * `-runWithEntrypoint:` or `-runWithEntrypointAndLibraryUri:` is called. + * `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI` is called. * * @param labelPrefix The label prefix used to identify threads for this instance. Should * be unique across FlutterEngine instances diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 1cf351cd39ffc..8ab164dd18103 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -133,7 +133,7 @@ - (void)setViewController:(FlutterViewController*)viewController { [self maybeSetupPlatformViewChannels]; } -- (FlutterViewController*)getViewController { +- (FlutterViewController*)viewController { if (!_viewController) { return nil; } @@ -230,7 +230,7 @@ - (void)maybeSetupPlatformViewChannels { return self.shell.Screenshot(type, base64Encode); } -- (void)launchEngine:(NSString*)entrypoint libraryUri:(NSString*)libraryOrNil { +- (void)launchEngine:(NSString*)entrypoint libraryURI:(NSString*)libraryOrNil { // Launch the Dart application with the inferred run configuration. self.shell.GetTaskRunners().GetUITaskRunner()->PostTask(fml::MakeCopyable( [engine = _shell->GetEngine(), @@ -246,7 +246,7 @@ - (void)launchEngine:(NSString*)entrypoint libraryUri:(NSString*)libraryOrNil { })); } -- (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSString*)libraryUri { +- (bool)runWithEntrypoint:(NSString*)entrypoint libraryURI:(NSString*)libraryURI { if (_shell != nullptr) { FML_LOG(WARNING) << "This FlutterEngine was already invoked."; return false; @@ -256,10 +256,10 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin auto settings = [_dartProject.get() settings]; - if (libraryUri) { + if (libraryURI) { FML_DCHECK(entrypoint) << "Must specify entrypoint if specifying library"; settings.advisory_script_entrypoint = entrypoint.UTF8String; - settings.advisory_script_uri = libraryUri.UTF8String; + settings.advisory_script_uri = libraryURI.UTF8String; } else if (entrypoint) { settings.advisory_script_entrypoint = entrypoint.UTF8String; settings.advisory_script_entrypoint = std::string("main.dart"); @@ -309,14 +309,14 @@ - (bool)runWithEntrypointAndLibraryUri:(NSString*)entrypoint libraryUri:(NSStrin << entrypoint.UTF8String; } else { [self maybeSetupPlatformViewChannels]; - [self launchEngine:entrypoint libraryUri:libraryUri]; + [self launchEngine:entrypoint libraryURI:libraryURI]; } return _shell != nullptr; } - (bool)runWithEntrypoint:(NSString*)entrypoint { - return [self runWithEntrypointAndLibraryUri:entrypoint libraryUri:nil]; + return [self runWithEntrypoint:entrypoint libraryURI:nil]; } #pragma mark - Text input delegate diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h index e5e132335f282..5162f9c3ce078 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h @@ -38,7 +38,7 @@ - (FlutterPlatformPlugin*)platformPlugin; - (FlutterTextInputPlugin*)textInputPlugin; -- (void)launchEngine:(NSString*)entrypoint libraryUri:(NSString*)libraryOrNil; +- (void)launchEngine:(NSString*)entrypoint libraryURI:(NSString*)libraryOrNil; @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm index 4ab5e1cd42307..fb52763303e08 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm @@ -205,7 +205,7 @@ - (void)popSystemNavigator { [((UINavigationController*)viewController) popViewControllerAnimated:NO]; [_engine.get() setViewController:nil]; } else { - auto engineViewController = static_cast([_engine.get() getViewController]); + auto engineViewController = static_cast([_engine.get() viewController]); if (engineViewController != viewController) { [engineViewController dismissViewControllerAnimated:NO completion:nil]; [_engine.get() setViewController:nil]; From 974c77de362b49cdb1e1fd51e9e39c294f06d199 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 25 Oct 2018 00:30:06 -0700 Subject: [PATCH 28/31] format --- shell/platform/darwin/ios/framework/Headers/FlutterEngine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index a532635e49320..c1d8ebe251d89 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -39,7 +39,7 @@ */ FLUTTER_EXPORT @interface FlutterEngine - : NSObject + : NSObject /** * Initialize this FlutterEngine with a `FlutterDartProject`. * From f5b1b678a2f79fe1e24f51a9942d71df9766d91b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 25 Oct 2018 09:43:08 -0700 Subject: [PATCH 29/31] avoid deadlock --- shell/platform/darwin/ios/platform_view_ios.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 0d8da582f3b3c..90efe183316fa 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -79,7 +79,7 @@ latch.Signal(); }; - task_runners_.GetGPUTaskRunner()->PostTask(gpu_task); + fml::TaskRunner::RunNowOrPostTask(task_runners_.GetGPUTaskRunner(), gpu_task); latch.Wait(); return surface; } From b9950783f4e1889e8a8cbffcb47afb11c1d944a7 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 26 Oct 2018 10:28:30 -0700 Subject: [PATCH 30/31] fix bad property access --- .../platform/darwin/ios/framework/Source/FlutterEngine.mm | 8 +++++--- .../ios/framework/Source/FlutterViewController_Internal.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 1f4da6a6b675b..ef82e14e5f813 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -517,9 +517,11 @@ - (void)registerViewFactory:(NSObject*)factory // 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(_viewController) << "Cannot register a view factory on a headless engine."; - if (_viewController) { - [_viewController platformViewsController] -> RegisterViewFactory(factory, factoryId); + 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."; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h index 3031adbf46baa..75e820907cc0a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h @@ -8,10 +8,12 @@ #include "flutter/fml/memory/weak_ptr.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" #include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h" @interface FlutterViewController () - (fml::WeakPtr)getWeakPtr; +- (shell::FlutterPlatformViewsController*)platformViewsController; @property(readonly) fml::scoped_nsobject engine; From 01bb8b20df094785c1b797715968cf545ce05503 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 26 Oct 2018 12:44:21 -0700 Subject: [PATCH 31/31] remove latch; fix objcdoc parameter names --- .../darwin/ios/framework/Headers/FlutterChannels.h | 5 ++--- .../darwin/ios/framework/Headers/FlutterCodecs.h | 2 +- .../darwin/ios/framework/Headers/FlutterEngine.h | 4 ++-- .../framework/Headers/FlutterHeadlessDartRunner.h | 2 +- .../ios/framework/Headers/FlutterPlatformViews.h | 4 ++-- .../darwin/ios/framework/Headers/FlutterPlugin.h | 2 +- .../ios/framework/Headers/FlutterViewController.h | 8 ++++---- shell/platform/darwin/ios/platform_view_ios.mm | 14 +------------- 8 files changed, 14 insertions(+), 27 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h b/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h index bd80d6426377e..373f32293d609 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h @@ -24,7 +24,7 @@ typedef void (^FlutterReply)(id _Nullable reply); * asynchronous replies back to Flutter. * * @param message The message. - * @param reply A callback for submitting a reply to the sender. + * @param callback A callback for submitting a reply to the sender. */ typedef void (^FlutterMessageHandler)(id _Nullable message, FlutterReply callback); @@ -226,7 +226,7 @@ FLUTTER_EXPORT * @param method The name of the method to invoke. * @param arguments The arguments. Must be a value supported by the codec of this * channel. - * @param result A callback that will be invoked with the asynchronous result. + * @param callback A callback that will be invoked with the asynchronous result. * The result will be a `FlutterError` instance, if the method call resulted * in an error on the Flutter side. Will be `FlutterMethodNotImplemented`, if * the method called was not implemented on the Flutter side. Any other value, @@ -317,7 +317,6 @@ FLUTTER_EXPORT * * @param name The channel name. * @param messenger The binary messenger. - * @param codec The method codec. */ + (instancetype)eventChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger; diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h b/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h index 6f6719c0f6665..4a8e0775ac0ae 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h @@ -369,7 +369,7 @@ FLUTTER_EXPORT /** * Deccodes the specified result envelope from binary. * - * @param error The error object. + * @param envelope The error object. * @return The result value, if the envelope represented a successful result, * or a `FlutterError` instance, if not. */ diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index c1d8ebe251d89..52e8017a299af 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -53,7 +53,7 @@ FLUTTER_EXPORT * @param labelPrefix The label prefix used to identify threads for this instance. Should * be unique across FlutterEngine instances, and is used in instrumentation to label * the threads used by this FlutterEngine. - * @param project The `FlutterDartProject` to run. + * @param projectOrNil The `FlutterDartProject` to run. */ - (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)projectOrNil NS_DESIGNATED_INITIALIZER; @@ -91,7 +91,7 @@ FLUTTER_EXPORT * default to `main()`. If it is not the app's main() function, that function * must be decorated with `@pragma(vm:entry-point)` to ensure the method is not * tree-shaken by the Dart compiler. - * @param libraryURI The URI of the Dart library which contains the entrypoint method. IF nil, + * @param uri The URI of the Dart library which contains the entrypoint method. IF nil, * this will default to the same library as the `main()` function in the Dart program. * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. */ diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h b/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h index 9df00af3da7ff..eed2219fd821b 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h @@ -44,7 +44,7 @@ FLUTTER_DEPRECATED("FlutterEngine should be used rather than FlutterHeadlessDart * * @param labelPrefix The label prefix used to identify threads for this instance. Should * be unique across FlutterEngine instances - * @param project The `FlutterDartProject` to run. + * @param projectOrNil The `FlutterDartProject` to run. */ - (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)projectOrNil NS_DESIGNATED_INITIALIZER; diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h b/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h index c077d52cd2a00..2e3f85c6054e0 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h @@ -22,8 +22,8 @@ FLUTTER_EXPORT * The implementation of this method should create a new `UIView` and return it. * * @param frame The rectangle for the newly created `UIView` measued in points. - * @param viewIdentifier A unique identifier for this `UIView`. - * @param arguments Parameters for creating the `UIView` sent from the Dart side of the Flutter app. + * @param viewId A unique identifier for this `UIView`. + * @param args Parameters for creating the `UIView` sent from the Dart side of the Flutter app. * If `createArgsCodec` is not implemented, or if no creation arguments were sent from the Dart * code, this will be null. Otherwise this will be the value sent from the Dart code as decoded by * `createArgsCodec`. diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h b/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h index 4f6497712b619..a116a95efda51 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h @@ -210,7 +210,7 @@ NS_ASSUME_NONNULL_BEGIN * Plugins expose `UIView` for embedding in Flutter apps by registering a view factory. * * @param factory The view factory that will be registered. - * @param factoryId:: A unique identifier for the factory, the Dart code of the Flutter app can use + * @param factoryId A unique identifier for the factory, the Dart code of the Flutter app can use * this identifier to request creation of a `UIView` by the registered factory. */ - (void)registerViewFactory:(NSObject*)factory diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index 34fb7586aff6d..a53f14244cea9 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -41,8 +41,8 @@ FLUTTER_EXPORT * The initialized viewcontroller will attach itself to the engine as part of this process. * * @param engine The `FlutterEngine` instance to attach to. - * @param nibName The NIB name to initialize this UIViewController with. - * @param bundle The NIB bundle + * @param nibNameOrNil The NIB name to initialize this UIViewController with. + * @param nibBundleOrNil The NIB bundle. */ - (instancetype)initWithEngine:(FlutterEngine*)engine nibName:(NSString*)nibNameOrNil @@ -53,8 +53,8 @@ FLUTTER_EXPORT * `FlutterDartProject`. * * @param projectOrNil The `FlutterDartProject` to initialize the `FlutterEngine` with. - * @param nibName The NIB name to initialize this UIViewController with. - * @param bundle The NIB bundle + * @param nibNameOrNil The NIB name to initialize this UIViewController with. + * @param nibBundleOrNil The NIB bundle. */ - (instancetype)initWithProject:(FlutterDartProject*)projectOrNil nibName:(NSString*)nibNameOrNil diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 90efe183316fa..6a701d06669da 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -69,19 +69,7 @@ "has no ViewController."; return nullptr; } - - fml::AutoResetWaitableEvent latch; - std::unique_ptr surface; - auto gpu_task = [ios_surface = ios_surface_.get(), &surface, &latch]() mutable { - if (ios_surface) { - surface = ios_surface->CreateGPUSurface(); - } - latch.Signal(); - }; - - fml::TaskRunner::RunNowOrPostTask(task_runners_.GetGPUTaskRunner(), gpu_task); - latch.Wait(); - return surface; + return ios_surface_->CreateGPUSurface(); } // |shell::PlatformView|