Don't read AndroidManifest.xml if it doesn't exit (#43669)

diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart
index cae49b0..251d8cb 100644
--- a/packages/flutter_tools/lib/src/plugins.dart
+++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -361,8 +361,11 @@
 /// [project] is using.
 String _getAndroidEmbeddingVersion(FlutterProject project) {
   assert(project.android != null);
+
   final File androidManifest = project.android.appManifestFile;
-  assert(androidManifest.existsSync());
+  if (androidManifest == null || !androidManifest.existsSync()) {
+    return '1';
+  }
   xml.XmlDocument document;
   try {
     document = xml.parse(androidManifest.readAsStringSync());
diff --git a/packages/flutter_tools/test/general.shard/plugins_test.dart b/packages/flutter_tools/test/general.shard/plugins_test.dart
index 68a0594..67d232f 100644
--- a/packages/flutter_tools/test/general.shard/plugins_test.dart
+++ b/packages/flutter_tools/test/general.shard/plugins_test.dart
@@ -16,434 +16,450 @@
 import '../src/context.dart';
 
 void main() {
-  FileSystem fs;
-  MockFlutterProject flutterProject;
-  MockIosProject iosProject;
-  MockMacOSProject macosProject;
-  MockAndroidProject androidProject;
-  MockWebProject webProject;
-  File packagesFile;
-  Directory dummyPackageDirectory;
+  group('plugins', () {
+    FileSystem fs;
+    MockFlutterProject flutterProject;
+    MockIosProject iosProject;
+    MockMacOSProject macosProject;
+    MockAndroidProject androidProject;
+    MockWebProject webProject;
+    File packagesFile;
+    Directory dummyPackageDirectory;
 
-  setUp(() async {
-    fs = MemoryFileSystem();
+    setUp(() async {
+      fs = MemoryFileSystem();
 
-    // Add basic properties to the Flutter project and subprojects
-    flutterProject = MockFlutterProject();
-    when(flutterProject.directory).thenReturn(fs.directory('/'));
-    when(flutterProject.flutterPluginsFile).thenReturn(flutterProject.directory.childFile('.plugins'));
-    iosProject = MockIosProject();
-    when(flutterProject.ios).thenReturn(iosProject);
-    when(iosProject.pluginRegistrantHost).thenReturn(flutterProject.directory.childDirectory('Runner'));
-    when(iosProject.podfile).thenReturn(flutterProject.directory.childDirectory('ios').childFile('Podfile'));
-    when(iosProject.podManifestLock).thenReturn(flutterProject.directory.childDirectory('ios').childFile('Podfile.lock'));
-    macosProject = MockMacOSProject();
-    when(flutterProject.macos).thenReturn(macosProject);
-    when(macosProject.podfile).thenReturn(flutterProject.directory.childDirectory('macos').childFile('Podfile'));
-    when(macosProject.podManifestLock).thenReturn(flutterProject.directory.childDirectory('macos').childFile('Podfile.lock'));
-    androidProject = MockAndroidProject();
-    when(flutterProject.android).thenReturn(androidProject);
-    when(androidProject.pluginRegistrantHost).thenReturn(flutterProject.directory.childDirectory('android').childDirectory('app'));
-    when(androidProject.hostAppGradleRoot).thenReturn(flutterProject.directory.childDirectory('android'));
-    webProject = MockWebProject();
-    when(flutterProject.web).thenReturn(webProject);
-    when(webProject.libDirectory).thenReturn(flutterProject.directory.childDirectory('lib'));
-    when(webProject.existsSync()).thenReturn(true);
+      // Add basic properties to the Flutter project and subprojects
+      flutterProject = MockFlutterProject();
+      when(flutterProject.directory).thenReturn(fs.directory('/'));
+      when(flutterProject.flutterPluginsFile).thenReturn(flutterProject.directory.childFile('.plugins'));
+      iosProject = MockIosProject();
+      when(flutterProject.ios).thenReturn(iosProject);
+      when(iosProject.pluginRegistrantHost).thenReturn(flutterProject.directory.childDirectory('Runner'));
+      when(iosProject.podfile).thenReturn(flutterProject.directory.childDirectory('ios').childFile('Podfile'));
+      when(iosProject.podManifestLock).thenReturn(flutterProject.directory.childDirectory('ios').childFile('Podfile.lock'));
+      macosProject = MockMacOSProject();
+      when(flutterProject.macos).thenReturn(macosProject);
+      when(macosProject.podfile).thenReturn(flutterProject.directory.childDirectory('macos').childFile('Podfile'));
+      when(macosProject.podManifestLock).thenReturn(flutterProject.directory.childDirectory('macos').childFile('Podfile.lock'));
+      androidProject = MockAndroidProject();
+      when(flutterProject.android).thenReturn(androidProject);
+      when(androidProject.pluginRegistrantHost).thenReturn(flutterProject.directory.childDirectory('android').childDirectory('app'));
+      when(androidProject.hostAppGradleRoot).thenReturn(flutterProject.directory.childDirectory('android'));
+      webProject = MockWebProject();
+      when(flutterProject.web).thenReturn(webProject);
+      when(webProject.libDirectory).thenReturn(flutterProject.directory.childDirectory('lib'));
+      when(webProject.existsSync()).thenReturn(true);
 
-    // Set up a simple .packages file for all the tests to use, pointing to one package.
-    dummyPackageDirectory = fs.directory('/pubcache/apackage/lib/');
-    packagesFile = fs.file(fs.path.join(flutterProject.directory.path, PackageMap.globalPackagesPath));
-    packagesFile..createSync(recursive: true)
-        ..writeAsStringSync('apackage:file://${dummyPackageDirectory.path}');
-  });
-
-  // Makes the dummy package pointed to by packagesFile look like a plugin.
-  void configureDummyPackageAsPlugin() {
-    dummyPackageDirectory.parent.childFile('pubspec.yaml')..createSync(recursive: true)..writeAsStringSync('''
-flutter:
-  plugin:
-    platforms:
-      ios:
-        pluginClass: FLESomePlugin
-''');
-  }
-
-  // Creates the files that would indicate that pod install has run for the
-  // given project.
-  void simulatePodInstallRun(XcodeBasedProject project) {
-    project.podManifestLock.createSync(recursive: true);
-  }
-
-  group('refreshPlugins', () {
-    testUsingContext('Refreshing the plugin list is a no-op when the plugins list stays empty', () {
-      refreshPluginsList(flutterProject);
-      expect(flutterProject.flutterPluginsFile.existsSync(), false);
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
+      // Set up a simple .packages file for all the tests to use, pointing to one package.
+      dummyPackageDirectory = fs.directory('/pubcache/apackage/lib/');
+      packagesFile = fs.file(fs.path.join(flutterProject.directory.path, PackageMap.globalPackagesPath));
+      packagesFile..createSync(recursive: true)
+          ..writeAsStringSync('apackage:file://${dummyPackageDirectory.path}');
     });
 
-    testUsingContext('Refreshing the plugin list deletes the plugin file when there were plugins but no longer are', () {
-      flutterProject.flutterPluginsFile.createSync();
-      when(iosProject.existsSync()).thenReturn(false);
-      when(macosProject.existsSync()).thenReturn(false);
-      refreshPluginsList(flutterProject);
-      expect(flutterProject.flutterPluginsFile.existsSync(), false);
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
+    // Makes the dummy package pointed to by packagesFile look like a plugin.
+    void configureDummyPackageAsPlugin() {
+      dummyPackageDirectory.parent.childFile('pubspec.yaml')..createSync(recursive: true)..writeAsStringSync('''
+  flutter:
+    plugin:
+      platforms:
+        ios:
+          pluginClass: FLESomePlugin
+  ''');
+    }
+
+    // Creates the files that would indicate that pod install has run for the
+    // given project.
+    void simulatePodInstallRun(XcodeBasedProject project) {
+      project.podManifestLock.createSync(recursive: true);
+    }
+
+    group('refreshPlugins', () {
+      testUsingContext('Refreshing the plugin list is a no-op when the plugins list stays empty', () {
+        refreshPluginsList(flutterProject);
+        expect(flutterProject.flutterPluginsFile.existsSync(), false);
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+      });
+
+      testUsingContext('Refreshing the plugin list deletes the plugin file when there were plugins but no longer are', () {
+        flutterProject.flutterPluginsFile.createSync();
+        when(iosProject.existsSync()).thenReturn(false);
+        when(macosProject.existsSync()).thenReturn(false);
+        refreshPluginsList(flutterProject);
+        expect(flutterProject.flutterPluginsFile.existsSync(), false);
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+      });
+
+      testUsingContext('Refreshing the plugin list creates a plugin directory when there are plugins', () {
+        configureDummyPackageAsPlugin();
+        when(iosProject.existsSync()).thenReturn(false);
+        when(macosProject.existsSync()).thenReturn(false);
+        refreshPluginsList(flutterProject);
+        expect(flutterProject.flutterPluginsFile.existsSync(), true);
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+      });
+
+      testUsingContext('Changes to the plugin list invalidates the Cocoapod lockfiles', () {
+        simulatePodInstallRun(iosProject);
+        simulatePodInstallRun(macosProject);
+        configureDummyPackageAsPlugin();
+        when(iosProject.existsSync()).thenReturn(true);
+        when(macosProject.existsSync()).thenReturn(true);
+        refreshPluginsList(flutterProject);
+        expect(iosProject.podManifestLock.existsSync(), false);
+        expect(macosProject.podManifestLock.existsSync(), false);
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+      });
     });
 
-    testUsingContext('Refreshing the plugin list creates a plugin directory when there are plugins', () {
-      configureDummyPackageAsPlugin();
-      when(iosProject.existsSync()).thenReturn(false);
-      when(macosProject.existsSync()).thenReturn(false);
-      refreshPluginsList(flutterProject);
-      expect(flutterProject.flutterPluginsFile.existsSync(), true);
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
-    });
+    group('injectPlugins', () {
+      MockFeatureFlags featureFlags;
+      MockXcodeProjectInterpreter xcodeProjectInterpreter;
 
-    testUsingContext('Changes to the plugin list invalidates the Cocoapod lockfiles', () {
-      simulatePodInstallRun(iosProject);
-      simulatePodInstallRun(macosProject);
-      configureDummyPackageAsPlugin();
-      when(iosProject.existsSync()).thenReturn(true);
-      when(macosProject.existsSync()).thenReturn(true);
-      refreshPluginsList(flutterProject);
-      expect(iosProject.podManifestLock.existsSync(), false);
-      expect(macosProject.podManifestLock.existsSync(), false);
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
-    });
-  });
+      const String kAndroidManifestUsingOldEmbedding = '''
+  <manifest>
+      <application>
+      </application>
+  </manifest>
+  ''';
+      const String kAndroidManifestUsingNewEmbedding = '''
+  <manifest>
+      <application>
+          <meta-data
+              android:name="flutterEmbedding"
+              android:value="2" />
+      </application>
+  </manifest>
+  ''';
 
-  group('injectPlugins', () {
-    MockFeatureFlags featureFlags;
-    MockXcodeProjectInterpreter xcodeProjectInterpreter;
+      setUp(() {
+        featureFlags = MockFeatureFlags();
+        when(featureFlags.isLinuxEnabled).thenReturn(false);
+        when(featureFlags.isMacOSEnabled).thenReturn(false);
+        when(featureFlags.isWindowsEnabled).thenReturn(false);
+        when(featureFlags.isWebEnabled).thenReturn(false);
 
-    const String kAndroidManifestUsingOldEmbedding = '''
-<manifest>
-    <application>
-    </application>
-</manifest>
-''';
-    const String kAndroidManifestUsingNewEmbedding = '''
-<manifest>
-    <application>
-        <meta-data
-            android:name="flutterEmbedding"
-            android:value="2" />
-    </application>
-</manifest>
-''';
+        xcodeProjectInterpreter = MockXcodeProjectInterpreter();
+        when(xcodeProjectInterpreter.isInstalled).thenReturn(false);
+      });
 
-    setUp(() {
-      featureFlags = MockFeatureFlags();
-      when(featureFlags.isLinuxEnabled).thenReturn(false);
-      when(featureFlags.isMacOSEnabled).thenReturn(false);
-      when(featureFlags.isWindowsEnabled).thenReturn(false);
-      when(featureFlags.isWebEnabled).thenReturn(false);
+      testUsingContext('Registrant uses old embedding in app project', () async {
+        when(flutterProject.isModule).thenReturn(false);
 
-      xcodeProjectInterpreter = MockXcodeProjectInterpreter();
-      when(xcodeProjectInterpreter.isInstalled).thenReturn(false);
-    });
+        final File androidManifest = flutterProject.directory
+          .childDirectory('android')
+          .childFile('AndroidManifest.xml')
+          ..createSync(recursive: true)
+          ..writeAsStringSync(kAndroidManifestUsingOldEmbedding);
+        when(androidProject.appManifestFile).thenReturn(androidManifest);
 
-    testUsingContext('Registrant uses old embedding in app project', () async {
-      when(flutterProject.isModule).thenReturn(false);
+        await injectPlugins(flutterProject);
 
-      final File androidManifest = flutterProject.directory
-        .childDirectory('android')
-        .childFile('AndroidManifest.xml')
-        ..createSync(recursive: true)
-        ..writeAsStringSync(kAndroidManifestUsingOldEmbedding);
-      when(androidProject.appManifestFile).thenReturn(androidManifest);
+        final File registrant = flutterProject.directory
+          .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
+          .childFile('GeneratedPluginRegistrant.java');
 
-      await injectPlugins(flutterProject);
+        expect(registrant.existsSync(), isTrue);
+        expect(registrant.readAsStringSync(), contains('package io.flutter.plugins'));
+        expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant'));
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+        FeatureFlags: () => featureFlags,
+      });
 
-      final File registrant = flutterProject.directory
-        .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
-        .childFile('GeneratedPluginRegistrant.java');
+      testUsingContext('Registrant uses new embedding if app uses new embedding', () async {
+        when(flutterProject.isModule).thenReturn(false);
 
-      expect(registrant.existsSync(), isTrue);
-      expect(registrant.readAsStringSync(), contains('package io.flutter.plugins'));
-      expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant'));
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
-      FeatureFlags: () => featureFlags,
-    });
+        final File androidManifest = flutterProject.directory
+          .childDirectory('android')
+          .childFile('AndroidManifest.xml')
+          ..createSync(recursive: true)
+          ..writeAsStringSync(kAndroidManifestUsingNewEmbedding);
+        when(androidProject.appManifestFile).thenReturn(androidManifest);
 
-    testUsingContext('Registrant uses new embedding if app uses new embedding', () async {
-      when(flutterProject.isModule).thenReturn(false);
+        await injectPlugins(flutterProject);
 
-      final File androidManifest = flutterProject.directory
-        .childDirectory('android')
-        .childFile('AndroidManifest.xml')
-        ..createSync(recursive: true)
-        ..writeAsStringSync(kAndroidManifestUsingNewEmbedding);
-      when(androidProject.appManifestFile).thenReturn(androidManifest);
+        final File registrant = flutterProject.directory
+          .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'dev', 'flutter', 'plugins'))
+          .childFile('GeneratedPluginRegistrant.java');
 
-      await injectPlugins(flutterProject);
+        expect(registrant.existsSync(), isTrue);
+        expect(registrant.readAsStringSync(), contains('package dev.flutter.plugins'));
+        expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant'));
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+        FeatureFlags: () => featureFlags,
+      });
 
-      final File registrant = flutterProject.directory
-        .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'dev', 'flutter', 'plugins'))
-        .childFile('GeneratedPluginRegistrant.java');
+      testUsingContext('Registrant uses shim for plugins using old embedding if app uses new embedding', () async {
+        when(flutterProject.isModule).thenReturn(false);
 
-      expect(registrant.existsSync(), isTrue);
-      expect(registrant.readAsStringSync(), contains('package dev.flutter.plugins'));
-      expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant'));
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
-      FeatureFlags: () => featureFlags,
-    });
+        final File androidManifest = flutterProject.directory
+          .childDirectory('android')
+          .childFile('AndroidManifest.xml')
+          ..createSync(recursive: true)
+          ..writeAsStringSync(kAndroidManifestUsingNewEmbedding);
+        when(androidProject.appManifestFile).thenReturn(androidManifest);
 
-    testUsingContext('Registrant uses shim for plugins using old embedding if app uses new embedding', () async {
-      when(flutterProject.isModule).thenReturn(false);
+        final Directory pluginUsingJavaAndNewEmbeddingDir =
+          fs.systemTempDirectory.createTempSync('flutter_plugin_using_java_and_new_embedding_dir.');
+        pluginUsingJavaAndNewEmbeddingDir
+          .childFile('pubspec.yaml')
+          .writeAsStringSync('''
+  flutter:
+    plugin:
+      androidPackage: plugin1
+      pluginClass: UseNewEmbedding
+  ''');
+        pluginUsingJavaAndNewEmbeddingDir
+          .childDirectory('android')
+          .childDirectory('src')
+          .childDirectory('main')
+          .childDirectory('java')
+          .childDirectory('plugin1')
+          .childFile('UseNewEmbedding.java')
+          ..createSync(recursive: true)
+          ..writeAsStringSync('import io.flutter.embedding.engine.plugins.FlutterPlugin;');
 
-      final File androidManifest = flutterProject.directory
-        .childDirectory('android')
-        .childFile('AndroidManifest.xml')
-        ..createSync(recursive: true)
-        ..writeAsStringSync(kAndroidManifestUsingNewEmbedding);
-      when(androidProject.appManifestFile).thenReturn(androidManifest);
+        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');
 
-      final Directory pluginUsingJavaAndNewEmbeddingDir =
-        fs.systemTempDirectory.createTempSync('flutter_plugin_using_java_and_new_embedding_dir.');
-      pluginUsingJavaAndNewEmbeddingDir
-        .childFile('pubspec.yaml')
-        .writeAsStringSync('''
-flutter:
-  plugin:
-    androidPackage: plugin1
-    pluginClass: UseNewEmbedding
-''');
-      pluginUsingJavaAndNewEmbeddingDir
-        .childDirectory('android')
-        .childDirectory('src')
-        .childDirectory('main')
-        .childDirectory('java')
-        .childDirectory('plugin1')
-        .childFile('UseNewEmbedding.java')
-        ..createSync(recursive: true)
-        ..writeAsStringSync('import io.flutter.embedding.engine.plugins.FlutterPlugin;');
+        final Directory pluginUsingOldEmbeddingDir =
+          fs.systemTempDirectory.createTempSync('flutter_plugin_using_old_embedding_dir.');
+        pluginUsingOldEmbeddingDir
+          .childFile('pubspec.yaml')
+          .writeAsStringSync('''
+  flutter:
+    plugin:
+      androidPackage: plugin3
+      pluginClass: UseOldEmbedding
+  ''');
+        pluginUsingOldEmbeddingDir
+          .childDirectory('android')
+          .childDirectory('src')
+          .childDirectory('main')
+          .childDirectory('java')
+          .childDirectory('plugin3')
+          .childFile('UseOldEmbedding.java')
+          ..createSync(recursive: true);
 
-      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');
-
-      final Directory pluginUsingOldEmbeddingDir =
-        fs.systemTempDirectory.createTempSync('flutter_plugin_using_old_embedding_dir.');
-      pluginUsingOldEmbeddingDir
-        .childFile('pubspec.yaml')
-        .writeAsStringSync('''
-flutter:
-  plugin:
-    androidPackage: plugin3
-    pluginClass: UseOldEmbedding
-''');
-      pluginUsingOldEmbeddingDir
-        .childDirectory('android')
-        .childDirectory('src')
-        .childDirectory('main')
-        .childDirectory('java')
-        .childDirectory('plugin3')
-        .childFile('UseOldEmbedding.java')
-        ..createSync(recursive: true);
-
-      flutterProject.directory
-        .childFile('.packages')
-        .writeAsStringSync('''
+        flutterProject.directory
+          .childFile('.packages')
+          .writeAsStringSync('''
 plugin1:${pluginUsingJavaAndNewEmbeddingDir.childDirectory('lib').uri.toString()}
 plugin2:${pluginUsingKotlinAndNewEmbeddingDir.childDirectory('lib').uri.toString()}
 plugin3:${pluginUsingOldEmbeddingDir.childDirectory('lib').uri.toString()}
 ''');
 
-      await injectPlugins(flutterProject);
+        await injectPlugins(flutterProject);
 
-      final File registrant = flutterProject.directory
-        .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'dev', 'flutter', 'plugins'))
-        .childFile('GeneratedPluginRegistrant.java');
+        final File registrant = flutterProject.directory
+          .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'dev', '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"));'));
+        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"));'));
 
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
-      FeatureFlags: () => featureFlags,
-      XcodeProjectInterpreter: () => xcodeProjectInterpreter,
-    });
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+        FeatureFlags: () => featureFlags,
+        XcodeProjectInterpreter: () => xcodeProjectInterpreter,
+      });
 
-    testUsingContext('Registrant doesn\'t use new embedding if app doesn\'t use new embedding', () async {
-      when(flutterProject.isModule).thenReturn(false);
+      testUsingContext('Registrant doesn\'t use new embedding if app doesn\'t use new embedding', () async {
+        when(flutterProject.isModule).thenReturn(false);
 
-      final File androidManifest = flutterProject.directory
-        .childDirectory('android')
-        .childFile('AndroidManifest.xml')
-        ..createSync(recursive: true)
-        ..writeAsStringSync(kAndroidManifestUsingOldEmbedding);
-      when(androidProject.appManifestFile).thenReturn(androidManifest);
+        final File androidManifest = flutterProject.directory
+          .childDirectory('android')
+          .childFile('AndroidManifest.xml')
+          ..createSync(recursive: true)
+          ..writeAsStringSync(kAndroidManifestUsingOldEmbedding);
+        when(androidProject.appManifestFile).thenReturn(androidManifest);
 
-      await injectPlugins(flutterProject);
+        await injectPlugins(flutterProject);
 
-      final File registrant = flutterProject.directory
-        .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
-        .childFile('GeneratedPluginRegistrant.java');
+        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'));
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
-      FeatureFlags: () => featureFlags,
-    });
+        expect(registrant.existsSync(), isTrue);
+        expect(registrant.readAsStringSync(), contains('package io.flutter.plugins'));
+        expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant'));
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+        FeatureFlags: () => featureFlags,
+      });
 
-    testUsingContext('Registrant uses old embedding in module project', () async {
-      when(flutterProject.isModule).thenReturn(true);
+      testUsingContext('Registrant uses old embedding in module project', () async {
+        when(flutterProject.isModule).thenReturn(true);
 
-      final File androidManifest = flutterProject.directory
-        .childDirectory('android')
-        .childFile('AndroidManifest.xml')
-        ..createSync(recursive: true)
-        ..writeAsStringSync(kAndroidManifestUsingOldEmbedding);
-      when(androidProject.appManifestFile).thenReturn(androidManifest);
+        final File androidManifest = flutterProject.directory
+          .childDirectory('android')
+          .childFile('AndroidManifest.xml')
+          ..createSync(recursive: true)
+          ..writeAsStringSync(kAndroidManifestUsingOldEmbedding);
+        when(androidProject.appManifestFile).thenReturn(androidManifest);
 
-      await injectPlugins(flutterProject);
+        await injectPlugins(flutterProject);
 
-      final File registrant = flutterProject.directory
-        .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
-        .childFile('GeneratedPluginRegistrant.java');
+        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'));
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
-      FeatureFlags: () => featureFlags,
-    });
+        expect(registrant.existsSync(), isTrue);
+        expect(registrant.readAsStringSync(), contains('package io.flutter.plugins'));
+        expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant'));
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+        FeatureFlags: () => featureFlags,
+      });
 
-    testUsingContext('Registrant uses new embedding if module uses new embedding', () async {
-      when(flutterProject.isModule).thenReturn(true);
+      testUsingContext('Registrant uses new embedding if module uses new embedding', () async {
+        when(flutterProject.isModule).thenReturn(true);
 
-      final File androidManifest = flutterProject.directory
-        .childDirectory('android')
-        .childFile('AndroidManifest.xml')
-        ..createSync(recursive: true)
-        ..writeAsStringSync(kAndroidManifestUsingNewEmbedding);
-      when(androidProject.appManifestFile).thenReturn(androidManifest);
+        final File androidManifest = flutterProject.directory
+          .childDirectory('android')
+          .childFile('AndroidManifest.xml')
+          ..createSync(recursive: true)
+          ..writeAsStringSync(kAndroidManifestUsingNewEmbedding);
+        when(androidProject.appManifestFile).thenReturn(androidManifest);
 
-      await injectPlugins(flutterProject);
+        await injectPlugins(flutterProject);
 
-      final File registrant = flutterProject.directory
-        .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'dev', 'flutter', 'plugins'))
-        .childFile('GeneratedPluginRegistrant.java');
+        final File registrant = flutterProject.directory
+          .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'dev', 'flutter', 'plugins'))
+          .childFile('GeneratedPluginRegistrant.java');
 
-      expect(registrant.existsSync(), isTrue);
-      expect(registrant.readAsStringSync(), contains('package dev.flutter.plugins'));
-      expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant'));
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
-      FeatureFlags: () => featureFlags,
-    });
+        expect(registrant.existsSync(), isTrue);
+        expect(registrant.readAsStringSync(), contains('package dev.flutter.plugins'));
+        expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant'));
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+        FeatureFlags: () => featureFlags,
+      });
 
-    testUsingContext('Registrant doesn\'t use new embedding if module doesn\'t use new embedding', () async {
-      when(flutterProject.isModule).thenReturn(true);
+      testUsingContext('Registrant doesn\'t use new embedding if module doesn\'t use new embedding', () async {
+        when(flutterProject.isModule).thenReturn(true);
 
-      final File androidManifest = flutterProject.directory
-        .childDirectory('android')
-        .childFile('AndroidManifest.xml')
-        ..createSync(recursive: true)
-        ..writeAsStringSync(kAndroidManifestUsingOldEmbedding);
-      when(androidProject.appManifestFile).thenReturn(androidManifest);
+        final File androidManifest = flutterProject.directory
+          .childDirectory('android')
+          .childFile('AndroidManifest.xml')
+          ..createSync(recursive: true)
+          ..writeAsStringSync(kAndroidManifestUsingOldEmbedding);
+        when(androidProject.appManifestFile).thenReturn(androidManifest);
 
-      await injectPlugins(flutterProject);
+        await injectPlugins(flutterProject);
 
-      final File registrant = flutterProject.directory
-        .childDirectory(fs.path.join('android', 'app', 'src', 'main', 'java', 'io', 'flutter', 'plugins'))
-        .childFile('GeneratedPluginRegistrant.java');
+        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'));
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
-      FeatureFlags: () => featureFlags,
-    });
+        expect(registrant.existsSync(), isTrue);
+        expect(registrant.readAsStringSync(), contains('package io.flutter.plugins'));
+        expect(registrant.readAsStringSync(), contains('class GeneratedPluginRegistrant'));
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+        FeatureFlags: () => featureFlags,
+      });
 
-    testUsingContext('Registrant for web doesn\'t escape slashes in imports', () async {
-      when(flutterProject.isModule).thenReturn(true);
-      when(featureFlags.isWebEnabled).thenReturn(true);
+      testUsingContext('Does not throw when AndroidManifest.xml is not found', () async {
+        when(flutterProject.isModule).thenReturn(false);
 
-      // injectPlugins will crash if there is no AndroidManifest
-      final File androidManifest = flutterProject.directory
-        .childDirectory('android')
-        .childFile('AndroidManifest.xml')
-        ..createSync(recursive: true)
-        ..writeAsStringSync(kAndroidManifestUsingOldEmbedding);
-      when(androidProject.appManifestFile).thenReturn(androidManifest);
+        final File manifest = MockFile();
+        when(manifest.existsSync()).thenReturn(false);
+        when(androidProject.appManifestFile).thenReturn(manifest);
 
-      final Directory webPluginWithNestedFile =
-          fs.systemTempDirectory.createTempSync('web_plugin_with_nested');
-      webPluginWithNestedFile.childFile('pubspec.yaml').writeAsStringSync('''
-flutter:
-  plugin:
-    platforms:
-      web:
-        pluginClass: WebPlugin
-        fileName: src/web_plugin.dart
-''');
-      webPluginWithNestedFile
-        .childDirectory('lib')
-        .childDirectory('src')
-        .childFile('web_plugin.dart')
-        ..createSync(recursive: true);
+        await injectPlugins(flutterProject);
 
-      flutterProject.directory
-        .childFile('.packages')
-        .writeAsStringSync('''
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+      });
+
+      testUsingContext('Registrant for web doesn\'t escape slashes in imports', () async {
+        when(flutterProject.isModule).thenReturn(true);
+        when(featureFlags.isWebEnabled).thenReturn(true);
+
+        // injectPlugins will crash if there is no AndroidManifest
+        final File androidManifest = flutterProject.directory
+          .childDirectory('android')
+          .childFile('AndroidManifest.xml')
+          ..createSync(recursive: true)
+          ..writeAsStringSync(kAndroidManifestUsingOldEmbedding);
+        when(androidProject.appManifestFile).thenReturn(androidManifest);
+
+        final Directory webPluginWithNestedFile =
+            fs.systemTempDirectory.createTempSync('web_plugin_with_nested');
+        webPluginWithNestedFile.childFile('pubspec.yaml').writeAsStringSync('''
+  flutter:
+    plugin:
+      platforms:
+        web:
+          pluginClass: WebPlugin
+          fileName: src/web_plugin.dart
+  ''');
+        webPluginWithNestedFile
+          .childDirectory('lib')
+          .childDirectory('src')
+          .childFile('web_plugin.dart')
+          ..createSync(recursive: true);
+
+        flutterProject.directory
+          .childFile('.packages')
+          .writeAsStringSync('''
 web_plugin_with_nested:${webPluginWithNestedFile.childDirectory('lib').uri.toString()}
 ''');
 
-      await injectPlugins(flutterProject);
+        await injectPlugins(flutterProject);
 
-      final File registrant = flutterProject.directory
-          .childDirectory('lib')
-          .childFile('generated_plugin_registrant.dart');
+        final File registrant = flutterProject.directory
+            .childDirectory('lib')
+            .childFile('generated_plugin_registrant.dart');
 
-      expect(registrant.existsSync(), isTrue);
-      expect(registrant.readAsStringSync(), contains("import 'package:web_plugin_with_nested/src/web_plugin.dart';"));
-    }, overrides: <Type, Generator>{
-      FileSystem: () => fs,
-      ProcessManager: () => FakeProcessManager.any(),
-      FeatureFlags: () => featureFlags,
+        expect(registrant.existsSync(), isTrue);
+        expect(registrant.readAsStringSync(), contains("import 'package:web_plugin_with_nested/src/web_plugin.dart';"));
+      }, overrides: <Type, Generator>{
+        FileSystem: () => fs,
+        ProcessManager: () => FakeProcessManager.any(),
+        FeatureFlags: () => featureFlags,
+      });
     });
   });
 }
@@ -451,6 +467,7 @@
 class MockAndroidProject extends Mock implements AndroidProject {}
 class MockFeatureFlags extends Mock implements FeatureFlags {}
 class MockFlutterProject extends Mock implements FlutterProject {}
+class MockFile extends Mock implements File {}
 class MockIosProject extends Mock implements IosProject {}
 class MockMacOSProject extends Mock implements MacOSProject {}
 class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}