• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 The Chromium 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
5/// Convenience methods for Flutter application driving on Fuchsia. Can
6/// be run on either a host machine (making a remote connection to a Fuchsia
7/// device), or on the target Fuchsia machine.
8import 'dart:async';
9import 'dart:core';
10import 'dart:io';
11
12import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart';
13
14import 'error.dart';
15
16class _DummyPortForwarder implements PortForwarder {
17  _DummyPortForwarder(this._port, this._remotePort);
18
19  final int _port;
20  final int _remotePort;
21
22  @override
23  int get port => _port;
24
25  @override
26  int get remotePort => _remotePort;
27
28  @override
29  Future<void> stop() async { }
30}
31
32class _DummySshCommandRunner implements SshCommandRunner {
33  _DummySshCommandRunner();
34
35  final Logger _log = Logger('_DummySshCommandRunner');
36
37  @override
38  String get sshConfigPath => null;
39
40  @override
41  String get address => InternetAddress.loopbackIPv4.address;
42
43  @override
44  String get interface => null;
45
46  @override
47  Future<List<String>> run(String command) async {
48    try {
49      final List<String> splitCommand = command.split(' ');
50      final String exe = splitCommand[0];
51      final List<String> args = splitCommand.skip(1).toList();
52      // This needs to remain async in the event that this command attempts to
53      // access something (like the hub) that requires interaction with this
54      // process's event loop. A specific example is attempting to run `find`, a
55      // synchronous command, on this own process's `out` directory. As `find`
56      // will wait indefinitely for the `out` directory to be serviced, causing
57      // a deadlock.
58      final ProcessResult r = await Process.run(exe, args);
59      return r.stdout.split('\n');
60    } on ProcessException catch (e) {
61      _log.warning("Error running '$command': $e");
62    }
63    return <String>[];
64  }
65}
66
67Future<PortForwarder> _dummyPortForwardingFunction(
68  String address,
69  int remotePort, [
70  String interface = '',
71  String configFile,
72]) async {
73  return _DummyPortForwarder(remotePort, remotePort);
74}
75
76/// Utility class for creating connections to the Fuchsia Device.
77///
78/// If executed on a host (non-Fuchsia device), behaves the same as running
79/// [FuchsiaRemoteConnection.connect] whereby the `FUCHSIA_REMOTE_URL` and
80/// `FUCHSIA_SSH_CONFIG` variables must be set. If run on a Fuchsia device, will
81/// connect locally without need for environment variables.
82class FuchsiaCompat {
83  static void _init() {
84    fuchsiaPortForwardingFunction = _dummyPortForwardingFunction;
85  }
86
87  /// Restores state to normal if running on a Fuchsia device.
88  ///
89  /// Noop if running on the host machine.
90  static void cleanup() {
91    restoreFuchsiaPortForwardingFunction();
92  }
93
94  /// Creates a connection to the Fuchsia device's Dart VM's.
95  ///
96  /// See [FuchsiaRemoteConnection.connect] for more details.
97  /// [FuchsiaCompat.cleanup] must be called when the connection is no longer in
98  /// use. It is the caller's responsibility to call
99  /// [FuchsiaRemoteConnection.stop].
100  static Future<FuchsiaRemoteConnection> connect() async {
101    FuchsiaCompat._init();
102    return FuchsiaRemoteConnection.connectWithSshCommandRunner(
103        _DummySshCommandRunner());
104  }
105}
106