diff --git a/bin/internal/engine.version b/bin/internal/engine.version index f22bfa0cf6..df75e66ba7 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -0928c1af2f45361a9473565d7946978dbc42493e +05ab04dbe8cf8ad0e27821abb785ee2655d9af0b diff --git a/dev/bots/test.dart b/dev/bots/test.dart index b2377215fb..e0cf187d6a 100644 --- a/dev/bots/test.dart +++ b/dev/bots/test.dart @@ -106,6 +106,7 @@ Future main(List args) async { print('═' * 80); await selectShard(const { 'add_to_app_tests': _runAddToAppTests, + 'add_to_app_life_cycle_tests': _runAddToAppLifeCycleTests, 'build_tests': _runBuildTests, 'framework_coverage': _runFrameworkCoverage, 'framework_tests': _runFrameworkTests, @@ -358,6 +359,17 @@ Future _runAddToAppTests() async { } } +Future _runAddToAppLifeCycleTests() async { + if (Platform.isMacOS) { + print('${green}Running add-to-app life cycle iOS integration tests$reset...'); + final String addToAppDir = path.join(flutterRoot, 'dev', 'integration_tests', 'ios_add2app_life_cycle'); + await runCommand('./build_and_test.sh', + [], + workingDirectory: addToAppDir, + ); + } +} + Future _runFrameworkTests() async { final bq.BigqueryApi bigqueryApi = await _getBigqueryApi(); diff --git a/dev/integration_tests/ios_add2app_life_cycle/.gitignore b/dev/integration_tests/ios_add2app_life_cycle/.gitignore new file mode 100644 index 0000000000..39e7c6e37d --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/.gitignore @@ -0,0 +1,69 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +.DS_Store + +## Build generated +build/ +DerivedData/ +Pods/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ +# +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +# Code Injection +# +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app_life_cycle/LICENSE b/dev/integration_tests/ios_add2app_life_cycle/LICENSE new file mode 100644 index 0000000000..8211a02c06 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/LICENSE @@ -0,0 +1,27 @@ +Copyright 2014 The Chromium Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dev/integration_tests/ios_add2app_life_cycle/Podfile b/dev/integration_tests/ios_add2app_life_cycle/Podfile new file mode 100644 index 0000000000..11981e2fe2 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/Podfile @@ -0,0 +1,15 @@ +platform :ios, '12.0' + +flutter_application_path = 'flutterapp/' + +load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') + +target 'ios_add2app' do + install_all_flutter_pods(flutter_application_path) +end + +target 'ios_add2appTests' do + inherit! :search_paths + install_flutter_engine_pod + pod 'EarlGrey' +end diff --git a/dev/integration_tests/ios_add2app_life_cycle/README.md b/dev/integration_tests/ios_add2app_life_cycle/README.md new file mode 100644 index 0000000000..351492bed2 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/README.md @@ -0,0 +1,28 @@ +# iOS Add2App Life Cycle Test + +This application demonstrates some basic functionality for Add2App, +along with a native iOS ViewController as a baseline and to demonstrate +interaction. + +The following functionality is currently implemented: + +1. A regular iOS view controller (UIViewController), similar to the default + `flutter create` template (NativeViewController.m). +1. A FlutterViewController subclass that takes over full screen. Demos showing + this both from a cold/fresh engine state and a warm engine state + (FullScreenViewController.m). +1. A demo of pushing a FlutterViewController on as a child view. +1. A demo of showing both the native and the Flutter views using a platform + channel to to interact with each other (HybridViewController.m). +1. A demo of showing two FlutterViewControllers simultaneously + (DualViewController.m). + +A few key things are tested here (IntegrationTests.m): + +1. The ability to pre-warm the engine and attach/detatch a ViewController from + it. +1. The ability to use platform channels to communicate between views. +1. The ability to simultaneously run two instances of the engine. +1. That a FlutterViewController can be freed when no longer in use (also tested + from FlutterViewControllerTests.m). +1. That a FlutterEngine can be freed when no longer in use. \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app_life_cycle/build_and_test.sh b/dev/integration_tests/ios_add2app_life_cycle/build_and_test.sh new file mode 100755 index 0000000000..89d59e17cc --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/build_and_test.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -e + +cd "$(dirname "$0")" + +pushd flutterapp +../../../../bin/flutter build ios --debug --simulator --no-codesign +popd + +pod install +os_version=$(xcrun --show-sdk-version --sdk iphonesimulator) + +PRETTY="cat" +if which xcpretty; then + PRETTY="xcpretty" +fi + +set -o pipefail && xcodebuild \ + -workspace ios_add2app.xcworkspace \ + -scheme ios_add2app \ + -sdk "iphonesimulator$os_version" \ + -destination "OS=$os_version,name=iPhone X" test | $PRETTY + diff --git a/dev/integration_tests/ios_add2app_life_cycle/flutterapp/.gitignore b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/.gitignore new file mode 100644 index 0000000000..cdecf14aaa --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/.gitignore @@ -0,0 +1,41 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +*.swp +profile + +DerivedData/ + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +build/ +.android/ +.ios/ +.flutter-plugins diff --git a/dev/integration_tests/ios_add2app_life_cycle/flutterapp/.metadata b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/.metadata new file mode 100644 index 0000000000..04ff028c3d --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 06179457d553b96b4d7421a08ac90535ca2c9632 + channel: unknown + +project_type: module diff --git a/dev/integration_tests/ios_add2app_life_cycle/flutterapp/README.md b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/README.md new file mode 100644 index 0000000000..37c971b1f4 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/README.md @@ -0,0 +1,8 @@ +# ios_add2app_life_cycle_flutter + +A new flutter module project. + +## Getting Started + +For help getting started with Flutter, view our online +[documentation](https://flutter.dev/). diff --git a/dev/integration_tests/ios_add2app_life_cycle/flutterapp/lib/main.dart b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/lib/main.dart new file mode 100644 index 0000000000..3ae04687bd --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/lib/main.dart @@ -0,0 +1,77 @@ +import 'dart:ui' as ui; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter/foundation.dart'; +import 'package:collection/collection.dart'; + +VoidCallback originalSemanticsListener; + +void main() { + WidgetsFlutterBinding.ensureInitialized(); + // Disconnects semantics listener for testing purposes. + originalSemanticsListener = ui.window.onSemanticsEnabledChanged; + ui.window.onSemanticsEnabledChanged = null; + RendererBinding.instance.setSemanticsEnabled(false); + // If the test passes, LifeCycleSpy will rewire the semantics listener back. + runApp(const LifeCycleSpy()); +} + +/// A Test widget that spies on app life cycle changes. +/// +/// It will collect the AppLifecycleState sequence during its lifetime, and it +/// will rewire semantics harness if the sequence it receives matches the +/// expected list. +/// +/// Rewiring semantics is a signal to native IOS test that the test has passed. +class LifeCycleSpy extends StatefulWidget { + const LifeCycleSpy(); + + @override + _LifeCycleSpyState createState() => _LifeCycleSpyState(); +} + +class _LifeCycleSpyState extends State with WidgetsBindingObserver { + final List _expectedLifeCycleSequence = [ + AppLifecycleState.detached, + AppLifecycleState.inactive, + AppLifecycleState.resumed, + ]; + List _actualLifeCycleSequence; + + @override + void initState(){ + super.initState(); + WidgetsBinding.instance.addObserver(this); + _actualLifeCycleSequence = [ + SchedulerBinding.instance.lifecycleState + ]; + } + + @override + void dispose() { + WidgetsBinding.instance.removeObserver(this); + super.dispose(); + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + setState(() { + _actualLifeCycleSequence = List.from(_actualLifeCycleSequence); + _actualLifeCycleSequence.add(state); + }); + } + + @override + Widget build(BuildContext context) { + if (const ListEquality().equals(_actualLifeCycleSequence, _expectedLifeCycleSequence)) { + // Rewires the semantics harness if test passes. + RendererBinding.instance.setSemanticsEnabled(true); + ui.window.onSemanticsEnabledChanged = originalSemanticsListener; + } + return const MaterialApp( + title: 'Flutter View', + home: Text('test'), + ); + } +} diff --git a/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml new file mode 100644 index 0000000000..024f945355 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml @@ -0,0 +1,110 @@ +name: ios_add2app_life_cycle_flutter +description: A new flutter module project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# Read more about versioning at semver.org. +# +# This version is used _only_ for the Runner app, which is used if you just do +# a `flutter run` or a `flutter make-host-app-editable`. It has no impact +# on any other native host app that you embed your Flutter project into. +version: 1.0.0+1 + +environment: + sdk: ">=2.0.0-dev.68.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + flutter_driver: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: 0.1.2 + + collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + meta: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + + archive: 2.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + async: 2.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + image: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + matcher: 0.12.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + path: 1.6.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.8.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + petitparser: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + quiver: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + test_api: 0.2.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add Flutter specific assets to your application, add an assets section, + # like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add Flutter specific custom fonts to your application, add a fonts + # section here, in this "flutter" section. Each entry in this list should + # have a "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages + + # This section identifies your Flutter project as a module meant for + # embedding in a native host app. These identifiers should _not_ ordinarily + # be changed after generation - they are used to ensure that the tooling can + # maintain consistency when adding or modifying assets and plugins. + # They also do not have any bearing on your native host application's + # identifiers, which may be completely independent or the same as these. + module: + androidPackage: com.example.iosadd2appflutter + iosBundleIdentifier: com.example.iosAdd2appFlutter + +# PUBSPEC CHECKSUM: 2ffc diff --git a/dev/integration_tests/ios_add2app_life_cycle/flutterapp/test/widget_test.dart b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/test/widget_test.dart new file mode 100644 index 0000000000..153f055660 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/test/widget_test.dart @@ -0,0 +1,3 @@ +void main() { + +} diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/project.pbxproj b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..d58f1f8861 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/project.pbxproj @@ -0,0 +1,632 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 09C65652A2B48A21C94FF831 /* EarlGrey.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */; }; + 24D2933821A29628008787A5 /* IntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 24D2933721A29628008787A5 /* IntegrationTests.m */; }; + 24E221BA21A28A0B008ADF09 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221B921A28A0B008ADF09 /* AppDelegate.m */; }; + 24E221C821A28A0C008ADF09 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221C721A28A0C008ADF09 /* main.m */; }; + 24E221DD21A28B23008ADF09 /* FullScreenViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221D321A28B23008ADF09 /* FullScreenViewController.m */; }; + 24E221DE21A28B23008ADF09 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221D421A28B23008ADF09 /* MainViewController.m */; }; + 24E221E021A28B23008ADF09 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24E221D721A28B23008ADF09 /* Launch Screen.storyboard */; }; + 24E221E221A28B36008ADF09 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 24E221E121A28B36008ADF09 /* Assets.xcassets */; }; + 4C21FEB4D629B570C74073D1 /* libPods-ios_add2appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F90B141A9A8A680033E97924 /* libPods-ios_add2appTests.a */; }; + 8BDD73EC12DFA6CD2AC4EEDA /* EarlGrey.framework in EarlGrey Copy Files */ = {isa = PBXBuildFile; fileRef = DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + DB9A200AFEB7AAE22B4E12E4 /* libPods-ios_add2app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A318514E0307AE0FF0EFC76 /* libPods-ios_add2app.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 24D2933A21A29628008787A5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 24E221AD21A28A0B008ADF09 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 24E221B421A28A0B008ADF09; + remoteInfo = ios_add2app; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + C155689B0EB46CB1FF251109 /* EarlGrey Copy Files */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(TEST_HOST)/../"; + dstSubfolderSpec = 0; + files = ( + 8BDD73EC12DFA6CD2AC4EEDA /* EarlGrey.framework in EarlGrey Copy Files */, + ); + name = "EarlGrey Copy Files"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 16D27B9BE77DC8804292A9A9 /* Pods-ios_add2appUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appUITests/Pods-ios_add2appUITests.release.xcconfig"; sourceTree = ""; }; + 24D2933521A29627008787A5 /* ios_add2appTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ios_add2appTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 24D2933721A29628008787A5 /* IntegrationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IntegrationTests.m; sourceTree = ""; }; + 24D2933921A29628008787A5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 24E221B521A28A0B008ADF09 /* ios_add2app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ios_add2app.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 24E221B821A28A0B008ADF09 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 24E221B921A28A0B008ADF09 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 24E221C621A28A0C008ADF09 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 24E221C721A28A0C008ADF09 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 24E221CF21A28B22008ADF09 /* FullScreenViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullScreenViewController.h; sourceTree = ""; }; + 24E221D221A28B23008ADF09 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 24E221D321A28B23008ADF09 /* FullScreenViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FullScreenViewController.m; sourceTree = ""; }; + 24E221D421A28B23008ADF09 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + 24E221D721A28B23008ADF09 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; + 24E221E121A28B36008ADF09 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 36DA6BEAA5127D74EC6E3E13 /* Pods-ios_add2appUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appUITests/Pods-ios_add2appUITests.debug.xcconfig"; sourceTree = ""; }; + 52EA0B290EEBC1D28BF6E803 /* libPods-ios_add2appUITests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios_add2appUITests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 74266A4D94FA1C3157B5B560 /* Pods-ios_add2appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.debug.xcconfig"; sourceTree = ""; }; + 762E954C71D922C091619CD4 /* Pods-ios_add2app-ios_add2appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2app-ios_add2appTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2app-ios_add2appTests/Pods-ios_add2app-ios_add2appTests.debug.xcconfig"; sourceTree = ""; }; + 7A318514E0307AE0FF0EFC76 /* libPods-ios_add2app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios_add2app.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 83017A33946358F55BAE24E1 /* Pods-ios_add2appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.release.xcconfig"; sourceTree = ""; }; + 98A4882F55A3E107DFCB67D8 /* Pods-ios_add2app-ios_add2appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2app-ios_add2appTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2app-ios_add2appTests/Pods-ios_add2app-ios_add2appTests.release.xcconfig"; sourceTree = ""; }; + A18D4CDABD6795975FD6B49F /* Pods-ios_add2app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2app.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.release.xcconfig"; sourceTree = ""; }; + CCFA174387D083C931FB85D0 /* Pods-ios_add2app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2app.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.debug.xcconfig"; sourceTree = ""; }; + DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EarlGrey.framework; path = Pods/EarlGrey/EarlGrey/EarlGrey.framework; sourceTree = SOURCE_ROOT; }; + F90B141A9A8A680033E97924 /* libPods-ios_add2appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios_add2appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 24D2933221A29627008787A5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 09C65652A2B48A21C94FF831 /* EarlGrey.framework in Frameworks */, + 4C21FEB4D629B570C74073D1 /* libPods-ios_add2appTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 24E221B221A28A0B008ADF09 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DB9A200AFEB7AAE22B4E12E4 /* libPods-ios_add2app.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 24D2933621A29628008787A5 /* ios_add2appTests */ = { + isa = PBXGroup; + children = ( + 24D2933721A29628008787A5 /* IntegrationTests.m */, + 24D2933921A29628008787A5 /* Info.plist */, + ); + path = ios_add2appTests; + sourceTree = ""; + }; + 24E221AC21A28A0B008ADF09 = { + isa = PBXGroup; + children = ( + 24E221B721A28A0B008ADF09 /* ios_add2app */, + 24D2933621A29628008787A5 /* ios_add2appTests */, + 24E221B621A28A0B008ADF09 /* Products */, + F8E51775C9B1473BB9A1386D /* Pods */, + 8403FDDD872DC11EF3710BB4 /* Frameworks */, + ); + sourceTree = ""; + }; + 24E221B621A28A0B008ADF09 /* Products */ = { + isa = PBXGroup; + children = ( + 24E221B521A28A0B008ADF09 /* ios_add2app.app */, + 24D2933521A29627008787A5 /* ios_add2appTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 24E221B721A28A0B008ADF09 /* ios_add2app */ = { + isa = PBXGroup; + children = ( + 24E221E121A28B36008ADF09 /* Assets.xcassets */, + 24E221CF21A28B22008ADF09 /* FullScreenViewController.h */, + 24E221D321A28B23008ADF09 /* FullScreenViewController.m */, + 24E221D721A28B23008ADF09 /* Launch Screen.storyboard */, + 24E221D221A28B23008ADF09 /* MainViewController.h */, + 24E221D421A28B23008ADF09 /* MainViewController.m */, + 24E221B821A28A0B008ADF09 /* AppDelegate.h */, + 24E221B921A28A0B008ADF09 /* AppDelegate.m */, + 24E221C621A28A0C008ADF09 /* Info.plist */, + 24E221C721A28A0C008ADF09 /* main.m */, + ); + path = ios_add2app; + sourceTree = ""; + }; + 8403FDDD872DC11EF3710BB4 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7A318514E0307AE0FF0EFC76 /* libPods-ios_add2app.a */, + DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */, + 52EA0B290EEBC1D28BF6E803 /* libPods-ios_add2appUITests.a */, + F90B141A9A8A680033E97924 /* libPods-ios_add2appTests.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + F8E51775C9B1473BB9A1386D /* Pods */ = { + isa = PBXGroup; + children = ( + CCFA174387D083C931FB85D0 /* Pods-ios_add2app.debug.xcconfig */, + A18D4CDABD6795975FD6B49F /* Pods-ios_add2app.release.xcconfig */, + 36DA6BEAA5127D74EC6E3E13 /* Pods-ios_add2appUITests.debug.xcconfig */, + 16D27B9BE77DC8804292A9A9 /* Pods-ios_add2appUITests.release.xcconfig */, + 74266A4D94FA1C3157B5B560 /* Pods-ios_add2appTests.debug.xcconfig */, + 83017A33946358F55BAE24E1 /* Pods-ios_add2appTests.release.xcconfig */, + 762E954C71D922C091619CD4 /* Pods-ios_add2app-ios_add2appTests.debug.xcconfig */, + 98A4882F55A3E107DFCB67D8 /* Pods-ios_add2app-ios_add2appTests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 24D2933421A29627008787A5 /* ios_add2appTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 24D2933C21A29628008787A5 /* Build configuration list for PBXNativeTarget "ios_add2appTests" */; + buildPhases = ( + DE5CDCD8B3565EAB9F38F455 /* [CP] Check Pods Manifest.lock */, + 24D2933121A29627008787A5 /* Sources */, + 24D2933221A29627008787A5 /* Frameworks */, + 24D2933321A29627008787A5 /* Resources */, + C155689B0EB46CB1FF251109 /* EarlGrey Copy Files */, + E32E699BE7026038F5987095 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 24D2933B21A29628008787A5 /* PBXTargetDependency */, + ); + name = ios_add2appTests; + productName = ios_add2appTests; + productReference = 24D2933521A29627008787A5 /* ios_add2appTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 24E221B421A28A0B008ADF09 /* ios_add2app */ = { + isa = PBXNativeTarget; + buildConfigurationList = 24E221CB21A28A0C008ADF09 /* Build configuration list for PBXNativeTarget "ios_add2app" */; + buildPhases = ( + 4375EE880A727341E9C9A57D /* [CP] Check Pods Manifest.lock */, + CE6831C2A33C6C5C84521FDE /* [CP-User] Run Flutter Build Script */, + 24E221B121A28A0B008ADF09 /* Sources */, + 24E221B221A28A0B008ADF09 /* Frameworks */, + 24E221B321A28A0B008ADF09 /* Resources */, + 7FADF19EC61F97E525982780 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ios_add2app; + productName = ios_add2app; + productReference = 24E221B521A28A0B008ADF09 /* ios_add2app.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 24E221AD21A28A0B008ADF09 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1000; + ORGANIZATIONNAME = Flutter.io; + TargetAttributes = { + 24D2933421A29627008787A5 = { + CreatedOnToolsVersion = 10.0; + TestTargetID = 24E221B421A28A0B008ADF09; + }; + 24E221B421A28A0B008ADF09 = { + CreatedOnToolsVersion = 10.0; + }; + }; + }; + buildConfigurationList = 24E221B021A28A0B008ADF09 /* Build configuration list for PBXProject "ios_add2app" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 24E221AC21A28A0B008ADF09; + productRefGroup = 24E221B621A28A0B008ADF09 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 24E221B421A28A0B008ADF09 /* ios_add2app */, + 24D2933421A29627008787A5 /* ios_add2appTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 24D2933321A29627008787A5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 24E221B321A28A0B008ADF09 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 24E221E021A28B23008ADF09 /* Launch Screen.storyboard in Resources */, + 24E221E221A28B36008ADF09 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4375EE880A727341E9C9A57D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ios_add2app-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 7FADF19EC61F97E525982780 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + CE6831C2A33C6C5C84521FDE /* [CP-User] Run Flutter Build Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/flutterapp/.metadata", + "${SRCROOT}/flutterapp/.ios/Flutter/App.framework/App", + "${SRCROOT}/flutterapp/.ios/Flutter/engine/Flutter.framework/Flutter", + "${SRCROOT}/flutterapp/.ios/Flutter/flutter_export_environment.sh", + ); + name = "[CP-User] Run Flutter Build Script"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -e\nset -u\nsource \"${SRCROOT}/flutterapp/.ios/Flutter/flutter_export_environment.sh\"\n\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh build"; + }; + DE5CDCD8B3565EAB9F38F455 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ios_add2appTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E32E699BE7026038F5987095 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 24D2933121A29627008787A5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 24D2933821A29628008787A5 /* IntegrationTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 24E221B121A28A0B008ADF09 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 24E221C821A28A0C008ADF09 /* main.m in Sources */, + 24E221DE21A28B23008ADF09 /* MainViewController.m in Sources */, + 24E221DD21A28B23008ADF09 /* FullScreenViewController.m in Sources */, + 24E221BA21A28A0B008ADF09 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 24D2933B21A29628008787A5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 24E221B421A28A0B008ADF09 /* ios_add2app */; + targetProxy = 24D2933A21A29628008787A5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 24D2933D21A29628008787A5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 74266A4D94FA1C3157B5B560 /* Pods-ios_add2appTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = S8QB4VV633; + INFOPLIST_FILE = ios_add2appTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.test.ios-add2appTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ios_add2app.app/ios_add2app"; + }; + name = Debug; + }; + 24D2933E21A29628008787A5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 83017A33946358F55BAE24E1 /* Pods-ios_add2appTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = S8QB4VV633; + INFOPLIST_FILE = ios_add2appTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.test.ios-add2appTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ios_add2app.app/ios_add2app"; + }; + name = Release; + }; + 24E221C921A28A0C008ADF09 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_PEDANTIC = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + WARNING_CFLAGS = "-Wno-gnu"; + WARNING_LDFLAGS = ( + "-Wall", + "-Werror", + ); + }; + name = Debug; + }; + 24E221CA21A28A0C008ADF09 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_PEDANTIC = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + WARNING_CFLAGS = "-Wno-gnu"; + WARNING_LDFLAGS = ( + "-Wall", + "-Werror", + ); + }; + name = Release; + }; + 24E221CC21A28A0C008ADF09 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CCFA174387D083C931FB85D0 /* Pods-ios_add2app.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = S8QB4VV633; + INFOPLIST_FILE = ios_add2app/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.test.ios-add2app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 24E221CD21A28A0C008ADF09 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A18D4CDABD6795975FD6B49F /* Pods-ios_add2app.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = S8QB4VV633; + INFOPLIST_FILE = ios_add2app/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.test.ios-add2app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 24D2933C21A29628008787A5 /* Build configuration list for PBXNativeTarget "ios_add2appTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 24D2933D21A29628008787A5 /* Debug */, + 24D2933E21A29628008787A5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 24E221B021A28A0B008ADF09 /* Build configuration list for PBXProject "ios_add2app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 24E221C921A28A0C008ADF09 /* Debug */, + 24E221CA21A28A0C008ADF09 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 24E221CB21A28A0C008ADF09 /* Build configuration list for PBXNativeTarget "ios_add2app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 24E221CC21A28A0C008ADF09 /* Debug */, + 24E221CD21A28A0C008ADF09 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 24E221AD21A28A0B008ADF09 /* Project object */; +} diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..919434a625 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/xcshareddata/xcschemes/ios_add2app.xcscheme b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/xcshareddata/xcschemes/ios_add2app.xcscheme new file mode 100644 index 0000000000..8be77125db --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcodeproj/xcshareddata/xcschemes/ios_add2app.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..a22b612a0c --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/AppDelegate.h b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/AppDelegate.h new file mode 100644 index 0000000000..ff15e9224b --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/AppDelegate.h @@ -0,0 +1,12 @@ +// Copyright 2018 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 + +@interface AppDelegate : FlutterAppDelegate + +@property(nonatomic, strong, readonly) FlutterEngine* engine; + +@end diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/AppDelegate.m b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/AppDelegate.m new file mode 100644 index 0000000000..72188c805f --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/AppDelegate.m @@ -0,0 +1,35 @@ +// Copyright 2018 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 "AppDelegate.h" +#import "MainViewController.h" + +@interface AppDelegate () + +@property(nonatomic, strong, readwrite) FlutterEngine* engine; + +@end + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + + MainViewController *mainViewController = [[MainViewController alloc] init]; + UINavigationController *navigationController = [[UINavigationController alloc] + initWithRootViewController:mainViewController]; + + navigationController.navigationBar.translucent = NO; + + self.engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; + [self.engine runWithEntrypoint:nil]; + + self.window.rootViewController = navigationController; + [self.window makeKeyAndVisible]; + + return YES; +} + +@end diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Contents.json b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..d36b1fab2d --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000..b6a5d3f48e Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000..28c6bf0301 Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000..2ccbfd967d Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000..f091b6b0bc Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000000..4cde12118d Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000..d0ef06e7ed Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000000..dcdc2306c2 Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000000..2ccbfd967d Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000..c8f9ed8f5c Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000..a6d6b8609d Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000..a6d6b8609d Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000..75b2d164a5 Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000..c4df70d39d Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000000..6a84f41e14 Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000..d0e1f58536 Binary files /dev/null and b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/Contents.json b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/Contents.json new file mode 100644 index 0000000000..da4a164c91 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/FullScreenViewController.h b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/FullScreenViewController.h new file mode 100644 index 0000000000..f2a79aa36b --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/FullScreenViewController.h @@ -0,0 +1,13 @@ +// Copyright 2018 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface FullScreenViewController : FlutterViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/FullScreenViewController.m b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/FullScreenViewController.m new file mode 100644 index 0000000000..ce612cf354 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/FullScreenViewController.m @@ -0,0 +1,39 @@ +// Copyright 2018 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 "FullScreenViewController.h" + +@interface FullScreenViewController () + +@end + +@implementation FullScreenViewController + +-(void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + self.title = @"Full Screen Flutter"; + self.navigationController.navigationBarHidden = YES; + self.navigationController.hidesBarsOnSwipe = YES; +} + +-(void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + self.navigationController.navigationBarHidden = NO; + self.navigationController.hidesBarsOnSwipe = NO; + if (self.isMovingFromParentViewController) { + // Note that if we were doing things that might cause the VC + // to disappear (like using the image_picker plugin) + // we shouldn't do this. But in this case we know we're + // just going back to the navigation controller. + // If we needed Flutter to tell us when we could actually go away, + // we'd need to communicate over a method channel with it. + [self.engine setViewController:nil]; + } +} + +-(BOOL)prefersStatusBarHidden { + return true; +} + +@end diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Info.plist b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Info.plist new file mode 100644 index 0000000000..08cae2a8dc --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + Launch Screen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Launch Screen.storyboard b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Launch Screen.storyboard new file mode 100644 index 0000000000..6a6b1b8249 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/Launch Screen.storyboard @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/MainViewController.h b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/MainViewController.h new file mode 100644 index 0000000000..70ace15225 --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/MainViewController.h @@ -0,0 +1,10 @@ +// Copyright 2018 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 + +@interface MainViewController : UIViewController + +@end diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/MainViewController.m b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/MainViewController.m new file mode 100644 index 0000000000..e826221bbd --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/MainViewController.m @@ -0,0 +1,63 @@ +// Copyright 2018 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 "MainViewController.h" + +#import "AppDelegate.h" +#import "FullScreenViewController.h" + +@interface MainViewController () + +@property(nonatomic, strong) UIStackView* stackView; + +@end + + +@implementation MainViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + [self.view setFrame:self.view.window.bounds]; + self.title = @"Flutter iOS Demos"; + self.view.backgroundColor = UIColor.whiteColor; + + self.stackView = [[UIStackView alloc] initWithFrame:self.view.frame]; + self.stackView.axis = UILayoutConstraintAxisVertical; + self.stackView.distribution = UIStackViewDistributionEqualSpacing; + self.stackView.alignment = UIStackViewAlignmentCenter; + self.stackView.autoresizingMask = + UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.stackView.layoutMargins = UIEdgeInsetsMake(0, 0, 50, 0); + self.stackView.layoutMarginsRelativeArrangement = YES; + [self.view addSubview:_stackView]; + + [self addButton:@"Full Screen (Cold)" action:@selector(showFullScreenCold)]; +} + +- (void)showFullScreenCold { + FlutterEngine *engine = + [(AppDelegate *)[[UIApplication sharedApplication] delegate] engine]; + + FullScreenViewController *flutterViewController = + [[FullScreenViewController alloc] initWithEngine:engine + nibName:nil + bundle:nil]; + [self.navigationController + pushViewController:flutterViewController + animated:NO]; // Animating this is janky because of + // transitions with header on the native side. + // It's especially bad with a cold engine. +} + +- (void)addButton:(NSString *)title action:(SEL)action { + UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; + [button setTitle:title forState:UIControlStateNormal]; + [button addTarget:self + action:action + forControlEvents:UIControlEventTouchUpInside]; + [self.stackView addArrangedSubview:button]; +} + +@end diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/main.m b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/main.m new file mode 100644 index 0000000000..01f25d2dee --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2app/main.m @@ -0,0 +1,12 @@ +// Copyright 2018 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 "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2appTests/Info.plist b/dev/integration_tests/ios_add2app_life_cycle/ios_add2appTests/Info.plist new file mode 100644 index 0000000000..6c40a6cd0c --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2appTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/dev/integration_tests/ios_add2app_life_cycle/ios_add2appTests/IntegrationTests.m b/dev/integration_tests/ios_add2app_life_cycle/ios_add2appTests/IntegrationTests.m new file mode 100644 index 0000000000..06e8cb87cc --- /dev/null +++ b/dev/integration_tests/ios_add2app_life_cycle/ios_add2appTests/IntegrationTests.m @@ -0,0 +1,45 @@ +// Copyright 2018 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" +#import "FullScreenViewController.h" + +@interface FlutterTests : XCTestCase +@end + +@implementation FlutterTests + +- (void)expectSemanticsNotification:(UIViewController*)viewController + engine:(FlutterEngine*)engine { + // Flutter app will only send semantics update if test passes in main.dart. + [self expectationForNotification:FlutterSemanticsUpdateNotification object:viewController handler:nil]; + [self waitForExpectationsWithTimeout:30.0 handler:nil]; +} + +- (void)checkAppConnection { + FlutterEngine *engine = [((AppDelegate *)[[UIApplication sharedApplication] delegate]) engine]; + UINavigationController *navController = + (UINavigationController *)((AppDelegate *) + [[UIApplication sharedApplication] + delegate]) + .window.rootViewController; + __weak UIViewController *weakViewController = navController.visibleViewController; + [self expectSemanticsNotification:weakViewController + engine:engine]; + GREYAssertNotNil(weakViewController, + @"Expected non-nil FullScreenViewController."); +} + +- (void)testFullScreenCanPop { + [[EarlGrey selectElementWithMatcher:grey_keyWindow()] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Full Screen (Cold)")] + performAction:grey_tap()]; + [self checkAppConnection]; +} + +@end diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart index d732a8c27b..6550bbbc2a 100644 --- a/packages/flutter/lib/src/scheduler/binding.dart +++ b/packages/flutter/lib/src/scheduler/binding.dart @@ -333,7 +333,7 @@ mixin SchedulerBinding on BindingBase, ServicesBinding { _setFramesEnabledState(true); break; case AppLifecycleState.paused: - case AppLifecycleState.suspending: + case AppLifecycleState.detached: _setFramesEnabledState(false); break; } @@ -352,8 +352,8 @@ mixin SchedulerBinding on BindingBase, ServicesBinding { return AppLifecycleState.resumed; case 'AppLifecycleState.inactive': return AppLifecycleState.inactive; - case 'AppLifecycleState.suspending': - return AppLifecycleState.suspending; + case 'AppLifecycleState.detached': + return AppLifecycleState.detached; } return null; } diff --git a/packages/flutter/test/widgets/binding_attach_root_widget_test.dart b/packages/flutter/test/widgets/binding_attach_root_widget_test.dart index 32918a4399..c539b17920 100644 --- a/packages/flutter/test/widgets/binding_attach_root_widget_test.dart +++ b/packages/flutter/test/widgets/binding_attach_root_widget_test.dart @@ -2,7 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:typed_data'; + import 'package:flutter/scheduler.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; @@ -10,6 +13,9 @@ void main() { test('attachRootWidget will schedule a frame', () async { final WidgetsFlutterBinding binding = WidgetsFlutterBinding.ensureInitialized(); expect(SchedulerBinding.instance.hasScheduledFrame, isFalse); + // Framework starts with detached statue. Sends resumed signal to enable frame. + final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.resumed'); + await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { }); binding.attachRootWidget(const Placeholder()); expect(SchedulerBinding.instance.hasScheduledFrame, isTrue); diff --git a/packages/flutter/test/widgets/binding_frame_scheduling_test.dart b/packages/flutter/test/widgets/binding_frame_scheduling_test.dart index 3d52d233e6..1edc3db39a 100644 --- a/packages/flutter/test/widgets/binding_frame_scheduling_test.dart +++ b/packages/flutter/test/widgets/binding_frame_scheduling_test.dart @@ -2,9 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:typed_data'; import 'dart:ui' show window; import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; void main() { @@ -22,6 +24,10 @@ void main() { expect(window.onBeginFrame, isNull); expect(window.onDrawFrame, isNull); + // Framework starts with detached statue. Sends resumed signal to enable frame. + final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.resumed'); + await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { }); + // Frame callbacks are registered lazily when a frame is scheduled. binding.scheduleFrame(); expect(window.onBeginFrame, isNotNull); diff --git a/packages/flutter/test/widgets/binding_test.dart b/packages/flutter/test/widgets/binding_test.dart index 31695e25ee..d4159e6e2c 100644 --- a/packages/flutter/test/widgets/binding_test.dart +++ b/packages/flutter/test/widgets/binding_test.dart @@ -68,9 +68,9 @@ void main() { await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { }); expect(observer.lifecycleState, AppLifecycleState.inactive); - message = const StringCodec().encodeMessage('AppLifecycleState.suspending'); + message = const StringCodec().encodeMessage('AppLifecycleState.detached'); await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { }); - expect(observer.lifecycleState, AppLifecycleState.suspending); + expect(observer.lifecycleState, AppLifecycleState.detached); }); testWidgets('didPushRoute callback', (WidgetTester tester) async { @@ -105,7 +105,7 @@ void main() { await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { }); expect(tester.binding.hasScheduledFrame, isFalse); - message = const StringCodec().encodeMessage('AppLifecycleState.suspending'); + message = const StringCodec().encodeMessage('AppLifecycleState.detached'); await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { }); expect(tester.binding.hasScheduledFrame, isFalse); diff --git a/packages/flutter_tools/test/integration.shard/test_data/hot_reload_project.dart b/packages/flutter_tools/test/integration.shard/test_data/hot_reload_project.dart index 7f155d4fb3..c3052398f7 100644 --- a/packages/flutter_tools/test/integration.shard/test_data/hot_reload_project.dart +++ b/packages/flutter_tools/test/integration.shard/test_data/hot_reload_project.dart @@ -23,8 +23,15 @@ class HotReloadProject extends Project { final String main = r''' import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; + import 'package:flutter/services.dart'; + import 'package:flutter/widgets.dart'; - void main() => runApp(MyApp()); + void main() async { + WidgetsFlutterBinding.ensureInitialized(); + final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.resumed'); + await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { }); + runApp(MyApp()); + } int count = 1;