diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 34e34f9804..bc1a32764f 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -44571,6 +44571,8 @@ ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatf ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate.mm + ../../../flutter/LICENSE @@ -44632,8 +44634,6 @@ ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/overlay_laye ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.mm + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h + ../../../flutter/LICENSE @@ -47514,6 +47514,8 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatfor FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate.mm @@ -47575,8 +47577,6 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.mm 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/darwin/ios/framework/Source/platform_views_controller.h -FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h diff --git a/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn b/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn index 95f2dfa9ff..4a0eeac21c 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn +++ b/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn @@ -80,6 +80,8 @@ source_set("flutter_framework_source") { "framework/Source/FlutterPlatformPlugin.h", "framework/Source/FlutterPlatformPlugin.mm", "framework/Source/FlutterPlatformViews.mm", + "framework/Source/FlutterPlatformViewsController.h", + "framework/Source/FlutterPlatformViewsController.mm", "framework/Source/FlutterPlatformViews_Internal.h", "framework/Source/FlutterPluginAppLifeCycleDelegate.mm", "framework/Source/FlutterRestorationPlugin.h", @@ -120,8 +122,6 @@ source_set("flutter_framework_source") { "framework/Source/overlay_layer_pool.mm", "framework/Source/platform_message_response_darwin.h", "framework/Source/platform_message_response_darwin.mm", - "framework/Source/platform_views_controller.h", - "framework/Source/platform_views_controller.mm", "framework/Source/profiler_metrics_ios.h", "framework/Source/profiler_metrics_ios.mm", "framework/Source/vsync_waiter_ios.h", diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 85f1ba5519..eff08e6cc5 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -105,6 +105,8 @@ static constexpr int kNumProfilerSamplesPerSec = 5; @property(nonatomic, readonly, assign) BOOL allowHeadlessExecution; @property(nonatomic, readonly, assign) BOOL restorationEnabled; +@property(nonatomic, strong) FlutterPlatformViewsController* platformViewsController; + // Maintains a dictionary of plugin names that have registered with the engine. Used by // FlutterEngineRegistrar to implement a FlutterPluginRegistrar. @property(nonatomic, readonly) NSMutableDictionary* pluginPublications; @@ -150,7 +152,6 @@ static constexpr int kNumProfilerSamplesPerSec = 5; std::shared_ptr _threadHost; std::unique_ptr _shell; - std::shared_ptr _platformViewsController; flutter::IOSRenderingAPI _renderingApi; std::shared_ptr _profiler; @@ -211,7 +212,7 @@ static constexpr int kNumProfilerSamplesPerSec = 5; _pluginPublications = [[NSMutableDictionary alloc] init]; _registrars = [[NSMutableDictionary alloc] init]; - [self recreatePlatformViewController]; + [self recreatePlatformViewsController]; _binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self]; _textureRegistry = [[FlutterTextureRegistryRelay alloc] initWithParent:self]; _connections.reset(new flutter::ConnectionCollection()); @@ -262,9 +263,9 @@ static constexpr int kNumProfilerSamplesPerSec = 5; object:nil]; } -- (void)recreatePlatformViewController { +- (void)recreatePlatformViewsController { _renderingApi = flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering); - _platformViewsController.reset(new flutter::PlatformViewsController()); + _platformViewsController = [[FlutterPlatformViewsController alloc] init]; } - (flutter::IOSRenderingAPI)platformViewsRenderingAPI { @@ -452,11 +453,7 @@ static constexpr int kNumProfilerSamplesPerSec = 5; _shell.reset(); _profiler.reset(); _threadHost.reset(); - _platformViewsController.reset(); -} - -- (std::shared_ptr&)platformViewsController { - return _platformViewsController; + _platformViewsController = nil; } - (NSURL*)observatoryUrl { @@ -635,7 +632,7 @@ static constexpr int kNumProfilerSamplesPerSec = 5; [self.platformViewsChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { if (weakSelf) { - weakSelf.platformViewsController->OnMethodCall(call, result); + [weakSelf.platformViewsController onMethodCall:call result:result]; } }]; @@ -777,11 +774,11 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS if (!strongSelf) { return std::unique_ptr(); } - [strongSelf recreatePlatformViewController]; - strongSelf->_platformViewsController->SetTaskRunner( - shell.GetTaskRunners().GetPlatformTaskRunner()); + [strongSelf recreatePlatformViewsController]; + strongSelf.platformViewsController.taskRunner = + shell.GetTaskRunners().GetPlatformTaskRunner(); return std::make_unique( - shell, strongSelf->_renderingApi, strongSelf->_platformViewsController, + shell, strongSelf->_renderingApi, strongSelf.platformViewsController, shell.GetTaskRunners(), shell.GetConcurrentWorkerTaskRunner(), shell.GetIsGpuDisabledSyncSwitch()); }; @@ -1103,7 +1100,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS // Have to check in the next run loop, because iOS requests the previous first responder to // resign before requesting the next view to become first responder. dispatch_async(dispatch_get_main_queue(), ^(void) { - long platform_view_id = self.platformViewsController->FindFirstResponderPlatformViewId(); + long platform_view_id = [self.platformViewsController firstResponderPlatformViewId]; if (platform_view_id == -1) { return; } @@ -1400,11 +1397,10 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS // create call is synchronous. flutter::Shell::CreateCallback on_create_platform_view = [result, context](flutter::Shell& shell) { - [result recreatePlatformViewController]; - result->_platformViewsController->SetTaskRunner( - shell.GetTaskRunners().GetPlatformTaskRunner()); + [result recreatePlatformViewsController]; + result.platformViewsController.taskRunner = shell.GetTaskRunners().GetPlatformTaskRunner(); return std::make_unique( - shell, context, result->_platformViewsController, shell.GetTaskRunners()); + shell, context, result.platformViewsController, shell.GetTaskRunners()); }; flutter::Shell::CreateCallback on_create_rasterizer = @@ -1499,8 +1495,9 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS withId:(NSString*)factoryId gestureRecognizersBlockingPolicy: (FlutterPlatformViewGestureRecognizersBlockingPolicy)gestureRecognizersBlockingPolicy { - [_flutterEngine platformViewsController]->RegisterViewFactory(factory, factoryId, - gestureRecognizersBlockingPolicy); + [_flutterEngine.platformViewsController registerViewFactory:factory + withId:factoryId + gestureRecognizersBlockingPolicy:gestureRecognizersBlockingPolicy]; } @end diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h index 6f954adbcb..bb3beca9db 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h @@ -46,7 +46,6 @@ NS_ASSUME_NONNULL_BEGIN base64Encode:(bool)base64Encode; - (FlutterPlatformPlugin*)platformPlugin; -- (std::shared_ptr&)platformViewsController; - (FlutterTextInputPlugin*)textInputPlugin; - (FlutterRestorationPlugin*)restorationPlugin; - (void)launchEngine:(nullable NSString*)entrypoint @@ -81,6 +80,7 @@ NS_ASSUME_NONNULL_BEGIN userData:(nullable void*)userData; @property(nonatomic, readonly) FlutterDartProject* project; + @end NS_ASSUME_NONNULL_END diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index ce38124365..a0e140e6e4 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -518,8 +518,7 @@ static BOOL _preparedOnce = NO; @implementation FlutterTouchInterceptingView - (instancetype)initWithEmbeddedView:(UIView*)embeddedView - platformViewsController: - (fml::WeakPtr)platformViewsController + platformViewsController:(FlutterPlatformViewsController*)platformViewsController gestureRecognizersBlockingPolicy: (FlutterPlatformViewGestureRecognizersBlockingPolicy)blockingPolicy { self = [super initWithFrame:embeddedView.frame]; @@ -667,7 +666,7 @@ static BOOL _preparedOnce = NO; // outlives the FlutterViewController. And ForwardingGestureRecognizer is owned by a subview of // FlutterView, so the ForwardingGestureRecognizer never out lives FlutterViewController. // Therefore, `_platformViewsController` should never be nullptr. - fml::WeakPtr _platformViewsController; + __weak FlutterPlatformViewsController* _platformViewsController; // Counting the pointers that has started in one touch sequence. NSInteger _currentTouchPointersCount; // We can't dispatch events to the framework without this back pointer. @@ -678,13 +677,12 @@ static BOOL _preparedOnce = NO; } - (instancetype)initWithTarget:(id)target - platformViewsController: - (fml::WeakPtr)platformViewsController { + platformViewsController:(FlutterPlatformViewsController*)platformViewsController { self = [super initWithTarget:target action:nil]; if (self) { self.delegate = self; - FML_DCHECK(platformViewsController.get() != nullptr); - _platformViewsController = std::move(platformViewsController); + FML_DCHECK(platformViewsController); + _platformViewsController = platformViewsController; _currentTouchPointersCount = 0; } return self; @@ -692,7 +690,7 @@ static BOOL _preparedOnce = NO; - (ForwardingGestureRecognizer*)recreateRecognizerWithTarget:(id)target { return [[ForwardingGestureRecognizer alloc] initWithTarget:target - platformViewsController:std::move(_platformViewsController)]; + platformViewsController:_platformViewsController]; } - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { @@ -701,7 +699,7 @@ static BOOL _preparedOnce = NO; // At the start of each gesture sequence, we reset the `_flutterViewController`, // so that all the touch events in the same sequence are forwarded to the same // `_flutterViewController`. - _flutterViewController = _platformViewsController->GetFlutterViewController(); + _flutterViewController = _platformViewsController.flutterViewController; } [_flutterViewController touchesBegan:touches withEvent:event]; _currentTouchPointersCount += touches.count; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h new file mode 100644 index 0000000000..2c2dea71e3 --- /dev/null +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h @@ -0,0 +1,152 @@ +// 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_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWSCONTROLLER_H_ +#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWSCONTROLLER_H_ + +#include +#include +#include +#include + +#include "flutter/flow/surface.h" +#include "flutter/fml/task_runner.h" +#include "flutter/fml/trace_event.h" +#include "impeller/base/thread_safety.h" +#include "third_party/skia/include/core/SkRect.h" + +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h" +#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h" +#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewResponder.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h" +#import "flutter/shell/platform/darwin/ios/ios_context.h" + +@class FlutterTouchInterceptingView; +@class FlutterClippingMaskViewPool; + +@interface FlutterPlatformViewsController : NSObject + +- (id)init NS_DESIGNATED_INITIALIZER; + +/// The task runner used to post rendering tasks to the platform thread. +@property(nonatomic, assign) const fml::RefPtr& taskRunner; + +/// The flutter view. +@property(nonatomic, weak) UIView* flutterView; + +/// @brief The flutter view controller. +@property(nonatomic, weak) UIViewController* flutterViewController; + +/// @brief Retrieve the view controller. +- (UIViewController*)flutterViewController; + +/// @brief set the factory used to construct embedded UI Views. +- (void)registerViewFactory:(NSObject*)factory + withId:(NSString*)factoryId + gestureRecognizersBlockingPolicy: + (FlutterPlatformViewGestureRecognizersBlockingPolicy)gestureRecognizerBlockingPolicy; + +/// @brief Mark the beginning of a frame and record the size of the onscreen. +- (void)beginFrameWithSize:(SkISize)frameSize; + +/// @brief Cancel the current frame, indicating that no platform views are composited. +/// +/// Additionally, reverts the composition order to its original state at the beginning of the +/// frame. +- (void)cancelFrame; + +/// @brief Record a platform view in the layer tree to be rendered, along with the positioning and +/// mutator parameters. +/// +/// Called from the raster thread. +- (void)prerollCompositeEmbeddedView:(int64_t)viewId + withParams:(std::unique_ptr)params; + +/// @brief Returns the`FlutterTouchInterceptingView` with the provided view_id. +/// +/// Returns nil if there is no platform view with the provided id. Called +/// from the platform thread. +- (FlutterTouchInterceptingView*)flutterTouchInterceptingViewForId:(int64_t)viewId; + +/// @brief Determine if thread merging is required after prerolling platform views. +/// +/// Called from the raster thread. +- (flutter::PostPrerollResult)postPrerollActionWithThreadMerger: + (const fml::RefPtr&)rasterThreadMerger + impellerEnabled:(BOOL)impellerEnabled; + +/// @brief Mark the end of a compositor frame. +/// +/// May determine changes are required to the thread merging state. +/// Called from the raster thread. +- (void)endFrameWithResubmit:(BOOL)shouldResubmitFrame + threadMerger:(const fml::RefPtr&)rasterThreadMerger + impellerEnabled:(BOOL)impellerEnabled; + +/// @brief Returns the Canvas for the overlay slice for the given platform view. +/// +/// Called from the raster thread. +- (flutter::DlCanvas*)compositeEmbeddedViewWithId:(int64_t)viewId; + +/// @brief Discards all platform views instances and auxiliary resources. +/// +/// Called from the raster thread. +- (void)reset; + +/// @brief Encode rendering for the Flutter overlay views and queue up perform platform view +/// mutations. +/// +/// Called from the raster thread. +- (BOOL)submitFrame:(std::unique_ptr)frame + withIosContext:(const std::shared_ptr&)iosContext + grContext:(GrDirectContext*)grContext; + +/// @brief Handler for platform view message channels. +- (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result; + +/// @brief Returns the platform view id if the platform view (or any of its descendant view) is +/// the first responder. +/// +/// Returns -1 if no such platform view is found. +- (long)firstResponderPlatformViewId; + +/// @brief Pushes backdrop filter mutation to the mutator stack of each visited platform view. +- (void)pushFilterToVisitedPlatformViews:(const std::shared_ptr&)filter + withRect:(const SkRect&)filterRect; + +/// @brief Pushes the view id of a visted platform view to the list of visied platform views. +- (void)pushVisitedPlatformViewId:(int64_t)viewId; + +@end + +@interface FlutterPlatformViewsController (Testing) + +- (size_t)embeddedViewCount; + +// TODO(cbracken): Delete. This is unused. +- (size_t)layerPoolSize; + +// Returns the `FlutterPlatformView`'s `view` object associated with the view_id. +// +// If the `PlatformViewsController` does not contain any `FlutterPlatformView` object or +// a `FlutterPlatformView` object associated with the view_id cannot be found, the method +// returns nil. +- (UIView*)platformViewForId:(int64_t)viewId; + +// Composite the PlatformView with `viewId`. +// +// Every frame, during the paint traversal of the layer tree, this method is called for all +// the PlatformViews in `_viewsToRecomposite`. +// +// Note that `_viewsToRecomposite` does not represent all the views in the view hierarchy, +// if a PlatformView does not change its composition parameter from last frame, it is not +// included in the `views_to_recomposite_`. +- (void)compositeView:(int64_t)viewId withParams:(const flutter::EmbeddedViewParams&)params; + +- (const flutter::EmbeddedViewParams&)compositionParamsForView:(int64_t)viewId; + +@end + +#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWSCONTROLLER_H_ diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm new file mode 100644 index 0000000000..578037661c --- /dev/null +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm @@ -0,0 +1,1084 @@ +// 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 "shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h" + +#include "flutter/display_list/effects/image_filters/dl_blur_image_filter.h" +#include "flutter/flow/surface_frame.h" +#include "flutter/flow/view_slicer.h" +#include "flutter/fml/make_copyable.h" +#include "flutter/fml/synchronization/count_down_latch.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h" +#import "flutter/shell/platform/darwin/ios/ios_surface.h" + +namespace { + +// The number of frames the rasterizer task runner will continue +// to run on the platform thread after no platform view is rendered. +// +// Note: this is an arbitrary number. +static const int kDefaultMergedLeaseDuration = 10; + +static constexpr NSUInteger kFlutterClippingMaskViewPoolCapacity = 5; + +// Converts a SkMatrix to CATransform3D. +// +// Certain fields are ignored in CATransform3D since SkMatrix is 3x3 and CATransform3D is 4x4. +CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix) { + // Skia only supports 2D transform so we don't map z. + CATransform3D transform = CATransform3DIdentity; + transform.m11 = matrix.getScaleX(); + transform.m21 = matrix.getSkewX(); + transform.m41 = matrix.getTranslateX(); + transform.m14 = matrix.getPerspX(); + + transform.m12 = matrix.getSkewY(); + transform.m22 = matrix.getScaleY(); + transform.m42 = matrix.getTranslateY(); + transform.m24 = matrix.getPerspY(); + return transform; +} + +// Reset the anchor of `layer` to match the transform operation from flow. +// +// The position of the `layer` should be unchanged after resetting the anchor. +void ResetAnchor(CALayer* layer) { + // Flow uses (0, 0) to apply transform matrix so we need to match that in Quartz. + layer.anchorPoint = CGPointZero; + layer.position = CGPointZero; +} + +CGRect GetCGRectFromSkRect(const SkRect& clipSkRect) { + return CGRectMake(clipSkRect.fLeft, clipSkRect.fTop, clipSkRect.fRight - clipSkRect.fLeft, + clipSkRect.fBottom - clipSkRect.fTop); +} + +// Determines if the `clip_rect` from a clipRect mutator contains the +// `platformview_boundingrect`. +// +// `clip_rect` is in its own coordinate space. The rect needs to be transformed by +// `transform_matrix` to be in the coordinate space where the PlatformView is displayed. +// +// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate +// space where the PlatformView is displayed. +bool ClipRectContainsPlatformViewBoundingRect(const SkRect& clip_rect, + const SkRect& platformview_boundingrect, + const SkMatrix& transform_matrix) { + SkRect transformed_rect = transform_matrix.mapRect(clip_rect); + return transformed_rect.contains(platformview_boundingrect); +} + +// Determines if the `clipRRect` from a clipRRect mutator contains the +// `platformview_boundingrect`. +// +// `clip_rrect` is in its own coordinate space. The rrect needs to be transformed by +// `transform_matrix` to be in the coordinate space where the PlatformView is displayed. +// +// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate +// space where the PlatformView is displayed. +bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, + const SkRect& platformview_boundingrect, + const SkMatrix& transform_matrix) { + SkVector upper_left = clip_rrect.radii(SkRRect::Corner::kUpperLeft_Corner); + SkVector upper_right = clip_rrect.radii(SkRRect::Corner::kUpperRight_Corner); + SkVector lower_right = clip_rrect.radii(SkRRect::Corner::kLowerRight_Corner); + SkVector lower_left = clip_rrect.radii(SkRRect::Corner::kLowerLeft_Corner); + SkScalar transformed_upper_left_x = transform_matrix.mapRadius(upper_left.x()); + SkScalar transformed_upper_left_y = transform_matrix.mapRadius(upper_left.y()); + SkScalar transformed_upper_right_x = transform_matrix.mapRadius(upper_right.x()); + SkScalar transformed_upper_right_y = transform_matrix.mapRadius(upper_right.y()); + SkScalar transformed_lower_right_x = transform_matrix.mapRadius(lower_right.x()); + SkScalar transformed_lower_right_y = transform_matrix.mapRadius(lower_right.y()); + SkScalar transformed_lower_left_x = transform_matrix.mapRadius(lower_left.x()); + SkScalar transformed_lower_left_y = transform_matrix.mapRadius(lower_left.y()); + SkRect transformed_clip_rect = transform_matrix.mapRect(clip_rrect.rect()); + SkRRect transformed_rrect; + SkVector corners[] = {{transformed_upper_left_x, transformed_upper_left_y}, + {transformed_upper_right_x, transformed_upper_right_y}, + {transformed_lower_right_x, transformed_lower_right_y}, + {transformed_lower_left_x, transformed_lower_left_y}}; + transformed_rrect.setRectRadii(transformed_clip_rect, corners); + return transformed_rrect.contains(platformview_boundingrect); +} + +struct LayerData { + SkRect rect; + int64_t view_id; + int64_t overlay_id; + std::shared_ptr layer; +}; + +using LayersMap = std::unordered_map; + +/// Each of the following structs stores part of the platform view hierarchy according to its +/// ID. +/// +/// This data must only be accessed on the platform thread. +struct PlatformViewData { + NSObject* view; + FlutterTouchInterceptingView* touch_interceptor; + UIView* root_view; +}; + +} // namespace + +@interface FlutterPlatformViewsController () + +// The pool of reusable view layers. The pool allows to recycle layer in each frame. +@property(nonatomic, readonly) flutter::OverlayLayerPool* layerPool; + +// The platform view's |EmbedderViewSlice| keyed off the view id, which contains any subsequent +// operation until the next platform view or the end of the last leaf node in the layer tree. +// +// The Slices are deleted by the PlatformViewsController.reset(). +@property(nonatomic, readonly) + std::unordered_map>& slices; + +@property(nonatomic, readonly) FlutterClippingMaskViewPool* maskViewPool; + +@property(nonatomic, readonly) + std::unordered_map*>& factories; + +// The FlutterPlatformViewGestureRecognizersBlockingPolicy for each type of platform view. +@property(nonatomic, readonly) + std::unordered_map& + gestureRecognizersBlockingPolicies; + +/// The size of the current onscreen surface in physical pixels. +@property(nonatomic, assign) SkISize frameSize; + +/// The task runner for posting tasks to the platform thread. +@property(nonatomic, readonly) const fml::RefPtr& platformTaskRunner; + +/// This data must only be accessed on the platform thread. +@property(nonatomic, readonly) std::unordered_map& platformViews; + +/// The composition parameters for each platform view. +/// +/// This state is only modified on the raster thread. +@property(nonatomic, readonly) + std::unordered_map& currentCompositionParams; + +/// Method channel `OnDispose` calls adds the views to be disposed to this set to be disposed on +/// the next frame. +/// +/// This state is modified on both the platform and raster thread. +@property(nonatomic, readonly) std::unordered_set& viewsToDispose; + +/// view IDs in composition order. +/// +/// This state is only modified on the raster thread. +@property(nonatomic, readonly) std::vector& compositionOrder; + +/// platform view IDs visited during layer tree composition. +/// +/// This state is only modified on the raster thread. +@property(nonatomic, readonly) std::vector& visitedPlatformViews; + +/// Only composite platform views in this set. +/// +/// This state is only modified on the raster thread. +@property(nonatomic, readonly) std::unordered_set& viewsToRecomposite; + +/// @brief The composition order from the previous thread. +/// +/// Only accessed from the platform thread. +@property(nonatomic, readonly) std::vector& previousCompositionOrder; + +/// Whether the previous frame had any platform views in active composition order. +/// +/// This state is tracked so that the first frame after removing the last platform view +/// runs through the platform view rendering code path, giving us a chance to remove the +/// platform view from the UIView hierarchy. +/// +/// Only accessed from the raster thread. +@property(nonatomic, assign) BOOL hadPlatformViews; + +/// Populate any missing overlay layers. +/// +/// This requires posting a task to the platform thread and blocking on its completion. +- (void)createMissingOverlays:(size_t)requiredOverlayLayers + withIosContext:(const std::shared_ptr&)iosContext + grContext:(GrDirectContext*)grContext; + +/// Update the buffers and mutate the platform views in CATransaction on the platform thread. +- (void)performSubmit:(const LayersMap&)platformViewLayers + currentCompositionParams: + (std::unordered_map&)currentCompositionParams + viewsToRecomposite:(const std::unordered_set&)viewsToRecomposite + compositionOrder:(const std::vector&)compositionOrder + unusedLayers: + (const std::vector>&)unusedLayers + surfaceFrames: + (const std::vector>&)surfaceFrames; + +- (void)onCreate:(FlutterMethodCall*)call result:(FlutterResult)result; +- (void)onDispose:(FlutterMethodCall*)call result:(FlutterResult)result; +- (void)onAcceptGesture:(FlutterMethodCall*)call result:(FlutterResult)result; +- (void)onRejectGesture:(FlutterMethodCall*)call result:(FlutterResult)result; + +- (void)clipViewSetMaskView:(UIView*)clipView; + +// Applies the mutators in the mutatorsStack to the UIView chain that was constructed by +// `ReconstructClipViewsChain` +// +// Clips are applied to the `embeddedView`'s super view(|ChildClippingView|) using a +// |FlutterClippingMaskView|. Transforms are applied to `embeddedView` +// +// The `boundingRect` is the final bounding rect of the PlatformView +// (EmbeddedViewParams::finalBoundingRect). If a clip mutator's rect contains the final bounding +// rect of the PlatformView, the clip mutator is not applied for performance optimization. +// +// This method is only called when the `embeddedView` needs to be re-composited at the current +// frame. See: `compositeView:withParams:` for details. +- (void)applyMutators:(const flutter::MutatorsStack&)mutatorsStack + embeddedView:(UIView*)embeddedView + boundingRect:(const SkRect&)boundingRect; + +// Appends the overlay views and platform view and sets their z index based on the composition +// order. +- (void)bringLayersIntoView:(const LayersMap&)layerMap + withCompositionOrder:(const std::vector&)compositionOrder; + +- (std::shared_ptr)nextLayerInPool; + +/// Runs on the platform thread. +- (void)createLayerWithIosContext:(const std::shared_ptr&)iosContext + grContext:(GrDirectContext*)grContext + pixelFormat:(MTLPixelFormat)pixelFormat; + +/// Removes overlay views and platform views that aren't needed in the current frame. +/// Must run on the platform thread. +- (void)removeUnusedLayers:(const std::vector>&)unusedLayers + withCompositionOrder:(const std::vector&)compositionOrder; + +/// Computes and returns all views to be disposed on the platform thread, removes them from +/// self.platformViews, self.viewsToRecomposite, and self.currentCompositionParams. Any views that +/// still require compositing are not returned, but instead added to `viewsToDelayDispose` for +/// disposal on the next call. +- (std::vector)computeViewsToDispose; + +/// Resets the state of the frame. +- (void)resetFrameState; +@end + +namespace flutter { + +// TODO(cbracken): Eliminate the use of globals. +// Becomes NO if Apple's API changes and blurred backdrop filters cannot be applied. +BOOL canApplyBlurBackdrop = YES; + +} // namespace flutter + +@implementation FlutterPlatformViewsController { + // TODO(cbracken): Replace with Obj-C types and use @property declarations to automatically + // synthesize the ivars. + // + // These ivars are required because we're transitioning the previous C++ implementation to Obj-C. + // We require ivars to declare the concrete types and then wrap with @property declarations that + // return a reference to the ivar, allowing for use like `self.layerPool` and + // `self.slices[viewId] = x`. + std::unique_ptr _layerPool; + std::unordered_map> _slices; + std::unordered_map*> _factories; + std::unordered_map + _gestureRecognizersBlockingPolicies; + fml::RefPtr _platformTaskRunner; + std::unordered_map _platformViews; + std::unordered_map _currentCompositionParams; + std::unordered_set _viewsToDispose; + std::vector _compositionOrder; + std::vector _visitedPlatformViews; + std::unordered_set _viewsToRecomposite; + std::vector _previousCompositionOrder; +} + +- (id)init { + if (self = [super init]) { + _layerPool = std::make_unique(); + _maskViewPool = + [[FlutterClippingMaskViewPool alloc] initWithCapacity:kFlutterClippingMaskViewPoolCapacity]; + _hadPlatformViews = NO; + } + return self; +} + +- (const fml::RefPtr&)taskRunner { + return _platformTaskRunner; +} + +- (void)setTaskRunner:(const fml::RefPtr&)platformTaskRunner { + _platformTaskRunner = platformTaskRunner; +} + +- (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { + if ([[call method] isEqualToString:@"create"]) { + [self onCreate:call result:result]; + } else if ([[call method] isEqualToString:@"dispose"]) { + [self onDispose:call result:result]; + } else if ([[call method] isEqualToString:@"acceptGesture"]) { + [self onAcceptGesture:call result:result]; + } else if ([[call method] isEqualToString:@"rejectGesture"]) { + [self onRejectGesture:call result:result]; + } else { + result(FlutterMethodNotImplemented); + } +} + +- (void)onCreate:(FlutterMethodCall*)call result:(FlutterResult)result { + NSDictionary* args = [call arguments]; + + int64_t viewId = [args[@"id"] longLongValue]; + NSString* viewTypeString = args[@"viewType"]; + std::string viewType(viewTypeString.UTF8String); + + if (self.platformViews.count(viewId) != 0) { + result([FlutterError errorWithCode:@"recreating_view" + message:@"trying to create an already created view" + details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); + return; + } + + NSObject* factory = self.factories[viewType]; + if (factory == nil) { + result([FlutterError + errorWithCode:@"unregistered_view_type" + message:[NSString stringWithFormat:@"A UIKitView widget is trying to create a " + @"PlatformView with an unregistered type: < %@ >", + viewTypeString] + details:@"If you are the author of the PlatformView, make sure `registerViewFactory` " + @"is invoked.\n" + @"See: " + @"https://docs.flutter.dev/development/platform-integration/" + @"platform-views#on-the-platform-side-1 for more details.\n" + @"If you are not the author of the PlatformView, make sure to call " + @"`GeneratedPluginRegistrant.register`."]); + return; + } + + id params = nil; + if ([factory respondsToSelector:@selector(createArgsCodec)]) { + NSObject* codec = [factory createArgsCodec]; + if (codec != nil && args[@"params"] != nil) { + FlutterStandardTypedData* paramsData = args[@"params"]; + params = [codec decode:paramsData.data]; + } + } + + NSObject* embeddedView = [factory createWithFrame:CGRectZero + viewIdentifier:viewId + arguments:params]; + UIView* platformView = [embeddedView view]; + // Set a unique view identifier, so the platform view can be identified in unit tests. + platformView.accessibilityIdentifier = [NSString stringWithFormat:@"platform_view[%lld]", viewId]; + + FlutterTouchInterceptingView* touchInterceptor = [[FlutterTouchInterceptingView alloc] + initWithEmbeddedView:platformView + platformViewsController:self + gestureRecognizersBlockingPolicy:self.gestureRecognizersBlockingPolicies[viewType]]; + + ChildClippingView* clippingView = [[ChildClippingView alloc] initWithFrame:CGRectZero]; + [clippingView addSubview:touchInterceptor]; + + self.platformViews.emplace(viewId, PlatformViewData{ + .view = embeddedView, // + .touch_interceptor = touchInterceptor, // + .root_view = clippingView // + }); + + result(nil); +} + +- (void)onDispose:(FlutterMethodCall*)call result:(FlutterResult)result { + NSNumber* arg = [call arguments]; + int64_t viewId = [arg longLongValue]; + + if (self.platformViews.count(viewId) == 0) { + result([FlutterError errorWithCode:@"unknown_view" + message:@"trying to dispose an unknown" + details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); + return; + } + // We wait for next submitFrame to dispose views. + self.viewsToDispose.insert(viewId); + result(nil); +} + +- (void)onAcceptGesture:(FlutterMethodCall*)call result:(FlutterResult)result { + NSDictionary* args = [call arguments]; + int64_t viewId = [args[@"id"] longLongValue]; + + if (self.platformViews.count(viewId) == 0) { + result([FlutterError errorWithCode:@"unknown_view" + message:@"trying to set gesture state for an unknown view" + details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); + return; + } + + FlutterTouchInterceptingView* view = self.platformViews[viewId].touch_interceptor; + [view releaseGesture]; + + result(nil); +} + +- (void)onRejectGesture:(FlutterMethodCall*)call result:(FlutterResult)result { + NSDictionary* args = [call arguments]; + int64_t viewId = [args[@"id"] longLongValue]; + + if (self.platformViews.count(viewId) == 0) { + result([FlutterError errorWithCode:@"unknown_view" + message:@"trying to set gesture state for an unknown view" + details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); + return; + } + + FlutterTouchInterceptingView* view = self.platformViews[viewId].touch_interceptor; + [view blockGesture]; + + result(nil); +} + +- (void)registerViewFactory:(NSObject*)factory + withId:(NSString*)factoryId + gestureRecognizersBlockingPolicy: + (FlutterPlatformViewGestureRecognizersBlockingPolicy)gestureRecognizerBlockingPolicy { + std::string idString([factoryId UTF8String]); + FML_CHECK(self.factories.count(idString) == 0); + self.factories[idString] = factory; + self.gestureRecognizersBlockingPolicies[idString] = gestureRecognizerBlockingPolicy; +} + +- (void)beginFrameWithSize:(SkISize)frameSize { + [self resetFrameState]; + self.frameSize = frameSize; +} + +- (void)cancelFrame { + [self resetFrameState]; +} + +- (flutter::PostPrerollResult)postPrerollActionWithThreadMerger: + (const fml::RefPtr&)rasterThreadMerger + impellerEnabled:(BOOL)impellerEnabled { + // TODO(jonahwilliams): remove this once Software backend is removed for iOS Sim. +#ifdef FML_OS_IOS_SIMULATOR + const bool mergeThreads = true; +#else + const bool mergeThreads = !impellerEnabled; +#endif // FML_OS_IOS_SIMULATOR + + if (mergeThreads) { + if (self.compositionOrder.empty()) { + return flutter::PostPrerollResult::kSuccess; + } + if (!rasterThreadMerger->IsMerged()) { + // The raster thread merger may be disabled if the rasterizer is being + // created or teared down. + // + // In such cases, the current frame is dropped, and a new frame is attempted + // with the same layer tree. + // + // Eventually, the frame is submitted once this method returns `kSuccess`. + // At that point, the raster tasks are handled on the platform thread. + [self cancelFrame]; + return flutter::PostPrerollResult::kSkipAndRetryFrame; + } + // If the post preroll action is successful, we will display platform views in the current + // frame. In order to sync the rendering of the platform views (quartz) with skia's rendering, + // We need to begin an explicit CATransaction. This transaction needs to be submitted + // after the current frame is submitted. + rasterThreadMerger->ExtendLeaseTo(kDefaultMergedLeaseDuration); + } + return flutter::PostPrerollResult::kSuccess; +} + +- (void)endFrameWithResubmit:(BOOL)shouldResubmitFrame + threadMerger:(const fml::RefPtr&)rasterThreadMerger + impellerEnabled:(BOOL)impellerEnabled { +#if FML_OS_IOS_SIMULATOR + BOOL runCheck = YES; +#else + BOOL runCheck = !impellerEnabled; +#endif // FML_OS_IOS_SIMULATOR + if (runCheck && shouldResubmitFrame) { + rasterThreadMerger->MergeWithLease(kDefaultMergedLeaseDuration); + } +} + +- (void)pushFilterToVisitedPlatformViews:(const std::shared_ptr&)filter + withRect:(const SkRect&)filterRect { + for (int64_t id : self.visitedPlatformViews) { + flutter::EmbeddedViewParams params = self.currentCompositionParams[id]; + params.PushImageFilter(filter, filterRect); + self.currentCompositionParams[id] = params; + } +} + +- (void)prerollCompositeEmbeddedView:(int64_t)viewId + withParams:(std::unique_ptr)params { + SkRect viewBounds = SkRect::Make(self.frameSize); + std::unique_ptr view; + view = std::make_unique(viewBounds); + self.slices.insert_or_assign(viewId, std::move(view)); + + self.compositionOrder.push_back(viewId); + + if (self.currentCompositionParams.count(viewId) == 1 && + self.currentCompositionParams[viewId] == *params.get()) { + // Do nothing if the params didn't change. + return; + } + self.currentCompositionParams[viewId] = flutter::EmbeddedViewParams(*params.get()); + self.viewsToRecomposite.insert(viewId); +} + +- (size_t)embeddedViewCount { + return self.compositionOrder.size(); +} + +- (size_t)layerPoolSize { + return self.layerPool->size(); +} + +- (UIView*)platformViewForId:(int64_t)viewId { + return [self flutterTouchInterceptingViewForId:viewId].embeddedView; +} + +- (FlutterTouchInterceptingView*)flutterTouchInterceptingViewForId:(int64_t)viewId { + if (self.platformViews.empty()) { + return nil; + } + return self.platformViews[viewId].touch_interceptor; +} + +- (long)firstResponderPlatformViewId { + for (auto const& [id, platformViewData] : self.platformViews) { + UIView* rootView = platformViewData.root_view; + if (rootView.flt_hasFirstResponderInViewHierarchySubtree) { + return id; + } + } + return -1; +} + +- (void)clipViewSetMaskView:(UIView*)clipView { + FML_DCHECK([[NSThread currentThread] isMainThread]); + if (clipView.maskView) { + return; + } + CGRect frame = + CGRectMake(-clipView.frame.origin.x, -clipView.frame.origin.y, + CGRectGetWidth(self.flutterView.bounds), CGRectGetHeight(self.flutterView.bounds)); + clipView.maskView = [self.maskViewPool getMaskViewWithFrame:frame]; +} + +- (void)applyMutators:(const flutter::MutatorsStack&)mutatorsStack + embeddedView:(UIView*)embeddedView + boundingRect:(const SkRect&)boundingRect { + if (self.flutterView == nil) { + return; + } + + ResetAnchor(embeddedView.layer); + ChildClippingView* clipView = (ChildClippingView*)embeddedView.superview; + + SkMatrix transformMatrix; + NSMutableArray* blurFilters = [[NSMutableArray alloc] init]; + FML_DCHECK(!clipView.maskView || + [clipView.maskView isKindOfClass:[FlutterClippingMaskView class]]); + if (clipView.maskView) { + [self.maskViewPool insertViewToPoolIfNeeded:(FlutterClippingMaskView*)(clipView.maskView)]; + clipView.maskView = nil; + } + CGFloat screenScale = [UIScreen mainScreen].scale; + auto iter = mutatorsStack.Begin(); + while (iter != mutatorsStack.End()) { + switch ((*iter)->GetType()) { + case flutter::kTransform: { + transformMatrix.preConcat((*iter)->GetMatrix()); + break; + } + case flutter::kClipRect: { + if (ClipRectContainsPlatformViewBoundingRect((*iter)->GetRect(), boundingRect, + transformMatrix)) { + break; + } + [self clipViewSetMaskView:clipView]; + [(FlutterClippingMaskView*)clipView.maskView clipRect:(*iter)->GetRect() + matrix:transformMatrix]; + break; + } + case flutter::kClipRRect: { + if (ClipRRectContainsPlatformViewBoundingRect((*iter)->GetRRect(), boundingRect, + transformMatrix)) { + break; + } + [self clipViewSetMaskView:clipView]; + [(FlutterClippingMaskView*)clipView.maskView clipRRect:(*iter)->GetRRect() + matrix:transformMatrix]; + break; + } + case flutter::kClipPath: { + // TODO(cyanglaz): Find a way to pre-determine if path contains the PlatformView boudning + // rect. See `ClipRRectContainsPlatformViewBoundingRect`. + // https://github.com/flutter/flutter/issues/118650 + [self clipViewSetMaskView:clipView]; + [(FlutterClippingMaskView*)clipView.maskView clipPath:(*iter)->GetPath() + matrix:transformMatrix]; + break; + } + case flutter::kOpacity: + embeddedView.alpha = (*iter)->GetAlphaFloat() * embeddedView.alpha; + break; + case flutter::kBackdropFilter: { + // Only support DlBlurImageFilter for BackdropFilter. + if (!flutter::canApplyBlurBackdrop || !(*iter)->GetFilterMutation().GetFilter().asBlur()) { + break; + } + CGRect filterRect = GetCGRectFromSkRect((*iter)->GetFilterMutation().GetFilterRect()); + // `filterRect` is in global coordinates. We need to convert to local space. + filterRect = CGRectApplyAffineTransform( + filterRect, CGAffineTransformMakeScale(1 / screenScale, 1 / screenScale)); + // `filterRect` reprents the rect that should be filtered inside the `_flutterView`. + // The `PlatformViewFilter` needs the frame inside the `clipView` that needs to be + // filtered. + if (CGRectIsNull(CGRectIntersection(filterRect, clipView.frame))) { + break; + } + CGRect intersection = CGRectIntersection(filterRect, clipView.frame); + CGRect frameInClipView = [self.flutterView convertRect:intersection toView:clipView]; + // sigma_x is arbitrarily chosen as the radius value because Quartz sets + // sigma_x and sigma_y equal to each other. DlBlurImageFilter's Tile Mode + // is not supported in Quartz's gaussianBlur CAFilter, so it is not used + // to blur the PlatformView. + CGFloat blurRadius = (*iter)->GetFilterMutation().GetFilter().asBlur()->sigma_x(); + UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc] + initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]]; + PlatformViewFilter* filter = [[PlatformViewFilter alloc] initWithFrame:frameInClipView + blurRadius:blurRadius + visualEffectView:visualEffectView]; + if (!filter) { + flutter::canApplyBlurBackdrop = NO; + } else { + [blurFilters addObject:filter]; + } + break; + } + } + ++iter; + } + + if (flutter::canApplyBlurBackdrop) { + [clipView applyBlurBackdropFilters:blurFilters]; + } + + // The UIKit frame is set based on the logical resolution (points) instead of physical. + // (https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html). + // However, flow is based on the physical resolution. For example, 1000 pixels in flow equals + // 500 points in UIKit for devices that has screenScale of 2. We need to scale the transformMatrix + // down to the logical resoltion before applying it to the layer of PlatformView. + transformMatrix.postScale(1 / screenScale, 1 / screenScale); + + // Reverse the offset of the clipView. + // The clipView's frame includes the final translate of the final transform matrix. + // Thus, this translate needs to be reversed so the platform view can layout at the correct + // offset. + // + // Note that the transforms are not applied to the clipping paths because clipping paths happen on + // the mask view, whose origin is always (0,0) to the _flutterView. + transformMatrix.postTranslate(-clipView.frame.origin.x, -clipView.frame.origin.y); + + embeddedView.layer.transform = GetCATransform3DFromSkMatrix(transformMatrix); +} + +- (void)compositeView:(int64_t)viewId withParams:(const flutter::EmbeddedViewParams&)params { + // TODO(https://github.com/flutter/flutter/issues/109700) + CGRect frame = CGRectMake(0, 0, params.sizePoints().width(), params.sizePoints().height()); + FlutterTouchInterceptingView* touchInterceptor = self.platformViews[viewId].touch_interceptor; + touchInterceptor.layer.transform = CATransform3DIdentity; + touchInterceptor.frame = frame; + touchInterceptor.alpha = 1; + + const flutter::MutatorsStack& mutatorStack = params.mutatorsStack(); + UIView* clippingView = self.platformViews[viewId].root_view; + // The frame of the clipping view should be the final bounding rect. + // Because the translate matrix in the Mutator Stack also includes the offset, + // when we apply the transforms matrix in |applyMutators:embeddedView:boundingRect|, we need + // to remember to do a reverse translate. + const SkRect& rect = params.finalBoundingRect(); + CGFloat screenScale = [UIScreen mainScreen].scale; + clippingView.frame = CGRectMake(rect.x() / screenScale, rect.y() / screenScale, + rect.width() / screenScale, rect.height() / screenScale); + [self applyMutators:mutatorStack embeddedView:touchInterceptor boundingRect:rect]; +} + +- (flutter::DlCanvas*)compositeEmbeddedViewWithId:(int64_t)viewId { + return self.slices[viewId]->canvas(); +} + +- (void)reset { + // Reset will only be called from the raster thread or a merged raster/platform thread. + // _platformViews must only be modified on the platform thread, and any operations that + // read or modify platform views should occur there. + fml::TaskRunner::RunNowOrPostTask(self.platformTaskRunner, [self]() { + for (int64_t viewId : self.compositionOrder) { + [self.platformViews[viewId].root_view removeFromSuperview]; + } + self.platformViews.clear(); + }); + + self.compositionOrder.clear(); + self.slices.clear(); + self.currentCompositionParams.clear(); + self.viewsToRecomposite.clear(); + self.layerPool->RecycleLayers(); + self.visitedPlatformViews.clear(); +} + +- (BOOL)submitFrame:(std::unique_ptr)background_frame + withIosContext:(const std::shared_ptr&)iosContext + grContext:(GrDirectContext*)grContext { + TRACE_EVENT0("flutter", "PlatformViewsController::SubmitFrame"); + + // No platform views to render; we're done. + if (self.flutterView == nil || (self.compositionOrder.empty() && !self.hadPlatformViews)) { + self.hadPlatformViews = NO; + return background_frame->Submit(); + } + self.hadPlatformViews = !self.compositionOrder.empty(); + + bool didEncode = true; + LayersMap platformViewLayers; + std::vector> surfaceFrames; + surfaceFrames.reserve(self.compositionOrder.size()); + std::unordered_map viewRects; + + for (int64_t viewId : self.compositionOrder) { + viewRects[viewId] = self.currentCompositionParams[viewId].finalBoundingRect(); + } + + std::unordered_map overlayLayers = + SliceViews(background_frame->Canvas(), self.compositionOrder, self.slices, viewRects); + + size_t requiredOverlayLayers = 0; + for (int64_t viewId : self.compositionOrder) { + std::unordered_map::const_iterator overlay = overlayLayers.find(viewId); + if (overlay == overlayLayers.end()) { + continue; + } + requiredOverlayLayers++; + } + + // If there are not sufficient overlay layers, we must construct them on the platform + // thread, at least until we've refactored iOS surface creation to use IOSurfaces + // instead of CALayers. + [self createMissingOverlays:requiredOverlayLayers withIosContext:iosContext grContext:grContext]; + + int64_t overlayId = 0; + for (int64_t viewId : self.compositionOrder) { + std::unordered_map::const_iterator overlay = overlayLayers.find(viewId); + if (overlay == overlayLayers.end()) { + continue; + } + std::shared_ptr layer = self.nextLayerInPool; + if (!layer) { + continue; + } + + std::unique_ptr frame = layer->surface->AcquireFrame(self.frameSize); + // If frame is null, AcquireFrame already printed out an error message. + if (!frame) { + continue; + } + flutter::DlCanvas* overlayCanvas = frame->Canvas(); + int restoreCount = overlayCanvas->GetSaveCount(); + overlayCanvas->Save(); + overlayCanvas->ClipRect(overlay->second); + overlayCanvas->Clear(flutter::DlColor::kTransparent()); + self.slices[viewId]->render_into(overlayCanvas); + overlayCanvas->RestoreToCount(restoreCount); + + // This flutter view is never the last in a frame, since we always submit the + // underlay view last. + frame->set_submit_info({.frame_boundary = false, .present_with_transaction = true}); + layer->did_submit_last_frame = frame->Encode(); + + didEncode &= layer->did_submit_last_frame; + platformViewLayers[viewId] = LayerData{ + .rect = overlay->second, // + .view_id = viewId, // + .overlay_id = overlayId, // + .layer = layer // + }; + surfaceFrames.push_back(std::move(frame)); + overlayId++; + } + + auto previousSubmitInfo = background_frame->submit_info(); + background_frame->set_submit_info({ + .frame_damage = previousSubmitInfo.frame_damage, + .buffer_damage = previousSubmitInfo.buffer_damage, + .present_with_transaction = true, + }); + background_frame->Encode(); + surfaceFrames.push_back(std::move(background_frame)); + + // Mark all layers as available, so they can be used in the next frame. + std::vector> unusedLayers = + self.layerPool->RemoveUnusedLayers(); + self.layerPool->RecycleLayers(); + + auto task = [self, // + platformViewLayers = std::move(platformViewLayers), // + currentCompositionParams = self.currentCompositionParams, // + viewsToRecomposite = self.viewsToRecomposite, // + compositionOrder = self.compositionOrder, // + unusedLayers = std::move(unusedLayers), // + surfaceFrames = std::move(surfaceFrames) // + ]() mutable { + [self performSubmit:platformViewLayers + currentCompositionParams:currentCompositionParams + viewsToRecomposite:viewsToRecomposite + compositionOrder:compositionOrder + unusedLayers:unusedLayers + surfaceFrames:surfaceFrames]; + }; + + fml::TaskRunner::RunNowOrPostTask(self.platformTaskRunner, fml::MakeCopyable(std::move(task))); + + return didEncode; +} + +- (void)createMissingOverlays:(size_t)requiredOverlayLayers + withIosContext:(const std::shared_ptr&)iosContext + grContext:(GrDirectContext*)grContext { + TRACE_EVENT0("flutter", "PlatformViewsController::CreateMissingLayers"); + + if (requiredOverlayLayers <= self.layerPool->size()) { + return; + } + auto missingLayerCount = requiredOverlayLayers - self.layerPool->size(); + + // If the raster thread isn't merged, create layers on the platform thread and block until + // complete. + auto latch = std::make_shared(1u); + fml::TaskRunner::RunNowOrPostTask( + self.platformTaskRunner, [self, missingLayerCount, iosContext, grContext, latch]() { + for (auto i = 0u; i < missingLayerCount; i++) { + [self createLayerWithIosContext:iosContext + grContext:grContext + pixelFormat:((FlutterView*)self.flutterView).pixelFormat]; + } + latch->CountDown(); + }); + if (![[NSThread currentThread] isMainThread]) { + latch->Wait(); + } +} + +- (void)performSubmit:(const LayersMap&)platformViewLayers + currentCompositionParams: + (std::unordered_map&)currentCompositionParams + viewsToRecomposite:(const std::unordered_set&)viewsToRecomposite + compositionOrder:(const std::vector&)compositionOrder + unusedLayers: + (const std::vector>&)unusedLayers + surfaceFrames: + (const std::vector>&)surfaceFrames { + TRACE_EVENT0("flutter", "PlatformViewsController::PerformSubmit"); + FML_DCHECK([[NSThread currentThread] isMainThread]); + + [CATransaction begin]; + + // Configure Flutter overlay views. + for (const auto& [viewId, layerData] : platformViewLayers) { + layerData.layer->UpdateViewState(self.flutterView, // + layerData.rect, // + layerData.view_id, // + layerData.overlay_id // + ); + } + + // Dispose unused Flutter Views. + for (auto& view : [self computeViewsToDispose]) { + [view removeFromSuperview]; + } + + // Composite Platform Views. + for (int64_t viewId : viewsToRecomposite) { + [self compositeView:viewId withParams:currentCompositionParams[viewId]]; + } + + // Present callbacks. + for (const auto& frame : surfaceFrames) { + frame->Submit(); + } + + // If a layer was allocated in the previous frame, but it's not used in the current frame, + // then it can be removed from the scene. + [self removeUnusedLayers:unusedLayers withCompositionOrder:compositionOrder]; + + // Organize the layers by their z indexes. + [self bringLayersIntoView:platformViewLayers withCompositionOrder:compositionOrder]; + + [CATransaction commit]; +} + +- (void)bringLayersIntoView:(const LayersMap&)layerMap + withCompositionOrder:(const std::vector&)compositionOrder { + FML_DCHECK(self.flutterView); + UIView* flutterView = self.flutterView; + + self.previousCompositionOrder.clear(); + NSMutableArray* desiredPlatformSubviews = [NSMutableArray array]; + for (int64_t platformViewId : compositionOrder) { + self.previousCompositionOrder.push_back(platformViewId); + UIView* platformViewRoot = self.platformViews[platformViewId].root_view; + if (platformViewRoot != nil) { + [desiredPlatformSubviews addObject:platformViewRoot]; + } + + auto maybeLayerData = layerMap.find(platformViewId); + if (maybeLayerData != layerMap.end()) { + auto view = maybeLayerData->second.layer->overlay_view_wrapper; + if (view != nil) { + [desiredPlatformSubviews addObject:view]; + } + } + } + + NSSet* desiredPlatformSubviewsSet = [NSSet setWithArray:desiredPlatformSubviews]; + NSArray* existingPlatformSubviews = [flutterView.subviews + filteredArrayUsingPredicate:[NSPredicate + predicateWithBlock:^BOOL(id object, NSDictionary* bindings) { + return [desiredPlatformSubviewsSet containsObject:object]; + }]]; + + // Manipulate view hierarchy only if needed, to address a performance issue where + // this method is called even when view hierarchy stays the same. + // See: https://github.com/flutter/flutter/issues/121833 + // TODO(hellohuanlin): investigate if it is possible to skip unnecessary bringLayersIntoView. + if (![desiredPlatformSubviews isEqualToArray:existingPlatformSubviews]) { + for (UIView* subview in desiredPlatformSubviews) { + // `addSubview` will automatically reorder subview if it is already added. + [flutterView addSubview:subview]; + } + } +} + +- (std::shared_ptr)nextLayerInPool { + return self.layerPool->GetNextLayer(); +} + +- (void)createLayerWithIosContext:(const std::shared_ptr&)iosContext + grContext:(GrDirectContext*)grContext + pixelFormat:(MTLPixelFormat)pixelFormat { + self.layerPool->CreateLayer(grContext, iosContext, pixelFormat); +} + +- (void)removeUnusedLayers:(const std::vector>&)unusedLayers + withCompositionOrder:(const std::vector&)compositionOrder { + for (const std::shared_ptr& layer : unusedLayers) { + [layer->overlay_view_wrapper removeFromSuperview]; + } + + std::unordered_set compositionOrderSet; + for (int64_t viewId : compositionOrder) { + compositionOrderSet.insert(viewId); + } + // Remove unused platform views. + for (int64_t viewId : self.previousCompositionOrder) { + if (compositionOrderSet.find(viewId) == compositionOrderSet.end()) { + UIView* platformViewRoot = self.platformViews[viewId].root_view; + [platformViewRoot removeFromSuperview]; + } + } +} + +- (std::vector)computeViewsToDispose { + std::vector views; + if (self.viewsToDispose.empty()) { + return views; + } + + std::unordered_set viewsToComposite(self.compositionOrder.begin(), + self.compositionOrder.end()); + std::unordered_set viewsToDelayDispose; + for (int64_t viewId : self.viewsToDispose) { + if (viewsToComposite.count(viewId)) { + viewsToDelayDispose.insert(viewId); + continue; + } + UIView* rootView = self.platformViews[viewId].root_view; + views.push_back(rootView); + self.currentCompositionParams.erase(viewId); + self.viewsToRecomposite.erase(viewId); + self.platformViews.erase(viewId); + } + self.viewsToDispose = std::move(viewsToDelayDispose); + return views; +} + +- (void)resetFrameState { + self.slices.clear(); + self.compositionOrder.clear(); + self.visitedPlatformViews.clear(); +} + +- (void)pushVisitedPlatformViewId:(int64_t)viewId { + self.visitedPlatformViews.push_back(viewId); +} + +- (const flutter::EmbeddedViewParams&)compositionParamsForView:(int64_t)viewId { + return self.currentCompositionParams.find(viewId)->second; +} + +#pragma mark - Properties + +- (flutter::OverlayLayerPool*)layerPool { + return _layerPool.get(); +} + +- (std::unordered_map>&)slices { + return _slices; +} + +- (std::unordered_map*>&)factories { + return _factories; +} +- (std::unordered_map&) + gestureRecognizersBlockingPolicies { + return _gestureRecognizersBlockingPolicies; +} + +- (std::unordered_map&)platformViews { + return _platformViews; +} + +- (std::unordered_map&)currentCompositionParams { + return _currentCompositionParams; +} + +- (std::unordered_set&)viewsToDispose { + return _viewsToDispose; +} + +- (std::vector&)compositionOrder { + return _compositionOrder; +} + +- (std::vector&)visitedPlatformViews { + return _visitedPlatformViews; +} + +- (std::unordered_set&)viewsToRecomposite { + return _viewsToRecomposite; +} + +- (std::vector&)previousCompositionOrder { + return _previousCompositionOrder; +} + +@end diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 8c0bb2b03e..dd48e60364 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -2,21 +2,22 @@ // 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/FlutterPlatformViews.h" + #import #import #import -#include "fml/synchronization/count_down_latch.h" -#include "shell/platform/darwin/ios/framework/Source/platform_views_controller.h" -#import "flutter/display_list/effects/dl_image_filters.h" -#import "flutter/fml/thread.h" +#include "flutter/display_list/effects/dl_image_filters.h" +#include "flutter/fml/synchronization/count_down_latch.h" +#include "flutter/fml/thread.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" -#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h" #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTouchInterceptingView_Test.h" -#import "flutter/shell/platform/darwin/ios/platform_view_ios.h" +#include "flutter/shell/platform/darwin/ios/platform_view_ios.h" FLUTTER_ASSERT_ARC @@ -163,8 +164,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -177,18 +179,21 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -204,11 +209,12 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; XCTAssertNotNil(gMockPlatformView); - flutterPlatformViewsController->Reset(); + [flutterPlatformViewsController reset]; } - (void)testCanCreatePlatformViewWithoutFlutterView { @@ -219,8 +225,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -233,16 +240,19 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); } @@ -312,8 +322,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -326,21 +337,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -354,9 +368,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:[ChildClippingView class]]); ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; @@ -389,8 +405,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -403,21 +420,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -431,9 +451,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(5, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:[ChildClippingView class]]); ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; @@ -466,8 +488,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -480,21 +503,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -510,9 +536,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(20, 20), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; @@ -544,8 +572,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -558,21 +587,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -586,9 +618,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:[ChildClippingView class]]); ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; @@ -625,9 +659,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -665,8 +701,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -679,21 +716,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -709,9 +749,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; @@ -746,9 +788,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -787,9 +831,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -811,8 +857,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -825,21 +872,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -855,9 +905,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; @@ -900,9 +952,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -955,9 +1009,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -1008,9 +1064,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -1058,9 +1116,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -1098,8 +1158,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -1112,21 +1173,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -1140,9 +1204,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:[ChildClippingView class]]); ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; @@ -1182,9 +1248,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -1223,9 +1291,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -1264,9 +1334,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -1299,9 +1371,11 @@ fml::RefPtr GetDefaultTaskRunner() { embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; [flutterView setNeedsLayout]; [flutterView layoutIfNeeded]; @@ -1417,8 +1491,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -1431,21 +1506,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -1461,9 +1539,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds toView:flutterView]; @@ -1478,8 +1558,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -1492,21 +1573,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -1517,14 +1601,17 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->BeginFrame(SkISize::Make(0, 0)); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->PushVisitedPlatformView(2); + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(0, 0)]; + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController pushVisitedPlatformViewId:2]; auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp); - flutterPlatformViewsController->PushFilterToVisitedPlatformViews( - filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController + pushFilterToVisitedPlatformViews:filter + withRect:SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:[ChildClippingView class]]); ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; @@ -1551,10 +1638,12 @@ fml::RefPtr GetDefaultTaskRunner() { // New frame, with no filter pushed. auto embeddedViewParams2 = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->BeginFrame(SkISize::Make(0, 0)); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams2)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(0, 0)]; + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams2)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:[ChildClippingView class]]); @@ -1579,8 +1668,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -1593,21 +1683,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -1624,9 +1717,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds toView:flutterView]; @@ -1655,8 +1750,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -1669,21 +1765,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params. flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack. @@ -1705,9 +1804,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique( SkMatrix::Concat(screenScaleMatrix, translateMatrix), SkSize::Make(5, 5), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; gMockPlatformView.backgroundColor = UIColor.redColor; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); @@ -1727,8 +1828,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -1741,21 +1843,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack. @@ -1775,9 +1880,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique( SkMatrix::Concat(screenScaleMatrix, translateMatrix), SkSize::Make(5, 5), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; gMockPlatformView.backgroundColor = UIColor.redColor; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); @@ -1798,8 +1905,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -1812,21 +1920,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -1840,9 +1951,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; gMockPlatformView.backgroundColor = UIColor.redColor; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); @@ -1874,8 +1987,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -1888,21 +2002,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -1919,9 +2036,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; gMockPlatformView.backgroundColor = UIColor.redColor; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); @@ -1970,8 +2089,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -1984,21 +2104,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -2012,9 +2135,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; gMockPlatformView.backgroundColor = UIColor.redColor; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); @@ -2073,8 +2198,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2087,21 +2213,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -2118,9 +2247,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; gMockPlatformView.backgroundColor = UIColor.redColor; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); @@ -2193,8 +2324,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2207,21 +2339,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -2236,9 +2371,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; gMockPlatformView.backgroundColor = UIColor.redColor; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); @@ -2297,8 +2434,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2311,21 +2449,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -2343,9 +2484,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; gMockPlatformView.backgroundColor = UIColor.redColor; XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); @@ -2418,8 +2561,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2432,16 +2576,19 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); @@ -2472,7 +2619,7 @@ fml::RefPtr GetDefaultTaskRunner() { // Set flutter view controller allows events to be dispatched. NSSet* touches2 = [[NSSet alloc] init]; id event2 = OCMClassMock([UIEvent class]); - flutterPlatformViewsController->SetFlutterViewController(flutterViewController); + flutterPlatformViewsController.flutterViewController = flutterViewController; [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2]; OCMVerify([flutterViewController touchesBegan:touches2 withEvent:event2]); } @@ -2485,8 +2632,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2499,16 +2647,19 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); @@ -2531,14 +2682,14 @@ fml::RefPtr GetDefaultTaskRunner() { id flutterViewController = OCMClassMock([FlutterViewController class]); { // ***** Sequence 1, finishing touch event with touchEnded ***** // - flutterPlatformViewsController->SetFlutterViewController(flutterViewController); + flutterPlatformViewsController.flutterViewController = flutterViewController; NSSet* touches1 = [[NSSet alloc] init]; id event1 = OCMClassMock([UIEvent class]); [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1]; OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]); - flutterPlatformViewsController->SetFlutterViewController(nil); + flutterPlatformViewsController.flutterViewController = nil; // Allow the touch events to finish NSSet* touches2 = [[NSSet alloc] init]; @@ -2565,14 +2716,14 @@ fml::RefPtr GetDefaultTaskRunner() { { // ***** Sequence 2, finishing touch event with touchCancelled ***** // - flutterPlatformViewsController->SetFlutterViewController(flutterViewController); + flutterPlatformViewsController.flutterViewController = flutterViewController; NSSet* touches1 = [[NSSet alloc] init]; id event1 = OCMClassMock([UIEvent class]); [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1]; OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]); - flutterPlatformViewsController->SetFlutterViewController(nil); + flutterPlatformViewsController.flutterViewController = nil; // Allow the touch events to finish NSSet* touches2 = [[NSSet alloc] init]; @@ -2597,7 +2748,7 @@ fml::RefPtr GetDefaultTaskRunner() { OCMReject([flutterViewController touchesEnded:touches5 withEvent:event5]); } - flutterPlatformViewsController->Reset(); + [flutterPlatformViewsController reset]; } - (void) @@ -2609,8 +2760,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2623,16 +2775,19 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); @@ -2653,8 +2808,7 @@ fml::RefPtr GetDefaultTaskRunner() { } } id flutterViewController = OCMClassMock([FlutterViewController class]); - - flutterPlatformViewsController->SetFlutterViewController(flutterViewController); + flutterPlatformViewsController.flutterViewController = flutterViewController; // The touches in this sequence requires 1 touch object, we always create the NSSet with one item. NSSet* touches1 = [NSSet setWithObject:@1]; @@ -2663,7 +2817,7 @@ fml::RefPtr GetDefaultTaskRunner() { OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]); FlutterViewController* flutterViewController2 = OCMClassMock([FlutterViewController class]); - flutterPlatformViewsController->SetFlutterViewController(flutterViewController2); + flutterPlatformViewsController.flutterViewController = flutterViewController2; // Touch events should still send to the old FlutterViewController if FlutterViewController // is updated in between. @@ -2712,7 +2866,7 @@ fml::RefPtr GetDefaultTaskRunner() { OCMVerify([flutterViewController2 touchesEnded:touches8 withEvent:event8]); OCMReject([flutterViewController touchesEnded:touches8 withEvent:event8]); - flutterPlatformViewsController->Reset(); + [flutterPlatformViewsController reset]; } - (void)testFlutterPlatformViewTouchesCancelledEventAreForcedToBeCancelled { @@ -2723,8 +2877,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2737,16 +2892,19 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); @@ -2767,8 +2925,7 @@ fml::RefPtr GetDefaultTaskRunner() { } } id flutterViewController = OCMClassMock([FlutterViewController class]); - - flutterPlatformViewsController->SetFlutterViewController(flutterViewController); + flutterPlatformViewsController.flutterViewController = flutterViewController; NSSet* touches1 = [NSSet setWithObject:@1]; id event1 = OCMClassMock([UIEvent class]); @@ -2777,7 +2934,7 @@ fml::RefPtr GetDefaultTaskRunner() { [forwardGectureRecognizer touchesCancelled:touches1 withEvent:event1]; OCMVerify([flutterViewController forceTouchesCancelled:touches1]); - flutterPlatformViewsController->Reset(); + [flutterPlatformViewsController reset]; } - (void)testFlutterPlatformViewTouchesEndedOrTouchesCancelledEventDoesNotFailTheGestureRecognizer { @@ -2788,8 +2945,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2802,16 +2960,19 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); @@ -2832,8 +2993,7 @@ fml::RefPtr GetDefaultTaskRunner() { } } id flutterViewController = OCMClassMock([FlutterViewController class]); - - flutterPlatformViewsController->SetFlutterViewController(flutterViewController); + flutterPlatformViewsController.flutterViewController = flutterViewController; NSSet* touches1 = [NSSet setWithObject:@1]; id event1 = OCMClassMock([UIEvent class]); @@ -2882,7 +3042,7 @@ fml::RefPtr GetDefaultTaskRunner() { }); [self waitForExpectationsWithTimeout:30 handler:nil]; - flutterPlatformViewsController->Reset(); + [flutterPlatformViewsController reset]; } - (void)testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashing { @@ -2893,8 +3053,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2907,16 +3068,19 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); @@ -2927,9 +3091,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams_1 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams_1)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams_1)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; flutter::SurfaceFrame::FramebufferInfo framebuffer_info; auto mock_surface = std::make_unique( @@ -2937,22 +3103,26 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return false; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertFalse( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertFalse([flutterPlatformViewsController submitFrame:std::move(mock_surface) + withIosContext:nil + grContext:nil]); auto embeddedViewParams_2 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams_2)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams_2)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; auto mock_surface_submit_true = std::make_unique( nullptr, framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, - std::move(mock_surface_submit_true))); + XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface_submit_true) + withIosContext:nil + grContext:nil]); } - (void) @@ -2964,8 +3134,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2977,34 +3148,38 @@ fml::RefPtr GetDefaultTaskRunner() { /*is_gpu_disabled_jsync_switch=*/std::make_shared()); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; // autorelease pool to trigger an autorelease for all the root_views_ and touch_interceptors_. @autoreleasepool { - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; flutter::MutatorsStack stack; SkMatrix finalMatrix; auto embeddedViewParams = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; - // Not calling |flutterPlatformViewsController::SubmitFrame| so that the platform views are not - // added to flutter_view_. + // Not calling |[flutterPlatformViewsController submitFrame:withIosContext:grContext:]| so that + // the platform views are not added to flutter_view_. XCTAssertNotNil(gMockPlatformView); - flutterPlatformViewsController->Reset(); + [flutterPlatformViewsController reset]; } XCTAssertNil(gMockPlatformView); } @@ -3017,8 +3192,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -3030,45 +3206,52 @@ fml::RefPtr GetDefaultTaskRunner() { /*is_gpu_disabled_jsync_switch=*/std::make_shared()); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @0, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @0, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; - // First frame, |EmbeddedViewCount| is not empty after composite. - flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300)); + // First frame, |embeddedViewCount| is not empty after composite. + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)]; flutter::MutatorsStack stack; SkMatrix finalMatrix; auto embeddedViewParams1 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams1)); - flutterPlatformViewsController->CompositeWithParams( - 0, flutterPlatformViewsController->GetCompositionParams(0)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:0 + withParams:std::move(embeddedViewParams1)]; + [flutterPlatformViewsController + compositeView:0 + withParams:[flutterPlatformViewsController compositionParamsForView:0]]; - XCTAssertEqual(flutterPlatformViewsController->EmbeddedViewCount(), 1UL); + XCTAssertEqual(flutterPlatformViewsController.embeddedViewCount, 1UL); - // Second frame, |EmbeddedViewCount| should be empty at the start - flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300)); - XCTAssertEqual(flutterPlatformViewsController->EmbeddedViewCount(), 0UL); + // Second frame, |embeddedViewCount| should be empty at the start + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)]; + XCTAssertEqual(flutterPlatformViewsController.embeddedViewCount, 0UL); auto embeddedViewParams2 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams2)); - flutterPlatformViewsController->CompositeWithParams( - 0, flutterPlatformViewsController->GetCompositionParams(0)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:0 + withParams:std::move(embeddedViewParams2)]; + [flutterPlatformViewsController + compositeView:0 + withParams:[flutterPlatformViewsController compositionParamsForView:0]]; - XCTAssertEqual(flutterPlatformViewsController->EmbeddedViewCount(), 1UL); + XCTAssertEqual(flutterPlatformViewsController.embeddedViewCount, 1UL); } - (void) @@ -3080,8 +3263,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -3093,40 +3277,47 @@ fml::RefPtr GetDefaultTaskRunner() { /*is_gpu_disabled_jsync_switch=*/std::make_shared()); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @0, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @0, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; UIView* view1 = gMockPlatformView; // This overwrites `gMockPlatformView` to another view. - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @1, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @1, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; UIView* view2 = gMockPlatformView; - flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300)); + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)]; flutter::MutatorsStack stack; SkMatrix finalMatrix; auto embeddedViewParams1 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:0 + withParams:std::move(embeddedViewParams1)]; auto embeddedViewParams2 = std::make_unique(finalMatrix, SkSize::Make(500, 500), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams2)]; // SKSurface is required if the root FlutterView is present. const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000); @@ -3138,8 +3329,9 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) + withIosContext:nil + grContext:nil]); // platform view is wrapped by touch interceptor, which itself is wrapped by clipping view. UIView* clippingView1 = view1.superview.superview; @@ -3149,15 +3341,17 @@ fml::RefPtr GetDefaultTaskRunner() { @"The first clipping view should be added before the second clipping view."); // Need to recreate these params since they are `std::move`ed. - flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300)); + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)]; // Process the second frame in the opposite order. embeddedViewParams2 = std::make_unique(finalMatrix, SkSize::Make(500, 500), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams2)]; embeddedViewParams1 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:0 + withParams:std::move(embeddedViewParams1)]; mock_sk_surface = SkSurfaces::Raster(image_info); mock_surface = std::make_unique( @@ -3165,8 +3359,9 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) + withIosContext:nil + grContext:nil]); XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] > [flutterView.subviews indexOfObject:clippingView2], @@ -3182,8 +3377,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -3195,40 +3391,47 @@ fml::RefPtr GetDefaultTaskRunner() { /*is_gpu_disabled_jsync_switch=*/std::make_shared()); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @0, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @0, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; UIView* view1 = gMockPlatformView; // This overwrites `gMockPlatformView` to another view. - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @1, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @1, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; UIView* view2 = gMockPlatformView; - flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300)); + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)]; flutter::MutatorsStack stack; SkMatrix finalMatrix; auto embeddedViewParams1 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:0 + withParams:std::move(embeddedViewParams1)]; auto embeddedViewParams2 = std::make_unique(finalMatrix, SkSize::Make(500, 500), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams2)]; // SKSurface is required if the root FlutterView is present. const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000); @@ -3240,8 +3443,9 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) + withIosContext:nil + grContext:nil]); // platform view is wrapped by touch interceptor, which itself is wrapped by clipping view. UIView* clippingView1 = view1.superview.superview; @@ -3251,15 +3455,17 @@ fml::RefPtr GetDefaultTaskRunner() { @"The first clipping view should be added before the second clipping view."); // Need to recreate these params since they are `std::move`ed. - flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300)); + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)]; // Process the second frame in the same order. embeddedViewParams1 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:0 + withParams:std::move(embeddedViewParams1)]; embeddedViewParams2 = std::make_unique(finalMatrix, SkSize::Make(500, 500), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams2)]; mock_sk_surface = SkSurfaces::Raster(image_info); mock_surface = std::make_unique( @@ -3267,8 +3473,10 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + + XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) + withIosContext:nil + grContext:nil]); XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] < [flutterView.subviews indexOfObject:clippingView2], @@ -3369,8 +3577,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -3383,20 +3592,23 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @1, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @1, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack1; // Layer tree always pushes a screen scale factor to the stack @@ -3410,39 +3622,47 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams1 = std::make_unique( screenScaleMatrix, SkSize::Make(10, 10), stack1); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams1)); - flutterPlatformViewsController->CompositeWithParams( - 1, flutterPlatformViewsController->GetCompositionParams(1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams1)]; + [flutterPlatformViewsController + compositeView:1 + withParams:[flutterPlatformViewsController compositionParamsForView:1]]; UIView* childClippingView1 = gMockPlatformView.superview.superview; UIView* maskView1 = childClippingView1.maskView; XCTAssertNotNil(maskView1); // Composite a new frame. - flutterPlatformViewsController->BeginFrame(SkISize::Make(100, 100)); + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(100, 100)]; flutter::MutatorsStack stack2; auto embeddedViewParams2 = std::make_unique( screenScaleMatrix, SkSize::Make(10, 10), stack2); auto embeddedViewParams3 = std::make_unique( screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams3)); - flutterPlatformViewsController->CompositeWithParams( - 1, flutterPlatformViewsController->GetCompositionParams(1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams3)]; + [flutterPlatformViewsController + compositeView:1 + withParams:[flutterPlatformViewsController compositionParamsForView:1]]; childClippingView1 = gMockPlatformView.superview.superview; // This overrides gMockPlatformView to point to the newly created platform view. - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; auto embeddedViewParams4 = std::make_unique( screenScaleMatrix, SkSize::Make(10, 10), stack1); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams4)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams4)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; UIView* childClippingView2 = gMockPlatformView.superview.superview; @@ -3460,8 +3680,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -3474,30 +3695,35 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @1, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @1, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; UIView* view1 = gMockPlatformView; // This overwrites `gMockPlatformView` to another view. - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; UIView* view2 = gMockPlatformView; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack1; // Layer tree always pushes a screen scale factor to the stack @@ -3516,15 +3742,19 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams2 = std::make_unique( screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams1)); - flutterPlatformViewsController->CompositeWithParams( - 1, flutterPlatformViewsController->GetCompositionParams(1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams1)]; + [flutterPlatformViewsController + compositeView:1 + withParams:[flutterPlatformViewsController compositionParamsForView:1]]; UIView* childClippingView1 = view1.superview.superview; - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams2)); - flutterPlatformViewsController->CompositeWithParams( - 2, flutterPlatformViewsController->GetCompositionParams(2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams2)]; + [flutterPlatformViewsController + compositeView:2 + withParams:[flutterPlatformViewsController compositionParamsForView:2]]; UIView* childClippingView2 = view2.superview.superview; UIView* maskView1 = childClippingView1.maskView; @@ -3540,8 +3770,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -3554,21 +3785,24 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @1, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @1, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; XCTAssertNotNil(gMockPlatformView); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack1; // Layer tree always pushes a screen scale factor to the stack @@ -3587,9 +3821,11 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams2 = std::make_unique( screenScaleMatrix, SkSize::Make(10, 10), stack2); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams1)); - flutterPlatformViewsController->CompositeWithParams( - 1, flutterPlatformViewsController->GetCompositionParams(1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams1)]; + [flutterPlatformViewsController + compositeView:1 + withParams:[flutterPlatformViewsController compositionParamsForView:1]]; UIView* childClippingView = gMockPlatformView.superview.superview; @@ -3633,8 +3869,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -3646,50 +3883,58 @@ fml::RefPtr GetDefaultTaskRunner() { /*is_gpu_disabled_jsync_switch=*/std::make_shared()); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @0, @"viewType" : @"MockFlutterPlatformView"}], - result); - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @1, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @0, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @1, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; { // **** First frame, view id 0, 1 in the composition_order_, disposing view 0 is called. **** // // No view should be disposed, or removed from the composition order. - flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300)); + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)]; flutter::MutatorsStack stack; SkMatrix finalMatrix; auto embeddedViewParams0 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams0)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:0 + withParams:std::move(embeddedViewParams0)]; auto embeddedViewParams1 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams1)]; - XCTAssertEqual(flutterPlatformViewsController->EmbeddedViewCount(), 2UL); + XCTAssertEqual(flutterPlatformViewsController.embeddedViewCount, 2UL); XCTestExpectation* expectation = [self expectationWithDescription:@"dispose call ended."]; FlutterResult disposeResult = ^(id result) { [expectation fulfill]; }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall methodCallWithMethodName:@"dispose" arguments:@0], disposeResult); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"dispose" arguments:@0] + result:disposeResult]; [self waitForExpectationsWithTimeout:30 handler:nil]; const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000); @@ -3700,24 +3945,27 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + + XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) + withIosContext:nil + grContext:nil]); // Disposing won't remove embedded views until the view is removed from the composition_order_ - XCTAssertEqual(flutterPlatformViewsController->EmbeddedViewCount(), 2UL); - XCTAssertNotNil(flutterPlatformViewsController->GetPlatformViewByID(0)); - XCTAssertNotNil(flutterPlatformViewsController->GetPlatformViewByID(1)); + XCTAssertEqual(flutterPlatformViewsController.embeddedViewCount, 2UL); + XCTAssertNotNil([flutterPlatformViewsController platformViewForId:0]); + XCTAssertNotNil([flutterPlatformViewsController platformViewForId:1]); } { // **** Second frame, view id 1 in the composition_order_, no disposing view is called, **** // // View 0 is removed from the composition order in this frame, hence also disposed. - flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300)); + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)]; flutter::MutatorsStack stack; SkMatrix finalMatrix; auto embeddedViewParams1 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams1)]; const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000); sk_sp mock_sk_surface = SkSurfaces::Raster(image_info); @@ -3727,13 +3975,15 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + + XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) + withIosContext:nil + grContext:nil]); // Disposing won't remove embedded views until the view is removed from the composition_order_ - XCTAssertEqual(flutterPlatformViewsController->EmbeddedViewCount(), 1UL); - XCTAssertNil(flutterPlatformViewsController->GetPlatformViewByID(0)); - XCTAssertNotNil(flutterPlatformViewsController->GetPlatformViewByID(1)); + XCTAssertEqual(flutterPlatformViewsController.embeddedViewCount, 1UL); + XCTAssertNil([flutterPlatformViewsController platformViewForId:0]); + XCTAssertNotNil([flutterPlatformViewsController platformViewForId:1]); } } - (void)testOnlyPlatformViewsAreRemovedWhenReset { @@ -3744,8 +3994,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -3758,18 +4009,21 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack @@ -3785,7 +4039,8 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; // SKSurface is required if the root FlutterView is present. const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000); @@ -3797,12 +4052,14 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface)); + [flutterPlatformViewsController submitFrame:std::move(mock_surface) + withIosContext:nil + grContext:nil]; UIView* someView = [[UIView alloc] init]; [flutterView addSubview:someView]; - flutterPlatformViewsController->Reset(); + [flutterPlatformViewsController reset]; XCTAssertEqual(flutterView.subviews.count, 1u); XCTAssertEqual(flutterView.subviews.firstObject, someView); } @@ -3815,8 +4072,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -3829,18 +4087,21 @@ fml::RefPtr GetDefaultTaskRunner() { FlutterPlatformViewsTestNilFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestNilFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; @@ -3857,7 +4118,8 @@ fml::RefPtr GetDefaultTaskRunner() { auto embeddedViewParams = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:2 + withParams:std::move(embeddedViewParams)]; // SKSurface is required if the root FlutterView is present. const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000); @@ -3869,7 +4131,9 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface)); + [flutterPlatformViewsController submitFrame:std::move(mock_surface) + withIosContext:nil + grContext:nil]; XCTAssertEqual(flutterView.subviews.count, 1u); } @@ -3915,8 +4179,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*raster=*/GetDefaultTaskRunner(), /*ui=*/GetDefaultTaskRunner(), /*io=*/GetDefaultTaskRunner()); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner(); auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -3928,38 +4193,45 @@ fml::RefPtr GetDefaultTaskRunner() { /*is_gpu_disabled_jsync_switch=*/std::make_shared()); UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; - flutterPlatformViewsController->SetFlutterView(flutterView); + flutterPlatformViewsController.flutterView = flutterView; FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @0, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @0, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; // This overwrites `gMockPlatformView` to another view. - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @1, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @1, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; - flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300)); + [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)]; flutter::MutatorsStack stack; SkMatrix finalMatrix; auto embeddedViewParams1 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams1)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:0 + withParams:std::move(embeddedViewParams1)]; auto embeddedViewParams2 = std::make_unique(finalMatrix, SkSize::Make(500, 500), stack); - flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams2)); + [flutterPlatformViewsController prerollCompositeEmbeddedView:1 + withParams:std::move(embeddedViewParams2)]; // SKSurface is required if the root FlutterView is present. const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000); @@ -3979,8 +4251,9 @@ fml::RefPtr GetDefaultTaskRunner() { .buffer_damage = SkIRect::MakeWH(400, 600), }); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + [flutterPlatformViewsController submitFrame:std::move(mock_surface) + withIosContext:nil + grContext:nil]; XCTAssertTrue(submit_info.has_value()); XCTAssertEqual(*submit_info->frame_damage, SkIRect::MakeWH(800, 600)); diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index 8267b1ccfe..b23d532cf4 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -6,20 +6,20 @@ #define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_ #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h" -#include "fml/task_runner.h" -#include "impeller/base/thread_safety.h" -#include "third_party/skia/include/core/SkRect.h" #include #include "flutter/flow/surface.h" #include "flutter/fml/memory/weak_ptr.h" +#include "flutter/fml/task_runner.h" #include "flutter/fml/trace_event.h" +#include "flutter/impeller/base/thread_safety.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h" #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewResponder.h" -#import "flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.h" -#import "flutter/shell/platform/darwin/ios/ios_context.h" +#include "flutter/shell/platform/darwin/ios/ios_context.h" +#include "third_party/skia/include/core/SkRect.h" // A UIView that acts as a clipping mask for the |ChildClippingView|. // @@ -134,8 +134,7 @@ // 2. Dispatching all events that are hittested to the embedded view to the FlutterView. @interface FlutterTouchInterceptingView : UIView - (instancetype)initWithEmbeddedView:(UIView*)embeddedView - platformViewsController: - (fml::WeakPtr)platformViewsController + platformViewsController:(FlutterPlatformViewsController*)platformViewsController gestureRecognizersBlockingPolicy: (FlutterPlatformViewGestureRecognizersBlockingPolicy)blockingPolicy; @@ -192,8 +191,7 @@ // directly to the FlutterView. @interface ForwardingGestureRecognizer : UIGestureRecognizer - (instancetype)initWithTarget:(id)target - platformViewsController: - (fml::WeakPtr)platformViewsController; + platformViewsController:(FlutterPlatformViewsController*)platformViewsController; - (ForwardingGestureRecognizer*)recreateRecognizerWithTarget:(id)target; @end diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h index 53dd50e45d..80619e44b7 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h @@ -14,12 +14,11 @@ @protocol FlutterViewEngineDelegate @property(nonatomic, readonly) BOOL isUsingImpeller; +@property(nonatomic, readonly) FlutterPlatformViewsController* platformViewsController; - (flutter::Rasterizer::Screenshot)takeScreenshot:(flutter::Rasterizer::ScreenshotType)type asBase64Encoded:(BOOL)base64Encode; -- (std::shared_ptr&)platformViewsController; - /** * A callback that is called when iOS queries accessibility information of the Flutter view. * diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 319f423d84..2fd71c0874 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -745,14 +745,14 @@ static void SendFakeTouchEvent(UIScreen* screen, // thread. if (appeared) { [self installFirstFrameCallback]; - [self.engine platformViewsController]->SetFlutterView(self.flutterView); - [self.engine platformViewsController]->SetFlutterViewController(self); + self.platformViewsController.flutterView = self.flutterView; + self.platformViewsController.flutterViewController = self; [self.engine iosPlatformView]->NotifyCreated(); } else { self.displayingFlutterUI = NO; [self.engine iosPlatformView]->NotifyDestroyed(); - [self.engine platformViewsController]->SetFlutterView(nullptr); - [self.engine platformViewsController]->SetFlutterViewController(nullptr); + self.platformViewsController.flutterView = nil; + self.platformViewsController.flutterViewController = nil; } } @@ -2321,7 +2321,7 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch) #pragma mark - Platform views -- (std::shared_ptr&)platformViewsController { +- (FlutterPlatformViewsController*)platformViewsController { return self.engine.platformViewsController; } diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h index 62a7df4133..3645d2c376 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h @@ -5,11 +5,12 @@ #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/time/time_point.h" - #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" + +#include "flutter/fml/time/time_point.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterKeySecondaryResponder.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterKeyboardManager.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterRestorationPlugin.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterUIPressProxy.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewResponder.h" @@ -56,7 +57,8 @@ typedef void (^FlutterKeyboardAnimationCallback)(fml::TimePoint); */ @property(nonatomic, assign, readwrite) BOOL prefersStatusBarHidden; -- (std::shared_ptr&)platformViewsController; +@property(nonatomic, readonly) FlutterPlatformViewsController* platformViewsController; + - (FlutterRestorationPlugin*)restorationPlugin; // Accepts keypress events, and then calls |nextAction| if the event was not diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewTest.mm index 08cf885da5..357c65e4c8 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewTest.mm @@ -13,13 +13,12 @@ FLUTTER_ASSERT_ARC @property(nonatomic, assign) BOOL isUsingImpeller; @end -@implementation FakeDelegate { - std::shared_ptr _platformViewsController; -} +@implementation FakeDelegate + +@synthesize platformViewsController = _platformViewsController; - (instancetype)init { _callbackCalled = NO; - _platformViewsController = std::shared_ptr(nullptr); return self; } @@ -28,10 +27,6 @@ FLUTTER_ASSERT_ARC return {}; } -- (std::shared_ptr&)platformViewsController { - return _platformViewsController; -} - - (void)flutterViewAccessibilityDidCall { _callbackCalled = YES; } diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTestMocks.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTestMocks.h index 4ccd57b1bb..562c471e93 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTestMocks.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTestMocks.h @@ -43,9 +43,7 @@ class MockAccessibilityBridge : public AccessibilityBridgeIos { } void AccessibilityObjectDidBecomeFocused(int32_t id) override {} void AccessibilityObjectDidLoseFocus(int32_t id) override {} - std::shared_ptr GetPlatformViewsController() const override { - return nil; - } + FlutterPlatformViewsController* GetPlatformViewsController() const override { return nil; } std::vector observations; bool isVoiceOverRunningValue; @@ -74,9 +72,7 @@ class MockAccessibilityBridgeNoWindow : public AccessibilityBridgeIos { } void AccessibilityObjectDidBecomeFocused(int32_t id) override {} void AccessibilityObjectDidLoseFocus(int32_t id) override {} - std::shared_ptr GetPlatformViewsController() const override { - return nil; - } + FlutterPlatformViewsController* GetPlatformViewsController() const override { return nil; } std::vector observations; bool isVoiceOverRunningValue; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h index ffbd8e49dd..e808b88d20 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h @@ -50,7 +50,7 @@ class AccessibilityBridge final : public AccessibilityBridgeIos { AccessibilityBridge(FlutterViewController* view_controller, PlatformViewIOS* platform_view, - std::shared_ptr platform_views_controller, + __weak FlutterPlatformViewsController* platform_views_controller, std::unique_ptr ios_delegate = nullptr); ~AccessibilityBridge(); @@ -72,7 +72,7 @@ class AccessibilityBridge final : public AccessibilityBridgeIos { fml::WeakPtr GetWeakPtr(); - std::shared_ptr GetPlatformViewsController() const override { + FlutterPlatformViewsController* GetPlatformViewsController() const override { return platform_views_controller_; }; @@ -91,7 +91,7 @@ class AccessibilityBridge final : public AccessibilityBridgeIos { FlutterViewController* view_controller_; PlatformViewIOS* platform_view_; - const std::shared_ptr platform_views_controller_; + __weak FlutterPlatformViewsController* platform_views_controller_; // If the this id is kSemanticObjectIdInvalid, it means either nothing has // been focused or the focus is currently outside of the flutter application // (i.e. the status bar or keyboard) diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm index 62467d3406..daf6389834 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm @@ -42,11 +42,11 @@ class DefaultIosDelegate : public AccessibilityBridge::IosDelegate { AccessibilityBridge::AccessibilityBridge( FlutterViewController* view_controller, PlatformViewIOS* platform_view, - std::shared_ptr platform_views_controller, + __weak FlutterPlatformViewsController* platform_views_controller, std::unique_ptr ios_delegate) : view_controller_(view_controller), platform_view_(platform_view), - platform_views_controller_(std::move(platform_views_controller)), + platform_views_controller_(platform_views_controller), last_focused_semantics_object_id_(kSemanticObjectIdInvalid), objects_([[NSMutableDictionary alloc] init]), previous_routes_({}), @@ -271,11 +271,13 @@ static SemanticsObject* CreateObject(const flutter::SemanticsNode& node, } else if (node.HasFlag(flutter::SemanticsFlags::kHasImplicitScrolling)) { return [[FlutterScrollableSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id]; } else if (node.IsPlatformViewNode()) { - return [[FlutterPlatformViewSemanticsContainer alloc] - initWithBridge:weak_ptr - uid:node.id - platformView:weak_ptr->GetPlatformViewsController()->GetFlutterTouchInterceptingViewByID( - node.platformViewId)]; + FlutterPlatformViewsController* platformViewsController = + weak_ptr->GetPlatformViewsController(); + FlutterTouchInterceptingView* touchInterceptingView = + [platformViewsController flutterTouchInterceptingViewForId:node.platformViewId]; + return [[FlutterPlatformViewSemanticsContainer alloc] initWithBridge:weak_ptr + uid:node.id + platformView:touchInterceptingView]; } else { return [[FlutterSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id]; } diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_ios.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_ios.h index 0da3646a2e..2168ca050d 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_ios.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_ios.h @@ -12,9 +12,9 @@ #include "flutter/lib/ui/semantics/semantics_node.h" @class UIView; +@class FlutterPlatformViewsController; namespace flutter { -class PlatformViewsController; /// Interface that represents an accessibility bridge for iOS. class AccessibilityBridgeIos { @@ -39,7 +39,7 @@ class AccessibilityBridgeIos { * The input id is the uid of the newly focused SemanticObject. */ virtual void AccessibilityObjectDidLoseFocus(int32_t id) = 0; - virtual std::shared_ptr GetPlatformViewsController() const = 0; + virtual FlutterPlatformViewsController* GetPlatformViewsController() const = 0; }; } // namespace flutter diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm index 63c2b14794..343ed99eae 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -279,8 +279,9 @@ fml::RefPtr CreateNewThread(const std::string& name) { /*ui=*/thread_task_runner, /*io=*/thread_task_runner); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(thread_task_runner); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = thread_task_runner; auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -294,19 +295,22 @@ fml::RefPtr CreateNewThread(const std::string& name) { id mockFlutterViewController = OCMClassMock([FlutterViewController class]); OCMStub([mockFlutterViewController view]).andReturn(mockFlutterView); std::string label = "some label"; - flutterPlatformViewsController->SetFlutterView(mockFlutterView); + flutterPlatformViewsController.flutterView = mockFlutterView; MockFlutterPlatformFactory* factory = [[MockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; auto bridge = std::make_unique( /*view_controller=*/mockFlutterViewController, @@ -322,7 +326,7 @@ fml::RefPtr CreateNewThread(const std::string& name) { flutter::CustomAccessibilityActionUpdates actions; bridge->UpdateSemantics(/*nodes=*/nodes, /*actions=*/actions); XCTAssertNotNil(gMockPlatformView); - flutterPlatformViewsController->Reset(); + [flutterPlatformViewsController reset]; } XCTAssertNil(gMockPlatformView); } @@ -340,8 +344,9 @@ fml::RefPtr CreateNewThread(const std::string& name) { /*ui=*/thread_task_runner, /*io=*/thread_task_runner); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(thread_task_runner); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = thread_task_runner; auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -353,16 +358,19 @@ fml::RefPtr CreateNewThread(const std::string& name) { /*is_gpu_disabled_sync_switch=*/std::make_shared()); MockFlutterPlatformFactory* factory = [[MockFlutterPlatformFactory alloc] init]; - flutterPlatformViewsController->RegisterViewFactory( - factory, @"MockFlutterPlatformView", - FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + [flutterPlatformViewsController + registerViewFactory:factory + withId:@"MockFlutterPlatformView" + gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager]; FlutterResult result = ^(id result) { }; - flutterPlatformViewsController->OnMethodCall( - [FlutterMethodCall - methodCallWithMethodName:@"create" - arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], - result); + [flutterPlatformViewsController + onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create" + arguments:@{ + @"id" : @2, + @"viewType" : @"MockFlutterPlatformView" + }] + result:result]; auto bridge = std::make_unique( /*view_controller=*/flutterViewController, @@ -370,7 +378,7 @@ fml::RefPtr CreateNewThread(const std::string& name) { /*platform_views_controller=*/flutterPlatformViewsController); XCTAssertNotNil(gMockPlatformView); - flutterPlatformViewsController->Reset(); + [flutterPlatformViewsController reset]; platform_view->NotifyDestroyed(); } XCTAssertNil(gMockPlatformView); @@ -387,8 +395,9 @@ fml::RefPtr CreateNewThread(const std::string& name) { /*ui=*/thread_task_runner, /*io=*/thread_task_runner); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(thread_task_runner); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = thread_task_runner; auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -484,8 +493,9 @@ fml::RefPtr CreateNewThread(const std::string& name) { /*ui=*/thread_task_runner, /*io=*/thread_task_runner); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(thread_task_runner); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = thread_task_runner; auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -559,8 +569,8 @@ fml::RefPtr CreateNewThread(const std::string& name) { /*ui=*/thread_task_runner, /*io=*/thread_task_runner); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(thread_task_runner); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; auto platform_view = std::make_unique( /*delegate=*/mock_delegate, /*rendering_api=*/mock_delegate.settings_.enable_impeller @@ -2175,11 +2185,12 @@ fml::RefPtr CreateNewThread(const std::string& name) { /*is_gpu_disabled_sync_switch=*/std::make_shared()); id mockFlutterViewController = OCMClassMock([FlutterViewController class]); - auto flutterPlatformViewsController = std::make_shared(); - flutterPlatformViewsController->SetTaskRunner(thread_task_runner); + FlutterPlatformViewsController* flutterPlatformViewsController = + [[FlutterPlatformViewsController alloc] init]; + flutterPlatformViewsController.taskRunner = thread_task_runner; OCMStub([mockFlutterViewController platformViewsController]) - .andReturn(flutterPlatformViewsController.get()); + .andReturn(flutterPlatformViewsController); platform_view->SetOwnerViewController(mockFlutterViewController); platform_view->SetSemanticsEnabled(true); diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.h deleted file mode 100644 index 06fd638244..0000000000 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.h +++ /dev/null @@ -1,318 +0,0 @@ -// 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_FRAMEWORK_SOURCE_PLATFORM_VIEWS_CONTROLLER_H_ -#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_PLATFORM_VIEWS_CONTROLLER_H_ - -#include -#include -#include - -#include "flutter/flow/surface.h" -#include "flutter/fml/memory/weak_ptr.h" -#include "flutter/fml/task_runner.h" -#include "flutter/fml/trace_event.h" -#include "impeller/base/thread_safety.h" -#include "third_party/skia/include/core/SkRect.h" - -#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h" -#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h" -#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h" -#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewResponder.h" -#import "flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h" -#import "flutter/shell/platform/darwin/ios/ios_context.h" - -@class FlutterTouchInterceptingView; -@class FlutterClippingMaskViewPool; - -namespace flutter { - -/// @brief Composites Flutter UI and overlay layers alongside embedded UIViews. -class PlatformViewsController { - public: - PlatformViewsController(); - - ~PlatformViewsController() = default; - - /// @brief Retrieve a weak pointer to this controller. - fml::WeakPtr GetWeakPtr(); - - /// @brief Set the platform task runner used to post rendering tasks. - void SetTaskRunner(const fml::RefPtr& platform_task_runner); - - /// @brief Set the flutter view. - void SetFlutterView(UIView* flutter_view) __attribute__((cf_audited_transfer)); - - /// @brief Set the flutter view controller. - void SetFlutterViewController(UIViewController* flutter_view_controller) - __attribute__((cf_audited_transfer)); - - /// @brief Retrieve the view controller. - UIViewController* GetFlutterViewController() - __attribute__((cf_audited_transfer)); - - /// @brief set the factory used to construct embedded UI Views. - void RegisterViewFactory( - NSObject* factory, - NSString* factoryId, - FlutterPlatformViewGestureRecognizersBlockingPolicy gestureRecognizerBlockingPolicy) - __attribute__((cf_audited_transfer)); - - /// @brief Mark the beginning of a frame and record the size of the onscreen. - void BeginFrame(SkISize frame_size); - - /// @brief Cancel the current frame, indicating that no platform views are composited. - /// - /// Additionally, reverts the composition order to its original state at the beginning of the - /// frame. - void CancelFrame(); - - /// @brief Record a platform view in the layer tree to be rendered, along with the positioning and - /// mutator parameters. - /// - /// Called from the raster thread. - void PrerollCompositeEmbeddedView(int64_t view_id, - std::unique_ptr params); - - /// @brief Returns the`FlutterTouchInterceptingView` with the provided view_id. - /// - /// Returns nil if there is no platform view with the provided id. Called - /// from the platform thread. - FlutterTouchInterceptingView* GetFlutterTouchInterceptingViewByID(int64_t view_id); - - /// @brief Determine if thread merging is required after prerolling platform views. - /// - /// Called from the raster thread. - PostPrerollResult PostPrerollAction( - const fml::RefPtr& raster_thread_merger, - bool impeller_enabled); - - /// @brief Mark the end of a compositor frame. - /// - /// May determine changes are required to the thread merging state. - /// Called from the raster thread. - void EndFrame(bool should_resubmit_frame, - const fml::RefPtr& raster_thread_merger, - bool impeller_enabled); - - /// @brief Returns the Canvas for the overlay slice for the given platform view. - /// - /// Called from the raster thread. - DlCanvas* CompositeEmbeddedView(int64_t view_id); - - /// @brief Discards all platform views instances and auxiliary resources. - /// - /// Called from the raster thread. - void Reset(); - - /// @brief Encode rendering for the Flutter overlay views and queue up perform platform view - /// mutations. - /// - /// Called from the raster thread. - bool SubmitFrame(GrDirectContext* gr_context, - const std::shared_ptr& ios_context, - std::unique_ptr frame); - - /// @brief Handler for platform view message channels. - void OnMethodCall(FlutterMethodCall* call, FlutterResult result) - __attribute__((cf_audited_transfer)); - - /// @brief Returns the platform view id if the platform view (or any of its descendant view) is - /// the first responder. - /// - /// Returns -1 if no such platform view is found. - long FindFirstResponderPlatformViewId(); - - /// @brief Pushes backdrop filter mutation to the mutator stack of each visited platform view. - void PushFilterToVisitedPlatformViews(const std::shared_ptr& filter, - const SkRect& filter_rect); - - /// @brief Pushes the view id of a visted platform view to the list of visied platform views. - void PushVisitedPlatformView(int64_t view_id) { visited_platform_views_.push_back(view_id); } - - // visible for testing. - size_t EmbeddedViewCount() const; - - // visible for testing. - size_t LayerPoolSize() const; - - // visible for testing. - // Returns the `FlutterPlatformView`'s `view` object associated with the view_id. - // - // If the `PlatformViewsController` does not contain any `FlutterPlatformView` object or - // a `FlutterPlatformView` object associated with the view_id cannot be found, the method - // returns nil. - UIView* GetPlatformViewByID(int64_t view_id); - - // Visible for testing. - void CompositeWithParams(int64_t view_id, const EmbeddedViewParams& params); - - // Visible for testing. - const EmbeddedViewParams& GetCompositionParams(int64_t view_id) const { - return current_composition_params_.find(view_id)->second; - } - - private: - PlatformViewsController(const PlatformViewsController&) = delete; - PlatformViewsController& operator=(const PlatformViewsController&) = delete; - - struct LayerData { - SkRect rect; - int64_t view_id; - int64_t overlay_id; - std::shared_ptr layer; - }; - - using LayersMap = std::unordered_map; - - // Update the buffers and mutate the platform views in CATransaction. - // - // Runs on the platform thread. - void PerformSubmit(const LayersMap& platform_view_layers, - std::unordered_map& current_composition_params, - const std::unordered_set& views_to_recomposite, - const std::vector& composition_order, - const std::vector>& unused_layers, - const std::vector>& surface_frames); - - /// @brief Populate any missing overlay layers. - /// - /// This requires posting a task to the platform thread and blocking on its completion. - void CreateMissingOverlays(GrDirectContext* gr_context, - const std::shared_ptr& ios_context, - size_t required_overlay_layers); - - void OnCreate(FlutterMethodCall* call, FlutterResult result) __attribute__((cf_audited_transfer)); - - void OnDispose(FlutterMethodCall* call, FlutterResult result) - __attribute__((cf_audited_transfer)); - - void OnAcceptGesture(FlutterMethodCall* call, FlutterResult result) - __attribute__((cf_audited_transfer)); - - void OnRejectGesture(FlutterMethodCall* call, FlutterResult result) - __attribute__((cf_audited_transfer)); - - /// @brief Return all views to be disposed on the platform thread. - std::vector GetViewsToDispose(); - - void ClipViewSetMaskView(UIView* clipView) __attribute__((cf_audited_transfer)); - - // Applies the mutators in the mutators_stack to the UIView chain that was constructed by - // `ReconstructClipViewsChain` - // - // Clips are applied to the `embedded_view`'s super view(|ChildClippingView|) using a - // |FlutterClippingMaskView|. Transforms are applied to `embedded_view` - // - // The `bounding_rect` is the final bounding rect of the PlatformView - // (EmbeddedViewParams::finalBoundingRect). If a clip mutator's rect contains the final bounding - // rect of the PlatformView, the clip mutator is not applied for performance optimization. - void ApplyMutators(const MutatorsStack& mutators_stack, - UIView* embedded_view, - const SkRect& bounding_rect) __attribute__((cf_audited_transfer)); - - std::shared_ptr GetExistingLayer(); - - // Runs on the platform thread. - void CreateLayer(GrDirectContext* gr_context, - const std::shared_ptr& ios_context, - MTLPixelFormat pixel_format); - - // Removes overlay views and platform views that aren't needed in the current frame. - // Must run on the platform thread. - void RemoveUnusedLayers(const std::vector>& unused_layers, - const std::vector& composition_order); - - // Appends the overlay views and platform view and sets their z index based on the composition - // order. - void BringLayersIntoView(const LayersMap& layer_map, - const std::vector& composition_order); - - // Resets the state of the frame. - void ResetFrameState(); - - // The pool of reusable view layers. The pool allows to recycle layer in each frame. - std::unique_ptr layer_pool_; - - // The platform view's |EmbedderViewSlice| keyed off the view id, which contains any subsequent - // operation until the next platform view or the end of the last leaf node in the layer tree. - // - // The Slices are deleted by the PlatformViewsController.reset(). - std::unordered_map> slices_; - - UIView* flutter_view_; - UIViewController* flutter_view_controller_; - FlutterClippingMaskViewPool* mask_view_pool_; - std::unordered_map*> factories_; - - // The FlutterPlatformViewGestureRecognizersBlockingPolicy for each type of platform view. - std::unordered_map - gesture_recognizers_blocking_policies_; - - /// The size of the current onscreen surface in physical pixels. - SkISize frame_size_; - - /// The task runner for posting tasks to the platform thread. - fml::RefPtr platform_task_runner_; - - /// Each of the following structs stores part of the platform view hierarchy according to its - /// ID. - /// - /// This data must only be accessed on the platform thread. - struct PlatformViewData { - NSObject* view; - FlutterTouchInterceptingView* touch_interceptor; - UIView* root_view; - }; - - /// This data must only be accessed on the platform thread. - std::unordered_map platform_views_; - - /// The composition parameters for each platform view. - /// - /// This state is only modified on the raster thread. - std::unordered_map current_composition_params_; - - /// Method channel `OnDispose` calls adds the views to be disposed to this set to be disposed on - /// the next frame. - /// - /// This state is modified on both the platform and raster thread. - std::unordered_set views_to_dispose_; - - /// view IDs in composition order. - /// - /// This state is only modified on the raster thread. - std::vector composition_order_; - - /// platform view IDs visited during layer tree composition. - /// - /// This state is only modified on the raster thread. - std::vector visited_platform_views_; - - /// Only composite platform views in this set. - /// - /// This state is only modified on the raster thread. - std::unordered_set views_to_recomposite_; - - /// @brief The composition order from the previous thread. - /// - /// Only accessed from the platform thread. - std::vector previous_composition_order_; - - /// Whether the previous frame had any platform views in active composition order. - /// - /// This state is tracked so that the first frame after removing the last platform view - /// runs through the platform view rendering code path, giving us a chance to remove the - /// platform view from the UIView hierarchy. - /// - /// Only accessed from the raster thread. - bool had_platform_views_ = false; - - // WeakPtrFactory must be the last member. - std::unique_ptr> weak_factory_; -}; - -} // namespace flutter - -#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_PLATFORM_VIEWS_CONTROLLER_H_ diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.mm deleted file mode 100644 index 6893c3d0f8..0000000000 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.mm +++ /dev/null @@ -1,874 +0,0 @@ -// 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 "shell/platform/darwin/ios/framework/Source/platform_views_controller.h" - -#include "flutter/display_list/effects/image_filters/dl_blur_image_filter.h" -#include "flutter/flow/surface_frame.h" -#include "flutter/flow/view_slicer.h" -#include "flutter/fml/make_copyable.h" -#include "flutter/fml/synchronization/count_down_latch.h" - -#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h" -#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h" -#import "flutter/shell/platform/darwin/ios/ios_surface.h" - -namespace { - -// The number of frames the rasterizer task runner will continue -// to run on the platform thread after no platform view is rendered. -// -// Note: this is an arbitrary number. -static const int kDefaultMergedLeaseDuration = 10; - -static constexpr NSUInteger kFlutterClippingMaskViewPoolCapacity = 5; - -// Converts a SkMatrix to CATransform3D. -// -// Certain fields are ignored in CATransform3D since SkMatrix is 3x3 and CATransform3D is 4x4. -CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix) { - // Skia only supports 2D transform so we don't map z. - CATransform3D transform = CATransform3DIdentity; - transform.m11 = matrix.getScaleX(); - transform.m21 = matrix.getSkewX(); - transform.m41 = matrix.getTranslateX(); - transform.m14 = matrix.getPerspX(); - - transform.m12 = matrix.getSkewY(); - transform.m22 = matrix.getScaleY(); - transform.m42 = matrix.getTranslateY(); - transform.m24 = matrix.getPerspY(); - return transform; -} - -// Reset the anchor of `layer` to match the transform operation from flow. -// -// The position of the `layer` should be unchanged after resetting the anchor. -void ResetAnchor(CALayer* layer) { - // Flow uses (0, 0) to apply transform matrix so we need to match that in Quartz. - layer.anchorPoint = CGPointZero; - layer.position = CGPointZero; -} - -CGRect GetCGRectFromSkRect(const SkRect& clipSkRect) { - return CGRectMake(clipSkRect.fLeft, clipSkRect.fTop, clipSkRect.fRight - clipSkRect.fLeft, - clipSkRect.fBottom - clipSkRect.fTop); -} - -// Determines if the `clip_rect` from a clipRect mutator contains the -// `platformview_boundingrect`. -// -// `clip_rect` is in its own coordinate space. The rect needs to be transformed by -// `transform_matrix` to be in the coordinate space where the PlatformView is displayed. -// -// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate -// space where the PlatformView is displayed. -bool ClipRectContainsPlatformViewBoundingRect(const SkRect& clip_rect, - const SkRect& platformview_boundingrect, - const SkMatrix& transform_matrix) { - SkRect transformed_rect = transform_matrix.mapRect(clip_rect); - return transformed_rect.contains(platformview_boundingrect); -} - -// Determines if the `clipRRect` from a clipRRect mutator contains the -// `platformview_boundingrect`. -// -// `clip_rrect` is in its own coordinate space. The rrect needs to be transformed by -// `transform_matrix` to be in the coordinate space where the PlatformView is displayed. -// -// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate -// space where the PlatformView is displayed. -bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, - const SkRect& platformview_boundingrect, - const SkMatrix& transform_matrix) { - SkVector upper_left = clip_rrect.radii(SkRRect::Corner::kUpperLeft_Corner); - SkVector upper_right = clip_rrect.radii(SkRRect::Corner::kUpperRight_Corner); - SkVector lower_right = clip_rrect.radii(SkRRect::Corner::kLowerRight_Corner); - SkVector lower_left = clip_rrect.radii(SkRRect::Corner::kLowerLeft_Corner); - SkScalar transformed_upper_left_x = transform_matrix.mapRadius(upper_left.x()); - SkScalar transformed_upper_left_y = transform_matrix.mapRadius(upper_left.y()); - SkScalar transformed_upper_right_x = transform_matrix.mapRadius(upper_right.x()); - SkScalar transformed_upper_right_y = transform_matrix.mapRadius(upper_right.y()); - SkScalar transformed_lower_right_x = transform_matrix.mapRadius(lower_right.x()); - SkScalar transformed_lower_right_y = transform_matrix.mapRadius(lower_right.y()); - SkScalar transformed_lower_left_x = transform_matrix.mapRadius(lower_left.x()); - SkScalar transformed_lower_left_y = transform_matrix.mapRadius(lower_left.y()); - SkRect transformed_clip_rect = transform_matrix.mapRect(clip_rrect.rect()); - SkRRect transformed_rrect; - SkVector corners[] = {{transformed_upper_left_x, transformed_upper_left_y}, - {transformed_upper_right_x, transformed_upper_right_y}, - {transformed_lower_right_x, transformed_lower_right_y}, - {transformed_lower_left_x, transformed_lower_left_y}}; - transformed_rrect.setRectRadii(transformed_clip_rect, corners); - return transformed_rrect.contains(platformview_boundingrect); -} - -} // namespace - -namespace flutter { - -// Becomes NO if Apple's API changes and blurred backdrop filters cannot be applied. -BOOL canApplyBlurBackdrop = YES; - -PlatformViewsController::PlatformViewsController() - : layer_pool_(std::make_unique()), - weak_factory_(std::make_unique>(this)) { - mask_view_pool_ = - [[FlutterClippingMaskViewPool alloc] initWithCapacity:kFlutterClippingMaskViewPoolCapacity]; -}; - -void PlatformViewsController::SetTaskRunner( - const fml::RefPtr& platform_task_runner) { - platform_task_runner_ = platform_task_runner; -} - -fml::WeakPtr PlatformViewsController::GetWeakPtr() { - return weak_factory_->GetWeakPtr(); -} - -void PlatformViewsController::SetFlutterView(UIView* flutter_view) { - flutter_view_ = flutter_view; -} - -void PlatformViewsController::SetFlutterViewController( - UIViewController* flutter_view_controller) { - flutter_view_controller_ = flutter_view_controller; -} - -UIViewController* PlatformViewsController::GetFlutterViewController() { - return flutter_view_controller_; -} - -void PlatformViewsController::OnMethodCall(FlutterMethodCall* call, FlutterResult result) { - if ([[call method] isEqualToString:@"create"]) { - OnCreate(call, result); - } else if ([[call method] isEqualToString:@"dispose"]) { - OnDispose(call, result); - } else if ([[call method] isEqualToString:@"acceptGesture"]) { - OnAcceptGesture(call, result); - } else if ([[call method] isEqualToString:@"rejectGesture"]) { - OnRejectGesture(call, result); - } else { - result(FlutterMethodNotImplemented); - } -} - -void PlatformViewsController::OnCreate(FlutterMethodCall* call, FlutterResult result) { - NSDictionary* args = [call arguments]; - - int64_t viewId = [args[@"id"] longLongValue]; - NSString* viewTypeString = args[@"viewType"]; - std::string viewType(viewTypeString.UTF8String); - - if (platform_views_.count(viewId) != 0) { - result([FlutterError errorWithCode:@"recreating_view" - message:@"trying to create an already created view" - details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); - return; - } - - NSObject* factory = factories_[viewType]; - if (factory == nil) { - result([FlutterError - errorWithCode:@"unregistered_view_type" - message:[NSString stringWithFormat:@"A UIKitView widget is trying to create a " - @"PlatformView with an unregistered type: < %@ >", - viewTypeString] - details:@"If you are the author of the PlatformView, make sure `registerViewFactory` " - @"is invoked.\n" - @"See: " - @"https://docs.flutter.dev/development/platform-integration/" - @"platform-views#on-the-platform-side-1 for more details.\n" - @"If you are not the author of the PlatformView, make sure to call " - @"`GeneratedPluginRegistrant.register`."]); - return; - } - - id params = nil; - if ([factory respondsToSelector:@selector(createArgsCodec)]) { - NSObject* codec = [factory createArgsCodec]; - if (codec != nil && args[@"params"] != nil) { - FlutterStandardTypedData* paramsData = args[@"params"]; - params = [codec decode:paramsData.data]; - } - } - - NSObject* embedded_view = [factory createWithFrame:CGRectZero - viewIdentifier:viewId - arguments:params]; - UIView* platform_view = [embedded_view view]; - // Set a unique view identifier, so the platform view can be identified in unit tests. - platform_view.accessibilityIdentifier = - [NSString stringWithFormat:@"platform_view[%lld]", viewId]; - - FlutterTouchInterceptingView* touch_interceptor = [[FlutterTouchInterceptingView alloc] - initWithEmbeddedView:platform_view - platformViewsController:GetWeakPtr() - gestureRecognizersBlockingPolicy:gesture_recognizers_blocking_policies_[viewType]]; - - ChildClippingView* clipping_view = [[ChildClippingView alloc] initWithFrame:CGRectZero]; - [clipping_view addSubview:touch_interceptor]; - - platform_views_.emplace(viewId, PlatformViewData{ - .view = embedded_view, // - .touch_interceptor = touch_interceptor, // - .root_view = clipping_view // - }); - - result(nil); -} - -void PlatformViewsController::OnDispose(FlutterMethodCall* call, FlutterResult result) { - NSNumber* arg = [call arguments]; - int64_t viewId = [arg longLongValue]; - - if (platform_views_.count(viewId) == 0) { - result([FlutterError errorWithCode:@"unknown_view" - message:@"trying to dispose an unknown" - details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); - return; - } - // We wait for next submitFrame to dispose views. - views_to_dispose_.insert(viewId); - result(nil); -} - -void PlatformViewsController::OnAcceptGesture(FlutterMethodCall* call, FlutterResult result) { - NSDictionary* args = [call arguments]; - int64_t viewId = [args[@"id"] longLongValue]; - - if (platform_views_.count(viewId) == 0) { - result([FlutterError errorWithCode:@"unknown_view" - message:@"trying to set gesture state for an unknown view" - details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); - return; - } - - FlutterTouchInterceptingView* view = platform_views_[viewId].touch_interceptor; - [view releaseGesture]; - - result(nil); -} - -void PlatformViewsController::OnRejectGesture(FlutterMethodCall* call, FlutterResult result) { - NSDictionary* args = [call arguments]; - int64_t viewId = [args[@"id"] longLongValue]; - - if (platform_views_.count(viewId) == 0) { - result([FlutterError errorWithCode:@"unknown_view" - message:@"trying to set gesture state for an unknown view" - details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); - return; - } - - FlutterTouchInterceptingView* view = platform_views_[viewId].touch_interceptor; - [view blockGesture]; - - result(nil); -} - -void PlatformViewsController::RegisterViewFactory( - NSObject* factory, - NSString* factoryId, - FlutterPlatformViewGestureRecognizersBlockingPolicy gestureRecognizerBlockingPolicy) { - std::string idString([factoryId UTF8String]); - FML_CHECK(factories_.count(idString) == 0); - factories_[idString] = factory; - gesture_recognizers_blocking_policies_[idString] = gestureRecognizerBlockingPolicy; -} - -void PlatformViewsController::BeginFrame(SkISize frame_size) { - ResetFrameState(); - frame_size_ = frame_size; -} - -void PlatformViewsController::CancelFrame() { - ResetFrameState(); -} - -PostPrerollResult PlatformViewsController::PostPrerollAction( - const fml::RefPtr& raster_thread_merger, - bool impeller_enabled) { - // TODO(jonahwilliams): remove this once Software backend is removed for iOS Sim. -#ifdef FML_OS_IOS_SIMULATOR - const bool merge_threads = true; -#else - const bool merge_threads = !impeller_enabled; -#endif // FML_OS_IOS_SIMULATOR - - if (merge_threads) { - if (composition_order_.empty()) { - return PostPrerollResult::kSuccess; - } - if (!raster_thread_merger->IsMerged()) { - // The raster thread merger may be disabled if the rasterizer is being - // created or teared down. - // - // In such cases, the current frame is dropped, and a new frame is attempted - // with the same layer tree. - // - // Eventually, the frame is submitted once this method returns `kSuccess`. - // At that point, the raster tasks are handled on the platform thread. - CancelFrame(); - return PostPrerollResult::kSkipAndRetryFrame; - } - // If the post preroll action is successful, we will display platform views in the current - // frame. In order to sync the rendering of the platform views (quartz) with skia's rendering, - // We need to begin an explicit CATransaction. This transaction needs to be submitted - // after the current frame is submitted. - raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration); - } - return PostPrerollResult::kSuccess; -} - -void PlatformViewsController::EndFrame( - bool should_resubmit_frame, - const fml::RefPtr& raster_thread_merger, - bool impeller_enabled) { -#if FML_OS_IOS_SIMULATOR - bool run_check = true; -#else - bool run_check = !impeller_enabled; -#endif // FML_OS_IOS_SIMULATOR - if (run_check && should_resubmit_frame) { - raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration); - } -} - -void PlatformViewsController::PushFilterToVisitedPlatformViews( - const std::shared_ptr& filter, - const SkRect& filter_rect) { - for (int64_t id : visited_platform_views_) { - EmbeddedViewParams params = current_composition_params_[id]; - params.PushImageFilter(filter, filter_rect); - current_composition_params_[id] = params; - } -} - -void PlatformViewsController::PrerollCompositeEmbeddedView( - int64_t view_id, - std::unique_ptr params) { - SkRect view_bounds = SkRect::Make(frame_size_); - std::unique_ptr view; - view = std::make_unique(view_bounds); - slices_.insert_or_assign(view_id, std::move(view)); - - composition_order_.push_back(view_id); - - if (current_composition_params_.count(view_id) == 1 && - current_composition_params_[view_id] == *params.get()) { - // Do nothing if the params didn't change. - return; - } - current_composition_params_[view_id] = EmbeddedViewParams(*params.get()); - views_to_recomposite_.insert(view_id); -} - -size_t PlatformViewsController::EmbeddedViewCount() const { - return composition_order_.size(); -} - -size_t PlatformViewsController::LayerPoolSize() const { - return layer_pool_->size(); -} - -UIView* PlatformViewsController::GetPlatformViewByID(int64_t view_id) { - return [GetFlutterTouchInterceptingViewByID(view_id) embeddedView]; -} - -FlutterTouchInterceptingView* PlatformViewsController::GetFlutterTouchInterceptingViewByID( - int64_t view_id) { - if (platform_views_.empty()) { - return nil; - } - return platform_views_[view_id].touch_interceptor; -} - -long PlatformViewsController::FindFirstResponderPlatformViewId() { - for (auto const& [id, platform_view_data] : platform_views_) { - UIView* root_view = platform_view_data.root_view; - if (root_view.flt_hasFirstResponderInViewHierarchySubtree) { - return id; - } - } - return -1; -} - -void PlatformViewsController::ClipViewSetMaskView(UIView* clipView) { - FML_DCHECK([[NSThread currentThread] isMainThread]); - if (clipView.maskView) { - return; - } - CGRect frame = - CGRectMake(-clipView.frame.origin.x, -clipView.frame.origin.y, - CGRectGetWidth(flutter_view_.bounds), CGRectGetHeight(flutter_view_.bounds)); - clipView.maskView = [mask_view_pool_ getMaskViewWithFrame:frame]; -} - -// This method is only called when the `embedded_view` needs to be re-composited at the current -// frame. See: `CompositeWithParams` for details. -void PlatformViewsController::ApplyMutators(const MutatorsStack& mutators_stack, - UIView* embedded_view, - const SkRect& bounding_rect) { - if (flutter_view_ == nullptr) { - return; - } - - ResetAnchor(embedded_view.layer); - ChildClippingView* clipView = (ChildClippingView*)embedded_view.superview; - - SkMatrix transformMatrix; - NSMutableArray* blurFilters = [[NSMutableArray alloc] init]; - FML_DCHECK(!clipView.maskView || - [clipView.maskView isKindOfClass:[FlutterClippingMaskView class]]); - if (clipView.maskView) { - [mask_view_pool_ insertViewToPoolIfNeeded:(FlutterClippingMaskView*)(clipView.maskView)]; - clipView.maskView = nil; - } - CGFloat screenScale = [UIScreen mainScreen].scale; - auto iter = mutators_stack.Begin(); - while (iter != mutators_stack.End()) { - switch ((*iter)->GetType()) { - case kTransform: { - transformMatrix.preConcat((*iter)->GetMatrix()); - break; - } - case kClipRect: { - if (ClipRectContainsPlatformViewBoundingRect((*iter)->GetRect(), bounding_rect, - transformMatrix)) { - break; - } - ClipViewSetMaskView(clipView); - [(FlutterClippingMaskView*)clipView.maskView clipRect:(*iter)->GetRect() - matrix:transformMatrix]; - break; - } - case kClipRRect: { - if (ClipRRectContainsPlatformViewBoundingRect((*iter)->GetRRect(), bounding_rect, - transformMatrix)) { - break; - } - ClipViewSetMaskView(clipView); - [(FlutterClippingMaskView*)clipView.maskView clipRRect:(*iter)->GetRRect() - matrix:transformMatrix]; - break; - } - case kClipPath: { - // TODO(cyanglaz): Find a way to pre-determine if path contains the PlatformView boudning - // rect. See `ClipRRectContainsPlatformViewBoundingRect`. - // https://github.com/flutter/flutter/issues/118650 - ClipViewSetMaskView(clipView); - [(FlutterClippingMaskView*)clipView.maskView clipPath:(*iter)->GetPath() - matrix:transformMatrix]; - break; - } - case kOpacity: - embedded_view.alpha = (*iter)->GetAlphaFloat() * embedded_view.alpha; - break; - case kBackdropFilter: { - // Only support DlBlurImageFilter for BackdropFilter. - if (!canApplyBlurBackdrop || !(*iter)->GetFilterMutation().GetFilter().asBlur()) { - break; - } - CGRect filterRect = GetCGRectFromSkRect((*iter)->GetFilterMutation().GetFilterRect()); - // `filterRect` is in global coordinates. We need to convert to local space. - filterRect = CGRectApplyAffineTransform( - filterRect, CGAffineTransformMakeScale(1 / screenScale, 1 / screenScale)); - // `filterRect` reprents the rect that should be filtered inside the `flutter_view_`. - // The `PlatformViewFilter` needs the frame inside the `clipView` that needs to be - // filtered. - if (CGRectIsNull(CGRectIntersection(filterRect, clipView.frame))) { - break; - } - CGRect intersection = CGRectIntersection(filterRect, clipView.frame); - CGRect frameInClipView = [flutter_view_ convertRect:intersection toView:clipView]; - // sigma_x is arbitrarily chosen as the radius value because Quartz sets - // sigma_x and sigma_y equal to each other. DlBlurImageFilter's Tile Mode - // is not supported in Quartz's gaussianBlur CAFilter, so it is not used - // to blur the PlatformView. - CGFloat blurRadius = (*iter)->GetFilterMutation().GetFilter().asBlur()->sigma_x(); - UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc] - initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]]; - PlatformViewFilter* filter = [[PlatformViewFilter alloc] initWithFrame:frameInClipView - blurRadius:blurRadius - visualEffectView:visualEffectView]; - if (!filter) { - canApplyBlurBackdrop = NO; - } else { - [blurFilters addObject:filter]; - } - break; - } - } - ++iter; - } - - if (canApplyBlurBackdrop) { - [clipView applyBlurBackdropFilters:blurFilters]; - } - - // The UIKit frame is set based on the logical resolution (points) instead of physical. - // (https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html). - // However, flow is based on the physical resolution. For example, 1000 pixels in flow equals - // 500 points in UIKit for devices that has screenScale of 2. We need to scale the transformMatrix - // down to the logical resoltion before applying it to the layer of PlatformView. - transformMatrix.postScale(1 / screenScale, 1 / screenScale); - - // Reverse the offset of the clipView. - // The clipView's frame includes the final translate of the final transform matrix. - // Thus, this translate needs to be reversed so the platform view can layout at the correct - // offset. - // - // Note that the transforms are not applied to the clipping paths because clipping paths happen on - // the mask view, whose origin is always (0,0) to the flutter_view. - transformMatrix.postTranslate(-clipView.frame.origin.x, -clipView.frame.origin.y); - - embedded_view.layer.transform = GetCATransform3DFromSkMatrix(transformMatrix); -} - -// Composite the PlatformView with `view_id`. -// -// Every frame, during the paint traversal of the layer tree, this method is called for all -// the PlatformViews in `views_to_recomposite_`. -// -// Note that `views_to_recomposite_` does not represent all the views in the view hierarchy, -// if a PlatformView does not change its composition parameter from last frame, it is not -// included in the `views_to_recomposite_`. -void PlatformViewsController::CompositeWithParams(int64_t view_id, - const EmbeddedViewParams& params) { - /// TODO(https://github.com/flutter/flutter/issues/109700) - CGRect frame = CGRectMake(0, 0, params.sizePoints().width(), params.sizePoints().height()); - FlutterTouchInterceptingView* touchInterceptor = platform_views_[view_id].touch_interceptor; - touchInterceptor.layer.transform = CATransform3DIdentity; - touchInterceptor.frame = frame; - touchInterceptor.alpha = 1; - - const MutatorsStack& mutatorStack = params.mutatorsStack(); - UIView* clippingView = platform_views_[view_id].root_view; - // The frame of the clipping view should be the final bounding rect. - // Because the translate matrix in the Mutator Stack also includes the offset, - // when we apply the transforms matrix in |ApplyMutators|, we need - // to remember to do a reverse translate. - const SkRect& rect = params.finalBoundingRect(); - CGFloat screenScale = [UIScreen mainScreen].scale; - clippingView.frame = CGRectMake(rect.x() / screenScale, rect.y() / screenScale, - rect.width() / screenScale, rect.height() / screenScale); - ApplyMutators(mutatorStack, touchInterceptor, rect); -} - -DlCanvas* PlatformViewsController::CompositeEmbeddedView(int64_t view_id) { - return slices_[view_id]->canvas(); -} - -void PlatformViewsController::Reset() { - // Reset will only be called from the raster thread or a merged raster/platform thread. - // platform_views_ must only be modified on the platform thread, and any operations that - // read or modify platform views should occur there. - fml::TaskRunner::RunNowOrPostTask(platform_task_runner_, - [&, composition_order = composition_order_]() { - for (int64_t view_id : composition_order_) { - [platform_views_[view_id].root_view removeFromSuperview]; - } - platform_views_.clear(); - }); - - composition_order_.clear(); - slices_.clear(); - current_composition_params_.clear(); - views_to_recomposite_.clear(); - layer_pool_->RecycleLayers(); - visited_platform_views_.clear(); -} - -bool PlatformViewsController::SubmitFrame(GrDirectContext* gr_context, - const std::shared_ptr& ios_context, - std::unique_ptr background_frame) { - TRACE_EVENT0("flutter", "PlatformViewsController::SubmitFrame"); - - // No platform views to render; we're done. - if (flutter_view_ == nullptr || (composition_order_.empty() && !had_platform_views_)) { - had_platform_views_ = false; - return background_frame->Submit(); - } - had_platform_views_ = !composition_order_.empty(); - - bool did_encode = true; - LayersMap platform_view_layers; - std::vector> surface_frames; - surface_frames.reserve(composition_order_.size()); - std::unordered_map view_rects; - - for (int64_t view_id : composition_order_) { - view_rects[view_id] = current_composition_params_[view_id].finalBoundingRect(); - } - - std::unordered_map overlay_layers = - SliceViews(background_frame->Canvas(), composition_order_, slices_, view_rects); - - size_t required_overlay_layers = 0; - for (int64_t view_id : composition_order_) { - std::unordered_map::const_iterator overlay = overlay_layers.find(view_id); - if (overlay == overlay_layers.end()) { - continue; - } - required_overlay_layers++; - } - - // If there are not sufficient overlay layers, we must construct them on the platform - // thread, at least until we've refactored iOS surface creation to use IOSurfaces - // instead of CALayers. - CreateMissingOverlays(gr_context, ios_context, required_overlay_layers); - - int64_t overlay_id = 0; - for (int64_t view_id : composition_order_) { - std::unordered_map::const_iterator overlay = overlay_layers.find(view_id); - if (overlay == overlay_layers.end()) { - continue; - } - std::shared_ptr layer = GetExistingLayer(); - if (!layer) { - continue; - } - - std::unique_ptr frame = layer->surface->AcquireFrame(frame_size_); - // If frame is null, AcquireFrame already printed out an error message. - if (!frame) { - continue; - } - DlCanvas* overlay_canvas = frame->Canvas(); - int restore_count = overlay_canvas->GetSaveCount(); - overlay_canvas->Save(); - overlay_canvas->ClipRect(overlay->second); - overlay_canvas->Clear(DlColor::kTransparent()); - slices_[view_id]->render_into(overlay_canvas); - overlay_canvas->RestoreToCount(restore_count); - - // This flutter view is never the last in a frame, since we always submit the - // underlay view last. - frame->set_submit_info({.frame_boundary = false, .present_with_transaction = true}); - layer->did_submit_last_frame = frame->Encode(); - - did_encode &= layer->did_submit_last_frame; - platform_view_layers[view_id] = LayerData{ - .rect = overlay->second, // - .view_id = view_id, // - .overlay_id = overlay_id, // - .layer = layer // - }; - surface_frames.push_back(std::move(frame)); - overlay_id++; - } - - auto previous_submit_info = background_frame->submit_info(); - background_frame->set_submit_info({ - .frame_damage = previous_submit_info.frame_damage, - .buffer_damage = previous_submit_info.buffer_damage, - .present_with_transaction = true, - }); - background_frame->Encode(); - surface_frames.push_back(std::move(background_frame)); - - // Mark all layers as available, so they can be used in the next frame. - std::vector> unused_layers = layer_pool_->RemoveUnusedLayers(); - layer_pool_->RecycleLayers(); - - auto task = [&, // - platform_view_layers = std::move(platform_view_layers), // - current_composition_params = current_composition_params_, // - views_to_recomposite = views_to_recomposite_, // - composition_order = composition_order_, // - unused_layers = std::move(unused_layers), // - surface_frames = std::move(surface_frames) // - ]() mutable { - PerformSubmit(platform_view_layers, // - current_composition_params, // - views_to_recomposite, // - composition_order, // - unused_layers, // - surface_frames // - ); - }; - - fml::TaskRunner::RunNowOrPostTask(platform_task_runner_, fml::MakeCopyable(std::move(task))); - - return did_encode; -} - -void PlatformViewsController::CreateMissingOverlays(GrDirectContext* gr_context, - const std::shared_ptr& ios_context, - size_t required_overlay_layers) { - TRACE_EVENT0("flutter", "PlatformViewsController::CreateMissingLayers"); - - if (required_overlay_layers <= layer_pool_->size()) { - return; - } - auto missing_layer_count = required_overlay_layers - layer_pool_->size(); - - // If the raster thread isn't merged, create layers on the platform thread and block until - // complete. - auto latch = std::make_shared(1u); - fml::TaskRunner::RunNowOrPostTask(platform_task_runner_, [&]() { - for (auto i = 0u; i < missing_layer_count; i++) { - CreateLayer(gr_context, // - ios_context, // - ((FlutterView*)flutter_view_).pixelFormat // - ); - } - latch->CountDown(); - }); - if (![[NSThread currentThread] isMainThread]) { - latch->Wait(); - } -} - -/// Update the buffers and mutate the platform views in CATransaction on the platform thread. -void PlatformViewsController::PerformSubmit( - const LayersMap& platform_view_layers, - std::unordered_map& current_composition_params, - const std::unordered_set& views_to_recomposite, - const std::vector& composition_order, - const std::vector>& unused_layers, - const std::vector>& surface_frames) { - TRACE_EVENT0("flutter", "PlatformViewsController::PerformSubmit"); - FML_DCHECK([[NSThread currentThread] isMainThread]); - - [CATransaction begin]; - - // Configure Flutter overlay views. - for (const auto& [view_id, layer_data] : platform_view_layers) { - layer_data.layer->UpdateViewState(flutter_view_, // - layer_data.rect, // - layer_data.view_id, // - layer_data.overlay_id // - ); - } - - // Dispose unused Flutter Views. - for (auto& view : GetViewsToDispose()) { - [view removeFromSuperview]; - } - - // Composite Platform Views. - for (int64_t view_id : views_to_recomposite) { - CompositeWithParams(view_id, current_composition_params[view_id]); - } - - // Present callbacks. - for (const auto& frame : surface_frames) { - frame->Submit(); - } - - // If a layer was allocated in the previous frame, but it's not used in the current frame, - // then it can be removed from the scene. - RemoveUnusedLayers(unused_layers, composition_order); - - // Organize the layers by their z indexes. - BringLayersIntoView(platform_view_layers, composition_order); - - [CATransaction commit]; -} - -void PlatformViewsController::BringLayersIntoView(const LayersMap& layer_map, - const std::vector& composition_order) { - FML_DCHECK(flutter_view_); - UIView* flutter_view = flutter_view_; - - previous_composition_order_.clear(); - NSMutableArray* desired_platform_subviews = [NSMutableArray array]; - for (int64_t platform_view_id : composition_order) { - previous_composition_order_.push_back(platform_view_id); - UIView* platform_view_root = platform_views_[platform_view_id].root_view; - if (platform_view_root != nil) { - [desired_platform_subviews addObject:platform_view_root]; - } - - auto maybe_layer_data = layer_map.find(platform_view_id); - if (maybe_layer_data != layer_map.end()) { - auto view = maybe_layer_data->second.layer->overlay_view_wrapper; - if (view != nil) { - [desired_platform_subviews addObject:view]; - } - } - } - - NSSet* desired_platform_subviews_set = [NSSet setWithArray:desired_platform_subviews]; - NSArray* existing_platform_subviews = [flutter_view.subviews - filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, - NSDictionary* bindings) { - return [desired_platform_subviews_set containsObject:object]; - }]]; - - // Manipulate view hierarchy only if needed, to address a performance issue where - // `BringLayersIntoView` is called even when view hierarchy stays the same. - // See: https://github.com/flutter/flutter/issues/121833 - // TODO(hellohuanlin): investigate if it is possible to skip unnecessary BringLayersIntoView. - if (![desired_platform_subviews isEqualToArray:existing_platform_subviews]) { - for (UIView* subview in desired_platform_subviews) { - // `addSubview` will automatically reorder subview if it is already added. - [flutter_view addSubview:subview]; - } - } -} - -std::shared_ptr PlatformViewsController::GetExistingLayer() { - return layer_pool_->GetNextLayer(); -} - -void PlatformViewsController::CreateLayer(GrDirectContext* gr_context, - const std::shared_ptr& ios_context, - MTLPixelFormat pixel_format) { - layer_pool_->CreateLayer(gr_context, ios_context, pixel_format); -} - -void PlatformViewsController::RemoveUnusedLayers( - const std::vector>& unused_layers, - const std::vector& composition_order) { - for (const std::shared_ptr& layer : unused_layers) { - [layer->overlay_view_wrapper removeFromSuperview]; - } - - std::unordered_set composition_order_set; - for (int64_t view_id : composition_order) { - composition_order_set.insert(view_id); - } - // Remove unused platform views. - for (int64_t view_id : previous_composition_order_) { - if (composition_order_set.find(view_id) == composition_order_set.end()) { - UIView* platform_view_root = platform_views_[view_id].root_view; - [platform_view_root removeFromSuperview]; - } - } -} - -std::vector PlatformViewsController::GetViewsToDispose() { - std::vector views; - if (views_to_dispose_.empty()) { - return views; - } - - std::unordered_set views_to_composite(composition_order_.begin(), - composition_order_.end()); - std::unordered_set views_to_delay_dispose; - for (int64_t viewId : views_to_dispose_) { - if (views_to_composite.count(viewId)) { - views_to_delay_dispose.insert(viewId); - continue; - } - UIView* root_view = platform_views_[viewId].root_view; - views.push_back(root_view); - current_composition_params_.erase(viewId); - views_to_recomposite_.erase(viewId); - platform_views_.erase(viewId); - } - views_to_dispose_ = std::move(views_to_delay_dispose); - return views; -} - -void PlatformViewsController::ResetFrameState() { - slices_.clear(); - composition_order_.clear(); - visited_platform_views_.clear(); -} - -} // namespace flutter diff --git a/engine/src/flutter/shell/platform/darwin/ios/ios_external_view_embedder.h b/engine/src/flutter/shell/platform/darwin/ios/ios_external_view_embedder.h index 6983ac83f0..d22fc3fb47 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/ios_external_view_embedder.h +++ b/engine/src/flutter/shell/platform/darwin/ios/ios_external_view_embedder.h @@ -13,14 +13,14 @@ namespace flutter { class IOSExternalViewEmbedder : public ExternalViewEmbedder { public: IOSExternalViewEmbedder( - const std::shared_ptr& platform_views_controller, + __weak FlutterPlatformViewsController* platform_views_controller, const std::shared_ptr& context); // |ExternalViewEmbedder| virtual ~IOSExternalViewEmbedder() override; private: - const std::shared_ptr& platform_views_controller_; + __weak FlutterPlatformViewsController* platform_views_controller_; std::shared_ptr ios_context_; // |ExternalViewEmbedder| diff --git a/engine/src/flutter/shell/platform/darwin/ios/ios_external_view_embedder.mm b/engine/src/flutter/shell/platform/darwin/ios/ios_external_view_embedder.mm index a2f5ff9c2b..ebde36386b 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/ios_external_view_embedder.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/ios_external_view_embedder.mm @@ -12,7 +12,7 @@ FLUTTER_ASSERT_ARC namespace flutter { IOSExternalViewEmbedder::IOSExternalViewEmbedder( - const std::shared_ptr& platform_views_controller, + __weak FlutterPlatformViewsController* platform_views_controller, const std::shared_ptr& context) : platform_views_controller_(platform_views_controller), ios_context_(context) { FML_CHECK(ios_context_); @@ -31,7 +31,7 @@ DlCanvas* IOSExternalViewEmbedder::GetRootCanvas() { void IOSExternalViewEmbedder::CancelFrame() { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::CancelFrame"); FML_CHECK(platform_views_controller_); - platform_views_controller_->CancelFrame(); + [platform_views_controller_ cancelFrame]; } // |ExternalViewEmbedder| @@ -42,7 +42,7 @@ void IOSExternalViewEmbedder::BeginFrame( // |ExternalViewEmbedder| void IOSExternalViewEmbedder::PrepareFlutterView(SkISize frame_size, double device_pixel_ratio) { FML_CHECK(platform_views_controller_); - platform_views_controller_->BeginFrame(frame_size); + [platform_views_controller_ beginFrameWithSize:frame_size]; } // |ExternalViewEmbedder| @@ -51,7 +51,7 @@ void IOSExternalViewEmbedder::PrerollCompositeEmbeddedView( std::unique_ptr params) { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::PrerollCompositeEmbeddedView"); FML_CHECK(platform_views_controller_); - platform_views_controller_->PrerollCompositeEmbeddedView(view_id, std::move(params)); + [platform_views_controller_ prerollCompositeEmbeddedView:view_id withParams:std::move(params)]; } // |ExternalViewEmbedder| @@ -59,8 +59,10 @@ PostPrerollResult IOSExternalViewEmbedder::PostPrerollAction( const fml::RefPtr& raster_thread_merger) { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::PostPrerollAction"); FML_CHECK(platform_views_controller_); - PostPrerollResult result = platform_views_controller_->PostPrerollAction( - raster_thread_merger, ios_context_->GetBackend() != IOSRenderingBackend::kSkia); + BOOL impeller_enabled = ios_context_->GetBackend() != IOSRenderingBackend::kSkia; + PostPrerollResult result = + [platform_views_controller_ postPrerollActionWithThreadMerger:raster_thread_merger + impellerEnabled:impeller_enabled]; return result; } @@ -68,7 +70,7 @@ PostPrerollResult IOSExternalViewEmbedder::PostPrerollAction( DlCanvas* IOSExternalViewEmbedder::CompositeEmbeddedView(int64_t view_id) { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::CompositeEmbeddedView"); FML_CHECK(platform_views_controller_); - return platform_views_controller_->CompositeEmbeddedView(view_id); + return [platform_views_controller_ compositeEmbeddedViewWithId:view_id]; } // |ExternalViewEmbedder| @@ -83,7 +85,9 @@ void IOSExternalViewEmbedder::SubmitFlutterView( // Properly support multi-view in the future. FML_DCHECK(flutter_view_id == kFlutterImplicitViewId); FML_CHECK(platform_views_controller_); - platform_views_controller_->SubmitFrame(context, ios_context_, std::move(frame)); + [platform_views_controller_ submitFrame:std::move(frame) + withIosContext:ios_context_ + grContext:context]; TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::DidSubmitFrame"); } @@ -92,8 +96,10 @@ void IOSExternalViewEmbedder::EndFrame( bool should_resubmit_frame, const fml::RefPtr& raster_thread_merger) { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::EndFrame"); - platform_views_controller_->EndFrame(should_resubmit_frame, raster_thread_merger, - ios_context_->GetBackend() != IOSRenderingBackend::kSkia); + BOOL impeller_enabled = ios_context_->GetBackend() != IOSRenderingBackend::kSkia; + [platform_views_controller_ endFrameWithResubmit:should_resubmit_frame + threadMerger:raster_thread_merger + impellerEnabled:impeller_enabled]; } // |ExternalViewEmbedder| @@ -110,12 +116,12 @@ bool IOSExternalViewEmbedder::SupportsDynamicThreadMerging() { void IOSExternalViewEmbedder::PushFilterToVisitedPlatformViews( const std::shared_ptr& filter, const SkRect& filter_rect) { - platform_views_controller_->PushFilterToVisitedPlatformViews(filter, filter_rect); + [platform_views_controller_ pushFilterToVisitedPlatformViews:filter withRect:filter_rect]; } // |ExternalViewEmbedder| void IOSExternalViewEmbedder::PushVisitedPlatformView(int64_t view_id) { - platform_views_controller_->PushVisitedPlatformView(view_id); + [platform_views_controller_ pushVisitedPlatformViewId:view_id]; } } // namespace flutter diff --git a/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.h b/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.h index 0e65e6174f..4e1da467d2 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.h +++ b/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.h @@ -40,13 +40,13 @@ class PlatformViewIOS final : public PlatformView { public: PlatformViewIOS(PlatformView::Delegate& delegate, const std::shared_ptr& context, - const std::shared_ptr& platform_views_controller, + __weak FlutterPlatformViewsController* platform_views_controller, const flutter::TaskRunners& task_runners); explicit PlatformViewIOS( PlatformView::Delegate& delegate, IOSRenderingAPI rendering_api, - const std::shared_ptr& platform_views_controller, + __weak FlutterPlatformViewsController* platform_views_controller, const flutter::TaskRunners& task_runners, const std::shared_ptr& worker_task_runner, const std::shared_ptr& is_gpu_disabled_sync_switch); @@ -137,7 +137,7 @@ class PlatformViewIOS final : public PlatformView { std::mutex ios_surface_mutex_; std::unique_ptr ios_surface_; std::shared_ptr ios_context_; - const std::shared_ptr& platform_views_controller_; + __weak FlutterPlatformViewsController* platform_views_controller_; AccessibilityBridgeManager accessibility_bridge_; ScopedObserver dealloc_view_controller_observer_; std::vector platform_resolved_locale_; diff --git a/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm b/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm index f651d00ec8..b726fd8fc1 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm @@ -41,11 +41,10 @@ void PlatformViewIOS::AccessibilityBridgeManager::Clear() { accessibility_bridge_.reset(); } -PlatformViewIOS::PlatformViewIOS( - PlatformView::Delegate& delegate, - const std::shared_ptr& context, - const std::shared_ptr& platform_views_controller, - const flutter::TaskRunners& task_runners) +PlatformViewIOS::PlatformViewIOS(PlatformView::Delegate& delegate, + const std::shared_ptr& context, + __weak FlutterPlatformViewsController* platform_views_controller, + const flutter::TaskRunners& task_runners) : PlatformView(delegate, task_runners), ios_context_(context), platform_views_controller_(platform_views_controller), @@ -56,7 +55,7 @@ PlatformViewIOS::PlatformViewIOS( PlatformViewIOS::PlatformViewIOS( PlatformView::Delegate& delegate, IOSRenderingAPI rendering_api, - const std::shared_ptr& platform_views_controller, + __weak FlutterPlatformViewsController* platform_views_controller, const flutter::TaskRunners& task_runners, const std::shared_ptr& worker_task_runner, const std::shared_ptr& is_gpu_disabled_sync_switch) @@ -209,7 +208,7 @@ void PlatformViewIOS::OnPreEngineRestart() const { if (!owner_controller_) { return; } - owner_controller_.platformViewsController->Reset(); + [owner_controller_.platformViewsController reset]; [owner_controller_.restorationPlugin reset]; }