Adding back commit #e0f6e62 with fix to test failures (#15212)

* Add to Artifacts, and add optional arguments to entry points for flut… (#15185)

Add to Artifacts, and add optional arguments to entry points for flutter run and test to allow for wiring up the same with preview-dart-2 internally

* Changing packages uri here is not necessary
diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart
index 9b11fde..ec33659 100644
--- a/packages/flutter_tools/lib/src/artifacts.dart
+++ b/packages/flutter_tools/lib/src/artifacts.dart
@@ -26,6 +26,7 @@
   flutterPatchedSdkPath,
   frontendServerSnapshotForEngineDartSdk,
   engineDartSdkPath,
+  engineDartBinary,
 }
 
 String _artifactToFileName(Artifact artifact) {
@@ -57,6 +58,8 @@
       return 'dart-sdk';
     case Artifact.frontendServerSnapshotForEngineDartSdk:
       return 'frontend_server.dart.snapshot';
+    case Artifact.engineDartBinary:
+      return 'dart';
   }
   assert(false, 'Invalid artifact $artifact.');
   return null;
@@ -170,6 +173,8 @@
         return fs.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact));
       case Artifact.engineDartSdkPath:
         return dartSdkPath;
+      case Artifact.engineDartBinary:
+        return fs.path.join(dartSdkPath,'bin', _artifactToFileName(artifact));
       case Artifact.platformKernelDill:
         return fs.path.join(_getFlutterPatchedSdkPath(), _artifactToFileName(artifact));
       case Artifact.platformLibrariesJson:
@@ -252,6 +257,8 @@
         return fs.path.join(_hostEngineOutPath, 'gen', _artifactToFileName(artifact));
       case Artifact.engineDartSdkPath:
         return fs.path.join(_hostEngineOutPath, 'dart-sdk');
+      case Artifact.engineDartBinary:
+        return fs.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', _artifactToFileName(artifact));
     }
     assert(false, 'Invalid artifact $artifact.');
     return null;
diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart
index 251573e..e374eda 100644
--- a/packages/flutter_tools/lib/src/commands/daemon.dart
+++ b/packages/flutter_tools/lib/src/commands/daemon.dart
@@ -357,6 +357,7 @@
     @required bool trackWidgetCreation,
     String projectRootPath,
     String packagesFilePath,
+    String dillOutputPath,
     bool ipv6: false,
   }) async {
     if (await device.isLocalEmulator && !options.buildInfo.supportsEmulator) {
@@ -371,6 +372,7 @@
       device,
       previewDart2: options.buildInfo.previewDart2,
       trackWidgetCreation: trackWidgetCreation,
+      dillOutputPath: dillOutputPath,
     );
 
     ResidentRunner runner;
@@ -384,6 +386,7 @@
         applicationBinary: applicationBinary,
         projectRootPath: projectRootPath,
         packagesFilePath: packagesFilePath,
+        dillOutputPath: dillOutputPath,
         ipv6: ipv6,
         hostIsIde: true,
       );
diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart
index b369987..8541b5d 100644
--- a/packages/flutter_tools/lib/src/commands/run.dart
+++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -147,6 +147,10 @@
             'results out to "refresh_benchmark.json", and exit. This flag is\n'
             'intended for use in generating automated flutter benchmarks.');
 
+    argParser.addOption('output-dill',
+        hide: !verboseHelp,
+        help: 'Specify the path to frontend server output kernel file.');
+
     argParser.addOption(FlutterOptions.kExtraFrontEndOptions, hide: true);
     argParser.addOption(FlutterOptions.kExtraGenSnapshotOptions, hide: true);
   }
@@ -262,6 +266,7 @@
           trackWidgetCreation: argResults['track-widget-creation'],
           projectRootPath: argResults['project-root'],
           packagesFilePath: globalResults['packages'],
+          dillOutputPath: argResults['output-dill'],
           ipv6: ipv6,
         );
       } catch (error) {
@@ -301,6 +306,7 @@
         device,
         previewDart2: argResults['preview-dart-2'],
         trackWidgetCreation: argResults['track-widget-creation'],
+        dillOutputPath: argResults['output-dill'],
       );
     }).toList();
 
@@ -314,6 +320,7 @@
         applicationBinary: argResults['use-application-binary'],
         projectRootPath: argResults['project-root'],
         packagesFilePath: globalResults['packages'],
