| Flutter iOS Embedder |

FlutterViewControllerTest_mrc.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import <OCMock/OCMock.h>
6 #import <XCTest/XCTest.h>
7
8 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
9 #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
10 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
11 #import "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"
12
13 FLUTTER_ASSERT_NOT_ARC
14
15 @interface UITouch ()
16
17 @property(nonatomic, readwrite) UITouchPhase phase;
18
19 @end
20
21 @interface VSyncClient (Testing)
22
23 - (CADisplayLink*)getDisplayLink;
24
25 @end
26
27 @interface FlutterViewController (Testing)
28
29 @property(nonatomic, assign) double targetViewInsetBottom;
30 @property(nonatomic, retain) VSyncClient* keyboardAnimationVSyncClient;
31
32 @property(nonatomic, retain) VSyncClient* touchRateCorrectionVSyncClient;
33
34 - (void)createTouchRateCorrectionVSyncClientIfNeeded;
35 - (void)setUpKeyboardAnimationVsyncClient:
36 (FlutterKeyboardAnimationCallback)keyboardAnimationCallback;
37 - (void)startKeyBoardAnimation:(NSTimeInterval)duration;
38 - (void)triggerTouchRateCorrectionIfNeeded:(NSSet*)touches;
39
40 @end
41
42 @interface FlutterViewControllerTest_mrc : XCTestCase
43 @end
44
45 @implementation FlutterViewControllerTest_mrc
46
47 - (void)testSetupKeyboardAnimationVsyncClientWillCreateNewVsyncClientForFlutterViewController {
48 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
49 OCMStub([bundleMock objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"])
50 .andReturn(@YES);
51 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
52 double maxFrameRate = 120;
53 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
54 FlutterEngine* engine = [[[FlutterEngine alloc] init] autorelease];
55 [engine runWithEntrypoint:nil];
56 FlutterViewController* viewController =
57 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
58 FlutterKeyboardAnimationCallback callback = ^(fml::TimePoint targetTime) {
59 };
60 [viewController setUpKeyboardAnimationVsyncClient:callback];
61 XCTAssertNotNil(viewController.keyboardAnimationVSyncClient);
62 CADisplayLink* link = [viewController.keyboardAnimationVSyncClient getDisplayLink];
63 XCTAssertNotNil(link);
64 if (@available(iOS 15.0, *)) {
65 XCTAssertEqual(link.preferredFrameRateRange.maximum, maxFrameRate);
66 XCTAssertEqual(link.preferredFrameRateRange.preferred, maxFrameRate);
67 XCTAssertEqual(link.preferredFrameRateRange.minimum, maxFrameRate / 2);
68 } else {
69 XCTAssertEqual(link.preferredFramesPerSecond, maxFrameRate);
70 }
71 }
72
73 - (void)
74 testCreateTouchRateCorrectionVSyncClientWillCreateVsyncClientWhenRefreshRateIsLargerThan60HZ {
75 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
76 double maxFrameRate = 120;
77 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
78 FlutterEngine* engine = [[[FlutterEngine alloc] init] autorelease];
79 [engine runWithEntrypoint:nil];
80 FlutterViewController* viewController =
81 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
82 [viewController createTouchRateCorrectionVSyncClientIfNeeded];
83 XCTAssertNotNil(viewController.touchRateCorrectionVSyncClient);
84 }
85
86 - (void)testCreateTouchRateCorrectionVSyncClientWillNotCreateNewVSyncClientWhenClientAlreadyExists {
87 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
88 double maxFrameRate = 120;
89 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
90
91 FlutterEngine* engine = [[[FlutterEngine alloc] init] autorelease];
92 [engine runWithEntrypoint:nil];
93 FlutterViewController* viewController =
94 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
95 [viewController createTouchRateCorrectionVSyncClientIfNeeded];
96 VSyncClient* clientBefore = viewController.touchRateCorrectionVSyncClient;
97 XCTAssertNotNil(clientBefore);
98
99 [viewController createTouchRateCorrectionVSyncClientIfNeeded];
100 VSyncClient* clientAfter = viewController.touchRateCorrectionVSyncClient;
101 XCTAssertNotNil(clientAfter);
102
103 XCTAssertTrue(clientBefore == clientAfter);
104 }
105
106 - (void)testCreateTouchRateCorrectionVSyncClientWillNotCreateVsyncClientWhenRefreshRateIs60HZ {
107 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
108 double maxFrameRate = 60;
109 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
110 FlutterEngine* engine = [[[FlutterEngine alloc] init] autorelease];
111 [engine runWithEntrypoint:nil];
112 FlutterViewController* viewController =
113 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
114 [viewController createTouchRateCorrectionVSyncClientIfNeeded];
115 XCTAssertNil(viewController.touchRateCorrectionVSyncClient);
116 }
117
118 - (void)testTriggerTouchRateCorrectionVSyncClientCorrectly {
119 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
120 double maxFrameRate = 120;
121 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
122 FlutterEngine* engine = [[[FlutterEngine alloc] init] autorelease];
123 [engine runWithEntrypoint:nil];
124 FlutterViewController* viewController =
125 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
126 [viewController loadView];
127 [viewController viewDidLoad];
128
129 VSyncClient* client = viewController.touchRateCorrectionVSyncClient;
130 CADisplayLink* link = [client getDisplayLink];
131
132 UITouch* fakeTouchBegan = [[[UITouch alloc] init] autorelease];
133 fakeTouchBegan.phase = UITouchPhaseBegan;
134
135 UITouch* fakeTouchMove = [[[UITouch alloc] init] autorelease];
136 fakeTouchMove.phase = UITouchPhaseMoved;
137
138 UITouch* fakeTouchEnd = [[[UITouch alloc] init] autorelease];
139 fakeTouchEnd.phase = UITouchPhaseEnded;
140
141 UITouch* fakeTouchCancelled = [[[UITouch alloc] init] autorelease];
142 fakeTouchCancelled.phase = UITouchPhaseCancelled;
143
144 [viewController
145 triggerTouchRateCorrectionIfNeeded:[[[NSSet alloc] initWithObjects:fakeTouchBegan, nil]
146 autorelease]];
147 XCTAssertFalse(link.isPaused);
148
149 [viewController
150 triggerTouchRateCorrectionIfNeeded:[[[NSSet alloc] initWithObjects:fakeTouchEnd, nil]
151 autorelease]];
152 XCTAssertTrue(link.isPaused);
153
154 [viewController
155 triggerTouchRateCorrectionIfNeeded:[[[NSSet alloc] initWithObjects:fakeTouchMove, nil]
156 autorelease]];
157 XCTAssertFalse(link.isPaused);
158
159 [viewController
160 triggerTouchRateCorrectionIfNeeded:[[[NSSet alloc] initWithObjects:fakeTouchCancelled, nil]
161 autorelease]];
162 XCTAssertTrue(link.isPaused);
163
164 [viewController
165 triggerTouchRateCorrectionIfNeeded:[[[NSSet alloc]
166 initWithObjects:fakeTouchBegan, fakeTouchEnd, nil]
167 autorelease]];
168 XCTAssertFalse(link.isPaused);
169
170 [viewController
171 triggerTouchRateCorrectionIfNeeded:[[[NSSet alloc]
172 initWithObjects:fakeTouchEnd, fakeTouchCancelled, nil]
173 autorelease]];
174 XCTAssertTrue(link.isPaused);
175
176 [viewController
177 triggerTouchRateCorrectionIfNeeded:[[[NSSet alloc]
178 initWithObjects:fakeTouchMove, fakeTouchEnd, nil]
179 autorelease]];
180 XCTAssertFalse(link.isPaused);
181 }
182
183 - (void)testFlutterViewControllerStartKeyboardAnimationWillCreateVsyncClientCorrectly {
184 FlutterEngine* engine = [[[FlutterEngine alloc] init] autorelease];
185 [engine runWithEntrypoint:nil];
186 FlutterViewController* viewController =
187 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
188 viewController.targetViewInsetBottom = 100;
189 [viewController startKeyBoardAnimation:0.25];
190 XCTAssertNotNil(viewController.keyboardAnimationVSyncClient);
191 }
192
193 - (void)
194 testSetupKeyboardAnimationVsyncClientWillNotCreateNewVsyncClientWhenKeyboardAnimationCallbackIsNil {
195 FlutterEngine* engine = [[[FlutterEngine alloc] init] autorelease];
196 [engine runWithEntrypoint:nil];
197 FlutterViewController* viewController =
198 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
199 [viewController setUpKeyboardAnimationVsyncClient:nil];
200 XCTAssertNil(viewController.keyboardAnimationVSyncClient);
201 }
202
203 @end
FlutterViewController(Testing)
Definition: FlutterViewControllerTest_mrc.mm:27
FlutterViewController(Testing)::touchRateCorrectionVSyncClient
VSyncClient * touchRateCorrectionVSyncClient
Definition: FlutterViewControllerTest_mrc.mm:32
FlutterViewController(Testing)::keyboardAnimationVSyncClient
VSyncClient * keyboardAnimationVSyncClient
Definition: FlutterViewControllerTest_mrc.mm:30
FlutterEngine
Definition: FlutterEngine.h:59
FlutterViewController
Definition: FlutterViewController.h:55
-[FlutterEngine runWithEntrypoint:]
BOOL runWithEntrypoint:(nullable NSString *entrypoint)
FLUTTER_ASSERT_NOT_ARC
Definition: VsyncWaiterIosTest.mm:15
FlutterViewController(Testing)::targetViewInsetBottom
double targetViewInsetBottom
Definition: FlutterViewControllerTest_mrc.mm:29
-[VSyncClient(Testing) getDisplayLink]
CADisplayLink * getDisplayLink()
DisplayLinkManager
Definition: vsync_waiter_ios.h:16
FlutterMacros.h
viewController
FlutterViewController * viewController
Definition: FlutterTextInputPluginTest.mm:92
FlutterKeyboardAnimationCallback
void(^ FlutterKeyboardAnimationCallback)(fml::TimePoint)
Definition: FlutterViewController_Internal.h:36
-[FlutterViewController(Testing) createTouchRateCorrectionVSyncClientIfNeeded]
void createTouchRateCorrectionVSyncClientIfNeeded()
engine
id engine
Definition: FlutterTextInputPluginTest.mm:89
FlutterViewController_Internal.h
VSyncClient(Testing)
Definition: FlutterViewControllerTest_mrc.mm:21
vsync_waiter_ios.h
FlutterViewControllerTest_mrc
Definition: FlutterViewControllerTest_mrc.mm:42
VSyncClient
Definition: vsync_waiter_ios.h:38
FlutterViewController.h