Commit 5ac6f931 authored by Devon Carew's avatar Devon Carew

Merge pull request #1305 from devoncarew/device_notification

Device notification
parents 5ad67975 8bb8e1d9
...@@ -21,8 +21,14 @@ abstract class Device { ...@@ -21,8 +21,14 @@ abstract class Device {
return _deviceCache.putIfAbsent(id, () => constructor(id)); return _deviceCache.putIfAbsent(id, () => constructor(id));
} }
static void removeFromCache(String id) {
_deviceCache.remove(id);
}
Device._(this.id); Device._(this.id);
String get name;
/// Install an app package on the current device /// Install an app package on the current device
bool installApp(ApplicationPackage app); bool installApp(ApplicationPackage app);
...@@ -532,20 +538,25 @@ class AndroidDevice extends Device { ...@@ -532,20 +538,25 @@ class AndroidDevice extends Device {
String modelID; String modelID;
String deviceCodeName; String deviceCodeName;
bool _connected;
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( factory AndroidDevice({
{String id: null, String id: null,
String productID: null, String productID: null,
String modelID: null, String modelID: null,
String deviceCodeName: null}) { String deviceCodeName: null,
bool connected
}) {
AndroidDevice device = Device._unique(id ?? defaultDeviceID, (String id) => new AndroidDevice._(id)); AndroidDevice device = Device._unique(id ?? defaultDeviceID, (String id) => new AndroidDevice._(id));
device.productID = productID; device.productID = productID;
device.modelID = modelID; device.modelID = modelID;
device.deviceCodeName = deviceCodeName; device.deviceCodeName = deviceCodeName;
if (connected != null)
device._connected = connected;
return device; return device;
} }
...@@ -553,7 +564,7 @@ class AndroidDevice extends Device { ...@@ -553,7 +564,7 @@ class AndroidDevice extends Device {
/// we don't have to rely on the test setup having adb available to it. /// we don't have to rely on the test setup having adb available to it.
static List<AndroidDevice> getAttachedDevices([AndroidDevice mockAndroid]) { static List<AndroidDevice> getAttachedDevices([AndroidDevice mockAndroid]) {
List<AndroidDevice> devices = []; List<AndroidDevice> devices = [];
String adbPath = (mockAndroid != null) ? mockAndroid.adbPath : _getAdbPath(); String adbPath = (mockAndroid != null) ? mockAndroid.adbPath : getAdbPath();
try { try {
runCheckedSync([adbPath, 'version']); runCheckedSync([adbPath, 'version']);
...@@ -623,7 +634,7 @@ class AndroidDevice extends Device { ...@@ -623,7 +634,7 @@ class AndroidDevice extends Device {
} }
AndroidDevice._(id) : super._(id) { AndroidDevice._(id) : super._(id) {
_adbPath = _getAdbPath(); _adbPath = getAdbPath();
_hasAdb = _checkForAdb(); _hasAdb = _checkForAdb();
// Checking for [minApiName] only needs to be done if we are starting an // Checking for [minApiName] only needs to be done if we are starting an
...@@ -655,7 +666,7 @@ class AndroidDevice extends Device { ...@@ -655,7 +666,7 @@ class AndroidDevice extends Device {
} }
} }
static 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 = path.join(androidHomeDir, 'sdk', 'platform-tools', 'adb'); String adbPath1 = path.join(androidHomeDir, 'sdk', 'platform-tools', 'adb');
...@@ -782,6 +793,8 @@ class AndroidDevice extends Device { ...@@ -782,6 +793,8 @@ class AndroidDevice extends Device {
return CryptoUtils.bytesToHex(sha1.close()); return CryptoUtils.bytesToHex(sha1.close());
} }
String get name => modelID;
@override @override
bool isAppInstalled(ApplicationPackage app) { bool isAppInstalled(ApplicationPackage app) {
if (!isConnected()) { if (!isConnected()) {
...@@ -992,8 +1005,11 @@ class AndroidDevice extends Device { ...@@ -992,8 +1005,11 @@ class AndroidDevice extends Device {
return null; return null;
} }
@override bool isConnected() => _connected != null ? _connected : _hasValidAndroid;
bool isConnected() => _hasValidAndroid;
void setConnected(bool value) {
_connected = value;
}
} }
class DeviceStore { class DeviceStore {
......
...@@ -26,9 +26,9 @@ defineTests() { ...@@ -26,9 +26,9 @@ defineTests() {
StreamController<Map> responses = new StreamController(); StreamController<Map> responses = new StreamController();
daemon = new Daemon( daemon = new Daemon(
commands.stream, commands.stream,
(Map result) => responses.add(result) (Map<String, dynamic> result) => responses.add(result)
); );
commands.add({'id': 0, 'event': 'daemon.version'}); commands.add({'id': 0, 'method': 'daemon.version'});
Map response = await responses.stream.first; Map response = await responses.stream.first;
expect(response['id'], 0); expect(response['id'], 0);
expect(response['result'], isNotEmpty); expect(response['result'], isNotEmpty);
...@@ -40,9 +40,9 @@ defineTests() { ...@@ -40,9 +40,9 @@ defineTests() {
StreamController<Map> responses = new StreamController(); StreamController<Map> responses = new StreamController();
daemon = new Daemon( daemon = new Daemon(
commands.stream, commands.stream,
(Map result) => responses.add(result) (Map<String, dynamic> result) => responses.add(result)
); );
commands.add({'id': 0, 'event': 'daemon.shutdown'}); commands.add({'id': 0, 'method': 'daemon.shutdown'});
return daemon.onExit.then((int code) { return daemon.onExit.then((int code) {
expect(code, 0); expect(code, 0);
}); });
...@@ -56,7 +56,7 @@ defineTests() { ...@@ -56,7 +56,7 @@ defineTests() {
StreamController<Map> responses = new StreamController(); StreamController<Map> responses = new StreamController();
daemon = new Daemon( daemon = new Daemon(
commands.stream, commands.stream,
(Map result) => responses.add(result), (Map<String, dynamic> result) => responses.add(result),
daemonCommand: command daemonCommand: command
); );
...@@ -71,10 +71,23 @@ defineTests() { ...@@ -71,10 +71,23 @@ defineTests() {
when(mockDevices.iOSSimulator.isConnected()).thenReturn(false); when(mockDevices.iOSSimulator.isConnected()).thenReturn(false);
when(mockDevices.iOSSimulator.stopApp(any)).thenReturn(false); when(mockDevices.iOSSimulator.stopApp(any)).thenReturn(false);
commands.add({'id': 0, 'event': 'app.stopAll'}); commands.add({'id': 0, 'method': 'app.stopAll'});
Map response = await responses.stream.first; Map response = await responses.stream.first;
expect(response['id'], 0); expect(response['id'], 0);
expect(response['result'], true); expect(response['result'], true);
}); });
test('device.getDevices', () async {
StreamController<Map> commands = new StreamController();
StreamController<Map> responses = new StreamController();
daemon = new Daemon(
commands.stream,
(Map<String, dynamic> result) => responses.add(result)
);
commands.add({'id': 0, 'method': 'device.getDevices'});
Map response = await responses.stream.first;
expect(response['id'], 0);
expect(response['result'], isList);
});
}); });
} }
...@@ -7,8 +7,15 @@ import 'dart:io'; ...@@ -7,8 +7,15 @@ import 'dart:io';
Process daemon; Process daemon;
// To use, start from the console and enter:
// version: print version
// shutdown: terminate the server
// start: start an app
// stopAll: stop any running app
// devices: list devices
main() async { main() async {
daemon = await Process.start('dart', ['bin/flutter_tools.dart', 'daemon']); daemon = await Process.start('flutter', ['daemon']);
print('daemon process started, pid: ${daemon.pid}'); print('daemon process started, pid: ${daemon.pid}');
daemon.stdout daemon.stdout
...@@ -20,13 +27,15 @@ main() async { ...@@ -20,13 +27,15 @@ main() async {
stdout.write('> '); stdout.write('> ');
stdin.transform(UTF8.decoder).transform(const LineSplitter()).listen((String line) { stdin.transform(UTF8.decoder).transform(const LineSplitter()).listen((String line) {
if (line == 'version' || line == 'v') { if (line == 'version' || line == 'v') {
_send({'event': 'daemon.version'}); _send({'method': 'daemon.version'});
} else if (line == 'shutdown' || line == 'q') { } else if (line == 'shutdown' || line == 'q') {
_send({'event': 'daemon.shutdown'}); _send({'method': 'daemon.shutdown'});
} else if (line == 'start') { } else if (line == 'start') {
_send({'event': 'app.start'}); _send({'method': 'app.start'});
} else if (line == 'stopAll') { } else if (line == 'stopAll') {
_send({'event': 'app.stopAll'}); _send({'method': 'app.stopAll'});
} else if (line == 'devices') {
_send({'method': 'device.getDevices'});
} else { } else {
print('command not understood: ${line}'); print('command not understood: ${line}');
} }
......
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