Repository navigation
Support iOS wireless debugging #118104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support iOS wireless debugging #118104
Changes from 1 commit
8a607d3
2dfdf97
5f3caaa
5691519
3e6c1a0
b63c79c
180e93d
7b6da55
60c487b
0cf0b70
f42e382
9655735
8d78df2
eb0f417
edcc5c5
60a63a9
f81ca6d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ import '../device.dart'; | |
| import '../device_port_forwarder.dart'; | ||
| import '../globals.dart' as globals; | ||
| import '../macos/xcdevice.dart'; | ||
| import '../mdns_discovery.dart'; | ||
| import '../project.dart'; | ||
| import '../protocol_discovery.dart'; | ||
| import '../vmservice.dart'; | ||
|
|
@@ -189,15 +190,6 @@ class IOSDevice extends Device { | |
| return majorVersionString != null ? int.tryParse(majorVersionString) ?? 0 : 0; | ||
| } | ||
|
|
||
| @override | ||
| bool get supportsHotReload => interfaceType == IOSDeviceConnectionInterface.usb; | ||
|
|
||
| @override | ||
| bool get supportsHotRestart => interfaceType == IOSDeviceConnectionInterface.usb; | ||
|
|
||
| @override | ||
| bool get supportsFlutterExit => interfaceType == IOSDeviceConnectionInterface.usb; | ||
|
|
||
| @override | ||
| final String name; | ||
|
|
||
|
|
@@ -318,7 +310,12 @@ class IOSDevice extends Device { | |
| @visibleForTesting Duration? discoveryTimeout, | ||
| }) async { | ||
| String? packageId; | ||
|
|
||
| if (interfaceType == IOSDeviceConnectionInterface.network && | ||
| debuggingOptions.debuggingEnabled && | ||
| debuggingOptions.disablePortPublication) { | ||
| _logger.printError('Port publication (publish-port) must be enabled for wireless debugging.'); | ||
| return LaunchResult.failed(); | ||
| } | ||
| if (!prebuiltApplication) { | ||
| _logger.printTrace('Building ${package.name} for $id'); | ||
|
|
||
|
|
@@ -353,6 +350,8 @@ class IOSDevice extends Device { | |
| EnvironmentType.physical, | ||
| route, | ||
| platformArgs, | ||
| ipv6: ipv6, | ||
| interfaceType: interfaceType, | ||
| ); | ||
| final Status installStatus = _logger.startProgress( | ||
| 'Installing and launching...', | ||
|
|
@@ -379,9 +378,10 @@ class IOSDevice extends Device { | |
| deviceLogReader.debuggerStream = iosDeployDebugger; | ||
| } | ||
| } | ||
| // Don't port foward if debugging with a network device. | ||
| observatoryDiscovery = ProtocolDiscovery.observatory( | ||
| deviceLogReader, | ||
| portForwarder: portForwarder, | ||
| portForwarder: interfaceType == IOSDeviceConnectionInterface.network ? null : portForwarder, | ||
| hostPort: debuggingOptions.hostVmServicePort, | ||
| devicePort: debuggingOptions.deviceVmServicePort, | ||
| ipv6: ipv6, | ||
|
|
@@ -413,11 +413,32 @@ class IOSDevice extends Device { | |
| } | ||
|
|
||
| _logger.printTrace('Application launched on the device. Waiting for observatory url.'); | ||
| final Timer timer = Timer(discoveryTimeout ?? const Duration(seconds: 30), () { | ||
| _logger.printError('iOS Observatory not discovered after 30 seconds. This is taking much longer than expected...'); | ||
| final int defaultTimeout = interfaceType == IOSDeviceConnectionInterface.network ? 60 : 30; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found that this took longer when using a network device. 60 seconds might be a bit generous, though. Sometimes 30 seconds is enough, but sometimes it's more like 35. Not sure if people's internet connections might influence this (mine is pretty fast), which is why I overestimated.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wow that's a long time. Maybe 45 and we'll see if we get complaints?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. Updated. |
||
| final Timer timer = Timer(discoveryTimeout ?? Duration(seconds: defaultTimeout), () { | ||
| _logger.printError('iOS Observatory not discovered after ${discoveryTimeout ?? defaultTimeout} seconds. This is taking much longer than expected...'); | ||
| iosDeployDebugger?.pauseDumpBacktraceResume(); | ||
| }); | ||
| final Uri? localUri = await observatoryDiscovery?.uri; | ||
|
|
||
| Uri? localUri; | ||
| if (interfaceType == IOSDeviceConnectionInterface.network) { | ||
| try { | ||
| // Wait for iOS Observatory to start up. | ||
| await observatoryDiscovery?.uri; | ||
|
|
||
| // Get Observatory URL with the device IP. | ||
| localUri = await MDnsObservatoryDiscovery.instance!.getObservatoryUri( | ||
| package.id, | ||
| this, | ||
| usesIpv6: ipv6, | ||
| deviceVmservicePort: debuggingOptions.deviceVmServicePort, | ||
| isNetworkDevice: true, | ||
| ); | ||
| } on StateError { | ||
| _logger.printError('iOS Observatory not discovered before stream was closed.'); | ||
| } | ||
| } else { | ||
| localUri = await observatoryDiscovery?.uri; | ||
| } | ||
| timer.cancel(); | ||
| if (localUri == null) { | ||
| await iosDeployDebugger?.stopAndDumpBacktrace(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -227,8 +227,16 @@ class XCDevice { | |
|
|
||
| /// [timeout] defaults to 2 seconds. | ||
| Future<List<IOSDevice>> getAvailableIOSDevices({ Duration? timeout }) async { | ||
| Status? loadDevicesStatus; | ||
| if (timeout != null && timeout.inSeconds > 2) { | ||
| loadDevicesStatus = _logger.startProgress( | ||
| 'Loading devices...', | ||
| ); | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change just gives some visual feedback that it's loading the devices. |
||
| final List<Object>? allAvailableDevices = await _getAllDevices(timeout: timeout ?? const Duration(seconds: 2)); | ||
|
|
||
| if (loadDevicesStatus != null) { | ||
| loadDevicesStatus.stop(); | ||
| } | ||
| if (allAvailableDevices == null) { | ||
| return const <IOSDevice>[]; | ||
| } | ||
|
|
@@ -305,12 +313,6 @@ class XCDevice { | |
|
|
||
| final IOSDeviceConnectionInterface interface = _interfaceType(device); | ||
|
|
||
| // Only support USB devices, skip "network" interface (Xcode > Window > Devices and Simulators > Connect via network). | ||
| // TODO(jmagman): Remove this check once wirelessly detected devices can be observed and attached, https://github.com/flutter/flutter/issues/15072. | ||
| if (interface != IOSDeviceConnectionInterface.usb) { | ||
| continue; | ||
| } | ||
|
|
||
| String? sdkVersion = _sdkVersion(device); | ||
|
|
||
| if (sdkVersion != null) { | ||
|
|
@@ -324,7 +326,7 @@ class XCDevice { | |
| identifier, | ||
| name: name, | ||
| cpuArchitecture: _cpuArchitecture(device), | ||
| interfaceType: interface, | ||
| interfaceType: _interfaceType(device), | ||
| sdkVersion: sdkVersion, | ||
| iProxy: _iProxy, | ||
| fileSystem: globals.fs, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Messages like this need to be actionable by the user. What are they supposed to do in this case to fix it? When we have actionable errors like this we should
throwToolExit.Something like:
Introduced in #67452 to prevent the pop-up from blocking the app in a CI setting.
Maybe
driveshould default to always publishing, and we update our CI scripts to pass--no-publish-portso users manually running tests won't hit this? wdyt?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the error message.
And thanks for the reminder about
drive, I misunderstood the first time we talked about it. I tried a different approach, so basically added an override fordisablePortPublicationthat checks if the flag wasn't provided as an actual argument and it's a network device, then changes publish-port to be enabled. It's a little bit hacky, but allowsdriveto continue functioning as it was before for all wired devices without needing to update anything. Let me know if you think that's not a good solution.