Flutter Engine
AppDelegate.m
Go to the documentation of this file.
1 // Copyright 2019 The Chromium 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 "AppDelegate.h"
6 
8 #import "ScreenBeforeFlutter.h"
9 #import "TextPlatformView.h"
10 
12 
13 @end
14 
16 - (BOOL)prefersStatusBarHidden {
17  return YES;
18 }
19 @end
20 
21 @implementation AppDelegate
22 
23 - (BOOL)application:(UIApplication*)application
24  didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
25  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
26  if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--maskview-blocking"]) {
27  self.window.tintColor = UIColor.systemPinkColor;
28  }
29  NSDictionary<NSString*, NSString*>* launchArgsMap = @{
30  // The Platform view golden test args should match `PlatformViewGoldenTestManager`.
31  @"--locale-initialization" : @"locale_initialization",
32  @"--platform-view" : @"platform_view",
33  @"--platform-view-no-overlay-intersection" : @"platform_view_no_overlay_intersection",
34  @"--platform-view-two-intersecting-overlays" : @"platform_view_two_intersecting_overlays",
35  @"--platform-view-partial-intersection" : @"platform_view_partial_intersection",
36  @"--platform-view-one-overlay-two-intersecting-overlays" :
37  @"platform_view_one_overlay_two_intersecting_overlays",
38  @"--platform-view-multiple-without-overlays" : @"platform_view_multiple_without_overlays",
39  @"--platform-view-max-overlays" : @"platform_view_max_overlays",
40  @"--platform-view-multiple" : @"platform_view_multiple",
41  @"--platform-view-multiple-background-foreground" :
42  @"platform_view_multiple_background_foreground",
43  @"--platform-view-cliprect" : @"platform_view_cliprect",
44  @"--platform-view-cliprrect" : @"platform_view_cliprrect",
45  @"--platform-view-clippath" : @"platform_view_clippath",
46  @"--platform-view-transform" : @"platform_view_transform",
47  @"--platform-view-opacity" : @"platform_view_opacity",
48  @"--platform-view-rotate" : @"platform_view_rotate",
49  @"--gesture-reject-after-touches-ended" : @"platform_view_gesture_reject_after_touches_ended",
50  @"--gesture-reject-eager" : @"platform_view_gesture_reject_eager",
51  @"--gesture-accept" : @"platform_view_gesture_accept",
52  @"--tap-status-bar" : @"tap_status_bar",
53  @"--text-semantics-focus" : @"text_semantics_focus",
54  @"--animated-color-square" : @"animated_color_square",
55  };
56  __block NSString* flutterViewControllerTestName = nil;
57  [launchArgsMap
58  enumerateKeysAndObjectsUsingBlock:^(NSString* argument, NSString* testName, BOOL* stop) {
59  if ([[[NSProcessInfo processInfo] arguments] containsObject:argument]) {
60  flutterViewControllerTestName = testName;
61  *stop = YES;
62  }
63  }];
64  if (flutterViewControllerTestName) {
65  [self setupFlutterViewControllerTest:flutterViewControllerTestName];
66  } else if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--screen-before-flutter"]) {
67  self.window.rootViewController = [[ScreenBeforeFlutter alloc] initWithEngineRunCompletion:nil];
68  } else {
69  self.window.rootViewController = [[UIViewController alloc] init];
70  }
71 
72  [self.window makeKeyAndVisible];
73  return [super application:application didFinishLaunchingWithOptions:launchOptions];
74 }
75 
76 - (FlutterViewController*)flutterViewControllerForTest:(NSString*)scenarioIdentifier
77  withEngine:(FlutterEngine*)engine {
78  if ([scenarioIdentifier isEqualToString:@"tap_status_bar"]) {
79  return [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
80  } else {
81  return [[NoStatusBarFlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
82  }
83 }
84 
85 - (void)setupFlutterViewControllerTest:(NSString*)scenarioIdentifier {
86  FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"FlutterControllerTest" project:nil];
87  [engine run];
88 
89  FlutterViewController* flutterViewController =
90  [self flutterViewControllerForTest:scenarioIdentifier withEngine:engine];
91 
92  [engine.binaryMessenger
93  setMessageHandlerOnChannel:@"waiting_for_status"
94  binaryMessageHandler:^(NSData* _Nullable message, FlutterBinaryReply _Nonnull reply) {
96  methodChannelWithName:@"driver"
97  binaryMessenger:engine.binaryMessenger
98  codec:[FlutterJSONMethodCodec sharedInstance]];
99  [channel invokeMethod:@"set_scenario" arguments:@{@"name" : scenarioIdentifier}];
100  }];
101  [engine.binaryMessenger
102  setMessageHandlerOnChannel:@"touches_scenario"
103  binaryMessageHandler:^(NSData* _Nullable message, FlutterBinaryReply _Nonnull reply) {
104  NSDictionary* dict = [NSJSONSerialization JSONObjectWithData:message
105  options:0
106  error:nil];
107  UITextField* text = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 300, 100)];
108  text.text = dict[@"change"];
109  [flutterViewController.view addSubview:text];
110  }];
111  TextPlatformViewFactory* textPlatformViewFactory =
112  [[TextPlatformViewFactory alloc] initWithMessenger:engine.binaryMessenger];
113  NSObject<FlutterPluginRegistrar>* registrar =
114  [engine registrarForPlugin:@"scenarios/TextPlatformViewPlugin"];
115  [registrar registerViewFactory:textPlatformViewFactory
116  withId:@"scenarios/textPlatformView"
117  gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager];
118  [registrar registerViewFactory:textPlatformViewFactory
119  withId:@"scenarios/textPlatformView_blockPolicyUntilTouchesEnded"
120  gestureRecognizersBlockingPolicy:
121  FlutterPlatformViewGestureRecognizersBlockingPolicyWaitUntilTouchesEnded];
122  self.window.rootViewController = flutterViewController;
123 
124  if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--assert-ca-layer-type"]) {
125  if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--enable-software-rendering"]) {
126  NSAssert([flutterViewController.view.layer isKindOfClass:[CALayer class]],
127  @"Expected CALayer for software rendering.");
128  } else {
129  NSAssert([flutterViewController.view.layer isKindOfClass:[CAMetalLayer class]],
130  @"Expected CAMetalLayer for non-software rendering.");
131  }
132  }
133 }
134 
135 @end
instancetype methodChannelWithName:binaryMessenger:codec:(NSString *name, [binaryMessenger] NSObject< FlutterBinaryMessenger > *messenger, [codec] NSObject< FlutterMethodCodec > *codec)
UIWindow * window
Definition: AppDelegate.h:9
NS_ASSUME_NONNULL_BEGIN NSDictionary * launchArgsMap