Allow --ipv6 flag for flutter attach on iOS devices (#123822)

Allow --ipv6 flag for flutter attach on iOS devices
This commit is contained in:
Victoria Ashworth 2023-04-04 17:33:28 -05:00 committed by GitHub
parent dbc18bbdb8
commit 842873c2fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 13 deletions

View file

@ -219,11 +219,19 @@ known, it can be explicitly provided to attach via the command-line, e.g.
MacOSDesignedForIPadDevices.allowDiscovery = true;
await super.validateCommand();
if (await findTargetDevice() == null) {
final Device? targetDevice = await findTargetDevice();
if (targetDevice == null) {
throwToolExit(null);
}
debugPort;
if (debugPort == null && debugUri == null && argResults!.wasParsed(FlutterCommand.ipv6Flag)) {
// Allow --ipv6 for iOS devices even if --debug-port and --debug-url
// are unknown
if (!_isIOSDevice(targetDevice) &&
debugPort == null &&
debugUri == null &&
argResults!.wasParsed(FlutterCommand.ipv6Flag)) {
throwToolExit(
'When the --debug-port or --debug-url is unknown, this command determines '
'the value of --ipv6 on its own.',
@ -311,7 +319,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
}
rethrow;
}
} else if ((device is IOSDevice) || (device is IOSSimulator) || (device is MacOSDesignedForIPadDevice)) {
} else if (_isIOSDevice(device)) {
// Protocol Discovery relies on logging. On iOS earlier than 13, logging is gathered using syslog.
// syslog is not available for iOS 13+. For iOS 13+, Protocol Discovery gathers logs from the VMService.
// Since we don't have access to the VMService yet, Protocol Discovery cannot be used for iOS 13+.
@ -395,8 +403,6 @@ known, it can be explicitly provided to attach via the command-line, e.g.
);
_logger.printStatus('Waiting for a connection from Flutter on ${device.name}...');
vmServiceUri = vmServiceDiscovery.uris;
// Determine ipv6 status from the scanned logs.
usesIpv6 = vmServiceDiscovery.ipv6;
}
} else {
vmServiceUri = Stream<Uri>
@ -544,6 +550,12 @@ known, it can be explicitly provided to attach via the command-line, e.g.
}
Future<void> _validateArguments() async { }
bool _isIOSDevice(Device device) {
return (device is IOSDevice) ||
(device is IOSSimulator) ||
(device is MacOSDesignedForIPadDevice);
}
}
class HotRunnerFactory {

View file

@ -20,9 +20,10 @@ class ProtocolDiscovery {
required this.throttleDuration,
this.hostPort,
this.devicePort,
required this.ipv6,
required bool ipv6,
required Logger logger,
}) : _logger = logger {
}) : _logger = logger,
_ipv6 = ipv6 {
_deviceLogSubscription = logReader.logLines.listen(
_handleLine,
onDone: _stopScrapingLogs,
@ -56,7 +57,7 @@ class ProtocolDiscovery {
final DevicePortForwarder? portForwarder;
final int? hostPort;
final int? devicePort;
final bool ipv6;
final bool _ipv6;
final Logger _logger;
/// The time to wait before forwarding a new VM Service URIs from [logReader].
@ -144,7 +145,7 @@ class ProtocolDiscovery {
hostUri = deviceUri.replace(port: actualHostPort);
}
if (InternetAddress(hostUri.host).isLoopback && ipv6) {
if (InternetAddress(hostUri.host).isLoopback && _ipv6) {
hostUri = hostUri.replace(host: InternetAddress.loopbackIPv6.host);
}
return hostUri;

View file

@ -603,8 +603,7 @@ abstract class FlutterCommand extends Command<void> {
argParser.addFlag(ipv6Flag,
negatable: false,
help: 'Binds to IPv6 localhost instead of IPv4 when the flutter tool '
'forwards the host port to a device port. Not used when the '
'"--debug-port" flag is not set.',
'forwards the host port to a device port.',
hide: !verboseHelp,
);
_usesIpv6Flag = true;

View file

@ -591,7 +591,7 @@ void main() {
DeviceManager: () => testDeviceManager,
});
testUsingContext('exits when ipv6 is specified and debug-port is not', () async {
testUsingContext('exits when ipv6 is specified and debug-port is not on non-iOS device', () async {
testDeviceManager.devices = <Device>[device];
final AttachCommand command = AttachCommand(
@ -615,7 +615,63 @@ void main() {
FileSystem: () => testFileSystem,
ProcessManager: () => FakeProcessManager.any(),
DeviceManager: () => testDeviceManager,
},);
});
testUsingContext('succeeds when ipv6 is specified and debug-port is not on iOS device', () async {
final FakeIOSDevice device = FakeIOSDevice(
logReader: fakeLogReader,
portForwarder: portForwarder,
majorSdkVersion: 12,
onGetLogReader: () {
fakeLogReader.addLine('Foo');
fakeLogReader.addLine('The Dart VM service is listening on http://[::1]:$devicePort');
return fakeLogReader;
},
);
testDeviceManager.devices = <Device>[device];
final Completer<void> completer = Completer<void>();
final StreamSubscription<String> loggerSubscription = logger.stream.listen((String message) {
if (message == '[verbose] VM Service URL on device: http://[::1]:$devicePort') {
// The "VM Service URL on device" message is output by the ProtocolDiscovery when it found the VM Service.
completer.complete();
}
});
final FakeHotRunner hotRunner = FakeHotRunner();
hotRunner.onAttach = (
Completer<DebugConnectionInfo>? connectionInfoCompleter,
Completer<void>? appStartedCompleter,
bool allowExistingDdsInstance,
bool enableDevTools,
) async => 0;
hotRunner.exited = false;
hotRunner.isWaitingForVmService = false;
final FakeHotRunnerFactory hotRunnerFactory = FakeHotRunnerFactory()
..hotRunner = hotRunner;
await createTestCommandRunner(AttachCommand(
hotRunnerFactory: hotRunnerFactory,
artifacts: artifacts,
stdio: stdio,
logger: logger,
terminal: terminal,
signals: signals,
platform: platform,
processInfo: processInfo,
fileSystem: testFileSystem,
)).run(<String>['attach', '--ipv6']);
await completer.future;
expect(portForwarder.devicePort, devicePort);
expect(portForwarder.hostPort, hostPort);
await fakeLogReader.dispose();
await loggerSubscription.cancel();
}, overrides: <Type, Generator>{
FileSystem: () => testFileSystem,
ProcessManager: () => FakeProcessManager.any(),
Logger: () => logger,
DeviceManager: () => testDeviceManager,
});
testUsingContext('exits when vm-service-port is specified and debug-port is not', () async {
device.onGetLogReader = () {