+        dillOutputPath: argResults['output-dill'],
         stayResident: stayResident,
         ipv6: ipv6,
       );
diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart
index bfee499..f99d21b 100644
--- a/packages/flutter_tools/lib/src/compile.dart
+++ b/packages/flutter_tools/lib/src/compile.dart
@@ -8,24 +8,10 @@
 import 'package:usage/uuid/uuid.dart';
 
 import 'artifacts.dart';
-import 'base/common.dart';
-import 'base/file_system.dart';
 import 'base/io.dart';
 import 'base/process_manager.dart';
 import 'globals.dart';
 
-String _dartExecutable() {
-  final String engineDartSdkPath = artifacts.getArtifactPath(
-    Artifact.engineDartSdkPath
-  );
-  if (!fs.isDirectorySync(engineDartSdkPath)) {
-    throwToolExit('No dart sdk Flutter host engine build found at $engineDartSdkPath.\n'
-      'Note that corresponding host engine build is required even when targeting particular device platforms.',
-      exitCode: 2);
-  }
-  return fs.path.join(engineDartSdkPath, 'bin', 'dart');
-}
-
 class _StdoutHandler {
   _StdoutHandler() {
     reset();
@@ -74,7 +60,7 @@
   if (!sdkRoot.endsWith('/'))
     sdkRoot = '$sdkRoot/';
   final List<String> command = <String>[
-    _dartExecutable(),
+    artifacts.getArtifactPath(Artifact.engineDartBinary),
     frontendServer,
     '--sdk-root',
     sdkRoot,
@@ -154,13 +140,13 @@
   /// Binary file name is returned if compilation was successful, otherwise
   /// null is returned.
   Future<String> recompile(String mainPath, List<String> invalidatedFiles,
-      {String outputPath}) async {
+      {String outputPath, String packagesFilePath}) async {
     stdoutHandler.reset();
 
     // First time recompile is called we actually have to compile the app from
     // scratch ignoring list of invalidated files.
     if (_server == null)
-      return _compile(mainPath, outputPath);
+      return _compile(mainPath, outputPath, packagesFilePath);
 
     final String inputKey = new Uuid().generateV4();
     _server.stdin.writeln('recompile ${mainPath != null ? mainPath + " ": ""}$inputKey');
@@ -170,12 +156,12 @@
     return stdoutHandler.outputFilename.future;
   }
 
-  Future<String> _compile(String scriptFilename, String outputPath) async {
+  Future<String> _compile(String scriptFilename, String outputPath, String packagesFilePath) async {
     final String frontendServer = artifacts.getArtifactPath(
       Artifact.frontendServerSnapshotForEngineDartSdk
     );
     final List<String> args = <String>[
-      _dartExecutable(),
+      artifacts.getArtifactPath(Artifact.engineDartBinary),
       frontendServer,
       '--sdk-root',
       _sdkRoot,
@@ -186,6 +172,9 @@
     if (outputPath != null) {
       args.addAll(<String>['--output-dill', outputPath]);
     }
+    if (packagesFilePath != null) {
+      args.addAll(<String>['--packages', packagesFilePath]);
+    }
     if (_trackWidgetCreation) {
       args.add('--track-widget-creation');
     }
diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart
index 00a79b7..efdf3ed 100644
--- a/packages/flutter_tools/lib/src/devfs.dart
+++ b/packages/flutter_tools/lib/src/devfs.dart
@@ -407,6 +407,7 @@
     bool bundleDirty: false,
     Set<String> fileFilter,
     ResidentCompiler generator,
+    String dillOutputPath,
     bool fullRestart: false,
   }) async {
     // Mark all entries as possibly deleted.
@@ -500,7 +501,8 @@
       }
       final String compiledBinary =
           await generator.recompile(mainPath, invalidatedFiles,
-              outputPath: fs.path.join(getBuildDirectory(), 'app.dill'));
+              outputPath:  dillOutputPath ?? fs.path.join(getBuildDirectory(), 'app.dill'),
+              packagesFilePath : _packagesFilePath);
       if (compiledBinary != null && compiledBinary.isNotEmpty)
         dirtyEntries.putIfAbsent(
           Uri.parse(target + '.dill'),
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index f671cd2..3abc152 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -35,12 +35,14 @@
   DevFS devFS;
   ApplicationPackage package;
   ResidentCompiler generator;
+  String dillOutputPath;
 
   StreamSubscription<String> _loggingSubscription;
 
   FlutterDevice(this.device, {
     @required bool previewDart2,
     @required bool trackWidgetCreation,
+    this.dillOutputPath,
   }) {
     if (previewDart2) {
       generator = new ResidentCompiler(
@@ -386,7 +388,8 @@
         bundleDirty: bundleDirty,
         fileFilter: fileFilter,
         generator: generator,
-        fullRestart: fullRestart
+        fullRestart: fullRestart,
+        dillOutputPath: dillOutputPath,
       );
     } on DevFSException {
       devFSStatus.cancel();
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart
index f3258f9..db0e119 100644
--- a/packages/flutter_tools/lib/src/run_hot.dart
+++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -42,6 +42,7 @@
     this.hostIsIde: false,
     String projectRootPath,
     String packagesFilePath,
+    this.dillOutputPath,
     bool stayResident: true,
     bool ipv6: false,
   }) : super(devices,
@@ -57,6 +58,7 @@
   final String applicationBinary;
   final bool hostIsIde;
   Set<String> _dartDependencies;
+  final String dillOutputPath;
 
   final Map<String, List<int>> benchmarkData = <String, List<int>>{};
   // The initial launch is from a snapshot.
@@ -389,7 +391,10 @@
     }
     // We are now running from source.
     _runningFromSnapshot = false;
-    await _launchFromDevFS(debuggingOptions.buildInfo.previewDart2 ? mainPath + '.dill' : mainPath);
+    final String launchPath = debuggingOptions.buildInfo.previewDart2
+        ? dillOutputPath ?? mainPath + '.dill'
+        : mainPath;
+    await _launchFromDevFS(launchPath);
     restartTimer.stop();
     printTrace('Restart performed in '
         '${getElapsedAsMilliseconds(restartTimer.elapsed)}.');
diff --git a/packages/flutter_tools/lib/src/test/flutter_platform.dart b/packages/flutter_tools/lib/src/test/flutter_platform.dart
index a51e2b6..19b45cd 100644
--- a/packages/flutter_tools/lib/src/test/flutter_platform.dart
+++ b/packages/flutter_tools/lib/src/test/flutter_platform.dart
@@ -59,6 +59,8 @@
   bool machine: false,
   bool startPaused: false,
   bool previewDart2: false,
+  int port: 0,
+  String dillFilePath,
   int observatoryPort,
   InternetAddressType serverType: InternetAddressType.IP_V4,
 }) {
@@ -75,6 +77,8 @@
       explicitObservatoryPort: observatoryPort,
       host: _kHosts[serverType],
       previewDart2: previewDart2,
+      port: port,
+      dillFilePath: dillFilePath,
     ),
   );
 }
