From c3b446a448bc6ff70756ca22c2c424eb3a12114b Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 12 Aug 2020 10:14:04 -0700 Subject: [PATCH] Revert "Refactor initial route code (#19684)" This reverts commit 8d08e6c369e349986831d83204a79af3fcb8d8ca. --- ci/licenses_golden/licenses_flutter | 1 - lib/ui/window.dart | 24 +++--- lib/web_ui/lib/src/ui/window.dart | 20 +++++ .../darwin/ios/framework/Headers/Flutter.h | 46 +++++++++++ .../ios/framework/Headers/FlutterEngine.h | 53 ++----------- .../framework/Headers/FlutterViewController.h | 32 +------- .../ios/framework/Source/FlutterEngine.mm | 54 ++----------- .../ios/framework/Source/FlutterEngineTest.mm | 22 +----- .../framework/Source/FlutterEngine_Internal.h | 4 +- .../ios/framework/Source/FlutterEngine_Test.h | 10 --- .../framework/Source/FlutterViewController.mm | 54 +++++-------- .../Source/FlutterViewControllerTest.mm | 8 +- .../IosUnitTests.xcodeproj/project.pbxproj | 27 ------- testing/run_tests.py | 5 +- .../Scenarios.xcodeproj/project.pbxproj | 4 - .../Scenarios/FlutterEngine+ScenariosTest.m | 2 +- .../ScenariosTests/FlutterEngineTest.m | 2 +- .../FlutterViewControllerInitialRouteTest.m | 76 ------------------- .../Scenarios/ScenariosTests/ScenariosTests.m | 10 ++- .../lib/src/initial_route_reply.dart | 30 -------- testing/scenario_app/lib/src/scenarios.dart | 2 - 21 files changed, 133 insertions(+), 353 deletions(-) delete mode 100644 shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h delete mode 100644 testing/scenario_app/ios/Scenarios/ScenariosTests/FlutterViewControllerInitialRouteTest.m delete mode 100644 testing/scenario_app/lib/src/initial_route_reply.dart diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 784f55693a011..5bb1a51273993 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -925,7 +925,6 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine. FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h -FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.mm diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 3fb31bf51ec00..be542150385de 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -1056,19 +1056,23 @@ class Window { /// /// ## Android /// - /// On Android, the initial route can be set on the [initialRoute](/javadoc/io/flutter/embedding/android/FlutterActivity.NewEngineIntentBuilder.html#initialRoute-java.lang.String-) - /// method of the [FlutterActivity](/javadoc/io/flutter/embedding/android/FlutterActivity.html)'s - /// intent builder. - /// - /// On a standalone engine, see https://flutter.dev/docs/development/add-to-app/android/add-flutter-screen#initial-route-with-a-cached-engine. + /// On Android, calling + /// [`FlutterView.setInitialRoute`](/javadoc/io/flutter/view/FlutterView.html#setInitialRoute-java.lang.String-) + /// will set this value. The value must be set sufficiently early, i.e. before + /// the [runApp] call is executed in Dart, for this to have any effect on the + /// framework. The `createFlutterView` method in your `FlutterActivity` + /// subclass is a suitable time to set the value. The application's + /// `AndroidManifest.xml` file must also be updated to have a suitable + /// [``](https://developer.android.com/guide/topics/manifest/intent-filter-element.html). /// /// ## iOS /// - /// On iOS, the initial route can be set on the `initialRoute` - /// parameter of the [FlutterViewController](/objcdoc/Classes/FlutterViewController.html)'s - /// initializer. - /// - /// On a standalone engine, see https://flutter.dev/docs/development/add-to-app/ios/add-flutter-screen#route. + /// On iOS, calling + /// [`FlutterViewController.setInitialRoute`](/objcdoc/Classes/FlutterViewController.html#/c:objc%28cs%29FlutterViewController%28im%29setInitialRoute:) + /// will set this value. The value must be set sufficiently early, i.e. before + /// the [runApp] call is executed in Dart, for this to have any effect on the + /// framework. The `application:didFinishLaunchingWithOptions:` method is a + /// suitable time to set this value. /// /// See also: /// diff --git a/lib/web_ui/lib/src/ui/window.dart b/lib/web_ui/lib/src/ui/window.dart index b004a95782c9f..ae795912a6539 100644 --- a/lib/web_ui/lib/src/ui/window.dart +++ b/lib/web_ui/lib/src/ui/window.dart @@ -710,6 +710,26 @@ abstract class Window { /// /// This will be the string "`/`" if no particular route was requested. /// + /// ## Android + /// + /// On Android, calling + /// [`FlutterView.setInitialRoute`](/javadoc/io/flutter/view/FlutterView.html#setInitialRoute-java.lang.String-) + /// will set this value. The value must be set sufficiently early, i.e. before + /// the [runApp] call is executed in Dart, for this to have any effect on the + /// framework. The `createFlutterView` method in your `FlutterActivity` + /// subclass is a suitable time to set the value. The application's + /// `AndroidManifest.xml` file must also be updated to have a suitable + /// [``](https://developer.android.com/guide/topics/manifest/intent-filter-element.html). + /// + /// ## iOS + /// + /// On iOS, calling + /// [`FlutterViewController.setInitialRoute`](/objcdoc/Classes/FlutterViewController.html#/c:objc%28cs%29FlutterViewController%28im%29setInitialRoute:) + /// will set this value. The value must be set sufficiently early, i.e. before + /// the [runApp] call is executed in Dart, for this to have any effect on the + /// framework. The `application:didFinishLaunchingWithOptions:` method is a + /// suitable time to set this value. + /// /// See also: /// /// * [Navigator], a widget that handles routing. diff --git a/shell/platform/darwin/ios/framework/Headers/Flutter.h b/shell/platform/darwin/ios/framework/Headers/Flutter.h index d91eba7576fec..9135c8200603c 100644 --- a/shell/platform/darwin/ios/framework/Headers/Flutter.h +++ b/shell/platform/darwin/ios/framework/Headers/Flutter.h @@ -5,6 +5,52 @@ #ifndef FLUTTER_FLUTTER_H_ #define FLUTTER_FLUTTER_H_ +/** + BREAKING CHANGES: + + December 17, 2018: + - Changed designated initializer on FlutterEngine + + October 5, 2018: + - Removed FlutterNavigationController.h/.mm + - Changed return signature of `FlutterDartHeadlessCodeRunner.run*` from void + to bool + - Removed HeadlessPlatformViewIOS + - Marked FlutterDartHeadlessCodeRunner deprecated + + August 31, 2018: Marked -[FlutterDartProject + initFromDefaultSourceForConfiguration] and FlutterStandardBigInteger as + unavailable. + + July 26, 2018: Marked -[FlutterDartProject + initFromDefaultSourceForConfiguration] deprecated. + + February 28, 2018: Removed "initWithFLXArchive" and + "initWithFLXArchiveWithScriptSnapshot". + + January 15, 2018: Marked "initWithFLXArchive" and + "initWithFLXArchiveWithScriptSnapshot" as unavailable following the + deprecation from December 11, 2017. Scheduled to be removed on February + 19, 2018. + + January 09, 2018: Deprecated "FlutterStandardBigInteger" and its use in + "FlutterStandardMessageCodec" and "FlutterStandardMethodCodec". Scheduled to + be marked as unavailable once the deprecation has been available on the + flutter/flutter alpha branch for four weeks. "FlutterStandardBigInteger" was + needed because the Dart 1.0 int type had no size limit. With Dart 2.0, the + int type is a fixed-size, 64-bit signed integer. If you need to communicate + larger integers, use NSString encoding instead. + + December 11, 2017: Deprecated "initWithFLXArchive" and + "initWithFLXArchiveWithScriptSnapshot" and scheculed the same to be marked as + unavailable on January 15, 2018. Instead, "initWithFlutterAssets" and + "initWithFlutterAssetsWithScriptSnapshot" should be used. The reason for this + change is that the FLX archive will be deprecated and replaced with a flutter + assets directory containing the same files as the FLX did. + + November 29, 2017: Added a BREAKING CHANGES section. + */ + #include "FlutterAppDelegate.h" #include "FlutterBinaryMessenger.h" #include "FlutterCallbackCache.h" diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 87b7753317e73..46980d609a078 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -24,11 +24,6 @@ NS_ASSUME_NONNULL_BEGIN */ extern NSString* const FlutterDefaultDartEntrypoint; -/** - * The default Flutter initial route ("/"). - */ -extern NSString* const FlutterDefaultInitialRoute; - /** * The FlutterEngine class coordinates a single instance of execution for a * `FlutterDartProject`. It may have zero or one `FlutterViewController` at a @@ -58,24 +53,6 @@ extern NSString* const FlutterDefaultInitialRoute; FLUTTER_EXPORT @interface FlutterEngine : NSObject -/** - * Default initializer for a FlutterEngine. - * - * Threads created by this FlutterEngine will appear as "FlutterEngine #" in - * Instruments. The prefix can be customized using `initWithName`. - * - * The engine will execute the project located in the bundle with the identifier - * "io.flutter.flutter.app" (the default for Flutter projects). - * - * A newly initialized engine will not run until either `-runWithEntrypoint:` or - * `-runWithEntrypoint:libraryURI:` is called. - * - * FlutterEngine created with this method will have allowHeadlessExecution set to `YES`. - * This means that the engine will continue to run regardless of whether a `FlutterViewController` - * is attached to it or not, until `-destroyContext:` is called or the process finishes. - */ -- (instancetype)init; - /** * Initialize this FlutterEngine. * @@ -137,12 +114,17 @@ FLUTTER_EXPORT project:(nullable FlutterDartProject*)project allowHeadlessExecution:(BOOL)allowHeadlessExecution NS_DESIGNATED_INITIALIZER; +/** + * The default initializer is not available for this object. + * Callers must use `-[FlutterEngine initWithName:project:]`. + */ +- (instancetype)init NS_UNAVAILABLE; + + (instancetype)new NS_UNAVAILABLE; /** * Runs a Dart program on an Isolate from the main Dart library (i.e. the library that - * contains `main()`), using `main()` as the entrypoint (the default for Flutter projects), - * and using "/" (the default route) as the initial route. + * contains `main()`), using `main()` as the entrypoint (the default for Flutter projects). * * The first call to this method will create a new Isolate. Subsequent calls will return * immediately and have no effect. @@ -153,7 +135,7 @@ FLUTTER_EXPORT /** * Runs a Dart program on an Isolate from the main Dart library (i.e. the library that - * contains `main()`), using "/" (the default route) as the initial route. + * contains `main()`). * * The first call to this method will create a new Isolate. Subsequent calls will return * immediately and have no effect. @@ -167,25 +149,6 @@ FLUTTER_EXPORT */ - (BOOL)runWithEntrypoint:(nullable NSString*)entrypoint; -/** - * Runs a Dart program on an Isolate from the main Dart library (i.e. the library that - * contains `main()`). - * - * The first call to this method will create a new Isolate. Subsequent calls will return - * immediately and have no effect. - * - * @param entrypoint The name of a top-level function from the same Dart - * library that contains the app's main() function. If this is FlutterDefaultDartEntrypoint (or - * nil), it will default to `main()`. If it is not the app's main() function, that function must - * be decorated with `@pragma(vm:entry-point)` to ensure the method is not tree-shaken by the Dart - * compiler. - * @param initialRoute The name of the initial Flutter `Navigator` `Route` to load. If this is - * FlutterDefaultInitialRoute (or nil), it will default to the "/" route. - * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. - */ -- (BOOL)runWithEntrypoint:(nullable NSString*)entrypoint - initialRoute:(nullable NSString*)initialRoute; - /** * Runs a Dart program on an Isolate using the specified entrypoint and Dart library, * which may not be the same as the library containing the Dart program's `main()` function. diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index 4468ce7ea770c..6f434af1047f7 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -55,7 +55,7 @@ FLUTTER_EXPORT * * The initialized viewcontroller will attach itself to the engine as part of this process. * - * @param engine The `FlutterEngine` instance to attach to. Cannot be nil. + * @param engine The `FlutterEngine` instance to attach to. * @param nibName The NIB name to initialize this UIViewController with. * @param nibBundle The NIB bundle. */ @@ -78,23 +78,6 @@ FLUTTER_EXPORT nibName:(nullable NSString*)nibName bundle:(nullable NSBundle*)nibBundle NS_DESIGNATED_INITIALIZER; -/** - * Initializes a new FlutterViewController and `FlutterEngine` with the specified - * `FlutterDartProject` and `initialRoute`. - * - * This will implicitly create a new `FlutterEngine` which is retrievable via the `engine` property - * after initialization. - * - * @param project The `FlutterDartProject` to initialize the `FlutterEngine` with. - * @param initialRoute The initial `Navigator` route to load. - * @param nibName The NIB name to initialize this UIViewController with. - * @param nibBundle The NIB bundle. - */ -- (instancetype)initWithProject:(nullable FlutterDartProject*)project - initialRoute:(nullable NSString*)initialRoute - nibName:(nullable NSString*)nibName - bundle:(nullable NSBundle*)nibBundle NS_DESIGNATED_INITIALIZER; - /** * Initializer that is called from loading a FlutterViewController from a XIB. * @@ -134,8 +117,6 @@ FLUTTER_EXPORT - (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package; /** - * Deprecated API to set initial route. - * * Attempts to set the first route that the Flutter app shows if the Flutter * runtime hasn't yet started. The default is "/". * @@ -146,15 +127,9 @@ FLUTTER_EXPORT * Setting this after the Flutter started running has no effect. See `pushRoute` * and `popRoute` to change the route after Flutter started running. * - * This is deprecated because it needs to be called at the time of initialization - * and thus should just be in the `initWithProject` initializer. If using - * `initWithEngine`, the initial route should be set on the engine's - * initializer. - * * @param route The name of the first route to show. */ -- (void)setInitialRoute:(NSString*)route - FLUTTER_DEPRECATED("Use FlutterViewController initializer to specify initial route"); +- (void)setInitialRoute:(NSString*)route; /** * Instructs the Flutter Navigator (if any) to go back. @@ -163,7 +138,8 @@ FLUTTER_EXPORT /** * Instructs the Flutter Navigator (if any) to push a route on to the navigation - * stack. + * stack. The setInitialRoute method should be preferred if this is called before the + * FlutterViewController has come into view. * * @param route The name of the route to push to the navigation stack. */ diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 8bbb81f5f61da..51a741fa4109f 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -33,7 +33,6 @@ #import "flutter/shell/platform/darwin/ios/platform_view_ios.h" NSString* const FlutterDefaultDartEntrypoint = nil; -NSString* const FlutterDefaultInitialRoute = nil; static constexpr int kNumProfilerSamplesPerSec = 5; @interface FlutterEngineRegistrar : NSObject @@ -48,7 +47,6 @@ @interface FlutterEngine () @property(nonatomic, readonly) NSMutableDictionary* registrars; @property(nonatomic, readwrite, copy) NSString* isolateId; -@property(nonatomic, copy) NSString* initialRoute; @property(nonatomic, retain) id flutterViewControllerWillDeallocObserver; @end @@ -85,10 +83,6 @@ @implementation FlutterEngine { std::unique_ptr _connections; } -- (instancetype)init { - return [self initWithName:@"FlutterEngine" project:nil allowHeadlessExecution:YES]; -} - - (instancetype)initWithName:(NSString*)labelPrefix { return [self initWithName:labelPrefix project:nil allowHeadlessExecution:YES]; } @@ -167,7 +161,6 @@ - (void)dealloc { }]; [_labelPrefix release]; - [_initialRoute release]; [_pluginPublications release]; [_registrars release]; _binaryMessenger.parent = nil; @@ -375,13 +368,6 @@ - (void)setupChannels { binaryMessenger:self.binaryMessenger codec:[FlutterJSONMethodCodec sharedInstance]]); - if ([_initialRoute length] > 0) { - // Flutter isn't ready to receive this method call yet but the channel buffer will cache this. - [_navigationChannel invokeMethod:@"setInitialRoute" arguments:_initialRoute]; - [_initialRoute release]; - _initialRoute = nil; - } - _platformChannel.reset([[FlutterMethodChannel alloc] initWithName:@"flutter/platform" binaryMessenger:self.binaryMessenger @@ -451,16 +437,13 @@ - (void)launchEngine:(NSString*)entrypoint libraryURI:(NSString*)libraryOrNil { libraryOrNil:libraryOrNil]); } -- (BOOL)createShell:(NSString*)entrypoint - libraryURI:(NSString*)libraryURI - initialRoute:(NSString*)initialRoute { +- (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI { if (_shell != nullptr) { FML_LOG(WARNING) << "This FlutterEngine was already invoked."; return NO; } static size_t shellCount = 1; - self.initialRoute = initialRoute; auto settings = [_dartProject.get() settings]; auto platformData = [_dartProject.get() defaultPlatformData]; @@ -570,35 +553,21 @@ - (BOOL)createShell:(NSString*)entrypoint } - (BOOL)run { - return [self runWithEntrypoint:FlutterDefaultDartEntrypoint - libraryURI:nil - initialRoute:FlutterDefaultInitialRoute]; + return [self runWithEntrypoint:FlutterDefaultDartEntrypoint libraryURI:nil]; } - (BOOL)runWithEntrypoint:(NSString*)entrypoint libraryURI:(NSString*)libraryURI { - return [self runWithEntrypoint:entrypoint - libraryURI:libraryURI - initialRoute:FlutterDefaultInitialRoute]; -} - -- (BOOL)runWithEntrypoint:(NSString*)entrypoint { - return [self runWithEntrypoint:entrypoint libraryURI:nil initialRoute:FlutterDefaultInitialRoute]; -} - -- (BOOL)runWithEntrypoint:(NSString*)entrypoint initialRoute:(NSString*)initialRoute { - return [self runWithEntrypoint:entrypoint libraryURI:nil initialRoute:initialRoute]; -} - -- (BOOL)runWithEntrypoint:(NSString*)entrypoint - libraryURI:(NSString*)libraryURI - initialRoute:(NSString*)initialRoute { - if ([self createShell:entrypoint libraryURI:libraryURI initialRoute:initialRoute]) { + if ([self createShell:entrypoint libraryURI:libraryURI]) { [self launchEngine:entrypoint libraryURI:libraryURI]; } return _shell != nullptr; } +- (BOOL)runWithEntrypoint:(NSString*)entrypoint { + return [self runWithEntrypoint:entrypoint libraryURI:nil]; +} + - (void)notifyLowMemory { if (_shell) { _shell->NotifyLowMemoryWarning(); @@ -701,15 +670,6 @@ - (void)showAutocorrectionPromptRectForStart:(NSUInteger)start return _binaryMessenger; } -// For test only. Ideally we should create a dependency injector for all dependencies and -// remove this. -- (void)setBinaryMessenger:(FlutterBinaryMessengerRelay*)binaryMessenger { - // Discard the previous messenger and keep the new one. - _binaryMessenger.parent = nil; - [_binaryMessenger release]; - _binaryMessenger = [binaryMessenger retain]; -} - #pragma mark - FlutterBinaryMessenger - (void)sendOnChannel:(NSString*)channel message:(NSData*)message { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm index e7a68f9a7d2bd..7fe3cb16e0775 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm @@ -5,8 +5,7 @@ #import #import #include "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" -#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h" -#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h" +#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h" FLUTTER_ASSERT_ARC @@ -80,23 +79,4 @@ - (void)testNotifyPluginOfDealloc { OCMVerify([plugin detachFromEngineForRegistrar:[OCMArg any]]); } -- (void)testRunningInitialRouteSendsNavigationMessage { - id mockBinaryMessenger = OCMClassMock([FlutterBinaryMessengerRelay class]); - - FlutterEngine* engine = [[FlutterEngine alloc] init]; - [engine setBinaryMessenger:mockBinaryMessenger]; - - // Run with an initial route. - [engine runWithEntrypoint:FlutterDefaultDartEntrypoint initialRoute:@"test"]; - - // Now check that an encoded method call has been made on the binary messenger to set the - // initial route to "test". - FlutterMethodCall* setInitialRouteMethodCall = - [FlutterMethodCall methodCallWithMethodName:@"setInitialRoute" arguments:@"test"]; - NSData* encodedSetInitialRouteMethod = - [[FlutterJSONMethodCodec sharedInstance] encodeMethodCall:setInitialRouteMethodCall]; - OCMVerify([mockBinaryMessenger sendOnChannel:@"flutter/navigation" - message:encodedSetInitialRouteMethod]); -} - @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h index 93e6cbac58514..52558eaf71ab3 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h @@ -43,9 +43,7 @@ - (flutter::FlutterPlatformViewsController*)platformViewsController; - (FlutterTextInputPlugin*)textInputPlugin; - (void)launchEngine:(NSString*)entrypoint libraryURI:(NSString*)libraryOrNil; -- (BOOL)createShell:(NSString*)entrypoint - libraryURI:(NSString*)libraryOrNil - initialRoute:(NSString*)initialRoute; +- (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryOrNil; - (void)attachView; - (void)notifyLowMemory; - (flutter::PlatformViewIOS*)iosPlatformView; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h deleted file mode 100644 index 7be2f68d77b50..0000000000000 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h" - -// Category to add test-only visibility. -@interface FlutterEngine (Test) -- (void)setBinaryMessenger:(FlutterBinaryMessengerRelay*)binaryMessenger; -@end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 6114281d8695b..d788b461586f6 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -111,24 +111,26 @@ - (instancetype)initWithEngine:(FlutterEngine*)engine return self; } -- (instancetype)initWithProject:(FlutterDartProject*)project - nibName:(NSString*)nibName - bundle:(NSBundle*)nibBundle { - self = [super initWithNibName:nibName bundle:nibBundle]; - if (self) { - [self sharedSetupWithProject:project initialRoute:nil]; - } - - return self; +- (void)sharedSetupWithProject:(nullable FlutterDartProject*)project { + _viewOpaque = YES; + _weakFactory = std::make_unique>(self); + _engine.reset([[FlutterEngine alloc] initWithName:@"io.flutter" + project:project + allowHeadlessExecution:self.engineAllowHeadlessExecution]); + _flutterView.reset([[FlutterView alloc] initWithDelegate:_engine opaque:self.isViewOpaque]); + [_engine.get() createShell:nil libraryURI:nil]; + _engineNeedsLaunch = YES; + _ongoingTouches = [[NSMutableSet alloc] init]; + [self loadDefaultSplashScreenView]; + [self performCommonViewControllerInitialization]; } -- (instancetype)initWithProject:(FlutterDartProject*)project - initialRoute:(NSString*)initialRoute - nibName:(NSString*)nibName - bundle:(NSBundle*)nibBundle { +- (instancetype)initWithProject:(nullable FlutterDartProject*)project + nibName:(nullable NSString*)nibName + bundle:(nullable NSBundle*)nibBundle { self = [super initWithNibName:nibName bundle:nibBundle]; if (self) { - [self sharedSetupWithProject:project initialRoute:initialRoute]; + [self sharedSetupWithProject:project]; } return self; @@ -146,7 +148,7 @@ - (instancetype)initWithCoder:(NSCoder*)aDecoder { - (void)awakeFromNib { [super awakeFromNib]; if (!_engine.get()) { - [self sharedSetupWithProject:nil initialRoute:nil]; + [self sharedSetupWithProject:nil]; } } @@ -154,21 +156,6 @@ - (instancetype)init { return [self initWithProject:nil nibName:nil bundle:nil]; } -- (void)sharedSetupWithProject:(nullable FlutterDartProject*)project - initialRoute:(nullable NSString*)initialRoute { - _viewOpaque = YES; - _weakFactory = std::make_unique>(self); - _engine.reset([[FlutterEngine alloc] initWithName:@"io.flutter" - project:project - allowHeadlessExecution:self.engineAllowHeadlessExecution]); - _flutterView.reset([[FlutterView alloc] initWithDelegate:_engine opaque:self.isViewOpaque]); - [_engine.get() createShell:nil libraryURI:nil initialRoute:initialRoute]; - _engineNeedsLaunch = YES; - _ongoingTouches = [[NSMutableSet alloc] init]; - [self loadDefaultSplashScreenView]; - [self performCommonViewControllerInitialization]; -} - - (BOOL)isViewOpaque { return _viewOpaque; } @@ -482,12 +469,7 @@ - (UIView*)splashScreenFromStoryboard:(NSString*)name { } - (UIView*)splashScreenFromXib:(NSString*)name { - NSArray* objects = nil; - @try { - objects = [[NSBundle mainBundle] loadNibNamed:name owner:self options:nil]; - } @catch (NSException* exception) { - return nil; - } + NSArray* objects = [[NSBundle mainBundle] loadNibNamed:name owner:self options:nil]; if ([objects count] != 0) { UIView* view = [objects objectAtIndex:0]; return view; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index 2418ea58bc72b..e508d031eb265 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -13,9 +13,7 @@ FLUTTER_ASSERT_ARC @interface FlutterEngine () -- (BOOL)createShell:(NSString*)entrypoint - libraryURI:(NSString*)libraryURI - initialRoute:(NSString*)initialRoute; +- (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI; @end @interface FlutterEngine (TestLowMemory) @@ -515,7 +513,7 @@ - (void)testWillDeallocNotification { - (void)testDoesntLoadViewInInit { FlutterDartProject* project = [[FlutterDartProject alloc] init]; FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project]; - [engine createShell:@"" libraryURI:@"" initialRoute:nil]; + [engine createShell:@"" libraryURI:@""]; FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil]; @@ -525,7 +523,7 @@ - (void)testDoesntLoadViewInInit { - (void)testHideOverlay { FlutterDartProject* project = [[FlutterDartProject alloc] init]; FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project]; - [engine createShell:@"" libraryURI:@"" initialRoute:nil]; + [engine createShell:@"" libraryURI:@""]; FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil]; diff --git a/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj b/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj index eeaef513460a9..598624564fe53 100644 --- a/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj +++ b/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj @@ -28,15 +28,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 0AC232F424BA71D300A85907 /* SemanticsObjectTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SemanticsObjectTest.mm; sourceTree = ""; }; - 0AC232F724BA71D300A85907 /* FlutterEngineTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FlutterEngineTest.mm; sourceTree = ""; }; - 0AC2330324BA71D300A85907 /* accessibility_bridge_test.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = accessibility_bridge_test.mm; sourceTree = ""; }; - 0AC2330B24BA71D300A85907 /* FlutterTextInputPluginTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FlutterTextInputPluginTest.m; sourceTree = ""; }; - 0AC2330F24BA71D300A85907 /* FlutterBinaryMessengerRelayTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FlutterBinaryMessengerRelayTest.mm; sourceTree = ""; }; - 0AC2331024BA71D300A85907 /* connection_collection_test.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = connection_collection_test.mm; sourceTree = ""; }; - 0AC2331224BA71D300A85907 /* FlutterEnginePlatformViewTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FlutterEnginePlatformViewTest.mm; sourceTree = ""; }; - 0AC2331924BA71D300A85907 /* FlutterPluginAppLifeCycleDelegateTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FlutterPluginAppLifeCycleDelegateTest.m; sourceTree = ""; }; - 0AC2332124BA71D300A85907 /* FlutterViewControllerTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FlutterViewControllerTest.mm; sourceTree = ""; }; 0D1CE5D7233430F400E5D880 /* FlutterChannelsTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FlutterChannelsTest.m; sourceTree = ""; }; 0D6AB6B122BB05E100EEE540 /* IosUnitTests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IosUnitTests.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0D6AB6B422BB05E100EEE540 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -71,23 +62,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0AC232E924BA71D300A85907 /* Source */ = { - isa = PBXGroup; - children = ( - 0AC232F424BA71D300A85907 /* SemanticsObjectTest.mm */, - 0AC232F724BA71D300A85907 /* FlutterEngineTest.mm */, - 0AC2330324BA71D300A85907 /* accessibility_bridge_test.mm */, - 0AC2330B24BA71D300A85907 /* FlutterTextInputPluginTest.m */, - 0AC2330F24BA71D300A85907 /* FlutterBinaryMessengerRelayTest.mm */, - 0AC2331024BA71D300A85907 /* connection_collection_test.mm */, - 0AC2331224BA71D300A85907 /* FlutterEnginePlatformViewTest.mm */, - 0AC2331924BA71D300A85907 /* FlutterPluginAppLifeCycleDelegateTest.m */, - 0AC2332124BA71D300A85907 /* FlutterViewControllerTest.mm */, - ); - name = Source; - path = ../../../shell/platform/darwin/ios/framework/Source; - sourceTree = ""; - }; 0D1CE5D62334309900E5D880 /* Source-Common */ = { isa = PBXGroup; children = ( @@ -100,7 +74,6 @@ 0D6AB6A822BB05E100EEE540 = { isa = PBXGroup; children = ( - 0AC232E924BA71D300A85907 /* Source */, 0D6AB6B322BB05E100EEE540 /* App */, 0D6AB6CC22BB05E200EEE540 /* Tests */, 0D6AB6B222BB05E100EEE540 /* Products */, diff --git a/testing/run_tests.py b/testing/run_tests.py index b692cd3b9eaf0..7df1757ee80b0 100755 --- a/testing/run_tests.py +++ b/testing/run_tests.py @@ -331,11 +331,10 @@ def AssertExpectedJavaVersion(): def AssertExpectedXcodeVersion(): """Checks that the user has a recent version of Xcode installed""" - EXPECTED_MAJOR_VERSION = ['11', '12'] + EXPECTED_MAJOR_VERSION = '11' version_output = subprocess.check_output(['xcodebuild', '-version']) - match = re.match("Xcode (\d+)", version_output) message = "Xcode must be installed to run the iOS embedding unit tests" - assert match.group(1) in EXPECTED_MAJOR_VERSION, message + assert "Xcode %s." % EXPECTED_MAJOR_VERSION in version_output, message def RunJavaTests(filter, android_variant='android_debug_unopt'): """Runs the Java JUnit unit tests for the Android embedding""" diff --git a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj index cc4462541c2d5..9c43ef8583a4a 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj +++ b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj @@ -11,7 +11,6 @@ 0A57B3BD2323C4BD00DD9521 /* ScreenBeforeFlutter.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A57B3BC2323C4BD00DD9521 /* ScreenBeforeFlutter.m */; }; 0A57B3BF2323C74200DD9521 /* FlutterEngine+ScenariosTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A57B3BE2323C74200DD9521 /* FlutterEngine+ScenariosTest.m */; }; 0A57B3C22323D2D700DD9521 /* AppLifecycleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A57B3C12323D2D700DD9521 /* AppLifecycleTests.m */; }; - 0A97D7C024BA937000050525 /* FlutterViewControllerInitialRouteTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A97D7BF24BA937000050525 /* FlutterViewControllerInitialRouteTest.m */; }; 0D14A3FE239743190013D873 /* golden_platform_view_rotate_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 0D14A3FD239743190013D873 /* golden_platform_view_rotate_iPhone SE_simulator.png */; }; 0D8470A4240F0B1F0030B565 /* StatusBarTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D8470A3240F0B1F0030B565 /* StatusBarTest.m */; }; 0DB781EF22E931BE00E9B371 /* Flutter.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -120,7 +119,6 @@ 0A57B3BE2323C74200DD9521 /* FlutterEngine+ScenariosTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "FlutterEngine+ScenariosTest.m"; sourceTree = ""; }; 0A57B3C02323C74D00DD9521 /* FlutterEngine+ScenariosTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FlutterEngine+ScenariosTest.h"; sourceTree = ""; }; 0A57B3C12323D2D700DD9521 /* AppLifecycleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppLifecycleTests.m; sourceTree = ""; }; - 0A97D7BF24BA937000050525 /* FlutterViewControllerInitialRouteTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FlutterViewControllerInitialRouteTest.m; sourceTree = ""; }; 0D14A3FD239743190013D873 /* golden_platform_view_rotate_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_rotate_iPhone SE_simulator.png"; sourceTree = ""; }; 0D8470A2240F0B1F0030B565 /* StatusBarTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StatusBarTest.h; sourceTree = ""; }; 0D8470A3240F0B1F0030B565 /* StatusBarTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StatusBarTest.m; sourceTree = ""; }; @@ -245,7 +243,6 @@ children = ( 248FDFC322FE7CD0009CC7CD /* FlutterEngineTest.m */, 0DB781FC22EA2C0300E9B371 /* FlutterViewControllerTest.m */, - 0A97D7BF24BA937000050525 /* FlutterViewControllerInitialRouteTest.m */, 248D76E522E388380012F0C1 /* Info.plist */, 0A57B3C12323D2D700DD9521 /* AppLifecycleTests.m */, ); @@ -472,7 +469,6 @@ files = ( 0DB7820222EA493B00E9B371 /* FlutterViewControllerTest.m in Sources */, 0A57B3C22323D2D700DD9521 /* AppLifecycleTests.m in Sources */, - 0A97D7C024BA937000050525 /* FlutterViewControllerInitialRouteTest.m in Sources */, 248FDFC422FE7CD0009CC7CD /* FlutterEngineTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/testing/scenario_app/ios/Scenarios/Scenarios/FlutterEngine+ScenariosTest.m b/testing/scenario_app/ios/Scenarios/Scenarios/FlutterEngine+ScenariosTest.m index cfa70262f2585..82aa5bf670993 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios/FlutterEngine+ScenariosTest.m +++ b/testing/scenario_app/ios/Scenarios/Scenarios/FlutterEngine+ScenariosTest.m @@ -11,7 +11,7 @@ - (instancetype)initWithScenario:(NSString*)scenario NSAssert([scenario length] != 0, @"You need to provide a scenario"); self = [self initWithName:[NSString stringWithFormat:@"Test engine for %@", scenario] project:nil]; - [self run]; + [self runWithEntrypoint:nil]; [self.binaryMessenger setMessageHandlerOnChannel:@"waiting_for_status" binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) { diff --git a/testing/scenario_app/ios/Scenarios/ScenariosTests/FlutterEngineTest.m b/testing/scenario_app/ios/Scenarios/ScenariosTests/FlutterEngineTest.m index b43c6bfa15bda..f875764e99e2b 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosTests/FlutterEngineTest.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosTests/FlutterEngineTest.m @@ -34,7 +34,7 @@ - (void)testChannelSetup { XCTAssertNil(engine.platformChannel); XCTAssertNil(engine.lifecycleChannel); - XCTAssertTrue([engine run]); + XCTAssertTrue([engine runWithEntrypoint:nil]); XCTAssertNotNil(engine.navigationChannel); XCTAssertNotNil(engine.platformChannel); diff --git a/testing/scenario_app/ios/Scenarios/ScenariosTests/FlutterViewControllerInitialRouteTest.m b/testing/scenario_app/ios/Scenarios/ScenariosTests/FlutterViewControllerInitialRouteTest.m deleted file mode 100644 index fa791e4dd14ab..0000000000000 --- a/testing/scenario_app/ios/Scenarios/ScenariosTests/FlutterViewControllerInitialRouteTest.m +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import -#import -#import "AppDelegate.h" - -@interface FlutterViewControllerInitialRouteTest : XCTestCase -@property(nonatomic, strong) FlutterViewController* flutterViewController; -@end - -// This test needs to be in its own file with only one test method because dart:ui -// window's defaultRouteName can only be set once per VM. -@implementation FlutterViewControllerInitialRouteTest - -- (void)setUp { - [super setUp]; - self.continueAfterFailure = NO; -} - -- (void)tearDown { - if (self.flutterViewController) { - [self.flutterViewController removeFromParentViewController]; - } - [super tearDown]; -} - -- (void)testSettingInitialRoute { - self.flutterViewController = - [[FlutterViewController alloc] initWithProject:nil - initialRoute:@"myCustomInitialRoute" - nibName:nil - bundle:nil]; - - NSObject* binaryMessenger = self.flutterViewController.binaryMessenger; - - FlutterBinaryMessengerConnection waitingForStatusConnection = [binaryMessenger - setMessageHandlerOnChannel:@"waiting_for_status" - binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) { - FlutterMethodChannel* channel = [FlutterMethodChannel - methodChannelWithName:@"driver" - binaryMessenger:binaryMessenger - codec:[FlutterJSONMethodCodec sharedInstance]]; - [channel invokeMethod:@"set_scenario" arguments:@{@"name" : @"initial_route_reply"}]; - }]; - - XCTestExpectation* customInitialRouteSet = - [self expectationWithDescription:@"Custom initial route was set on the Dart side"]; - FlutterBinaryMessengerConnection initialRoutTestChannelConnection = - [binaryMessenger setMessageHandlerOnChannel:@"initial_route_test_channel" - binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) { - NSDictionary* dict = [NSJSONSerialization JSONObjectWithData:message - options:0 - error:nil]; - NSString* initialRoute = dict[@"method"]; - if ([initialRoute isEqualToString:@"myCustomInitialRoute"]) { - [customInitialRouteSet fulfill]; - } else { - XCTFail(@"Expected initial route to be set to " - @"myCustomInitialRoute. Was set to %@ instead", - initialRoute); - } - }]; - - AppDelegate* appDelegate = (AppDelegate*)UIApplication.sharedApplication.delegate; - UIViewController* rootVC = appDelegate.window.rootViewController; - [rootVC presentViewController:self.flutterViewController animated:NO completion:nil]; - - [self waitForExpectationsWithTimeout:30.0 handler:nil]; - - [binaryMessenger cleanupConnection:waitingForStatusConnection]; - [binaryMessenger cleanupConnection:initialRoutTestChannelConnection]; -} - -@end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosTests/ScenariosTests.m b/testing/scenario_app/ios/Scenarios/ScenariosTests/ScenariosTests.m index 61610c06468a8..310f43fae4390 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosTests/ScenariosTests.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosTests/ScenariosTests.m @@ -1,6 +1,10 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +// +// ScenariosTests.m +// ScenariosTests +// +// Created by Dan Field on 7/20/19. +// Copyright © 2019 flutter. All rights reserved. +// #import diff --git a/testing/scenario_app/lib/src/initial_route_reply.dart b/testing/scenario_app/lib/src/initial_route_reply.dart deleted file mode 100644 index d53a118e842c9..0000000000000 --- a/testing/scenario_app/lib/src/initial_route_reply.dart +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// @dart = 2.6 -import 'dart:ui'; - -import 'package:scenario_app/src/channel_util.dart'; - -import 'scenario.dart'; - -/// A blank page that just sends back to the platform what the set initial -/// route is. -class InitialRouteReply extends Scenario { - /// Creates the InitialRouteReply. - /// - /// The [window] parameter must not be null. - InitialRouteReply(Window window) - : assert(window != null), - super(window); - - @override - void onBeginFrame(Duration duration) { - sendJsonMethodCall( - window: window, - channel: 'initial_route_test_channel', - method: window.defaultRouteName, - ); - } -} diff --git a/testing/scenario_app/lib/src/scenarios.dart b/testing/scenario_app/lib/src/scenarios.dart index 6aa553380d34c..e86b44b5d47e4 100644 --- a/testing/scenario_app/lib/src/scenarios.dart +++ b/testing/scenario_app/lib/src/scenarios.dart @@ -6,7 +6,6 @@ import 'dart:ui'; import 'animated_color_square.dart'; -import 'initial_route_reply.dart'; import 'locale_initialization.dart'; import 'platform_view.dart'; import 'poppable_screen.dart'; @@ -42,7 +41,6 @@ Map _scenarios = { 'platform_view_gesture_reject_after_touches_ended': () => PlatformViewForTouchIOSScenario(window, 'platform view touch', id: _viewId++, accept: false, rejectUntilTouchesEnded: true), 'tap_status_bar': () => TouchesScenario(window), 'text_semantics_focus': () => SendTextFocusScemantics(window), - 'initial_route_reply': () => InitialRouteReply(window), }; Map _currentScenarioParams = {};