7 #import <OCMock/OCMock.h>
8 #import <UIKit/UIKit.h>
9 #import <WebKit/WebKit.h>
10 #import <XCTest/XCTest.h>
14 #include "flutter/display_list/effects/dl_image_filters.h"
15 #include "flutter/fml/synchronization/count_down_latch.h"
16 #include "flutter/fml/thread.h"
36 - (instancetype)init {
51 @property(nonatomic, strong) UIView* view;
52 @property(nonatomic, assign) BOOL viewCreated;
57 - (instancetype)init {
58 if (
self = [super init]) {
66 [
self checkViewCreatedOnce];
70 - (void)checkViewCreatedOnce {
74 self.viewCreated = YES;
83 : NSObject <FlutterPlatformViewFactory>
88 viewIdentifier:(int64_t)viewId
89 arguments:(
id _Nullable)args {
96 @property(nonatomic, strong) UIView* view;
97 @property(nonatomic, assign) BOOL viewCreated;
101 - (instancetype)init {
102 if (
self = [super init]) {
103 _view = [[WKWebView alloc] init];
111 [
self checkViewCreatedOnce];
115 - (void)checkViewCreatedOnce {
119 self.viewCreated = YES;
131 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
132 viewIdentifier:(int64_t)viewId
133 arguments:(
id _Nullable)args {
142 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
143 viewIdentifier:(int64_t)viewId
144 arguments:(
id _Nullable)args {
151 @property(nonatomic, strong) UIView* view;
152 @property(nonatomic, assign) BOOL viewCreated;
156 - (instancetype)init {
157 if (
self = [super init]) {
158 _view = [[UIView alloc] init];
159 [_view addSubview:[[WKWebView alloc] init]];
167 [
self checkViewCreatedOnce];
171 - (void)checkViewCreatedOnce {
175 self.viewCreated = YES;
187 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
188 viewIdentifier:(int64_t)viewId
189 arguments:(
id _Nullable)args {
195 @property(nonatomic, strong) UIView* view;
196 @property(nonatomic, assign) BOOL viewCreated;
200 - (instancetype)init {
201 if (
self = [super init]) {
202 _view = [[UIView alloc] init];
203 UIView* childView = [[UIView alloc] init];
204 [_view addSubview:childView];
205 [childView addSubview:[[WKWebView alloc] init]];
213 [
self checkViewCreatedOnce];
217 - (void)checkViewCreatedOnce {
221 self.viewCreated = YES;
226 : NSObject <FlutterPlatformViewFactory>
231 viewIdentifier:(int64_t)viewId
232 arguments:(
id _Nullable)args {
246 UIScreen* mockScreen = OCMClassMock([UIScreen
class]);
247 CGFloat screenScale = 3;
248 OCMStub([mockScreen scale]).andReturn(screenScale);
257 class FlutterPlatformViewsTestMockPlatformViewDelegate :
public PlatformView::Delegate {
259 void OnPlatformViewCreated(std::unique_ptr<Surface> surface)
override {}
260 void OnPlatformViewDestroyed()
override {}
261 void OnPlatformViewScheduleFrame()
override {}
262 void OnPlatformViewAddView(int64_t view_id,
263 const ViewportMetrics& viewport_metrics,
264 AddViewCallback callback)
override {}
265 void OnPlatformViewRemoveView(int64_t view_id, RemoveViewCallback callback)
override {}
266 void OnPlatformViewSendViewFocusEvent(
const ViewFocusEvent& event)
override {};
267 void OnPlatformViewSetNextFrameCallback(
const fml::closure& closure)
override {}
268 void OnPlatformViewSetViewportMetrics(int64_t view_id,
const ViewportMetrics& metrics)
override {}
269 const flutter::Settings& OnPlatformViewGetSettings()
const override {
return settings_; }
270 void OnPlatformViewDispatchPlatformMessage(std::unique_ptr<PlatformMessage> message)
override {}
271 void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet)
override {
273 void OnPlatformViewDispatchSemanticsAction(int32_t
id,
274 SemanticsAction action,
275 fml::MallocMapping args)
override {}
276 void OnPlatformViewSetSemanticsEnabled(
bool enabled)
override {}
277 void OnPlatformViewSetAccessibilityFeatures(int32_t flags)
override {}
278 void OnPlatformViewRegisterTexture(std::shared_ptr<Texture> texture)
override {}
279 void OnPlatformViewUnregisterTexture(int64_t
texture_id)
override {}
280 void OnPlatformViewMarkTextureFrameAvailable(int64_t
texture_id)
override {}
282 void LoadDartDeferredLibrary(intptr_t loading_unit_id,
283 std::unique_ptr<const fml::Mapping> snapshot_data,
284 std::unique_ptr<const fml::Mapping> snapshot_instructions)
override {
286 void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
287 const std::string error_message,
288 bool transient)
override {}
289 void UpdateAssetResolverByType(std::unique_ptr<flutter::AssetResolver> updated_asset_resolver,
290 flutter::AssetResolver::AssetResolverType type)
override {}
295 BOOL BlurRadiusEqualToBlurRadius(CGFloat radius1, CGFloat radius2) {
296 const CGFloat epsilon = 0.01;
297 return std::abs(radius1 - radius2) < epsilon;
309 fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
310 fml::MessageLoop::EnsureInitializedForCurrentThread();
311 return fml::MessageLoop::GetCurrent().GetTaskRunner();
315 - (void)testFlutterViewOnlyCreateOnceInOneFrame {
316 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
318 flutter::TaskRunners runners(
self.name.UTF8String,
319 GetDefaultTaskRunner(),
320 GetDefaultTaskRunner(),
321 GetDefaultTaskRunner(),
322 GetDefaultTaskRunner());
325 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
326 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
329 flutterPlatformViewsController,
332 std::make_shared<fml::SyncSwitch>());
336 [flutterPlatformViewsController
338 withId:@"MockFlutterPlatformView"
342 [flutterPlatformViewsController
346 @"viewType" : @"MockFlutterPlatformView"
352 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
353 flutterPlatformViewsController.
flutterView = flutterView;
355 flutter::MutatorsStack stack;
358 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
359 stack.PushTransform(screenScaleMatrix);
361 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
362 stack.PushTransform(translateMatrix);
363 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
365 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
366 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
368 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
369 withParams:std::move(embeddedViewParams)];
373 [flutterPlatformViewsController
reset];
376 - (void)testCanCreatePlatformViewWithoutFlutterView {
377 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
379 flutter::TaskRunners runners(
self.name.UTF8String,
380 GetDefaultTaskRunner(),
381 GetDefaultTaskRunner(),
382 GetDefaultTaskRunner(),
383 GetDefaultTaskRunner());
386 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
387 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
390 flutterPlatformViewsController,
393 std::make_shared<fml::SyncSwitch>());
397 [flutterPlatformViewsController
399 withId:@"MockFlutterPlatformView"
403 [flutterPlatformViewsController
407 @"viewType" : @"MockFlutterPlatformView"
414 - (void)testChildClippingViewHitTests {
417 UIView* childView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
418 [childClippingView addSubview:childView];
420 XCTAssertFalse([childClippingView pointInside:CGPointMake(50, 50) withEvent:nil]);
421 XCTAssertFalse([childClippingView pointInside:CGPointMake(99, 100) withEvent:nil]);
422 XCTAssertFalse([childClippingView pointInside:CGPointMake(100, 99) withEvent:nil]);
423 XCTAssertFalse([childClippingView pointInside:CGPointMake(201, 200) withEvent:nil]);
424 XCTAssertFalse([childClippingView pointInside:CGPointMake(200, 201) withEvent:nil]);
425 XCTAssertFalse([childClippingView pointInside:CGPointMake(99, 200) withEvent:nil]);
426 XCTAssertFalse([childClippingView pointInside:CGPointMake(200, 299) withEvent:nil]);
428 XCTAssertTrue([childClippingView pointInside:CGPointMake(150, 150) withEvent:nil]);
429 XCTAssertTrue([childClippingView pointInside:CGPointMake(100, 100) withEvent:nil]);
430 XCTAssertTrue([childClippingView pointInside:CGPointMake(199, 100) withEvent:nil]);
431 XCTAssertTrue([childClippingView pointInside:CGPointMake(100, 199) withEvent:nil]);
432 XCTAssertTrue([childClippingView pointInside:CGPointMake(199, 199) withEvent:nil]);
435 - (void)testReleasesBackdropFilterSubviewsOnChildClippingViewDealloc {
436 __weak NSMutableArray<UIVisualEffectView*>* weakBackdropFilterSubviews = nil;
437 __weak UIVisualEffectView* weakVisualEffectView1 = nil;
438 __weak UIVisualEffectView* weakVisualEffectView2 = nil;
442 UIVisualEffectView* visualEffectView1 = [[UIVisualEffectView alloc]
443 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
444 weakVisualEffectView1 = visualEffectView1;
448 visualEffectView:visualEffectView1];
453 UIVisualEffectView* visualEffectView2 = [[UIVisualEffectView alloc]
454 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
455 weakVisualEffectView2 = visualEffectView2;
459 visualEffectView:visualEffectView2];
463 XCTAssertNotNil(weakBackdropFilterSubviews);
466 XCTAssertNil(weakBackdropFilterSubviews);
467 XCTAssertNil(weakVisualEffectView1);
468 XCTAssertNil(weakVisualEffectView2);
471 - (void)testApplyBackdropFilter {
472 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
474 flutter::TaskRunners runners(
self.name.UTF8String,
475 GetDefaultTaskRunner(),
476 GetDefaultTaskRunner(),
477 GetDefaultTaskRunner(),
478 GetDefaultTaskRunner());
481 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
482 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
485 flutterPlatformViewsController,
488 std::make_shared<fml::SyncSwitch>());
492 [flutterPlatformViewsController
494 withId:@"MockFlutterPlatformView"
498 [flutterPlatformViewsController
502 @"viewType" : @"MockFlutterPlatformView"
511 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
512 flutterPlatformViewsController.
flutterView = flutterView;
514 flutter::MutatorsStack stack;
517 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
518 stack.PushTransform(screenScaleMatrix);
520 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
521 stack.PushBackdropFilter(filter,
522 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
524 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
525 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
527 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
528 withParams:std::move(embeddedViewParams)];
529 [flutterPlatformViewsController
535 [flutterView addSubview:childClippingView];
537 [flutterView setNeedsLayout];
538 [flutterView layoutIfNeeded];
541 NSUInteger numberOfExpectedVisualEffectView = 0;
542 for (UIView* subview in childClippingView.subviews) {
543 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
546 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
547 if ([
self validateOneVisualEffectView:subview
548 expectedFrame:CGRectMake(0, 0, 10, 10)
550 numberOfExpectedVisualEffectView++;
553 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
556 - (void)testApplyBackdropFilterWithCorrectFrame {
557 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
559 flutter::TaskRunners runners(
self.name.UTF8String,
560 GetDefaultTaskRunner(),
561 GetDefaultTaskRunner(),
562 GetDefaultTaskRunner(),
563 GetDefaultTaskRunner());
566 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
567 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
570 flutterPlatformViewsController,
573 std::make_shared<fml::SyncSwitch>());
577 [flutterPlatformViewsController
579 withId:@"MockFlutterPlatformView"
583 [flutterPlatformViewsController
587 @"viewType" : @"MockFlutterPlatformView"
596 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
597 flutterPlatformViewsController.
flutterView = flutterView;
599 flutter::MutatorsStack stack;
602 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
603 stack.PushTransform(screenScaleMatrix);
605 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
606 stack.PushBackdropFilter(filter,
607 flutter::DlRect::MakeXYWH(0, 0, screenScale * 8, screenScale * 8));
609 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
610 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(5, 10), stack);
612 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
613 withParams:std::move(embeddedViewParams)];
614 [flutterPlatformViewsController
620 [flutterView addSubview:childClippingView];
622 [flutterView setNeedsLayout];
623 [flutterView layoutIfNeeded];
626 NSUInteger numberOfExpectedVisualEffectView = 0;
627 for (UIView* subview in childClippingView.subviews) {
628 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
631 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
632 if ([
self validateOneVisualEffectView:subview
633 expectedFrame:CGRectMake(0, 0, 5, 8)
635 numberOfExpectedVisualEffectView++;
638 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
641 - (void)testApplyMultipleBackdropFilters {
642 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
644 flutter::TaskRunners runners(
self.name.UTF8String,
645 GetDefaultTaskRunner(),
646 GetDefaultTaskRunner(),
647 GetDefaultTaskRunner(),
648 GetDefaultTaskRunner());
651 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
652 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
655 flutterPlatformViewsController,
658 std::make_shared<fml::SyncSwitch>());
662 [flutterPlatformViewsController
664 withId:@"MockFlutterPlatformView"
668 [flutterPlatformViewsController
672 @"viewType" : @"MockFlutterPlatformView"
681 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
682 flutterPlatformViewsController.
flutterView = flutterView;
684 flutter::MutatorsStack stack;
687 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
688 stack.PushTransform(screenScaleMatrix);
690 for (
int i = 0; i < 50; i++) {
691 auto filter = flutter::DlBlurImageFilter::Make(i, 2, flutter::DlTileMode::kClamp);
692 stack.PushBackdropFilter(filter,
693 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
696 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
697 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(20, 20), stack);
699 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
700 withParams:std::move(embeddedViewParams)];
701 [flutterPlatformViewsController
707 [flutterView addSubview:childClippingView];
709 [flutterView setNeedsLayout];
710 [flutterView layoutIfNeeded];
712 NSUInteger numberOfExpectedVisualEffectView = 0;
713 for (UIView* subview in childClippingView.subviews) {
714 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
717 XCTAssertLessThan(numberOfExpectedVisualEffectView, 50u);
718 if ([
self validateOneVisualEffectView:subview
719 expectedFrame:CGRectMake(0, 0, 10, 10)
720 inputRadius:(CGFloat)numberOfExpectedVisualEffectView]) {
721 numberOfExpectedVisualEffectView++;
724 XCTAssertEqual(numberOfExpectedVisualEffectView, (NSUInteger)numberOfExpectedVisualEffectView);
727 - (void)testAddBackdropFilters {
728 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
730 flutter::TaskRunners runners(
self.name.UTF8String,
731 GetDefaultTaskRunner(),
732 GetDefaultTaskRunner(),
733 GetDefaultTaskRunner(),
734 GetDefaultTaskRunner());
737 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
738 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
741 flutterPlatformViewsController,
744 std::make_shared<fml::SyncSwitch>());
748 [flutterPlatformViewsController
750 withId:@"MockFlutterPlatformView"
754 [flutterPlatformViewsController
758 @"viewType" : @"MockFlutterPlatformView"
767 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
768 flutterPlatformViewsController.
flutterView = flutterView;
770 flutter::MutatorsStack stack;
773 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
774 stack.PushTransform(screenScaleMatrix);
776 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
777 stack.PushBackdropFilter(filter,
778 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
780 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
781 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
783 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
784 withParams:std::move(embeddedViewParams)];
785 [flutterPlatformViewsController
791 [flutterView addSubview:childClippingView];
793 [flutterView setNeedsLayout];
794 [flutterView layoutIfNeeded];
796 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
797 for (UIView* subview in childClippingView.subviews) {
798 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
801 XCTAssertLessThan(originalVisualEffectViews.count, 1u);
802 if ([
self validateOneVisualEffectView:subview
803 expectedFrame:CGRectMake(0, 0, 10, 10)
804 inputRadius:(CGFloat)5]) {
805 [originalVisualEffectViews addObject:subview];
808 XCTAssertEqual(originalVisualEffectViews.count, 1u);
813 flutter::MutatorsStack stack2;
815 stack2.PushTransform(screenScaleMatrix);
817 for (
int i = 0; i < 2; i++) {
818 stack2.PushBackdropFilter(filter,
819 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
822 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
823 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
825 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
826 withParams:std::move(embeddedViewParams)];
827 [flutterPlatformViewsController
831 [flutterView setNeedsLayout];
832 [flutterView layoutIfNeeded];
834 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
835 for (UIView* subview in childClippingView.subviews) {
836 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
839 XCTAssertLessThan(newVisualEffectViews.count, 2u);
841 if ([
self validateOneVisualEffectView:subview
842 expectedFrame:CGRectMake(0, 0, 10, 10)
843 inputRadius:(CGFloat)5]) {
844 [newVisualEffectViews addObject:subview];
847 XCTAssertEqual(newVisualEffectViews.count, 2u);
848 for (NSUInteger i = 0; i < originalVisualEffectViews.count; i++) {
849 UIView* originalView = originalVisualEffectViews[i];
850 UIView* newView = newVisualEffectViews[i];
852 XCTAssertEqual(originalView, newView);
853 id mockOrignalView = OCMPartialMock(originalView);
854 OCMReject([mockOrignalView removeFromSuperview]);
855 [mockOrignalView stopMocking];
859 - (void)testRemoveBackdropFilters {
860 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
862 flutter::TaskRunners runners(
self.name.UTF8String,
863 GetDefaultTaskRunner(),
864 GetDefaultTaskRunner(),
865 GetDefaultTaskRunner(),
866 GetDefaultTaskRunner());
869 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
870 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
873 flutterPlatformViewsController,
876 std::make_shared<fml::SyncSwitch>());
880 [flutterPlatformViewsController
882 withId:@"MockFlutterPlatformView"
886 [flutterPlatformViewsController
890 @"viewType" : @"MockFlutterPlatformView"
899 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
900 flutterPlatformViewsController.
flutterView = flutterView;
902 flutter::MutatorsStack stack;
905 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
906 stack.PushTransform(screenScaleMatrix);
908 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
909 for (
int i = 0; i < 5; i++) {
910 stack.PushBackdropFilter(filter,
911 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
914 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
915 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
917 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
918 withParams:std::move(embeddedViewParams)];
919 [flutterPlatformViewsController
925 [flutterView addSubview:childClippingView];
927 [flutterView setNeedsLayout];
928 [flutterView layoutIfNeeded];
930 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
931 for (UIView* subview in childClippingView.subviews) {
932 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
935 XCTAssertLessThan(originalVisualEffectViews.count, 5u);
936 if ([
self validateOneVisualEffectView:subview
937 expectedFrame:CGRectMake(0, 0, 10, 10)
938 inputRadius:(CGFloat)5]) {
939 [originalVisualEffectViews addObject:subview];
945 flutter::MutatorsStack stack2;
947 stack2.PushTransform(screenScaleMatrix);
949 for (
int i = 0; i < 4; i++) {
950 stack2.PushBackdropFilter(filter,
951 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
954 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
955 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
957 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
958 withParams:std::move(embeddedViewParams)];
959 [flutterPlatformViewsController
963 [flutterView setNeedsLayout];
964 [flutterView layoutIfNeeded];
966 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
967 for (UIView* subview in childClippingView.subviews) {
968 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
971 XCTAssertLessThan(newVisualEffectViews.count, 4u);
972 if ([
self validateOneVisualEffectView:subview
973 expectedFrame:CGRectMake(0, 0, 10, 10)
974 inputRadius:(CGFloat)5]) {
975 [newVisualEffectViews addObject:subview];
978 XCTAssertEqual(newVisualEffectViews.count, 4u);
980 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
981 UIView* newView = newVisualEffectViews[i];
982 id mockNewView = OCMPartialMock(newView);
983 UIView* originalView = originalVisualEffectViews[i];
985 XCTAssertEqual(originalView, newView);
986 OCMReject([mockNewView removeFromSuperview]);
987 [mockNewView stopMocking];
992 for (
int i = 0; i < 5; i++) {
997 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
998 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
1000 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1001 withParams:std::move(embeddedViewParams)];
1002 [flutterPlatformViewsController
1006 [flutterView setNeedsLayout];
1007 [flutterView layoutIfNeeded];
1009 NSUInteger numberOfExpectedVisualEffectView = 0u;
1010 for (UIView* subview in childClippingView.subviews) {
1011 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1012 numberOfExpectedVisualEffectView++;
1015 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1018 - (void)testEditBackdropFilters {
1019 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1021 flutter::TaskRunners runners(
self.name.UTF8String,
1022 GetDefaultTaskRunner(),
1023 GetDefaultTaskRunner(),
1024 GetDefaultTaskRunner(),
1025 GetDefaultTaskRunner());
1028 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1029 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1032 flutterPlatformViewsController,
1035 std::make_shared<fml::SyncSwitch>());
1039 [flutterPlatformViewsController
1041 withId:@"MockFlutterPlatformView"
1045 [flutterPlatformViewsController
1049 @"viewType" : @"MockFlutterPlatformView"
1058 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1059 flutterPlatformViewsController.
flutterView = flutterView;
1061 flutter::MutatorsStack stack;
1064 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1065 stack.PushTransform(screenScaleMatrix);
1067 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1068 for (
int i = 0; i < 5; i++) {
1069 stack.PushBackdropFilter(filter,
1070 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1073 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1074 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
1076 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1077 withParams:std::move(embeddedViewParams)];
1078 [flutterPlatformViewsController
1084 [flutterView addSubview:childClippingView];
1086 [flutterView setNeedsLayout];
1087 [flutterView layoutIfNeeded];
1089 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
1090 for (UIView* subview in childClippingView.subviews) {
1091 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1094 XCTAssertLessThan(originalVisualEffectViews.count, 5u);
1095 if ([
self validateOneVisualEffectView:subview
1096 expectedFrame:CGRectMake(0, 0, 10, 10)
1097 inputRadius:(CGFloat)5]) {
1098 [originalVisualEffectViews addObject:subview];
1104 flutter::MutatorsStack stack2;
1106 stack2.PushTransform(screenScaleMatrix);
1108 for (
int i = 0; i < 5; i++) {
1110 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1112 stack2.PushBackdropFilter(
1113 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1117 stack2.PushBackdropFilter(filter,
1118 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1121 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1122 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
1124 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1125 withParams:std::move(embeddedViewParams)];
1126 [flutterPlatformViewsController
1130 [flutterView setNeedsLayout];
1131 [flutterView layoutIfNeeded];
1133 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
1134 for (UIView* subview in childClippingView.subviews) {
1135 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1138 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1139 CGFloat expectInputRadius = 5;
1140 if (newVisualEffectViews.count == 3) {
1141 expectInputRadius = 2;
1143 if ([
self validateOneVisualEffectView:subview
1144 expectedFrame:CGRectMake(0, 0, 10, 10)
1145 inputRadius:expectInputRadius]) {
1146 [newVisualEffectViews addObject:subview];
1149 XCTAssertEqual(newVisualEffectViews.count, 5u);
1150 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1151 UIView* newView = newVisualEffectViews[i];
1152 id mockNewView = OCMPartialMock(newView);
1153 UIView* originalView = originalVisualEffectViews[i];
1155 XCTAssertEqual(originalView, newView);
1156 OCMReject([mockNewView removeFromSuperview]);
1157 [mockNewView stopMocking];
1159 [newVisualEffectViews removeAllObjects];
1163 for (
int i = 0; i < 5; i++) {
1167 for (
int i = 0; i < 5; i++) {
1169 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1170 stack2.PushBackdropFilter(
1171 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1175 stack2.PushBackdropFilter(filter,
1176 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1179 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1180 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
1182 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1183 withParams:std::move(embeddedViewParams)];
1184 [flutterPlatformViewsController
1188 [flutterView setNeedsLayout];
1189 [flutterView layoutIfNeeded];
1191 for (UIView* subview in childClippingView.subviews) {
1192 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1195 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1196 CGFloat expectInputRadius = 5;
1197 if (newVisualEffectViews.count == 0) {
1198 expectInputRadius = 2;
1200 if ([
self validateOneVisualEffectView:subview
1201 expectedFrame:CGRectMake(0, 0, 10, 10)
1202 inputRadius:expectInputRadius]) {
1203 [newVisualEffectViews addObject:subview];
1206 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1207 UIView* newView = newVisualEffectViews[i];
1208 id mockNewView = OCMPartialMock(newView);
1209 UIView* originalView = originalVisualEffectViews[i];
1211 XCTAssertEqual(originalView, newView);
1212 OCMReject([mockNewView removeFromSuperview]);
1213 [mockNewView stopMocking];
1215 [newVisualEffectViews removeAllObjects];
1219 for (
int i = 0; i < 5; i++) {
1223 for (
int i = 0; i < 5; i++) {
1225 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1226 stack2.PushBackdropFilter(
1227 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1231 stack2.PushBackdropFilter(filter,
1232 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1235 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1236 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
1238 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1239 withParams:std::move(embeddedViewParams)];
1240 [flutterPlatformViewsController
1244 [flutterView setNeedsLayout];
1245 [flutterView layoutIfNeeded];
1247 for (UIView* subview in childClippingView.subviews) {
1248 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1251 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1252 CGFloat expectInputRadius = 5;
1253 if (newVisualEffectViews.count == 4) {
1254 expectInputRadius = 2;
1256 if ([
self validateOneVisualEffectView:subview
1257 expectedFrame:CGRectMake(0, 0, 10, 10)
1258 inputRadius:expectInputRadius]) {
1259 [newVisualEffectViews addObject:subview];
1262 XCTAssertEqual(newVisualEffectViews.count, 5u);
1264 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1265 UIView* newView = newVisualEffectViews[i];
1266 id mockNewView = OCMPartialMock(newView);
1267 UIView* originalView = originalVisualEffectViews[i];
1269 XCTAssertEqual(originalView, newView);
1270 OCMReject([mockNewView removeFromSuperview]);
1271 [mockNewView stopMocking];
1273 [newVisualEffectViews removeAllObjects];
1277 for (
int i = 0; i < 5; i++) {
1281 for (
int i = 0; i < 5; i++) {
1282 auto filter2 = flutter::DlBlurImageFilter::Make(i, 2, flutter::DlTileMode::kClamp);
1284 stack2.PushBackdropFilter(filter2,
1285 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1288 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1289 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
1291 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1292 withParams:std::move(embeddedViewParams)];
1293 [flutterPlatformViewsController
1297 [flutterView setNeedsLayout];
1298 [flutterView layoutIfNeeded];
1300 for (UIView* subview in childClippingView.subviews) {
1301 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1304 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1305 if ([
self validateOneVisualEffectView:subview
1306 expectedFrame:CGRectMake(0, 0, 10, 10)
1307 inputRadius:(CGFloat)newVisualEffectViews.count]) {
1308 [newVisualEffectViews addObject:subview];
1311 XCTAssertEqual(newVisualEffectViews.count, 5u);
1313 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1314 UIView* newView = newVisualEffectViews[i];
1315 id mockNewView = OCMPartialMock(newView);
1316 UIView* originalView = originalVisualEffectViews[i];
1318 XCTAssertEqual(originalView, newView);
1319 OCMReject([mockNewView removeFromSuperview]);
1320 [mockNewView stopMocking];
1322 [newVisualEffectViews removeAllObjects];
1325 - (void)testApplyBackdropFilterNotDlBlurImageFilter {
1326 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1328 flutter::TaskRunners runners(
self.name.UTF8String,
1329 GetDefaultTaskRunner(),
1330 GetDefaultTaskRunner(),
1331 GetDefaultTaskRunner(),
1332 GetDefaultTaskRunner());
1335 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1336 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1339 flutterPlatformViewsController,
1342 std::make_shared<fml::SyncSwitch>());
1346 [flutterPlatformViewsController
1348 withId:@"MockFlutterPlatformView"
1352 [flutterPlatformViewsController
1356 @"viewType" : @"MockFlutterPlatformView"
1365 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1366 flutterPlatformViewsController.
flutterView = flutterView;
1368 flutter::MutatorsStack stack;
1371 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1372 stack.PushTransform(screenScaleMatrix);
1374 auto dilateFilter = flutter::DlDilateImageFilter::Make(5, 2);
1375 stack.PushBackdropFilter(dilateFilter, flutter::DlRect());
1377 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1378 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
1380 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1381 withParams:std::move(embeddedViewParams)];
1382 [flutterPlatformViewsController
1389 [flutterView addSubview:childClippingView];
1391 [flutterView setNeedsLayout];
1392 [flutterView layoutIfNeeded];
1394 NSUInteger numberOfExpectedVisualEffectView = 0;
1395 for (UIView* subview in childClippingView.subviews) {
1396 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1397 numberOfExpectedVisualEffectView++;
1400 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1404 flutter::MutatorsStack stack2;
1406 stack2.PushTransform(screenScaleMatrix);
1408 auto blurFilter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1410 for (
int i = 0; i < 5; i++) {
1412 stack2.PushBackdropFilter(
1413 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1417 stack2.PushBackdropFilter(blurFilter,
1418 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1421 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1422 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
1424 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1425 withParams:std::move(embeddedViewParams)];
1426 [flutterPlatformViewsController
1430 [flutterView setNeedsLayout];
1431 [flutterView layoutIfNeeded];
1433 numberOfExpectedVisualEffectView = 0;
1434 for (UIView* subview in childClippingView.subviews) {
1435 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1438 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1439 if ([
self validateOneVisualEffectView:subview
1440 expectedFrame:CGRectMake(0, 0, 10, 10)
1441 inputRadius:(CGFloat)5]) {
1442 numberOfExpectedVisualEffectView++;
1445 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1449 for (
int i = 0; i < 5; i++) {
1453 for (
int i = 0; i < 5; i++) {
1455 stack2.PushBackdropFilter(
1456 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1460 stack2.PushBackdropFilter(blurFilter,
1461 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1464 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1465 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
1467 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1468 withParams:std::move(embeddedViewParams)];
1469 [flutterPlatformViewsController
1473 [flutterView setNeedsLayout];
1474 [flutterView layoutIfNeeded];
1476 numberOfExpectedVisualEffectView = 0;
1477 for (UIView* subview in childClippingView.subviews) {
1478 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1481 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1482 if ([
self validateOneVisualEffectView:subview
1483 expectedFrame:CGRectMake(0, 0, 10, 10)
1484 inputRadius:(CGFloat)5]) {
1485 numberOfExpectedVisualEffectView++;
1488 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1492 for (
int i = 0; i < 5; i++) {
1496 for (
int i = 0; i < 5; i++) {
1498 stack2.PushBackdropFilter(
1499 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1503 stack2.PushBackdropFilter(blurFilter,
1504 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1507 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1508 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
1510 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1511 withParams:std::move(embeddedViewParams)];
1512 [flutterPlatformViewsController
1516 [flutterView setNeedsLayout];
1517 [flutterView layoutIfNeeded];
1519 numberOfExpectedVisualEffectView = 0;
1520 for (UIView* subview in childClippingView.subviews) {
1521 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1524 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1525 if ([
self validateOneVisualEffectView:subview
1526 expectedFrame:CGRectMake(0, 0, 10, 10)
1527 inputRadius:(CGFloat)5]) {
1528 numberOfExpectedVisualEffectView++;
1531 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1535 for (
int i = 0; i < 5; i++) {
1539 for (
int i = 0; i < 5; i++) {
1540 stack2.PushBackdropFilter(dilateFilter,
1541 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1544 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1545 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
1547 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1548 withParams:std::move(embeddedViewParams)];
1549 [flutterPlatformViewsController
1553 [flutterView setNeedsLayout];
1554 [flutterView layoutIfNeeded];
1556 numberOfExpectedVisualEffectView = 0;
1557 for (UIView* subview in childClippingView.subviews) {
1558 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1559 numberOfExpectedVisualEffectView++;
1562 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1565 - (void)testApplyBackdropFilterCorrectAPI {
1570 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
1571 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1575 visualEffectView:visualEffectView];
1576 XCTAssertNotNil(platformViewFilter);
1579 - (void)testApplyBackdropFilterAPIChangedInvalidUIVisualEffectView {
1581 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc] init];
1585 visualEffectView:visualEffectView];
1586 XCTAssertNil(platformViewFilter);
1589 - (void)testApplyBackdropFilterAPIChangedNoGaussianBlurFilter {
1591 UIVisualEffectView* editedUIVisualEffectView = [[UIVisualEffectView alloc]
1592 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1593 NSArray* subviews = editedUIVisualEffectView.subviews;
1594 for (UIView* view in subviews) {
1595 if ([NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
1596 for (CIFilter* filter in view.layer.filters) {
1597 if ([[filter valueForKey:
@"name"] isEqual:
@"gaussianBlur"]) {
1598 [filter setValue:@"notGaussianBlur" forKey:@"name"];
1608 visualEffectView:editedUIVisualEffectView];
1609 XCTAssertNil(platformViewFilter);
1612 - (void)testApplyBackdropFilterAPIChangedInvalidInputRadius {
1614 UIVisualEffectView* editedUIVisualEffectView = [[UIVisualEffectView alloc]
1615 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1616 NSArray* subviews = editedUIVisualEffectView.subviews;
1617 for (UIView* view in subviews) {
1618 if ([NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
1619 for (CIFilter* filter in view.layer.filters) {
1620 if ([[filter valueForKey:
@"name"] isEqual:
@"gaussianBlur"]) {
1621 [filter setValue:@"invalidInputRadius" forKey:@"inputRadius"];
1632 visualEffectView:editedUIVisualEffectView];
1633 XCTAssertNil(platformViewFilter);
1636 - (void)testBackdropFilterVisualEffectSubviewBackgroundColor {
1637 __weak UIVisualEffectView* weakVisualEffectView;
1640 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
1641 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1642 weakVisualEffectView = visualEffectView;
1646 visualEffectView:visualEffectView];
1647 CGColorRef visualEffectSubviewBackgroundColor = nil;
1648 for (UIView* view in [platformViewFilter backdropFilterView].subviews) {
1649 if ([NSStringFromClass([view
class]) hasSuffix:
@"VisualEffectSubview"]) {
1650 visualEffectSubviewBackgroundColor = view.layer.backgroundColor;
1654 CGColorEqualToColor(visualEffectSubviewBackgroundColor, UIColor.clearColor.CGColor));
1656 XCTAssertNil(weakVisualEffectView);
1659 - (void)testCompositePlatformView {
1660 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1662 flutter::TaskRunners runners(
self.name.UTF8String,
1663 GetDefaultTaskRunner(),
1664 GetDefaultTaskRunner(),
1665 GetDefaultTaskRunner(),
1666 GetDefaultTaskRunner());
1669 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1670 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1673 flutterPlatformViewsController,
1676 std::make_shared<fml::SyncSwitch>());
1680 [flutterPlatformViewsController
1682 withId:@"MockFlutterPlatformView"
1686 [flutterPlatformViewsController
1690 @"viewType" : @"MockFlutterPlatformView"
1699 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
1700 flutterPlatformViewsController.
flutterView = flutterView;
1702 flutter::MutatorsStack stack;
1705 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1706 stack.PushTransform(screenScaleMatrix);
1708 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
1709 stack.PushTransform(translateMatrix);
1710 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
1712 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1713 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
1715 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1716 withParams:std::move(embeddedViewParams)];
1717 [flutterPlatformViewsController
1721 CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
1722 toView:flutterView];
1723 XCTAssertTrue(CGRectEqualToRect(platformViewRectInFlutterView, CGRectMake(100, 100, 300, 300)));
1726 - (void)testBackdropFilterCorrectlyPushedAndReset {
1727 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1729 flutter::TaskRunners runners(
self.name.UTF8String,
1730 GetDefaultTaskRunner(),
1731 GetDefaultTaskRunner(),
1732 GetDefaultTaskRunner(),
1733 GetDefaultTaskRunner());
1736 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1737 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1740 flutterPlatformViewsController,
1743 std::make_shared<fml::SyncSwitch>());
1747 [flutterPlatformViewsController
1749 withId:@"MockFlutterPlatformView"
1753 [flutterPlatformViewsController
1757 @"viewType" : @"MockFlutterPlatformView"
1766 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1767 flutterPlatformViewsController.
flutterView = flutterView;
1769 flutter::MutatorsStack stack;
1772 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1773 stack.PushTransform(screenScaleMatrix);
1775 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1776 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
1778 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(0, 0)];
1779 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1780 withParams:std::move(embeddedViewParams)];
1782 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1783 [flutterPlatformViewsController
1784 pushFilterToVisitedPlatformViews:filter
1785 withRect:SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10)];
1786 [flutterPlatformViewsController
1792 [flutterView addSubview:childClippingView];
1794 [flutterView setNeedsLayout];
1795 [flutterView layoutIfNeeded];
1798 NSUInteger numberOfExpectedVisualEffectView = 0;
1799 for (UIView* subview in childClippingView.subviews) {
1800 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1803 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
1804 if ([
self validateOneVisualEffectView:subview
1805 expectedFrame:CGRectMake(0, 0, 10, 10)
1807 numberOfExpectedVisualEffectView++;
1810 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
1813 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
1814 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
1815 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(0, 0)];
1816 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1817 withParams:std::move(embeddedViewParams2)];
1818 [flutterPlatformViewsController
1824 [flutterView setNeedsLayout];
1825 [flutterView layoutIfNeeded];
1827 numberOfExpectedVisualEffectView = 0;
1828 for (UIView* subview in childClippingView.subviews) {
1829 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1832 numberOfExpectedVisualEffectView++;
1834 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1837 - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
1838 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1840 flutter::TaskRunners runners(
self.name.UTF8String,
1841 GetDefaultTaskRunner(),
1842 GetDefaultTaskRunner(),
1843 GetDefaultTaskRunner(),
1844 GetDefaultTaskRunner());
1847 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1848 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1851 flutterPlatformViewsController,
1854 std::make_shared<fml::SyncSwitch>());
1858 [flutterPlatformViewsController
1860 withId:@"MockFlutterPlatformView"
1864 [flutterPlatformViewsController
1868 @"viewType" : @"MockFlutterPlatformView"
1877 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
1878 flutterPlatformViewsController.
flutterView = flutterView;
1880 flutter::MutatorsStack stack;
1883 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1884 stack.PushTransform(screenScaleMatrix);
1886 flutter::DlMatrix rotateMatrix = flutter::DlMatrix::MakeRotationZ(flutter::DlDegrees(10));
1887 stack.PushTransform(rotateMatrix);
1888 flutter::DlMatrix finalMatrix = screenScaleMatrix * rotateMatrix;
1890 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1891 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
1893 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1894 withParams:std::move(embeddedViewParams)];
1895 [flutterPlatformViewsController
1899 CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
1900 toView:flutterView];
1906 XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.x - childClippingView.frame.origin.x),
1908 XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.y - childClippingView.frame.origin.y),
1911 fabs(platformViewRectInFlutterView.size.width - childClippingView.frame.size.width),
1914 fabs(platformViewRectInFlutterView.size.height - childClippingView.frame.size.height),
1918 - (void)testClipsDoNotInterceptWithPlatformViewShouldNotAddMaskView {
1919 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1921 flutter::TaskRunners runners(
self.name.UTF8String,
1922 GetDefaultTaskRunner(),
1923 GetDefaultTaskRunner(),
1924 GetDefaultTaskRunner(),
1925 GetDefaultTaskRunner());
1928 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1929 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1932 flutterPlatformViewsController,
1935 std::make_shared<fml::SyncSwitch>());
1939 [flutterPlatformViewsController
1941 withId:@"MockFlutterPlatformView"
1945 [flutterPlatformViewsController
1949 @"viewType" : @"MockFlutterPlatformView"
1958 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
1959 flutterPlatformViewsController.
flutterView = flutterView;
1961 flutter::MutatorsStack stack;
1964 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1965 stack.PushTransform(screenScaleMatrix);
1966 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({5, 5});
1968 stack.PushTransform(translateMatrix);
1970 flutter::DlRect rect = flutter::DlRect::MakeXYWH(0, 0, 25, 25);
1971 stack.PushClipRect(rect);
1974 flutter::DlRect rect_for_rrect = flutter::DlRect::MakeXYWH(-1, -1, 25, 25);
1975 flutter::DlRoundRect rrect = flutter::DlRoundRect::MakeRectXY(rect_for_rrect, 1, 1);
1976 stack.PushClipRRect(rrect);
1978 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1979 flutter::ToSkMatrix(screenScaleMatrix * translateMatrix), SkSize::Make(5, 5), stack);
1981 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1982 withParams:std::move(embeddedViewParams)];
1983 [flutterPlatformViewsController
1990 [flutterView addSubview:childClippingView];
1992 [flutterView setNeedsLayout];
1993 [flutterView layoutIfNeeded];
1994 XCTAssertNil(childClippingView.maskView);
1997 - (void)testClipRRectOnlyHasCornersInterceptWithPlatformViewShouldAddMaskView {
1998 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2000 flutter::TaskRunners runners(
self.name.UTF8String,
2001 GetDefaultTaskRunner(),
2002 GetDefaultTaskRunner(),
2003 GetDefaultTaskRunner(),
2004 GetDefaultTaskRunner());
2007 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2008 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2011 flutterPlatformViewsController,
2014 std::make_shared<fml::SyncSwitch>());
2018 [flutterPlatformViewsController
2020 withId:@"MockFlutterPlatformView"
2024 [flutterPlatformViewsController
2028 @"viewType" : @"MockFlutterPlatformView"
2037 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
2038 flutterPlatformViewsController.
flutterView = flutterView;
2040 flutter::MutatorsStack stack;
2043 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2044 stack.PushTransform(screenScaleMatrix);
2045 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({5, 5});
2047 stack.PushTransform(translateMatrix);
2051 flutter::DlRect rect_for_rrect = flutter::DlRect::MakeXYWH(0, 0, 10, 10);
2052 flutter::DlRoundRect rrect = flutter::DlRoundRect::MakeRectXY(rect_for_rrect, 1, 1);
2053 stack.PushClipRRect(rrect);
2055 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2056 flutter::ToSkMatrix(screenScaleMatrix * translateMatrix), SkSize::Make(5, 5), stack);
2058 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2059 withParams:std::move(embeddedViewParams)];
2060 [flutterPlatformViewsController
2067 [flutterView addSubview:childClippingView];
2069 [flutterView setNeedsLayout];
2070 [flutterView layoutIfNeeded];
2072 XCTAssertNotNil(childClippingView.maskView);
2075 - (void)testClipRect {
2076 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2078 flutter::TaskRunners runners(
self.name.UTF8String,
2079 GetDefaultTaskRunner(),
2080 GetDefaultTaskRunner(),
2081 GetDefaultTaskRunner(),
2082 GetDefaultTaskRunner());
2085 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2086 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2089 flutterPlatformViewsController,
2092 std::make_shared<fml::SyncSwitch>());
2096 [flutterPlatformViewsController
2098 withId:@"MockFlutterPlatformView"
2102 [flutterPlatformViewsController
2106 @"viewType" : @"MockFlutterPlatformView"
2115 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2116 flutterPlatformViewsController.
flutterView = flutterView;
2118 flutter::MutatorsStack stack;
2121 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2122 stack.PushTransform(screenScaleMatrix);
2124 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
2125 stack.PushClipRect(rect);
2127 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2128 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
2130 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2131 withParams:std::move(embeddedViewParams)];
2132 [flutterPlatformViewsController
2139 [flutterView addSubview:childClippingView];
2141 [flutterView setNeedsLayout];
2142 [flutterView layoutIfNeeded];
2144 CGRect insideClipping = CGRectMake(2, 2, 3, 3);
2145 for (
int i = 0; i < 10; i++) {
2146 for (
int j = 0; j < 10; j++) {
2147 CGPoint point = CGPointMake(i, j);
2148 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2149 if (CGRectContainsPoint(insideClipping, point)) {
2150 XCTAssertEqual(alpha, 255);
2152 XCTAssertEqual(alpha, 0);
2158 - (void)testClipRect_multipleClips {
2159 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2161 flutter::TaskRunners runners(
self.name.UTF8String,
2162 GetDefaultTaskRunner(),
2163 GetDefaultTaskRunner(),
2164 GetDefaultTaskRunner(),
2165 GetDefaultTaskRunner());
2168 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2169 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2172 flutterPlatformViewsController,
2175 std::make_shared<fml::SyncSwitch>());
2179 [flutterPlatformViewsController
2181 withId:@"MockFlutterPlatformView"
2185 [flutterPlatformViewsController
2189 @"viewType" : @"MockFlutterPlatformView"
2198 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2199 flutterPlatformViewsController.
flutterView = flutterView;
2201 flutter::MutatorsStack stack;
2204 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2205 stack.PushTransform(screenScaleMatrix);
2207 flutter::DlRect rect1 = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
2208 stack.PushClipRect(rect1);
2210 flutter::DlRect rect2 = flutter::DlRect::MakeXYWH(3, 3, 3, 3);
2211 stack.PushClipRect(rect2);
2213 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2214 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
2216 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2217 withParams:std::move(embeddedViewParams)];
2218 [flutterPlatformViewsController
2225 [flutterView addSubview:childClippingView];
2227 [flutterView setNeedsLayout];
2228 [flutterView layoutIfNeeded];
2247 CGRect insideClipping = CGRectMake(3, 3, 2, 2);
2248 for (
int i = 0; i < 10; i++) {
2249 for (
int j = 0; j < 10; j++) {
2250 CGPoint point = CGPointMake(i, j);
2251 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2252 if (CGRectContainsPoint(insideClipping, point)) {
2253 XCTAssertEqual(alpha, 255);
2255 XCTAssertEqual(alpha, 0);
2261 - (void)testClipRRect {
2262 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2264 flutter::TaskRunners runners(
self.name.UTF8String,
2265 GetDefaultTaskRunner(),
2266 GetDefaultTaskRunner(),
2267 GetDefaultTaskRunner(),
2268 GetDefaultTaskRunner());
2271 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2272 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2275 flutterPlatformViewsController,
2278 std::make_shared<fml::SyncSwitch>());
2282 [flutterPlatformViewsController
2284 withId:@"MockFlutterPlatformView"
2288 [flutterPlatformViewsController
2292 @"viewType" : @"MockFlutterPlatformView"
2301 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2302 flutterPlatformViewsController.
flutterView = flutterView;
2304 flutter::MutatorsStack stack;
2307 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2308 stack.PushTransform(screenScaleMatrix);
2310 flutter::DlRoundRect rrect =
2311 flutter::DlRoundRect::MakeRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2312 stack.PushClipRRect(rrect);
2314 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2315 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
2317 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2318 withParams:std::move(embeddedViewParams)];
2319 [flutterPlatformViewsController
2326 [flutterView addSubview:childClippingView];
2328 [flutterView setNeedsLayout];
2329 [flutterView layoutIfNeeded];
2350 CGRect innerClipping1 = CGRectMake(3, 2, 4, 6);
2351 CGRect innerClipping2 = CGRectMake(2, 3, 6, 4);
2352 CGRect outterClipping = CGRectMake(2, 2, 6, 6);
2353 for (
int i = 0; i < 10; i++) {
2354 for (
int j = 0; j < 10; j++) {
2355 CGPoint point = CGPointMake(i, j);
2356 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2357 if (CGRectContainsPoint(innerClipping1, point) ||
2358 CGRectContainsPoint(innerClipping2, point)) {
2360 XCTAssertEqual(alpha, 255);
2361 }
else if (CGRectContainsPoint(outterClipping, point)) {
2363 XCTAssert(0 < alpha && alpha < 255);
2366 XCTAssertEqual(alpha, 0);
2372 - (void)testClipRRect_multipleClips {
2373 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2375 flutter::TaskRunners runners(
self.name.UTF8String,
2376 GetDefaultTaskRunner(),
2377 GetDefaultTaskRunner(),
2378 GetDefaultTaskRunner(),
2379 GetDefaultTaskRunner());
2382 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2383 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2386 flutterPlatformViewsController,
2389 std::make_shared<fml::SyncSwitch>());
2393 [flutterPlatformViewsController
2395 withId:@"MockFlutterPlatformView"
2399 [flutterPlatformViewsController
2403 @"viewType" : @"MockFlutterPlatformView"
2412 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2413 flutterPlatformViewsController.
flutterView = flutterView;
2415 flutter::MutatorsStack stack;
2418 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2419 stack.PushTransform(screenScaleMatrix);
2421 flutter::DlRoundRect rrect =
2422 flutter::DlRoundRect::MakeRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2423 stack.PushClipRRect(rrect);
2425 flutter::DlRect rect = flutter::DlRect::MakeXYWH(4, 2, 6, 6);
2426 stack.PushClipRect(rect);
2428 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2429 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
2431 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2432 withParams:std::move(embeddedViewParams)];
2433 [flutterPlatformViewsController
2440 [flutterView addSubview:childClippingView];
2442 [flutterView setNeedsLayout];
2443 [flutterView layoutIfNeeded];
2464 CGRect clipping = CGRectMake(4, 2, 4, 6);
2465 for (
int i = 0; i < 10; i++) {
2466 for (
int j = 0; j < 10; j++) {
2467 CGPoint point = CGPointMake(i, j);
2468 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2469 if (i == 7 && (j == 2 || j == 7)) {
2471 XCTAssert(0 < alpha && alpha < 255);
2474 (i == 4 && j >= 2 && j <= 7) ||
2476 (i == 7 && j >= 2 && j <= 7) ||
2478 (j == 2 && i >= 4 && i <= 7) ||
2480 (j == 7 && i >= 4 && i <= 7)) {
2483 XCTAssert(alpha > 127);
2484 }
else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) ||
2485 (j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) {
2488 XCTAssert(alpha < 127);
2489 }
else if (CGRectContainsPoint(clipping, point)) {
2491 XCTAssertEqual(alpha, 255);
2494 XCTAssertEqual(alpha, 0);
2500 - (void)testClipPath {
2501 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2503 flutter::TaskRunners runners(
self.name.UTF8String,
2504 GetDefaultTaskRunner(),
2505 GetDefaultTaskRunner(),
2506 GetDefaultTaskRunner(),
2507 GetDefaultTaskRunner());
2510 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2511 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2514 flutterPlatformViewsController,
2517 std::make_shared<fml::SyncSwitch>());
2521 [flutterPlatformViewsController
2523 withId:@"MockFlutterPlatformView"
2527 [flutterPlatformViewsController
2531 @"viewType" : @"MockFlutterPlatformView"
2540 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2541 flutterPlatformViewsController.
flutterView = flutterView;
2543 flutter::MutatorsStack stack;
2546 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2547 stack.PushTransform(screenScaleMatrix);
2549 flutter::DlPath path =
2550 flutter::DlPath::MakeRoundRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2551 stack.PushClipPath(path);
2553 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2554 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
2556 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2557 withParams:std::move(embeddedViewParams)];
2558 [flutterPlatformViewsController
2565 [flutterView addSubview:childClippingView];
2567 [flutterView setNeedsLayout];
2568 [flutterView layoutIfNeeded];
2589 CGRect innerClipping1 = CGRectMake(3, 2, 4, 6);
2590 CGRect innerClipping2 = CGRectMake(2, 3, 6, 4);
2591 CGRect outterClipping = CGRectMake(2, 2, 6, 6);
2592 for (
int i = 0; i < 10; i++) {
2593 for (
int j = 0; j < 10; j++) {
2594 CGPoint point = CGPointMake(i, j);
2595 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2596 if (CGRectContainsPoint(innerClipping1, point) ||
2597 CGRectContainsPoint(innerClipping2, point)) {
2599 XCTAssertEqual(alpha, 255);
2600 }
else if (CGRectContainsPoint(outterClipping, point)) {
2602 XCTAssert(0 < alpha && alpha < 255);
2605 XCTAssertEqual(alpha, 0);
2611 - (void)testClipPath_multipleClips {
2612 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2614 flutter::TaskRunners runners(
self.name.UTF8String,
2615 GetDefaultTaskRunner(),
2616 GetDefaultTaskRunner(),
2617 GetDefaultTaskRunner(),
2618 GetDefaultTaskRunner());
2621 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2622 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2625 flutterPlatformViewsController,
2628 std::make_shared<fml::SyncSwitch>());
2632 [flutterPlatformViewsController
2634 withId:@"MockFlutterPlatformView"
2638 [flutterPlatformViewsController
2642 @"viewType" : @"MockFlutterPlatformView"
2651 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2652 flutterPlatformViewsController.
flutterView = flutterView;
2654 flutter::MutatorsStack stack;
2657 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2658 stack.PushTransform(screenScaleMatrix);
2660 flutter::DlPath path =
2661 flutter::DlPath::MakeRoundRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2662 stack.PushClipPath(path);
2664 flutter::DlRect rect = flutter::DlRect::MakeXYWH(4, 2, 6, 6);
2665 stack.PushClipRect(rect);
2667 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2668 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
2670 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2671 withParams:std::move(embeddedViewParams)];
2672 [flutterPlatformViewsController
2679 [flutterView addSubview:childClippingView];
2681 [flutterView setNeedsLayout];
2682 [flutterView layoutIfNeeded];
2703 CGRect clipping = CGRectMake(4, 2, 4, 6);
2704 for (
int i = 0; i < 10; i++) {
2705 for (
int j = 0; j < 10; j++) {
2706 CGPoint point = CGPointMake(i, j);
2707 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2708 if (i == 7 && (j == 2 || j == 7)) {
2710 XCTAssert(0 < alpha && alpha < 255);
2713 (i == 4 && j >= 2 && j <= 7) ||
2715 (i == 7 && j >= 2 && j <= 7) ||
2717 (j == 2 && i >= 4 && i <= 7) ||
2719 (j == 7 && i >= 4 && i <= 7)) {
2722 XCTAssert(alpha > 127);
2723 }
else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) ||
2724 (j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) {
2727 XCTAssert(alpha < 127);
2728 }
else if (CGRectContainsPoint(clipping, point)) {
2730 XCTAssertEqual(alpha, 255);
2733 XCTAssertEqual(alpha, 0);
2739 - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents {
2740 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2742 flutter::TaskRunners runners(
self.name.UTF8String,
2743 GetDefaultTaskRunner(),
2744 GetDefaultTaskRunner(),
2745 GetDefaultTaskRunner(),
2746 GetDefaultTaskRunner());
2749 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2750 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2753 flutterPlatformViewsController,
2756 std::make_shared<fml::SyncSwitch>());
2760 [flutterPlatformViewsController
2762 withId:@"MockFlutterPlatformView"
2766 [flutterPlatformViewsController
2770 @"viewType" : @"MockFlutterPlatformView"
2778 while (touchInteceptorView != nil &&
2780 touchInteceptorView = touchInteceptorView.superview;
2782 XCTAssertNotNil(touchInteceptorView);
2785 UIGestureRecognizer* forwardGectureRecognizer = nil;
2786 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
2788 forwardGectureRecognizer = gestureRecognizer;
2794 NSSet* touches1 = [[NSSet alloc] init];
2795 id event1 = OCMClassMock([UIEvent
class]);
2797 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2798 OCMReject([flutterViewController touchesBegan:touches1 withEvent:event1]);
2801 NSSet* touches2 = [[NSSet alloc] init];
2802 id event2 = OCMClassMock([UIEvent
class]);
2804 [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2];
2805 OCMVerify([flutterViewController touchesBegan:touches2 withEvent:event2]);
2808 - (void)testSetFlutterViewControllerInTheMiddleOfTouchEventShouldStillAllowGesturesToBeHandled {
2809 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2811 flutter::TaskRunners runners(
self.name.UTF8String,
2812 GetDefaultTaskRunner(),
2813 GetDefaultTaskRunner(),
2814 GetDefaultTaskRunner(),
2815 GetDefaultTaskRunner());
2818 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2819 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2822 flutterPlatformViewsController,
2825 std::make_shared<fml::SyncSwitch>());
2829 [flutterPlatformViewsController
2831 withId:@"MockFlutterPlatformView"
2835 [flutterPlatformViewsController
2839 @"viewType" : @"MockFlutterPlatformView"
2847 while (touchInteceptorView != nil &&
2849 touchInteceptorView = touchInteceptorView.superview;
2851 XCTAssertNotNil(touchInteceptorView);
2854 UIGestureRecognizer* forwardGectureRecognizer = nil;
2855 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
2857 forwardGectureRecognizer = gestureRecognizer;
2866 NSSet* touches1 = [[NSSet alloc] init];
2867 id event1 = OCMClassMock([UIEvent
class]);
2868 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2869 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
2874 NSSet* touches2 = [[NSSet alloc] init];
2875 id event2 = OCMClassMock([UIEvent
class]);
2876 [forwardGectureRecognizer touchesMoved:touches2 withEvent:event2];
2877 OCMVerify([flutterViewController touchesMoved:touches2 withEvent:event2]);
2879 NSSet* touches3 = [[NSSet alloc] init];
2880 id event3 = OCMClassMock([UIEvent
class]);
2881 [forwardGectureRecognizer touchesEnded:touches3 withEvent:event3];
2882 OCMVerify([flutterViewController touchesEnded:touches3 withEvent:event3]);
2885 NSSet* touches4 = [[NSSet alloc] init];
2886 id event4 = OCMClassMock([UIEvent
class]);
2887 [forwardGectureRecognizer touchesBegan:touches4 withEvent:event4];
2888 OCMReject([flutterViewController touchesBegan:touches4 withEvent:event4]);
2890 NSSet* touches5 = [[NSSet alloc] init];
2891 id event5 = OCMClassMock([UIEvent
class]);
2892 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
2893 OCMReject([flutterViewController touchesEnded:touches5 withEvent:event5]);
2900 NSSet* touches1 = [[NSSet alloc] init];
2901 id event1 = OCMClassMock([UIEvent
class]);
2902 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2903 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
2908 NSSet* touches2 = [[NSSet alloc] init];
2909 id event2 = OCMClassMock([UIEvent
class]);
2910 [forwardGectureRecognizer touchesMoved:touches2 withEvent:event2];
2911 OCMVerify([flutterViewController touchesMoved:touches2 withEvent:event2]);
2913 NSSet* touches3 = [[NSSet alloc] init];
2914 id event3 = OCMClassMock([UIEvent
class]);
2915 [forwardGectureRecognizer touchesCancelled:touches3 withEvent:event3];
2916 OCMVerify([flutterViewController forceTouchesCancelled:touches3]);
2919 NSSet* touches4 = [[NSSet alloc] init];
2920 id event4 = OCMClassMock([UIEvent
class]);
2921 [forwardGectureRecognizer touchesBegan:touches4 withEvent:event4];
2922 OCMReject([flutterViewController touchesBegan:touches4 withEvent:event4]);
2924 NSSet* touches5 = [[NSSet alloc] init];
2925 id event5 = OCMClassMock([UIEvent
class]);
2926 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
2927 OCMReject([flutterViewController touchesEnded:touches5 withEvent:event5]);
2930 [flutterPlatformViewsController
reset];
2934 testSetFlutterViewControllerInTheMiddleOfTouchEventAllowsTheNewControllerToHandleSecondTouchSequence {
2935 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2937 flutter::TaskRunners runners(
self.name.UTF8String,
2938 GetDefaultTaskRunner(),
2939 GetDefaultTaskRunner(),
2940 GetDefaultTaskRunner(),
2941 GetDefaultTaskRunner());
2944 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2945 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2948 flutterPlatformViewsController,
2951 std::make_shared<fml::SyncSwitch>());
2955 [flutterPlatformViewsController
2957 withId:@"MockFlutterPlatformView"
2961 [flutterPlatformViewsController
2965 @"viewType" : @"MockFlutterPlatformView"
2973 while (touchInteceptorView != nil &&
2975 touchInteceptorView = touchInteceptorView.superview;
2977 XCTAssertNotNil(touchInteceptorView);
2980 UIGestureRecognizer* forwardGectureRecognizer = nil;
2981 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
2983 forwardGectureRecognizer = gestureRecognizer;
2991 NSSet* touches1 = [NSSet setWithObject:@1];
2992 id event1 = OCMClassMock([UIEvent
class]);
2993 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2994 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
3001 NSSet* touches2 = [NSSet setWithObject:@1];
3002 id event2 = OCMClassMock([UIEvent
class]);
3003 [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2];
3004 OCMVerify([flutterViewController touchesBegan:touches2 withEvent:event2]);
3005 OCMReject([flutterViewController2 touchesBegan:touches2 withEvent:event2]);
3007 NSSet* touches3 = [NSSet setWithObject:@1];
3008 id event3 = OCMClassMock([UIEvent
class]);
3009 [forwardGectureRecognizer touchesMoved:touches3 withEvent:event3];
3010 OCMVerify([flutterViewController touchesMoved:touches3 withEvent:event3]);
3011 OCMReject([flutterViewController2 touchesMoved:touches3 withEvent:event3]);
3013 NSSet* touches4 = [NSSet setWithObject:@1];
3014 id event4 = OCMClassMock([UIEvent
class]);
3015 [forwardGectureRecognizer touchesEnded:touches4 withEvent:event4];
3016 OCMVerify([flutterViewController touchesEnded:touches4 withEvent:event4]);
3017 OCMReject([flutterViewController2 touchesEnded:touches4 withEvent:event4]);
3019 NSSet* touches5 = [NSSet setWithObject:@1];
3020 id event5 = OCMClassMock([UIEvent
class]);
3021 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
3022 OCMVerify([flutterViewController touchesEnded:touches5 withEvent:event5]);
3023 OCMReject([flutterViewController2 touchesEnded:touches5 withEvent:event5]);
3027 NSSet* touches6 = [NSSet setWithObject:@1];
3028 id event6 = OCMClassMock([UIEvent
class]);
3029 [forwardGectureRecognizer touchesBegan:touches6 withEvent:event6];
3030 OCMVerify([flutterViewController2 touchesBegan:touches6 withEvent:event6]);
3031 OCMReject([flutterViewController touchesBegan:touches6 withEvent:event6]);
3034 NSSet* touches7 = [NSSet setWithObject:@1];
3035 id event7 = OCMClassMock([UIEvent
class]);
3036 [forwardGectureRecognizer touchesMoved:touches7 withEvent:event7];
3037 OCMVerify([flutterViewController2 touchesMoved:touches7 withEvent:event7]);
3038 OCMReject([flutterViewController touchesMoved:touches7 withEvent:event7]);
3040 NSSet* touches8 = [NSSet setWithObject:@1];
3041 id event8 = OCMClassMock([UIEvent
class]);
3042 [forwardGectureRecognizer touchesEnded:touches8 withEvent:event8];
3043 OCMVerify([flutterViewController2 touchesEnded:touches8 withEvent:event8]);
3044 OCMReject([flutterViewController touchesEnded:touches8 withEvent:event8]);
3046 [flutterPlatformViewsController
reset];
3049 - (void)testFlutterPlatformViewTouchesCancelledEventAreForcedToBeCancelled {
3050 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3052 flutter::TaskRunners runners(
self.name.UTF8String,
3053 GetDefaultTaskRunner(),
3054 GetDefaultTaskRunner(),
3055 GetDefaultTaskRunner(),
3056 GetDefaultTaskRunner());
3059 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3060 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3063 flutterPlatformViewsController,
3066 std::make_shared<fml::SyncSwitch>());
3070 [flutterPlatformViewsController
3072 withId:@"MockFlutterPlatformView"
3076 [flutterPlatformViewsController
3080 @"viewType" : @"MockFlutterPlatformView"
3088 while (touchInteceptorView != nil &&
3090 touchInteceptorView = touchInteceptorView.superview;
3092 XCTAssertNotNil(touchInteceptorView);
3095 UIGestureRecognizer* forwardGectureRecognizer = nil;
3096 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3098 forwardGectureRecognizer = gestureRecognizer;
3105 NSSet* touches1 = [NSSet setWithObject:@1];
3106 id event1 = OCMClassMock([UIEvent
class]);
3107 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
3109 [forwardGectureRecognizer touchesCancelled:touches1 withEvent:event1];
3110 OCMVerify([flutterViewController forceTouchesCancelled:touches1]);
3112 [flutterPlatformViewsController
reset];
3115 - (void)testFlutterPlatformViewTouchesEndedOrTouchesCancelledEventDoesNotFailTheGestureRecognizer {
3116 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3118 flutter::TaskRunners runners(
self.name.UTF8String,
3119 GetDefaultTaskRunner(),
3120 GetDefaultTaskRunner(),
3121 GetDefaultTaskRunner(),
3122 GetDefaultTaskRunner());
3125 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3126 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3129 flutterPlatformViewsController,
3132 std::make_shared<fml::SyncSwitch>());
3136 [flutterPlatformViewsController
3138 withId:@"MockFlutterPlatformView"
3142 [flutterPlatformViewsController
3146 @"viewType" : @"MockFlutterPlatformView"
3154 while (touchInteceptorView != nil &&
3156 touchInteceptorView = touchInteceptorView.superview;
3158 XCTAssertNotNil(touchInteceptorView);
3161 __block UIGestureRecognizer* forwardGestureRecognizer = nil;
3162 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3164 forwardGestureRecognizer = gestureRecognizer;
3171 NSSet* touches1 = [NSSet setWithObject:@1];
3172 id event1 = OCMClassMock([UIEvent
class]);
3173 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3174 @"Forwarding gesture recognizer must start with possible state.");
3175 [forwardGestureRecognizer touchesBegan:touches1 withEvent:event1];
3176 [forwardGestureRecognizer touchesEnded:touches1 withEvent:event1];
3177 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStateFailed,
3178 @"Forwarding gesture recognizer must end with failed state.");
3180 XCTestExpectation* touchEndedExpectation =
3181 [
self expectationWithDescription:@"Wait for gesture recognizer's state change."];
3182 dispatch_async(dispatch_get_main_queue(), ^{
3184 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3185 if ([gestureRecognizer isKindOfClass:[ForwardingGestureRecognizer class]]) {
3186 forwardGestureRecognizer = gestureRecognizer;
3190 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3191 @"Forwarding gesture recognizer must be reset to possible state.");
3192 [touchEndedExpectation fulfill];
3194 [
self waitForExpectationsWithTimeout:30 handler:nil];
3196 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3197 @"Forwarding gesture recognizer must start with possible state.");
3198 [forwardGestureRecognizer touchesBegan:touches1 withEvent:event1];
3199 [forwardGestureRecognizer touchesCancelled:touches1 withEvent:event1];
3200 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStateFailed,
3201 @"Forwarding gesture recognizer must end with failed state.");
3202 XCTestExpectation* touchCancelledExpectation =
3203 [
self expectationWithDescription:@"Wait for gesture recognizer's state change."];
3204 dispatch_async(dispatch_get_main_queue(), ^{
3206 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3207 if ([gestureRecognizer isKindOfClass:[ForwardingGestureRecognizer class]]) {
3208 forwardGestureRecognizer = gestureRecognizer;
3212 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3213 @"Forwarding gesture recognizer must be reset to possible state.");
3214 [touchCancelledExpectation fulfill];
3216 [
self waitForExpectationsWithTimeout:30 handler:nil];
3218 [flutterPlatformViewsController reset];
3222 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizerForWebView {
3223 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3225 flutter::TaskRunners runners(
self.name.UTF8String,
3226 GetDefaultTaskRunner(),
3227 GetDefaultTaskRunner(),
3228 GetDefaultTaskRunner(),
3229 GetDefaultTaskRunner());
3232 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3233 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3236 flutterPlatformViewsController,
3239 std::make_shared<fml::SyncSwitch>());
3243 [flutterPlatformViewsController
3249 [flutterPlatformViewsController
3252 arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3259 while (touchInteceptorView != nil &&
3261 touchInteceptorView = touchInteceptorView.superview;
3263 XCTAssertNotNil(touchInteceptorView);
3265 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3266 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3267 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3274 if (@available(iOS 18.2, *)) {
3276 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], forwardingRecognizer);
3277 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], delayingRecognizer);
3279 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3280 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3285 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizerForWrapperWebView {
3286 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3288 flutter::TaskRunners runners(
self.name.UTF8String,
3289 GetDefaultTaskRunner(),
3290 GetDefaultTaskRunner(),
3291 GetDefaultTaskRunner(),
3292 GetDefaultTaskRunner());
3295 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3296 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3299 flutterPlatformViewsController,
3302 std::make_shared<fml::SyncSwitch>());
3306 [flutterPlatformViewsController
3308 withId:@"MockWrapperWebView"
3312 [flutterPlatformViewsController
3315 arguments:@{@"id" : @2, @"viewType" : @"MockWrapperWebView"}]
3322 while (touchInteceptorView != nil &&
3324 touchInteceptorView = touchInteceptorView.superview;
3326 XCTAssertNotNil(touchInteceptorView);
3328 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3329 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3330 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3337 if (@available(iOS 18.2, *)) {
3339 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], forwardingRecognizer);
3340 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], delayingRecognizer);
3342 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3343 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3348 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldNotRemoveAndAddBackDelayingRecognizerForNestedWrapperWebView {
3349 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3351 flutter::TaskRunners runners(
self.name.UTF8String,
3352 GetDefaultTaskRunner(),
3353 GetDefaultTaskRunner(),
3354 GetDefaultTaskRunner(),
3355 GetDefaultTaskRunner());
3358 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3359 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3362 flutterPlatformViewsController,
3365 std::make_shared<fml::SyncSwitch>());
3369 [flutterPlatformViewsController
3371 withId:@"MockNestedWrapperWebView"
3375 [flutterPlatformViewsController
3379 @"viewType" : @"MockNestedWrapperWebView"
3387 while (touchInteceptorView != nil &&
3389 touchInteceptorView = touchInteceptorView.superview;
3391 XCTAssertNotNil(touchInteceptorView);
3393 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3394 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3395 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3402 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3403 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3407 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldNotRemoveAndAddBackDelayingRecognizerForNonWebView {
3408 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3410 flutter::TaskRunners runners(
self.name.UTF8String,
3411 GetDefaultTaskRunner(),
3412 GetDefaultTaskRunner(),
3413 GetDefaultTaskRunner(),
3414 GetDefaultTaskRunner());
3417 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3418 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3421 flutterPlatformViewsController,
3424 std::make_shared<fml::SyncSwitch>());
3428 [flutterPlatformViewsController
3430 withId:@"MockFlutterPlatformView"
3434 [flutterPlatformViewsController
3438 @"viewType" : @"MockFlutterPlatformView"
3446 while (touchInteceptorView != nil &&
3448 touchInteceptorView = touchInteceptorView.superview;
3450 XCTAssertNotNil(touchInteceptorView);
3452 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3453 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3454 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3461 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3462 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3465 - (void)testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashing {
3466 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3468 flutter::TaskRunners runners(
self.name.UTF8String,
3469 GetDefaultTaskRunner(),
3470 GetDefaultTaskRunner(),
3471 GetDefaultTaskRunner(),
3472 GetDefaultTaskRunner());
3475 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3476 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3479 flutterPlatformViewsController,
3482 std::make_shared<fml::SyncSwitch>());
3486 [flutterPlatformViewsController
3488 withId:@"MockFlutterPlatformView"
3492 [flutterPlatformViewsController
3496 @"viewType" : @"MockFlutterPlatformView"
3507 flutter::MutatorsStack stack;
3508 flutter::DlMatrix finalMatrix;
3510 auto embeddedViewParams_1 = std::make_unique<flutter::EmbeddedViewParams>(
3511 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
3513 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
3514 withParams:std::move(embeddedViewParams_1)];
3515 [flutterPlatformViewsController
3519 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
3520 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
3521 nullptr, framebuffer_info,
3522 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return false; },
3523 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
3524 SkISize::Make(800, 600));
3525 XCTAssertFalse([flutterPlatformViewsController
3526 submitFrame:std::move(mock_surface)
3527 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
3529 auto embeddedViewParams_2 = std::make_unique<flutter::EmbeddedViewParams>(
3530 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
3531 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
3532 withParams:std::move(embeddedViewParams_2)];
3533 [flutterPlatformViewsController
3537 auto mock_surface_submit_true = std::make_unique<flutter::SurfaceFrame>(
3538 nullptr, framebuffer_info,
3539 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
3540 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
3541 SkISize::Make(800, 600));
3542 XCTAssertTrue([flutterPlatformViewsController
3543 submitFrame:std::move(mock_surface_submit_true)
3544 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
3548 testFlutterPlatformViewControllerResetDeallocsPlatformViewWhenRootViewsNotBindedToFlutterView {
3549 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3551 flutter::TaskRunners runners(
self.name.UTF8String,
3552 GetDefaultTaskRunner(),
3553 GetDefaultTaskRunner(),
3554 GetDefaultTaskRunner(),
3555 GetDefaultTaskRunner());
3558 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3559 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3562 flutterPlatformViewsController,
3565 std::make_shared<fml::SyncSwitch>());
3567 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
3568 flutterPlatformViewsController.
flutterView = flutterView;
3572 [flutterPlatformViewsController
3574 withId:@"MockFlutterPlatformView"
3580 [flutterPlatformViewsController
3584 @"viewType" : @"MockFlutterPlatformView"
3588 flutter::MutatorsStack stack;
3589 flutter::DlMatrix finalMatrix;
3590 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
3591 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
3592 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
3593 withParams:std::move(embeddedViewParams)];
3599 [flutterPlatformViewsController
reset];
3604 - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder {
3605 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3607 flutter::TaskRunners runners(
self.name.UTF8String,
3608 GetDefaultTaskRunner(),
3609 GetDefaultTaskRunner(),
3610 GetDefaultTaskRunner(),
3611 GetDefaultTaskRunner());
3614 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3615 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3618 flutterPlatformViewsController,
3621 std::make_shared<fml::SyncSwitch>());
3626 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
3627 flutterPlatformViewsController.
flutterView = flutterView;
3631 [flutterPlatformViewsController
3633 withId:@"MockFlutterPlatformView"
3638 [flutterPlatformViewsController
3642 @"viewType" : @"MockFlutterPlatformView"
3647 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
3648 flutter::MutatorsStack stack;
3649 flutter::DlMatrix finalMatrix;
3650 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
3651 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
3652 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
3653 withParams:std::move(embeddedViewParams1)];
3654 [flutterPlatformViewsController
3661 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
3664 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
3665 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
3666 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
3667 withParams:std::move(embeddedViewParams2)];
3668 [flutterPlatformViewsController
3676 testFlutterPlatformViewControllerSubmitFrameShouldOrderSubviewsCorrectlyWithDifferentViewHierarchy {
3677 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3679 flutter::TaskRunners runners(
self.name.UTF8String,
3680 GetDefaultTaskRunner(),
3681 GetDefaultTaskRunner(),
3682 GetDefaultTaskRunner(),
3683 GetDefaultTaskRunner());
3686 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3687 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3690 flutterPlatformViewsController,
3693 std::make_shared<fml::SyncSwitch>());
3698 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
3699 flutterPlatformViewsController.
flutterView = flutterView;
3703 [flutterPlatformViewsController
3705 withId:@"MockFlutterPlatformView"
3709 [flutterPlatformViewsController
3713 @"viewType" : @"MockFlutterPlatformView"
3719 [flutterPlatformViewsController
3723 @"viewType" : @"MockFlutterPlatformView"
3728 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
3729 flutter::MutatorsStack stack;
3730 flutter::DlMatrix finalMatrix;
3731 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
3732 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
3733 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
3734 withParams:std::move(embeddedViewParams1)];
3736 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
3737 flutter::ToSkMatrix(finalMatrix), SkSize::Make(500, 500), stack);
3738 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
3739 withParams:std::move(embeddedViewParams2)];
3741 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
3742 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
3743 nullptr, framebuffer_info,
3744 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
3745 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
3746 SkISize::Make(800, 600),
nullptr,
true);
3747 XCTAssertTrue([flutterPlatformViewsController
3748 submitFrame:std::move(mock_surface)
3749 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
3752 UIView* clippingView1 = view1.superview.superview;
3753 UIView* clippingView2 = view2.superview.superview;
3754 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
3755 [flutterView.subviews indexOfObject:clippingView2],
3756 @"The first clipping view should be added before the second clipping view.");
3759 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
3761 embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
3762 flutter::ToSkMatrix(finalMatrix), SkSize::Make(500, 500), stack);
3763 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
3764 withParams:std::move(embeddedViewParams2)];
3766 embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
3767 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
3768 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
3769 withParams:std::move(embeddedViewParams1)];
3771 mock_surface = std::make_unique<flutter::SurfaceFrame>(
3772 nullptr, framebuffer_info,
3773 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
3774 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
3775 SkISize::Make(800, 600),
nullptr,
true);
3776 XCTAssertTrue([flutterPlatformViewsController
3777 submitFrame:std::move(mock_surface)
3778 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
3780 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] >
3781 [flutterView.subviews indexOfObject:clippingView2],
3782 @"The first clipping view should be added after the second clipping view.");
3786 testFlutterPlatformViewControllerSubmitFrameShouldOrderSubviewsCorrectlyWithSameViewHierarchy {
3787 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3789 flutter::TaskRunners runners(
self.name.UTF8String,
3790 GetDefaultTaskRunner(),
3791 GetDefaultTaskRunner(),
3792 GetDefaultTaskRunner(),
3793 GetDefaultTaskRunner());
3796 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3797 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3800 flutterPlatformViewsController,
3803 std::make_shared<fml::SyncSwitch>());
3808 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
3809 flutterPlatformViewsController.
flutterView = flutterView;
3813 [flutterPlatformViewsController
3815 withId:@"MockFlutterPlatformView"
3819 [flutterPlatformViewsController
3823 @"viewType" : @"MockFlutterPlatformView"
3829 [flutterPlatformViewsController
3833 @"viewType" : @"MockFlutterPlatformView"
3838 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
3839 flutter::MutatorsStack stack;
3840 flutter::DlMatrix finalMatrix;
3841 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
3842 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
3843 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
3844 withParams:std::move(embeddedViewParams1)];
3846 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
3847 flutter::ToSkMatrix(finalMatrix), SkSize::Make(500, 500), stack);
3848 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
3849 withParams:std::move(embeddedViewParams2)];
3851 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
3852 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
3853 nullptr, framebuffer_info,
3854 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
3855 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
3856 SkISize::Make(800, 600),
nullptr,
true);
3857 XCTAssertTrue([flutterPlatformViewsController
3858 submitFrame:std::move(mock_surface)
3859 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
3862 UIView* clippingView1 = view1.superview.superview;
3863 UIView* clippingView2 = view2.superview.superview;
3864 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
3865 [flutterView.subviews indexOfObject:clippingView2],
3866 @"The first clipping view should be added before the second clipping view.");
3869 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
3871 embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
3872 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
3873 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
3874 withParams:std::move(embeddedViewParams1)];
3876 embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
3877 flutter::ToSkMatrix(finalMatrix), SkSize::Make(500, 500), stack);
3878 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
3879 withParams:std::move(embeddedViewParams2)];
3881 mock_surface = std::make_unique<flutter::SurfaceFrame>(
3882 nullptr, framebuffer_info,
3883 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
3884 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
3885 SkISize::Make(800, 600),
nullptr,
true);
3886 XCTAssertTrue([flutterPlatformViewsController
3887 submitFrame:std::move(mock_surface)
3888 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
3890 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
3891 [flutterView.subviews indexOfObject:clippingView2],
3892 @"The first clipping view should be added before the second clipping view.");
3895 - (int)alphaOfPoint:(CGPoint)point onView:(UIView*)view {
3896 unsigned char pixel[4] = {0};
3898 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
3901 CGContextRef context = CGBitmapContextCreate(
3902 pixel, 1, 1, 8, 4, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);
3903 CGContextTranslateCTM(context, -point.x, -point.y);
3904 [view.layer renderInContext:context];
3906 CGContextRelease(context);
3907 CGColorSpaceRelease(colorSpace);
3912 - (void)testHasFirstResponderInViewHierarchySubtree_viewItselfBecomesFirstResponder {
3914 UIWindow* window = [[UIWindow alloc] init];
3915 UITextField* textField = [[UITextField alloc] init];
3916 [window addSubview:textField];
3918 [textField becomeFirstResponder];
3919 XCTAssertTrue(textField.isFirstResponder);
3920 XCTAssertTrue(textField.flt_hasFirstResponderInViewHierarchySubtree);
3921 [textField resignFirstResponder];
3922 XCTAssertFalse(textField.isFirstResponder);
3923 XCTAssertFalse(textField.flt_hasFirstResponderInViewHierarchySubtree);
3926 - (void)testHasFirstResponderInViewHierarchySubtree_descendantViewBecomesFirstResponder {
3928 UIWindow* window = [[UIWindow alloc] init];
3929 UIView* view = [[UIView alloc] init];
3930 UIView* childView = [[UIView alloc] init];
3931 UITextField* textField = [[UITextField alloc] init];
3932 [window addSubview:view];
3933 [view addSubview:childView];
3934 [childView addSubview:textField];
3936 [textField becomeFirstResponder];
3937 XCTAssertTrue(textField.isFirstResponder);
3938 XCTAssertTrue(view.flt_hasFirstResponderInViewHierarchySubtree);
3939 [textField resignFirstResponder];
3940 XCTAssertFalse(textField.isFirstResponder);
3941 XCTAssertFalse(view.flt_hasFirstResponderInViewHierarchySubtree);
3944 - (void)testFlutterClippingMaskViewPoolReuseViewsAfterRecycle {
3950 CGRect newRect = CGRectMake(0, 0, 10, 10);
3954 NSSet* set1 = [NSSet setWithObjects:view1, view2, nil];
3955 NSSet* set2 = [NSSet setWithObjects:view3, view4, nil];
3956 XCTAssertEqualObjects(set1, set2);
3957 XCTAssertTrue(CGRectEqualToRect(view3.frame, newRect));
3958 XCTAssertTrue(CGRectEqualToRect(view4.frame, newRect));
3961 - (void)testFlutterClippingMaskViewPoolAllocsNewMaskViewsAfterReachingCapacity {
3966 XCTAssertNotEqual(view1, view3);
3967 XCTAssertNotEqual(view2, view3);
3970 - (void)testMaskViewsReleasedWhenPoolIsReleased {
3971 __weak UIView* weakView;
3976 XCTAssertNotNil(weakView);
3978 XCTAssertNil(weakView);
3981 - (void)testClipMaskViewIsReused {
3982 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3984 flutter::TaskRunners runners(
self.name.UTF8String,
3985 GetDefaultTaskRunner(),
3986 GetDefaultTaskRunner(),
3987 GetDefaultTaskRunner(),
3988 GetDefaultTaskRunner());
3991 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3992 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3995 flutterPlatformViewsController,
3998 std::make_shared<fml::SyncSwitch>());
4002 [flutterPlatformViewsController
4004 withId:@"MockFlutterPlatformView"
4008 [flutterPlatformViewsController
4012 @"viewType" : @"MockFlutterPlatformView"
4020 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4021 flutterPlatformViewsController.
flutterView = flutterView;
4023 flutter::MutatorsStack stack1;
4026 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4027 stack1.PushTransform(screenScaleMatrix);
4029 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4030 stack1.PushClipRect(rect);
4032 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4033 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack1);
4035 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4036 withParams:std::move(embeddedViewParams1)];
4037 [flutterPlatformViewsController
4042 UIView* maskView1 = childClippingView1.maskView;
4043 XCTAssertNotNil(maskView1);
4046 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(100, 100)];
4047 flutter::MutatorsStack stack2;
4048 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4049 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
4050 auto embeddedViewParams3 = std::make_unique<flutter::EmbeddedViewParams>(
4051 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
4052 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4053 withParams:std::move(embeddedViewParams3)];
4054 [flutterPlatformViewsController
4061 [flutterPlatformViewsController
4065 @"viewType" : @"MockFlutterPlatformView"
4069 auto embeddedViewParams4 = std::make_unique<flutter::EmbeddedViewParams>(
4070 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack1);
4071 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4072 withParams:std::move(embeddedViewParams4)];
4073 [flutterPlatformViewsController
4079 UIView* maskView2 = childClippingView2.maskView;
4080 XCTAssertEqual(maskView1, maskView2);
4081 XCTAssertNotNil(childClippingView2.maskView);
4082 XCTAssertNil(childClippingView1.maskView);
4085 - (void)testDifferentClipMaskViewIsUsedForEachView {
4086 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4088 flutter::TaskRunners runners(
self.name.UTF8String,
4089 GetDefaultTaskRunner(),
4090 GetDefaultTaskRunner(),
4091 GetDefaultTaskRunner(),
4092 GetDefaultTaskRunner());
4095 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4096 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4099 flutterPlatformViewsController,
4102 std::make_shared<fml::SyncSwitch>());
4106 [flutterPlatformViewsController
4108 withId:@"MockFlutterPlatformView"
4113 [flutterPlatformViewsController
4117 @"viewType" : @"MockFlutterPlatformView"
4123 [flutterPlatformViewsController
4127 @"viewType" : @"MockFlutterPlatformView"
4136 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4137 flutterPlatformViewsController.
flutterView = flutterView;
4139 flutter::MutatorsStack stack1;
4142 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4143 stack1.PushTransform(screenScaleMatrix);
4145 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4146 stack1.PushClipRect(rect);
4148 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4149 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack1);
4151 flutter::MutatorsStack stack2;
4152 stack2.PushClipRect(rect);
4153 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4154 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
4156 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4157 withParams:std::move(embeddedViewParams1)];
4158 [flutterPlatformViewsController
4162 UIView* childClippingView1 = view1.superview.superview;
4164 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4165 withParams:std::move(embeddedViewParams2)];
4166 [flutterPlatformViewsController
4170 UIView* childClippingView2 = view2.superview.superview;
4171 UIView* maskView1 = childClippingView1.maskView;
4172 UIView* maskView2 = childClippingView2.maskView;
4173 XCTAssertNotEqual(maskView1, maskView2);
4176 - (void)testMaskViewUsesCAShapeLayerAsTheBackingLayer {
4177 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4179 flutter::TaskRunners runners(
self.name.UTF8String,
4180 GetDefaultTaskRunner(),
4181 GetDefaultTaskRunner(),
4182 GetDefaultTaskRunner(),
4183 GetDefaultTaskRunner());
4186 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4187 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4190 flutterPlatformViewsController,
4193 std::make_shared<fml::SyncSwitch>());
4197 [flutterPlatformViewsController
4199 withId:@"MockFlutterPlatformView"
4204 [flutterPlatformViewsController
4208 @"viewType" : @"MockFlutterPlatformView"
4216 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4217 flutterPlatformViewsController.
flutterView = flutterView;
4219 flutter::MutatorsStack stack1;
4222 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4223 stack1.PushTransform(screenScaleMatrix);
4225 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4226 stack1.PushClipRect(rect);
4228 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4229 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack1);
4231 flutter::MutatorsStack stack2;
4232 stack2.PushClipRect(rect);
4233 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4234 flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
4236 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4237 withParams:std::move(embeddedViewParams1)];
4238 [flutterPlatformViewsController
4244 UIView* maskView = childClippingView.maskView;
4245 XCTAssert([maskView.layer isKindOfClass:[CAShapeLayer
class]],
4246 @"Mask view must use CAShapeLayer as its backing layer.");
4254 - (BOOL)validateOneVisualEffectView:(UIView*)visualEffectView
4255 expectedFrame:(CGRect)frame
4256 inputRadius:(CGFloat)inputRadius {
4257 XCTAssertTrue(CGRectEqualToRect(visualEffectView.frame, frame));
4258 for (UIView* view in visualEffectView.subviews) {
4259 if (![NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
4262 XCTAssertEqual(view.layer.filters.count, 1u);
4263 NSObject* filter = view.layer.filters.firstObject;
4265 XCTAssertEqualObjects([filter valueForKey:
@"name"],
@"gaussianBlur");
4267 NSObject* inputRadiusInFilter = [filter valueForKey:@"inputRadius"];
4268 XCTAssertTrue([inputRadiusInFilter isKindOfClass:[NSNumber
class]] &&
4269 flutter::BlurRadiusEqualToBlurRadius(((NSNumber*)inputRadiusInFilter).floatValue,
4276 - (void)testDisposingViewInCompositionOrderDoNotCrash {
4277 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4279 flutter::TaskRunners runners(
self.name.UTF8String,
4280 GetDefaultTaskRunner(),
4281 GetDefaultTaskRunner(),
4282 GetDefaultTaskRunner(),
4283 GetDefaultTaskRunner());
4286 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4287 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4290 flutterPlatformViewsController,
4293 std::make_shared<fml::SyncSwitch>());
4298 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4299 flutterPlatformViewsController.
flutterView = flutterView;
4303 [flutterPlatformViewsController
4305 withId:@"MockFlutterPlatformView"
4310 [flutterPlatformViewsController
4314 @"viewType" : @"MockFlutterPlatformView"
4317 [flutterPlatformViewsController
4321 @"viewType" : @"MockFlutterPlatformView"
4328 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
4329 flutter::MutatorsStack stack;
4330 flutter::DlMatrix finalMatrix;
4331 auto embeddedViewParams0 = std::make_unique<flutter::EmbeddedViewParams>(
4332 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
4333 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4334 withParams:std::move(embeddedViewParams0)];
4336 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4337 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
4338 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4339 withParams:std::move(embeddedViewParams1)];
4343 XCTestExpectation* expectation = [
self expectationWithDescription:@"dispose call ended."];
4345 [expectation fulfill];
4348 [flutterPlatformViewsController
4351 [
self waitForExpectationsWithTimeout:30 handler:nil];
4353 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4354 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4355 nullptr, framebuffer_info,
4356 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4357 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4358 SkISize::Make(800, 600),
nullptr,
4360 XCTAssertTrue([flutterPlatformViewsController
4361 submitFrame:std::move(mock_surface)
4362 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4366 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:0]);
4367 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:1]);
4373 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
4374 flutter::MutatorsStack stack;
4375 flutter::DlMatrix finalMatrix;
4376 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4377 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
4378 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4379 withParams:std::move(embeddedViewParams1)];
4381 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4382 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4383 nullptr, framebuffer_info,
4384 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4385 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4386 SkISize::Make(800, 600),
nullptr,
true);
4387 XCTAssertTrue([flutterPlatformViewsController
4388 submitFrame:std::move(mock_surface)
4389 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4393 XCTAssertNil([flutterPlatformViewsController platformViewForId:0]);
4394 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:1]);
4397 - (void)testOnlyPlatformViewsAreRemovedWhenReset {
4398 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4400 flutter::TaskRunners runners(
self.name.UTF8String,
4401 GetDefaultTaskRunner(),
4402 GetDefaultTaskRunner(),
4403 GetDefaultTaskRunner(),
4404 GetDefaultTaskRunner());
4407 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4408 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4411 flutterPlatformViewsController,
4414 std::make_shared<fml::SyncSwitch>());
4418 [flutterPlatformViewsController
4420 withId:@"MockFlutterPlatformView"
4424 [flutterPlatformViewsController
4428 @"viewType" : @"MockFlutterPlatformView"
4434 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4435 flutterPlatformViewsController.
flutterView = flutterView;
4437 flutter::MutatorsStack stack;
4440 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4441 stack.PushTransform(screenScaleMatrix);
4443 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
4444 stack.PushTransform(translateMatrix);
4445 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
4447 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
4448 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
4450 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4451 withParams:std::move(embeddedViewParams)];
4453 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4454 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4455 nullptr, framebuffer_info,
4456 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4457 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4458 SkISize::Make(800, 600),
nullptr,
true);
4459 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
4460 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
4462 UIView* someView = [[UIView alloc] init];
4463 [flutterView addSubview:someView];
4465 [flutterPlatformViewsController
reset];
4466 XCTAssertEqual(flutterView.subviews.count, 1u);
4467 XCTAssertEqual(flutterView.subviews.firstObject, someView);
4470 - (void)testResetClearsPreviousCompositionOrder {
4471 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4473 flutter::TaskRunners runners(
self.name.UTF8String,
4474 GetDefaultTaskRunner(),
4475 GetDefaultTaskRunner(),
4476 GetDefaultTaskRunner(),
4477 GetDefaultTaskRunner());
4480 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4481 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4484 flutterPlatformViewsController,
4487 std::make_shared<fml::SyncSwitch>());
4491 [flutterPlatformViewsController
4493 withId:@"MockFlutterPlatformView"
4497 [flutterPlatformViewsController
4501 @"viewType" : @"MockFlutterPlatformView"
4507 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4508 flutterPlatformViewsController.
flutterView = flutterView;
4510 flutter::MutatorsStack stack;
4513 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4514 stack.PushTransform(screenScaleMatrix);
4516 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
4517 stack.PushTransform(translateMatrix);
4518 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
4520 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
4521 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
4523 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4524 withParams:std::move(embeddedViewParams)];
4526 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4527 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4528 nullptr, framebuffer_info,
4529 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4530 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4531 SkISize::Make(800, 600),
nullptr,
true);
4532 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
4533 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
4539 [flutterPlatformViewsController
reset];
4545 - (void)testNilPlatformViewDoesntCrash {
4546 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4548 flutter::TaskRunners runners(
self.name.UTF8String,
4549 GetDefaultTaskRunner(),
4550 GetDefaultTaskRunner(),
4551 GetDefaultTaskRunner(),
4552 GetDefaultTaskRunner());
4555 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4556 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4559 flutterPlatformViewsController,
4562 std::make_shared<fml::SyncSwitch>());
4566 [flutterPlatformViewsController
4568 withId:@"MockFlutterPlatformView"
4572 [flutterPlatformViewsController
4576 @"viewType" : @"MockFlutterPlatformView"
4582 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4583 flutterPlatformViewsController.
flutterView = flutterView;
4586 flutter::MutatorsStack stack;
4589 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4590 stack.PushTransform(screenScaleMatrix);
4592 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
4593 stack.PushTransform(translateMatrix);
4594 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
4596 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
4597 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
4599 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4600 withParams:std::move(embeddedViewParams)];
4602 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4603 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4604 nullptr, framebuffer_info,
4605 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4606 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4607 SkISize::Make(800, 600),
nullptr,
true);
4608 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
4609 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
4611 XCTAssertEqual(flutterView.subviews.count, 1u);
4614 - (void)testFlutterTouchInterceptingViewLinksToAccessibilityContainer {
4616 NSObject* container = [[NSObject alloc] init];
4617 [touchInteceptorView setFlutterAccessibilityContainer:container];
4618 XCTAssertEqualObjects([touchInteceptorView accessibilityContainer], container);
4621 - (void)testLayerPool {
4625 XCTAssertTrue(
engine.platformView !=
nullptr);
4626 auto ios_context =
engine.platformView->GetIosContext();
4631 pool.
CreateLayer(ios_context, MTLPixelFormatBGRA8Unorm, 1);
4632 XCTAssertEqual(pool.size(), 1u);
4633 pool.CreateLayer(ios_context, MTLPixelFormatBGRA8Unorm, 1);
4634 XCTAssertEqual(pool.size(), 2u);
4637 pool.RecycleLayers();
4638 XCTAssertEqual(pool.size(), 2u);
4641 auto unused_layers = pool.RemoveUnusedLayers();
4642 XCTAssertEqual(unused_layers.size(), 2u);
4643 XCTAssertEqual(pool.size(), 1u);
4646 - (void)testFlutterPlatformViewControllerSubmitFramePreservingFrameDamage {
4647 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4649 flutter::TaskRunners runners(
self.name.UTF8String,
4650 GetDefaultTaskRunner(),
4651 GetDefaultTaskRunner(),
4652 GetDefaultTaskRunner(),
4653 GetDefaultTaskRunner());
4656 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4657 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4660 flutterPlatformViewsController,
4663 std::make_shared<fml::SyncSwitch>());
4668 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4669 flutterPlatformViewsController.
flutterView = flutterView;
4673 [flutterPlatformViewsController
4675 withId:@"MockFlutterPlatformView"
4679 [flutterPlatformViewsController
4683 @"viewType" : @"MockFlutterPlatformView"
4688 [flutterPlatformViewsController
4692 @"viewType" : @"MockFlutterPlatformView"
4696 [flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
4697 flutter::MutatorsStack stack;
4698 flutter::DlMatrix finalMatrix;
4699 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4700 flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
4701 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4702 withParams:std::move(embeddedViewParams1)];
4704 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4705 flutter::ToSkMatrix(finalMatrix), SkSize::Make(500, 500), stack);
4706 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4707 withParams:std::move(embeddedViewParams2)];
4709 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4710 std::optional<flutter::SurfaceFrame::SubmitInfo> submit_info;
4711 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4712 nullptr, framebuffer_info,
4713 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4714 [&](
const flutter::SurfaceFrame& surface_frame) {
4715 submit_info = surface_frame.submit_info();
4718 SkISize::Make(800, 600),
nullptr,
4720 mock_surface->set_submit_info({
4721 .frame_damage = SkIRect::MakeWH(800, 600),
4722 .buffer_damage = SkIRect::MakeWH(400, 600),
4725 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
4726 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
4728 XCTAssertTrue(submit_info.has_value());
4729 XCTAssertEqual(*submit_info->frame_damage, SkIRect::MakeWH(800, 600));
4730 XCTAssertEqual(*submit_info->buffer_damage, SkIRect::MakeWH(400, 600));