@@ -100,6 +104,8 @@
     this.explicitObservatoryPort,
     this.host,
     this.previewDart2,
+    this.port,
+    this.dillFilePath,
   }) : assert(shellPath != null) {
     compilerController.stream.listen((CompilationRequest request) async {
       final bool isEmpty = compilationQueue.isEmpty;
@@ -133,6 +139,8 @@
   final int explicitObservatoryPort;
   final InternetAddress host;
   final bool previewDart2;
+  final int port;
+  final String dillFilePath;
   final StreamController<CompilationRequest> compilerController =
       new StreamController<CompilationRequest>();
   ResidentCompiler compiler =
@@ -193,7 +201,7 @@
       controller.sink.done.whenComplete(() { controllerSinkClosed = true; }); // ignore: unawaited_futures
 
       // Prepare our WebSocket server to talk to the engine subproces.
-      final HttpServer server = await HttpServer.bind(host, 0);
+      final HttpServer server = await HttpServer.bind(host, port);
       finalizers.add(() async {
         printTrace('test $ourTestCount: shutting down test harness socket server');
         await server.close(force: true);
@@ -218,56 +226,71 @@
       );
 
       // Prepare a temporary directory to store the Dart file that will talk to us.
-      final Directory temporaryDirectory = fs.systemTempDirectory.createTempSync('dart_test_listener');
-      finalizers.add(() async {
-        printTrace('test $ourTestCount: deleting temporary directory');
-        temporaryDirectory.deleteSync(recursive: true);
-      });
+      // If a kernel file is given, then use that to launch the test.
+      File listenerFile;
+      if (dillFilePath == null) {
+        final Directory temporaryDirectory = fs.systemTempDirectory
+            .createTempSync('dart_test_listener');
+        finalizers.add(() async {
+          printTrace('test $ourTestCount: deleting temporary directory');
+          temporaryDirectory.deleteSync(recursive: true);
+        });
 
-      // Prepare the Dart file that will talk to us and start the test.
-      final File listenerFile = fs.file('${temporaryDirectory.path}/listener.dart');
-      listenerFile.createSync();
-      listenerFile.writeAsStringSync(_generateTestMain(
-        testUrl: fs.path.toUri(fs.path.absolute(testPath)).toString(),
-        encodedWebsocketUrl: Uri.encodeComponent(_getWebSocketUrl(server)),
-      ));
-
+        // Prepare the Dart file that will talk to us and start the test.
+        listenerFile = fs.file(
+            '${temporaryDirectory.path}/listener.dart');
+        listenerFile.createSync();
+        listenerFile.writeAsStringSync(_generateTestMain(
+          testUrl: fs.path.toUri(fs.path.absolute(testPath)).toString(),
+          encodedWebsocketUrl: Uri.encodeComponent(_getWebSocketUrl(server)),
+        ));
+      }
       // Start the engine subprocess.
       printTrace('test $ourTestCount: starting shell process${previewDart2? " in preview-dart-2 mode":""}');
 
-      String mainDart = listenerFile.path;
+      String mainDart = listenerFile?.path ?? testPath;
       String bundlePath;
 
       if (previewDart2) {
-        final Completer<String> completer = new Completer<String>();
-        compilerController.add(new CompilationRequest(listenerFile.path, completer));
-        mainDart = await completer.future;
+        if (dillFilePath == null) {
+          final Completer<String> completer = new Completer<String>();
+          compilerController.add(
+              new CompilationRequest(listenerFile.path, completer));
+          mainDart = await completer.future;
 
-        if (mainDart == null) {
-          controller.sink.addError(_getErrorMessage('Compilation failed', testPath, shellPath));
-          return null;
+          if (mainDart == null) {
+            controller.sink.addError(
+                _getErrorMessage('Compilation failed', testPath, shellPath));
+            return null;
+          }
+
+          // bundlePath needs to point to a folder with `platform.dill` file.
+          final Directory tempBundleDirectory = fs.systemTempDirectory
+              .createTempSync('flutter_bundle_directory');
+          finalizers.add(() async {
+            printTrace(
+                'test $ourTestCount: deleting temporary bundle directory');
+            tempBundleDirectory.deleteSync(recursive: true);
+          });
+
+          // copy 'vm_platform_strong.dill' into 'platform.dill'
+          final File vmPlatformStrongDill = fs.file(
+            artifacts.getArtifactPath(Artifact.platformKernelDill),
+          );
+          final File platformDill = vmPlatformStrongDill.copySync(
+            tempBundleDirectory
+                .childFile('platform.dill')
+                .path,
+          );
+          if (!platformDill.existsSync()) {
+            printError('unexpected error copying platform kernel file');
+          }
+
+          bundlePath = tempBundleDirectory.path;
+        } else {
+          mainDart = dillFilePath;
+          bundlePath = artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath);
         }
-
-        // bundlePath needs to point to a folder with `platform.dill` file.
-        final Directory tempBundleDirectory = fs.systemTempDirectory
-            .createTempSync('flutter_bundle_directory');
-        finalizers.add(() async {
-          printTrace('test $ourTestCount: deleting temporary bundle directory');
-          tempBundleDirectory.deleteSync(recursive: true);
-        });
-
-        // copy 'vm_platform_strong.dill' into 'platform.dill'
-        final File vmPlatformStrongDill = fs.file(
-          artifacts.getArtifactPath(Artifact.platformKernelDill),
-        );
-        final File platformDill = vmPlatformStrongDill.copySync(
-          tempBundleDirectory.childFile('platform.dill').path,
-        );
-        if (!platformDill.existsSync()) {
-          printError('unexpected error copying platform kernel file');
-        }
-
-        bundlePath = tempBundleDirectory.path;
       }
 
       final Process process = await _startProcess(