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

5
import '../base/common.dart';
6
import '../base/utils.dart';
7
import '../convert.dart';
8
import '../device.dart';
9
import '../globals.dart' as globals;
10
import '../runner/flutter_command.dart';
11

12
class DevicesCommand extends FlutterCommand {
13

14
  DevicesCommand() {
15 16 17 18
    argParser.addFlag('machine',
      negatable: false,
      help: 'Output device information in machine readable structured JSON format',
    );
19 20 21 22
    argParser.addOption(
      'timeout',
      abbr: 't',
      defaultsTo: null,
23
      help: '(deprecated) Use --device-timeout instead',
24
    );
25
    usesDeviceTimeoutOption();
26 27
  }

28
  @override
29
  final String name = 'devices';
30 31

  @override
32
  final String description = 'List all connected devices.';
33

34 35 36
  @override
  Duration get deviceDiscoveryTimeout {
    if (argResults['timeout'] != null) {
37 38 39 40
      final int timeoutSeconds = int.tryParse(stringArg('timeout'));
      if (timeoutSeconds == null) {
        throwToolExit( 'Could not parse -t/--timeout argument. It must be an integer.');
      }
41 42 43 44 45 46 47 48 49
      return Duration(seconds: timeoutSeconds);
    }
    return super.deviceDiscoveryTimeout;
  }

  @override
  Future<void> validateCommand() {
    if (argResults['timeout'] != null) {
      globals.printError('--timeout has been deprecated, use --${FlutterOptions.kDeviceTimeout} instead');
50
    }
51
    return super.validateCommand();
52 53
  }

54
  @override
55
  Future<FlutterCommandResult> runCommand() async {
56
    if (!globals.doctor.canListAnything) {
57 58
      throwToolExit(
        "Unable to locate a development device; please run 'flutter doctor' for "
59
        'information about installing additional components.',
60
        exitCode: 1);
61 62
    }

63
    final List<Device> devices = await globals.deviceManager.refreshAllConnectedDevices(timeout: deviceDiscoveryTimeout);
64

65 66
    if (boolArg('machine')) {
      await printDevicesAsJson(devices);
67 68 69 70 71 72 73 74
    } else {
      if (devices.isEmpty) {
        final StringBuffer status = StringBuffer('No devices detected.');
        status.writeln();
        status.writeln();
        status.writeln('Run "flutter emulators" to list and start any available device emulators.');
        status.writeln();
        status.write('If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. ');
75 76
        if (deviceDiscoveryTimeout == null) {
          status.write('You may also try increasing the time to wait for connected devices with the --${FlutterOptions.kDeviceTimeout} flag. ');
77
        }
78 79 80 81 82 83
        status.write('Visit https://flutter.dev/setup/ for troubleshooting tips.');

        globals.printStatus(status.toString());
      } else {
        globals.printStatus('${devices.length} connected ${pluralize('device', devices.length)}:\n');
        await Device.printDevices(devices);
84
      }
85
      await _printDiagnostics();
86
    }
87
    return FlutterCommandResult.success();
88
  }
89

90
  Future<void> _printDiagnostics() async {
91
    final List<String> diagnostics = await globals.deviceManager.getDeviceDiagnostics();
92 93 94 95 96 97 98 99
    if (diagnostics.isNotEmpty) {
      globals.printStatus('');
      for (final String diagnostic in diagnostics) {
        globals.printStatus('• $diagnostic', hangingIndent: 2);
      }
    }
  }

100 101 102 103 104 105 106
  Future<void> printDevicesAsJson(List<Device> devices) async {
    globals.printStatus(
      const JsonEncoder.withIndent('  ').convert(
        await Future.wait(devices.map((Device d) => d.toJson()))
      )
    );
  }
107
}