Flutter 1.17.2 cherrypicks (#58050)
* fix segment hit test behavior (#57461)
* Making DropdownButtonFormField to re-render if parent widget changes (#57037)
* Update DropdownButtonFormField's state if widget updates
Co-authored-by: Shi-Hao Hong <shihaohong@google.com>
* throw more specific toolexit when git fails during upgrade (#57162)
* [flutter_tools] Refresh VM state before executing hot reload (#53960)
* Update engine hash for 1.17.2
* Remove MaterialControls from examples/flutter_view (#57621)
Co-authored-by: Jenn Magder <magder@google.com>
* Prevent building non-android plugins in build aar (#58018)
* Allow FLUTTER_APPLICATION_PATH to be null for misconfigured Xcode projects (#57701)
* Don't import plugins that don't support android in settings.gradle (#54407)
Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
Co-authored-by: Pedro Massango <pedromassango.developer@gmail.com>
Co-authored-by: Shi-Hao Hong <shihaohong@google.com>
Co-authored-by: Christopher Fujino <christopherfujino@gmail.com>
Co-authored-by: Jason Simmons <jason-simmons@users.noreply.github.com>
Co-authored-by: stuartmorgan <stuartmorgan@google.com>
Co-authored-by: Jenn Magder <magder@google.com>
Co-authored-by: Emmanuel Garcia <egarciad@google.com>
diff --git a/bin/internal/engine.version b/bin/internal/engine.version
index d9d42ce..ed199b1 100644
--- a/bin/internal/engine.version
+++ b/bin/internal/engine.version
@@ -1 +1 @@
-6bc433c6b6b5b98dcf4cc11aff31cdee90849f32
+b851c718295a896918dc93cb1ff14f2f895a1b90
diff --git a/dev/benchmarks/macrobenchmarks/android/settings.gradle b/dev/benchmarks/macrobenchmarks/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/dev/benchmarks/macrobenchmarks/android/settings.gradle
+++ b/dev/benchmarks/macrobenchmarks/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/benchmarks/test_apps/stocks/android/settings.gradle b/dev/benchmarks/test_apps/stocks/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/benchmarks/test_apps/stocks/android/settings.gradle
+++ b/dev/benchmarks/test_apps/stocks/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/bots/test.dart b/dev/bots/test.dart
index b6dea10..318244f 100644
--- a/dev/bots/test.dart
+++ b/dev/bots/test.dart
@@ -976,6 +976,7 @@
// TODO(ianh): Fails on macOS looking for "dexdump", https://github.com/flutter/flutter/issues/42494
if (!Platform.isMacOS) () => _runDevicelabTest('gradle_jetifier_test', environment: gradleEnvironment),
() => _runDevicelabTest('gradle_non_android_plugin_test', environment: gradleEnvironment),
+ () => _runDevicelabTest('gradle_deprecated_settings_test', environment: gradleEnvironment),
() => _runDevicelabTest('gradle_plugin_bundle_test', environment: gradleEnvironment),
() => _runDevicelabTest('gradle_plugin_fat_apk_test', environment: gradleEnvironment),
() => _runDevicelabTest('gradle_plugin_light_apk_test', environment: gradleEnvironment),
diff --git a/dev/devicelab/bin/tasks/build_aar_module_test.dart b/dev/devicelab/bin/tasks/build_aar_module_test.dart
index 199e2ae..7711509 100644
--- a/dev/devicelab/bin/tasks/build_aar_module_test.dart
+++ b/dev/devicelab/bin/tasks/build_aar_module_test.dart
@@ -24,11 +24,11 @@
return TaskResult.failure('Could not find Java');
print('\nUsing JAVA_HOME=$javaHome');
- section('Create module project');
-
final Directory tempDir = Directory.systemTemp.createTempSync('flutter_module_test.');
final Directory projectDir = Directory(path.join(tempDir.path, 'hello'));
try {
+ section('Create module project');
+
await inDirectory(tempDir, () async {
await flutter(
'create',
@@ -36,15 +36,55 @@
);
});
- section('Add plugins');
+ section('Create plugin that supports android platform');
- final File pubspec = File(path.join(projectDir.path, 'pubspec.yaml'));
- String content = pubspec.readAsStringSync();
+ await inDirectory(tempDir, () async {
+ await flutter(
+ 'create',
+ options: <String>['--org', 'io.flutter.devicelab', '--template', 'plugin', 'plugin_with_android'],
+ );
+ });
+
+ section('Create plugin that doesn\'t support android project');
+
+ await inDirectory(tempDir, () async {
+ await flutter(
+ 'create',
+ options: <String>['--org', 'io.flutter.devicelab', '--template', 'plugin', 'plugin_without_android'],
+ );
+ });
+
+ // Delete the android/ directory.
+ File(path.join(
+ tempDir.path,
+ 'plugin_without_android',
+ 'android'
+ )).deleteSync(recursive: true);
+
+ // Remove Android support from the plugin pubspec.yaml
+ final File pluginPubspec = File(path.join(tempDir.path, 'plugin_without_android', 'pubspec.yaml'));
+ pluginPubspec.writeAsStringSync(pluginPubspec.readAsStringSync().replaceFirst('''
+ android:
+ package: io.flutter.devicelab.plugin_without_android
+ pluginClass: PluginWithoutAndroidPlugin
+''', ''), flush: true);
+
+ section('Add plugins to pubspec.yaml');
+
+ final File modulePubspec = File(path.join(projectDir.path, 'pubspec.yaml'));
+ String content = modulePubspec.readAsStringSync();
content = content.replaceFirst(
'\ndependencies:\n',
- '\ndependencies:\n device_info: 0.4.1\n package_info: 0.4.0+9\n',
+ '\ndependencies:\n'
+ ' plugin_with_android:\n'
+ ' path: ../plugin_with_android\n'
+ ' plugin_without_android:\n'
+ ' path: ../plugin_without_android\n',
);
- pubspec.writeAsStringSync(content, flush: true);
+ modulePubspec.writeAsStringSync(content, flush: true);
+
+ section('Run packages get in module project');
+
await inDirectory(projectDir, () async {
await flutter(
'packages',
@@ -57,7 +97,7 @@
await inDirectory(projectDir, () async {
await flutter(
'build',
- options: <String>['aar', '--release', '--verbose'],
+ options: <String>['aar', '--verbose'],
);
});
@@ -99,44 +139,22 @@
repoPath,
'io',
'flutter',
- 'plugins',
- 'deviceinfo',
- 'device_info_release',
+ 'devicelab',
+ 'plugin_with_android',
+ 'plugin_with_android_release',
'1.0',
- 'device_info_release-1.0.aar',
+ 'plugin_with_android_release-1.0.aar',
));
checkFileExists(path.join(
repoPath,
'io',
'flutter',
- 'plugins',
- 'deviceinfo',
- 'device_info_release',
+ 'devicelab',
+ 'plugin_with_android',
+ 'plugin_with_android_release',
'1.0',
- 'device_info_release-1.0.pom',
- ));
-
- checkFileExists(path.join(
- repoPath,
- 'io',
- 'flutter',
- 'plugins',
- 'packageinfo',
- 'package_info_release',
- '1.0',
- 'package_info_release-1.0.aar',
- ));
-
- checkFileExists(path.join(
- repoPath,
- 'io',
- 'flutter',
- 'plugins',
- 'packageinfo',
- 'package_info_release',
- '1.0',
- 'package_info_release-1.0.pom',
+ 'plugin_with_android_release-1.0.pom',
));
section('Check AOT blobs in release POM');
@@ -146,8 +164,7 @@
'armeabi_v7a_release',
'arm64_v8a_release',
'x86_64_release',
- 'package_info_release',
- 'device_info_release',
+ 'plugin_with_android_release',
], releasePom);
section('Check assets in release AAR');
@@ -174,15 +191,6 @@
)
);
- section('Build debug AAR');
-
- await inDirectory(projectDir, () async {
- await flutter(
- 'build',
- options: <String>['aar', '--verbose', '--debug'],
- );
- });
-
section('Check debug Maven artifacts');
checkFileExists(path.join(
@@ -213,44 +221,22 @@
repoPath,
'io',
'flutter',
- 'plugins',
- 'deviceinfo',
- 'device_info_debug',
+ 'devicelab',
+ 'plugin_with_android',
+ 'plugin_with_android_debug',
'1.0',
- 'device_info_debug-1.0.aar',
+ 'plugin_with_android_debug-1.0.aar',
));
checkFileExists(path.join(
repoPath,
'io',
'flutter',
- 'plugins',
- 'deviceinfo',
- 'device_info_debug',
+ 'devicelab',
+ 'plugin_with_android',
+ 'plugin_with_android_debug',
'1.0',
- 'device_info_debug-1.0.pom',
- ));
-
- checkFileExists(path.join(
- repoPath,
- 'io',
- 'flutter',
- 'plugins',
- 'packageinfo',
- 'package_info_debug',
- '1.0',
- 'package_info_debug-1.0.aar',
- ));
-
- checkFileExists(path.join(
- repoPath,
- 'io',
- 'flutter',
- 'plugins',
- 'packageinfo',
- 'package_info_debug',
- '1.0',
- 'package_info_debug-1.0.pom',
+ 'plugin_with_android_debug-1.0.pom',
));
section('Check AOT blobs in debug POM');
@@ -261,8 +247,7 @@
'x86_64_debug',
'armeabi_v7a_debug',
'arm64_v8a_debug',
- 'package_info_debug',
- 'device_info_debug',
+ 'plugin_with_android_debug',
], debugPom);
section('Check assets in debug AAR');
diff --git a/dev/devicelab/bin/tasks/flutter_view_ios__start_up.dart b/dev/devicelab/bin/tasks/flutter_view_ios__start_up.dart
index 21ec1e4..d761626 100644
--- a/dev/devicelab/bin/tasks/flutter_view_ios__start_up.dart
+++ b/dev/devicelab/bin/tasks/flutter_view_ios__start_up.dart
@@ -3,30 +3,12 @@
// found in the LICENSE file.
import 'dart:async';
-import 'dart:io';
-import 'package:flutter_devicelab/framework/utils.dart';
import 'package:flutter_devicelab/tasks/perf_tests.dart';
import 'package:flutter_devicelab/framework/adb.dart';
import 'package:flutter_devicelab/framework/framework.dart';
Future<void> main() async {
deviceOperatingSystem = DeviceOperatingSystem.ios;
- await task(() async {
- final Directory iosDirectory = dir(
- '${flutterDirectory.path}/examples/flutter_view/ios',
- );
- await inDirectory(iosDirectory, () async {
- await exec(
- 'pod',
- <String>['install'],
- environment: <String, String>{
- 'LANG': 'en_US.UTF-8',
- },
- );
- });
-
- final TaskFunction taskFunction = createFlutterViewStartupTest();
- return await taskFunction();
- });
+ await task(createFlutterViewStartupTest());
}
diff --git a/dev/devicelab/bin/tasks/gradle_deprecated_settings_test.dart b/dev/devicelab/bin/tasks/gradle_deprecated_settings_test.dart
new file mode 100644
index 0000000..1465891
--- /dev/null
+++ b/dev/devicelab/bin/tasks/gradle_deprecated_settings_test.dart
@@ -0,0 +1,57 @@
+// Copyright 2014 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 'dart:async';
+import 'dart:io';
+
+import 'package:flutter_devicelab/framework/framework.dart';
+import 'package:flutter_devicelab/framework/utils.dart';
+import 'package:path/path.dart' as path;
+
+/// Tests that apps can be built using the deprecated `android/settings.gradle` file.
+/// This test should be removed once apps have been migrated to this new file.
+// TODO(egarciad): Migrate existing files, https://github.com/flutter/flutter/issues/54566
+Future<void> main() async {
+ await task(() async {
+
+ section('Find Java');
+
+ final String javaHome = await findJavaHome();
+ if (javaHome == null)
+ return TaskResult.failure('Could not find Java');
+ print('\nUsing JAVA_HOME=$javaHome');
+
+ final Directory projectDirectory =
+ dir('${flutterDirectory.path}/dev/integration_tests/gradle_deprecated_settings');
+ try {
+ section('Build debug APK using deprecated settings.gradle');
+ await inDirectory(projectDirectory, () async {
+ await flutter(
+ 'build',
+ options: <String>[
+ 'apk',
+ '--debug',
+ '--target-platform', 'android-arm',
+ '--no-shrink',
+ '--verbose',
+ ],
+ );
+ });
+ final File debugApk = File(path.join(
+ projectDirectory.path,
+ 'build',
+ 'app',
+ 'outputs',
+ 'flutter-apk',
+ 'app-debug.apk',
+ ));
+ if (!exists(debugApk)) {
+ return TaskResult.failure('Failed to build debug APK.');
+ }
+ return TaskResult.success(null);
+ } catch (e) {
+ return TaskResult.failure(e.toString());
+ }
+ });
+}
diff --git a/dev/devicelab/bin/tasks/gradle_migrate_settings_test.dart b/dev/devicelab/bin/tasks/gradle_migrate_settings_test.dart
index a9d5fff..4117e75 100644
--- a/dev/devicelab/bin/tasks/gradle_migrate_settings_test.dart
+++ b/dev/devicelab/bin/tasks/gradle_migrate_settings_test.dart
@@ -117,7 +117,7 @@
section('Override settings.gradle with custom logic');
- const String customDeprecatedFileContent = '''
+ const String customDeprecatedFileContent = r'''
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
@@ -130,8 +130,8 @@
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":\$name"
- project(":\$name").projectDir = pluginDirectory
+ include ":$name"
+ project(":$name").projectDir = pluginDirectory
}
// some custom logic
''';
diff --git a/dev/devicelab/bin/tasks/ios_content_validation_test.dart b/dev/devicelab/bin/tasks/ios_content_validation_test.dart
index 2137618..2f12097 100644
--- a/dev/devicelab/bin/tasks/ios_content_validation_test.dart
+++ b/dev/devicelab/bin/tasks/ios_content_validation_test.dart
@@ -24,19 +24,32 @@
'--release',
'--obfuscate',
'--split-debug-info=foo/',
+ '--no-codesign',
]);
});
+ final String buildPath = path.join(
+ flutterProject.rootPath,
+ 'build',
+ 'ios',
+ 'iphoneos',
+ );
final String outputAppPath = path.join(
- flutterProject.rootPath,
- 'build/ios/iphoneos/Runner.app',
+ buildPath,
+ 'Runner.app',
);
- final String outputAppFramework = path.join(
- flutterProject.rootPath,
+ final Directory outputAppFramework = Directory(path.join(
outputAppPath,
- 'Frameworks/App.framework/App',
- );
- if (!File(outputAppFramework).existsSync()) {
- fail('Failed to produce expected output at $outputAppFramework');
+ 'Frameworks',
+ 'App.framework',
+ ));
+
+ final File outputAppFrameworkBinary = File(path.join(
+ outputAppFramework.path,
+ 'App',
+ ));
+
+ if (!outputAppFrameworkBinary.existsSync()) {
+ fail('Failed to produce expected output at ${outputAppFrameworkBinary.path}');
}
section('Validate obfuscation');
@@ -46,7 +59,7 @@
await inDirectory(flutterProject.rootPath, () async {
final String response = await eval(
'grep',
- <String>[flutterProject.name, outputAppFramework],
+ <String>[flutterProject.name, outputAppFrameworkBinary.path],
canFail: true,
);
if (response.trim().contains('matches')) {
@@ -56,16 +69,63 @@
section('Validate bitcode');
- final String outputFlutterFramework = path.join(
+ final Directory outputFlutterFramework = Directory(path.join(
flutterProject.rootPath,
outputAppPath,
- 'Frameworks/Flutter.framework/Flutter',
+ 'Frameworks',
+ 'Flutter.framework',
+ ));
+ final File outputFlutterFrameworkBinary = File(path.join(
+ outputFlutterFramework.path,
+ 'Flutter',
+ ));
+
+ if (!outputFlutterFrameworkBinary.existsSync()) {
+ fail('Failed to produce expected output at ${outputFlutterFrameworkBinary.path}');
+ }
+ bitcode = await containsBitcode(outputFlutterFrameworkBinary.path);
+
+ section('Xcode backend script');
+
+ outputFlutterFramework.deleteSync(recursive: true);
+ outputAppFramework.deleteSync(recursive: true);
+ if (outputFlutterFramework.existsSync() || outputAppFramework.existsSync()) {
+ fail('Failed to delete embedded frameworks');
+ }
+
+ final String xcodeBackendPath = path.join(
+ flutterDirectory.path,
+ 'packages',
+ 'flutter_tools',
+ 'bin',
+ 'xcode_backend.sh'
);
- if (!File(outputFlutterFramework).existsSync()) {
- fail('Failed to produce expected output at $outputFlutterFramework');
+ // Simulate a commonly Xcode build setting misconfiguration
+ // where FLUTTER_APPLICATION_PATH is missing
+ final int result = await exec(
+ xcodeBackendPath,
+ <String>['embed_and_thin'],
+ environment: <String, String>{
+ 'SOURCE_ROOT': flutterProject.iosPath,
+ 'TARGET_BUILD_DIR': buildPath,
+ 'FRAMEWORKS_FOLDER_PATH': 'Runner.app/Frameworks',
+ 'VERBOSE_SCRIPT_LOGGING': '1',
+ 'ACTION': 'install', // Skip bitcode stripping since we just checked that above.
+ },
+ );
+
+ if (result != 0) {
+ fail('xcode_backend embed_and_thin failed');
}
- bitcode = await containsBitcode(outputFlutterFramework);
+
+ if (!outputFlutterFrameworkBinary.existsSync()) {
+ fail('Failed to re-embed ${outputFlutterFrameworkBinary.path}');
+ }
+
+ if (!outputAppFrameworkBinary.existsSync()) {
+ fail('Failed to re-embed ${outputAppFrameworkBinary.path}');
+ }
});
if (foundProjectName) {
diff --git a/dev/devicelab/lib/framework/apk_utils.dart b/dev/devicelab/lib/framework/apk_utils.dart
index 1eb4955..961074d 100644
--- a/dev/devicelab/lib/framework/apk_utils.dart
+++ b/dev/devicelab/lib/framework/apk_utils.dart
@@ -214,6 +214,7 @@
String get rootPath => path.join(parent.path, name);
String get androidPath => path.join(rootPath, 'android');
+ String get iosPath => path.join(rootPath, 'ios');
Future<void> addCustomBuildType(String name, {String initWith}) async {
final File buildScript = File(
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle b/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle
+++ b/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/android_embedding_v2_smoke_test/android/settings.gradle b/dev/integration_tests/android_embedding_v2_smoke_test/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/dev/integration_tests/android_embedding_v2_smoke_test/android/settings.gradle
+++ b/dev/integration_tests/android_embedding_v2_smoke_test/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/android_semantics_testing/android/settings.gradle b/dev/integration_tests/android_semantics_testing/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/integration_tests/android_semantics_testing/android/settings.gradle
+++ b/dev/integration_tests/android_semantics_testing/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/settings.gradle b/dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/settings.gradle
+++ b/dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/android_splash_screens/splash_screen_load_rotate/android/settings.gradle b/dev/integration_tests/android_splash_screens/splash_screen_load_rotate/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/dev/integration_tests/android_splash_screens/splash_screen_load_rotate/android/settings.gradle
+++ b/dev/integration_tests/android_splash_screens/splash_screen_load_rotate/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/android_splash_screens/splash_screen_trans_rotate/android/settings.gradle b/dev/integration_tests/android_splash_screens/splash_screen_trans_rotate/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/dev/integration_tests/android_splash_screens/splash_screen_trans_rotate/android/settings.gradle
+++ b/dev/integration_tests/android_splash_screens/splash_screen_trans_rotate/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/android_views/android/settings.gradle b/dev/integration_tests/android_views/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/dev/integration_tests/android_views/android/settings.gradle
+++ b/dev/integration_tests/android_views/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/channels/android/settings.gradle b/dev/integration_tests/channels/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/integration_tests/channels/android/settings.gradle
+++ b/dev/integration_tests/channels/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/codegen/android/settings.gradle b/dev/integration_tests/codegen/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/integration_tests/codegen/android/settings.gradle
+++ b/dev/integration_tests/codegen/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/external_ui/android/settings.gradle b/dev/integration_tests/external_ui/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/integration_tests/external_ui/android/settings.gradle
+++ b/dev/integration_tests/external_ui/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/flavors/android/settings.gradle b/dev/integration_tests/flavors/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/integration_tests/flavors/android/settings.gradle
+++ b/dev/integration_tests/flavors/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/flutter_driver_screenshot_test/android/settings.gradle b/dev/integration_tests/flutter_driver_screenshot_test/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/dev/integration_tests/flutter_driver_screenshot_test/android/settings.gradle
+++ b/dev/integration_tests/flutter_driver_screenshot_test/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/flutter_gallery/android/settings.gradle b/dev/integration_tests/flutter_gallery/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/integration_tests/flutter_gallery/android/settings.gradle
+++ b/dev/integration_tests/flutter_gallery/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/gradle_deprecated_settings/README.md b/dev/integration_tests/gradle_deprecated_settings/README.md
new file mode 100644
index 0000000..a4c6081
--- /dev/null
+++ b/dev/integration_tests/gradle_deprecated_settings/README.md
@@ -0,0 +1,7 @@
+# Deprecated settings.gradle
+
+This project is meant to test that apps using the current `android/settings.gradle`
+can still be built. This project can be removed once apps have been migrated to
+this new file.
+
+Issue: https://github.com/flutter/flutter/issues/54566
\ No newline at end of file
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/app/build.gradle b/dev/integration_tests/gradle_deprecated_settings/android/app/build.gradle
new file mode 100644
index 0000000..be24d8d
--- /dev/null
+++ b/dev/integration_tests/gradle_deprecated_settings/android/app/build.gradle
@@ -0,0 +1,45 @@
+// Copyright 2014 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.
+
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withInputStream { stream ->
+ localProperties.load(stream)
+ }
+}
+
+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.")
+}
+
+apply plugin: 'com.android.application'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion 28
+
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+
+ defaultConfig {
+ applicationId "com.yourcompany.flavors"
+ minSdkVersion 21
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ }
+
+ buildTypes {
+ release {
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/app/src/main/AndroidManifest.xml b/dev/integration_tests/gradle_deprecated_settings/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..e1a37c0
--- /dev/null
+++ b/dev/integration_tests/gradle_deprecated_settings/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<!-- Copyright 2014 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. -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.yourcompany.flavors">
+
+ <uses-permission android:name="android.permission.INTERNET"/>
+
+ <application
+ android:name="io.flutter.app.FlutterApplication"
+ android:label="flavors">
+ <activity
+ android:name=".MainActivity"
+ android:launchMode="singleTop"
+ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
+ android:hardwareAccelerated="true"
+ android:windowSoftInputMode="adjustResize">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/app/src/main/java/com/yourcompany/flavors/MainActivity.java b/dev/integration_tests/gradle_deprecated_settings/android/app/src/main/java/com/yourcompany/flavors/MainActivity.java
new file mode 100644
index 0000000..7e6d4fe
--- /dev/null
+++ b/dev/integration_tests/gradle_deprecated_settings/android/app/src/main/java/com/yourcompany/flavors/MainActivity.java
@@ -0,0 +1,26 @@
+// Copyright 2014 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.
+
+package com.yourcompany.flavors;
+
+import android.os.Bundle;
+
+import io.flutter.app.FlutterActivity;
+import io.flutter.plugin.common.MethodCall;
+import io.flutter.plugin.common.MethodChannel;
+import io.flutter.plugins.GeneratedPluginRegistrant;
+
+public class MainActivity extends FlutterActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ GeneratedPluginRegistrant.registerWith(this);
+ new MethodChannel(getFlutterView(), "flavor").setMethodCallHandler(new MethodChannel.MethodCallHandler() {
+ @Override
+ public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
+ result.success(BuildConfig.FLAVOR);
+ }
+ });
+ }
+}
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/build.gradle b/dev/integration_tests/gradle_deprecated_settings/android/build.gradle
new file mode 100644
index 0000000..5df71fc
--- /dev/null
+++ b/dev/integration_tests/gradle_deprecated_settings/android/build.gradle
@@ -0,0 +1,33 @@
+// Copyright 2014 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.
+
+buildscript {
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.0'
+ }
+}
+
+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/gradle_deprecated_settings/android/gradle.properties b/dev/integration_tests/gradle_deprecated_settings/android/gradle.properties
new file mode 100644
index 0000000..a673820
--- /dev/null
+++ b/dev/integration_tests/gradle_deprecated_settings/android/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
+android.enableR8=true
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/gradle/wrapper/gradle-wrapper.properties b/dev/integration_tests/gradle_deprecated_settings/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..296b146
--- /dev/null
+++ b/dev/integration_tests/gradle_deprecated_settings/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.2-all.zip
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/settings.gradle b/dev/integration_tests/gradle_deprecated_settings/android/settings.gradle
new file mode 100644
index 0000000..2a07d76
--- /dev/null
+++ b/dev/integration_tests/gradle_deprecated_settings/android/settings.gradle
@@ -0,0 +1,24 @@
+// Copyright 2014 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.
+
+// This is the `settings.gradle` file that apps currently use.
+// This file has changed, so it must be migrated in existing projects.
+
+include ':app'
+
+def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
+
+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/gradle_deprecated_settings/lib/main.dart b/dev/integration_tests/gradle_deprecated_settings/lib/main.dart
new file mode 100644
index 0000000..b0681fd
--- /dev/null
+++ b/dev/integration_tests/gradle_deprecated_settings/lib/main.dart
@@ -0,0 +1,9 @@
+// Copyright 2014 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 'package:flutter/material.dart';
+
+void main() {
+ runApp(const Text('Nothing to show'));
+}
diff --git a/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml b/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml
new file mode 100644
index 0000000..dbe6b8d
--- /dev/null
+++ b/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml
@@ -0,0 +1,21 @@
+name: gradle_deprecated_settings
+description: Integration test for the current settings.gradle.
+
+environment:
+ # The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite.
+ sdk: ">=2.0.0-dev.68.0 <3.0.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+ camera: 0.5.7+4
+
+ collection: 1.14.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ meta: 1.1.8 # 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"
+
+flutter:
+ uses-material-design: true
+
+# PUBSPEC CHECKSUM: 185d
diff --git a/dev/integration_tests/image_loading/android/settings.gradle b/dev/integration_tests/image_loading/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/integration_tests/image_loading/android/settings.gradle
+++ b/dev/integration_tests/image_loading/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/named_isolates/android/settings.gradle b/dev/integration_tests/named_isolates/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/integration_tests/named_isolates/android/settings.gradle
+++ b/dev/integration_tests/named_isolates/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/platform_interaction/android/settings.gradle b/dev/integration_tests/platform_interaction/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/integration_tests/platform_interaction/android/settings.gradle
+++ b/dev/integration_tests/platform_interaction/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/release_smoke_test/android/settings.gradle b/dev/integration_tests/release_smoke_test/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/dev/integration_tests/release_smoke_test/android/settings.gradle
+++ b/dev/integration_tests/release_smoke_test/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/integration_tests/ui/android/settings.gradle b/dev/integration_tests/ui/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/dev/integration_tests/ui/android/settings.gradle
+++ b/dev/integration_tests/ui/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/dev/manual_tests/android/settings.gradle b/dev/manual_tests/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/dev/manual_tests/android/settings.gradle
+++ b/dev/manual_tests/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/examples/catalog/android/settings.gradle b/examples/catalog/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/examples/catalog/android/settings.gradle
+++ b/examples/catalog/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/examples/flutter_view/README.md b/examples/flutter_view/README.md
index 6c84a2a..b6db10b 100644
--- a/examples/flutter_view/README.md
+++ b/examples/flutter_view/README.md
@@ -11,8 +11,7 @@
## iOS
You can open `ios/Runner.xcworkspace` in Xcode and build the project as
-usual. For this sample you need to run `pod install` from the `ios` folder
-before building the first time.
+usual.
## Android
diff --git a/examples/flutter_view/android/settings.gradle b/examples/flutter_view/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/examples/flutter_view/android/settings.gradle
+++ b/examples/flutter_view/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/examples/flutter_view/ios/Flutter/Debug.xcconfig b/examples/flutter_view/ios/Flutter/Debug.xcconfig
index 9803018..592ceee 100644
--- a/examples/flutter_view/ios/Flutter/Debug.xcconfig
+++ b/examples/flutter_view/ios/Flutter/Debug.xcconfig
@@ -1,2 +1 @@
#include "Generated.xcconfig"
-#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
diff --git a/examples/flutter_view/ios/Flutter/Release.xcconfig b/examples/flutter_view/ios/Flutter/Release.xcconfig
index a4a8c60..592ceee 100644
--- a/examples/flutter_view/ios/Flutter/Release.xcconfig
+++ b/examples/flutter_view/ios/Flutter/Release.xcconfig
@@ -1,2 +1 @@
#include "Generated.xcconfig"
-#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
diff --git a/examples/flutter_view/ios/Podfile b/examples/flutter_view/ios/Podfile
deleted file mode 100644
index 827fe47..0000000
--- a/examples/flutter_view/ios/Podfile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Uncomment this line to define a global platform for your project
-# platform :ios, '9.0'
-
-# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
-install! 'cocoapods', :disable_input_output_paths => true
-
-target 'Runner' do
- # Uncomment this line if you're using Swift or would like to use dynamic frameworks
- use_frameworks!
- use_modular_headers!
-
- # Pods for Runner
- pod 'MaterialControls', '~> 1.2.2'
-
-end
diff --git a/examples/flutter_view/ios/Runner.xcodeproj/project.pbxproj b/examples/flutter_view/ios/Runner.xcodeproj/project.pbxproj
index c8b69db..a9d9e6b 100644
--- a/examples/flutter_view/ios/Runner.xcodeproj/project.pbxproj
+++ b/examples/flutter_view/ios/Runner.xcodeproj/project.pbxproj
@@ -16,7 +16,6 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
- A10521F6BE294095B24A8A75 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 069A5C81CEBC82AF6693F60F /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -33,14 +32,12 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
- 069A5C81CEBC82AF6693F60F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
2D4B11261E55A15A00FF14DB /* NativeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeViewController.m; sourceTree = "<group>"; };
2D4B11281E55A31800FF14DB /* NativeViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeViewController.h; sourceTree = "<group>"; };
2DD8945E1E5B87AF0010574F /* ic_add.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ic_add.png; sourceTree = "<group>"; };
2DE332E61E55C6D800393FD5 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = "<group>"; };
2DE332E81E55C6F100393FD5 /* MainViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = "<group>"; };
3B3967041E83383D004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
- 63EC5EC13E843CD861057871 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@@ -52,8 +49,6 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
- C50B4FE91C29B0DE9DD62DD3 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
- EADA814501F2EF49C9E6C636 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -61,23 +56,12 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- A10521F6BE294095B24A8A75 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
- 840012C8B5EDBCF56B0E4AC1 /* Pods */ = {
- isa = PBXGroup;
- children = (
- 63EC5EC13E843CD861057871 /* Pods-Runner.debug.xcconfig */,
- C50B4FE91C29B0DE9DD62DD3 /* Pods-Runner.release.xcconfig */,
- EADA814501F2EF49C9E6C636 /* Pods-Runner.profile.xcconfig */,
- );
- name = Pods;
- sourceTree = "<group>";
- };
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@@ -95,8 +79,6 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
- 840012C8B5EDBCF56B0E4AC1 /* Pods */,
- CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -135,14 +117,6 @@
name = "Supporting Files";
sourceTree = "<group>";
};
- CF3B75C9A7D2FA2A4C99F110 /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- 069A5C81CEBC82AF6693F60F /* Pods_Runner.framework */,
- );
- name = Frameworks;
- sourceTree = "<group>";
- };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -150,14 +124,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
- C15931CF7E2D081FE06790F0 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
- D7EBAA0AD2D4385BA6FA83BA /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -245,39 +217,6 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
- C15931CF7E2D081FE06790F0 /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-Runner-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;
- };
- D7EBAA0AD2D4385BA6FA83BA /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
diff --git a/examples/flutter_view/ios/Runner.xcworkspace/contents.xcworkspacedata b/examples/flutter_view/ios/Runner.xcworkspace/contents.xcworkspacedata
index 21a3cc1..1d526a1 100644
--- a/examples/flutter_view/ios/Runner.xcworkspace/contents.xcworkspacedata
+++ b/examples/flutter_view/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -4,7 +4,4 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
- <FileRef
- location = "group:Pods/Pods.xcodeproj">
- </FileRef>
</Workspace>
diff --git a/examples/flutter_view/ios/Runner/Base.lproj/Main.storyboard b/examples/flutter_view/ios/Runner/Base.lproj/Main.storyboard
index 380dd14..76c8ca3 100644
--- a/examples/flutter_view/ios/Runner/Base.lproj/Main.storyboard
+++ b/examples/flutter_view/ios/Runner/Base.lproj/Main.storyboard
@@ -1,10 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="FnB-1o-m6P">
- <device id="retina4_7" orientation="portrait">
- <adaptation id="fullscreen"/>
- </device>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="FnB-1o-m6P">
+ <device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@@ -85,13 +84,13 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="zVI-Xh-iNx">
- <rect key="frame" x="0.0" y="0.0" width="375" height="334"/>
+ <rect key="frame" x="0.0" y="0.0" width="375" height="333.5"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NLS-lx-anZ" userLabel="Top">
- <rect key="frame" x="0.0" y="0.0" width="375" height="264"/>
+ <rect key="frame" x="0.0" y="0.0" width="375" height="263.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Flutter button tapped 0 times." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PJ2-AA-Riy" userLabel="IncrementLabel">
- <rect key="frame" x="73" y="122" width="229" height="21"/>
+ <rect key="frame" x="73.5" y="121.5" width="228.5" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
@@ -103,15 +102,15 @@
</constraints>
</view>
<view contentMode="scaleToFill" restorationIdentifier="Bottom" translatesAutoresizingMaskIntoConstraints="NO" id="Qxj-hW-CeP" userLabel="Bottom">
- <rect key="frame" x="0.0" y="264" width="375" height="70"/>
+ <rect key="frame" x="0.0" y="263.5" width="375" height="70"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="iOS" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="K0h-kv-J7E">
- <rect key="frame" x="20" y="14" width="48" height="36"/>
+ <rect key="frame" x="20" y="14" width="47" height="36"/>
<fontDescription key="fontDescription" type="system" pointSize="30"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
- <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Jfa-Lk-nDI" customClass="MDButton">
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Jfa-Lk-nDI">
<rect key="frame" x="300" y="-5" width="55" height="55"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
@@ -119,15 +118,10 @@
<constraint firstAttribute="width" constant="55" id="zeJ-gS-6zj"/>
</constraints>
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
- <userDefinedRuntimeAttributes>
- <userDefinedRuntimeAttribute type="number" keyPath="type">
- <integer key="value" value="2"/>
- </userDefinedRuntimeAttribute>
- <userDefinedRuntimeAttribute type="image" keyPath="imageNormal" value="ic_add.png"/>
- <userDefinedRuntimeAttribute type="color" keyPath="rippleColor">
- <color key="value" red="0.82337594754841859" green="0.83186435937881464" blue="0.83186435937881464" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
- </userDefinedRuntimeAttribute>
- </userDefinedRuntimeAttributes>
+ <state key="normal" image="ic_add.png"/>
+ <state key="disabled" image="ic_add.png"/>
+ <state key="selected" image="ic_add.png"/>
+ <state key="highlighted" image="ic_add.png"/>
<connections>
<action selector="handleIncrement:" destination="g6V-0q-Qmt" eventType="touchUpInside" id="3ie-8K-E0v"/>
</connections>
diff --git a/examples/flutter_view/ios/Runner/NativeViewController.m b/examples/flutter_view/ios/Runner/NativeViewController.m
index 17813e5..e82375a 100644
--- a/examples/flutter_view/ios/Runner/NativeViewController.m
+++ b/examples/flutter_view/ios/Runner/NativeViewController.m
@@ -5,7 +5,6 @@
#import <Foundation/Foundation.h>
#import "NativeViewController.h"
-#import "MDButton.h"
@interface NativeViewController ()
@property int counter;
@@ -19,7 +18,7 @@
self.counter = 0;
}
-- (IBAction)handleIncrement:(MDButton*)sender {
+- (IBAction)handleIncrement:(id)sender {
[self.delegate didTapIncrementButton];
}
diff --git a/examples/hello_world/android/settings.gradle b/examples/hello_world/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/examples/hello_world/android/settings.gradle
+++ b/examples/hello_world/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/examples/image_list/android/settings.gradle b/examples/image_list/android/settings.gradle
index bef552e..d3b6a40 100644
--- a/examples/image_list/android/settings.gradle
+++ b/examples/image_list/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/examples/layers/android/settings.gradle b/examples/layers/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/examples/layers/android/settings.gradle
+++ b/examples/layers/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/examples/platform_channel/android/settings.gradle b/examples/platform_channel/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/examples/platform_channel/android/settings.gradle
+++ b/examples/platform_channel/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/examples/platform_view/android/settings.gradle b/examples/platform_view/android/settings.gradle
index dbc3b58..d3b6a40 100644
--- a/examples/platform_view/android/settings.gradle
+++ b/examples/platform_view/android/settings.gradle
@@ -4,16 +4,12 @@
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withInputStream { stream -> plugins.load(stream) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/packages/flutter/lib/src/cupertino/segmented_control.dart b/packages/flutter/lib/src/cupertino/segmented_control.dart
index 3506c0a..82cb6db 100644
--- a/packages/flutter/lib/src/cupertino/segmented_control.dart
+++ b/packages/flutter/lib/src/cupertino/segmented_control.dart
@@ -382,6 +382,7 @@
);
child = GestureDetector(
+ behavior: HitTestBehavior.opaque,
onTapDown: (TapDownDetails event) {
_onTapDown(currentKey);
},
diff --git a/packages/flutter/lib/src/material/dropdown.dart b/packages/flutter/lib/src/material/dropdown.dart
index fe22689..9775ea0 100644
--- a/packages/flutter/lib/src/material/dropdown.dart
+++ b/packages/flutter/lib/src/material/dropdown.dart
@@ -1539,4 +1539,12 @@
assert(widget.onChanged != null);
widget.onChanged(value);
}
+
+ @override
+ void didUpdateWidget(DropdownButtonFormField<T> oldWidget) {
+ super.didUpdateWidget(oldWidget);
+ if (oldWidget.initialValue != widget.initialValue) {
+ setValue(widget.initialValue);
+ }
+ }
}
diff --git a/packages/flutter/test/cupertino/segmented_control_test.dart b/packages/flutter/test/cupertino/segmented_control_test.dart
index 86384a1..bdf1927 100644
--- a/packages/flutter/test/cupertino/segmented_control_test.dart
+++ b/packages/flutter/test/cupertino/segmented_control_test.dart
@@ -926,6 +926,44 @@
expect(sharedValue, 0);
});
+ testWidgets(
+ 'Segment still hittable with a child that has no hitbox',
+ (WidgetTester tester) async {
+ // Regression test for https://github.com/flutter/flutter/issues/57326.
+ final Map<int, Widget> children = <int, Widget>{};
+ children[0] = const Text('Child 1');
+ children[1] = const SizedBox();
+ int sharedValue = 0;
+
+ await tester.pumpWidget(
+ StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return boilerplate(
+ child: CupertinoSegmentedControl<int>(
+ key: const ValueKey<String>('Segmented Control'),
+ children: children,
+ onValueChanged: (int newValue) {
+ setState(() {
+ sharedValue = newValue;
+ });
+ },
+ groupValue: sharedValue,
+ ),
+ );
+ },
+ ),
+ );
+
+ expect(sharedValue, 0);
+
+ final Offset centerOfTwo = tester.getCenter(find.byWidget(children[1]));
+ // Tap within the bounds of children[1], but not at the center.
+ // children[1] is a SizedBox thus not hittable by itself.
+ await tester.tapAt(centerOfTwo + const Offset(10, 0));
+
+ expect(sharedValue, 1);
+ });
+
testWidgets('Animation is correct when the selected segment changes', (WidgetTester tester) async {
await tester.pumpWidget(setupSimpleSegmentedControl());
diff --git a/packages/flutter/test/cupertino/sliding_segmented_control_test.dart b/packages/flutter/test/cupertino/sliding_segmented_control_test.dart
index bd92bd2..1c13302 100644
--- a/packages/flutter/test/cupertino/sliding_segmented_control_test.dart
+++ b/packages/flutter/test/cupertino/sliding_segmented_control_test.dart
@@ -776,7 +776,8 @@
expect(groupValue, 0);
final Offset centerOfTwo = tester.getCenter(find.byWidget(children[1]));
- // Tap just inside segment bounds
+ // Tap within the bounds of children[1], but not at the center.
+ // children[1] is a SizedBox thus not hittable by itself.
await tester.tapAt(centerOfTwo + const Offset(10, 0));
expect(groupValue, 1);
diff --git a/packages/flutter/test/material/dropdown_form_field_test.dart b/packages/flutter/test/material/dropdown_form_field_test.dart
index 224e07f..e5e7d6f 100644
--- a/packages/flutter/test/material/dropdown_form_field_test.dart
+++ b/packages/flutter/test/material/dropdown_form_field_test.dart
@@ -715,4 +715,50 @@
expect(value, equals('two'));
expect(dropdownButtonTapCounter, 2); // Should not change.
});
+
+ testWidgets('DropdownButtonFormField should re-render if value param changes', (WidgetTester tester) async {
+ String currentValue = 'two';
+
+ await tester.pumpWidget(
+ StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return MaterialApp(
+ home: Material(
+ child: DropdownButtonFormField<String>(
+ value: currentValue,
+ onChanged: onChanged,
+ items: menuItems.map((String value) {
+ return DropdownMenuItem<String>(
+ value: value,
+ child: Text(value),
+ onTap: () {
+ setState(() {
+ currentValue = value;
+ });
+ },
+ );
+ }).toList(),
+ ),
+ ),
+ );
+ },
+ ),
+ );
+
+ // Make sure the rendered text value matches the initial state value.
+ expect(currentValue, equals('two'));
+ expect(find.text(currentValue), findsOneWidget);
+
+ // Tap the DropdownButtonFormField widget
+ await tester.tap(find.byType(dropdownButtonType));
+ await tester.pumpAndSettle();
+
+ // Tap the first dropdown menu item.
+ await tester.tap(find.text('one').last);
+ await tester.pumpAndSettle();
+
+ // Make sure the rendered text value matches the updated state value.
+ expect(currentValue, equals('one'));
+ expect(find.text(currentValue), findsOneWidget);
+ });
}
diff --git a/packages/flutter_tools/bin/xcode_backend.sh b/packages/flutter_tools/bin/xcode_backend.sh
index 37806d5..f8c2795 100755
--- a/packages/flutter_tools/bin/xcode_backend.sh
+++ b/packages/flutter_tools/bin/xcode_backend.sh
@@ -277,15 +277,18 @@
# Adds the App.framework as an embedded binary and the flutter_assets as
# resources.
EmbedFlutterFrameworks() {
- AssertExists "${FLUTTER_APPLICATION_PATH}"
+ local project_path="${SOURCE_ROOT}/.."
+ if [[ -n "$FLUTTER_APPLICATION_PATH" ]]; then
+ project_path="${FLUTTER_APPLICATION_PATH}"
+ fi
# Prefer the hidden .ios folder, but fallback to a visible ios folder if .ios
# doesn't exist.
- local flutter_ios_out_folder="${FLUTTER_APPLICATION_PATH}/.ios/Flutter"
- local flutter_ios_engine_folder="${FLUTTER_APPLICATION_PATH}/.ios/Flutter/engine"
+ local flutter_ios_out_folder="${project_path}/.ios/Flutter"
+ local flutter_ios_engine_folder="${project_path}/.ios/Flutter/engine"
if [[ ! -d ${flutter_ios_out_folder} ]]; then
- flutter_ios_out_folder="${FLUTTER_APPLICATION_PATH}/ios/Flutter"
- flutter_ios_engine_folder="${FLUTTER_APPLICATION_PATH}/ios/Flutter"
+ flutter_ios_out_folder="${project_path}/ios/Flutter"
+ flutter_ios_engine_folder="${project_path}/ios/Flutter"
fi
AssertExists "${flutter_ios_out_folder}"
diff --git a/packages/flutter_tools/gradle/aar_init_script.gradle b/packages/flutter_tools/gradle/aar_init_script.gradle
index 030d9b2..0175e99 100644
--- a/packages/flutter_tools/gradle/aar_init_script.gradle
+++ b/packages/flutter_tools/gradle/aar_init_script.gradle
@@ -72,6 +72,14 @@
}
}
+void configurePlugin(Project project, String outputDir) {
+ if (!project.hasProperty("android")) {
+ // A plugin doesn't support the Android platform when this property isn't defined in the plugin.
+ return
+ }
+ configureProject(project, outputDir)
+}
+
String getFlutterRoot(Project project) {
if (!project.hasProperty("flutter-root")) {
throw new GradleException("The `-Pflutter-root` flag must be specified.")
@@ -157,7 +165,7 @@
// This is due to the Android Gradle Plugin expecting all library subprojects to be published
// as Maven artifacts.
modulePlugins.each { pluginProject ->
- configureProject(pluginProject, moduleProject.property("output-dir"))
+ configurePlugin(pluginProject, moduleProject.property("output-dir"))
moduleProject.android.libraryVariants.all { variant ->
// Configure the `assembleAar<variantName>` task for each plugin's projects and make
// the module's equivalent task depend on the plugin's task.
diff --git a/packages/flutter_tools/gradle/app_plugin_loader.gradle b/packages/flutter_tools/gradle/app_plugin_loader.gradle
new file mode 100644
index 0000000..f722ea8
--- /dev/null
+++ b/packages/flutter_tools/gradle/app_plugin_loader.gradle
@@ -0,0 +1,30 @@
+// Copyright 2014 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.
+
+// This file is included from `<app>/android/settings.gradle`,
+// so it can be versioned with the Flutter SDK.
+
+import groovy.json.JsonSlurper
+
+def flutterProjectRoot = rootProject.projectDir.parentFile
+
+// Note: if this logic is changed, also change the logic in module_plugin_loader.gradle.
+def pluginsFile = new File(flutterProjectRoot, '.flutter-plugins-dependencies')
+if (!pluginsFile.exists()) {
+ return
+}
+
+def object = new JsonSlurper().parseText(pluginsFile.text)
+assert object instanceof Map
+assert object.plugins instanceof Map
+assert object.plugins.android instanceof List
+// Includes the Flutter plugins that support the Android platform.
+object.plugins.android.each { androidPlugin ->
+ assert androidPlugin.name instanceof String
+ assert androidPlugin.path instanceof String
+ def pluginDirectory = new File(androidPlugin.path, 'android')
+ assert pluginDirectory.exists()
+ include ":${androidPlugin.name}"
+ project(":${androidPlugin.name}").projectDir = pluginDirectory
+}
diff --git a/packages/flutter_tools/gradle/deprecated_settings.gradle b/packages/flutter_tools/gradle/deprecated_settings.gradle
index 98e3600..c276a6f 100644
--- a/packages/flutter_tools/gradle/deprecated_settings.gradle
+++ b/packages/flutter_tools/gradle/deprecated_settings.gradle
@@ -29,3 +29,19 @@
include ":$name"
project(":$name").projectDir = pluginDirectory
}
+;EOF
+// Copyright 2014 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.
+
+include ':app'
+
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
+
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/packages/flutter_tools/gradle/manual_migration_settings.gradle.md b/packages/flutter_tools/gradle/manual_migration_settings.gradle.md
index f899531..b8e062f 100644
--- a/packages/flutter_tools/gradle/manual_migration_settings.gradle.md
+++ b/packages/flutter_tools/gradle/manual_migration_settings.gradle.md
@@ -3,17 +3,12 @@
1. Copy `settings.gradle` as `settings_aar.gradle`
2. Remove the following code from `settings_aar.gradle`:
- def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+ def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+ def properties = new Properties()
- def plugins = new Properties()
- def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
- if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
- }
+ assert localPropertiesFile.exists()
+ localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
- plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
- }
-
+ def flutterSdkPath = properties.getProperty("flutter.sdk")
+ assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+ apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/packages/flutter_tools/gradle/module_plugin_loader.gradle b/packages/flutter_tools/gradle/module_plugin_loader.gradle
new file mode 100644
index 0000000..ebce109
--- /dev/null
+++ b/packages/flutter_tools/gradle/module_plugin_loader.gradle
@@ -0,0 +1,44 @@
+// Copyright 2014 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.
+
+// This file is included from `<module>/.android/include_flutter.groovy`,
+// so it can be versioned with the Flutter SDK.
+
+import groovy.json.JsonSlurper
+
+def moduleProjectRoot = project(':flutter').projectDir.parentFile.parentFile
+
+// Note: if this logic is changed, also change the logic in app_plugin_loader.gradle.
+def pluginsFile = new File(moduleProjectRoot, '.flutter-plugins-dependencies')
+if (pluginsFile.exists()) {
+ def object = new JsonSlurper().parseText(pluginsFile.text)
+ assert object instanceof Map
+ assert object.plugins instanceof Map
+ assert object.plugins.android instanceof List
+ // Includes the Flutter plugins that support the Android platform.
+ object.plugins.android.each { androidPlugin ->
+ assert androidPlugin.name instanceof String
+ assert androidPlugin.path instanceof String
+ def pluginDirectory = new File(androidPlugin.path, 'android')
+ assert pluginDirectory.exists()
+ include ":${androidPlugin.name}"
+ project(":${androidPlugin.name}").projectDir = pluginDirectory
+ }
+}
+
+gradle.getGradle().projectsLoaded { g ->
+ g.rootProject.beforeEvaluate { p ->
+ def _mainModuleName = binding.variables['mainModuleName']
+ if (_mainModuleName != null && !_mainModuleName.empty) {
+ p.ext.mainModuleName = _mainModuleName
+ }
+ }
+ g.rootProject.afterEvaluate { p ->
+ p.subprojects { sp ->
+ if (sp.name != 'flutter') {
+ sp.evaluationDependsOn(':flutter')
+ }
+ }
+ }
+}
diff --git a/packages/flutter_tools/lib/src/commands/upgrade.dart b/packages/flutter_tools/lib/src/commands/upgrade.dart
index 21d1569..3c0b182 100644
--- a/packages/flutter_tools/lib/src/commands/upgrade.dart
+++ b/packages/flutter_tools/lib/src/commands/upgrade.dart
@@ -219,12 +219,23 @@
workingDirectory: workingDirectory,
);
revision = result.stdout.trim();
- } on Exception {
- throwToolExit(
- 'Unable to upgrade Flutter: no origin repository configured. '
- "Run 'git remote add origin "
- "https://github.com/flutter/flutter' in $workingDirectory",
- );
+ } on Exception catch (e) {
+ final String errorString = e.toString();
+ if (errorString.contains('fatal: HEAD does not point to a branch')) {
+ throwToolExit(
+ 'You are not currently on a release branch. Use git to '
+ 'check out an official branch (\'stable\', \'beta\', \'dev\', or \'master\') '
+ 'and retry, for example:\n'
+ ' git checkout stable'
+ );
+ } else if (errorString.contains('fatal: no upstream configured for branch')) {
+ throwToolExit(
+ 'Unable to upgrade Flutter: no origin repository configured. '
+ 'Run \'git remote add origin '
+ 'https://github.com/flutter/flutter\' in $workingDirectory');
+ } else {
+ throwToolExit(errorString);
+ }
}
return revision;
}
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index 7f013a4..636f52b 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -787,6 +787,13 @@
await Future.wait(futures);
}
+ Future<void> refreshVM() async {
+ final List<Future<void>> futures = <Future<void>>[
+ for (final FlutterDevice device in flutterDevices) device.getVMs(),
+ ];
+ await Future.wait(futures);
+ }
+
Future<void> debugDumpApp() async {
await refreshViews();
for (final FlutterDevice device in flutterDevices) {
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart
index 727e062..3df2c5b 100644
--- a/packages/flutter_tools/lib/src/run_hot.dart
+++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -798,6 +798,7 @@
if (!_isPaused()) {
globals.printTrace('Refreshing active FlutterViews before reloading.');
+ await refreshVM();
await refreshViews();
}
diff --git a/packages/flutter_tools/templates/app/android.tmpl/settings.gradle b/packages/flutter_tools/templates/app/android.tmpl/settings.gradle
index 5a2f14f..d3b6a40 100644
--- a/packages/flutter_tools/templates/app/android.tmpl/settings.gradle
+++ b/packages/flutter_tools/templates/app/android.tmpl/settings.gradle
@@ -1,15 +1,15 @@
+// Copyright 2014 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.
+
include ':app'
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/packages/flutter_tools/templates/module/android/library/include_flutter.groovy.copy.tmpl b/packages/flutter_tools/templates/module/android/library/include_flutter.groovy.copy.tmpl
index c6939be..ddec9ad 100644
--- a/packages/flutter_tools/templates/module/android/library/include_flutter.groovy.copy.tmpl
+++ b/packages/flutter_tools/templates/module/android/library/include_flutter.groovy.copy.tmpl
@@ -1,35 +1,20 @@
-// Generated file. Do not edit.
+// Copyright 2014 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.
def scriptFile = getClass().protectionDomain.codeSource.location.toURI()
def flutterProjectRoot = new File(scriptFile).parentFile.parentFile
-gradle.include ':flutter'
-gradle.project(':flutter').projectDir = new File(flutterProjectRoot, '.android/Flutter')
+gradle.include ":flutter"
+gradle.project(":flutter").projectDir = new File(flutterProjectRoot, ".android/Flutter")
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot, '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+def localPropertiesFile = new File(flutterProjectRoot, ".android/local.properties")
+def properties = new Properties()
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.toPath().resolve(path).resolve('android').toFile()
- gradle.include ":$name"
- gradle.project(":$name").projectDir = pluginDirectory
-}
+assert localPropertiesFile.exists(), "❗️The Flutter module doesn't have a `$localPropertiesFile` file." +
+ "\nYou must run `flutter pub get` in `$flutterProjectRoot`."
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-gradle.getGradle().projectsLoaded { g ->
- g.rootProject.beforeEvaluate { p ->
- _mainModuleName = binding.variables['mainModuleName']
- if (_mainModuleName != null && !_mainModuleName.empty) {
- p.ext.mainModuleName = _mainModuleName
- }
- }
- g.rootProject.afterEvaluate { p ->
- p.subprojects { sp ->
- if (sp.name != 'flutter') {
- sp.evaluationDependsOn(':flutter')
- }
- }
- }
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+gradle.apply from: "$flutterSdkPath/packages/flutter_tools/gradle/module_plugin_loader.gradle"
diff --git a/packages/flutter_tools/templates/module/android/library_new_embedding/include_flutter.groovy.copy.tmpl b/packages/flutter_tools/templates/module/android/library_new_embedding/include_flutter.groovy.copy.tmpl
index c6939be..ddec9ad 100644
--- a/packages/flutter_tools/templates/module/android/library_new_embedding/include_flutter.groovy.copy.tmpl
+++ b/packages/flutter_tools/templates/module/android/library_new_embedding/include_flutter.groovy.copy.tmpl
@@ -1,35 +1,20 @@
-// Generated file. Do not edit.
+// Copyright 2014 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.
def scriptFile = getClass().protectionDomain.codeSource.location.toURI()
def flutterProjectRoot = new File(scriptFile).parentFile.parentFile
-gradle.include ':flutter'
-gradle.project(':flutter').projectDir = new File(flutterProjectRoot, '.android/Flutter')
+gradle.include ":flutter"
+gradle.project(":flutter").projectDir = new File(flutterProjectRoot, ".android/Flutter")
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot, '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
+def localPropertiesFile = new File(flutterProjectRoot, ".android/local.properties")
+def properties = new Properties()
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.toPath().resolve(path).resolve('android').toFile()
- gradle.include ":$name"
- gradle.project(":$name").projectDir = pluginDirectory
-}
+assert localPropertiesFile.exists(), "❗️The Flutter module doesn't have a `$localPropertiesFile` file." +
+ "\nYou must run `flutter pub get` in `$flutterProjectRoot`."
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
-gradle.getGradle().projectsLoaded { g ->
- g.rootProject.beforeEvaluate { p ->
- _mainModuleName = binding.variables['mainModuleName']
- if (_mainModuleName != null && !_mainModuleName.empty) {
- p.ext.mainModuleName = _mainModuleName
- }
- }
- g.rootProject.afterEvaluate { p ->
- p.subprojects { sp ->
- if (sp.name != 'flutter') {
- sp.evaluationDependsOn(':flutter')
- }
- }
- }
-}
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+gradle.apply from: "$flutterSdkPath/packages/flutter_tools/gradle/module_plugin_loader.gradle"
diff --git a/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart b/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart
index 633ff27..e85c6ea 100644
--- a/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart
+++ b/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart
@@ -161,7 +161,7 @@
Platform: () => fakePlatform,
});
- testUsingContext('fetchRemoteRevision', () async {
+ testUsingContext('fetchRemoteRevision returns revision if git succeeds', () async {
const String revision = 'abc123';
when(processManager.run(
<String>['git', 'fetch', '--tags'],
@@ -186,6 +186,60 @@
Platform: () => fakePlatform,
});
+ testUsingContext('fetchRemoteRevision throws toolExit if HEAD is detached', () async {
+ when(processManager.run(
+ <String>['git', 'fetch', '--tags'],
+ environment:anyNamed('environment'),
+ workingDirectory: anyNamed('workingDirectory')),
+ ).thenAnswer((Invocation invocation) async {
+ return FakeProcessResult()..exitCode = 0;
+ });
+ when(processManager.run(
+ <String>['git', 'rev-parse', '--verify', '@{u}'],
+ environment:anyNamed('environment'),
+ workingDirectory: anyNamed('workingDirectory')),
+ ).thenThrow(const ProcessException(
+ 'git',
+ <String>['rev-parse', '--verify', '@{u}'],
+ 'fatal: HEAD does not point to a branch',
+ ));
+ expect(
+ () async => await realCommandRunner.fetchRemoteRevision(),
+ throwsToolExit(message: 'You are not currently on a release branch.'),
+ );
+ }, overrides: <Type, Generator>{
+ ProcessManager: () => processManager,
+ Platform: () => fakePlatform,
+ });
+
+ testUsingContext('fetchRemoteRevision throws toolExit if no upstream configured', () async {
+ when(processManager.run(
+ <String>['git', 'fetch', '--tags'],
+ environment:anyNamed('environment'),
+ workingDirectory: anyNamed('workingDirectory')),
+ ).thenAnswer((Invocation invocation) async {
+ return FakeProcessResult()..exitCode = 0;
+ });
+ when(processManager.run(
+ <String>['git', 'rev-parse', '--verify', '@{u}'],
+ environment:anyNamed('environment'),
+ workingDirectory: anyNamed('workingDirectory')),
+ ).thenThrow(const ProcessException(
+ 'git',
+ <String>['rev-parse', '--verify', '@{u}'],
+ 'fatal: no upstream configured for branch',
+ ));
+ expect(
+ () async => await realCommandRunner.fetchRemoteRevision(),
+ throwsToolExit(
+ message: 'Unable to upgrade Flutter: no origin repository configured\.',
+ ),
+ );
+ }, overrides: <Type, Generator>{
+ ProcessManager: () => processManager,
+ Platform: () => fakePlatform,
+ });
+
testUsingContext('git exception during attemptReset throwsToolExit', () async {
const String revision = 'abc123';
const String errorMessage = 'fatal: Could not parse object ´$revision´';
diff --git a/packages/flutter_tools/test/general.shard/android/gradle_test.dart b/packages/flutter_tools/test/general.shard/android/gradle_test.dart
index 4906b66..4d20f5d 100644
--- a/packages/flutter_tools/test/general.shard/android/gradle_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/gradle_test.dart
@@ -470,8 +470,10 @@
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
+ if (pluginDirectory.exists()) {
+ include ":$name"
+ project(":$name").projectDir = pluginDirectory
+ }
}
''';
diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
index bbf44b2..fe93619 100644
--- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
@@ -110,6 +110,7 @@
});
when(mockFlutterDevice.vmService).thenReturn(mockVMService);
when(mockFlutterDevice.refreshViews()).thenAnswer((Invocation invocation) async { });
+ when(mockFlutterDevice.getVMs()).thenAnswer((Invocation invocation) async { });
when(mockFlutterDevice.reloadSources(any, pause: anyNamed('pause'))).thenReturn(<Future<Map<String, dynamic>>>[
Future<Map<String, dynamic>>.value(<String, dynamic>{
'type': 'ReloadReport',