Fix remote DDS in proxied devices. (#145346)

A ProxiedDevice has two port forwarder, one to forward remote host port and another to forward remote device port. During an attach workflow, the port was forwarded by the latter. Update ProxiedDDS to make sure that it works in such case.
This commit is contained in:
Lau Ching Jun 2024-03-19 14:36:06 -07:00 committed by GitHub
parent 9cb90d4932
commit a80286270c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 79 additions and 4 deletions

View file

@ -277,11 +277,11 @@ class ProxiedDevice extends Device {
/// [proxiedPortForwarder] forwards a port from the remote host to local host.
ProxiedPortForwarder get proxiedPortForwarder => _proxiedPortForwarder ??= ProxiedPortForwarder(connection, logger: _logger);
DevicePortForwarder? _portForwarder;
ProxiedPortForwarder? _portForwarder;
/// [portForwarder] forwards a port from the remote device to remote host, and
/// then forward the port from remote host to local host.
@override
DevicePortForwarder get portForwarder => _portForwarder ??= ProxiedPortForwarder(connection, deviceId: id, logger: _logger);
ProxiedPortForwarder get portForwarder => _portForwarder ??= ProxiedPortForwarder(connection, deviceId: id, logger: _logger);
ProxiedDartDevelopmentService? _proxiedDds;
@override
@ -290,7 +290,7 @@ class ProxiedDevice extends Device {
return super.dds;
}
return _proxiedDds ??= ProxiedDartDevelopmentService(connection, id,
logger: _logger, proxiedPortForwarder: proxiedPortForwarder);
logger: _logger, proxiedPortForwarder: proxiedPortForwarder, devicePortForwarder: portForwarder);
}
@override
@ -715,9 +715,11 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService {
this.deviceId, {
required Logger logger,
required ProxiedPortForwarder proxiedPortForwarder,
required ProxiedPortForwarder devicePortForwarder,
@visibleForTesting DartDevelopmentService? localDds,
}) : _logger = logger,
_proxiedPortForwarder = proxiedPortForwarder,
_devicePortForwarder = devicePortForwarder,
_localDds = localDds ?? DartDevelopmentService();
final String deviceId;
@ -727,8 +729,14 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService {
/// [DaemonConnection] used to communicate with the daemon.
final DaemonConnection connection;
/// [_proxiedPortForwarder] matches the [proxiedPortForwarder] of a ProxiedDevice.
/// It forwards a port on the remote host to the local host.
final ProxiedPortForwarder _proxiedPortForwarder;
/// [_devicePortForwarder] matches the [portForwarder] of a ProxiedDevice.
/// It forwards a port on the remotely connected device, to the remote host, then to the local host.
final ProxiedPortForwarder _devicePortForwarder;
Uri? _localUri;
@override
@ -752,7 +760,11 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService {
bool cacheStartupProfile = false,
}) async {
// Locate the original VM service port on the remote daemon.
final int? remoteVMServicePort = _proxiedPortForwarder.originalRemotePort(vmServiceUri.port);
// A proxied device has two PortForwarder. Check both to determine which
// one forwarded the VM service port.
final int? remoteVMServicePort =
_proxiedPortForwarder.originalRemotePort(vmServiceUri.port) ??
_devicePortForwarder.originalRemotePort(vmServiceUri.port);
if (remoteVMServicePort == null) {
_logger.printTrace('VM service port is not a forwarded port. Start DDS locally.');

View file

@ -607,11 +607,70 @@ void main() {
final FakeProxiedPortForwarder portForwarder = FakeProxiedPortForwarder();
portForwarder.originalRemotePortReturnValue = 200;
portForwarder.forwardReturnValue = 400;
final FakeProxiedPortForwarder devicePortForwarder = FakeProxiedPortForwarder();
final ProxiedDartDevelopmentService dds = ProxiedDartDevelopmentService(
clientDaemonConnection,
'test_id',
logger: bufferLogger,
proxiedPortForwarder: portForwarder,
devicePortForwarder: devicePortForwarder,
);
final Stream<DaemonMessage> broadcastOutput = serverDaemonConnection.incomingCommands.asBroadcastStream();
final Future<void> startFuture = dds.startDartDevelopmentService(
Uri.parse('http://127.0.0.1:100/fake'),
disableServiceAuthCodes: true,
hostPort: 150,
ipv6: false,
logger: bufferLogger,
);
final DaemonMessage startMessage = await broadcastOutput.first;
expect(startMessage.data['id'], isNotNull);
expect(startMessage.data['method'], 'device.startDartDevelopmentService');
expect(startMessage.data['params'], <String, Object?>{
'deviceId': 'test_id',
'vmServiceUri': 'http://127.0.0.1:200/fake',
'disableServiceAuthCodes': true,
});
serverDaemonConnection.sendResponse(startMessage.data['id']!, 'http://127.0.0.1:300/remote');
await startFuture;
expect(portForwarder.receivedLocalForwardedPort, 100);
expect(portForwarder.forwardedDevicePort, 300);
expect(portForwarder.forwardedHostPort, 150);
expect(portForwarder.forwardedIpv6, false);
expect(dds.uri, Uri.parse('http://127.0.0.1:400/remote'));
expect(
bufferLogger.eventText.trim(),
'{"name":"device.proxied_dds_forwarded","args":{"deviceId":"test_id","remoteUri":"http://127.0.0.1:300/remote","localUri":"http://127.0.0.1:400/remote"}}',
);
unawaited(dds.shutdown());
final DaemonMessage shutdownMessage = await broadcastOutput.first;
expect(shutdownMessage.data['id'], isNotNull);
expect(shutdownMessage.data['method'], 'device.shutdownDartDevelopmentService');
expect(shutdownMessage.data['params'], <String, Object?>{
'deviceId': 'test_id',
});
});
testWithoutContext('forwards start and shutdown to remote if port was forwarded by the device port forwarder', () async {
final FakeProxiedPortForwarder portForwarder = FakeProxiedPortForwarder();
portForwarder.forwardReturnValue = 400;
final FakeProxiedPortForwarder devicePortForwarder = FakeProxiedPortForwarder();
devicePortForwarder.originalRemotePortReturnValue = 200;
final ProxiedDartDevelopmentService dds = ProxiedDartDevelopmentService(
clientDaemonConnection,
'test_id',
logger: bufferLogger,
proxiedPortForwarder: portForwarder,
devicePortForwarder: devicePortForwarder,
);
final Stream<DaemonMessage> broadcastOutput = serverDaemonConnection.incomingCommands.asBroadcastStream();
@ -660,6 +719,7 @@ void main() {
testWithoutContext('starts a local dds if the VM service port is not a forwarded port', () async {
final FakeProxiedPortForwarder portForwarder = FakeProxiedPortForwarder();
final FakeProxiedPortForwarder devicePortForwarder = FakeProxiedPortForwarder();
final FakeDartDevelopmentService localDds = FakeDartDevelopmentService();
localDds.uri = Uri.parse('http://127.0.0.1:450/local');
final ProxiedDartDevelopmentService dds = ProxiedDartDevelopmentService(
@ -667,6 +727,7 @@ void main() {
'test_id',
logger: bufferLogger,
proxiedPortForwarder: portForwarder,
devicePortForwarder: devicePortForwarder,
localDds: localDds,
);
@ -696,6 +757,7 @@ void main() {
testWithoutContext('starts a local dds if the remote VM does not support starting DDS', () async {
final FakeProxiedPortForwarder portForwarder = FakeProxiedPortForwarder();
portForwarder.originalRemotePortReturnValue = 200;
final FakeProxiedPortForwarder devicePortForwarder = FakeProxiedPortForwarder();
final FakeDartDevelopmentService localDds = FakeDartDevelopmentService();
localDds.uri = Uri.parse('http://127.0.0.1:450/local');
final ProxiedDartDevelopmentService dds = ProxiedDartDevelopmentService(
@ -703,6 +765,7 @@ void main() {
'test_id',
logger: bufferLogger,
proxiedPortForwarder: portForwarder,
devicePortForwarder: devicePortForwarder,
localDds: localDds,
);