Move plugin injection to just after pub get (#14743)

diff --git a/dev/devicelab/bin/tasks/plugin_test.dart b/dev/devicelab/bin/tasks/plugin_test.dart
new file mode 100644
index 0000000..3217961
--- /dev/null
+++ b/dev/devicelab/bin/tasks/plugin_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2018 The Chromium 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 'package:flutter_devicelab/tasks/plugin_tests.dart';
+import 'package:flutter_devicelab/framework/framework.dart';
+
+Future<Null> main() async {
+  await task(new PluginTest('apk'));
+}
diff --git a/dev/devicelab/bin/tasks/plugin_test_ios.dart b/dev/devicelab/bin/tasks/plugin_test_ios.dart
new file mode 100644
index 0000000..492e7d6
--- /dev/null
+++ b/dev/devicelab/bin/tasks/plugin_test_ios.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2018 The Chromium 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 'package:flutter_devicelab/tasks/plugin_tests.dart';
+import 'package:flutter_devicelab/framework/framework.dart';
+
+Future<Null> main() async {
+  await task(new PluginTest('ios'));
+}
diff --git a/dev/devicelab/bin/tasks/plugin_test_win.dart b/dev/devicelab/bin/tasks/plugin_test_win.dart
new file mode 100644
index 0000000..3217961
--- /dev/null
+++ b/dev/devicelab/bin/tasks/plugin_test_win.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2018 The Chromium 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 'package:flutter_devicelab/tasks/plugin_tests.dart';
+import 'package:flutter_devicelab/framework/framework.dart';
+
+Future<Null> main() async {
+  await task(new PluginTest('apk'));
+}
diff --git a/dev/devicelab/lib/tasks/plugin_tests.dart b/dev/devicelab/lib/tasks/plugin_tests.dart
new file mode 100644
index 0000000..d7baac5
--- /dev/null
+++ b/dev/devicelab/lib/tasks/plugin_tests.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2018 The Chromium 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:path/path.dart' as path;
+import 'package:flutter_devicelab/framework/framework.dart';
+import 'package:flutter_devicelab/framework/ios.dart';
+import 'package:flutter_devicelab/framework/utils.dart';
+
+/// Defines task that creates new Flutter project, adds a plugin, and then
+/// builds the specified [buildTarget].
+class PluginTest {
+  final String buildTarget;
+
+  PluginTest(this.buildTarget);
+
+  Future<TaskResult> call() async {
+    section('Create Flutter project');
+    final Directory tmp = await Directory.systemTemp.createTemp('plugin');
+    final FlutterProject project = await FlutterProject.create(tmp);
+    if (buildTarget == 'ios') {
+      await prepareProvisioningCertificates(project.rootPath);
+    }
+    try {
+      section('Add plugin');
+      await project.addPlugin('path_provider');
+
+      section('Build');
+      await project.build(buildTarget);
+
+      return new TaskResult.success(null);
+    } catch (e) {
+      return new TaskResult.failure(e.toString());
+    } finally {
+      await project.delete();
+    }
+  }
+}
+
+class FlutterProject {
+  FlutterProject(this.parent, this.name);
+
+  final Directory parent;
+  final String name;
+
+  static Future<FlutterProject> create(Directory directory) async {
+    await inDirectory(directory, () async {
+      await flutter('create', options: <String>['--org', 'io.flutter.devicelab', 'plugintest']);
+    });
+    return new FlutterProject(directory, 'plugintest');
+  }
+
+  String get rootPath => path.join(parent.path, name);
+
+  Future<Null> addPlugin(String plugin) async {
+    final File pubspec = new File(path.join(rootPath, 'pubspec.yaml'));
+    String content = await pubspec.readAsString();
+    content = content.replaceFirst(
+      '\ndependencies:\n',
+      '\ndependencies:\n  $plugin:\n',
+    );
+    await pubspec.writeAsString(content, flush: true);
+  }
+
+  Future<Null> build(String target) async {
+    await inDirectory(new Directory(rootPath), () async {
+      await flutter('build', options: <String>[target]);
+    });
+  }
+
+  Future<Null> delete() async {
+    await parent.delete(recursive: true);
+  }
+}
diff --git a/dev/devicelab/manifest.yaml b/dev/devicelab/manifest.yaml
index 63b3d1f..27a0bfc 100644
--- a/dev/devicelab/manifest.yaml
+++ b/dev/devicelab/manifest.yaml
@@ -237,6 +237,13 @@
     stage: devicelab
     required_agent_capabilities: ["linux/android"]
 
+  plugin_test:
+    description: >
+      Checks that the project template works and supports plugins.
+    stage: devicelab
+    required_agent_capabilities: ["linux/android"]
+    flaky: true
+
   flutter_gallery_instrumentation_test:
     description: >
       Same as flutter_gallery__transition_perf but uses Android instrumentation
@@ -253,6 +260,13 @@
     stage: devicelab_ios
     required_agent_capabilities: ["mac/ios"]
 
+  plugin_test_ios:
+    description: >
+      Checks that the project template works and supports plugins on iOS.
+    stage: devicelab_ios
+    required_agent_capabilities: ["mac/ios"]
+    flaky: true
+
   external_ui_integration_test_ios:
     description: >
       Checks that external UIs work on iOS.
@@ -347,6 +361,13 @@
     stage: devicelab_win
     required_agent_capabilities: ["windows/android"]
 
+  plugin_test_win:
+    description: >
+      Checks that the project template works and supports plugins on Windows.
+    stage: devicelab_win
+    required_agent_capabilities: ["windows/android"]
+    flaky: true
+
   hot_mode_dev_cycle_win__benchmark:
     description: >
       Measures the performance of Dart VM hot patching feature on Windows.