Commit d07ca929 authored by Ian Fischer's avatar Ian Fischer

Basic sky_tools list command, Android implementation, and test.

parent b8085cd0
...@@ -13,6 +13,7 @@ import 'package:sky_tools/src/build.dart'; ...@@ -13,6 +13,7 @@ import 'package:sky_tools/src/build.dart';
import 'package:sky_tools/src/cache.dart'; import 'package:sky_tools/src/cache.dart';
import 'package:sky_tools/src/init.dart'; import 'package:sky_tools/src/init.dart';
import 'package:sky_tools/src/install.dart'; import 'package:sky_tools/src/install.dart';
import 'package:sky_tools/src/list.dart';
import 'package:sky_tools/src/listen.dart'; import 'package:sky_tools/src/listen.dart';
import 'package:sky_tools/src/logs.dart'; import 'package:sky_tools/src/logs.dart';
import 'package:sky_tools/src/run_mojo.dart'; import 'package:sky_tools/src/run_mojo.dart';
...@@ -151,6 +152,7 @@ void main(List<String> args) { ...@@ -151,6 +152,7 @@ void main(List<String> args) {
..addCommand(new CacheCommand()) ..addCommand(new CacheCommand())
..addCommand(new InitCommand()) ..addCommand(new InitCommand())
..addCommand(new InstallCommand()) ..addCommand(new InstallCommand())
..addCommand(new ListCommand())
..addCommand(new ListenCommand()) ..addCommand(new ListenCommand())
..addCommand(new LogsCommand()) ..addCommand(new LogsCommand())
..addCommand(new RunMojoCommand()) ..addCommand(new RunMojoCommand())
......
...@@ -60,13 +60,60 @@ class AndroidDevice extends _Device { ...@@ -60,13 +60,60 @@ class AndroidDevice extends _Device {
static const String className = 'AndroidDevice'; static const String className = 'AndroidDevice';
static final String defaultDeviceID = 'default'; static final String defaultDeviceID = 'default';
String productID;
String modelID;
String deviceCodeName;
String _adbPath; String _adbPath;
String get adbPath => _adbPath; String get adbPath => _adbPath;
bool _hasAdb = false; bool _hasAdb = false;
bool _hasValidAndroid = false; bool _hasValidAndroid = false;
factory AndroidDevice([String id = null]) { factory AndroidDevice(
return new _Device(className, id); {String id: null,
String productID: null,
String modelID: null,
String deviceCodeName: null}) {
AndroidDevice device = new _Device(className, id);
device.productID = productID;
device.modelID = modelID;
device.deviceCodeName = deviceCodeName;
return device;
}
/// mockAndroid argument is only to facilitate testing with mocks, so that
/// we don't have to rely on the test setup having adb available to it.
static List<AndroidDevice> getAttachedDevices([AndroidDevice mockAndroid]) {
List<AndroidDevice> devices = [];
String adbPath = _getAdbPath();
if (mockAndroid != null) {
adbPath = mockAndroid.adbPath;
}
List<String> output =
runSync([adbPath, 'devices', '-l']).trim().split('\n');
RegExp deviceInfo = new RegExp(
r'^(\S+)\s+device\s+\S+\s+product:(\S+)\s+model:(\S+)\s+device:(\S+)$');
// Skip first line, which is always 'List of devices attached'.
for (String line in output.skip(1)) {
Match match = deviceInfo.firstMatch(line);
if (match != null) {
String deviceID = match[1];
String productID = match[2];
String modelID = match[3];
String deviceCodeName = match[4];
devices.add(new AndroidDevice(
id: deviceID,
productID: productID,
modelID: modelID,
deviceCodeName: deviceCodeName));
} else {
_logging.warning('Unexpected failure parsing device information '
'from adb output:\n$line\n'
'Please report a bug at http://flutter.io/');
}
}
return devices;
} }
AndroidDevice._(id) : super._(id) { AndroidDevice._(id) : super._(id) {
...@@ -83,7 +130,7 @@ class AndroidDevice extends _Device { ...@@ -83,7 +130,7 @@ class AndroidDevice extends _Device {
} }
} }
String _getAdbPath() { static String _getAdbPath() {
if (Platform.environment.containsKey('ANDROID_HOME')) { if (Platform.environment.containsKey('ANDROID_HOME')) {
String androidHomeDir = Platform.environment['ANDROID_HOME']; String androidHomeDir = Platform.environment['ANDROID_HOME'];
String adbPath1 = String adbPath1 =
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library sky_tools.list;
import 'dart:async';
import 'package:args/command_runner.dart';
import 'package:logging/logging.dart';
import 'package:sky_tools/src/device.dart';
final Logger _logging = new Logger('sky_tools.list');
class ListCommand extends Command {
final name = 'list';
final description = 'List all connected devices.';
AndroidDevice android;
ListCommand([this.android]) {
argParser.addFlag('details',
abbr: 'd',
negatable: false,
help: 'Log additional details about attached devices.');
}
@override
Future<int> run() async {
bool details = argResults['details'];
if (details) {
print('Android Devices:');
}
for (AndroidDevice device in AndroidDevice.getAttachedDevices(android)) {
if (details) {
print('${device.id}\t'
'${device.modelID}\t'
'${device.productID}\t'
'${device.deviceCodeName}');
} else {
print(device.id);
}
}
return 0;
}
}
...@@ -63,7 +63,7 @@ class TraceCommand extends Command { ...@@ -63,7 +63,7 @@ class TraceCommand extends Command {
if (tracePath == null) { if (tracePath == null) {
_logging.warning('No trace file saved.'); _logging.warning('No trace file saved.');
} else { } else {
_logging.warning('Trace file saved to $tracePath'); print('Trace file saved to $tracePath');
} }
} }
} }
...@@ -18,14 +18,14 @@ defineTests() { ...@@ -18,14 +18,14 @@ defineTests() {
test('stores the requested id', () { test('stores the requested id', () {
String deviceID = '1234'; String deviceID = '1234';
AndroidDevice android = new AndroidDevice(deviceID); AndroidDevice android = new AndroidDevice(id: deviceID);
expect(android.id, equals(deviceID)); expect(android.id, equals(deviceID));
}); });
test('correctly creates only one of each requested device id', () { test('correctly creates only one of each requested device id', () {
String deviceID = '1234'; String deviceID = '1234';
AndroidDevice a1 = new AndroidDevice(deviceID); AndroidDevice a1 = new AndroidDevice(id: deviceID);
AndroidDevice a2 = new AndroidDevice(deviceID); AndroidDevice a2 = new AndroidDevice(id: deviceID);
expect(a1, equals(a2)); expect(a1, equals(a2));
}); });
}); });
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library list_test;
import 'package:args/command_runner.dart';
import 'package:mockito/mockito.dart';
import 'package:sky_tools/src/list.dart';
import 'package:test/test.dart';
import 'src/common.dart';
main() => defineTests();
defineTests() {
group('list', () {
test('returns 0 when called', () {
MockAndroidDevice android = new MockAndroidDevice();
// Avoid relying on adb being installed on the test system.
// Instead, cause the test to run the echo command.
when(android.adbPath).thenReturn('echo');
ListCommand command = new ListCommand(android);
CommandRunner runner = new CommandRunner('test_flutter', '')
..addCommand(command);
runner.run(['list']).then((int code) => expect(code, equals(0)));
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment