diff --git a/dev/bots/firebase_testlab.sh b/dev/bots/firebase_testlab.sh
index 14be500e618..41e29f088e2 100755
--- a/dev/bots/firebase_testlab.sh
+++ b/dev/bots/firebase_testlab.sh
@@ -1,13 +1,17 @@
#!/bin/bash
+# The tests to run on Firebase Test Lab.
+# Currently, the test consists on building an Android App Bundle and ensuring
+# that the app doesn't crash upon startup.
+tests=(
+ "dev/integration_tests/release_smoke_test"
+ "dev/integration_tests/abstract_method_smoke_test"
+)
+
set -e
GIT_REVISION=$(git rev-parse HEAD)
-pushd dev/integration_tests/release_smoke_test
-
-../../../bin/flutter build appbundle --target-platform android-arm,android-arm64
-
# New contributors will not have permissions to run this test - they won't be
# able to access the service account information. We should just mark the test
# as passed - it will run fine on post submit, where it will still catch
@@ -22,21 +26,29 @@ echo $GCLOUD_FIREBASE_TESTLAB_KEY > ${HOME}/gcloud-service-key.json
gcloud auth activate-service-account --key-file=${HOME}/gcloud-service-key.json
gcloud --quiet config set project flutter-infra
-# Firebase Test Lab tests are currently known to be failing with
-# "Firebase Test Lab infrastructure failure: Error during preprocessing"
-# Remove "|| exit 0" once the failures are resolved
-# https://github.com/flutter/flutter/issues/36501
+function test_app_bundle() {
+ pushd "$@"
+ ../../../bin/flutter build appbundle --target-platform android-arm,android-arm64
-# Run the test.
-gcloud firebase test android run --type robo \
- --app build/app/outputs/bundle/release/app.aab \
- --timeout 2m \
- --results-bucket=gs://flutter_firebase_testlab \
- --results-dir=release_smoke_test/$GIT_REVISION/$CIRRUS_BUILD_ID || exit 0
+ # Firebase Test Lab tests are currently known to be failing with
+ # "Firebase Test Lab infrastructure failure: Error during preprocessing"
+ # Remove "|| exit 0" once the failures are resolved
+ # https://github.com/flutter/flutter/issues/36501
-# Check logcat for "E/flutter" - if it's there, something's wrong.
-gsutil cp gs://flutter_firebase_testlab/release_smoke_test/$GIT_REVISION/$CIRRUS_BUILD_ID/walleye-26-en-portrait/logcat /tmp/logcat
-! grep "E/flutter" /tmp/logcat || false
-grep "I/flutter" /tmp/logcat
+ # Run the test.
+ gcloud firebase test android run --type robo \
+ --app build/app/outputs/bundle/release/app.aab \
+ --timeout 2m \
+ --results-bucket=gs://flutter_firebase_testlab \
+ --results-dir="$@"/"$GIT_REVISION"/"$CIRRUS_BUILD_ID" || exit 0
-popd
+ # Check logcat for "E/flutter" - if it's there, something's wrong.
+ gsutil cp gs://flutter_firebase_testlab/"$@"/"$GIT_REVISION"/"$CIRRUS_BUILD_ID"/walleye-26-en-portrait/logcat /tmp/logcat
+ ! grep "E/flutter" /tmp/logcat || false
+ grep "I/flutter" /tmp/logcat
+ popd
+}
+
+for test in ${tests[*]}; do
+ test_app_bundle $test
+done
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/app/build.gradle b/dev/integration_tests/abstract_method_smoke_test/android/app/build.gradle
new file mode 100644
index 00000000000..ed57ad71f0a
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/app/build.gradle
@@ -0,0 +1,71 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion 29
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId "com.example.abstract_method_smoke_test"
+ minSdkVersion 21
+ targetSdkVersion 29
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ signingConfig signingConfigs.debug
+ }
+ }
+
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/app/src/debug/AndroidManifest.xml b/dev/integration_tests/abstract_method_smoke_test/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 00000000000..122c170ab62
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/AndroidManifest.xml b/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000000..87652c589d6
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/kotlin/com/example/abstract_method_smoke_test/MainActivity.kt b/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/kotlin/com/example/abstract_method_smoke_test/MainActivity.kt
new file mode 100644
index 00000000000..4b7eeb7b1fc
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/kotlin/com/example/abstract_method_smoke_test/MainActivity.kt
@@ -0,0 +1,19 @@
+package com.example.abstract_method_smoke_test
+
+import android.content.Context
+import android.os.Bundle
+import android.view.inputmethod.InputMethodManager
+import io.flutter.app.FlutterActivity
+import io.flutter.plugins.GeneratedPluginRegistrant
+
+class MainActivity: FlutterActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ GeneratedPluginRegistrant.registerWith(this)
+
+ // Triggers the Android keyboard, which causes the resize of the Flutter view.
+ // https://github.com/flutter/flutter/issues/40126
+ val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
+ }
+}
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/res/drawable/launch_background.xml b/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 00000000000..304732f8842
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/res/values/styles.xml b/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/res/values/styles.xml
new file mode 100644
index 00000000000..00fa4417cfb
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/app/src/profile/AndroidManifest.xml b/dev/integration_tests/abstract_method_smoke_test/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 00000000000..122c170ab62
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/build.gradle b/dev/integration_tests/abstract_method_smoke_test/android/build.gradle
new file mode 100644
index 00000000000..3100ad2d555
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/build.gradle
@@ -0,0 +1,31 @@
+buildscript {
+ ext.kotlin_version = '1.3.50'
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/gradle.properties b/dev/integration_tests/abstract_method_smoke_test/android/gradle.properties
new file mode 100644
index 00000000000..d2032bce8be
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx1536M
+android.enableJetifier=true
+android.useAndroidX=true
+android.enableR8=true
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/gradle/wrapper/gradle-wrapper.properties b/dev/integration_tests/abstract_method_smoke_test/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000000..9ec7236c631
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jun 23 08:50:38 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.1-all.zip
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle b/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle
new file mode 100644
index 00000000000..5a2f14fb18f
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle
@@ -0,0 +1,15 @@
+include ':app'
+
+def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+
+def plugins = new Properties()
+def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
+if (pluginsFile.exists()) {
+ pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
+}
+
+plugins.each { name, path ->
+ def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
+ include ":$name"
+ project(":$name").projectDir = pluginDirectory
+}
diff --git a/dev/integration_tests/abstract_method_smoke_test/lib/main.dart b/dev/integration_tests/abstract_method_smoke_test/lib/main.dart
new file mode 100644
index 00000000000..9720d8fe737
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/lib/main.dart
@@ -0,0 +1,61 @@
+import 'package:flutter/material.dart';
+import 'package:google_maps_flutter/google_maps_flutter.dart';
+
+void main() => runApp(MyApp());
+
+class MyApp extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ title: 'Flutter Demo',
+ theme: ThemeData(
+ primarySwatch: Colors.blue,
+ ),
+ home: HomePage(),
+ );
+ }
+}
+
+class HomePage extends StatefulWidget {
+ @override
+ _HomePage createState() => _HomePage();
+}
+
+class _HomePage extends State {
+ @override
+ void initState() {
+ super.initState();
+
+ // Trigger the second route.
+ // https://github.com/flutter/flutter/issues/40126
+ WidgetsBinding.instance.addPostFrameCallback((_) async {
+ Navigator.of(context).push(
+ MaterialPageRoute(builder: (_) => SecondPage()));
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return const Scaffold();
+ }
+}
+
+class SecondPage extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: Column(
+ children: [
+ TextFormField(),
+ const Expanded(
+ child: GoogleMap(
+ initialCameraPosition: CameraPosition(
+ target: LatLng(0, 0)
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
\ No newline at end of file
diff --git a/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml b/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml
new file mode 100644
index 00000000000..cc95e731a19
--- /dev/null
+++ b/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml
@@ -0,0 +1,47 @@
+name: abstract_method_smoke_test
+description: A new Flutter project.
+
+version: 1.0.0+1
+
+environment:
+ sdk: ">=2.1.0 <3.0.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+ google_maps_flutter: 0.5.21+4
+
+ 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
+
+ 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:
+ uses-material-design: true
+
+# PUBSPEC CHECKSUM: 3231
diff --git a/packages/flutter_tools/gradle/flutter.gradle b/packages/flutter_tools/gradle/flutter.gradle
index 606d3a3bd2c..bbc1c8e2933 100644
--- a/packages/flutter_tools/gradle/flutter.gradle
+++ b/packages/flutter_tools/gradle/flutter.gradle
@@ -332,9 +332,11 @@ class FlutterPlugin implements Plugin {
}
Closure addEmbeddingCompileOnlyDependency = { buildType ->
String flutterBuildMode = buildModeFor(buildType)
- // Add the embedding as a compile only dependency to the plugin.
+ // In AGP 3.5, the embedding must be added as an API implementation,
+ // so java8 features are desugared against the runtime classpath.
+ // For more, see https://github.com/flutter/flutter/issues/40126
if (flutterJar) {
- addCompileOnlyDependency(
+ addApiDependencies(
pluginProject,
buildType.name,
project.files {
@@ -343,7 +345,7 @@ class FlutterPlugin implements Plugin {
)
return
}
- addCompileOnlyDependency(
+ addApiDependencies(
pluginProject,
buildType.name,
"io.flutter:flutter_embedding_$flutterBuildMode:1.0.0-$engineVersion",