Tools daemon handlers for discovering apps and forwarding device ports (#4324)
This commit is contained in:
parent
8ec26f02da
commit
00c7734c8b
@ -513,6 +513,28 @@ class AndroidDevice extends Device {
|
|||||||
|
|
||||||
return new Future<bool>.value(true);
|
return new Future<bool>.value(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<DiscoveredApp>> discoverApps() {
|
||||||
|
RegExp discoverExp = new RegExp(r'DISCOVER: (.*)');
|
||||||
|
List<DiscoveredApp> result = <DiscoveredApp>[];
|
||||||
|
StreamSubscription<String> logs = logReader.logLines.listen((String line) {
|
||||||
|
Match match = discoverExp.firstMatch(line);
|
||||||
|
if (match != null) {
|
||||||
|
Map<String, dynamic> app = JSON.decode(match.group(1));
|
||||||
|
result.add(new DiscoveredApp(app['id'], app['observatoryPort']));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
runCheckedSync(adbCommandForDevice(<String>[
|
||||||
|
'shell', 'am', 'broadcast', '-a', 'io.flutter.view.DISCOVER'
|
||||||
|
]));
|
||||||
|
|
||||||
|
return new Future<List<DiscoveredApp>>.delayed(new Duration(seconds: 1), () {
|
||||||
|
logs.cancel();
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 015d172c98400a03 device usb:340787200X product:nakasi model:Nexus_7 device:grouper
|
// 015d172c98400a03 device usb:340787200X product:nakasi model:Nexus_7 device:grouper
|
||||||
|
@ -237,6 +237,23 @@ class DaemonDomain extends Domain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the device matching the deviceId field in the args.
|
||||||
|
Future<Device> _getDevice(Daemon daemon, Map<String, dynamic> args) async {
|
||||||
|
if (args == null || args['deviceId'] is! String)
|
||||||
|
throw 'deviceId is required';
|
||||||
|
|
||||||
|
List<Device> devices = await daemon.deviceDomain.getDevices();
|
||||||
|
Device device = devices.firstWhere(
|
||||||
|
(Device device) => device.id == args['deviceId'],
|
||||||
|
orElse: () => null
|
||||||
|
);
|
||||||
|
|
||||||
|
if (device == null)
|
||||||
|
throw "device '${args['deviceId']}' not found";
|
||||||
|
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
/// This domain responds to methods like [start] and [stop].
|
/// This domain responds to methods like [start] and [stop].
|
||||||
///
|
///
|
||||||
/// It'll be extended to fire events for when applications start, stop, and
|
/// It'll be extended to fire events for when applications start, stop, and
|
||||||
@ -245,14 +262,11 @@ class AppDomain extends Domain {
|
|||||||
AppDomain(Daemon daemon) : super(daemon, 'app') {
|
AppDomain(Daemon daemon) : super(daemon, 'app') {
|
||||||
registerHandler('start', start);
|
registerHandler('start', start);
|
||||||
registerHandler('stop', stop);
|
registerHandler('stop', stop);
|
||||||
|
registerHandler('discover', discover);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> start(Map<String, dynamic> args) async {
|
Future<dynamic> start(Map<String, dynamic> args) async {
|
||||||
if (args == null || args['deviceId'] is! String)
|
Device device = await _getDevice(daemon, args);
|
||||||
throw "deviceId is required";
|
|
||||||
Device device = await _getDevice(args['deviceId']);
|
|
||||||
if (device == null)
|
|
||||||
throw "device '${args['deviceId']}' not found";
|
|
||||||
|
|
||||||
if (args['projectDirectory'] is! String)
|
if (args['projectDirectory'] is! String)
|
||||||
throw "projectDirectory is required";
|
throw "projectDirectory is required";
|
||||||
@ -282,12 +296,8 @@ class AppDomain extends Domain {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> stop(dynamic args) async {
|
Future<bool> stop(Map<String, dynamic> args) async {
|
||||||
if (args == null || args['deviceId'] is! String)
|
Device device = await _getDevice(daemon, args);
|
||||||
throw "deviceId is required";
|
|
||||||
Device device = await _getDevice(args['deviceId']);
|
|
||||||
if (device == null)
|
|
||||||
throw "device '${args['deviceId']}' not found";
|
|
||||||
|
|
||||||
if (args['projectDirectory'] is! String)
|
if (args['projectDirectory'] is! String)
|
||||||
throw "projectDirectory is required";
|
throw "projectDirectory is required";
|
||||||
@ -306,9 +316,12 @@ class AppDomain extends Domain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Device> _getDevice(String deviceId) async {
|
Future<List<Map<String, dynamic>>> discover(Map<String, dynamic> args) async {
|
||||||
List<Device> devices = await daemon.deviceDomain.getDevices();
|
Device device = await _getDevice(daemon, args);
|
||||||
return devices.firstWhere((Device device) => device.id == deviceId, orElse: () => null);
|
List<DiscoveredApp> apps = await device.discoverApps();
|
||||||
|
return apps.map((DiscoveredApp app) =>
|
||||||
|
<String, dynamic>{'id': app.id, 'observatoryDevicePort': app.observatoryPort}
|
||||||
|
).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,6 +334,8 @@ class DeviceDomain extends Domain {
|
|||||||
registerHandler('getDevices', getDevices);
|
registerHandler('getDevices', getDevices);
|
||||||
registerHandler('enable', enable);
|
registerHandler('enable', enable);
|
||||||
registerHandler('disable', disable);
|
registerHandler('disable', disable);
|
||||||
|
registerHandler('forward', forward);
|
||||||
|
registerHandler('unforward', unforward);
|
||||||
|
|
||||||
PollingDeviceDiscovery deviceDiscovery = new AndroidDevices();
|
PollingDeviceDiscovery deviceDiscovery = new AndroidDevices();
|
||||||
if (deviceDiscovery.supportsPlatform)
|
if (deviceDiscovery.supportsPlatform)
|
||||||
@ -369,6 +384,36 @@ class DeviceDomain extends Domain {
|
|||||||
return new Future<Null>.value();
|
return new Future<Null>.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Forward a host port to a device port.
|
||||||
|
Future<Map<String, dynamic>> forward(Map<String, dynamic> args) async {
|
||||||
|
Device device = await _getDevice(daemon, args);
|
||||||
|
|
||||||
|
if (args['devicePort'] is! int)
|
||||||
|
throw 'devicePort is required';
|
||||||
|
int devicePort = args['devicePort'];
|
||||||
|
|
||||||
|
int hostPort = args['hostPort'];
|
||||||
|
|
||||||
|
hostPort = await device.portForwarder.forward(devicePort, hostPort: hostPort);
|
||||||
|
|
||||||
|
return <String, dynamic>{'hostPort': hostPort};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes a forwarded port.
|
||||||
|
Future<Null> unforward(Map<String, dynamic> args) async {
|
||||||
|
Device device = await _getDevice(daemon, args);
|
||||||
|
|
||||||
|
if (args['devicePort'] is! int)
|
||||||
|
throw 'devicePort is required';
|
||||||
|
int devicePort = args['devicePort'];
|
||||||
|
|
||||||
|
if (args['hostPort'] is! int)
|
||||||
|
throw 'hostPort is required';
|
||||||
|
int hostPort = args['hostPort'];
|
||||||
|
|
||||||
|
device.portForwarder.unforward(new ForwardedPort(hostPort, devicePort));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
for (PollingDeviceDiscovery discoverer in _discoverers) {
|
for (PollingDeviceDiscovery discoverer in _discoverers) {
|
||||||
|
@ -205,6 +205,10 @@ abstract class Device {
|
|||||||
|
|
||||||
Future<bool> takeScreenshot(File outputFile) => new Future<bool>.error('unimplemented');
|
Future<bool> takeScreenshot(File outputFile) => new Future<bool>.error('unimplemented');
|
||||||
|
|
||||||
|
/// Find the apps that are currently running on this device.
|
||||||
|
Future<List<DiscoveredApp>> discoverApps() =>
|
||||||
|
new Future<List<DiscoveredApp>>.value(<DiscoveredApp>[]);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => id.hashCode;
|
int get hashCode => id.hashCode;
|
||||||
|
|
||||||
@ -333,3 +337,10 @@ abstract class DeviceLogReader {
|
|||||||
@override
|
@override
|
||||||
String toString() => name;
|
String toString() => name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Describes an app running on the device.
|
||||||
|
class DiscoveredApp {
|
||||||
|
DiscoveredApp(this.id, this.observatoryPort);
|
||||||
|
final String id;
|
||||||
|
final int observatoryPort;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user