5 #include "display_list/geometry/dl_geometry_types.h"
8 #import <OCMock/OCMock.h>
9 #import <UIKit/UIKit.h>
10 #import <WebKit/WebKit.h>
11 #import <XCTest/XCTest.h>
15 #include "flutter/display_list/effects/dl_image_filters.h"
16 #include "flutter/fml/synchronization/count_down_latch.h"
17 #include "flutter/fml/thread.h"
37 - (instancetype)init {
57 @property(nonatomic, strong) NSMutableArray<NSNumber*>* toggleHistory;
61 - (instancetype)init {
64 _toggleHistory = [NSMutableArray array];
68 - (void)setEnabled:(BOOL)enabled {
69 [
super setEnabled:enabled];
70 [
self.toggleHistory addObject:@(enabled)];
82 @property(nonatomic, strong) UIView* view;
83 @property(nonatomic, assign) BOOL viewCreated;
88 - (instancetype)init {
89 if (
self = [super init]) {
97 [
self checkViewCreatedOnce];
101 - (void)checkViewCreatedOnce {
105 self.viewCreated = YES;
114 : NSObject <FlutterPlatformViewFactory>
119 viewIdentifier:(int64_t)viewId
120 arguments:(
id _Nullable)args {
127 @property(nonatomic, strong) UIView* view;
128 @property(nonatomic, assign) BOOL viewCreated;
132 - (instancetype)init {
133 if (
self = [super init]) {
134 _view = [[WKWebView alloc] init];
142 [
self checkViewCreatedOnce];
146 - (void)checkViewCreatedOnce {
150 self.viewCreated = YES;
162 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
163 viewIdentifier:(int64_t)viewId
164 arguments:(
id _Nullable)args {
173 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
174 viewIdentifier:(int64_t)viewId
175 arguments:(
id _Nullable)args {
182 @property(nonatomic, strong) UIView* view;
183 @property(nonatomic, assign) BOOL viewCreated;
187 - (instancetype)init {
188 if (
self = [super init]) {
189 _view = [[UIView alloc] init];
190 [_view addSubview:[[WKWebView alloc] init]];
198 [
self checkViewCreatedOnce];
202 - (void)checkViewCreatedOnce {
206 self.viewCreated = YES;
218 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
219 viewIdentifier:(int64_t)viewId
220 arguments:(
id _Nullable)args {
226 @property(nonatomic, strong) UIView* view;
227 @property(nonatomic, assign) BOOL viewCreated;
231 - (instancetype)init {
232 if (
self = [super init]) {
233 _view = [[UIView alloc] init];
234 UIView* childView = [[UIView alloc] init];
235 [_view addSubview:childView];
236 [childView addSubview:[[WKWebView alloc] init]];
244 [
self checkViewCreatedOnce];
248 - (void)checkViewCreatedOnce {
252 self.viewCreated = YES;
257 : NSObject <FlutterPlatformViewFactory>
262 viewIdentifier:(int64_t)viewId
263 arguments:(
id _Nullable)args {
270 class FlutterPlatformViewsTestMockPlatformViewDelegate :
public PlatformView::Delegate {
272 void OnPlatformViewCreated(std::unique_ptr<Surface> surface)
override {}
273 void OnPlatformViewDestroyed()
override {}
274 void OnPlatformViewScheduleFrame()
override {}
275 void OnPlatformViewAddView(int64_t view_id,
276 const ViewportMetrics& viewport_metrics,
277 AddViewCallback callback)
override {}
278 void OnPlatformViewRemoveView(int64_t view_id, RemoveViewCallback callback)
override {}
279 void OnPlatformViewSendViewFocusEvent(
const ViewFocusEvent& event)
override {};
280 void OnPlatformViewSetNextFrameCallback(
const fml::closure& closure)
override {}
281 void OnPlatformViewSetViewportMetrics(int64_t view_id,
const ViewportMetrics& metrics)
override {}
282 const flutter::Settings& OnPlatformViewGetSettings()
const override {
return settings_; }
283 void OnPlatformViewDispatchPlatformMessage(std::unique_ptr<PlatformMessage> message)
override {}
284 void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet)
override {
286 void OnPlatformViewDispatchSemanticsAction(int64_t view_id,
288 SemanticsAction action,
289 fml::MallocMapping args)
override {}
290 void OnPlatformViewSetSemanticsEnabled(
bool enabled)
override {}
291 void OnPlatformViewSetAccessibilityFeatures(int32_t flags)
override {}
292 void OnPlatformViewRegisterTexture(std::shared_ptr<Texture> texture)
override {}
293 void OnPlatformViewUnregisterTexture(int64_t
texture_id)
override {}
294 void OnPlatformViewMarkTextureFrameAvailable(int64_t
texture_id)
override {}
296 void LoadDartDeferredLibrary(intptr_t loading_unit_id,
297 std::unique_ptr<const fml::Mapping> snapshot_data,
298 std::unique_ptr<const fml::Mapping> snapshot_instructions)
override {
300 void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
301 const std::string error_message,
302 bool transient)
override {}
303 void UpdateAssetResolverByType(std::unique_ptr<flutter::AssetResolver> updated_asset_resolver,
304 flutter::AssetResolver::AssetResolverType type)
override {}
309 BOOL BlurRadiusEqualToBlurRadius(CGFloat radius1, CGFloat radius2) {
310 const CGFloat epsilon = 0.01;
311 return std::abs(radius1 - radius2) < epsilon;
323 fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
324 fml::MessageLoop::EnsureInitializedForCurrentThread();
325 return fml::MessageLoop::GetCurrent().GetTaskRunner();
329 - (void)testFlutterViewOnlyCreateOnceInOneFrame {
330 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
332 flutter::TaskRunners runners(
self.name.UTF8String,
333 GetDefaultTaskRunner(),
334 GetDefaultTaskRunner(),
335 GetDefaultTaskRunner(),
336 GetDefaultTaskRunner());
339 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
340 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
343 flutterPlatformViewsController,
346 std::make_shared<fml::SyncSwitch>());
350 [flutterPlatformViewsController
352 withId:@"MockFlutterPlatformView"
356 [flutterPlatformViewsController
360 @"viewType" : @"MockFlutterPlatformView"
363 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
364 flutterPlatformViewsController.
flutterView = flutterView;
366 flutter::MutatorsStack stack;
368 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
369 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
370 stack.PushTransform(screenScaleMatrix);
372 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
373 stack.PushTransform(translateMatrix);
374 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
376 auto embeddedViewParams =
377 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
379 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
380 withParams:std::move(embeddedViewParams)];
384 [flutterPlatformViewsController
reset];
387 - (void)testCanCreatePlatformViewWithoutFlutterView {
388 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
390 flutter::TaskRunners runners(
self.name.UTF8String,
391 GetDefaultTaskRunner(),
392 GetDefaultTaskRunner(),
393 GetDefaultTaskRunner(),
394 GetDefaultTaskRunner());
397 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
398 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
401 flutterPlatformViewsController,
404 std::make_shared<fml::SyncSwitch>());
408 [flutterPlatformViewsController
410 withId:@"MockFlutterPlatformView"
414 [flutterPlatformViewsController
418 @"viewType" : @"MockFlutterPlatformView"
425 - (void)testChildClippingViewHitTests {
428 UIView* childView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
429 [childClippingView addSubview:childView];
431 XCTAssertFalse([childClippingView pointInside:CGPointMake(50, 50) withEvent:nil]);
432 XCTAssertFalse([childClippingView pointInside:CGPointMake(99, 100) withEvent:nil]);
433 XCTAssertFalse([childClippingView pointInside:CGPointMake(100, 99) withEvent:nil]);
434 XCTAssertFalse([childClippingView pointInside:CGPointMake(201, 200) withEvent:nil]);
435 XCTAssertFalse([childClippingView pointInside:CGPointMake(200, 201) withEvent:nil]);
436 XCTAssertFalse([childClippingView pointInside:CGPointMake(99, 200) withEvent:nil]);
437 XCTAssertFalse([childClippingView pointInside:CGPointMake(200, 299) withEvent:nil]);
439 XCTAssertTrue([childClippingView pointInside:CGPointMake(150, 150) withEvent:nil]);
440 XCTAssertTrue([childClippingView pointInside:CGPointMake(100, 100) withEvent:nil]);
441 XCTAssertTrue([childClippingView pointInside:CGPointMake(199, 100) withEvent:nil]);
442 XCTAssertTrue([childClippingView pointInside:CGPointMake(100, 199) withEvent:nil]);
443 XCTAssertTrue([childClippingView pointInside:CGPointMake(199, 199) withEvent:nil]);
446 - (void)testReleasesBackdropFilterSubviewsOnChildClippingViewDealloc {
447 __weak NSMutableArray<UIVisualEffectView*>* weakBackdropFilterSubviews = nil;
448 __weak UIVisualEffectView* weakVisualEffectView1 = nil;
449 __weak UIVisualEffectView* weakVisualEffectView2 = nil;
453 UIVisualEffectView* visualEffectView1 = [[UIVisualEffectView alloc]
454 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
455 weakVisualEffectView1 = visualEffectView1;
460 isRoundedSuperellipse:NO
461 visualEffectView:visualEffectView1];
466 UIVisualEffectView* visualEffectView2 = [[UIVisualEffectView alloc]
467 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
468 weakVisualEffectView2 = visualEffectView2;
473 isRoundedSuperellipse:NO
474 visualEffectView:visualEffectView2];
478 XCTAssertNotNil(weakBackdropFilterSubviews);
481 XCTAssertNil(weakBackdropFilterSubviews);
482 XCTAssertNil(weakVisualEffectView1);
483 XCTAssertNil(weakVisualEffectView2);
486 - (void)testApplyBackdropFilter {
487 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
489 flutter::TaskRunners runners(
self.name.UTF8String,
490 GetDefaultTaskRunner(),
491 GetDefaultTaskRunner(),
492 GetDefaultTaskRunner(),
493 GetDefaultTaskRunner());
496 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
497 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
500 flutterPlatformViewsController,
503 std::make_shared<fml::SyncSwitch>());
507 [flutterPlatformViewsController
509 withId:@"MockFlutterPlatformView"
513 [flutterPlatformViewsController
517 @"viewType" : @"MockFlutterPlatformView"
523 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
524 flutterPlatformViewsController.
flutterView = flutterView;
526 flutter::MutatorsStack stack;
528 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
529 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
530 stack.PushTransform(screenScaleMatrix);
532 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
533 stack.PushBackdropFilter(filter,
534 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
536 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
537 screenScaleMatrix, flutter::DlSize(10, 10), stack);
539 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
540 withParams:std::move(embeddedViewParams)];
541 [flutterPlatformViewsController
547 [flutterView addSubview:childClippingView];
549 [flutterView setNeedsLayout];
550 [flutterView layoutIfNeeded];
553 NSUInteger numberOfExpectedVisualEffectView = 0;
554 for (UIView* subview in childClippingView.subviews) {
555 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
558 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
559 if ([
self validateOneVisualEffectView:subview
560 expectedFrame:CGRectMake(0, 0, 10, 10)
562 numberOfExpectedVisualEffectView++;
565 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
568 - (void)testApplyBackdropFilterWithCorrectFrame {
569 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
571 flutter::TaskRunners runners(
self.name.UTF8String,
572 GetDefaultTaskRunner(),
573 GetDefaultTaskRunner(),
574 GetDefaultTaskRunner(),
575 GetDefaultTaskRunner());
578 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
579 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
582 flutterPlatformViewsController,
585 std::make_shared<fml::SyncSwitch>());
589 [flutterPlatformViewsController
591 withId:@"MockFlutterPlatformView"
595 [flutterPlatformViewsController
599 @"viewType" : @"MockFlutterPlatformView"
605 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
606 flutterPlatformViewsController.
flutterView = flutterView;
608 flutter::MutatorsStack stack;
610 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
611 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
612 stack.PushTransform(screenScaleMatrix);
614 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
615 stack.PushBackdropFilter(filter,
616 flutter::DlRect::MakeXYWH(0, 0, screenScale * 8, screenScale * 8));
618 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
619 screenScaleMatrix, flutter::DlSize(5, 10), stack);
621 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
622 withParams:std::move(embeddedViewParams)];
623 [flutterPlatformViewsController
629 [flutterView addSubview:childClippingView];
631 [flutterView setNeedsLayout];
632 [flutterView layoutIfNeeded];
635 NSUInteger numberOfExpectedVisualEffectView = 0;
636 for (UIView* subview in childClippingView.subviews) {
637 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
640 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
641 if ([
self validateOneVisualEffectView:subview
642 expectedFrame:CGRectMake(0, 0, 5, 8)
644 numberOfExpectedVisualEffectView++;
647 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
650 - (void)testApplyMultipleBackdropFilters {
651 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
653 flutter::TaskRunners runners(
self.name.UTF8String,
654 GetDefaultTaskRunner(),
655 GetDefaultTaskRunner(),
656 GetDefaultTaskRunner(),
657 GetDefaultTaskRunner());
660 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
661 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
664 flutterPlatformViewsController,
667 std::make_shared<fml::SyncSwitch>());
671 [flutterPlatformViewsController
673 withId:@"MockFlutterPlatformView"
677 [flutterPlatformViewsController
681 @"viewType" : @"MockFlutterPlatformView"
687 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
688 flutterPlatformViewsController.
flutterView = flutterView;
690 flutter::MutatorsStack stack;
692 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
693 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
694 stack.PushTransform(screenScaleMatrix);
696 for (
int i = 0; i < 50; i++) {
697 auto filter = flutter::DlBlurImageFilter::Make(i, 2, flutter::DlTileMode::kClamp);
698 stack.PushBackdropFilter(filter,
699 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
702 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
703 screenScaleMatrix, flutter::DlSize(20, 20), stack);
705 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
706 withParams:std::move(embeddedViewParams)];
707 [flutterPlatformViewsController
713 [flutterView addSubview:childClippingView];
715 [flutterView setNeedsLayout];
716 [flutterView layoutIfNeeded];
718 NSUInteger numberOfExpectedVisualEffectView = 0;
719 for (UIView* subview in childClippingView.subviews) {
720 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
723 XCTAssertLessThan(numberOfExpectedVisualEffectView, 50u);
724 if ([
self validateOneVisualEffectView:subview
725 expectedFrame:CGRectMake(0, 0, 10, 10)
726 inputRadius:(CGFloat)numberOfExpectedVisualEffectView]) {
727 numberOfExpectedVisualEffectView++;
730 XCTAssertEqual(numberOfExpectedVisualEffectView, (NSUInteger)numberOfExpectedVisualEffectView);
733 - (void)testAddBackdropFilters {
734 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
736 flutter::TaskRunners runners(
self.name.UTF8String,
737 GetDefaultTaskRunner(),
738 GetDefaultTaskRunner(),
739 GetDefaultTaskRunner(),
740 GetDefaultTaskRunner());
743 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
744 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
747 flutterPlatformViewsController,
750 std::make_shared<fml::SyncSwitch>());
754 [flutterPlatformViewsController
756 withId:@"MockFlutterPlatformView"
760 [flutterPlatformViewsController
764 @"viewType" : @"MockFlutterPlatformView"
770 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
771 flutterPlatformViewsController.
flutterView = flutterView;
773 flutter::MutatorsStack stack;
775 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
776 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
777 stack.PushTransform(screenScaleMatrix);
779 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
780 stack.PushBackdropFilter(filter,
781 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
783 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
784 screenScaleMatrix, flutter::DlSize(10, 10), stack);
786 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
787 withParams:std::move(embeddedViewParams)];
788 [flutterPlatformViewsController
794 [flutterView addSubview:childClippingView];
796 [flutterView setNeedsLayout];
797 [flutterView layoutIfNeeded];
799 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
800 for (UIView* subview in childClippingView.subviews) {
801 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
804 XCTAssertLessThan(originalVisualEffectViews.count, 1u);
805 if ([
self validateOneVisualEffectView:subview
806 expectedFrame:CGRectMake(0, 0, 10, 10)
807 inputRadius:(CGFloat)5]) {
808 [originalVisualEffectViews addObject:subview];
811 XCTAssertEqual(originalVisualEffectViews.count, 1u);
816 flutter::MutatorsStack stack2;
818 stack2.PushTransform(screenScaleMatrix);
820 for (
int i = 0; i < 2; i++) {
821 stack2.PushBackdropFilter(filter,
822 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
825 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
826 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
828 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
829 withParams:std::move(embeddedViewParams)];
830 [flutterPlatformViewsController
834 [flutterView setNeedsLayout];
835 [flutterView layoutIfNeeded];
837 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
838 for (UIView* subview in childClippingView.subviews) {
839 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
842 XCTAssertLessThan(newVisualEffectViews.count, 2u);
844 if ([
self validateOneVisualEffectView:subview
845 expectedFrame:CGRectMake(0, 0, 10, 10)
846 inputRadius:(CGFloat)5]) {
847 [newVisualEffectViews addObject:subview];
850 XCTAssertEqual(newVisualEffectViews.count, 2u);
851 for (NSUInteger i = 0; i < originalVisualEffectViews.count; i++) {
852 UIView* originalView = originalVisualEffectViews[i];
853 UIView* newView = newVisualEffectViews[i];
855 XCTAssertEqual(originalView, newView);
856 id mockOrignalView = OCMPartialMock(originalView);
857 OCMReject([mockOrignalView removeFromSuperview]);
858 [mockOrignalView stopMocking];
862 - (void)testRemoveBackdropFilters {
863 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
865 flutter::TaskRunners runners(
self.name.UTF8String,
866 GetDefaultTaskRunner(),
867 GetDefaultTaskRunner(),
868 GetDefaultTaskRunner(),
869 GetDefaultTaskRunner());
872 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
873 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
876 flutterPlatformViewsController,
879 std::make_shared<fml::SyncSwitch>());
883 [flutterPlatformViewsController
885 withId:@"MockFlutterPlatformView"
889 [flutterPlatformViewsController
893 @"viewType" : @"MockFlutterPlatformView"
899 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
900 flutterPlatformViewsController.
flutterView = flutterView;
902 flutter::MutatorsStack stack;
904 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
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 screenScaleMatrix, flutter::DlSize(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 screenScaleMatrix, flutter::DlSize(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 screenScaleMatrix, flutter::DlSize(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"
1055 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1056 flutterPlatformViewsController.
flutterView = flutterView;
1058 flutter::MutatorsStack stack;
1060 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1061 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1062 stack.PushTransform(screenScaleMatrix);
1064 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1065 for (
int i = 0; i < 5; i++) {
1066 stack.PushBackdropFilter(filter,
1067 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1070 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1071 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1073 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1074 withParams:std::move(embeddedViewParams)];
1075 [flutterPlatformViewsController
1081 [flutterView addSubview:childClippingView];
1083 [flutterView setNeedsLayout];
1084 [flutterView layoutIfNeeded];
1086 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
1087 for (UIView* subview in childClippingView.subviews) {
1088 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1091 XCTAssertLessThan(originalVisualEffectViews.count, 5u);
1092 if ([
self validateOneVisualEffectView:subview
1093 expectedFrame:CGRectMake(0, 0, 10, 10)
1094 inputRadius:(CGFloat)5]) {
1095 [originalVisualEffectViews addObject:subview];
1101 flutter::MutatorsStack stack2;
1103 stack2.PushTransform(screenScaleMatrix);
1105 for (
int i = 0; i < 5; i++) {
1107 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1109 stack2.PushBackdropFilter(
1110 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1114 stack2.PushBackdropFilter(filter,
1115 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1118 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1119 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1121 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1122 withParams:std::move(embeddedViewParams)];
1123 [flutterPlatformViewsController
1127 [flutterView setNeedsLayout];
1128 [flutterView layoutIfNeeded];
1130 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
1131 for (UIView* subview in childClippingView.subviews) {
1132 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1135 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1136 CGFloat expectInputRadius = 5;
1137 if (newVisualEffectViews.count == 3) {
1138 expectInputRadius = 2;
1140 if ([
self validateOneVisualEffectView:subview
1141 expectedFrame:CGRectMake(0, 0, 10, 10)
1142 inputRadius:expectInputRadius]) {
1143 [newVisualEffectViews addObject:subview];
1146 XCTAssertEqual(newVisualEffectViews.count, 5u);
1147 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1148 UIView* newView = newVisualEffectViews[i];
1149 id mockNewView = OCMPartialMock(newView);
1150 UIView* originalView = originalVisualEffectViews[i];
1152 XCTAssertEqual(originalView, newView);
1153 OCMReject([mockNewView removeFromSuperview]);
1154 [mockNewView stopMocking];
1156 [newVisualEffectViews removeAllObjects];
1160 for (
int i = 0; i < 5; i++) {
1164 for (
int i = 0; i < 5; i++) {
1166 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1167 stack2.PushBackdropFilter(
1168 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1172 stack2.PushBackdropFilter(filter,
1173 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1176 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1177 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1179 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1180 withParams:std::move(embeddedViewParams)];
1181 [flutterPlatformViewsController
1185 [flutterView setNeedsLayout];
1186 [flutterView layoutIfNeeded];
1188 for (UIView* subview in childClippingView.subviews) {
1189 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1192 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1193 CGFloat expectInputRadius = 5;
1194 if (newVisualEffectViews.count == 0) {
1195 expectInputRadius = 2;
1197 if ([
self validateOneVisualEffectView:subview
1198 expectedFrame:CGRectMake(0, 0, 10, 10)
1199 inputRadius:expectInputRadius]) {
1200 [newVisualEffectViews addObject:subview];
1203 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1204 UIView* newView = newVisualEffectViews[i];
1205 id mockNewView = OCMPartialMock(newView);
1206 UIView* originalView = originalVisualEffectViews[i];
1208 XCTAssertEqual(originalView, newView);
1209 OCMReject([mockNewView removeFromSuperview]);
1210 [mockNewView stopMocking];
1212 [newVisualEffectViews removeAllObjects];
1216 for (
int i = 0; i < 5; i++) {
1220 for (
int i = 0; i < 5; i++) {
1222 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1223 stack2.PushBackdropFilter(
1224 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1228 stack2.PushBackdropFilter(filter,
1229 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1232 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1233 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1235 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1236 withParams:std::move(embeddedViewParams)];
1237 [flutterPlatformViewsController
1241 [flutterView setNeedsLayout];
1242 [flutterView layoutIfNeeded];
1244 for (UIView* subview in childClippingView.subviews) {
1245 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1248 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1249 CGFloat expectInputRadius = 5;
1250 if (newVisualEffectViews.count == 4) {
1251 expectInputRadius = 2;
1253 if ([
self validateOneVisualEffectView:subview
1254 expectedFrame:CGRectMake(0, 0, 10, 10)
1255 inputRadius:expectInputRadius]) {
1256 [newVisualEffectViews addObject:subview];
1259 XCTAssertEqual(newVisualEffectViews.count, 5u);
1261 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1262 UIView* newView = newVisualEffectViews[i];
1263 id mockNewView = OCMPartialMock(newView);
1264 UIView* originalView = originalVisualEffectViews[i];
1266 XCTAssertEqual(originalView, newView);
1267 OCMReject([mockNewView removeFromSuperview]);
1268 [mockNewView stopMocking];
1270 [newVisualEffectViews removeAllObjects];
1274 for (
int i = 0; i < 5; i++) {
1278 for (
int i = 0; i < 5; i++) {
1279 auto filter2 = flutter::DlBlurImageFilter::Make(i, 2, flutter::DlTileMode::kClamp);
1281 stack2.PushBackdropFilter(filter2,
1282 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1285 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1286 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1288 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1289 withParams:std::move(embeddedViewParams)];
1290 [flutterPlatformViewsController
1294 [flutterView setNeedsLayout];
1295 [flutterView layoutIfNeeded];
1297 for (UIView* subview in childClippingView.subviews) {
1298 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1301 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1302 if ([
self validateOneVisualEffectView:subview
1303 expectedFrame:CGRectMake(0, 0, 10, 10)
1304 inputRadius:(CGFloat)newVisualEffectViews.count]) {
1305 [newVisualEffectViews addObject:subview];
1308 XCTAssertEqual(newVisualEffectViews.count, 5u);
1310 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1311 UIView* newView = newVisualEffectViews[i];
1312 id mockNewView = OCMPartialMock(newView);
1313 UIView* originalView = originalVisualEffectViews[i];
1315 XCTAssertEqual(originalView, newView);
1316 OCMReject([mockNewView removeFromSuperview]);
1317 [mockNewView stopMocking];
1319 [newVisualEffectViews removeAllObjects];
1322 - (void)testApplyBackdropFilterNotDlBlurImageFilter {
1323 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1325 flutter::TaskRunners runners(
self.name.UTF8String,
1326 GetDefaultTaskRunner(),
1327 GetDefaultTaskRunner(),
1328 GetDefaultTaskRunner(),
1329 GetDefaultTaskRunner());
1332 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1333 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1336 flutterPlatformViewsController,
1339 std::make_shared<fml::SyncSwitch>());
1343 [flutterPlatformViewsController
1345 withId:@"MockFlutterPlatformView"
1349 [flutterPlatformViewsController
1353 @"viewType" : @"MockFlutterPlatformView"
1359 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1360 flutterPlatformViewsController.
flutterView = flutterView;
1362 flutter::MutatorsStack stack;
1364 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1365 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1366 stack.PushTransform(screenScaleMatrix);
1368 auto dilateFilter = flutter::DlDilateImageFilter::Make(5, 2);
1369 stack.PushBackdropFilter(dilateFilter, flutter::DlRect());
1371 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1372 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1374 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1375 withParams:std::move(embeddedViewParams)];
1376 [flutterPlatformViewsController
1383 [flutterView addSubview:childClippingView];
1385 [flutterView setNeedsLayout];
1386 [flutterView layoutIfNeeded];
1388 NSUInteger numberOfExpectedVisualEffectView = 0;
1389 for (UIView* subview in childClippingView.subviews) {
1390 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1391 numberOfExpectedVisualEffectView++;
1394 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1398 flutter::MutatorsStack stack2;
1400 stack2.PushTransform(screenScaleMatrix);
1402 auto blurFilter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1404 for (
int i = 0; i < 5; i++) {
1406 stack2.PushBackdropFilter(
1407 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1411 stack2.PushBackdropFilter(blurFilter,
1412 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1415 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1416 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1418 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1419 withParams:std::move(embeddedViewParams)];
1420 [flutterPlatformViewsController
1424 [flutterView setNeedsLayout];
1425 [flutterView layoutIfNeeded];
1427 numberOfExpectedVisualEffectView = 0;
1428 for (UIView* subview in childClippingView.subviews) {
1429 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1432 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1433 if ([
self validateOneVisualEffectView:subview
1434 expectedFrame:CGRectMake(0, 0, 10, 10)
1435 inputRadius:(CGFloat)5]) {
1436 numberOfExpectedVisualEffectView++;
1439 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1443 for (
int i = 0; i < 5; i++) {
1447 for (
int i = 0; i < 5; i++) {
1449 stack2.PushBackdropFilter(
1450 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1454 stack2.PushBackdropFilter(blurFilter,
1455 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1458 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1459 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1461 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1462 withParams:std::move(embeddedViewParams)];
1463 [flutterPlatformViewsController
1467 [flutterView setNeedsLayout];
1468 [flutterView layoutIfNeeded];
1470 numberOfExpectedVisualEffectView = 0;
1471 for (UIView* subview in childClippingView.subviews) {
1472 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1475 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1476 if ([
self validateOneVisualEffectView:subview
1477 expectedFrame:CGRectMake(0, 0, 10, 10)
1478 inputRadius:(CGFloat)5]) {
1479 numberOfExpectedVisualEffectView++;
1482 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1486 for (
int i = 0; i < 5; i++) {
1490 for (
int i = 0; i < 5; i++) {
1492 stack2.PushBackdropFilter(
1493 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1497 stack2.PushBackdropFilter(blurFilter,
1498 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1501 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1502 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1504 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1505 withParams:std::move(embeddedViewParams)];
1506 [flutterPlatformViewsController
1510 [flutterView setNeedsLayout];
1511 [flutterView layoutIfNeeded];
1513 numberOfExpectedVisualEffectView = 0;
1514 for (UIView* subview in childClippingView.subviews) {
1515 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1518 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1519 if ([
self validateOneVisualEffectView:subview
1520 expectedFrame:CGRectMake(0, 0, 10, 10)
1521 inputRadius:(CGFloat)5]) {
1522 numberOfExpectedVisualEffectView++;
1525 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1529 for (
int i = 0; i < 5; i++) {
1533 for (
int i = 0; i < 5; i++) {
1534 stack2.PushBackdropFilter(dilateFilter,
1535 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1538 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1539 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1541 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1542 withParams:std::move(embeddedViewParams)];
1543 [flutterPlatformViewsController
1547 [flutterView setNeedsLayout];
1548 [flutterView layoutIfNeeded];
1550 numberOfExpectedVisualEffectView = 0;
1551 for (UIView* subview in childClippingView.subviews) {
1552 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1553 numberOfExpectedVisualEffectView++;
1556 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1559 - (void)testApplyBackdropFilterCorrectAPI {
1564 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
1565 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1570 isRoundedSuperellipse:NO
1571 visualEffectView:visualEffectView];
1572 XCTAssertNotNil(platformViewFilter);
1575 - (void)testApplyBackdropFilterAPIChangedInvalidUIVisualEffectView {
1577 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc] init];
1582 isRoundedSuperellipse:NO
1583 visualEffectView:visualEffectView];
1584 XCTAssertNil(platformViewFilter);
1587 - (void)testApplyBackdropFilterAPIChangedNoGaussianBlurFilter {
1589 UIVisualEffectView* editedUIVisualEffectView = [[UIVisualEffectView alloc]
1590 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1591 NSArray* subviews = editedUIVisualEffectView.subviews;
1592 for (UIView* view in subviews) {
1593 if ([NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
1594 for (CIFilter* filter in view.layer.filters) {
1595 if ([[filter valueForKey:
@"name"] isEqual:
@"gaussianBlur"]) {
1596 [filter setValue:@"notGaussianBlur" forKey:@"name"];
1607 isRoundedSuperellipse:NO
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"];
1633 isRoundedSuperellipse:NO
1634 visualEffectView:editedUIVisualEffectView];
1635 XCTAssertNil(platformViewFilter);
1638 - (void)testApplyBackdropFilterRespectsClipRRect {
1639 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1641 flutter::TaskRunners runners(
self.name.UTF8String,
1642 GetDefaultTaskRunner(),
1643 GetDefaultTaskRunner(),
1644 GetDefaultTaskRunner(),
1645 GetDefaultTaskRunner());
1648 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1649 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1652 flutterPlatformViewsController,
1655 std::make_shared<fml::SyncSwitch>());
1659 [flutterPlatformViewsController
1661 withId:@"MockFlutterPlatformView"
1665 [flutterPlatformViewsController
1669 @"viewType" : @"MockFlutterPlatformView"
1675 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1676 flutterPlatformViewsController.
flutterView = flutterView;
1678 flutter::MutatorsStack stack;
1680 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1681 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1682 stack.PushTransform(screenScaleMatrix);
1685 auto clipRect = flutter::DlRect::MakeXYWH(2, 2, 6, 6);
1686 auto clipRRect = flutter::DlRoundRect::MakeRectXY(clipRect, 3, 3);
1687 stack.PushPlatformViewClipRRect(clipRRect);
1690 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1691 stack.PushBackdropFilter(filter,
1692 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1694 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1695 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1697 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1698 withParams:std::move(embeddedViewParams)];
1699 [flutterPlatformViewsController
1705 [flutterView addSubview:childClippingView];
1707 [flutterView setNeedsLayout];
1708 [flutterView layoutIfNeeded];
1711 XCTAssertEqual(filters.count, 1u);
1713 UIVisualEffectView* visualEffectView = filters[0];
1714 auto radii = clipRRect.GetRadii();
1716 XCTAssertEqual(visualEffectView.layer.cornerRadius, radii.top_left.width);
1717 XCTAssertEqual(visualEffectView.layer.cornerCurve, kCACornerCurveCircular);
1720 - (void)testApplyBackdropFilterRespectsClipRSuperellipse {
1721 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1723 flutter::TaskRunners runners(
self.name.UTF8String,
1724 GetDefaultTaskRunner(),
1725 GetDefaultTaskRunner(),
1726 GetDefaultTaskRunner(),
1727 GetDefaultTaskRunner());
1730 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1731 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1734 flutterPlatformViewsController,
1737 std::make_shared<fml::SyncSwitch>());
1741 [flutterPlatformViewsController
1743 withId:@"MockFlutterPlatformView"
1747 [flutterPlatformViewsController
1751 @"viewType" : @"MockFlutterPlatformView"
1757 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1758 flutterPlatformViewsController.
flutterView = flutterView;
1760 flutter::MutatorsStack stack;
1762 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1763 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1764 stack.PushTransform(screenScaleMatrix);
1767 auto clipRect = flutter::DlRect::MakeXYWH(2, 2, 6, 6);
1768 auto clipRSE = flutter::DlRoundSuperellipse::MakeRectXY(clipRect, 3, 3);
1769 stack.PushPlatformViewClipRSuperellipse(clipRSE);
1772 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1773 stack.PushBackdropFilter(filter,
1774 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1776 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1777 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1779 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1780 withParams:std::move(embeddedViewParams)];
1781 [flutterPlatformViewsController
1787 [flutterView addSubview:childClippingView];
1789 [flutterView setNeedsLayout];
1790 [flutterView layoutIfNeeded];
1793 XCTAssertEqual(filters.count, 1u);
1795 UIVisualEffectView* visualEffectView = filters[0];
1796 auto radii = clipRSE.GetRadii();
1798 XCTAssertEqual(visualEffectView.layer.cornerRadius, radii.top_left.width);
1799 XCTAssertEqual(visualEffectView.layer.cornerCurve, kCACornerCurveContinuous);
1802 - (void)testBackdropFilterVisualEffectSubviewBackgroundColor {
1803 __weak UIVisualEffectView* weakVisualEffectView;
1806 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
1807 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1808 weakVisualEffectView = visualEffectView;
1813 isRoundedSuperellipse:NO
1814 visualEffectView:visualEffectView];
1815 CGColorRef visualEffectSubviewBackgroundColor = nil;
1816 for (UIView* view in [platformViewFilter backdropFilterView].subviews) {
1817 if ([NSStringFromClass([view
class]) hasSuffix:
@"VisualEffectSubview"]) {
1818 visualEffectSubviewBackgroundColor = view.layer.backgroundColor;
1822 CGColorEqualToColor(visualEffectSubviewBackgroundColor, UIColor.clearColor.CGColor));
1824 XCTAssertNil(weakVisualEffectView);
1827 - (void)testCompositePlatformView {
1828 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1830 flutter::TaskRunners runners(
self.name.UTF8String,
1831 GetDefaultTaskRunner(),
1832 GetDefaultTaskRunner(),
1833 GetDefaultTaskRunner(),
1834 GetDefaultTaskRunner());
1837 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1838 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1841 flutterPlatformViewsController,
1844 std::make_shared<fml::SyncSwitch>());
1848 [flutterPlatformViewsController
1850 withId:@"MockFlutterPlatformView"
1854 [flutterPlatformViewsController
1858 @"viewType" : @"MockFlutterPlatformView"
1864 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
1865 flutterPlatformViewsController.
flutterView = flutterView;
1867 flutter::MutatorsStack stack;
1869 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1870 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1871 stack.PushTransform(screenScaleMatrix);
1873 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
1874 stack.PushTransform(translateMatrix);
1875 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
1877 auto embeddedViewParams =
1878 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
1880 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1881 withParams:std::move(embeddedViewParams)];
1882 [flutterPlatformViewsController
1886 CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
1887 toView:flutterView];
1888 XCTAssertTrue(CGRectEqualToRect(platformViewRectInFlutterView, CGRectMake(100, 100, 300, 300)));
1891 - (void)testBackdropFilterCorrectlyPushedAndReset {
1892 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1894 flutter::TaskRunners runners(
self.name.UTF8String,
1895 GetDefaultTaskRunner(),
1896 GetDefaultTaskRunner(),
1897 GetDefaultTaskRunner(),
1898 GetDefaultTaskRunner());
1901 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1902 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1905 flutterPlatformViewsController,
1908 std::make_shared<fml::SyncSwitch>());
1912 [flutterPlatformViewsController
1914 withId:@"MockFlutterPlatformView"
1918 [flutterPlatformViewsController
1922 @"viewType" : @"MockFlutterPlatformView"
1928 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1929 flutterPlatformViewsController.
flutterView = flutterView;
1931 flutter::MutatorsStack stack;
1933 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1934 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1935 stack.PushTransform(screenScaleMatrix);
1937 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1938 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1940 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(0, 0)];
1941 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1942 withParams:std::move(embeddedViewParams)];
1944 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp, std::nullopt);
1945 [flutterPlatformViewsController
1946 pushFilterToVisitedPlatformViews:filter
1947 withRect:flutter::DlRect::MakeXYWH(0, 0, screenScale * 10,
1949 [flutterPlatformViewsController
1955 [flutterView addSubview:childClippingView];
1957 [flutterView setNeedsLayout];
1958 [flutterView layoutIfNeeded];
1961 NSUInteger numberOfExpectedVisualEffectView = 0;
1962 for (UIView* subview in childClippingView.subviews) {
1963 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1966 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
1967 if ([
self validateOneVisualEffectView:subview
1968 expectedFrame:CGRectMake(0, 0, 10, 10)
1970 numberOfExpectedVisualEffectView++;
1973 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
1976 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
1977 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1978 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(0, 0)];
1979 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1980 withParams:std::move(embeddedViewParams2)];
1981 [flutterPlatformViewsController
1987 [flutterView setNeedsLayout];
1988 [flutterView layoutIfNeeded];
1990 numberOfExpectedVisualEffectView = 0;
1991 for (UIView* subview in childClippingView.subviews) {
1992 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1995 numberOfExpectedVisualEffectView++;
1997 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
2000 - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
2001 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2003 flutter::TaskRunners runners(
self.name.UTF8String,
2004 GetDefaultTaskRunner(),
2005 GetDefaultTaskRunner(),
2006 GetDefaultTaskRunner(),
2007 GetDefaultTaskRunner());
2010 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2011 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2014 flutterPlatformViewsController,
2017 std::make_shared<fml::SyncSwitch>());
2021 [flutterPlatformViewsController
2023 withId:@"MockFlutterPlatformView"
2027 [flutterPlatformViewsController
2031 @"viewType" : @"MockFlutterPlatformView"
2037 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
2038 flutterPlatformViewsController.
flutterView = flutterView;
2040 flutter::MutatorsStack stack;
2042 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2043 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2044 stack.PushTransform(screenScaleMatrix);
2046 flutter::DlMatrix rotateMatrix = flutter::DlMatrix::MakeRotationZ(flutter::DlDegrees(10));
2047 stack.PushTransform(rotateMatrix);
2048 flutter::DlMatrix finalMatrix = screenScaleMatrix * rotateMatrix;
2050 auto embeddedViewParams =
2051 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
2053 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2054 withParams:std::move(embeddedViewParams)];
2055 [flutterPlatformViewsController
2059 CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
2060 toView:flutterView];
2066 XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.x - childClippingView.frame.origin.x),
2068 XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.y - childClippingView.frame.origin.y),
2071 fabs(platformViewRectInFlutterView.size.width - childClippingView.frame.size.width),
2074 fabs(platformViewRectInFlutterView.size.height - childClippingView.frame.size.height),
2078 - (void)testClipsDoNotInterceptWithPlatformViewShouldNotAddMaskView {
2079 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2081 flutter::TaskRunners runners(
self.name.UTF8String,
2082 GetDefaultTaskRunner(),
2083 GetDefaultTaskRunner(),
2084 GetDefaultTaskRunner(),
2085 GetDefaultTaskRunner());
2088 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2089 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2092 flutterPlatformViewsController,
2095 std::make_shared<fml::SyncSwitch>());
2099 [flutterPlatformViewsController
2101 withId:@"MockFlutterPlatformView"
2105 [flutterPlatformViewsController
2109 @"viewType" : @"MockFlutterPlatformView"
2115 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
2116 flutterPlatformViewsController.
flutterView = flutterView;
2118 flutter::MutatorsStack stack;
2120 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2121 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2122 stack.PushTransform(screenScaleMatrix);
2123 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({5, 5});
2125 stack.PushTransform(translateMatrix);
2127 flutter::DlRect rect = flutter::DlRect::MakeXYWH(0, 0, 25, 25);
2128 stack.PushClipRect(rect);
2131 flutter::DlRect rect_for_rrect = flutter::DlRect::MakeXYWH(-1, -1, 25, 25);
2132 flutter::DlRoundRect rrect = flutter::DlRoundRect::MakeRectXY(rect_for_rrect, 1, 1);
2133 stack.PushClipRRect(rrect);
2135 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2136 screenScaleMatrix * translateMatrix, flutter::DlSize(5, 5), stack);
2138 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2139 withParams:std::move(embeddedViewParams)];
2140 [flutterPlatformViewsController
2147 [flutterView addSubview:childClippingView];
2149 [flutterView setNeedsLayout];
2150 [flutterView layoutIfNeeded];
2151 XCTAssertNil(childClippingView.maskView);
2154 - (void)testClipRRectOnlyHasCornersInterceptWithPlatformViewShouldAddMaskView {
2155 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2157 flutter::TaskRunners runners(
self.name.UTF8String,
2158 GetDefaultTaskRunner(),
2159 GetDefaultTaskRunner(),
2160 GetDefaultTaskRunner(),
2161 GetDefaultTaskRunner());
2164 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2165 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2168 flutterPlatformViewsController,
2171 std::make_shared<fml::SyncSwitch>());
2175 [flutterPlatformViewsController
2177 withId:@"MockFlutterPlatformView"
2181 [flutterPlatformViewsController
2185 @"viewType" : @"MockFlutterPlatformView"
2191 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
2192 flutterPlatformViewsController.
flutterView = flutterView;
2194 flutter::MutatorsStack stack;
2196 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2197 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2198 stack.PushTransform(screenScaleMatrix);
2199 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({5, 5});
2201 stack.PushTransform(translateMatrix);
2205 flutter::DlRect rect_for_rrect = flutter::DlRect::MakeXYWH(0, 0, 10, 10);
2206 flutter::DlRoundRect rrect = flutter::DlRoundRect::MakeRectXY(rect_for_rrect, 1, 1);
2207 stack.PushClipRRect(rrect);
2209 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2210 screenScaleMatrix * translateMatrix, flutter::DlSize(5, 5), stack);
2212 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2213 withParams:std::move(embeddedViewParams)];
2214 [flutterPlatformViewsController
2221 [flutterView addSubview:childClippingView];
2223 [flutterView setNeedsLayout];
2224 [flutterView layoutIfNeeded];
2226 XCTAssertNotNil(childClippingView.maskView);
2229 - (void)testClipRect {
2230 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2232 flutter::TaskRunners runners(
self.name.UTF8String,
2233 GetDefaultTaskRunner(),
2234 GetDefaultTaskRunner(),
2235 GetDefaultTaskRunner(),
2236 GetDefaultTaskRunner());
2239 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2240 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2243 flutterPlatformViewsController,
2246 std::make_shared<fml::SyncSwitch>());
2250 [flutterPlatformViewsController
2252 withId:@"MockFlutterPlatformView"
2256 [flutterPlatformViewsController
2260 @"viewType" : @"MockFlutterPlatformView"
2266 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2267 flutterPlatformViewsController.
flutterView = flutterView;
2269 flutter::MutatorsStack stack;
2271 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2272 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2273 stack.PushTransform(screenScaleMatrix);
2275 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
2276 stack.PushClipRect(rect);
2278 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2279 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2281 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2282 withParams:std::move(embeddedViewParams)];
2283 [flutterPlatformViewsController
2290 [flutterView addSubview:childClippingView];
2292 [flutterView setNeedsLayout];
2293 [flutterView layoutIfNeeded];
2295 CGRect insideClipping = CGRectMake(2, 2, 3, 3);
2296 for (
int i = 0; i < 10; i++) {
2297 for (
int j = 0; j < 10; j++) {
2298 CGPoint point = CGPointMake(i, j);
2299 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2300 if (CGRectContainsPoint(insideClipping, point)) {
2301 XCTAssertEqual(alpha, 255);
2303 XCTAssertEqual(alpha, 0);
2309 - (void)testClipRect_multipleClips {
2310 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2312 flutter::TaskRunners runners(
self.name.UTF8String,
2313 GetDefaultTaskRunner(),
2314 GetDefaultTaskRunner(),
2315 GetDefaultTaskRunner(),
2316 GetDefaultTaskRunner());
2319 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2320 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2323 flutterPlatformViewsController,
2326 std::make_shared<fml::SyncSwitch>());
2330 [flutterPlatformViewsController
2332 withId:@"MockFlutterPlatformView"
2336 [flutterPlatformViewsController
2340 @"viewType" : @"MockFlutterPlatformView"
2346 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2347 flutterPlatformViewsController.
flutterView = flutterView;
2349 flutter::MutatorsStack stack;
2351 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2352 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2353 stack.PushTransform(screenScaleMatrix);
2355 flutter::DlRect rect1 = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
2356 stack.PushClipRect(rect1);
2358 flutter::DlRect rect2 = flutter::DlRect::MakeXYWH(3, 3, 3, 3);
2359 stack.PushClipRect(rect2);
2361 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2362 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2364 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2365 withParams:std::move(embeddedViewParams)];
2366 [flutterPlatformViewsController
2373 [flutterView addSubview:childClippingView];
2375 [flutterView setNeedsLayout];
2376 [flutterView layoutIfNeeded];
2395 CGRect insideClipping = CGRectMake(3, 3, 2, 2);
2396 for (
int i = 0; i < 10; i++) {
2397 for (
int j = 0; j < 10; j++) {
2398 CGPoint point = CGPointMake(i, j);
2399 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2400 if (CGRectContainsPoint(insideClipping, point)) {
2401 XCTAssertEqual(alpha, 255);
2403 XCTAssertEqual(alpha, 0);
2409 - (void)testClipRRect {
2410 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2412 flutter::TaskRunners runners(
self.name.UTF8String,
2413 GetDefaultTaskRunner(),
2414 GetDefaultTaskRunner(),
2415 GetDefaultTaskRunner(),
2416 GetDefaultTaskRunner());
2419 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2420 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2423 flutterPlatformViewsController,
2426 std::make_shared<fml::SyncSwitch>());
2430 [flutterPlatformViewsController
2432 withId:@"MockFlutterPlatformView"
2436 [flutterPlatformViewsController
2440 @"viewType" : @"MockFlutterPlatformView"
2446 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2447 flutterPlatformViewsController.
flutterView = flutterView;
2449 flutter::MutatorsStack stack;
2451 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2452 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2453 stack.PushTransform(screenScaleMatrix);
2455 flutter::DlRoundRect rrect =
2456 flutter::DlRoundRect::MakeRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2457 stack.PushClipRRect(rrect);
2459 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2460 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2462 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2463 withParams:std::move(embeddedViewParams)];
2464 [flutterPlatformViewsController
2471 [flutterView addSubview:childClippingView];
2473 [flutterView setNeedsLayout];
2474 [flutterView layoutIfNeeded];
2495 CGRect innerClipping1 = CGRectMake(3, 2, 4, 6);
2496 CGRect innerClipping2 = CGRectMake(2, 3, 6, 4);
2497 CGRect outterClipping = CGRectMake(2, 2, 6, 6);
2498 for (
int i = 0; i < 10; i++) {
2499 for (
int j = 0; j < 10; j++) {
2500 CGPoint point = CGPointMake(i, j);
2501 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2502 if (CGRectContainsPoint(innerClipping1, point) ||
2503 CGRectContainsPoint(innerClipping2, point)) {
2505 XCTAssertEqual(alpha, 255);
2506 }
else if (CGRectContainsPoint(outterClipping, point)) {
2508 XCTAssert(0 < alpha && alpha < 255);
2511 XCTAssertEqual(alpha, 0);
2517 - (void)testClipRRect_multipleClips {
2518 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2520 flutter::TaskRunners runners(
self.name.UTF8String,
2521 GetDefaultTaskRunner(),
2522 GetDefaultTaskRunner(),
2523 GetDefaultTaskRunner(),
2524 GetDefaultTaskRunner());
2527 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2528 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2531 flutterPlatformViewsController,
2534 std::make_shared<fml::SyncSwitch>());
2538 [flutterPlatformViewsController
2540 withId:@"MockFlutterPlatformView"
2544 [flutterPlatformViewsController
2548 @"viewType" : @"MockFlutterPlatformView"
2554 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2555 flutterPlatformViewsController.
flutterView = flutterView;
2557 flutter::MutatorsStack stack;
2559 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2560 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2561 stack.PushTransform(screenScaleMatrix);
2563 flutter::DlRoundRect rrect =
2564 flutter::DlRoundRect::MakeRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2565 stack.PushClipRRect(rrect);
2567 flutter::DlRect rect = flutter::DlRect::MakeXYWH(4, 2, 6, 6);
2568 stack.PushClipRect(rect);
2570 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2571 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2573 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2574 withParams:std::move(embeddedViewParams)];
2575 [flutterPlatformViewsController
2582 [flutterView addSubview:childClippingView];
2584 [flutterView setNeedsLayout];
2585 [flutterView layoutIfNeeded];
2606 CGRect clipping = CGRectMake(4, 2, 4, 6);
2607 for (
int i = 0; i < 10; i++) {
2608 for (
int j = 0; j < 10; j++) {
2609 CGPoint point = CGPointMake(i, j);
2610 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2611 if (i == 7 && (j == 2 || j == 7)) {
2613 XCTAssert(0 < alpha && alpha < 255);
2616 (i == 4 && j >= 2 && j <= 7) ||
2618 (i == 7 && j >= 2 && j <= 7) ||
2620 (j == 2 && i >= 4 && i <= 7) ||
2622 (j == 7 && i >= 4 && i <= 7)) {
2625 XCTAssert(alpha > 127);
2626 }
else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) ||
2627 (j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) {
2630 XCTAssert(alpha < 127);
2631 }
else if (CGRectContainsPoint(clipping, point)) {
2633 XCTAssertEqual(alpha, 255);
2636 XCTAssertEqual(alpha, 0);
2642 - (void)testClipPath {
2643 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2645 flutter::TaskRunners runners(
self.name.UTF8String,
2646 GetDefaultTaskRunner(),
2647 GetDefaultTaskRunner(),
2648 GetDefaultTaskRunner(),
2649 GetDefaultTaskRunner());
2652 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2653 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2656 flutterPlatformViewsController,
2659 std::make_shared<fml::SyncSwitch>());
2663 [flutterPlatformViewsController
2665 withId:@"MockFlutterPlatformView"
2669 [flutterPlatformViewsController
2673 @"viewType" : @"MockFlutterPlatformView"
2679 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2680 flutterPlatformViewsController.
flutterView = flutterView;
2682 flutter::MutatorsStack stack;
2684 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2685 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2686 stack.PushTransform(screenScaleMatrix);
2688 flutter::DlPath path =
2689 flutter::DlPath::MakeRoundRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2690 stack.PushClipPath(path);
2692 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2693 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2695 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2696 withParams:std::move(embeddedViewParams)];
2697 [flutterPlatformViewsController
2704 [flutterView addSubview:childClippingView];
2706 [flutterView setNeedsLayout];
2707 [flutterView layoutIfNeeded];
2728 CGRect innerClipping1 = CGRectMake(3, 2, 4, 6);
2729 CGRect innerClipping2 = CGRectMake(2, 3, 6, 4);
2730 CGRect outterClipping = CGRectMake(2, 2, 6, 6);
2731 for (
int i = 0; i < 10; i++) {
2732 for (
int j = 0; j < 10; j++) {
2733 CGPoint point = CGPointMake(i, j);
2734 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2735 if (CGRectContainsPoint(innerClipping1, point) ||
2736 CGRectContainsPoint(innerClipping2, point)) {
2738 XCTAssertEqual(alpha, 255);
2739 }
else if (CGRectContainsPoint(outterClipping, point)) {
2741 XCTAssert(0 < alpha && alpha < 255);
2744 XCTAssertEqual(alpha, 0);
2750 - (void)testClipPath_multipleClips {
2751 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2753 flutter::TaskRunners runners(
self.name.UTF8String,
2754 GetDefaultTaskRunner(),
2755 GetDefaultTaskRunner(),
2756 GetDefaultTaskRunner(),
2757 GetDefaultTaskRunner());
2760 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2761 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2764 flutterPlatformViewsController,
2767 std::make_shared<fml::SyncSwitch>());
2771 [flutterPlatformViewsController
2773 withId:@"MockFlutterPlatformView"
2777 [flutterPlatformViewsController
2781 @"viewType" : @"MockFlutterPlatformView"
2787 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2788 flutterPlatformViewsController.
flutterView = flutterView;
2790 flutter::MutatorsStack stack;
2792 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2793 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2794 stack.PushTransform(screenScaleMatrix);
2796 flutter::DlPath path =
2797 flutter::DlPath::MakeRoundRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2798 stack.PushClipPath(path);
2800 flutter::DlRect rect = flutter::DlRect::MakeXYWH(4, 2, 6, 6);
2801 stack.PushClipRect(rect);
2803 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2804 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2806 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2807 withParams:std::move(embeddedViewParams)];
2808 [flutterPlatformViewsController
2815 [flutterView addSubview:childClippingView];
2817 [flutterView setNeedsLayout];
2818 [flutterView layoutIfNeeded];
2839 CGRect clipping = CGRectMake(4, 2, 4, 6);
2840 for (
int i = 0; i < 10; i++) {
2841 for (
int j = 0; j < 10; j++) {
2842 CGPoint point = CGPointMake(i, j);
2843 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2844 if (i == 7 && (j == 2 || j == 7)) {
2846 XCTAssert(0 < alpha && alpha < 255);
2849 (i == 4 && j >= 2 && j <= 7) ||
2851 (i == 7 && j >= 2 && j <= 7) ||
2853 (j == 2 && i >= 4 && i <= 7) ||
2855 (j == 7 && i >= 4 && i <= 7)) {
2858 XCTAssert(alpha > 127);
2859 }
else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) ||
2860 (j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) {
2863 XCTAssert(alpha < 127);
2864 }
else if (CGRectContainsPoint(clipping, point)) {
2866 XCTAssertEqual(alpha, 255);
2869 XCTAssertEqual(alpha, 0);
2875 - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents {
2876 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2878 flutter::TaskRunners runners(
self.name.UTF8String,
2879 GetDefaultTaskRunner(),
2880 GetDefaultTaskRunner(),
2881 GetDefaultTaskRunner(),
2882 GetDefaultTaskRunner());
2885 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2886 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2889 flutterPlatformViewsController,
2892 std::make_shared<fml::SyncSwitch>());
2896 [flutterPlatformViewsController
2898 withId:@"MockFlutterPlatformView"
2902 [flutterPlatformViewsController
2906 @"viewType" : @"MockFlutterPlatformView"
2914 while (touchInteceptorView != nil &&
2916 touchInteceptorView = touchInteceptorView.superview;
2918 XCTAssertNotNil(touchInteceptorView);
2921 UIGestureRecognizer* forwardGectureRecognizer = nil;
2922 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
2924 forwardGectureRecognizer = gestureRecognizer;
2930 NSSet* touches1 = [[NSSet alloc] init];
2931 id event1 = OCMClassMock([UIEvent
class]);
2933 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2934 OCMReject([flutterViewController touchesBegan:touches1 withEvent:event1]);
2937 NSSet* touches2 = [[NSSet alloc] init];
2938 id event2 = OCMClassMock([UIEvent
class]);
2940 [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2];
2941 OCMVerify([flutterViewController touchesBegan:touches2 withEvent:event2]);
2944 - (void)testSetFlutterViewControllerInTheMiddleOfTouchEventShouldStillAllowGesturesToBeHandled {
2945 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2947 flutter::TaskRunners runners(
self.name.UTF8String,
2948 GetDefaultTaskRunner(),
2949 GetDefaultTaskRunner(),
2950 GetDefaultTaskRunner(),
2951 GetDefaultTaskRunner());
2954 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2955 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2958 flutterPlatformViewsController,
2961 std::make_shared<fml::SyncSwitch>());
2965 [flutterPlatformViewsController
2967 withId:@"MockFlutterPlatformView"
2971 [flutterPlatformViewsController
2975 @"viewType" : @"MockFlutterPlatformView"
2983 while (touchInteceptorView != nil &&
2985 touchInteceptorView = touchInteceptorView.superview;
2987 XCTAssertNotNil(touchInteceptorView);
2990 UIGestureRecognizer* forwardGectureRecognizer = nil;
2991 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
2993 forwardGectureRecognizer = gestureRecognizer;
3002 NSSet* touches1 = [[NSSet alloc] init];
3003 id event1 = OCMClassMock([UIEvent
class]);
3004 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
3005 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
3010 NSSet* touches2 = [[NSSet alloc] init];
3011 id event2 = OCMClassMock([UIEvent
class]);
3012 [forwardGectureRecognizer touchesMoved:touches2 withEvent:event2];
3013 OCMVerify([flutterViewController touchesMoved:touches2 withEvent:event2]);
3015 NSSet* touches3 = [[NSSet alloc] init];
3016 id event3 = OCMClassMock([UIEvent
class]);
3017 [forwardGectureRecognizer touchesEnded:touches3 withEvent:event3];
3018 OCMVerify([flutterViewController touchesEnded:touches3 withEvent:event3]);
3021 NSSet* touches4 = [[NSSet alloc] init];
3022 id event4 = OCMClassMock([UIEvent
class]);
3023 [forwardGectureRecognizer touchesBegan:touches4 withEvent:event4];
3024 OCMReject([flutterViewController touchesBegan:touches4 withEvent:event4]);
3026 NSSet* touches5 = [[NSSet alloc] init];
3027 id event5 = OCMClassMock([UIEvent
class]);
3028 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
3029 OCMReject([flutterViewController touchesEnded:touches5 withEvent:event5]);
3036 NSSet* touches1 = [[NSSet alloc] init];
3037 id event1 = OCMClassMock([UIEvent
class]);
3038 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
3039 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
3044 NSSet* touches2 = [[NSSet alloc] init];
3045 id event2 = OCMClassMock([UIEvent
class]);
3046 [forwardGectureRecognizer touchesMoved:touches2 withEvent:event2];
3047 OCMVerify([flutterViewController touchesMoved:touches2 withEvent:event2]);
3049 NSSet* touches3 = [[NSSet alloc] init];
3050 id event3 = OCMClassMock([UIEvent
class]);
3051 [forwardGectureRecognizer touchesCancelled:touches3 withEvent:event3];
3052 OCMVerify([flutterViewController forceTouchesCancelled:touches3]);
3055 NSSet* touches4 = [[NSSet alloc] init];
3056 id event4 = OCMClassMock([UIEvent
class]);
3057 [forwardGectureRecognizer touchesBegan:touches4 withEvent:event4];
3058 OCMReject([flutterViewController touchesBegan:touches4 withEvent:event4]);
3060 NSSet* touches5 = [[NSSet alloc] init];
3061 id event5 = OCMClassMock([UIEvent
class]);
3062 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
3063 OCMReject([flutterViewController touchesEnded:touches5 withEvent:event5]);
3066 [flutterPlatformViewsController
reset];
3070 testSetFlutterViewControllerInTheMiddleOfTouchEventAllowsTheNewControllerToHandleSecondTouchSequence {
3071 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3073 flutter::TaskRunners runners(
self.name.UTF8String,
3074 GetDefaultTaskRunner(),
3075 GetDefaultTaskRunner(),
3076 GetDefaultTaskRunner(),
3077 GetDefaultTaskRunner());
3080 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3081 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3084 flutterPlatformViewsController,
3087 std::make_shared<fml::SyncSwitch>());
3091 [flutterPlatformViewsController
3093 withId:@"MockFlutterPlatformView"
3097 [flutterPlatformViewsController
3101 @"viewType" : @"MockFlutterPlatformView"
3109 while (touchInteceptorView != nil &&
3111 touchInteceptorView = touchInteceptorView.superview;
3113 XCTAssertNotNil(touchInteceptorView);
3116 UIGestureRecognizer* forwardGectureRecognizer = nil;
3117 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3119 forwardGectureRecognizer = gestureRecognizer;
3127 NSSet* touches1 = [NSSet setWithObject:@1];
3128 id event1 = OCMClassMock([UIEvent
class]);
3129 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
3130 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
3137 NSSet* touches2 = [NSSet setWithObject:@1];
3138 id event2 = OCMClassMock([UIEvent
class]);
3139 [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2];
3140 OCMVerify([flutterViewController touchesBegan:touches2 withEvent:event2]);
3141 OCMReject([flutterViewController2 touchesBegan:touches2 withEvent:event2]);
3143 NSSet* touches3 = [NSSet setWithObject:@1];
3144 id event3 = OCMClassMock([UIEvent
class]);
3145 [forwardGectureRecognizer touchesMoved:touches3 withEvent:event3];
3146 OCMVerify([flutterViewController touchesMoved:touches3 withEvent:event3]);
3147 OCMReject([flutterViewController2 touchesMoved:touches3 withEvent:event3]);
3149 NSSet* touches4 = [NSSet setWithObject:@1];
3150 id event4 = OCMClassMock([UIEvent
class]);
3151 [forwardGectureRecognizer touchesEnded:touches4 withEvent:event4];
3152 OCMVerify([flutterViewController touchesEnded:touches4 withEvent:event4]);
3153 OCMReject([flutterViewController2 touchesEnded:touches4 withEvent:event4]);
3155 NSSet* touches5 = [NSSet setWithObject:@1];
3156 id event5 = OCMClassMock([UIEvent
class]);
3157 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
3158 OCMVerify([flutterViewController touchesEnded:touches5 withEvent:event5]);
3159 OCMReject([flutterViewController2 touchesEnded:touches5 withEvent:event5]);
3163 NSSet* touches6 = [NSSet setWithObject:@1];
3164 id event6 = OCMClassMock([UIEvent
class]);
3165 [forwardGectureRecognizer touchesBegan:touches6 withEvent:event6];
3166 OCMVerify([flutterViewController2 touchesBegan:touches6 withEvent:event6]);
3167 OCMReject([flutterViewController touchesBegan:touches6 withEvent:event6]);
3170 NSSet* touches7 = [NSSet setWithObject:@1];
3171 id event7 = OCMClassMock([UIEvent
class]);
3172 [forwardGectureRecognizer touchesMoved:touches7 withEvent:event7];
3173 OCMVerify([flutterViewController2 touchesMoved:touches7 withEvent:event7]);
3174 OCMReject([flutterViewController touchesMoved:touches7 withEvent:event7]);
3176 NSSet* touches8 = [NSSet setWithObject:@1];
3177 id event8 = OCMClassMock([UIEvent
class]);
3178 [forwardGectureRecognizer touchesEnded:touches8 withEvent:event8];
3179 OCMVerify([flutterViewController2 touchesEnded:touches8 withEvent:event8]);
3180 OCMReject([flutterViewController touchesEnded:touches8 withEvent:event8]);
3182 [flutterPlatformViewsController
reset];
3185 - (void)testFlutterPlatformViewTouchesCancelledEventAreForcedToBeCancelled {
3186 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3188 flutter::TaskRunners runners(
self.name.UTF8String,
3189 GetDefaultTaskRunner(),
3190 GetDefaultTaskRunner(),
3191 GetDefaultTaskRunner(),
3192 GetDefaultTaskRunner());
3195 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3196 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3199 flutterPlatformViewsController,
3202 std::make_shared<fml::SyncSwitch>());
3206 [flutterPlatformViewsController
3208 withId:@"MockFlutterPlatformView"
3212 [flutterPlatformViewsController
3216 @"viewType" : @"MockFlutterPlatformView"
3224 while (touchInteceptorView != nil &&
3226 touchInteceptorView = touchInteceptorView.superview;
3228 XCTAssertNotNil(touchInteceptorView);
3231 UIGestureRecognizer* forwardGectureRecognizer = nil;
3232 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3234 forwardGectureRecognizer = gestureRecognizer;
3241 NSSet* touches1 = [NSSet setWithObject:@1];
3242 id event1 = OCMClassMock([UIEvent
class]);
3243 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
3245 [forwardGectureRecognizer touchesCancelled:touches1 withEvent:event1];
3246 OCMVerify([flutterViewController forceTouchesCancelled:touches1]);
3248 [flutterPlatformViewsController
reset];
3251 - (void)testFlutterPlatformViewTouchesEndedOrTouchesCancelledEventDoesNotFailTheGestureRecognizer {
3256 if (@available(iOS 26.0, *)) {
3260 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3262 flutter::TaskRunners runners(
self.name.UTF8String,
3263 GetDefaultTaskRunner(),
3264 GetDefaultTaskRunner(),
3265 GetDefaultTaskRunner(),
3266 GetDefaultTaskRunner());
3269 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3270 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3273 flutterPlatformViewsController,
3276 std::make_shared<fml::SyncSwitch>());
3280 [flutterPlatformViewsController
3282 withId:@"MockFlutterPlatformView"
3286 [flutterPlatformViewsController
3290 @"viewType" : @"MockFlutterPlatformView"
3298 while (touchInteceptorView != nil &&
3300 touchInteceptorView = touchInteceptorView.superview;
3302 XCTAssertNotNil(touchInteceptorView);
3305 __block UIGestureRecognizer* forwardGestureRecognizer = nil;
3306 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3308 forwardGestureRecognizer = gestureRecognizer;
3315 NSSet* touches1 = [NSSet setWithObject:@1];
3316 id event1 = OCMClassMock([UIEvent
class]);
3317 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3318 @"Forwarding gesture recognizer must start with possible state.");
3319 [forwardGestureRecognizer touchesBegan:touches1 withEvent:event1];
3320 [forwardGestureRecognizer touchesEnded:touches1 withEvent:event1];
3321 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStateFailed,
3322 @"Forwarding gesture recognizer must end with failed state.");
3324 XCTestExpectation* touchEndedExpectation =
3325 [
self expectationWithDescription:@"Wait for gesture recognizer's state change."];
3326 dispatch_async(dispatch_get_main_queue(), ^{
3328 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3329 if ([gestureRecognizer isKindOfClass:[ForwardingGestureRecognizer class]]) {
3330 forwardGestureRecognizer = gestureRecognizer;
3334 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3335 @"Forwarding gesture recognizer must be reset to possible state.");
3336 [touchEndedExpectation fulfill];
3338 [
self waitForExpectationsWithTimeout:30 handler:nil];
3340 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3341 @"Forwarding gesture recognizer must start with possible state.");
3342 [forwardGestureRecognizer touchesBegan:touches1 withEvent:event1];
3343 [forwardGestureRecognizer touchesCancelled:touches1 withEvent:event1];
3344 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStateFailed,
3345 @"Forwarding gesture recognizer must end with failed state.");
3346 XCTestExpectation* touchCancelledExpectation =
3347 [
self expectationWithDescription:@"Wait for gesture recognizer's state change."];
3348 dispatch_async(dispatch_get_main_queue(), ^{
3350 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3351 if ([gestureRecognizer isKindOfClass:[ForwardingGestureRecognizer class]]) {
3352 forwardGestureRecognizer = gestureRecognizer;
3356 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3357 @"Forwarding gesture recognizer must be reset to possible state.");
3358 [touchCancelledExpectation fulfill];
3360 [
self waitForExpectationsWithTimeout:30 handler:nil];
3362 [flutterPlatformViewsController reset];
3366 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizerForWebView {
3367 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3369 flutter::TaskRunners runners(
self.name.UTF8String,
3370 GetDefaultTaskRunner(),
3371 GetDefaultTaskRunner(),
3372 GetDefaultTaskRunner(),
3373 GetDefaultTaskRunner());
3376 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3377 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3380 flutterPlatformViewsController,
3383 std::make_shared<fml::SyncSwitch>());
3387 [flutterPlatformViewsController
3393 [flutterPlatformViewsController
3396 arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3403 while (touchInteceptorView != nil &&
3405 touchInteceptorView = touchInteceptorView.superview;
3407 XCTAssertNotNil(touchInteceptorView);
3409 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3410 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3411 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3418 BOOL shouldReAddDelayingRecognizer = NO;
3419 if (@available(iOS 26.0, *)) {
3422 }
else if (@available(iOS 18.2, *)) {
3423 shouldReAddDelayingRecognizer = YES;
3425 if (shouldReAddDelayingRecognizer) {
3427 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], forwardingRecognizer);
3428 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], delayingRecognizer);
3430 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3431 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3436 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizerForWrapperWebView {
3437 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3439 flutter::TaskRunners runners(
self.name.UTF8String,
3440 GetDefaultTaskRunner(),
3441 GetDefaultTaskRunner(),
3442 GetDefaultTaskRunner(),
3443 GetDefaultTaskRunner());
3446 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3447 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3450 flutterPlatformViewsController,
3453 std::make_shared<fml::SyncSwitch>());
3457 [flutterPlatformViewsController
3459 withId:@"MockWrapperWebView"
3463 [flutterPlatformViewsController
3466 arguments:@{@"id" : @2, @"viewType" : @"MockWrapperWebView"}]
3473 while (touchInteceptorView != nil &&
3475 touchInteceptorView = touchInteceptorView.superview;
3477 XCTAssertNotNil(touchInteceptorView);
3479 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3480 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3481 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3488 BOOL shouldReAddDelayingRecognizer = NO;
3489 if (@available(iOS 26.0, *)) {
3493 }
else if (@available(iOS 18.2, *)) {
3494 shouldReAddDelayingRecognizer = YES;
3496 if (shouldReAddDelayingRecognizer) {
3498 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], forwardingRecognizer);
3499 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], delayingRecognizer);
3501 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3502 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3507 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizerForNestedWrapperWebView {
3508 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3510 flutter::TaskRunners runners(
self.name.UTF8String,
3511 GetDefaultTaskRunner(),
3512 GetDefaultTaskRunner(),
3513 GetDefaultTaskRunner(),
3514 GetDefaultTaskRunner());
3517 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3518 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3521 flutterPlatformViewsController,
3524 std::make_shared<fml::SyncSwitch>());
3528 [flutterPlatformViewsController
3530 withId:@"MockNestedWrapperWebView"
3534 [flutterPlatformViewsController
3538 @"viewType" : @"MockNestedWrapperWebView"
3546 while (touchInteceptorView != nil &&
3548 touchInteceptorView = touchInteceptorView.superview;
3550 XCTAssertNotNil(touchInteceptorView);
3552 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3553 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3554 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3561 BOOL shouldReAddDelayingRecognizer = NO;
3562 if (@available(iOS 26.0, *)) {
3566 }
else if (@available(iOS 18.2, *)) {
3567 shouldReAddDelayingRecognizer = YES;
3569 if (shouldReAddDelayingRecognizer) {
3571 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], forwardingRecognizer);
3572 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], delayingRecognizer);
3574 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3575 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3580 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldNotRemoveAndAddBackDelayingRecognizerForNonWebView {
3581 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3583 flutter::TaskRunners runners(
self.name.UTF8String,
3584 GetDefaultTaskRunner(),
3585 GetDefaultTaskRunner(),
3586 GetDefaultTaskRunner(),
3587 GetDefaultTaskRunner());
3590 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3591 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3594 flutterPlatformViewsController,
3597 std::make_shared<fml::SyncSwitch>());
3601 [flutterPlatformViewsController
3603 withId:@"MockFlutterPlatformView"
3607 [flutterPlatformViewsController
3611 @"viewType" : @"MockFlutterPlatformView"
3619 while (touchInteceptorView != nil &&
3621 touchInteceptorView = touchInteceptorView.superview;
3623 XCTAssertNotNil(touchInteceptorView);
3625 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3626 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3627 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3634 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3635 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3639 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldDisableAndReEnableTouchEventsGestureRecognizerForSimpleWebView {
3640 if (@available(iOS 26.0, *)) {
3641 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3643 flutter::TaskRunners runners(
self.name.UTF8String,
3644 GetDefaultTaskRunner(),
3645 GetDefaultTaskRunner(),
3646 GetDefaultTaskRunner(),
3647 GetDefaultTaskRunner());
3650 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3651 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3654 flutterPlatformViewsController,
3657 std::make_shared<fml::SyncSwitch>());
3661 [flutterPlatformViewsController
3667 [flutterPlatformViewsController
3670 arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3677 while (touchInteceptorView != nil &&
3679 touchInteceptorView = touchInteceptorView.superview;
3681 XCTAssertNotNil(touchInteceptorView);
3695 root.gestureRecognizers = nil;
3696 for (UIView* subview in root.subviews) {
3697 [subview removeFromSuperview];
3701 [root addGestureRecognizer:normalRecognizer0];
3703 UIView* child1 = [[UIView alloc] init];
3704 [root addSubview:child1];
3706 [child1 addGestureRecognizer:normalRecognizer1];
3708 UIView* child2 = [[UIView alloc] init];
3709 [root addSubview:child2];
3711 [child2 addGestureRecognizer:normalRecognizer2];
3713 UIView* child2_1 = [[UIView alloc] init];
3714 [child2 addSubview:child2_1];
3716 [child2_1 addGestureRecognizer:normalRecognizer2_1];
3718 UIView* child2_2 = [[UIView alloc] init];
3719 [child2 addSubview:child2_2];
3721 [child2_2 addGestureRecognizer:normalRecognizer2_2];
3726 [root addGestureRecognizer:targetRecognizer0];
3730 [child2_2 addGestureRecognizer:targetRecognizer2_2];
3734 NSArray* normalRecognizers = @[
3735 normalRecognizer0, normalRecognizer1, normalRecognizer2, normalRecognizer2_1,
3739 NSArray* targetRecognizers = @[ targetRecognizer0, targetRecognizer2_2 ];
3741 NSArray* expectedEmptyHistory = @[];
3742 NSArray* expectedToggledHistory = @[ @NO, @YES ];
3745 XCTAssertEqualObjects(recognizer.toggleHistory, expectedEmptyHistory);
3748 XCTAssertEqualObjects(recognizer.toggleHistory, expectedToggledHistory);
3754 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldDisableAndReEnableTouchEventsGestureRecognizerForMultipleWebViewInDifferentBranches {
3755 if (@available(iOS 26.0, *)) {
3756 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3758 flutter::TaskRunners runners(
self.name.UTF8String,
3759 GetDefaultTaskRunner(),
3760 GetDefaultTaskRunner(),
3761 GetDefaultTaskRunner(),
3762 GetDefaultTaskRunner());
3765 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3766 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3769 flutterPlatformViewsController,
3772 std::make_shared<fml::SyncSwitch>());
3776 [flutterPlatformViewsController
3778 withId:@"MockWrapperWebView"
3782 [flutterPlatformViewsController
3786 @"viewType" : @"MockWrapperWebView"
3794 while (touchInteceptorView != nil &&
3796 touchInteceptorView = touchInteceptorView.superview;
3798 XCTAssertNotNil(touchInteceptorView);
3816 for (UIView* subview in root.subviews) {
3817 [subview removeFromSuperview];
3821 [root addGestureRecognizer:normalRecognizer0];
3823 UIView* child1 = [[UIView alloc] init];
3824 [root addSubview:child1];
3826 [child1 addGestureRecognizer:normalRecognizer1];
3828 UIView* child2 = [[WKWebView alloc] init];
3829 child2.gestureRecognizers = nil;
3830 for (UIView* subview in child2.subviews) {
3831 [subview removeFromSuperview];
3833 [root addSubview:child2];
3835 [child2 addGestureRecognizer:normalRecognizer2];
3837 UIView* child2_1 = [[UIView alloc] init];
3838 [child2 addSubview:child2_1];
3840 [child2_1 addGestureRecognizer:normalRecognizer2_1];
3842 UIView* child2_2 = [[UIView alloc] init];
3843 [child2 addSubview:child2_2];
3845 [child2_2 addGestureRecognizer:normalRecognizer2_2];
3847 UIView* child3 = [[UIView alloc] init];
3848 [root addSubview:child3];
3850 [child3 addGestureRecognizer:normalRecognizer3];
3852 UIView* child3_1 = [[WKWebView alloc] init];
3853 child3_1.gestureRecognizers = nil;
3854 for (UIView* subview in child3_1.subviews) {
3855 [subview removeFromSuperview];
3857 [child3 addSubview:child3_1];
3859 [child3_1 addGestureRecognizer:normalRecognizer3_1];
3861 UIView* child3_1_1 = [[UIView alloc] init];
3862 [child3_1 addSubview:child3_1_1];
3864 [child3_1_1 addGestureRecognizer:normalRecognizer3_1_1];
3866 UIView* child3_1_2 = [[UIView alloc] init];
3867 [child3_1 addSubview:child3_1_2];
3869 [child3_1_2 addGestureRecognizer:normalRecognizer3_1_2];
3875 [child2_2 addGestureRecognizer:targetRecognizer2_2];
3879 [child3_1_2 addGestureRecognizer:targetRecognizer3_1_2];
3883 NSArray* normalRecognizers = @[
3884 normalRecognizer0, normalRecognizer1, normalRecognizer2, normalRecognizer2_1,
3885 normalRecognizer2_2, normalRecognizer3, normalRecognizer3_1, normalRecognizer3_1_1,
3886 normalRecognizer3_1_2
3888 NSArray* targetRecognizers = @[ targetRecognizer2_2, targetRecognizer3_1_2 ];
3890 NSArray* expectedEmptyHistory = @[];
3891 NSArray* expectedToggledHistory = @[ @NO, @YES ];
3894 XCTAssertEqualObjects(recognizer.toggleHistory, expectedEmptyHistory);
3898 XCTAssertEqualObjects(recognizer.toggleHistory, expectedToggledHistory);
3904 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldDisableAndReEnableTouchEventsGestureRecognizerForNestedMultipleWebView {
3905 if (@available(iOS 26.0, *)) {
3906 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3908 flutter::TaskRunners runners(
self.name.UTF8String,
3909 GetDefaultTaskRunner(),
3910 GetDefaultTaskRunner(),
3911 GetDefaultTaskRunner(),
3912 GetDefaultTaskRunner());
3915 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3916 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3919 flutterPlatformViewsController,
3922 std::make_shared<fml::SyncSwitch>());
3926 [flutterPlatformViewsController
3932 [flutterPlatformViewsController
3935 arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3942 while (touchInteceptorView != nil &&
3944 touchInteceptorView = touchInteceptorView.superview;
3946 XCTAssertNotNil(touchInteceptorView);
3966 root.gestureRecognizers = nil;
3967 for (UIView* subview in root.subviews) {
3968 [subview removeFromSuperview];
3972 [root addGestureRecognizer:normalRecognizer0];
3974 UIView* child1 = [[UIView alloc] init];
3975 [root addSubview:child1];
3977 [child1 addGestureRecognizer:normalRecognizer1];
3979 UIView* child2 = [[UIView alloc] init];
3980 [root addSubview:child2];
3982 [child2 addGestureRecognizer:normalRecognizer2];
3984 UIView* child2_1 = [[UIView alloc] init];
3985 [child2 addSubview:child2_1];
3987 [child2_1 addGestureRecognizer:normalRecognizer2_1];
3989 UIView* child2_2 = [[UIView alloc] init];
3990 [child2 addSubview:child2_2];
3992 [child2_2 addGestureRecognizer:normalRecognizer2_2];
3994 UIView* child3 = [[UIView alloc] init];
3995 [root addSubview:child3];
3997 [child3 addGestureRecognizer:normalRecognizer3];
3999 UIView* child3_1 = [[WKWebView alloc] init];
4000 child3_1.gestureRecognizers = nil;
4001 for (UIView* subview in child3_1.subviews) {
4002 [subview removeFromSuperview];
4004 [child3 addSubview:child3_1];
4006 [child3_1 addGestureRecognizer:normalRecognizer3_1];
4008 UIView* child3_1_1 = [[UIView alloc] init];
4009 [child3_1 addSubview:child3_1_1];
4011 [child3_1_1 addGestureRecognizer:normalRecognizer3_1_1];
4013 UIView* child3_1_2 = [[UIView alloc] init];
4014 [child3_1 addSubview:child3_1_2];
4016 [child3_1_2 addGestureRecognizer:normalRecognizer3_1_2];
4018 UIView* child3_1_2_1 = [[UIView alloc] init];
4019 [child3_1_2 addSubview:child3_1_2_1];
4021 [child3_1_2_1 addGestureRecognizer:normalRecognizer3_1_2_1];
4023 UIView* child3_1_2_2 = [[UIView alloc] init];
4024 [child3_1_2 addSubview:child3_1_2_2];
4026 [child3_1_2_2 addGestureRecognizer:normalRecognizer3_1_2_2];
4032 [child2_2 addGestureRecognizer:targetRecognizer2_2];
4036 [child3_1_2_2 addGestureRecognizer:targetRecognizer3_1_2_2];
4040 NSArray* normalRecognizers = @[
4041 normalRecognizer0, normalRecognizer1, normalRecognizer2, normalRecognizer2_1,
4042 normalRecognizer2_2, normalRecognizer3, normalRecognizer3_1, normalRecognizer3_1_1,
4043 normalRecognizer3_1_2, normalRecognizer3_1_2_1, normalRecognizer3_1_2_2
4046 NSArray* targetRecognizers = @[ targetRecognizer2_2, targetRecognizer3_1_2_2 ];
4048 NSArray* expectedEmptyHistory = @[];
4049 NSArray* expectedToggledHistory = @[ @NO, @YES ];
4052 XCTAssertEqualObjects(recognizer.toggleHistory, expectedEmptyHistory);
4056 XCTAssertEqualObjects(recognizer.toggleHistory, expectedToggledHistory);
4061 - (void)testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashing {
4062 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4064 flutter::TaskRunners runners(
self.name.UTF8String,
4065 GetDefaultTaskRunner(),
4066 GetDefaultTaskRunner(),
4067 GetDefaultTaskRunner(),
4068 GetDefaultTaskRunner());
4071 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4072 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4075 flutterPlatformViewsController,
4078 std::make_shared<fml::SyncSwitch>());
4082 [flutterPlatformViewsController
4084 withId:@"MockFlutterPlatformView"
4088 [flutterPlatformViewsController
4092 @"viewType" : @"MockFlutterPlatformView"
4099 flutter::MutatorsStack stack;
4100 flutter::DlMatrix finalMatrix;
4102 auto embeddedViewParams_1 =
4103 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4105 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4106 withParams:std::move(embeddedViewParams_1)];
4107 [flutterPlatformViewsController
4111 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4112 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4113 nullptr, framebuffer_info,
4114 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return false; },
4115 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4116 flutter::DlISize(800, 600));
4117 XCTAssertFalse([flutterPlatformViewsController
4118 submitFrame:std::move(mock_surface)
4119 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4121 auto embeddedViewParams_2 =
4122 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4123 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4124 withParams:std::move(embeddedViewParams_2)];
4125 [flutterPlatformViewsController
4129 auto mock_surface_submit_true = std::make_unique<flutter::SurfaceFrame>(
4130 nullptr, framebuffer_info,
4131 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4132 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4133 flutter::DlISize(800, 600));
4134 XCTAssertTrue([flutterPlatformViewsController
4135 submitFrame:std::move(mock_surface_submit_true)
4136 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4140 testFlutterPlatformViewControllerResetDeallocsPlatformViewWhenRootViewsNotBindedToFlutterView {
4141 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4143 flutter::TaskRunners runners(
self.name.UTF8String,
4144 GetDefaultTaskRunner(),
4145 GetDefaultTaskRunner(),
4146 GetDefaultTaskRunner(),
4147 GetDefaultTaskRunner());
4150 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4151 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4154 flutterPlatformViewsController,
4157 std::make_shared<fml::SyncSwitch>());
4159 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4160 flutterPlatformViewsController.
flutterView = flutterView;
4164 [flutterPlatformViewsController
4166 withId:@"MockFlutterPlatformView"
4172 [flutterPlatformViewsController
4176 @"viewType" : @"MockFlutterPlatformView"
4180 flutter::MutatorsStack stack;
4181 flutter::DlMatrix finalMatrix;
4182 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
4183 finalMatrix, flutter::DlSize(300, 300), stack);
4184 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4185 withParams:std::move(embeddedViewParams)];
4191 [flutterPlatformViewsController
reset];
4196 - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder {
4197 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4199 flutter::TaskRunners runners(
self.name.UTF8String,
4200 GetDefaultTaskRunner(),
4201 GetDefaultTaskRunner(),
4202 GetDefaultTaskRunner(),
4203 GetDefaultTaskRunner());
4206 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4207 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4210 flutterPlatformViewsController,
4213 std::make_shared<fml::SyncSwitch>());
4215 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4216 flutterPlatformViewsController.
flutterView = flutterView;
4220 [flutterPlatformViewsController
4222 withId:@"MockFlutterPlatformView"
4227 [flutterPlatformViewsController
4231 @"viewType" : @"MockFlutterPlatformView"
4236 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4237 flutter::MutatorsStack stack;
4238 flutter::DlMatrix finalMatrix;
4239 auto embeddedViewParams1 =
4240 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4241 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4242 withParams:std::move(embeddedViewParams1)];
4243 [flutterPlatformViewsController
4250 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4253 auto embeddedViewParams2 =
4254 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4255 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4256 withParams:std::move(embeddedViewParams2)];
4257 [flutterPlatformViewsController
4265 testFlutterPlatformViewControllerSubmitFrameShouldOrderSubviewsCorrectlyWithDifferentViewHierarchy {
4266 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4268 flutter::TaskRunners runners(
self.name.UTF8String,
4269 GetDefaultTaskRunner(),
4270 GetDefaultTaskRunner(),
4271 GetDefaultTaskRunner(),
4272 GetDefaultTaskRunner());
4275 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4276 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4279 flutterPlatformViewsController,
4282 std::make_shared<fml::SyncSwitch>());
4284 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4285 flutterPlatformViewsController.
flutterView = flutterView;
4289 [flutterPlatformViewsController
4291 withId:@"MockFlutterPlatformView"
4295 [flutterPlatformViewsController
4299 @"viewType" : @"MockFlutterPlatformView"
4305 [flutterPlatformViewsController
4309 @"viewType" : @"MockFlutterPlatformView"
4314 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4315 flutter::MutatorsStack stack;
4316 flutter::DlMatrix finalMatrix;
4317 auto embeddedViewParams1 =
4318 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4319 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4320 withParams:std::move(embeddedViewParams1)];
4322 auto embeddedViewParams2 =
4323 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4324 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4325 withParams:std::move(embeddedViewParams2)];
4327 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4328 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4329 nullptr, framebuffer_info,
4330 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4331 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4332 flutter::DlISize(800, 600),
nullptr,
true);
4333 XCTAssertTrue([flutterPlatformViewsController
4334 submitFrame:std::move(mock_surface)
4335 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4338 UIView* clippingView1 = view1.superview.superview;
4339 UIView* clippingView2 = view2.superview.superview;
4340 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
4341 [flutterView.subviews indexOfObject:clippingView2],
4342 @"The first clipping view should be added before the second clipping view.");
4345 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4347 embeddedViewParams2 =
4348 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4349 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4350 withParams:std::move(embeddedViewParams2)];
4352 embeddedViewParams1 =
4353 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4354 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4355 withParams:std::move(embeddedViewParams1)];
4357 mock_surface = std::make_unique<flutter::SurfaceFrame>(
4358 nullptr, framebuffer_info,
4359 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4360 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4361 flutter::DlISize(800, 600),
nullptr,
true);
4362 XCTAssertTrue([flutterPlatformViewsController
4363 submitFrame:std::move(mock_surface)
4364 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4366 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] >
4367 [flutterView.subviews indexOfObject:clippingView2],
4368 @"The first clipping view should be added after the second clipping view.");
4372 testFlutterPlatformViewControllerSubmitFrameShouldOrderSubviewsCorrectlyWithSameViewHierarchy {
4373 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4375 flutter::TaskRunners runners(
self.name.UTF8String,
4376 GetDefaultTaskRunner(),
4377 GetDefaultTaskRunner(),
4378 GetDefaultTaskRunner(),
4379 GetDefaultTaskRunner());
4382 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4383 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4386 flutterPlatformViewsController,
4389 std::make_shared<fml::SyncSwitch>());
4391 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4392 flutterPlatformViewsController.
flutterView = flutterView;
4396 [flutterPlatformViewsController
4398 withId:@"MockFlutterPlatformView"
4402 [flutterPlatformViewsController
4406 @"viewType" : @"MockFlutterPlatformView"
4412 [flutterPlatformViewsController
4416 @"viewType" : @"MockFlutterPlatformView"
4421 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4422 flutter::MutatorsStack stack;
4423 flutter::DlMatrix finalMatrix;
4424 auto embeddedViewParams1 =
4425 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4426 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4427 withParams:std::move(embeddedViewParams1)];
4429 auto embeddedViewParams2 =
4430 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4431 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4432 withParams:std::move(embeddedViewParams2)];
4434 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4435 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4436 nullptr, framebuffer_info,
4437 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4438 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4439 flutter::DlISize(800, 600),
nullptr,
true);
4440 XCTAssertTrue([flutterPlatformViewsController
4441 submitFrame:std::move(mock_surface)
4442 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4445 UIView* clippingView1 = view1.superview.superview;
4446 UIView* clippingView2 = view2.superview.superview;
4447 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
4448 [flutterView.subviews indexOfObject:clippingView2],
4449 @"The first clipping view should be added before the second clipping view.");
4452 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4454 embeddedViewParams1 =
4455 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4456 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4457 withParams:std::move(embeddedViewParams1)];
4459 embeddedViewParams2 =
4460 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4461 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4462 withParams:std::move(embeddedViewParams2)];
4464 mock_surface = std::make_unique<flutter::SurfaceFrame>(
4465 nullptr, framebuffer_info,
4466 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4467 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4468 flutter::DlISize(800, 600),
nullptr,
true);
4469 XCTAssertTrue([flutterPlatformViewsController
4470 submitFrame:std::move(mock_surface)
4471 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4473 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
4474 [flutterView.subviews indexOfObject:clippingView2],
4475 @"The first clipping view should be added before the second clipping view.");
4478 - (int)alphaOfPoint:(CGPoint)point onView:(UIView*)view {
4479 unsigned char pixel[4] = {0};
4481 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
4484 CGContextRef context =
4485 CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace,
4486 static_cast<uint32_t
>(kCGBitmapAlphaInfoMask) &
4487 static_cast<uint32_t
>(kCGImageAlphaPremultipliedLast));
4488 CGContextTranslateCTM(context, -point.x, -point.y);
4489 [view.layer renderInContext:context];
4491 CGContextRelease(context);
4492 CGColorSpaceRelease(colorSpace);
4497 - (void)testHasFirstResponderInViewHierarchySubtree_viewItselfBecomesFirstResponder {
4499 UIWindow* window = [[UIWindow alloc] init];
4500 UITextField* textField = [[UITextField alloc] init];
4501 [window addSubview:textField];
4503 [textField becomeFirstResponder];
4504 XCTAssertTrue(textField.isFirstResponder);
4505 XCTAssertTrue(textField.flt_hasFirstResponderInViewHierarchySubtree);
4506 [textField resignFirstResponder];
4507 XCTAssertFalse(textField.isFirstResponder);
4508 XCTAssertFalse(textField.flt_hasFirstResponderInViewHierarchySubtree);
4511 - (void)testHasFirstResponderInViewHierarchySubtree_descendantViewBecomesFirstResponder {
4513 UIWindow* window = [[UIWindow alloc] init];
4514 UIView* view = [[UIView alloc] init];
4515 UIView* childView = [[UIView alloc] init];
4516 UITextField* textField = [[UITextField alloc] init];
4517 [window addSubview:view];
4518 [view addSubview:childView];
4519 [childView addSubview:textField];
4521 [textField becomeFirstResponder];
4522 XCTAssertTrue(textField.isFirstResponder);
4523 XCTAssertTrue(view.flt_hasFirstResponderInViewHierarchySubtree);
4524 [textField resignFirstResponder];
4525 XCTAssertFalse(textField.isFirstResponder);
4526 XCTAssertFalse(view.flt_hasFirstResponderInViewHierarchySubtree);
4529 - (void)testFlutterClippingMaskViewPoolReuseViewsAfterRecycle {
4535 CGRect newRect = CGRectMake(0, 0, 10, 10);
4539 NSSet* set1 = [NSSet setWithObjects:view1, view2, nil];
4540 NSSet* set2 = [NSSet setWithObjects:view3, view4, nil];
4541 XCTAssertEqualObjects(set1, set2);
4542 XCTAssertTrue(CGRectEqualToRect(view3.frame, newRect));
4543 XCTAssertTrue(CGRectEqualToRect(view4.frame, newRect));
4546 - (void)testFlutterClippingMaskViewPoolAllocsNewMaskViewsAfterReachingCapacity {
4551 XCTAssertNotEqual(view1, view3);
4552 XCTAssertNotEqual(view2, view3);
4555 - (void)testMaskViewsReleasedWhenPoolIsReleased {
4556 __weak UIView* weakView;
4561 XCTAssertNotNil(weakView);
4563 XCTAssertNil(weakView);
4566 - (void)testClipMaskViewIsReused {
4567 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4569 flutter::TaskRunners runners(
self.name.UTF8String,
4570 GetDefaultTaskRunner(),
4571 GetDefaultTaskRunner(),
4572 GetDefaultTaskRunner(),
4573 GetDefaultTaskRunner());
4576 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4577 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4580 flutterPlatformViewsController,
4583 std::make_shared<fml::SyncSwitch>());
4587 [flutterPlatformViewsController
4589 withId:@"MockFlutterPlatformView"
4593 [flutterPlatformViewsController
4597 @"viewType" : @"MockFlutterPlatformView"
4602 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4603 flutterPlatformViewsController.
flutterView = flutterView;
4605 flutter::MutatorsStack stack1;
4607 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4608 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4609 stack1.PushTransform(screenScaleMatrix);
4611 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4612 stack1.PushClipRect(rect);
4614 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4615 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4617 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4618 withParams:std::move(embeddedViewParams1)];
4619 [flutterPlatformViewsController
4624 UIView* maskView1 = childClippingView1.maskView;
4625 XCTAssertNotNil(maskView1);
4628 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(100, 100)];
4629 flutter::MutatorsStack stack2;
4630 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4631 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4632 auto embeddedViewParams3 = std::make_unique<flutter::EmbeddedViewParams>(
4633 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4634 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4635 withParams:std::move(embeddedViewParams3)];
4636 [flutterPlatformViewsController
4643 [flutterPlatformViewsController
4647 @"viewType" : @"MockFlutterPlatformView"
4651 auto embeddedViewParams4 = std::make_unique<flutter::EmbeddedViewParams>(
4652 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4653 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4654 withParams:std::move(embeddedViewParams4)];
4655 [flutterPlatformViewsController
4661 UIView* maskView2 = childClippingView2.maskView;
4662 XCTAssertEqual(maskView1, maskView2);
4663 XCTAssertNotNil(childClippingView2.maskView);
4664 XCTAssertNil(childClippingView1.maskView);
4667 - (void)testDifferentClipMaskViewIsUsedForEachView {
4668 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4670 flutter::TaskRunners runners(
self.name.UTF8String,
4671 GetDefaultTaskRunner(),
4672 GetDefaultTaskRunner(),
4673 GetDefaultTaskRunner(),
4674 GetDefaultTaskRunner());
4677 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4678 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4681 flutterPlatformViewsController,
4684 std::make_shared<fml::SyncSwitch>());
4688 [flutterPlatformViewsController
4690 withId:@"MockFlutterPlatformView"
4695 [flutterPlatformViewsController
4699 @"viewType" : @"MockFlutterPlatformView"
4705 [flutterPlatformViewsController
4709 @"viewType" : @"MockFlutterPlatformView"
4715 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4716 flutterPlatformViewsController.
flutterView = flutterView;
4718 flutter::MutatorsStack stack1;
4720 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4721 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4722 stack1.PushTransform(screenScaleMatrix);
4724 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4725 stack1.PushClipRect(rect);
4727 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4728 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4730 flutter::MutatorsStack stack2;
4731 stack2.PushClipRect(rect);
4732 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4733 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4735 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4736 withParams:std::move(embeddedViewParams1)];
4737 [flutterPlatformViewsController
4741 UIView* childClippingView1 = view1.superview.superview;
4743 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4744 withParams:std::move(embeddedViewParams2)];
4745 [flutterPlatformViewsController
4749 UIView* childClippingView2 = view2.superview.superview;
4750 UIView* maskView1 = childClippingView1.maskView;
4751 UIView* maskView2 = childClippingView2.maskView;
4752 XCTAssertNotEqual(maskView1, maskView2);
4755 - (void)testMaskViewUsesCAShapeLayerAsTheBackingLayer {
4756 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4758 flutter::TaskRunners runners(
self.name.UTF8String,
4759 GetDefaultTaskRunner(),
4760 GetDefaultTaskRunner(),
4761 GetDefaultTaskRunner(),
4762 GetDefaultTaskRunner());
4765 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4766 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4769 flutterPlatformViewsController,
4772 std::make_shared<fml::SyncSwitch>());
4776 [flutterPlatformViewsController
4778 withId:@"MockFlutterPlatformView"
4783 [flutterPlatformViewsController
4787 @"viewType" : @"MockFlutterPlatformView"
4792 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4793 flutterPlatformViewsController.
flutterView = flutterView;
4795 flutter::MutatorsStack stack1;
4797 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4798 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4799 stack1.PushTransform(screenScaleMatrix);
4801 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4802 stack1.PushClipRect(rect);
4804 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4805 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4807 flutter::MutatorsStack stack2;
4808 stack2.PushClipRect(rect);
4809 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4810 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4812 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4813 withParams:std::move(embeddedViewParams1)];
4814 [flutterPlatformViewsController
4820 UIView* maskView = childClippingView.maskView;
4821 XCTAssert([maskView.layer isKindOfClass:[CAShapeLayer
class]],
4822 @"Mask view must use CAShapeLayer as its backing layer.");
4830 - (BOOL)validateOneVisualEffectView:(UIView*)visualEffectView
4831 expectedFrame:(CGRect)frame
4832 inputRadius:(CGFloat)inputRadius {
4833 XCTAssertTrue(CGRectEqualToRect(visualEffectView.frame, frame));
4834 for (UIView* view in visualEffectView.subviews) {
4835 if (![NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
4838 XCTAssertEqual(view.layer.filters.count, 1u);
4839 NSObject* filter = view.layer.filters.firstObject;
4841 XCTAssertEqualObjects([filter valueForKey:
@"name"],
@"gaussianBlur");
4843 NSObject* inputRadiusInFilter = [filter valueForKey:@"inputRadius"];
4844 XCTAssertTrue([inputRadiusInFilter isKindOfClass:[NSNumber
class]] &&
4845 flutter::BlurRadiusEqualToBlurRadius(((NSNumber*)inputRadiusInFilter).floatValue,
4852 - (void)testDisposingViewInCompositionOrderDoNotCrash {
4853 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4855 flutter::TaskRunners runners(
self.name.UTF8String,
4856 GetDefaultTaskRunner(),
4857 GetDefaultTaskRunner(),
4858 GetDefaultTaskRunner(),
4859 GetDefaultTaskRunner());
4862 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4863 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4866 flutterPlatformViewsController,
4869 std::make_shared<fml::SyncSwitch>());
4871 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4872 flutterPlatformViewsController.
flutterView = flutterView;
4876 [flutterPlatformViewsController
4878 withId:@"MockFlutterPlatformView"
4883 [flutterPlatformViewsController
4887 @"viewType" : @"MockFlutterPlatformView"
4890 [flutterPlatformViewsController
4894 @"viewType" : @"MockFlutterPlatformView"
4901 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4902 flutter::MutatorsStack stack;
4903 flutter::DlMatrix finalMatrix;
4904 auto embeddedViewParams0 = std::make_unique<flutter::EmbeddedViewParams>(
4905 finalMatrix, flutter::DlSize(300, 300), stack);
4906 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4907 withParams:std::move(embeddedViewParams0)];
4909 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4910 finalMatrix, flutter::DlSize(300, 300), stack);
4911 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4912 withParams:std::move(embeddedViewParams1)];
4916 XCTestExpectation* expectation = [
self expectationWithDescription:@"dispose call ended."];
4918 [expectation fulfill];
4921 [flutterPlatformViewsController
4924 [
self waitForExpectationsWithTimeout:30 handler:nil];
4926 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4927 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4928 nullptr, framebuffer_info,
4929 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4930 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4931 flutter::DlISize(800, 600),
nullptr,
4933 XCTAssertTrue([flutterPlatformViewsController
4934 submitFrame:std::move(mock_surface)
4935 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4939 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:0]);
4940 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:1]);
4946 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4947 flutter::MutatorsStack stack;
4948 flutter::DlMatrix finalMatrix;
4949 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4950 finalMatrix, flutter::DlSize(300, 300), stack);
4951 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4952 withParams:std::move(embeddedViewParams1)];
4954 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4955 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4956 nullptr, framebuffer_info,
4957 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4958 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4959 flutter::DlISize(800, 600),
nullptr,
true);
4960 XCTAssertTrue([flutterPlatformViewsController
4961 submitFrame:std::move(mock_surface)
4962 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4966 XCTAssertNil([flutterPlatformViewsController platformViewForId:0]);
4967 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:1]);
4970 - (void)testOnlyPlatformViewsAreRemovedWhenReset {
4971 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4973 flutter::TaskRunners runners(
self.name.UTF8String,
4974 GetDefaultTaskRunner(),
4975 GetDefaultTaskRunner(),
4976 GetDefaultTaskRunner(),
4977 GetDefaultTaskRunner());
4980 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4981 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4984 flutterPlatformViewsController,
4987 std::make_shared<fml::SyncSwitch>());
4991 [flutterPlatformViewsController
4993 withId:@"MockFlutterPlatformView"
4997 [flutterPlatformViewsController
5001 @"viewType" : @"MockFlutterPlatformView"
5004 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
5005 flutterPlatformViewsController.
flutterView = flutterView;
5007 flutter::MutatorsStack stack;
5009 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
5010 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
5011 stack.PushTransform(screenScaleMatrix);
5013 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
5014 stack.PushTransform(translateMatrix);
5015 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
5017 auto embeddedViewParams =
5018 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
5020 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
5021 withParams:std::move(embeddedViewParams)];
5023 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
5024 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
5025 nullptr, framebuffer_info,
5026 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
5027 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
5028 flutter::DlISize(800, 600),
nullptr,
true);
5029 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
5030 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
5032 UIView* someView = [[UIView alloc] init];
5033 [flutterView addSubview:someView];
5035 [flutterPlatformViewsController
reset];
5036 XCTAssertEqual(flutterView.subviews.count, 1u);
5037 XCTAssertEqual(flutterView.subviews.firstObject, someView);
5040 - (void)testResetClearsPreviousCompositionOrder {
5041 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
5043 flutter::TaskRunners runners(
self.name.UTF8String,
5044 GetDefaultTaskRunner(),
5045 GetDefaultTaskRunner(),
5046 GetDefaultTaskRunner(),
5047 GetDefaultTaskRunner());
5050 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
5051 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
5054 flutterPlatformViewsController,
5057 std::make_shared<fml::SyncSwitch>());
5061 [flutterPlatformViewsController
5063 withId:@"MockFlutterPlatformView"
5067 [flutterPlatformViewsController
5071 @"viewType" : @"MockFlutterPlatformView"
5074 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
5075 flutterPlatformViewsController.
flutterView = flutterView;
5077 flutter::MutatorsStack stack;
5079 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
5080 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
5081 stack.PushTransform(screenScaleMatrix);
5083 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
5084 stack.PushTransform(translateMatrix);
5085 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
5087 auto embeddedViewParams =
5088 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
5090 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
5091 withParams:std::move(embeddedViewParams)];
5093 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
5094 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
5095 nullptr, framebuffer_info,
5096 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
5097 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
5098 flutter::DlISize(800, 600),
nullptr,
true);
5099 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
5100 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
5106 [flutterPlatformViewsController
reset];
5112 - (void)testNilPlatformViewDoesntCrash {
5113 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
5115 flutter::TaskRunners runners(
self.name.UTF8String,
5116 GetDefaultTaskRunner(),
5117 GetDefaultTaskRunner(),
5118 GetDefaultTaskRunner(),
5119 GetDefaultTaskRunner());
5122 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
5123 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
5126 flutterPlatformViewsController,
5129 std::make_shared<fml::SyncSwitch>());
5133 [flutterPlatformViewsController
5135 withId:@"MockFlutterPlatformView"
5139 [flutterPlatformViewsController
5143 @"viewType" : @"MockFlutterPlatformView"
5146 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
5147 flutterPlatformViewsController.
flutterView = flutterView;
5150 flutter::MutatorsStack stack;
5152 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
5153 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
5154 stack.PushTransform(screenScaleMatrix);
5156 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
5157 stack.PushTransform(translateMatrix);
5158 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
5160 auto embeddedViewParams =
5161 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
5163 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
5164 withParams:std::move(embeddedViewParams)];
5166 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
5167 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
5168 nullptr, framebuffer_info,
5169 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
5170 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
5171 flutter::DlISize(800, 600),
nullptr,
true);
5172 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
5173 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
5175 XCTAssertEqual(flutterView.subviews.count, 1u);
5178 - (void)testFlutterTouchInterceptingViewLinksToAccessibilityContainer {
5180 NSObject* container = [[NSObject alloc] init];
5181 [touchInteceptorView setFlutterAccessibilityContainer:container];
5182 XCTAssertEqualObjects([touchInteceptorView accessibilityContainer], container);
5185 - (void)testLayerPool {
5189 XCTAssertTrue(
engine.platformView !=
nullptr);
5190 auto ios_context =
engine.platformView->GetIosContext();
5195 pool.
CreateLayer(ios_context, MTLPixelFormatBGRA8Unorm);
5196 XCTAssertEqual(pool.size(), 1u);
5197 pool.CreateLayer(ios_context, MTLPixelFormatBGRA8Unorm);
5198 XCTAssertEqual(pool.size(), 2u);
5201 pool.RecycleLayers();
5202 XCTAssertEqual(pool.size(), 2u);
5205 auto unused_layers = pool.RemoveUnusedLayers();
5206 XCTAssertEqual(unused_layers.size(), 2u);
5207 XCTAssertEqual(pool.size(), 1u);
5210 - (void)testFlutterPlatformViewControllerSubmitFramePreservingFrameDamage {
5211 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
5213 flutter::TaskRunners runners(
self.name.UTF8String,
5214 GetDefaultTaskRunner(),
5215 GetDefaultTaskRunner(),
5216 GetDefaultTaskRunner(),
5217 GetDefaultTaskRunner());
5220 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
5221 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
5224 flutterPlatformViewsController,
5227 std::make_shared<fml::SyncSwitch>());
5229 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
5230 flutterPlatformViewsController.
flutterView = flutterView;
5234 [flutterPlatformViewsController
5236 withId:@"MockFlutterPlatformView"
5240 [flutterPlatformViewsController
5244 @"viewType" : @"MockFlutterPlatformView"
5249 [flutterPlatformViewsController
5253 @"viewType" : @"MockFlutterPlatformView"
5257 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
5258 flutter::MutatorsStack stack;
5259 flutter::DlMatrix finalMatrix;
5260 auto embeddedViewParams1 =
5261 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
5262 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
5263 withParams:std::move(embeddedViewParams1)];
5265 auto embeddedViewParams2 =
5266 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
5267 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
5268 withParams:std::move(embeddedViewParams2)];
5270 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
5271 std::optional<flutter::SurfaceFrame::SubmitInfo> submit_info;
5272 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
5273 nullptr, framebuffer_info,
5274 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
5275 [&](
const flutter::SurfaceFrame& surface_frame) {
5276 submit_info = surface_frame.submit_info();
5279 flutter::DlISize(800, 600),
nullptr,
5281 mock_surface->set_submit_info({
5282 .frame_damage = flutter::DlIRect::MakeWH(800, 600),
5283 .buffer_damage = flutter::DlIRect::MakeWH(400, 600),
5286 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
5287 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
5289 XCTAssertTrue(submit_info.has_value());
5290 XCTAssertEqual(*submit_info->frame_damage, flutter::DlIRect::MakeWH(800, 600));
5291 XCTAssertEqual(*submit_info->buffer_damage, flutter::DlIRect::MakeWH(400, 600));
5294 - (void)testClipSuperellipse {
5295 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
5297 flutter::TaskRunners runners(
self.name.UTF8String,
5298 GetDefaultTaskRunner(),
5299 GetDefaultTaskRunner(),
5300 GetDefaultTaskRunner(),
5301 GetDefaultTaskRunner());
5304 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
5305 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
5308 flutterPlatformViewsController,
5311 std::make_shared<fml::SyncSwitch>());
5315 [flutterPlatformViewsController
5317 withId:@"MockFlutterPlatformView"
5321 [flutterPlatformViewsController
5325 @"viewType" : @"MockFlutterPlatformView"
5331 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
5332 flutterPlatformViewsController.
flutterView = flutterView;
5334 flutter::MutatorsStack stack;
5336 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
5337 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
5338 stack.PushTransform(screenScaleMatrix);
5340 flutter::DlRect rect = flutter::DlRect::MakeXYWH(3, 3, 5, 5);
5341 stack.PushClipRSE(flutter::DlRoundSuperellipse::MakeOval(rect));
5343 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
5344 screenScaleMatrix, flutter::DlSize(10, 10), stack);
5346 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
5347 withParams:std::move(embeddedViewParams)];
5348 [flutterPlatformViewsController
5355 [flutterView addSubview:childClippingView];
5357 [flutterView setNeedsLayout];
5358 [flutterView layoutIfNeeded];
5360 CGPoint corners[] = {CGPointMake(rect.GetLeft(), rect.GetTop()),
5361 CGPointMake(rect.GetRight(), rect.GetTop()),
5362 CGPointMake(rect.GetLeft(), rect.GetBottom()),
5363 CGPointMake(rect.GetRight(), rect.GetBottom())};
5364 for (
auto point : corners) {
5365 int alpha = [
self alphaOfPoint:point onView:flutterView];
5366 XCTAssertNotEqual(alpha, 255);
5369 CGPointMake(rect.GetLeft() + rect.GetWidth() / 2, rect.GetTop() + rect.GetHeight() / 2);
5370 int alpha = [
self alphaOfPoint:center onView:flutterView];
5371 XCTAssertEqual(alpha, 255);
void(^ FlutterResult)(id _Nullable result)
NSMutableArray * backdropFilterSubviews()
void applyBlurBackdropFilters:(NSArray< PlatformViewFilter * > *filters)
FlutterClippingMaskView * getMaskViewWithFrame:(CGRect frame)
void insertViewToPoolIfNeeded:(FlutterClippingMaskView *maskView)
Storage for Overlay layers across frames.
void CreateLayer(const std::shared_ptr< IOSContext > &ios_context, MTLPixelFormat pixel_format)
Create a new overlay layer.
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)