diff --git a/packages/flutter_tools/lib/src/flutter_plugins.dart b/packages/flutter_tools/lib/src/flutter_plugins.dart index 72f7dbb123..693ec77a60 100644 --- a/packages/flutter_tools/lib/src/flutter_plugins.dart +++ b/packages/flutter_tools/lib/src/flutter_plugins.dart @@ -277,38 +277,6 @@ String? _readFileContent(File file) { return file.existsSync() ? file.readAsStringSync() : null; } -const String _androidPluginRegistryTemplateOldEmbedding = ''' -package io.flutter.plugins; - -import io.flutter.plugin.common.PluginRegistry; -{{#methodChannelPlugins}} -import {{package}}.{{class}}; -{{/methodChannelPlugins}} - -/** - * Generated file. Do not edit. - */ -public final class GeneratedPluginRegistrant { - public static void registerWith(PluginRegistry registry) { - if (alreadyRegisteredWith(registry)) { - return; - } -{{#methodChannelPlugins}} - {{class}}.registerWith(registry.registrarFor("{{package}}.{{class}}")); -{{/methodChannelPlugins}} - } - - private static boolean alreadyRegisteredWith(PluginRegistry registry) { - final String key = GeneratedPluginRegistrant.class.getCanonicalName(); - if (registry.hasPlugin(key)) { - return true; - } - registry.registrarFor(key); - return false; - } -} -'''; - const String _androidPluginRegistryTemplateNewEmbedding = ''' package io.flutter.plugins; @@ -317,9 +285,6 @@ import androidx.annotation.NonNull; import io.flutter.Log; import io.flutter.embedding.engine.FlutterEngine; -{{#needsShim}} -import io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry; -{{/needsShim}} /** * Generated file. Do not edit. @@ -330,9 +295,6 @@ import io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry; public final class GeneratedPluginRegistrant { private static final String TAG = "GeneratedPluginRegistrant"; public static void registerWith(@NonNull FlutterEngine flutterEngine) { -{{#needsShim}} - ShimPluginRegistry shimPluginRegistry = new ShimPluginRegistry(flutterEngine); -{{/needsShim}} {{#methodChannelPlugins}} {{#supportsEmbeddingV2}} try { @@ -341,15 +303,6 @@ public final class GeneratedPluginRegistrant { Log.e(TAG, "Error registering plugin {{name}}, {{package}}.{{class}}", e); } {{/supportsEmbeddingV2}} - {{^supportsEmbeddingV2}} - {{#supportsEmbeddingV1}} - try { - {{package}}.{{class}}.registerWith(shimPluginRegistry.registrarFor("{{package}}.{{class}}")); - } catch (Exception e) { - Log.e(TAG, "Error registering plugin {{name}}, {{package}}.{{class}}", e); - } - {{/supportsEmbeddingV1}} - {{/supportsEmbeddingV2}} {{/methodChannelPlugins}} } } @@ -366,12 +319,6 @@ List> _extractPlatformMaps(List plugins, String typ return pluginConfigs; } -/// Returns the version of the Android embedding that the current -/// [project] is using. -AndroidEmbeddingVersion _getAndroidEmbeddingVersion(FlutterProject project) { - return project.android.getEmbeddingVersion(); -} - Future _writeAndroidPluginRegistrant(FlutterProject project, List plugins) async { final List methodChannelPlugins = _filterMethodChannelPlugins(plugins, AndroidPlugin.kConfigKey); final List> androidPlugins = _extractPlatformMaps(methodChannelPlugins, AndroidPlugin.kConfigKey); @@ -393,65 +340,7 @@ Future _writeAndroidPluginRegistrant(FlutterProject project, List 'plugins', 'GeneratedPluginRegistrant.java', ); - String templateContent; - final AndroidEmbeddingVersion appEmbeddingVersion = _getAndroidEmbeddingVersion(project); - switch (appEmbeddingVersion) { - case AndroidEmbeddingVersion.v2: - templateContext['needsShim'] = false; - // If a plugin is using an embedding version older than 2.0 and the app is using 2.0, - // then add shim for the old plugins. - - final List pluginsUsingV1 = []; - for (final Map plugin in androidPlugins) { - final bool supportsEmbeddingV1 = (plugin['supportsEmbeddingV1'] as bool?) ?? false; - final bool supportsEmbeddingV2 = (plugin['supportsEmbeddingV2'] as bool?) ?? false; - if (supportsEmbeddingV1 && !supportsEmbeddingV2) { - templateContext['needsShim'] = true; - if (plugin['name'] != null) { - pluginsUsingV1.add(plugin['name']! as String); - } - } - } - if (pluginsUsingV1.length > 1) { - globals.printWarning( - 'The plugins `${pluginsUsingV1.join(', ')}` use a deprecated version of the Android embedding.\n' - 'To avoid unexpected runtime failures, or future build failures, try to see if these plugins ' - 'support the Android V2 embedding. Otherwise, consider removing them since a future release ' - 'of Flutter will remove these deprecated APIs.\n' - 'If you are plugin author, take a look at the docs for migrating the plugin to the V2 embedding: ' - 'https://flutter.dev/go/android-plugin-migration.' - ); - } else if (pluginsUsingV1.isNotEmpty) { - globals.printWarning( - 'The plugin `${pluginsUsingV1.first}` uses a deprecated version of the Android embedding.\n' - 'To avoid unexpected runtime failures, or future build failures, try to see if this plugin ' - 'supports the Android V2 embedding. Otherwise, consider removing it since a future release ' - 'of Flutter will remove these deprecated APIs.\n' - 'If you are plugin author, take a look at the docs for migrating the plugin to the V2 embedding: ' - 'https://flutter.dev/go/android-plugin-migration.' - ); - } - templateContent = _androidPluginRegistryTemplateNewEmbedding; - case AndroidEmbeddingVersion.v1: - globals.printWarning( - 'This app is using a deprecated version of the Android embedding.\n' - 'To avoid unexpected runtime failures, or future build failures, try to migrate this ' - 'app to the V2 embedding.\n' - 'Take a look at the docs for migrating an app: https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects' - ); - for (final Map plugin in androidPlugins) { - final bool supportsEmbeddingV1 = (plugin['supportsEmbeddingV1'] as bool?) ?? false; - final bool supportsEmbeddingV2 = (plugin['supportsEmbeddingV2'] as bool?) ?? false; - if (!supportsEmbeddingV1 && supportsEmbeddingV2) { - throwToolExit( - 'The plugin `${plugin['name']}` requires your app to be migrated to ' - 'the Android embedding v2. Follow the steps on the migration doc above ' - 'and re-run this command.' - ); - } - } - templateContent = _androidPluginRegistryTemplateOldEmbedding; - } + const String templateContent = _androidPluginRegistryTemplateNewEmbedding; globals.printTrace('Generating $registryPath'); await _renderTemplateToFile( templateContent, diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index 711af67c48..b4c2e69399 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'package:meta/meta.dart'; -import 'package:unified_analytics/unified_analytics.dart'; import 'package:xml/xml.dart'; import 'package:yaml/yaml.dart'; @@ -24,7 +23,6 @@ import 'flutter_plugins.dart'; import 'globals.dart' as globals; import 'platform_plugins.dart'; import 'project_validator_result.dart'; -import 'reporting/reporting.dart'; import 'template.dart'; import 'xcode_project.dart'; @@ -806,47 +804,23 @@ $javaGradleCompatUrl if (result.version != AndroidEmbeddingVersion.v1) { return; } - globals.printStatus( -''' -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Warning -────────────────────────────────────────────────────────────────────────────── -Your Flutter application is created using an older version of the Android -embedding. It is being deprecated in favor of Android embedding v2. To migrate -your project, follow the steps at: - -https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects - -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -The detected reason was: - - ${result.reason} -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -'''); - if (deprecationBehavior == DeprecationBehavior.ignore) { - BuildEvent('deprecated-v1-android-embedding-ignored', type: 'gradle', flutterUsage: globals.flutterUsage).send(); - globals.analytics.send( - Event.flutterBuildInfo( - label: 'deprecated-v1-android-embedding-ignored', - buildType: 'gradle', - )); - - } else { // DeprecationBehavior.exit - globals.analytics.send( - Event.flutterBuildInfo( - label: 'deprecated-v1-android-embedding-failed', - buildType: 'gradle', - )); - - throwToolExit( - 'Build failed due to use of deprecated Android v1 embedding.', - exitCode: 1, - ); - } + // The v1 android embedding has been deleted. + throwToolExit( + 'Build failed due to use of deleted Android v1 embedding.', + exitCode: 1, + ); } AndroidEmbeddingVersion getEmbeddingVersion() { - return computeEmbeddingVersion().version; + final AndroidEmbeddingVersion androidEmbeddingVersion = computeEmbeddingVersion().version; + if (androidEmbeddingVersion == AndroidEmbeddingVersion.v1) { + throwToolExit( + 'Build failed due to use of deleted Android v1 embedding.', + exitCode: 1, + ); + } + + return androidEmbeddingVersion; } AndroidEmbeddingVersionResult computeEmbeddingVersion() { diff --git a/packages/flutter_tools/test/commands.shard/hermetic/pub_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/pub_test.dart index d482cf874d..0f637b6645 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/pub_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/pub_test.dart @@ -16,6 +16,17 @@ import 'package:test/fake.dart'; import '../../src/context.dart'; import '../../src/test_flutter_command_runner.dart'; +const String minimalV2EmbeddingManifest = r''' + + + + + +'''; + void main() { late FileSystem fileSystem; late FakePub pub; @@ -48,6 +59,9 @@ void main() { fileSystem.currentDirectory.childFile('pubspec.yaml').createSync(); fileSystem.currentDirectory.childFile('.flutter-plugins').createSync(); fileSystem.currentDirectory.childFile('.flutter-plugins-dependencies').createSync(); + fileSystem.currentDirectory.childDirectory('android').childFile('AndroidManifest.xml') + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); @@ -57,7 +71,7 @@ void main() { expect(await command.usageValues, const CustomDimensions( commandPackagesNumberPlugins: 0, commandPackagesProjectModule: false, - commandPackagesAndroidEmbeddingVersion: 'v1', + commandPackagesAndroidEmbeddingVersion: 'v2', )); }, overrides: { Pub: () => pub, @@ -73,6 +87,9 @@ void main() { fileSystem.currentDirectory.childFile('.dart_tool/package_config.json') ..createSync(recursive: true) ..writeAsBytesSync([0]); + fileSystem.currentDirectory.childDirectory('android').childFile('AndroidManifest.xml') + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); @@ -82,7 +99,7 @@ void main() { expect(await command.usageValues, const CustomDimensions( commandPackagesNumberPlugins: 0, commandPackagesProjectModule: false, - commandPackagesAndroidEmbeddingVersion: 'v1', + commandPackagesAndroidEmbeddingVersion: 'v2', )); }, overrides: { Pub: () => pub, @@ -137,6 +154,9 @@ void main() { testUsingContext("pub get skips example directory if it doesn't contain a pubspec.yaml", () async { fileSystem.currentDirectory.childFile('pubspec.yaml').createSync(); fileSystem.currentDirectory.childDirectory('example').createSync(recursive: true); + fileSystem.currentDirectory.childDirectory('android').childFile('AndroidManifest.xml') + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet); final CommandRunner commandRunner = createTestCommandRunner(command); @@ -146,7 +166,7 @@ void main() { expect(await command.usageValues, const CustomDimensions( commandPackagesNumberPlugins: 0, commandPackagesProjectModule: false, - commandPackagesAndroidEmbeddingVersion: 'v1', + commandPackagesAndroidEmbeddingVersion: 'v2', )); }, overrides: { Pub: () => pub, diff --git a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart index 18b9ad976c..d62cafd47d 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart @@ -7,15 +7,12 @@ import 'dart:async'; import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:file/memory.dart'; -import 'package:flutter_tools/src/android/android_device.dart'; -import 'package:flutter_tools/src/android/android_sdk.dart'; import 'package:flutter_tools/src/application_package.dart'; import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/logger.dart'; -import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/cache.dart'; @@ -369,84 +366,6 @@ void main() { Cache: () => Cache.test(processManager: FakeProcessManager.any()), }); - testUsingContext('fails when v1 FlutterApplication is detected', () async { - fs.file('pubspec.yaml').createSync(); - fs.file('android/AndroidManifest.xml') - ..createSync(recursive: true) - ..writeAsStringSync(''' - - - - - ''', flush: true); - fs.file('.packages').writeAsStringSync('\n'); - fs.file('lib/main.dart').createSync(recursive: true); - final AndroidDevice device = AndroidDevice('1234', - modelID: 'TestModel', - logger: testLogger, - platform: FakePlatform(), - androidSdk: FakeAndroidSdk(), - fileSystem: fs, - processManager: FakeProcessManager.any(), - ); - - testDeviceManager.devices = [device]; - - final RunCommand command = RunCommand(); - await expectLater(createTestCommandRunner(command).run([ - 'run', - '--pub', - ]), throwsToolExit(message: 'Build failed due to use of deprecated Android v1 embedding.')); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - DeviceManager: () => testDeviceManager, - Stdio: () => FakeStdio(), - Cache: () => Cache.test(processManager: FakeProcessManager.any()), - }); - - testUsingContext('fails when v1 metadata is detected', () async { - fs.file('pubspec.yaml').createSync(); - fs.file('android/AndroidManifest.xml') - ..createSync(recursive: true) - ..writeAsStringSync(''' - - - - - - ''', flush: true); - fs.file('.packages').writeAsStringSync('\n'); - fs.file('lib/main.dart').createSync(recursive: true); - final AndroidDevice device = AndroidDevice('1234', - modelID: 'TestModel', - logger: testLogger, - platform: FakePlatform(), - androidSdk: FakeAndroidSdk(), - fileSystem: fs, - processManager: FakeProcessManager.any(), - ); - - testDeviceManager.devices = [device]; - - final RunCommand command = RunCommand(); - await expectLater(createTestCommandRunner(command).run([ - 'run', - '--pub', - ]), throwsToolExit(message: 'Build failed due to use of deprecated Android v1 embedding.')); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - DeviceManager: () => testDeviceManager, - Stdio: () => FakeStdio(), - Cache: () => Cache.test(processManager: FakeProcessManager.any()), - }); - testUsingContext('shows unsupported devices when no supported devices are found', () async { final RunCommand command = RunCommand(); final FakeDevice mockDevice = FakeDevice( @@ -1288,11 +1207,6 @@ class TestDeviceManager extends DeviceManager { } } -class FakeAndroidSdk extends Fake implements AndroidSdk { - @override - String get adbPath => 'adb'; -} - class FakeDevice extends Fake implements Device { FakeDevice({ bool isLocalEmulator = false, diff --git a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart index de1505d091..2c2045da71 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart @@ -457,42 +457,6 @@ flutter: ), }); - testUsingContext('indicate that Android project reports v1 in usage value', () async { - final String projectPath = await createProject(tempDir, - arguments: ['--no-pub']); - removeGeneratedFiles(projectPath); - - final File androidManifest = globals.fs.file(globals.fs.path.join( - projectPath, - 'android/app/src/main/AndroidManifest.xml', - )); - final String updatedAndroidManifestString = - androidManifest.readAsStringSync().replaceAll('android:value="2"', 'android:value="1"'); - - androidManifest.writeAsStringSync(updatedAndroidManifestString); - - final PackagesCommand command = await runCommandIn(projectPath, 'get'); - final PackagesGetCommand getCommand = command.subcommands['get']! as PackagesGetCommand; - - expect((await getCommand.usageValues).commandPackagesAndroidEmbeddingVersion, 'v1'); - expect( - (await getCommand.unifiedAnalyticsUsageValues('pub/get')) - .eventData['packagesAndroidEmbeddingVersion'], - 'v1', - ); - }, overrides: { - Stdio: () => mockStdio, - Pub: () => Pub.test( - fileSystem: globals.fs, - logger: globals.logger, - processManager: globals.processManager, - usage: globals.flutterUsage, - botDetector: globals.botDetector, - platform: globals.platform, - stdio: mockStdio, - ), - }); - testUsingContext('indicate that Android project reports v2 in usage value', () async { final String projectPath = await createProject(tempDir, arguments: ['--no-pub']); diff --git a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart index 124da18267..b7e32a2456 100644 --- a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart +++ b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart @@ -30,6 +30,17 @@ import '../../src/context.dart'; import '../../src/fake_process_manager.dart'; import '../../src/fakes.dart'; +const String minimalV2EmbeddingManifest = r''' + + + + + +'''; + void main() { group('gradle build', () { late BufferLogger logger; @@ -70,7 +81,7 @@ void main() { '-q', '-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -94,10 +105,15 @@ void main() { ..createSync(recursive: true) ..writeAsStringSync('apply from: irrelevant/flutter.gradle'); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); + bool handlerCalled = false; await expectLater(() async { await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -184,7 +200,7 @@ void main() { '-Pverbose=true', '-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -213,8 +229,13 @@ void main() { .childFile('app-release.apk') .createSync(recursive: true); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); + await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -252,7 +273,7 @@ void main() { '-q', '-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -283,11 +304,16 @@ void main() { ..createSync(recursive: true) ..writeAsStringSync('apply from: irrelevant/flutter.gradle'); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); + int testFnCalled = 0; await expectLater(() async { await builder.buildGradleApp( maxRetries: maxRetries, - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -366,7 +392,7 @@ void main() { '-q', '-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -390,10 +416,15 @@ void main() { ..createSync(recursive: true) ..writeAsStringSync('apply from: irrelevant/flutter.gradle'); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); + bool handlerCalled = false; await expectLater(() async { await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -469,7 +500,7 @@ void main() { '-q', '-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -495,9 +526,14 @@ void main() { ..createSync(recursive: true) ..writeAsStringSync('apply from: irrelevant/flutter.gradle'); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); + await expectLater(() async { await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -535,7 +571,7 @@ void main() { '-q', '-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -550,7 +586,7 @@ void main() { '-q', '-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -579,8 +615,13 @@ void main() { .childFile('app-release.apk') .createSync(recursive: true); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); + await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -643,7 +684,7 @@ void main() { '-q', '-Ptarget-platform=android-arm64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -696,8 +737,13 @@ void main() { ..createSync(recursive: true) ..writeAsStringSync('{}'); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); + await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -742,7 +788,7 @@ void main() { '-q', '-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -770,8 +816,13 @@ void main() { .childFile('app-release.apk') .createSync(recursive: true); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); + await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -1194,7 +1245,7 @@ Gradle Crashed '-Plocal-engine-host-out=out/host_release', '-Ptarget-platform=android-arm', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -1230,10 +1281,14 @@ Gradle Crashed .childFile('build.gradle') ..createSync(recursive: true) ..writeAsStringSync('apply from: irrelevant/flutter.gradle'); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); await expectLater(() async { await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -1275,7 +1330,7 @@ Gradle Crashed '-Plocal-engine-host-out=out/host_release', '-Ptarget-platform=android-arm64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -1311,10 +1366,14 @@ Gradle Crashed .childFile('build.gradle') ..createSync(recursive: true) ..writeAsStringSync('apply from: irrelevant/flutter.gradle'); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); await expectLater(() async { await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -1356,7 +1415,7 @@ Gradle Crashed '-Plocal-engine-host-out=out/host_release', '-Ptarget-platform=android-x86', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -1392,10 +1451,14 @@ Gradle Crashed .childFile('build.gradle') ..createSync(recursive: true) ..writeAsStringSync('apply from: irrelevant/flutter.gradle'); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); await expectLater(() async { await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -1437,7 +1500,7 @@ Gradle Crashed '-Plocal-engine-host-out=out/host_release', '-Ptarget-platform=android-x64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -1474,10 +1537,14 @@ Gradle Crashed .childFile('build.gradle') ..createSync(recursive: true) ..writeAsStringSync('apply from: irrelevant/flutter.gradle'); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); await expectLater(() async { await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, @@ -1516,7 +1583,7 @@ Gradle Crashed '--no-daemon', '-Ptarget-platform=android-arm,android-arm64,android-x64', '-Ptarget=lib/main.dart', - '-Pbase-application-name=io.flutter.app.FlutterApplication', + '-Pbase-application-name=android.app.Application', '-Pdart-obfuscation=false', '-Ptrack-widget-creation=false', '-Ptree-shake-icons=false', @@ -1535,10 +1602,14 @@ Gradle Crashed .childFile('build.gradle') ..createSync(recursive: true) ..writeAsStringSync('apply from: irrelevant/flutter.gradle'); + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); await expectLater(() async { await builder.buildGradleApp( - project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), + project: project, androidBuildInfo: const AndroidBuildInfo( BuildInfo( BuildMode.release, diff --git a/packages/flutter_tools/test/general.shard/plugins_test.dart b/packages/flutter_tools/test/general.shard/plugins_test.dart index a1787c0116..2084c4227a 100644 --- a/packages/flutter_tools/test/general.shard/plugins_test.dart +++ b/packages/flutter_tools/test/general.shard/plugins_test.dart @@ -286,63 +286,6 @@ flutter: return pluginUsingJavaAndNewEmbeddingDir; } - void createNewKotlinPlugin2() { - final Directory pluginUsingKotlinAndNewEmbeddingDir = - fs.systemTempDirectory.createTempSync('flutter_plugin_using_kotlin_and_new_embedding_dir.'); - pluginUsingKotlinAndNewEmbeddingDir - .childFile('pubspec.yaml') - .writeAsStringSync(''' -flutter: - plugin: - androidPackage: plugin2 - pluginClass: UseNewEmbedding - '''); - pluginUsingKotlinAndNewEmbeddingDir - .childDirectory('android') - .childDirectory('src') - .childDirectory('main') - .childDirectory('kotlin') - .childDirectory('plugin2') - .childFile('UseNewEmbedding.kt') - ..createSync(recursive: true) - ..writeAsStringSync('import io.flutter.embedding.engine.plugins.FlutterPlugin'); - - flutterProject.directory - .childFile('.packages') - .writeAsStringSync( - 'plugin2:${pluginUsingKotlinAndNewEmbeddingDir.childDirectory('lib').uri}\n', - mode: FileMode.append, - ); - } - - void createOldJavaPlugin(String pluginName) { - final Directory pluginUsingOldEmbeddingDir = - fs.systemTempDirectory.createTempSync('flutter_plugin_using_old_embedding_dir.'); - pluginUsingOldEmbeddingDir - .childFile('pubspec.yaml') - .writeAsStringSync(''' -flutter: - plugin: - androidPackage: $pluginName - pluginClass: UseOldEmbedding - '''); - pluginUsingOldEmbeddingDir - .childDirectory('android') - .childDirectory('src') - .childDirectory('main') - .childDirectory('java') - .childDirectory(pluginName) - .childFile('UseOldEmbedding.java') - .createSync(recursive: true); - - flutterProject.directory - .childFile('.packages') - .writeAsStringSync( - '$pluginName:${pluginUsingOldEmbeddingDir.childDirectory('lib').uri}\n', - mode: FileMode.append, - ); - } - void createDualSupportJavaPlugin4() { final Directory pluginUsingJavaAndNewEmbeddingDir = fs.systemTempDirectory.createTempSync('flutter_plugin_using_java_and_new_embedding_dir.'); @@ -714,24 +657,6 @@ dependencies: xcodeProjectInterpreter = FakeXcodeProjectInterpreter(); }); - testUsingContext('Registrant uses old embedding in app project', () async { - androidProject.embeddingVersion = AndroidEmbeddingVersion.v1; - - await injectPlugins(flutterProject, androidPlatform: true); - - final File registrant = flutterProject.directory - .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins')) - .childFile('GeneratedPluginRegistrant.java'); - - expect(registrant.existsSync(), isTrue); - expect(registrant.readAsStringSync(), contains('package io.flutter.plugins')); - expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant')); - expect(registrant.readAsStringSync(), contains('public static void registerWith(PluginRegistry registry)')); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - }); - testUsingContext('Registrant uses new embedding if app uses new embedding', () async { androidProject.embeddingVersion = AndroidEmbeddingVersion.v2; @@ -750,54 +675,6 @@ dependencies: ProcessManager: () => FakeProcessManager.any(), }); - testUsingContext('Registrant uses shim for plugins using old embedding if app uses new embedding', () async { - androidProject.embeddingVersion = AndroidEmbeddingVersion.v2; - - createNewJavaPlugin1(); - createNewKotlinPlugin2(); - createOldJavaPlugin('plugin3'); - - await injectPlugins(flutterProject, androidPlatform: true); - - final File registrant = flutterProject.directory - .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins')) - .childFile('GeneratedPluginRegistrant.java'); - - expect(registrant.readAsStringSync(), - contains('flutterEngine.getPlugins().add(new plugin1.UseNewEmbedding());')); - expect(registrant.readAsStringSync(), - contains('flutterEngine.getPlugins().add(new plugin2.UseNewEmbedding());')); - expect(registrant.readAsStringSync(), - contains('plugin3.UseOldEmbedding.registerWith(shimPluginRegistry.registrarFor("plugin3.UseOldEmbedding"));')); - - // There should be no warning message - expect(testLogger.statusText, isNot(contains('go/android-plugin-migration'))); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - XcodeProjectInterpreter: () => xcodeProjectInterpreter, - }); - - testUsingContext('exits the tool if an app uses the v1 embedding and a plugin only supports the v2 embedding', () async { - androidProject.embeddingVersion = AndroidEmbeddingVersion.v1; - - createNewJavaPlugin1(); - - await expectLater( - () async { - await injectPlugins(flutterProject, androidPlatform: true); - }, - throwsToolExit( - message: 'The plugin `plugin1` requires your app to be migrated to the Android embedding v2. ' - 'Follow the steps on the migration doc above and re-run this command.' - ), - ); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - XcodeProjectInterpreter: () => xcodeProjectInterpreter, - }); - // Issue: https://github.com/flutter/flutter/issues/47803 testUsingContext('exits the tool if a plugin sets an invalid android package in pubspec.yaml', () async { androidProject.embeddingVersion = AndroidEmbeddingVersion.v1; @@ -823,28 +700,6 @@ dependencies: XcodeProjectInterpreter: () => xcodeProjectInterpreter, }); - testUsingContext('old embedding app uses a plugin that supports v1 and v2 embedding works', () async { - androidProject.embeddingVersion = AndroidEmbeddingVersion.v1; - - createDualSupportJavaPlugin4(); - - await injectPlugins(flutterProject, androidPlatform: true); - - final File registrant = flutterProject.directory - .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins')) - .childFile('GeneratedPluginRegistrant.java'); - - expect(registrant.existsSync(), isTrue); - expect(registrant.readAsStringSync(), contains('package io.flutter.plugins')); - expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant')); - expect(registrant.readAsStringSync(), - contains('UseBothEmbedding.registerWith(registry.registrarFor("plugin4.UseBothEmbedding"));')); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - XcodeProjectInterpreter: () => xcodeProjectInterpreter, - }); - testUsingContext('new embedding app uses a plugin that supports v1 and v2 embedding', () async { androidProject.embeddingVersion = AndroidEmbeddingVersion.v2; @@ -886,30 +741,6 @@ dependencies: ProcessManager: () => FakeProcessManager.any(), }); - testUsingContext('Module using old plugin shows warning', () async { - flutterProject.isModule = true; - androidProject.embeddingVersion = AndroidEmbeddingVersion.v2; - - createOldJavaPlugin('plugin3'); - - await injectPlugins(flutterProject, androidPlatform: true); - - final File registrant = flutterProject.directory - .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins')) - .childFile('GeneratedPluginRegistrant.java'); - expect(registrant.readAsStringSync(), - contains('plugin3.UseOldEmbedding.registerWith(shimPluginRegistry.registrarFor("plugin3.UseOldEmbedding"));')); - expect(testLogger.warningText, equals( - 'The plugin `plugin3` uses a deprecated version of the Android embedding.\n' - 'To avoid unexpected runtime failures, or future build failures, try to see if this plugin supports the Android V2 embedding. ' - 'Otherwise, consider removing it since a future release of Flutter will remove these deprecated APIs.\n' - 'If you are plugin author, take a look at the docs for migrating the plugin to the V2 embedding: https://flutter.dev/go/android-plugin-migration.\n')); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - XcodeProjectInterpreter: () => xcodeProjectInterpreter, - }); - testUsingContext('Module using new plugin shows no warnings', () async { flutterProject.isModule = true; androidProject.embeddingVersion = AndroidEmbeddingVersion.v2; @@ -973,105 +804,6 @@ dependencies: XcodeProjectInterpreter: () => xcodeProjectInterpreter, }); - testUsingContext('App using the v1 embedding shows warning', () async { - flutterProject.isModule = false; - androidProject.embeddingVersion = AndroidEmbeddingVersion.v1; - - await injectPlugins(flutterProject, androidPlatform: true); - - expect(testLogger.warningText, equals( - 'This app is using a deprecated version of the Android embedding.\n' - 'To avoid unexpected runtime failures, or future build failures, try to migrate this app to the V2 embedding.\n' - 'Take a look at the docs for migrating an app: https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects\n' - )); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - XcodeProjectInterpreter: () => xcodeProjectInterpreter, - }); - - testUsingContext('Module using multiple old plugins all show warnings', () async { - flutterProject.isModule = true; - androidProject.embeddingVersion = AndroidEmbeddingVersion.v2; - - createOldJavaPlugin('plugin3'); - createOldJavaPlugin('plugin4'); - - await injectPlugins(flutterProject, androidPlatform: true); - - final File registrant = flutterProject.directory - .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins')) - .childFile('GeneratedPluginRegistrant.java'); - expect(registrant.readAsStringSync(), - contains('plugin3.UseOldEmbedding.registerWith(shimPluginRegistry.registrarFor("plugin3.UseOldEmbedding"));')); - expect(registrant.readAsStringSync(), - contains('plugin4.UseOldEmbedding.registerWith(shimPluginRegistry.registrarFor("plugin4.UseOldEmbedding"));')); - expect(testLogger.warningText, equals( - 'The plugins `plugin3, plugin4` use a deprecated version of the Android embedding.\n' - 'To avoid unexpected runtime failures, or future build failures, try to see if these plugins support the Android V2 embedding. ' - 'Otherwise, consider removing them since a future release of Flutter will remove these deprecated APIs.\n' - 'If you are plugin author, take a look at the docs for migrating the plugin to the V2 embedding: https://flutter.dev/go/android-plugin-migration.\n' - )); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - XcodeProjectInterpreter: () => xcodeProjectInterpreter, - }); - - testUsingContext('App using multiple old plugins all show warnings', () async { - flutterProject.isModule = false; - androidProject.embeddingVersion = AndroidEmbeddingVersion.v2; - - createOldJavaPlugin('plugin3'); - createOldJavaPlugin('plugin4'); - - await injectPlugins(flutterProject, androidPlatform: true); - - final File registrant = flutterProject.directory - .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins')) - .childFile('GeneratedPluginRegistrant.java'); - expect(registrant.readAsStringSync(), - contains('plugin3.UseOldEmbedding.registerWith(shimPluginRegistry.registrarFor("plugin3.UseOldEmbedding"));')); - expect(registrant.readAsStringSync(), - contains('plugin4.UseOldEmbedding.registerWith(shimPluginRegistry.registrarFor("plugin4.UseOldEmbedding"));')); - expect(testLogger.warningText, equals( - 'The plugins `plugin3, plugin4` use a deprecated version of the Android embedding.\n' - 'To avoid unexpected runtime failures, or future build failures, try to see if these plugins support the Android V2 embedding. ' - 'Otherwise, consider removing them since a future release of Flutter will remove these deprecated APIs.\n' - 'If you are plugin author, take a look at the docs for migrating the plugin to the V2 embedding: https://flutter.dev/go/android-plugin-migration.\n' - )); - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - XcodeProjectInterpreter: () => xcodeProjectInterpreter, - }); - - testUsingContext('Module using multiple old and new plugins should be wrapped with try catch', () async { - flutterProject.isModule = true; - androidProject.embeddingVersion = AndroidEmbeddingVersion.v2; - - createOldJavaPlugin('abcplugin1'); - createNewJavaPlugin1(); - - await injectPlugins(flutterProject, androidPlatform: true); - - final File registrant = flutterProject.directory - .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins')) - .childFile('GeneratedPluginRegistrant.java'); - const String newPluginName = 'flutterEngine.getPlugins().add(new plugin1.UseNewEmbedding());'; - const String oldPluginName = 'abcplugin1.UseOldEmbedding.registerWith(shimPluginRegistry.registrarFor("abcplugin1.UseOldEmbedding"));'; - final String content = registrant.readAsStringSync(); - for (final String plugin in [newPluginName,oldPluginName]) { - expect(content, contains(plugin)); - expect(content.split(plugin).first.trim().endsWith('try {'), isTrue); - expect(content.split(plugin).last.trim().startsWith('} catch (Exception e) {'), isTrue); - } - }, overrides: { - FileSystem: () => fs, - ProcessManager: () => FakeProcessManager.any(), - XcodeProjectInterpreter: () => xcodeProjectInterpreter, - }); - testUsingContext('Does not throw when AndroidManifest.xml is not found', () async { final File manifest = fs.file('AndroidManifest.xml'); androidProject.appManifestFile = manifest; diff --git a/packages/flutter_tools/test/general.shard/project_test.dart b/packages/flutter_tools/test/general.shard/project_test.dart index bd84f9d553..2934a2d5f8 100644 --- a/packages/flutter_tools/test/general.shard/project_test.dart +++ b/packages/flutter_tools/test/general.shard/project_test.dart @@ -194,28 +194,6 @@ void main() { throwsToolExit(message: 'Please ensure that the android manifest is a valid XML document and try again.'), ); }); - _testInMemory('Android project not on v2 embedding shows a warning', () async { - final FlutterProject project = await someProject(includePubspec: true); - // The default someProject with an empty already indicates - // v1 embedding, as opposed to having . - - project.checkForDeprecation(deprecationBehavior: DeprecationBehavior.ignore); - expect(testLogger.statusText, contains('https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects')); - }); - _testInMemory('Android project not on v2 embedding exits', () async { - final FlutterProject project = await someProject(includePubspec: true); - // The default someProject with an empty already indicates - // v1 embedding, as opposed to having . - - await expectToolExitLater( - Future.sync(() => project.checkForDeprecation(deprecationBehavior: DeprecationBehavior.exit)), - contains('Build failed due to use of deprecated Android v1 embedding.') - ); - expect(testLogger.statusText, contains('https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects')); - expect(testLogger.statusText, contains('No `` in ')); - }); _testInMemory('Project not on v2 embedding does not warn if deprecation status is irrelevant', () async { final FlutterProject project = await someProject(includePubspec: true); // The default someProject with an empty already indicates @@ -226,15 +204,6 @@ void main() { project.checkForDeprecation(); expect(testLogger.statusText, isEmpty); }); - _testInMemory('Android project not on v2 embedding ignore continues', () async { - final FlutterProject project = await someProject(includePubspec: true); - // The default someProject with an empty already indicates - // v1 embedding, as opposed to having . - - project.checkForDeprecation(deprecationBehavior: DeprecationBehavior.ignore); - expect(testLogger.statusText, contains('https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects')); - }); _testInMemory('Android project no pubspec continues', () async { final FlutterProject project = await someProject(); // The default someProject with an empty already indicates