Skip to content

Commit 27248d4

Browse files
authored
Separate attached and wireless devices (flutter#122615)
Separate attached and wireless devices
1 parent 5d10cc2 commit 27248d4

34 files changed

+1597
-621
lines changed

packages/flutter_tools/lib/src/android/android_device.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ class AndroidDevice extends Device {
8989
final String modelID;
9090
final String? deviceCodeName;
9191

92+
@override
93+
// Wirelessly paired Android devices should have `adb-tls-connect` in the id.
94+
// Source: https://android.googlesource.com/platform/packages/modules/adb/+/f4ba8d73079b99532069dbe888a58167b8723d6c/adb_mdns.h#30
95+
DeviceConnectionInterface get connectionInterface =>
96+
id.contains('adb-tls-connect')
97+
? DeviceConnectionInterface.wireless
98+
: DeviceConnectionInterface.attached;
99+
92100
late final Future<Map<String, String>> _properties = () async {
93101
Map<String, String> properties = <String, String>{};
94102

packages/flutter_tools/lib/src/base/user_messages.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ class UserMessages {
265265
'for information about installing additional components.';
266266
String flutterNoMatchingDevice(String deviceId) => 'No supported devices found with name or id '
267267
"matching '$deviceId'.";
268-
String get flutterNoDevicesFound => 'No devices found';
268+
String get flutterNoDevicesFound => 'No devices found.';
269269
String get flutterNoSupportedDevices => 'No supported devices connected.';
270270
String flutterMissPlatformProjects(List<String> unsupportedDevicesType) =>
271271
'If you would like your app to run on ${unsupportedDevicesType.join(' or ')}, consider running `flutter create .` to generate projects for these platforms.';

packages/flutter_tools/lib/src/commands/attach.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import '../device.dart';
2424
import '../device_port_forwarder.dart';
2525
import '../fuchsia/fuchsia_device.dart';
2626
import '../ios/devices.dart';
27-
import '../ios/iproxy.dart';
2827
import '../ios/simulators.dart';
2928
import '../macos/macos_ipad_device.dart';
3029
import '../mdns_discovery.dart';
@@ -287,7 +286,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
287286
final String ipv6Loopback = InternetAddress.loopbackIPv6.address;
288287
final String ipv4Loopback = InternetAddress.loopbackIPv4.address;
289288
final String hostname = usesIpv6 ? ipv6Loopback : ipv4Loopback;
290-
final bool isNetworkDevice = (device is IOSDevice) && device.interfaceType == IOSDeviceConnectionInterface.network;
289+
final bool isNetworkDevice = (device is IOSDevice) && device.isWirelesslyConnected;
291290

292291
if ((debugPort == null && debugUri == null) || isNetworkDevice) {
293292
if (device is FuchsiaDevice) {

packages/flutter_tools/lib/src/commands/devices.dart

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,31 +79,71 @@ class DevicesCommandOutput {
7979

8080
final Duration? deviceDiscoveryTimeout;
8181

82+
Future<List<Device>> _getAttachedDevices(DeviceManager deviceManager) async {
83+
return deviceManager.getAllDevices(
84+
filter: DeviceDiscoveryFilter(
85+
deviceConnectionInterface: DeviceConnectionInterface.attached,
86+
),
87+
);
88+
}
89+
90+
Future<List<Device>> _getWirelessDevices(DeviceManager deviceManager) async {
91+
return deviceManager.getAllDevices(
92+
filter: DeviceDiscoveryFilter(
93+
deviceConnectionInterface: DeviceConnectionInterface.wireless,
94+
),
95+
);
96+
}
97+
8298
Future<void> findAndOutputAllTargetDevices({required bool machine}) async {
83-
final List<Device> devices = await globals.deviceManager?.refreshAllDevices(timeout: deviceDiscoveryTimeout) ?? <Device>[];
99+
List<Device> attachedDevices = <Device>[];
100+
List<Device> wirelessDevices = <Device>[];
101+
final DeviceManager? deviceManager = globals.deviceManager;
102+
if (deviceManager != null) {
103+
// Refresh the cache and then get the attached and wireless devices from
104+
// the cache.
105+
await deviceManager.refreshAllDevices(timeout: deviceDiscoveryTimeout);
106+
attachedDevices = await _getAttachedDevices(deviceManager);
107+
wirelessDevices = await _getWirelessDevices(deviceManager);
108+
}
109+
final List<Device> allDevices = attachedDevices + wirelessDevices;
84110

85111
if (machine) {
86-
await printDevicesAsJson(devices);
112+
await printDevicesAsJson(allDevices);
113+
return;
114+
}
115+
116+
if (allDevices.isEmpty) {
117+
_printNoDevicesDetected();
87118
} else {
88-
if (devices.isEmpty) {
89-
final StringBuffer status = StringBuffer('No devices detected.');
90-
status.writeln();
91-
status.writeln();
92-
status.writeln('Run "flutter emulators" to list and start any available device emulators.');
93-
status.writeln();
94-
status.write('If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. ');
95-
if (deviceDiscoveryTimeout == null) {
96-
status.write('You may also try increasing the time to wait for connected devices with the --${FlutterOptions.kDeviceTimeout} flag. ');
119+
if (attachedDevices.isNotEmpty) {
120+
globals.printStatus('${attachedDevices.length} connected ${pluralize('device', attachedDevices.length)}:\n');
121+
await Device.printDevices(attachedDevices, globals.logger);
122+
}
123+
if (wirelessDevices.isNotEmpty) {
124+
if (attachedDevices.isNotEmpty) {
125+
globals.printStatus('');
97126
}
98-
status.write('Visit https://flutter.dev/setup/ for troubleshooting tips.');
99-
100-
globals.printStatus(status.toString());
101-
} else {
102-
globals.printStatus('${devices.length} connected ${pluralize('device', devices.length)}:\n');
103-
await Device.printDevices(devices, globals.logger);
127+
globals.printStatus('${wirelessDevices.length} wirelessly connected ${pluralize('device', wirelessDevices.length)}:\n');
128+
await Device.printDevices(wirelessDevices, globals.logger);
104129
}
105-
await _printDiagnostics();
106130
}
131+
await _printDiagnostics();
132+
}
133+
134+
void _printNoDevicesDetected() {
135+
final StringBuffer status = StringBuffer('No devices detected.');
136+
status.writeln();
137+
status.writeln();
138+
status.writeln('Run "flutter emulators" to list and start any available device emulators.');
139+
status.writeln();
140+
status.write('If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. ');
141+
if (deviceDiscoveryTimeout == null) {
142+
status.write('You may also try increasing the time to wait for connected devices with the --${FlutterOptions.kDeviceTimeout} flag. ');
143+
}
144+
status.write('Visit https://flutter.dev/setup/ for troubleshooting tips.');
145+
146+
globals.printStatus(status.toString());
107147
}
108148

109149
Future<void> _printDiagnostics() async {

packages/flutter_tools/lib/src/commands/drive.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import '../device.dart';
2323
import '../drive/drive_service.dart';
2424
import '../globals.dart' as globals;
2525
import '../ios/devices.dart';
26-
import '../ios/iproxy.dart';
2726
import '../resident_runner.dart';
2827
import '../runner/flutter_command.dart' show FlutterCommandCategory, FlutterCommandResult, FlutterOptions;
2928
import '../web/web_device.dart';
@@ -220,7 +219,7 @@ class DriveCommand extends RunCommandBase {
220219
Future<bool> get disablePortPublication async {
221220
final ArgResults? localArgResults = argResults;
222221
final Device? device = await targetedDevice;
223-
final bool isNetworkDevice = device is IOSDevice && device.interfaceType == IOSDeviceConnectionInterface.network;
222+
final bool isNetworkDevice = device is IOSDevice && device.isWirelesslyConnected;
224223
if (isNetworkDevice && localArgResults != null && !localArgResults.wasParsed('publish-port')) {
225224
_logger.printTrace('Network device is being used. Changing `publish-port` to be enabled.');
226225
return false;

packages/flutter_tools/lib/src/commands/run.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import '../device.dart';
2020
import '../features.dart';
2121
import '../globals.dart' as globals;
2222
import '../ios/devices.dart';
23-
import '../ios/iproxy.dart';
2423
import '../project.dart';
2524
import '../reporting/reporting.dart';
2625
import '../resident_runner.dart';
@@ -426,7 +425,7 @@ class RunCommand extends RunCommandBase {
426425
final TargetPlatform platform = await device.targetPlatform;
427426
anyAndroidDevices = platform == TargetPlatform.android;
428427
anyIOSDevices = platform == TargetPlatform.ios;
429-
if (device is IOSDevice && device.interfaceType == IOSDeviceConnectionInterface.network) {
428+
if (device is IOSDevice && device.isWirelesslyConnected) {
430429
anyIOSNetworkDevices = true;
431430
}
432431
deviceType = getNameForTargetPlatform(platform);
@@ -440,7 +439,7 @@ class RunCommand extends RunCommandBase {
440439
final TargetPlatform platform = await device.targetPlatform;
441440
anyAndroidDevices = anyAndroidDevices || (platform == TargetPlatform.android);
442441
anyIOSDevices = anyIOSDevices || (platform == TargetPlatform.ios);
443-
if (device is IOSDevice && device.interfaceType == IOSDeviceConnectionInterface.network) {
442+
if (device is IOSDevice && device.isWirelesslyConnected) {
444443
anyIOSNetworkDevices = true;
445444
}
446445
if (anyAndroidDevices && anyIOSDevices) {

packages/flutter_tools/lib/src/device.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import 'base/utils.dart';
1717
import 'build_info.dart';
1818
import 'devfs.dart';
1919
import 'device_port_forwarder.dart';
20-
import 'ios/iproxy.dart';
2120
import 'project.dart';
2221
import 'vmservice.dart';
2322

@@ -1098,7 +1097,7 @@ class DebuggingOptions {
10981097
String? route,
10991098
Map<String, Object?> platformArgs, {
11001099
bool ipv6 = false,
1101-
IOSDeviceConnectionInterface interfaceType = IOSDeviceConnectionInterface.none
1100+
DeviceConnectionInterface interfaceType = DeviceConnectionInterface.attached,
11021101
}) {
11031102
final String dartVmFlags = computeDartVmFlags(this);
11041103
return <String>[
@@ -1137,7 +1136,7 @@ class DebuggingOptions {
11371136
if (environmentType == EnvironmentType.simulator && hostVmServicePort != null)
11381137
'--vm-service-port=$hostVmServicePort',
11391138
// Tell the VM service to listen on all interfaces, don't restrict to the loopback.
1140-
if (interfaceType == IOSDeviceConnectionInterface.network)
1139+
if (interfaceType == DeviceConnectionInterface.wireless)
11411140
'--vm-service-host=${ipv6 ? '::0' : '0.0.0.0'}',
11421141
if (enableEmbedderApi) '--enable-embedder-api',
11431142
];

packages/flutter_tools/lib/src/ios/devices.dart

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class IOSDevice extends Device {
151151
required FileSystem fileSystem,
152152
required this.name,
153153
required this.cpuArchitecture,
154-
required this.interfaceType,
154+
required this.connectionInterface,
155155
String? sdkVersion,
156156
required Platform platform,
157157
required IOSDeploy iosDeploy,
@@ -199,7 +199,8 @@ class IOSDevice extends Device {
199199

200200
final DarwinArch cpuArchitecture;
201201

202-
final IOSDeviceConnectionInterface interfaceType;
202+
@override
203+
final DeviceConnectionInterface connectionInterface;
203204

204205
final Map<IOSApp?, DeviceLogReader> _logReaders = <IOSApp?, DeviceLogReader>{};
205206

@@ -256,7 +257,7 @@ class IOSDevice extends Device {
256257
bundlePath: bundle.path,
257258
appDeltaDirectory: app.appDeltaDirectory,
258259
launchArguments: <String>[],
259-
interfaceType: interfaceType,
260+
interfaceType: connectionInterface,
260261
);
261262
} on ProcessException catch (e) {
262263
_logger.printError(e.message);
@@ -311,7 +312,7 @@ class IOSDevice extends Device {
311312
@visibleForTesting Duration? discoveryTimeout,
312313
}) async {
313314
String? packageId;
314-
if (interfaceType == IOSDeviceConnectionInterface.network &&
315+
if (isWirelesslyConnected &&
315316
debuggingOptions.debuggingEnabled &&
316317
debuggingOptions.disablePortPublication) {
317318
throwToolExit('Cannot start app on wirelessly tethered iOS device. Try running again with the --publish-port flag');
@@ -351,7 +352,7 @@ class IOSDevice extends Device {
351352
route,
352353
platformArgs,
353354
ipv6: ipv6,
354-
interfaceType: interfaceType,
355+
interfaceType: connectionInterface,
355356
);
356357
Status startAppStatus = _logger.startProgress(
357358
'Installing and launching...',
@@ -371,7 +372,7 @@ class IOSDevice extends Device {
371372
bundlePath: bundle.path,
372373
appDeltaDirectory: package.appDeltaDirectory,
373374
launchArguments: launchArguments,
374-
interfaceType: interfaceType,
375+
interfaceType: connectionInterface,
375376
uninstallFirst: debuggingOptions.uninstallFirst,
376377
);
377378
if (deviceLogReader is IOSDeviceLogReader) {
@@ -381,7 +382,7 @@ class IOSDevice extends Device {
381382
// Don't port foward if debugging with a network device.
382383
vmServiceDiscovery = ProtocolDiscovery.vmService(
383384
deviceLogReader,
384-
portForwarder: interfaceType == IOSDeviceConnectionInterface.network ? null : portForwarder,
385+
portForwarder: isWirelesslyConnected ? null : portForwarder,
385386
hostPort: debuggingOptions.hostVmServicePort,
386387
devicePort: debuggingOptions.deviceVmServicePort,
387388
ipv6: ipv6,
@@ -394,7 +395,7 @@ class IOSDevice extends Device {
394395
bundlePath: bundle.path,
395396
appDeltaDirectory: package.appDeltaDirectory,
396397
launchArguments: launchArguments,
397-
interfaceType: interfaceType,
398+
interfaceType: connectionInterface,
398399
uninstallFirst: debuggingOptions.uninstallFirst,
399400
);
400401
} else {
@@ -414,13 +415,13 @@ class IOSDevice extends Device {
414415

415416
_logger.printTrace('Application launched on the device. Waiting for Dart VM Service url.');
416417

417-
final int defaultTimeout = interfaceType == IOSDeviceConnectionInterface.network ? 45 : 30;
418+
final int defaultTimeout = isWirelesslyConnected ? 45 : 30;
418419
final Timer timer = Timer(discoveryTimeout ?? Duration(seconds: defaultTimeout), () {
419420
_logger.printError('The Dart VM Service was not discovered after $defaultTimeout seconds. This is taking much longer than expected...');
420421

421422
// If debugging with a wireless device and the timeout is reached, remind the
422423
// user to allow local network permissions.
423-
if (interfaceType == IOSDeviceConnectionInterface.network) {
424+
if (isWirelesslyConnected) {
424425
_logger.printError(
425426
'\nClick "Allow" to the prompt asking if you would like to find and connect devices on your local network. '
426427
'This is required for wireless debugging. If you selected "Don\'t Allow", '
@@ -433,7 +434,7 @@ class IOSDevice extends Device {
433434
});
434435

435436
Uri? localUri;
436-
if (interfaceType == IOSDeviceConnectionInterface.network) {
437+
if (isWirelesslyConnected) {
437438
// Wait for Dart VM Service to start up.
438439
final Uri? serviceURL = await vmServiceDiscovery?.uri;
439440
if (serviceURL == null) {
@@ -538,7 +539,7 @@ class IOSDevice extends Device {
538539

539540
@override
540541
Future<void> takeScreenshot(File outputFile) async {
541-
await _iMobileDevice.takeScreenshot(outputFile, id, interfaceType);
542+
await _iMobileDevice.takeScreenshot(outputFile, id, connectionInterface);
542543
}
543544

544545
@override

packages/flutter_tools/lib/src/ios/ios_deploy.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import '../base/platform.dart';
1515
import '../base/process.dart';
1616
import '../cache.dart';
1717
import '../convert.dart';
18+
import '../device.dart';
1819
import 'code_signing.dart';
19-
import 'iproxy.dart';
2020

2121
// Error message patterns from ios-deploy output
2222
const String noProvisioningProfileErrorOne = 'Error 0xe8008015';
@@ -88,7 +88,7 @@ class IOSDeploy {
8888
required String deviceId,
8989
required String bundlePath,
9090
required List<String>launchArguments,
91-
required IOSDeviceConnectionInterface interfaceType,
91+
required DeviceConnectionInterface interfaceType,
9292
Directory? appDeltaDirectory,
9393
}) async {
9494
appDeltaDirectory?.createSync(recursive: true);
@@ -102,7 +102,7 @@ class IOSDeploy {
102102
'--app_deltas',
103103
appDeltaDirectory.path,
104104
],
105-
if (interfaceType != IOSDeviceConnectionInterface.network)
105+
if (interfaceType != DeviceConnectionInterface.wireless)
106106
'--no-wifi',
107107
if (launchArguments.isNotEmpty) ...<String>[
108108
'--args',
@@ -126,7 +126,7 @@ class IOSDeploy {
126126
required String deviceId,
127127
required String bundlePath,
128128
required List<String> launchArguments,
129-
required IOSDeviceConnectionInterface interfaceType,
129+
required DeviceConnectionInterface interfaceType,
130130
Directory? appDeltaDirectory,
131131
required bool uninstallFirst,
132132
}) {
@@ -149,7 +149,7 @@ class IOSDeploy {
149149
if (uninstallFirst)
150150
'--uninstall',
151151
'--debug',
152-
if (interfaceType != IOSDeviceConnectionInterface.network)
152+
if (interfaceType != DeviceConnectionInterface.wireless)
153153
'--no-wifi',
154154
if (launchArguments.isNotEmpty) ...<String>[
155155
'--args',
@@ -171,7 +171,7 @@ class IOSDeploy {
171171
required String deviceId,
172172
required String bundlePath,
173173
required List<String> launchArguments,
174-
required IOSDeviceConnectionInterface interfaceType,
174+
required DeviceConnectionInterface interfaceType,
175175
required bool uninstallFirst,
176176
Directory? appDeltaDirectory,
177177
}) async {
@@ -186,7 +186,7 @@ class IOSDeploy {
186186
'--app_deltas',
187187
appDeltaDirectory.path,
188188
],
189-
if (interfaceType != IOSDeviceConnectionInterface.network)
189+
if (interfaceType != DeviceConnectionInterface.wireless)
190190
'--no-wifi',
191191
if (uninstallFirst)
192192
'--uninstall',

packages/flutter_tools/lib/src/ios/iproxy.dart

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@ import '../base/io.dart';
88
import '../base/logger.dart';
99
import '../base/process.dart';
1010

11-
enum IOSDeviceConnectionInterface {
12-
none,
13-
usb,
14-
network,
15-
}
16-
1711
/// Wraps iproxy command line tool port forwarding.
1812
///
1913
/// See https://github.com/libimobiledevice/libusbmuxd.

0 commit comments

Comments
 (0)