diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index 02ea92bc9d500..76db728261794 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -39,7 +39,7 @@ _flutter_framework_headers = [ _flutter_framework_headers_copy_dir = "$_flutter_framework_dir/Headers" -source_set("flutter_framework_source_arc") { +source_set("flutter_framework_source") { visibility = [ ":*" ] cflags_objc = flutter_cflags_objc_arc cflags_objcc = flutter_cflags_objcc_arc @@ -48,15 +48,10 @@ source_set("flutter_framework_source_arc") { if (darwin_extension_safe) { defines += [ "APPLICATION_EXTENSION_API_ONLY=1" ] } - allow_circular_includes_from = [ ":flutter_framework_source" ] - deps = [ - ":flutter_framework_source", - "//flutter/fml", - "//flutter/shell/platform/common:common_cpp_input", - "//flutter/shell/platform/darwin/common:framework_common", - "//flutter/third_party/icu", + public_configs = [ + ":ios_gpu_configuration_config", + "//flutter:config", ] - public_configs = [ "//flutter:config" ] sources = [ "framework/Source/FlutterAppDelegate.mm", @@ -157,81 +152,46 @@ source_set("flutter_framework_source_arc") { "ios_surface_software.mm", "platform_message_handler_ios.h", "platform_message_handler_ios.mm", + "platform_view_ios.h", + "platform_view_ios.mm", "rendering_api_selection.h", "rendering_api_selection.mm", ] + sources += _flutter_framework_headers frameworks = [ - "UIKit.framework", + "AudioToolbox.framework", + "CoreMedia.framework", + "CoreVideo.framework", "IOSurface.framework", + "QuartzCore.framework", + "UIKit.framework", ] + if (flutter_runtime_mode == "profile" || flutter_runtime_mode == "debug") { + # This is required by the profiler_metrics_ios.mm to get GPU statistics. + # Usage in release builds will cause rejection from the App Store. + frameworks += [ "IOKit.framework" ] + } - deps += [ + deps = [ ":ios_gpu_configuration", "//flutter/common:common", "//flutter/common/graphics", + "//flutter/fml", "//flutter/lib/ui", "//flutter/runtime", "//flutter/shell/common", + "//flutter/shell/platform/common:common_cpp_input", "//flutter/shell/platform/darwin/common", + "//flutter/shell/platform/darwin/common:framework_common", "//flutter/shell/platform/darwin/graphics", "//flutter/shell/platform/embedder:embedder_as_internal_library", "//flutter/shell/profiling:profiling", + "//flutter/third_party/icu", "//flutter/third_party/spring_animation", ] } -source_set("flutter_framework_source") { - visibility = [ ":*" ] - cflags_objc = flutter_cflags_objc - cflags_objcc = flutter_cflags_objcc - - deps = [] - - sources = [ - # iOS embedder is migrating to ARC. - # New files are highly encouraged to be in ARC. - # To add new files in ARC, add them to the `flutter_framework_source_arc` target. - "platform_view_ios.h", - "platform_view_ios.mm", - ] - - sources += _flutter_framework_headers - - defines = [ "FLUTTER_FRAMEWORK=1" ] - if (darwin_extension_safe) { - defines += [ "APPLICATION_EXTENSION_API_ONLY=1" ] - } - - deps += [ - "//flutter/fml", - "//flutter/runtime", - "//flutter/shell/common", - "//flutter/shell/platform/darwin/common", - "//flutter/shell/platform/darwin/common:framework_common", - "//flutter/shell/platform/embedder:embedder_as_internal_library", - "//flutter/shell/profiling:profiling", - ] - - public_configs = [ - ":ios_gpu_configuration_config", - "//flutter:config", - ] - - frameworks = [ - "AudioToolbox.framework", - "CoreMedia.framework", - "CoreVideo.framework", - "QuartzCore.framework", - "UIKit.framework", - ] - if (flutter_runtime_mode == "profile" || flutter_runtime_mode == "debug") { - # This is required by the profiler_metrics_ios.mm to get GPU statistics. - # Usage in release builds will cause rejection from the App Store. - frameworks += [ "IOKit.framework" ] - } -} - platform_frameworks_path = rebase_path("$ios_sdk_path/../../Library/Frameworks/") @@ -296,7 +256,6 @@ shared_library("ios_test_flutter") { deps = [ ":flutter_framework", ":flutter_framework_source", - ":flutter_framework_source_arc", ":ios_gpu_configuration", "//flutter/common:common", "//flutter/lib/ui:ui", @@ -333,10 +292,7 @@ shared_library("create_flutter_framework_dylib") { public = _flutter_framework_headers - deps = [ - ":flutter_framework_source", - ":flutter_framework_source_arc", - ] + deps = [ ":flutter_framework_source" ] public_configs = [ "//flutter:config" ] } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index b5398514d2e9c..d5b69257f7173 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -12,7 +12,6 @@ #include "flutter/common/constants.h" #include "flutter/fml/message_loop.h" #include "flutter/fml/platform/darwin/platform_version.h" -#include "flutter/fml/platform/darwin/weak_nsobject.h" #include "flutter/fml/trace_event.h" #include "flutter/runtime/ptrace_check.h" #include "flutter/shell/common/engine.h" @@ -152,10 +151,6 @@ @implementation FlutterEngine { std::shared_ptr _threadHost; std::unique_ptr _shell; - // TODO(cbracken): https://github.com/flutter/flutter/issues/155943 - // Migrate to @property(nonatomic, weak). - fml::WeakNSObject _viewController; - std::shared_ptr _platformViewsController; flutter::IOSRenderingAPI _renderingApi; std::shared_ptr _profiler; @@ -406,8 +401,7 @@ - (void)ensureSemanticsEnabled { - (void)setViewController:(FlutterViewController*)viewController { FML_DCHECK(self.iosPlatformView); - _viewController = viewController ? [viewController getWeakNSObject] - : fml::WeakNSObject(); + _viewController = viewController; self.iosPlatformView->SetOwnerViewController(_viewController); [self maybeSetupPlatformViewChannels]; [self updateDisplays]; @@ -454,7 +448,7 @@ - (void)notifyViewControllerDeallocated { } } [self.textInputPlugin resetViewResponder]; - _viewController.reset(); + _viewController = nil; } - (void)destroyContext { @@ -466,13 +460,6 @@ - (void)destroyContext { _platformViewsController.reset(); } -- (FlutterViewController*)viewController { - if (!_viewController) { - return nil; - } - return _viewController.get(); -} - - (std::shared_ptr&)platformViewsController { return _platformViewsController; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 2ef686974f793..e4dbf2546fdf5 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -153,11 +153,7 @@ - (void)handleKeyboardAnimationCallbackWithTargetTime:(fml::TimePoint)targetTime @end @implementation FlutterViewController { - // TODO(cbracken): https://github.com/flutter/flutter/issues/137801 - // Eliminate once we can use weak pointers in platform_view_ios.h. - std::unique_ptr> _weakFactory; FlutterEngine* _engine; - flutter::ViewportMetrics _viewportMetrics; MouseState _mouseState; } @@ -189,7 +185,6 @@ - (instancetype)initWithEngine:(FlutterEngine*)engine _flutterView = [[FlutterView alloc] initWithDelegate:_engine opaque:self.isViewOpaque enableWideGamut:engine.project.isWideGamutEnabled]; - _weakFactory = std::make_unique>(self); _ongoingTouches = [[NSMutableSet alloc] init]; // TODO(cbracken): https://github.com/flutter/flutter/issues/157140 @@ -256,7 +251,6 @@ - (void)sharedSetupWithProject:(nullable FlutterDartProject*)project project = [[FlutterDartProject alloc] init]; } FlutterView.forceSoftwareRendering = project.settings.enable_software_rendering; - _weakFactory = std::make_unique>(self); FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"io.flutter" project:project allowHeadlessExecution:self.engineAllowHeadlessExecution @@ -312,10 +306,6 @@ - (FlutterEngine*)engine { return _engine; } -- (fml::WeakNSObject)getWeakNSObject { - return _weakFactory->GetWeakNSObject(); -} - - (void)setUpNotificationCenterObservers { NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; [center addObserver:self @@ -980,10 +970,6 @@ - (void)deregisterNotifications { } - (void)dealloc { - // It will be destroyed and invalidate its weak pointers - // before any other members are destroyed. - _weakFactory.reset(); - // TODO(cbracken): https://github.com/flutter/flutter/issues/157140 // Eliminate method calls in initializers and dealloc. [self removeInternalPlugins]; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h index db9fc37bfd75f..62a7df4133a1d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h @@ -5,7 +5,6 @@ #ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERVIEWCONTROLLER_INTERNAL_H_ #define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERVIEWCONTROLLER_INTERNAL_H_ -#include "flutter/fml/platform/darwin/weak_nsobject.h" #include "flutter/fml/time/time_point.h" #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" @@ -57,7 +56,6 @@ typedef void (^FlutterKeyboardAnimationCallback)(fml::TimePoint); */ @property(nonatomic, assign, readwrite) BOOL prefersStatusBarHidden; -- (fml::WeakNSObject)getWeakNSObject; - (std::shared_ptr&)platformViewsController; - (FlutterRestorationPlugin*)restorationPlugin; diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm index b3a69b1ab5d8d..56f9da5fa8200 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm @@ -55,7 +55,7 @@ void PostAccessibilityNotification(UIAccessibilityNotifications notification, weak_factory_(this) { accessibility_channel_.reset([[FlutterBasicMessageChannel alloc] initWithName:@"flutter/accessibility" - binaryMessenger:platform_view->GetOwnerViewController().get().engine.binaryMessenger + binaryMessenger:platform_view->GetOwnerViewController().engine.binaryMessenger codec:[FlutterStandardMessageCodec sharedInstance]]); [accessibility_channel_.get() setMessageHandler:^(id message, FlutterReply reply) { HandleEvent((NSDictionary*)message); @@ -69,7 +69,7 @@ void PostAccessibilityNotification(UIAccessibilityNotifications notification, } UIView* AccessibilityBridge::textInputView() { - return [[platform_view_->GetOwnerViewController().get().engine textInputPlugin] textInputView]; + return [[platform_view_->GetOwnerViewController().engine textInputPlugin] textInputView]; } void AccessibilityBridge::AccessibilityObjectDidBecomeFocused(int32_t id) { diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm index f89c02febf616..63c2b14794bf9 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -1402,9 +1402,7 @@ - (void)testAccessibilityObjectDidBecomeFocused { /*is_gpu_disabled_sync_switch=*/std::make_shared()); fml::AutoResetWaitableEvent latch; thread_task_runner->PostTask([&] { - auto weakFactory = - std::make_unique>(flutterViewController); - platform_view->SetOwnerViewController(weakFactory->GetWeakNSObject()); + platform_view->SetOwnerViewController(flutterViewController); auto bridge = std::make_unique(/*view=*/nil, /*platform_view=*/platform_view.get(), @@ -2091,9 +2089,7 @@ - (void)testAccessibilityMessageAfterDeletion { /*is_gpu_disabled_sync_switch=*/std::make_shared()); fml::AutoResetWaitableEvent latch; thread_task_runner->PostTask([&] { - auto weakFactory = - std::make_unique>(flutterViewController); - platform_view->SetOwnerViewController(weakFactory->GetWeakNSObject()); + platform_view->SetOwnerViewController(flutterViewController); auto bridge = std::make_unique(/*view=*/nil, /*platform_view=*/platform_view.get(), @@ -2184,9 +2180,7 @@ - (void)testPlatformViewDestructorDoesNotCallSemanticsAPIs { OCMStub([mockFlutterViewController platformViewsController]) .andReturn(flutterPlatformViewsController.get()); - auto weakFactory = std::make_unique>( - mockFlutterViewController); - platform_view->SetOwnerViewController(weakFactory->GetWeakNSObject()); + platform_view->SetOwnerViewController(mockFlutterViewController); platform_view->SetSemanticsEnabled(true); XCTAssertNotEqual(test_delegate.set_semantics_enabled_calls, 0); diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index 299015d785074..0e65e6174f594 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -9,8 +9,6 @@ #include "flutter/fml/closure.h" #include "flutter/fml/macros.h" -#include "flutter/fml/platform/darwin/scoped_nsobject.h" -#include "flutter/fml/platform/darwin/weak_nsobject.h" #include "flutter/shell/common/platform_view.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h" #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" @@ -59,14 +57,14 @@ class PlatformViewIOS final : public PlatformView { * Returns the `FlutterViewController` currently attached to the `FlutterEngine` owning * this PlatformViewIOS. */ - fml::WeakNSObject GetOwnerViewController() const; + FlutterViewController* GetOwnerViewController() const __attribute__((cf_audited_transfer)); /** * Updates the `FlutterViewController` currently attached to the `FlutterEngine` owning * this PlatformViewIOS. This should be updated when the `FlutterEngine` * is given a new `FlutterViewController`. */ - void SetOwnerViewController(const fml::WeakNSObject& owner_controller); + void SetOwnerViewController(__weak FlutterViewController* owner_controller); /** * Called one time per `FlutterViewController` when the `FlutterViewController`'s @@ -133,7 +131,7 @@ class PlatformViewIOS final : public PlatformView { std::function set_semantics_enabled_; }; - fml::WeakNSObject owner_controller_; + __weak FlutterViewController* owner_controller_; // Since the `ios_surface_` is created on the platform thread but // used on the raster thread we need to protect it with a mutex. std::mutex ios_surface_mutex_; @@ -141,7 +139,6 @@ class PlatformViewIOS final : public PlatformView { std::shared_ptr ios_context_; const std::shared_ptr& platform_views_controller_; AccessibilityBridgeManager accessibility_bridge_; - fml::scoped_nsprotocol text_input_plugin_; ScopedObserver dealloc_view_controller_observer_; std::vector platform_resolved_locale_; std::shared_ptr platform_message_handler_; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 1e58148319e84..4541e1039ed78 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -14,6 +14,8 @@ #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h" #import "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h" +FLUTTER_ASSERT_ARC + namespace flutter { PlatformViewIOS::AccessibilityBridgeManager::AccessibilityBridgeManager( @@ -74,12 +76,11 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} platform_message_handler_->HandlePlatformMessage(std::move(message)); } -fml::WeakNSObject PlatformViewIOS::GetOwnerViewController() const { +FlutterViewController* PlatformViewIOS::GetOwnerViewController() const { return owner_controller_; } -void PlatformViewIOS::SetOwnerViewController( - const fml::WeakNSObject& owner_controller) { +void PlatformViewIOS::SetOwnerViewController(__weak FlutterViewController* owner_controller) { FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); std::lock_guard guard(ios_surface_mutex_); if (ios_surface_ || !owner_controller) { @@ -91,17 +92,17 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} // Add an observer that will clear out the owner_controller_ ivar and // the accessibility_bridge_ in case the view controller is deleted. - dealloc_view_controller_observer_.reset( - [[[NSNotificationCenter defaultCenter] addObserverForName:FlutterViewControllerWillDealloc - object:owner_controller_.get() - queue:[NSOperationQueue mainQueue] - usingBlock:^(NSNotification* note) { - // Implicit copy of 'this' is fine. - accessibility_bridge_.Clear(); - owner_controller_.reset(); - }] retain]); - - if (owner_controller_ && [owner_controller_.get() isViewLoaded]) { + dealloc_view_controller_observer_.reset([[NSNotificationCenter defaultCenter] + addObserverForName:FlutterViewControllerWillDealloc + object:owner_controller_ + queue:[NSOperationQueue mainQueue] + usingBlock:^(NSNotification* note) { + // Implicit copy of 'this' is fine. + accessibility_bridge_.Clear(); + owner_controller_ = nil; + }]); + + if (owner_controller_ && owner_controller_.isViewLoaded) { this->attachView(); } // Do not call `NotifyCreated()` here - let FlutterViewController take care @@ -112,17 +113,16 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} void PlatformViewIOS::attachView() { FML_DCHECK(owner_controller_); - FML_DCHECK(owner_controller_.get().isViewLoaded) - << "FlutterViewController's view should be loaded " - "before attaching to PlatformViewIOS."; - auto flutter_view = static_cast(owner_controller_.get().view); - auto ca_layer = fml::scoped_nsobject{[[flutter_view layer] retain]}; + FML_DCHECK(owner_controller_.isViewLoaded) << "FlutterViewController's view should be loaded " + "before attaching to PlatformViewIOS."; + FlutterView* flutter_view = static_cast(owner_controller_.view); + auto ca_layer = fml::scoped_nsobject{[flutter_view layer]}; ios_surface_ = IOSSurface::Create(ios_context_, ca_layer); FML_DCHECK(ios_surface_ != nullptr); if (accessibility_bridge_) { accessibility_bridge_.Set(std::make_unique( - owner_controller_.get(), this, [owner_controller_.get() platformViewsController])); + owner_controller_, this, owner_controller_.platformViewsController)); } } @@ -135,7 +135,7 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} void PlatformViewIOS::RegisterExternalTexture(int64_t texture_id, NSObject* texture) { RegisterTexture(ios_context_->CreateExternalTexture( - texture_id, fml::scoped_nsobject>{[texture retain]})); + texture_id, fml::scoped_nsobject>{texture})); } // |PlatformView| @@ -174,7 +174,7 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} } if (enabled && !accessibility_bridge_) { accessibility_bridge_.Set(std::make_unique( - owner_controller_.get(), this, [owner_controller_.get() platformViewsController])); + owner_controller_, this, owner_controller_.platformViewsController)); } else if (!enabled && accessibility_bridge_) { accessibility_bridge_.Clear(); } else { @@ -194,7 +194,7 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} if (accessibility_bridge_) { accessibility_bridge_.get()->UpdateSemantics(std::move(update), actions); [[NSNotificationCenter defaultCenter] postNotificationName:FlutterSemanticsUpdateNotification - object:owner_controller_.get()]; + object:owner_controller_]; } } @@ -210,8 +210,8 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} if (!owner_controller_) { return; } - [owner_controller_.get() platformViewsController]->Reset(); - [[owner_controller_.get() restorationPlugin] reset]; + owner_controller_.platformViewsController->Reset(); + [owner_controller_.restorationPlugin reset]; } std::unique_ptr> PlatformViewIOS::ComputePlatformResolvedLocales( @@ -253,7 +253,6 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} PlatformViewIOS::ScopedObserver::~ScopedObserver() { if (observer_) { [[NSNotificationCenter defaultCenter] removeObserver:observer_]; - [observer_ release]; } } @@ -261,7 +260,6 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} if (observer != observer_) { if (observer_) { [[NSNotificationCenter defaultCenter] removeObserver:observer_]; - [observer_ release]; } observer_ = observer; }