From 004b2a5a714a7de995bb86489d2330696af407f7 Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Tue, 20 Oct 2020 14:49:49 -0700 Subject: [PATCH 1/3] Reland "[ios] Refactor IOSSurface factory and unify surface creation" This reverts commit 0c7c477245041d02220ae322b3d601eb3cc05bf9. --- ci/licenses_golden/licenses_flutter | 2 + shell/platform/darwin/ios/BUILD.gn | 2 + .../ios/framework/Source/FlutterEngine.mm | 26 ++++++++---- .../Source/FlutterEnginePlatformViewTest.mm | 1 + .../ios/framework/Source/FlutterOverlayView.h | 2 - .../framework/Source/FlutterOverlayView.mm | 8 ---- .../framework/Source/FlutterPlatformViews.mm | 9 ++-- .../Source/FlutterPlatformViewsTest.mm | 42 +++++++++++++++---- .../Source/FlutterPlatformViews_Internal.h | 9 +++- .../Source/FlutterPlatformViews_Internal.mm | 5 ++- .../darwin/ios/framework/Source/FlutterView.h | 1 - .../ios/framework/Source/FlutterView.mm | 9 ---- .../Source/accessibility_bridge_test.mm | 17 +++++++- .../platform/darwin/ios/ios_surface_factory.h | 39 +++++++++++++++++ .../darwin/ios/ios_surface_factory.mm | 30 +++++++++++++ shell/platform/darwin/ios/platform_view_ios.h | 3 ++ .../platform/darwin/ios/platform_view_ios.mm | 8 +++- 17 files changed, 167 insertions(+), 46 deletions(-) create mode 100644 shell/platform/darwin/ios/ios_surface_factory.h create mode 100644 shell/platform/darwin/ios/ios_surface_factory.mm diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index c6e5047eaa2bb..aea08acb9b27b 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1016,6 +1016,8 @@ FILE: ../../../flutter/shell/platform/darwin/ios/ios_render_target_gl.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_render_target_gl.mm FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface.mm +FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_factory.h +FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_factory.mm FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_gl.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_gl.mm FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_metal.h diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index c0caf9f94d588..764fc726fa117 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -99,6 +99,8 @@ source_set("flutter_framework_source") { "ios_render_target_gl.mm", "ios_surface.h", "ios_surface.mm", + "ios_surface_factory.h", + "ios_surface_factory.mm", "ios_surface_gl.h", "ios_surface_gl.mm", "ios_surface_software.h", diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 8a0de614f10ec..48ee39b1c82af 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -28,7 +28,9 @@ #import "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" #import "flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.h" #import "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h" +#import "flutter/shell/platform/darwin/ios/ios_context.h" #import "flutter/shell/platform/darwin/ios/ios_surface.h" +#import "flutter/shell/platform/darwin/ios/ios_surface_factory.h" #import "flutter/shell/platform/darwin/ios/platform_view_ios.h" #import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" #include "flutter/shell/profiling/sampling_profiler.h" @@ -64,6 +66,7 @@ @implementation FlutterEngine { fml::scoped_nsobject _publisher; std::shared_ptr _platformViewsController; + std::shared_ptr _surfaceFactory; std::unique_ptr _profiler_metrics; std::unique_ptr _profiler; @@ -128,7 +131,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix _pluginPublications = [NSMutableDictionary new]; _registrars = [[NSMutableDictionary alloc] init]; - _platformViewsController.reset(new flutter::FlutterPlatformViewsController()); + [self ensurePlatformViewController]; _binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self]; _connections.reset(new flutter::ConnectionCollection()); @@ -162,6 +165,16 @@ - (instancetype)initWithName:(NSString*)labelPrefix return self; } +- (void)ensurePlatformViewController { + if (!_platformViewsController) { + auto renderingApi = flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering); + _surfaceFactory = flutter::IOSSurfaceFactory::Create(renderingApi); + auto pvc = new flutter::FlutterPlatformViewsController(_surfaceFactory); + _surfaceFactory->SetPlatformViewsController(pvc); + _platformViewsController.reset(pvc); + } +} + - (void)dealloc { /// Notify plugins of dealloc. This should happen first in dealloc since the /// plugins may be talking to things like the binaryMessenger. @@ -520,13 +533,13 @@ - (BOOL)createShell:(NSString*)entrypoint threadHostType}; // Lambda captures by pointers to ObjC objects are fine here because the - // create call is - // synchronous. + // create call is synchronous. flutter::Shell::CreateCallback on_create_platform_view = - [](flutter::Shell& shell) { + [self](flutter::Shell& shell) { + [self ensurePlatformViewController]; return std::make_unique( shell, flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering), - shell.GetTaskRunners()); + self->_surfaceFactory, shell.GetTaskRunners()); }; flutter::Shell::CreateCallback on_create_rasterizer = @@ -554,9 +567,6 @@ - (BOOL)createShell:(NSString*)entrypoint [self setupChannels]; [self onLocaleUpdated:nil]; [self initializeDisplays]; - if (!_platformViewsController) { - _platformViewsController.reset(new flutter::FlutterPlatformViewsController()); - } _publisher.reset([[FlutterObservatoryPublisher alloc] initWithEnableObservatoryPublication:settings.enable_observatory_publication]); [self maybeSetupPlatformViewChannels]; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm index a202eba4d8d8d..3e002e2aa78ee 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm @@ -67,6 +67,7 @@ - (void)testCallsNotifyLowMemory { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id project = OCMClassMock([FlutterDartProject class]); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h b/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h index cb56163c6c5c2..b77ac7181853f 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h @@ -35,8 +35,6 @@ - (instancetype)init NS_DESIGNATED_INITIALIZER; - (instancetype)initWithContentsScale:(CGFloat)contentsScale; -- (std::unique_ptr)createSurface: - (std::shared_ptr)ios_context; @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.mm b/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.mm index f6a0cd8239756..345d3a36798cb 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.mm @@ -62,14 +62,6 @@ + (Class)layerClass { return [FlutterView layerClass]; } -- (std::unique_ptr)createSurface: - (std::shared_ptr)ios_context { - return flutter::IOSSurface::Create(std::move(ios_context), // context - fml::scoped_nsobject{[self.layer retain]}, // layer - nullptr // platform views controller - ); -} - // TODO(amirh): implement drawLayer to support snapshotting. @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 2d14282d096ad..9c0dc2f003303 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -16,6 +16,7 @@ #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h" #import "flutter/shell/platform/darwin/ios/ios_surface.h" +#import "flutter/shell/platform/darwin/ios/ios_surface_factory.h" #import "flutter/shell/platform/darwin/ios/ios_surface_gl.h" namespace flutter { @@ -32,8 +33,8 @@ overlay_view.reset([[FlutterOverlayView alloc] init]); overlay_view_wrapper.reset([[FlutterOverlayView alloc] init]); - std::unique_ptr ios_surface = - [overlay_view.get() createSurface:std::move(ios_context)]; + auto ca_layer = fml::scoped_nsobject{[[overlay_view.get() layer] retain]}; + std::unique_ptr ios_surface = ios_surface_factory_->CreateSurface(ca_layer); std::unique_ptr surface = ios_surface->CreateGPUSurface(); layer = std::make_shared( @@ -44,8 +45,8 @@ overlay_view.reset([[FlutterOverlayView alloc] initWithContentsScale:screenScale]); overlay_view_wrapper.reset([[FlutterOverlayView alloc] initWithContentsScale:screenScale]); - std::unique_ptr ios_surface = - [overlay_view.get() createSurface:std::move(ios_context)]; + auto ca_layer = fml::scoped_nsobject{[[overlay_view.get() layer] retain]}; + std::unique_ptr ios_surface = ios_surface_factory_->CreateSurface(ca_layer); std::unique_ptr surface = ios_surface->CreateGPUSurface(gr_context); layer = std::make_shared( diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 283a86cf2ae46..0a890b7e92882 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -121,12 +121,16 @@ - (void)testCanCreatePlatformViewWithoutFlutterView { /*raster=*/thread_task_runner, /*ui=*/thread_task_runner, /*io=*/thread_task_runner); + auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*ios_surface_factory=*/surface_factory, /*task_runners=*/runners); - auto flutterPlatformViewsController = std::make_unique(); + auto flutterPlatformViewsController = + std::make_unique(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -175,12 +179,16 @@ - (void)testCompositePlatformView { /*raster=*/thread_task_runner, /*ui=*/thread_task_runner, /*io=*/thread_task_runner); + auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*ios_surface_factory=*/surface_factory, /*task_runners=*/runners); - auto flutterPlatformViewsController = std::make_unique(); + auto flutterPlatformViewsController = + std::make_unique(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -230,12 +238,16 @@ - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView { /*raster=*/thread_task_runner, /*ui=*/thread_task_runner, /*io=*/thread_task_runner); + auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*ios_surface_factory=*/surface_factory, /*task_runners=*/runners); - auto flutterPlatformViewsController = std::make_unique(); + auto flutterPlatformViewsController = + std::make_unique(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -301,12 +313,16 @@ - (void)testClipRect { /*raster=*/thread_task_runner, /*ui=*/thread_task_runner, /*io=*/thread_task_runner); + auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*ios_surface_factory=*/surface_factory, /*task_runners=*/runners); - auto flutterPlatformViewsController = std::make_unique(); + auto flutterPlatformViewsController = + std::make_unique(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -373,12 +389,16 @@ - (void)testClipRRect { /*raster=*/thread_task_runner, /*ui=*/thread_task_runner, /*io=*/thread_task_runner); + auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*ios_surface_factory=*/surface_factory, /*task_runners=*/runners); - auto flutterPlatformViewsController = std::make_unique(); + auto flutterPlatformViewsController = + std::make_unique(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -445,12 +465,16 @@ - (void)testClipPath { /*raster=*/thread_task_runner, /*ui=*/thread_task_runner, /*io=*/thread_task_runner); + auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*ios_surface_factory=*/surface_factory, /*task_runners=*/runners); - auto flutterPlatformViewsController = std::make_unique(); + auto flutterPlatformViewsController = + std::make_unique(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -518,12 +542,16 @@ - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents { /*raster=*/thread_task_runner, /*ui=*/thread_task_runner, /*io=*/thread_task_runner); + auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*ios_surface_factory=*/surface_factory, /*task_runners=*/runners); - auto flutterPlatformViewsController = std::make_unique(); + auto flutterPlatformViewsController = + std::make_unique(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index 4fcaaf3874212..d9638d75b6b15 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -61,6 +61,7 @@ void ResetAnchor(CALayer* layer); class IOSContextGL; class IOSSurface; +class IOSSurfaceFactory; struct FlutterPlatformViewLayer { FlutterPlatformViewLayer(fml::scoped_nsobject overlay_view, @@ -87,7 +88,9 @@ struct FlutterPlatformViewLayer { // This class isn't thread safe. class FlutterPlatformViewLayerPool { public: - FlutterPlatformViewLayerPool() = default; + FlutterPlatformViewLayerPool(std::shared_ptr ios_surface_factory) + : ios_surface_factory_(ios_surface_factory) {} + ~FlutterPlatformViewLayerPool() = default; // Gets a layer from the pool if available, or allocates a new one. @@ -118,12 +121,14 @@ class FlutterPlatformViewLayerPool { size_t available_layer_index_ = 0; std::vector> layers_; + const std::shared_ptr ios_surface_factory_; + FML_DISALLOW_COPY_AND_ASSIGN(FlutterPlatformViewLayerPool); }; class FlutterPlatformViewsController { public: - FlutterPlatformViewsController(); + FlutterPlatformViewsController(std::shared_ptr surface_factory); ~FlutterPlatformViewsController(); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm index a6d3d03653b17..a46684ccb1064 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm @@ -23,8 +23,9 @@ FlutterPlatformViewLayer::~FlutterPlatformViewLayer() = default; -FlutterPlatformViewsController::FlutterPlatformViewsController() - : layer_pool_(std::make_unique()), +FlutterPlatformViewsController::FlutterPlatformViewsController( + std::shared_ptr surface_factory) + : layer_pool_(std::make_unique(surface_factory)), weak_factory_(std::make_unique>(this)){}; FlutterPlatformViewsController::~FlutterPlatformViewsController() = default; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterView.h b/shell/platform/darwin/ios/framework/Source/FlutterView.h index b874bbc8636ff..0cdd56d2cfbdc 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterView.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterView.h @@ -32,7 +32,6 @@ - (instancetype)initWithDelegate:(id)delegate opaque:(BOOL)opaque NS_DESIGNATED_INITIALIZER; -- (std::unique_ptr)createSurface:(std::shared_ptr)context; // Set by FlutterEngine or FlutterViewController to override software rendering. @property(class, nonatomic) BOOL forceSoftwareRendering; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterView.mm b/shell/platform/darwin/ios/framework/Source/FlutterView.mm index 3f6b19decdac3..73a9b8b529088 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterView.mm @@ -83,15 +83,6 @@ + (Class)layerClass { flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering)); } -- (std::unique_ptr)createSurface: - (std::shared_ptr)ios_context { - return flutter::IOSSurface::Create( - std::move(ios_context), // context - fml::scoped_nsobject{[self.layer retain]}, // layer - [_delegate platformViewsController] // platform views controller - ); -} - - (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context { TRACE_EVENT0("flutter", "SnapshotFlutterView"); 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 fea18becd87b6..2436a93c90c50 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -137,6 +137,7 @@ - (void)testCreate { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); auto bridge = std::make_unique(/*view=*/nil, @@ -156,6 +157,7 @@ - (void)testUpdateSemanticsEmpty { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterView = OCMClassMock([FlutterView class]); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); @@ -182,6 +184,7 @@ - (void)testUpdateSemanticsOneNode { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterView = OCMClassMock([FlutterView class]); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); @@ -224,9 +227,12 @@ - (void)testSemanticsDeallocated { /*raster=*/thread_task_runner, /*ui=*/thread_task_runner, /*io=*/thread_task_runner); + + auto surfaceFactory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*ios_surface_factory=*/surfaceFactory, /*task_runners=*/runners); id mockFlutterView = OCMClassMock([FlutterView class]); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); @@ -234,8 +240,9 @@ - (void)testSemanticsDeallocated { std::string label = "some label"; auto flutterPlatformViewsController = - std::make_shared(); + std::make_shared(surfaceFactory); flutterPlatformViewsController->SetFlutterView(mockFlutterView); + surfaceFactory->SetPlatformViewsController(flutterPlatformViewsController.get()); MockFlutterPlatformFactory* factory = [[MockFlutterPlatformFactory new] autorelease]; flutterPlatformViewsController->RegisterViewFactory( @@ -279,6 +286,7 @@ - (void)testAnnouncesRouteChanges { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterView = OCMClassMock([FlutterView class]); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); @@ -516,6 +524,7 @@ - (void)testAnnouncesRouteChangesWhenNoNamesRoute { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterView = OCMClassMock([FlutterView class]); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); @@ -583,6 +592,7 @@ - (void)testAnnouncesLayoutChangeWithNilIfLastFocusIsRemoved { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); id mockFlutterView = OCMClassMock([FlutterView class]); @@ -649,6 +659,7 @@ - (void)testAnnouncesLayoutChangeWithLastFocused { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); id mockFlutterView = OCMClassMock([FlutterView class]); @@ -721,6 +732,7 @@ - (void)testAnnouncesLayoutChangeWhenFocusMovedOutside { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); id mockFlutterView = OCMClassMock([FlutterView class]); @@ -795,6 +807,7 @@ - (void)testAnnouncesScrollChangeWithLastFocused { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); id mockFlutterView = OCMClassMock([FlutterView class]); @@ -865,6 +878,7 @@ - (void)testAnnouncesIgnoresRouteChangesWhenModal { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterView = OCMClassMock([FlutterView class]); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); @@ -932,6 +946,7 @@ - (void)testAccessibilityMessageAfterDeletion { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); fml::AutoResetWaitableEvent latch; thread_task_runner->PostTask([&] { diff --git a/shell/platform/darwin/ios/ios_surface_factory.h b/shell/platform/darwin/ios/ios_surface_factory.h new file mode 100644 index 0000000000000..a692c56754887 --- /dev/null +++ b/shell/platform/darwin/ios/ios_surface_factory.h @@ -0,0 +1,39 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS__SURFACE_FACTORY_H_ +#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS__SURFACE_FACTORY_H_ + +#include + +#import "flutter/shell/platform/darwin/ios/ios_surface.h" +#import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" + +namespace flutter { + +class IOSSurfaceFactory { + public: + static std::shared_ptr Create( + IOSRenderingAPI rendering_api); + + explicit IOSSurfaceFactory(std::shared_ptr ios_context); + + ~IOSSurfaceFactory(); + + void SetPlatformViewsController( + FlutterPlatformViewsController* platform_views_controller); + + std::unique_ptr CreateSurface( + fml::scoped_nsobject ca_layer); + + private: + FlutterPlatformViewsController* platform_views_controller_; + std::shared_ptr ios_context_; + + FML_DISALLOW_COPY_AND_ASSIGN(IOSSurfaceFactory); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS__SURFACE_FACTORY_H_ diff --git a/shell/platform/darwin/ios/ios_surface_factory.mm b/shell/platform/darwin/ios/ios_surface_factory.mm new file mode 100644 index 0000000000000..4ed7d4c0b96a9 --- /dev/null +++ b/shell/platform/darwin/ios/ios_surface_factory.mm @@ -0,0 +1,30 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "flutter/shell/platform/darwin/ios/ios_surface_factory.h" +#import "flutter/shell/platform/darwin/ios/ios_context.h" + +namespace flutter { + +IOSSurfaceFactory::IOSSurfaceFactory(std::shared_ptr ios_context) + : ios_context_(ios_context) {} + +std::shared_ptr IOSSurfaceFactory::Create(IOSRenderingAPI rendering_api) { + std::shared_ptr ios_context = IOSContext::Create(rendering_api); + return std::make_shared(ios_context); +} + +IOSSurfaceFactory::~IOSSurfaceFactory() = default; + +void IOSSurfaceFactory::SetPlatformViewsController( + FlutterPlatformViewsController* platform_views_controller) { + platform_views_controller_ = platform_views_controller; +} + +std::unique_ptr IOSSurfaceFactory::CreateSurface( + fml::scoped_nsobject ca_layer) { + return flutter::IOSSurface::Create(ios_context_, ca_layer, platform_views_controller_); +} + +} // namespace flutter diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index 8e63bbda2f132..661d5e57f5b85 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -19,6 +19,7 @@ #import "flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h" #import "flutter/shell/platform/darwin/ios/ios_context.h" #import "flutter/shell/platform/darwin/ios/ios_surface.h" +#import "flutter/shell/platform/darwin/ios/ios_surface_factory.h" #import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" @class FlutterViewController; @@ -41,6 +42,7 @@ class PlatformViewIOS final : public PlatformView { public: explicit PlatformViewIOS(PlatformView::Delegate& delegate, IOSRenderingAPI rendering_api, + std::shared_ptr surface_factory, flutter::TaskRunners task_runners); ~PlatformViewIOS() override; @@ -124,6 +126,7 @@ class PlatformViewIOS final : public PlatformView { std::mutex ios_surface_mutex_; std::unique_ptr ios_surface_; std::shared_ptr ios_context_; + std::shared_ptr ios_surface_factory_; PlatformMessageRouter platform_message_router_; AccessibilityBridgePtr accessibility_bridge_; fml::scoped_nsprotocol text_input_plugin_; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index faf764be7cb0c..43543c1e2fcde 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -3,6 +3,7 @@ // found in the LICENSE file. #import "flutter/shell/platform/darwin/ios/platform_view_ios.h" +#include #include @@ -46,9 +47,11 @@ PlatformViewIOS::PlatformViewIOS(PlatformView::Delegate& delegate, IOSRenderingAPI rendering_api, + std::shared_ptr surface_factory, flutter::TaskRunners task_runners) : PlatformView(delegate, std::move(task_runners)), ios_context_(IOSContext::Create(rendering_api)), + ios_surface_factory_(surface_factory), accessibility_bridge_([this](bool enabled) { PlatformView::SetSemanticsEnabled(enabled); }) {} PlatformViewIOS::~PlatformViewIOS() = default; @@ -102,8 +105,9 @@ FML_DCHECK(owner_controller_.get().isViewLoaded) << "FlutterViewController's view should be loaded " "before attaching to PlatformViewIOS."; - ios_surface_ = - [static_cast(owner_controller_.get().view) createSurface:ios_context_]; + auto flutter_view = static_cast(owner_controller_.get().view); + auto ca_layer = fml::scoped_nsobject{[[flutter_view layer] retain]}; + ios_surface_ = ios_surface_factory_->CreateSurface(ca_layer); FML_DCHECK(ios_surface_ != nullptr); if (accessibility_bridge_) { From 5fe7ccacc2848e9f4ed9ca7a3192d034fda9b6ad Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Tue, 20 Oct 2020 15:49:59 -0700 Subject: [PATCH 2/3] Recreate platform view controller even if it exists On simulator for example we instantiate the app with `initWithName` after this is done, we might still not have set the `FlutterView.forceSoftwareRendering` which is done in `createShell`. This will ensure that we create the platform view controller with the right rendering api. --- shell/platform/darwin/ios/BUILD.gn | 1 + .../framework/Source/FlutterDartProject.mm | 14 ++++++++-- .../Source/FlutterDartProject_Internal.h | 6 ++++ .../ios/framework/Source/FlutterEngine.mm | 25 +++++++++-------- .../ios/framework/Source/FlutterEngineTest.mm | 21 ++++++++++++++ .../ios/framework/Source/FlutterEngine_Test.h | 2 ++ .../Source/FlutterPlatformViewsTest.mm | 28 +++++++++---------- .../Source/accessibility_bridge_test.mm | 4 ++- .../platform/darwin/ios/ios_surface_factory.h | 5 ++-- .../darwin/ios/ios_surface_factory.mm | 2 +- testing/ios/IosUnitTests/README.md | 4 +-- 11 files changed, 78 insertions(+), 34 deletions(-) diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index 764fc726fa117..99acf3960c825 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -221,6 +221,7 @@ shared_library("ios_test_flutter") { deps = [ ":flutter_framework_source", ":ios_test_flutter_mrc", + "//flutter/common:common", "//flutter/shell/platform/darwin/common:framework_shared", "//flutter/third_party/tonic", "//flutter/third_party/txt", diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm index b87fde573c3ef..d22a9684f3b2a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm @@ -27,7 +27,7 @@ static const char* kApplicationKernelSnapshotFileName = "kernel_blob.bin"; -static flutter::Settings DefaultSettingsForProcess(NSBundle* bundle = nil) { +flutter::Settings FLTDefaultSettingsForBundle(NSBundle* bundle) { auto command_line = flutter::CommandLineFromNSProcessInfo(); // Precedence: @@ -181,7 +181,17 @@ - (instancetype)initWithPrecompiledDartBundle:(nullable NSBundle*)bundle { self = [super init]; if (self) { - _settings = DefaultSettingsForProcess(bundle); + _settings = FLTDefaultSettingsForBundle(bundle); + } + + return self; +} + +- (instancetype)initWithSettings:(const flutter::Settings&)settings { + self = [self initWithPrecompiledDartBundle:nil]; + + if (self) { + _settings = settings; } return self; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h index b5570a321458d..1efdf75880281 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h @@ -12,8 +12,14 @@ NS_ASSUME_NONNULL_BEGIN +flutter::Settings FLTDefaultSettingsForBundle(NSBundle* bundle = nil); + @interface FlutterDartProject () +/** + * This is currently used for *only for tests* to override settings. + */ +- (instancetype)initWithSettings:(const flutter::Settings&)settings; - (const flutter::Settings&)settings; - (const flutter::PlatformData)defaultPlatformData; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 48ee39b1c82af..acac834082fff 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -66,6 +66,7 @@ @implementation FlutterEngine { fml::scoped_nsobject _publisher; std::shared_ptr _platformViewsController; + flutter::IOSRenderingAPI _renderingApi; std::shared_ptr _surfaceFactory; std::unique_ptr _profiler_metrics; std::unique_ptr _profiler; @@ -131,7 +132,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix _pluginPublications = [NSMutableDictionary new]; _registrars = [[NSMutableDictionary alloc] init]; - [self ensurePlatformViewController]; + [self recreatePlatformViewController]; _binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self]; _connections.reset(new flutter::ConnectionCollection()); @@ -165,14 +166,15 @@ - (instancetype)initWithName:(NSString*)labelPrefix return self; } -- (void)ensurePlatformViewController { - if (!_platformViewsController) { - auto renderingApi = flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering); - _surfaceFactory = flutter::IOSSurfaceFactory::Create(renderingApi); - auto pvc = new flutter::FlutterPlatformViewsController(_surfaceFactory); - _surfaceFactory->SetPlatformViewsController(pvc); - _platformViewsController.reset(pvc); - } +- (void)recreatePlatformViewController { + _renderingApi = flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering); + _surfaceFactory = flutter::IOSSurfaceFactory::Create(_renderingApi); + _platformViewsController.reset(new flutter::FlutterPlatformViewsController(_surfaceFactory)); + _surfaceFactory->SetPlatformViewsController(_platformViewsController); +} + +- (flutter::IOSRenderingAPI)platformViewsRenderingAPI { + return _renderingApi; } - (void)dealloc { @@ -536,10 +538,9 @@ - (BOOL)createShell:(NSString*)entrypoint // create call is synchronous. flutter::Shell::CreateCallback on_create_platform_view = [self](flutter::Shell& shell) { - [self ensurePlatformViewController]; + [self recreatePlatformViewController]; return std::make_unique( - shell, flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering), - self->_surfaceFactory, shell.GetTaskRunners()); + shell, self->_renderingApi, self->_surfaceFactory, shell.GetTaskRunners()); }; flutter::Shell::CreateCallback on_create_rasterizer = diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm index cfbb8cbdb87b3..9e56ca45a753d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm @@ -5,8 +5,10 @@ #import #import +#import "flutter/common/settings.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h" FLUTTER_ASSERT_ARC @@ -113,4 +115,23 @@ - (void)testWaitForFirstFrameTimeout { [self waitForExpectationsWithTimeout:1 handler:nil]; } +- (void)testPlatformViewsControllerRenderingMetalBackend { + FlutterEngine* engine = [[FlutterEngine alloc] init]; + [engine run]; + flutter::IOSRenderingAPI renderingApi = [engine platformViewsRenderingAPI]; + + XCTAssertEqual(renderingApi, flutter::IOSRenderingAPI::kMetal); +} + +- (void)testPlatformViewsControllerRenderingSoftware { + auto settings = FLTDefaultSettingsForBundle(); + settings.enable_software_rendering = true; + FlutterDartProject* project = [[FlutterDartProject alloc] initWithSettings:settings]; + FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project]; + [engine run]; + flutter::IOSRenderingAPI renderingApi = [engine platformViewsRenderingAPI]; + + XCTAssertEqual(renderingApi, flutter::IOSRenderingAPI::kSoftware); +} + @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h index 748cc8c642d8b..a458ea167b1f8 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h @@ -3,6 +3,7 @@ // found in the LICENSE file. #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h" +#include "shell/platform/darwin/ios/rendering_api_selection.h" @class FlutterBinaryMessengerRelay; @@ -10,4 +11,5 @@ @interface FlutterEngine (Test) - (void)setBinaryMessenger:(FlutterBinaryMessengerRelay*)binaryMessenger; - (void)waitForFirstFrame:(NSTimeInterval)timeout callback:(void (^)(BOOL didTimeout))callback; +- (flutter::IOSRenderingAPI)platformViewsRenderingAPI; @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 0a890b7e92882..b71b603bc379e 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -129,8 +129,8 @@ - (void)testCanCreatePlatformViewWithoutFlutterView { /*task_runners=*/runners); auto flutterPlatformViewsController = - std::make_unique(surface_factory); - surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); + std::make_shared(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -187,8 +187,8 @@ - (void)testCompositePlatformView { /*task_runners=*/runners); auto flutterPlatformViewsController = - std::make_unique(surface_factory); - surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); + std::make_shared(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -246,8 +246,8 @@ - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView { /*task_runners=*/runners); auto flutterPlatformViewsController = - std::make_unique(surface_factory); - surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); + std::make_shared(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -321,8 +321,8 @@ - (void)testClipRect { /*task_runners=*/runners); auto flutterPlatformViewsController = - std::make_unique(surface_factory); - surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); + std::make_shared(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -397,8 +397,8 @@ - (void)testClipRRect { /*task_runners=*/runners); auto flutterPlatformViewsController = - std::make_unique(surface_factory); - surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); + std::make_shared(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -473,8 +473,8 @@ - (void)testClipPath { /*task_runners=*/runners); auto flutterPlatformViewsController = - std::make_unique(surface_factory); - surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); + std::make_shared(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; @@ -550,8 +550,8 @@ - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents { /*task_runners=*/runners); auto flutterPlatformViewsController = - std::make_unique(surface_factory); - surface_factory->SetPlatformViewsController(flutterPlatformViewsController.get()); + std::make_shared(surface_factory); + surface_factory->SetPlatformViewsController(flutterPlatformViewsController); FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; 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 2436a93c90c50..7596578bd5e64 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -242,7 +242,7 @@ - (void)testSemanticsDeallocated { auto flutterPlatformViewsController = std::make_shared(surfaceFactory); flutterPlatformViewsController->SetFlutterView(mockFlutterView); - surfaceFactory->SetPlatformViewsController(flutterPlatformViewsController.get()); + surfaceFactory->SetPlatformViewsController(flutterPlatformViewsController); MockFlutterPlatformFactory* factory = [[MockFlutterPlatformFactory new] autorelease]; flutterPlatformViewsController->RegisterViewFactory( @@ -352,6 +352,7 @@ - (void)testAnnouncesRouteChangesWhenAddAdditionalRoute { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterView = OCMClassMock([FlutterView class]); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); @@ -435,6 +436,7 @@ - (void)testAnnouncesRouteChangesRemoveRouteInMiddle { auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware), /*task_runners=*/runners); id mockFlutterView = OCMClassMock([FlutterView class]); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); diff --git a/shell/platform/darwin/ios/ios_surface_factory.h b/shell/platform/darwin/ios/ios_surface_factory.h index a692c56754887..8184918114c78 100644 --- a/shell/platform/darwin/ios/ios_surface_factory.h +++ b/shell/platform/darwin/ios/ios_surface_factory.h @@ -22,13 +22,14 @@ class IOSSurfaceFactory { ~IOSSurfaceFactory(); void SetPlatformViewsController( - FlutterPlatformViewsController* platform_views_controller); + const std::shared_ptr& + platform_views_controller); std::unique_ptr CreateSurface( fml::scoped_nsobject ca_layer); private: - FlutterPlatformViewsController* platform_views_controller_; + std::shared_ptr platform_views_controller_; std::shared_ptr ios_context_; FML_DISALLOW_COPY_AND_ASSIGN(IOSSurfaceFactory); diff --git a/shell/platform/darwin/ios/ios_surface_factory.mm b/shell/platform/darwin/ios/ios_surface_factory.mm index 4ed7d4c0b96a9..2c228bc074e92 100644 --- a/shell/platform/darwin/ios/ios_surface_factory.mm +++ b/shell/platform/darwin/ios/ios_surface_factory.mm @@ -18,7 +18,7 @@ IOSSurfaceFactory::~IOSSurfaceFactory() = default; void IOSSurfaceFactory::SetPlatformViewsController( - FlutterPlatformViewsController* platform_views_controller) { + const std::shared_ptr& platform_views_controller) { platform_views_controller_ = platform_views_controller; } diff --git a/testing/ios/IosUnitTests/README.md b/testing/ios/IosUnitTests/README.md index 096f66875f5eb..4e22fb8d29258 100644 --- a/testing/ios/IosUnitTests/README.md +++ b/testing/ios/IosUnitTests/README.md @@ -9,7 +9,7 @@ also run in LUCI builds. testing/run_tests.py [--type=objc] ``` -After the `ios_flutter_test` target is built you can also run the tests inside +After the `ios_test_flutter` target is built you can also run the tests inside of Xcode with `testing/ios/IosUnitTests/IosUnitTests.xcodeproj`. If you modify the test or under-test files, you'll have to run `run_tests.py` again. @@ -17,5 +17,5 @@ modify the test or under-test files, you'll have to run `run_tests.py` again. When you add a new unit test file, also add a reference to that file in shell/platform/darwin/ios/BUILD.gn, under the `sources` list of the -`ios_flutter_test` target. Once it's there, it will execute with the other +`ios_test_flutter` target. Once it's there, it will execute with the other tests. From e4fbbb166adb8f8553066618b7d8429a11cde0a1 Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Thu, 29 Oct 2020 08:34:49 -0700 Subject: [PATCH 3/3] temporary fix for a memory leak see: https://github.com/flutter/flutter/issues/69305 --- .../darwin/ios/framework/Source/FlutterPlatformViews.mm | 6 ++++++ .../IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj | 4 ++-- .../xcshareddata/xcschemes/IosUnitTests.xcscheme | 7 +++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 9c0dc2f003303..ef1860037eeb1 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -437,6 +437,12 @@ for (UIView* sub_view in [flutter_view subviews]) { [sub_view removeFromSuperview]; } + // See: https://github.com/flutter/flutter/issues/69305 + for (auto it = touch_interceptors_.begin(); it != touch_interceptors_.end(); it++) { + FlutterTouchInterceptingView* view = it->second.get(); + [view removeFromSuperview]; + } + touch_interceptors_.clear(); views_.clear(); composition_order_.clear(); active_composition_order_.clear(); diff --git a/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj b/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj index dde07daccd170..ea69e52363610 100644 --- a/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj +++ b/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj @@ -332,6 +332,7 @@ /* Begin XCBuildConfiguration section */ 0D6AB6D022BB05E200EEE540 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 0D6AB73E22BD8F0200EEE540 /* FlutterEngineConfig.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -391,6 +392,7 @@ }; 0D6AB6D122BB05E200EEE540 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 0D6AB73E22BD8F0200EEE540 /* FlutterEngineConfig.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -484,7 +486,6 @@ }; 0D6AB6D622BB05E200EEE540 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0D6AB73E22BD8F0200EEE540 /* FlutterEngineConfig.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; @@ -528,7 +529,6 @@ }; 0D6AB6D722BB05E200EEE540 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0D6AB73E22BD8F0200EEE540 /* FlutterEngineConfig.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; diff --git a/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/xcshareddata/xcschemes/IosUnitTests.xcscheme b/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/xcshareddata/xcschemes/IosUnitTests.xcscheme index 503fa272ca433..0394976e2de6d 100644 --- a/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/xcshareddata/xcschemes/IosUnitTests.xcscheme +++ b/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/xcshareddata/xcschemes/IosUnitTests.xcscheme @@ -28,6 +28,13 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES" systemAttachmentLifetime = "keepNever"> + + + +