1// Copyright 2013 The Flutter Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5library observatory_sky_shell_launcher; 6 7import 'dart:async'; 8import 'dart:convert'; 9import 'dart:io'; 10 11class ShellProcess { 12 final Completer<Uri> _observatoryUriCompleter = Completer<Uri>(); 13 final Process _process; 14 15 ShellProcess(this._process) : assert(_process != null) { 16 // Scan stdout and scrape the Observatory Uri. 17 _process.stdout.transform(utf8.decoder) 18 .transform(const LineSplitter()).listen((String line) { 19 const String observatoryUriPrefix = 'Observatory listening on '; 20 if (line.startsWith(observatoryUriPrefix)) { 21 print(line); 22 final Uri uri = Uri.parse(line.substring(observatoryUriPrefix.length)); 23 _observatoryUriCompleter.complete(uri); 24 } 25 }); 26 } 27 28 Future<bool> kill() async { 29 if (_process == null) { 30 return false; 31 } 32 return _process.kill(); 33 } 34 35 Future<Uri> waitForObservatory() async { 36 return _observatoryUriCompleter.future; 37 } 38} 39 40class ShellLauncher { 41 final List<String> args = <String>[ 42 '--observatory-port=0', 43 '--non-interactive', 44 '--run-forever', 45 '--disable-service-auth-codes', 46 ]; 47 final String shellExecutablePath; 48 final String mainDartPath; 49 final bool startPaused; 50 51 ShellLauncher(this.shellExecutablePath, 52 this.mainDartPath, 53 this.startPaused, 54 List<String> extraArgs) { 55 if (extraArgs is List) { 56 args.addAll(extraArgs); 57 } 58 args.add(mainDartPath); 59 } 60 61 Future<ShellProcess> launch() async { 62 try { 63 final List<String> shellArguments = <String>[]; 64 if (startPaused) { 65 shellArguments.add('--start-paused'); 66 } 67 shellArguments.addAll(args); 68 print('Launching $shellExecutablePath $shellArguments'); 69 final Process process = await Process.start(shellExecutablePath, shellArguments); 70 return ShellProcess(process); 71 } catch (e) { 72 print('Error launching shell: $e'); 73 } 74 return null; 75 } 76} 77