android_console.dart 2.32 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:async/async.dart';
6

7 8 9 10
import '../base/io.dart';
import '../convert.dart';

/// Default factory that creates a real Android console connection.
11 12 13 14
///
/// The default implementation will create real connections to a device.
/// Override this in tests with an implementation that returns mock responses.
Future<Socket> kAndroidConsoleSocketFactory(String host, int port) => Socket.connect(host, port);
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

/// Currently active implementation of the AndroidConsoleFactory.
///
/// The default implementation will create real connections to a device.
/// Override this in tests with an implementation that returns mock responses.
typedef AndroidConsoleSocketFactory = Future<Socket> Function(String host, int port);

/// Creates a console connection to an Android emulator that can be used to run
/// commands such as "avd name" which are not available to ADB.
///
/// See documentation at
/// https://developer.android.com/studio/run/emulator-console
class AndroidConsole {
  AndroidConsole(this._socket);

30 31
  Socket? _socket;
  StreamQueue<String>? _queue;
32 33 34 35 36

  Future<void> connect() async {
    assert(_socket != null);
    assert(_queue == null);

37
    _queue = StreamQueue<String>(_socket!.asyncMap(ascii.decode));
38 39 40 41 42

    // Discard any initial connection text.
    await _readResponse();
  }

43
  Future<String?> getAvdName() async {
44 45 46
    if (_queue == null) {
      return null;
    }
47 48 49 50 51
    _write('avd name\n');
    return _readResponse();
  }

  void destroy() {
52 53 54
    _socket?.destroy();
    _socket = null;
    _queue = null;
55 56
  }

57
  Future<String?> _readResponse() async {
58 59 60
    if (_queue == null) {
      return null;
    }
61 62
    final StringBuffer output = StringBuffer();
    while (true) {
63
      if (!await _queue!.hasNext) {
64 65 66
        destroy();
        return null;
      }
67
      final String text = await _queue!.next;
68
      final String trimmedText = text.trim();
69
      if (trimmedText == 'OK') {
70
        break;
71
      }
72 73 74 75 76 77 78 79 80 81
      if (trimmedText.endsWith('\nOK')) {
        output.write(trimmedText.substring(0, trimmedText.length - 3));
        break;
      }
      output.write(text);
    }
    return output.toString().trim();
  }

  void _write(String text) {
82
    _socket?.add(ascii.encode(text));
83 84
  }
}