Unverified Commit 27248d4b authored by Victoria Ashworth's avatar Victoria Ashworth Committed by GitHub

Separate attached and wireless devices (#122615)

Separate attached and wireless devices
parent 5d10cc28
......@@ -89,6 +89,14 @@ class AndroidDevice extends Device {
final String modelID;
final String? deviceCodeName;
@override
// Wirelessly paired Android devices should have `adb-tls-connect` in the id.
// Source: https://android.googlesource.com/platform/packages/modules/adb/+/f4ba8d73079b99532069dbe888a58167b8723d6c/adb_mdns.h#30
DeviceConnectionInterface get connectionInterface =>
id.contains('adb-tls-connect')
? DeviceConnectionInterface.wireless
: DeviceConnectionInterface.attached;
late final Future<Map<String, String>> _properties = () async {
Map<String, String> properties = <String, String>{};
......
......@@ -265,7 +265,7 @@ class UserMessages {
'for information about installing additional components.';
String flutterNoMatchingDevice(String deviceId) => 'No supported devices found with name or id '
"matching '$deviceId'.";
String get flutterNoDevicesFound => 'No devices found';
String get flutterNoDevicesFound => 'No devices found.';
String get flutterNoSupportedDevices => 'No supported devices connected.';
String flutterMissPlatformProjects(List<String> unsupportedDevicesType) =>
'If you would like your app to run on ${unsupportedDevicesType.join(' or ')}, consider running `flutter create .` to generate projects for these platforms.';
......
......@@ -24,7 +24,6 @@ import '../device.dart';
import '../device_port_forwarder.dart';
import '../fuchsia/fuchsia_device.dart';
import '../ios/devices.dart';
import '../ios/iproxy.dart';
import '../ios/simulators.dart';
import '../macos/macos_ipad_device.dart';
import '../mdns_discovery.dart';
......@@ -287,7 +286,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
final String ipv6Loopback = InternetAddress.loopbackIPv6.address;
final String ipv4Loopback = InternetAddress.loopbackIPv4.address;
final String hostname = usesIpv6 ? ipv6Loopback : ipv4Loopback;
final bool isNetworkDevice = (device is IOSDevice) && device.interfaceType == IOSDeviceConnectionInterface.network;
final bool isNetworkDevice = (device is IOSDevice) && device.isWirelesslyConnected;
if ((debugPort == null && debugUri == null) || isNetworkDevice) {
if (device is FuchsiaDevice) {
......
......@@ -79,31 +79,71 @@ class DevicesCommandOutput {
final Duration? deviceDiscoveryTimeout;
Future<List<Device>> _getAttachedDevices(DeviceManager deviceManager) async {
return deviceManager.getAllDevices(
filter: DeviceDiscoveryFilter(
deviceConnectionInterface: DeviceConnectionInterface.attached,
),
);
}
Future<List<Device>> _getWirelessDevices(DeviceManager deviceManager) async {
return deviceManager.getAllDevices(
filter: DeviceDiscoveryFilter(
deviceConnectionInterface: DeviceConnectionInterface.wireless,
),
);
}
Future<void> findAndOutputAllTargetDevices({required bool machine}) async {
final List<Device> devices = await globals.deviceManager?.refreshAllDevices(timeout: deviceDiscoveryTimeout) ?? <Device>[];
List<Device> attachedDevices = <Device>[];
List<Device> wirelessDevices = <Device>[];
final DeviceManager? deviceManager = globals.deviceManager;
if (deviceManager != null) {
// Refresh the cache and then get the attached and wireless devices from
// the cache.
await deviceManager.refreshAllDevices(timeout: deviceDiscoveryTimeout);
attachedDevices = await _getAttachedDevices(deviceManager);
wirelessDevices = await _getWirelessDevices(deviceManager);
}
final List<Device> allDevices = attachedDevices + wirelessDevices;
if (machine) {
await printDevicesAsJson(devices);
await printDevicesAsJson(allDevices);
return;
}
if (allDevices.isEmpty) {
_printNoDevicesDetected();
} else {
if (devices.isEmpty) {
final StringBuffer status = StringBuffer('No devices detected.');
status.writeln();
status.writeln();
status.writeln('Run "flutter emulators" to list and start any available device emulators.');
status.writeln();
status.write('If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. ');
if (deviceDiscoveryTimeout == null) {
status.write('You may also try increasing the time to wait for connected devices with the --${FlutterOptions.kDeviceTimeout} flag. ');
if (attachedDevices.isNotEmpty) {
globals.printStatus('${attachedDevices.length} connected ${pluralize('device', attachedDevices.length)}:\n');
await Device.printDevices(attachedDevices, globals.logger);
}
if (wirelessDevices.isNotEmpty) {
if (attachedDevices.isNotEmpty) {
globals.printStatus('');
}
status.write('Visit https://flutter.dev/setup/ for troubleshooting tips.');
globals.printStatus(status.toString());
} else {
globals.printStatus('${devices.length} connected ${pluralize('device', devices.length)}:\n');
await Device.printDevices(devices, globals.logger);
globals.printStatus('${wirelessDevices.length} wirelessly connected ${pluralize('device', wirelessDevices.length)}:\n');
await Device.printDevices(wirelessDevices, globals.logger);
}
await _printDiagnostics();
}
await _printDiagnostics();
}
void _printNoDevicesDetected() {
final StringBuffer status = StringBuffer('No devices detected.');
status.writeln();
status.writeln();
status.writeln('Run "flutter emulators" to list and start any available device emulators.');
status.writeln();
status.write('If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. ');
if (deviceDiscoveryTimeout == null) {
status.write('You may also try increasing the time to wait for connected devices with the --${FlutterOptions.kDeviceTimeout} flag. ');
}
status.write('Visit https://flutter.dev/setup/ for troubleshooting tips.');
globals.printStatus(status.toString());
}
Future<void> _printDiagnostics() async {
......
......@@ -23,7 +23,6 @@ import '../device.dart';
import '../drive/drive_service.dart';
import '../globals.dart' as globals;
import '../ios/devices.dart';
import '../ios/iproxy.dart';
import '../resident_runner.dart';
import '../runner/flutter_command.dart' show FlutterCommandCategory, FlutterCommandResult, FlutterOptions;
import '../web/web_device.dart';
......@@ -220,7 +219,7 @@ class DriveCommand extends RunCommandBase {
Future<bool> get disablePortPublication async {
final ArgResults? localArgResults = argResults;
final Device? device = await targetedDevice;
final bool isNetworkDevice = device is IOSDevice && device.interfaceType == IOSDeviceConnectionInterface.network;
final bool isNetworkDevice = device is IOSDevice && device.isWirelesslyConnected;
if (isNetworkDevice && localArgResults != null && !localArgResults.wasParsed('publish-port')) {
_logger.printTrace('Network device is being used. Changing `publish-port` to be enabled.');
return false;
......
......@@ -20,7 +20,6 @@ import '../device.dart';
import '../features.dart';
import '../globals.dart' as globals;
import '../ios/devices.dart';
import '../ios/iproxy.dart';
import '../project.dart';
import '../reporting/reporting.dart';
import '../resident_runner.dart';
......@@ -426,7 +425,7 @@ class RunCommand extends RunCommandBase {
final TargetPlatform platform = await device.targetPlatform;
anyAndroidDevices = platform == TargetPlatform.android;
anyIOSDevices = platform == TargetPlatform.ios;
if (device is IOSDevice && device.interfaceType == IOSDeviceConnectionInterface.network) {
if (device is IOSDevice && device.isWirelesslyConnected) {
anyIOSNetworkDevices = true;
}
deviceType = getNameForTargetPlatform(platform);
......@@ -440,7 +439,7 @@ class RunCommand extends RunCommandBase {
final TargetPlatform platform = await device.targetPlatform;
anyAndroidDevices = anyAndroidDevices || (platform == TargetPlatform.android);
anyIOSDevices = anyIOSDevices || (platform == TargetPlatform.ios);
if (device is IOSDevice && device.interfaceType == IOSDeviceConnectionInterface.network) {
if (device is IOSDevice && device.isWirelesslyConnected) {
anyIOSNetworkDevices = true;
}
if (anyAndroidDevices && anyIOSDevices) {
......
......@@ -17,7 +17,6 @@ import 'base/utils.dart';
import 'build_info.dart';
import 'devfs.dart';
import 'device_port_forwarder.dart';
import 'ios/iproxy.dart';
import 'project.dart';
import 'vmservice.dart';
......@@ -1098,7 +1097,7 @@ class DebuggingOptions {
String? route,
Map<String, Object?> platformArgs, {
bool ipv6 = false,
IOSDeviceConnectionInterface interfaceType = IOSDeviceConnectionInterface.none
DeviceConnectionInterface interfaceType = DeviceConnectionInterface.attached,
}) {
final String dartVmFlags = computeDartVmFlags(this);
return <String>[
......@@ -1137,7 +1136,7 @@ class DebuggingOptions {
if (environmentType == EnvironmentType.simulator && hostVmServicePort != null)
'--vm-service-port=$hostVmServicePort',
// Tell the VM service to listen on all interfaces, don't restrict to the loopback.
if (interfaceType == IOSDeviceConnectionInterface.network)
if (interfaceType == DeviceConnectionInterface.wireless)
'--vm-service-host=${ipv6 ? '::0' : '0.0.0.0'}',
if (enableEmbedderApi) '--enable-embedder-api',
];
......
......@@ -151,7 +151,7 @@ class IOSDevice extends Device {
required FileSystem fileSystem,
required this.name,
required this.cpuArchitecture,
required this.interfaceType,
required this.connectionInterface,
String? sdkVersion,
required Platform platform,
required IOSDeploy iosDeploy,
......@@ -199,7 +199,8 @@ class IOSDevice extends Device {
final DarwinArch cpuArchitecture;
final IOSDeviceConnectionInterface interfaceType;
@override
final DeviceConnectionInterface connectionInterface;
final Map<IOSApp?, DeviceLogReader> _logReaders = <IOSApp?, DeviceLogReader>{};
......@@ -256,7 +257,7 @@ class IOSDevice extends Device {
bundlePath: bundle.path,
appDeltaDirectory: app.appDeltaDirectory,
launchArguments: <String>[],
interfaceType: interfaceType,
interfaceType: connectionInterface,
);
} on ProcessException catch (e) {
_logger.printError(e.message);
......@@ -311,7 +312,7 @@ class IOSDevice extends Device {
@visibleForTesting Duration? discoveryTimeout,
}) async {
String? packageId;
if (interfaceType == IOSDeviceConnectionInterface.network &&
if (isWirelesslyConnected &&
debuggingOptions.debuggingEnabled &&
debuggingOptions.disablePortPublication) {
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 {
route,
platformArgs,
ipv6: ipv6,
interfaceType: interfaceType,
interfaceType: connectionInterface,
);
Status startAppStatus = _logger.startProgress(
'Installing and launching...',
......@@ -371,7 +372,7 @@ class IOSDevice extends Device {
bundlePath: bundle.path,
appDeltaDirectory: package.appDeltaDirectory,
launchArguments: launchArguments,
interfaceType: interfaceType,
interfaceType: connectionInterface,
uninstallFirst: debuggingOptions.uninstallFirst,
);
if (deviceLogReader is IOSDeviceLogReader) {
......@@ -381,7 +382,7 @@ class IOSDevice extends Device {
// Don't port foward if debugging with a network device.
vmServiceDiscovery = ProtocolDiscovery.vmService(
deviceLogReader,
portForwarder: interfaceType == IOSDeviceConnectionInterface.network ? null : portForwarder,
portForwarder: isWirelesslyConnected ? null : portForwarder,
hostPort: debuggingOptions.hostVmServicePort,
devicePort: debuggingOptions.deviceVmServicePort,
ipv6: ipv6,
......@@ -394,7 +395,7 @@ class IOSDevice extends Device {
bundlePath: bundle.path,
appDeltaDirectory: package.appDeltaDirectory,
launchArguments: launchArguments,
interfaceType: interfaceType,
interfaceType: connectionInterface,
uninstallFirst: debuggingOptions.uninstallFirst,
);
} else {
......@@ -414,13 +415,13 @@ class IOSDevice extends Device {
_logger.printTrace('Application launched on the device. Waiting for Dart VM Service url.');
final int defaultTimeout = interfaceType == IOSDeviceConnectionInterface.network ? 45 : 30;
final int defaultTimeout = isWirelesslyConnected ? 45 : 30;
final Timer timer = Timer(discoveryTimeout ?? Duration(seconds: defaultTimeout), () {
_logger.printError('The Dart VM Service was not discovered after $defaultTimeout seconds. This is taking much longer than expected...');
// If debugging with a wireless device and the timeout is reached, remind the
// user to allow local network permissions.
if (interfaceType == IOSDeviceConnectionInterface.network) {
if (isWirelesslyConnected) {
_logger.printError(
'\nClick "Allow" to the prompt asking if you would like to find and connect devices on your local network. '
'This is required for wireless debugging. If you selected "Don\'t Allow", '
......@@ -433,7 +434,7 @@ class IOSDevice extends Device {
});
Uri? localUri;
if (interfaceType == IOSDeviceConnectionInterface.network) {
if (isWirelesslyConnected) {
// Wait for Dart VM Service to start up.
final Uri? serviceURL = await vmServiceDiscovery?.uri;
if (serviceURL == null) {
......@@ -538,7 +539,7 @@ class IOSDevice extends Device {
@override
Future<void> takeScreenshot(File outputFile) async {
await _iMobileDevice.takeScreenshot(outputFile, id, interfaceType);
await _iMobileDevice.takeScreenshot(outputFile, id, connectionInterface);
}
@override
......
......@@ -15,8 +15,8 @@ import '../base/platform.dart';
import '../base/process.dart';
import '../cache.dart';
import '../convert.dart';
import '../device.dart';
import 'code_signing.dart';
import 'iproxy.dart';
// Error message patterns from ios-deploy output
const String noProvisioningProfileErrorOne = 'Error 0xe8008015';
......@@ -88,7 +88,7 @@ class IOSDeploy {
required String deviceId,
required String bundlePath,
required List<String>launchArguments,
required IOSDeviceConnectionInterface interfaceType,
required DeviceConnectionInterface interfaceType,
Directory? appDeltaDirectory,
}) async {
appDeltaDirectory?.createSync(recursive: true);
......@@ -102,7 +102,7 @@ class IOSDeploy {
'--app_deltas',
appDeltaDirectory.path,
],
if (interfaceType != IOSDeviceConnectionInterface.network)
if (interfaceType != DeviceConnectionInterface.wireless)
'--no-wifi',
if (launchArguments.isNotEmpty) ...<String>[
'--args',
......@@ -126,7 +126,7 @@ class IOSDeploy {
required String deviceId,
required String bundlePath,
required List<String> launchArguments,
required IOSDeviceConnectionInterface interfaceType,
required DeviceConnectionInterface interfaceType,
Directory? appDeltaDirectory,
required bool uninstallFirst,
}) {
......@@ -149,7 +149,7 @@ class IOSDeploy {
if (uninstallFirst)
'--uninstall',
'--debug',
if (interfaceType != IOSDeviceConnectionInterface.network)
if (interfaceType != DeviceConnectionInterface.wireless)
'--no-wifi',
if (launchArguments.isNotEmpty) ...<String>[
'--args',
......@@ -171,7 +171,7 @@ class IOSDeploy {
required String deviceId,
required String bundlePath,
required List<String> launchArguments,
required IOSDeviceConnectionInterface interfaceType,
required DeviceConnectionInterface interfaceType,
required bool uninstallFirst,
Directory? appDeltaDirectory,
}) async {
......@@ -186,7 +186,7 @@ class IOSDeploy {
'--app_deltas',
appDeltaDirectory.path,
],
if (interfaceType != IOSDeviceConnectionInterface.network)
if (interfaceType != DeviceConnectionInterface.wireless)
'--no-wifi',
if (uninstallFirst)
'--uninstall',
......
......@@ -8,12 +8,6 @@ import '../base/io.dart';
import '../base/logger.dart';
import '../base/process.dart';
enum IOSDeviceConnectionInterface {
none,
usb,
network,
}
/// Wraps iproxy command line tool port forwarding.
///
/// See https://github.com/libimobiledevice/libusbmuxd.
......
......@@ -16,6 +16,7 @@ import '../base/project_migrator.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
import '../device.dart';
import '../flutter_manifest.dart';
import '../globals.dart' as globals;
import '../macos/cocoapod_utils.dart';
......@@ -27,7 +28,6 @@ import '../project.dart';
import '../reporting/reporting.dart';
import 'application_package.dart';
import 'code_signing.dart';
import 'iproxy.dart';
import 'migrations/host_app_info_plist_migration.dart';
import 'migrations/ios_deployment_target_migration.dart';
import 'migrations/project_base_configuration_migration.dart';
......@@ -87,7 +87,7 @@ class IMobileDevice {
Future<void> takeScreenshot(
File outputFile,
String deviceID,
IOSDeviceConnectionInterface interfaceType,
DeviceConnectionInterface interfaceType,
) {
return _processUtils.run(
<String>[
......@@ -95,7 +95,7 @@ class IMobileDevice {
outputFile.path,
'--udid',
deviceID,
if (interfaceType == IOSDeviceConnectionInterface.network)
if (interfaceType == DeviceConnectionInterface.wireless)
'--network',
],
throwOnError: true,
......
......@@ -14,6 +14,7 @@ import '../base/process.dart';
import '../build_info.dart';
import '../cache.dart';
import '../convert.dart';
import '../device.dart';
import '../globals.dart' as globals;
import '../ios/devices.dart';
import '../ios/ios_deploy.dart';
......@@ -303,8 +304,6 @@ class XCDevice {
}
}
final IOSDeviceConnectionInterface interface = _interfaceType(device);
String? sdkVersion = _sdkVersion(device);
if (sdkVersion != null) {
......@@ -318,7 +317,7 @@ class XCDevice {
identifier,
name: name,
cpuArchitecture: _cpuArchitecture(device),
interfaceType: interface,
connectionInterface: _interfaceType(device),
sdkVersion: sdkVersion,
iProxy: _iProxy,
fileSystem: globals.fs,
......@@ -356,19 +355,16 @@ class XCDevice {
return code is int ? code : null;
}
static IOSDeviceConnectionInterface _interfaceType(Map<String, Object?> deviceProperties) {
// Interface can be "usb", "network", or "none" for simulators
// and unknown future interfaces.
static DeviceConnectionInterface _interfaceType(Map<String, Object?> deviceProperties) {
// Interface can be "usb" or "network". It can also be missing
// (e.g. simulators do not have an interface property).
// If the interface is "network", use `DeviceConnectionInterface.wireless`,
// otherwise use `DeviceConnectionInterface.attached.
final Object? interface = deviceProperties['interface'];
if (interface is String) {
if (interface.toLowerCase() == 'network') {
return IOSDeviceConnectionInterface.network;
} else {
return IOSDeviceConnectionInterface.usb;
}
if (interface is String && interface.toLowerCase() == 'network') {
return DeviceConnectionInterface.wireless;
}
return IOSDeviceConnectionInterface.none;
return DeviceConnectionInterface.attached;
}
static String? _sdkVersion(Map<String, Object?> deviceProperties) {
......
......@@ -23,7 +23,6 @@ import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/device_port_forwarder.dart';
import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
import 'package:flutter_tools/src/macos/macos_ipad_device.dart';
import 'package:flutter_tools/src/mdns_discovery.dart';
import 'package:flutter_tools/src/project.dart';
......@@ -241,7 +240,7 @@ void main() {
logReader: fakeLogReader,
portForwarder: portForwarder,
majorSdkVersion: 16,
interfaceType: IOSDeviceConnectionInterface.network,
connectionInterface: DeviceConnectionInterface.wireless,
);
testDeviceManager.devices = <Device>[device];
final FakeHotRunner hotRunner = FakeHotRunner();
......@@ -313,7 +312,7 @@ void main() {
logReader: fakeLogReader,
portForwarder: portForwarder,
majorSdkVersion: 16,
interfaceType: IOSDeviceConnectionInterface.network,
connectionInterface: DeviceConnectionInterface.wireless,
);
testDeviceManager.devices = <Device>[device];
final FakeHotRunner hotRunner = FakeHotRunner();
......@@ -389,7 +388,7 @@ void main() {
logReader: fakeLogReader,
portForwarder: portForwarder,
majorSdkVersion: 16,
interfaceType: IOSDeviceConnectionInterface.network,
connectionInterface: DeviceConnectionInterface.wireless,
);
testDeviceManager.devices = <Device>[device];
final FakeHotRunner hotRunner = FakeHotRunner();
......@@ -1237,6 +1236,10 @@ class FakeAndroidDevice extends Fake implements AndroidDevice {
@override
Future<TargetPlatform> get targetPlatform async => TargetPlatform.android_arm;
@override
DeviceConnectionInterface get connectionInterface =>
DeviceConnectionInterface.attached;
@override
bool isSupported() => true;
......@@ -1291,7 +1294,7 @@ class FakeIOSDevice extends Fake implements IOSDevice {
DevicePortForwarder? portForwarder,
DeviceLogReader? logReader,
this.onGetLogReader,
this.interfaceType = IOSDeviceConnectionInterface.none,
this.connectionInterface = DeviceConnectionInterface.attached,
this.majorSdkVersion = 0,
}) : _portForwarder = portForwarder, _logReader = logReader;
......@@ -1300,7 +1303,11 @@ class FakeIOSDevice extends Fake implements IOSDevice {
int majorSdkVersion;
@override
final IOSDeviceConnectionInterface interfaceType;
final DeviceConnectionInterface connectionInterface;
@override
bool get isWirelesslyConnected =>
connectionInterface == DeviceConnectionInterface.wireless;
@override
DevicePortForwarder get portForwarder => _portForwarder!;
......
......@@ -6,12 +6,12 @@ import 'dart:convert';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/devices.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/fake_devices.dart';
import '../../src/test_flutter_command_runner.dart';
......@@ -23,9 +23,11 @@ void main() {
});
late Cache cache;
late Platform platform;
setUp(() {
cache = Cache.test(processManager: FakeProcessManager.any());
platform = FakePlatform();
});
testUsingContext('returns 0 when called', () async {
......@@ -39,7 +41,16 @@ void main() {
testUsingContext('no error when no connected devices', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices']);
expect(testLogger.statusText, containsIgnoringWhitespace('No devices detected'));
expect(
testLogger.statusText,
equals('''
No devices detected.
Run "flutter emulators" to list and start any available device emulators.
If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. You may also try increasing the time to wait for connected devices with the --device-timeout flag. Visit https://flutter.dev/setup/ for troubleshooting tips.
'''),
);
}, overrides: <Type, Generator>{
AndroidSdk: () => null,
DeviceManager: () => NoDevicesManager(),
......@@ -48,94 +59,143 @@ void main() {
Artifacts: () => Artifacts.test(),
});
testUsingContext("get devices' platform types", () async {
final List<String> platformTypes = Device.devicesPlatformTypes(
await globals.deviceManager!.getAllDevices(),
);
expect(platformTypes, <String>['android', 'web']);
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(),
ProcessManager: () => FakeProcessManager.any(),
Cache: () => cache,
Artifacts: () => Artifacts.test(),
});
group('when includes both attached and wireless devices', () {
List<FakeDeviceJsonData>? deviceList;
setUp(() {
deviceList = <FakeDeviceJsonData>[
fakeDevices[0],
fakeDevices[1],
fakeDevices[2],
];
});
testUsingContext("get devices' platform types", () async {
final List<String> platformTypes = Device.devicesPlatformTypes(
await globals.deviceManager!.getAllDevices(),
);
expect(platformTypes, <String>['android', 'web']);
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Cache: () => cache,
Artifacts: () => Artifacts.test(),
Platform: () => platform,
});
testUsingContext('Outputs parsable JSON with --machine flag', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--machine']);
expect(
json.decode(testLogger.statusText),
<Map<String, Object>>[
fakeDevices[0].json,
fakeDevices[1].json,
fakeDevices[2].json,
],
);
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Cache: () => cache,
Artifacts: () => Artifacts.test(),
Platform: () => platform,
});
testUsingContext('available devices and diagnostics', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices']);
expect(testLogger.statusText, '''
2 connected devices:
testUsingContext('Outputs parsable JSON with --machine flag', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--machine']);
expect(
json.decode(testLogger.statusText),
<Map<String,Object>>[
<String, Object>{
'name': 'ephemeral',
'id': 'ephemeral',
'isSupported': true,
'targetPlatform': 'android-arm',
'emulator': true,
'sdk': 'Test SDK (1.2.3)',
'capabilities': <String, Object>{
'hotReload': true,
'hotRestart': true,
'screenshot': false,
'fastStart': false,
'flutterExit': true,
'hardwareRendering': true,
'startPaused': true,
},
},
<String,Object>{
'name': 'webby',
'id': 'webby',
'isSupported': true,
'targetPlatform': 'web-javascript',
'emulator': true,
'sdk': 'Web SDK (1.2.4)',
'capabilities': <String, Object>{
'hotReload': true,
'hotRestart': true,
'screenshot': false,
'fastStart': false,
'flutterExit': true,
'hardwareRendering': true,
'startPaused': true,
},
},
],
);
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(),
ProcessManager: () => FakeProcessManager.any(),
Cache: () => cache,
Artifacts: () => Artifacts.test(),
ephemeral (mobile) • ephemeral • android-arm • Test SDK (1.2.3) (emulator)
webby (mobile) • webby • web-javascript • Web SDK (1.2.4) (emulator)
1 wirelessly connected device:
wireless android (mobile) • wireless-android • android-arm • Test SDK (1.2.3) (emulator)
• Cannot connect to device ABC
''');
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform,
});
});
testUsingContext('available devices and diagnostics', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices']);
expect(
testLogger.statusText,
'''
group('when includes only attached devices', () {
List<FakeDeviceJsonData>? deviceList;
setUp(() {
deviceList = <FakeDeviceJsonData>[
fakeDevices[0],
fakeDevices[1],
];
});
testUsingContext('available devices and diagnostics', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices']);
expect(testLogger.statusText, '''
2 connected devices:
ephemeral (mobile) • ephemeral • android-arm • Test SDK (1.2.3) (emulator)
webby (mobile) • webby • web-javascript • Web SDK (1.2.4) (emulator)
• Cannot connect to device ABC
'''
);
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(),
ProcessManager: () => FakeProcessManager.any(),
''');
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform,
});
});
group('when includes only wireless devices', () {
List<FakeDeviceJsonData>? deviceList;
setUp(() {
deviceList = <FakeDeviceJsonData>[
fakeDevices[2],
];
});
testUsingContext('available devices and diagnostics', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices']);
expect(testLogger.statusText, '''
1 wirelessly connected device:
wireless android (mobile) • wireless-android • android-arm • Test SDK (1.2.3) (emulator)
• Cannot connect to device ABC
''');
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform,
});
});
});
}
class _FakeDeviceManager extends DeviceManager {
_FakeDeviceManager() : super(logger: testLogger);
_FakeDeviceManager({
List<FakeDeviceJsonData>? devices,
}) : fakeDevices = devices ?? <FakeDeviceJsonData>[],
super(logger: testLogger);
List<FakeDeviceJsonData> fakeDevices = <FakeDeviceJsonData>[];
@override
Future<List<Device>> getAllDevices({DeviceDiscoveryFilter? filter}) =>
Future<List<Device>>.value(fakeDevices.map((FakeDeviceJsonData d) => d.dev).toList());
Future<List<Device>> getAllDevices({DeviceDiscoveryFilter? filter}) async {
final List<Device> devices = <Device>[];
for (final FakeDeviceJsonData deviceJson in fakeDevices) {
if (filter?.deviceConnectionInterface == null ||
deviceJson.dev.connectionInterface == filter?.deviceConnectionInterface) {
devices.add(deviceJson.dev);
}
}
return devices;
}
@override
Future<List<Device>> refreshAllDevices({
......
......@@ -22,7 +22,6 @@ import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/drive/drive_service.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:package_config/package_config.dart';
import 'package:test/fake.dart';
......@@ -68,7 +67,7 @@ void main() {
final Device screenshotDevice = ThrowingScreenshotDevice()
..supportsScreenshot = false;
fakeDeviceManager.devices = <Device>[screenshotDevice];
fakeDeviceManager.attachedDevices = <Device>[screenshotDevice];
await expectLater(() => createTestCommandRunner(command).run(
<String>[
......@@ -104,7 +103,7 @@ void main() {
fileSystem.directory('drive_screenshots').createSync();
final Device screenshotDevice = ThrowingScreenshotDevice();
fakeDeviceManager.devices = <Device>[screenshotDevice];
fakeDeviceManager.attachedDevices = <Device>[screenshotDevice];
await expectLater(() => createTestCommandRunner(command).run(
<String>[
......@@ -142,7 +141,7 @@ void main() {
fileSystem.directory('drive_screenshots').createSync();
final Device screenshotDevice = ScreenshotDevice();
fakeDeviceManager.devices = <Device>[screenshotDevice];
fakeDeviceManager.attachedDevices = <Device>[screenshotDevice];
await expectLater(() => createTestCommandRunner(command).run(
<String>[
......@@ -184,7 +183,7 @@ void main() {
fileSystem.file('drive_screenshots').createSync();
final Device screenshotDevice = ThrowingScreenshotDevice();
fakeDeviceManager.devices = <Device>[screenshotDevice];
fakeDeviceManager.attachedDevices = <Device>[screenshotDevice];
await expectLater(() => createTestCommandRunner(command).run(
<String>[
......@@ -222,7 +221,7 @@ void main() {
fileSystem.directory('drive_screenshots').createSync();
final ScreenshotDevice screenshotDevice = ScreenshotDevice();
fakeDeviceManager.devices = <Device>[screenshotDevice];
fakeDeviceManager.attachedDevices = <Device>[screenshotDevice];
expect(screenshotDevice.screenshots, isEmpty);
bool caughtToolExit = false;
......@@ -293,7 +292,7 @@ void main() {
fileSystem.directory('drive_screenshots').createSync();
final ScreenshotDevice screenshotDevice = ScreenshotDevice();
fakeDeviceManager.devices = <Device>[screenshotDevice];
fakeDeviceManager.attachedDevices = <Device>[screenshotDevice];
expect(screenshotDevice.screenshots, isEmpty);
......@@ -423,8 +422,8 @@ void main() {
fileSystem.file('pubspec.yaml').createSync();
final Device networkDevice = FakeIosDevice()
..interfaceType = IOSDeviceConnectionInterface.network;
fakeDeviceManager.devices = <Device>[networkDevice];
..connectionInterface = DeviceConnectionInterface.wireless;
fakeDeviceManager.wirelessDevices = <Device>[networkDevice];
await expectLater(() => createTestCommandRunner(command).run(<String>[
'drive',
......@@ -456,8 +455,8 @@ void main() {
]), throwsToolExit());
final Device usbDevice = FakeIosDevice()
..interfaceType = IOSDeviceConnectionInterface.usb;
fakeDeviceManager.devices = <Device>[usbDevice];
..connectionInterface = DeviceConnectionInterface.attached;
fakeDeviceManager.attachedDevices = <Device>[usbDevice];
final DebuggingOptions options = await command.createDebuggingOptions(false);
expect(options.disablePortPublication, true);
......@@ -481,8 +480,8 @@ void main() {
fileSystem.file('pubspec.yaml').createSync();
final Device networkDevice = FakeIosDevice()
..interfaceType = IOSDeviceConnectionInterface.network;
fakeDeviceManager.devices = <Device>[networkDevice];
..connectionInterface = DeviceConnectionInterface.wireless;
fakeDeviceManager.wirelessDevices = <Device>[networkDevice];
await expectLater(() => createTestCommandRunner(command).run(<String>[
'drive',
......@@ -661,7 +660,11 @@ class FakeProcessSignal extends Fake implements io.ProcessSignal {
// ignore: avoid_implementing_value_types
class FakeIosDevice extends Fake implements IOSDevice {
@override
IOSDeviceConnectionInterface interfaceType = IOSDeviceConnectionInterface.usb;
DeviceConnectionInterface connectionInterface = DeviceConnectionInterface.attached;
@override
bool get isWirelesslyConnected =>
connectionInterface == DeviceConnectionInterface.wireless;
@override
Future<TargetPlatform> get targetPlatform async => TargetPlatform.ios;
......
......@@ -36,7 +36,7 @@ void main() {
command.applicationPackages = FakeApplicationPackageFactory(FakeAndroidApk());
final FakeAndroidDevice device = FakeAndroidDevice();
testDeviceManager.addDevice(device);
testDeviceManager.addAttachedDevice(device);
await createTestCommandRunner(command).run(<String>['install']);
}, overrides: <Type, Generator>{
......@@ -50,7 +50,7 @@ void main() {
command.applicationPackages = FakeApplicationPackageFactory(FakeAndroidApk());
final FakeIOSDevice device = FakeIOSDevice();
testDeviceManager.addDevice(device);
testDeviceManager.addAttachedDevice(device);
expect(() async => createTestCommandRunner(command).run(<String>['install', '--device-user', '10']),
throwsToolExit(message: '--device-user is only supported for Android'));
......@@ -65,7 +65,7 @@ void main() {
command.applicationPackages = FakeApplicationPackageFactory(FakeIOSApp());
final FakeIOSDevice device = FakeIOSDevice();
testDeviceManager.addDevice(device);
testDeviceManager.addAttachedDevice(device);
await createTestCommandRunner(command).run(<String>['install']);
}, overrides: <Type, Generator>{
......@@ -79,7 +79,7 @@ void main() {
command.applicationPackages = FakeApplicationPackageFactory(FakeAndroidApk());
final FakeAndroidDevice device = FakeAndroidDevice();
testDeviceManager.addDevice(device);
testDeviceManager.addAttachedDevice(device);
expect(() async => createTestCommandRunner(command).run(<String>['install', '--use-application-binary', 'bogus']),
throwsToolExit(message: 'Prebuilt binary bogus does not exist'));
......@@ -94,7 +94,7 @@ void main() {
command.applicationPackages = FakeApplicationPackageFactory(FakeAndroidApk());
final FakeAndroidDevice device = FakeAndroidDevice();
testDeviceManager.addDevice(device);
testDeviceManager.addAttachedDevice(device);
fileSystem.file('binary').createSync(recursive: true);
await createTestCommandRunner(command).run(<String>['install', '--use-application-binary', 'binary']);
......@@ -111,7 +111,7 @@ void main() {
command.applicationPackages = fakeAppFactory;
final FakeIOSDevice device = FakeIOSDevice();
testDeviceManager.addDevice(device);
testDeviceManager.addAttachedDevice(device);
await createTestCommandRunner(command).run(<String>['install', '--flavor', flavor]);
expect(fakeAppFactory.buildInfo, isNotNull);
......@@ -183,4 +183,7 @@ class FakeAndroidDevice extends Fake implements AndroidDevice {
@override
String get name => 'Android';
@override
bool get ephemeral => true;
}
......@@ -26,7 +26,6 @@ import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/resident_runner.dart';
......@@ -711,7 +710,7 @@ void main() {
testUsingContext('with only iOS usb device', () async {
final List<Device> devices = <Device>[
FakeIOSDevice(interfaceType: IOSDeviceConnectionInterface.usb, sdkNameAndVersion: 'iOS 16.2'),
FakeIOSDevice(sdkNameAndVersion: 'iOS 16.2'),
];
final TestRunCommandForUsageValues command = TestRunCommandForUsageValues(devices: devices);
final CommandRunner<void> runner = createTestCommandRunner(command);
......@@ -752,7 +751,10 @@ void main() {
testUsingContext('with only iOS network device', () async {
final List<Device> devices = <Device>[
FakeIOSDevice(interfaceType: IOSDeviceConnectionInterface.network, sdkNameAndVersion: 'iOS 16.2'),
FakeIOSDevice(
connectionInterface: DeviceConnectionInterface.wireless,
sdkNameAndVersion: 'iOS 16.2',
),
];
final TestRunCommandForUsageValues command = TestRunCommandForUsageValues(devices: devices);
final CommandRunner<void> runner = createTestCommandRunner(command);
......@@ -793,8 +795,11 @@ void main() {
testUsingContext('with both iOS usb and network devices', () async {
final List<Device> devices = <Device>[
FakeIOSDevice(interfaceType: IOSDeviceConnectionInterface.network, sdkNameAndVersion: 'iOS 16.2'),
FakeIOSDevice(interfaceType: IOSDeviceConnectionInterface.usb, sdkNameAndVersion: 'iOS 16.2'),
FakeIOSDevice(
connectionInterface: DeviceConnectionInterface.wireless,
sdkNameAndVersion: 'iOS 16.2',
),
FakeIOSDevice(sdkNameAndVersion: 'iOS 16.2'),
];
final TestRunCommandForUsageValues command = TestRunCommandForUsageValues(devices: devices);
final CommandRunner<void> runner = createTestCommandRunner(command);
......@@ -1126,6 +1131,10 @@ class FakeDevice extends Fake implements Device {
@override
bool get isConnected => true;
@override
DeviceConnectionInterface get connectionInterface =>
DeviceConnectionInterface.attached;
bool supported = true;
@override
......@@ -1209,7 +1218,7 @@ class FakeDevice extends Fake implements Device {
// ignore: avoid_implementing_value_types
class FakeIOSDevice extends Fake implements IOSDevice {
FakeIOSDevice({
this.interfaceType = IOSDeviceConnectionInterface.none,
this.connectionInterface = DeviceConnectionInterface.attached,
bool isLocalEmulator = false,
String sdkNameAndVersion = '',
}): _isLocalEmulator = isLocalEmulator,
......@@ -1225,7 +1234,11 @@ class FakeIOSDevice extends Fake implements IOSDevice {
Future<String> get sdkNameAndVersion => Future<String>.value(_sdkNameAndVersion);
@override
final IOSDeviceConnectionInterface interfaceType;
final DeviceConnectionInterface connectionInterface;
@override
bool get isWirelesslyConnected =>
connectionInterface == DeviceConnectionInterface.wireless;
@override
Future<TargetPlatform> get targetPlatform async => TargetPlatform.ios;
......
......@@ -922,8 +922,15 @@ class _FakeDeviceManager extends DeviceManager {
@override
Future<List<Device>> getAllDevices({
DeviceDiscoveryFilter? filter,
}) async => _connectedDevices;
}) async => filteredDevices(filter);
@override
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];
List<Device> filteredDevices(DeviceDiscoveryFilter? filter) {
if (filter?.deviceConnectionInterface == DeviceConnectionInterface.wireless) {
return <Device>[];
}
return _connectedDevices;
}
}
......@@ -87,6 +87,13 @@ class FakeDeviceManager extends Fake implements DeviceManager {
@override
String? specifiedDeviceId;
@override
Future<List<Device>> getAllDevices({
DeviceDiscoveryFilter? filter,
}) async {
return devices;
}
@override
Future<List<Device>> refreshAllDevices({
Duration? timeout,
......
......@@ -122,7 +122,7 @@ void main() {
expect(androidDevices.supportsPlatform, false);
});
testWithoutContext('AndroidDevices can parse output for physical devices', () async {
testWithoutContext('AndroidDevices can parse output for physical attached devices', () async {
final AndroidDevices androidDevices = AndroidDevices(
userMessages: UserMessages(),
androidWorkflow: androidWorkflow,
......@@ -147,6 +147,35 @@ List of devices attached
expect(devices, hasLength(1));
expect(devices.first.name, 'Nexus 7');
expect(devices.first.category, Category.mobile);
expect(devices.first.connectionInterface, DeviceConnectionInterface.attached);
});
testWithoutContext('AndroidDevices can parse output for physical wireless devices', () async {
final AndroidDevices androidDevices = AndroidDevices(
userMessages: UserMessages(),
androidWorkflow: androidWorkflow,
androidSdk: FakeAndroidSdk(),
logger: BufferLogger.test(),
processManager: FakeProcessManager.list(<FakeCommand>[
const FakeCommand(
command: <String>['adb', 'devices', '-l'],
stdout: '''
List of devices attached
05a02bac._adb-tls-connect._tcp. device product:razor model:Nexus_7 device:flo
''',
),
]),
platform: FakePlatform(),
fileSystem: MemoryFileSystem.test(),
);
final List<Device> devices = await androidDevices.pollingGetDevices();
expect(devices, hasLength(1));
expect(devices.first.name, 'Nexus 7');
expect(devices.first.category, Category.mobile);
expect(devices.first.connectionInterface, DeviceConnectionInterface.wireless);
});
testWithoutContext('AndroidDevices can parse output for emulators and short listings', () async {
......
......@@ -11,7 +11,6 @@ import 'package:flutter_tools/src/base/utils.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:test/fake.dart';
......@@ -832,7 +831,7 @@ void main() {
EnvironmentType.physical,
null,
<String, Object?>{},
interfaceType: IOSDeviceConnectionInterface.network,
interfaceType: DeviceConnectionInterface.wireless,
);
expect(
......@@ -856,7 +855,7 @@ void main() {
null,
<String, Object?>{},
ipv6: true,
interfaceType: IOSDeviceConnectionInterface.network,
interfaceType: DeviceConnectionInterface.wireless,
);
expect(
......
......@@ -74,7 +74,7 @@ void main() {
name: 'iPhone 1',
sdkVersion: '13.3',
cpuArchitecture: DarwinArch.arm64,
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
);
expect(device.isSupported(), isTrue);
});
......@@ -90,7 +90,7 @@ void main() {
iMobileDevice: iMobileDevice,
name: 'iPhone 1',
cpuArchitecture: DarwinArch.armv7,
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
);
expect(device.isSupported(), isFalse);
});
......@@ -107,7 +107,7 @@ void main() {
name: 'iPhone 1',
cpuArchitecture: DarwinArch.arm64,
sdkVersion: '1.0.0',
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
).majorSdkVersion, 1);
expect(IOSDevice(
'device-123',
......@@ -120,7 +120,7 @@ void main() {
name: 'iPhone 1',
cpuArchitecture: DarwinArch.arm64,
sdkVersion: '13.1.1',
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
).majorSdkVersion, 13);
expect(IOSDevice(
'device-123',
......@@ -133,7 +133,7 @@ void main() {
name: 'iPhone 1',
cpuArchitecture: DarwinArch.arm64,
sdkVersion: '10',
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
).majorSdkVersion, 10);
expect(IOSDevice(
'device-123',
......@@ -146,7 +146,7 @@ void main() {
name: 'iPhone 1',
cpuArchitecture: DarwinArch.arm64,
sdkVersion: '0',
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
).majorSdkVersion, 0);
expect(IOSDevice(
'device-123',
......@@ -159,7 +159,7 @@ void main() {
name: 'iPhone 1',
cpuArchitecture: DarwinArch.arm64,
sdkVersion: 'bogus',
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
).majorSdkVersion, 0);
});
......@@ -175,7 +175,7 @@ void main() {
name: 'iPhone 1',
sdkVersion: '13.3 17C54',
cpuArchitecture: DarwinArch.arm64,
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
);
expect(await device.sdkNameAndVersion,'iOS 13.3 17C54');
......@@ -193,7 +193,7 @@ void main() {
name: 'iPhone 1',
sdkVersion: '13.3',
cpuArchitecture: DarwinArch.arm64,
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
);
expect(device.supportsRuntimeMode(BuildMode.debug), true);
......@@ -217,7 +217,7 @@ void main() {
name: 'iPhone 1',
sdkVersion: '13.3',
cpuArchitecture: DarwinArch.arm64,
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
);
},
throwsAssertionError,
......@@ -307,7 +307,7 @@ void main() {
name: 'iPhone 1',
sdkVersion: '13.3',
cpuArchitecture: DarwinArch.arm64,
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
);
logReader1 = createLogReader(device, appPackage1, process1);
logReader2 = createLogReader(device, appPackage2, process2);
......@@ -368,7 +368,7 @@ void main() {
logger: logger,
platform: macPlatform,
fileSystem: MemoryFileSystem.test(),
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
);
device2 = IOSDevice(
......@@ -382,7 +382,7 @@ void main() {
logger: logger,
platform: macPlatform,
fileSystem: MemoryFileSystem.test(),
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
);
});
......
......@@ -12,8 +12,8 @@ import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
import '../../src/common.dart';
import '../../src/fake_process_manager.dart';
......@@ -73,7 +73,7 @@ void main () {
bundlePath: '/',
appDeltaDirectory: appDeltaDirectory,
launchArguments: <String>['--enable-dart-profiling'],
interfaceType: IOSDeviceConnectionInterface.network,
interfaceType: DeviceConnectionInterface.wireless,
uninstallFirst: true,
);
......
......@@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
......@@ -62,7 +63,7 @@ void main() {
final IOSDevice device = setUpIOSDevice(
processManager: processManager,
fileSystem: fileSystem,
interfaceType: IOSDeviceConnectionInterface.usb,
interfaceType: DeviceConnectionInterface.attached,
artifacts: artifacts,
);
final bool wasInstalled = await device.installApp(iosApp);
......@@ -95,7 +96,7 @@ void main() {
final IOSDevice device = setUpIOSDevice(
processManager: processManager,
fileSystem: fileSystem,
interfaceType: IOSDeviceConnectionInterface.network,
interfaceType: DeviceConnectionInterface.wireless,
artifacts: artifacts,
);
final bool wasInstalled = await device.installApp(iosApp);
......@@ -319,7 +320,7 @@ IOSDevice setUpIOSDevice({
required ProcessManager processManager,
FileSystem? fileSystem,
Logger? logger,
IOSDeviceConnectionInterface? interfaceType,
DeviceConnectionInterface? interfaceType,
Artifacts? artifacts,
}) {
logger ??= BufferLogger.test();
......@@ -357,6 +358,6 @@ IOSDevice setUpIOSDevice({
cache: cache,
),
iProxy: IProxy.test(logger: logger, processManager: processManager),
interfaceType: interfaceType ?? IOSDeviceConnectionInterface.usb,
connectionInterface: interfaceType ?? DeviceConnectionInterface.attached,
);
}
......@@ -9,6 +9,7 @@ import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
......@@ -98,6 +99,6 @@ IOSDevice setUpIOSDevice(FileSystem fileSystem) {
sdkVersion: '13.3',
cpuArchitecture: DarwinArch.arm64,
iProxy: IProxy.test(logger: logger, processManager: processManager),
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
);
}
......@@ -337,7 +337,7 @@ IOSDevice setUpIOSDevice({
cache: cache,
),
cpuArchitecture: DarwinArch.arm64,
interfaceType: IOSDeviceConnectionInterface.usb,
connectionInterface: DeviceConnectionInterface.attached,
);
}
......
......@@ -250,7 +250,7 @@ void main() {
processManager: processManager,
fileSystem: fileSystem,
logger: logger,
interfaceType: IOSDeviceConnectionInterface.network,
interfaceType: DeviceConnectionInterface.wireless,
);
final IOSApp iosApp = PrebuiltIOSApp(
projectBundleId: 'app',
......@@ -560,7 +560,7 @@ IOSDevice setUpIOSDevice({
Logger? logger,
ProcessManager? processManager,
IOSDeploy? iosDeploy,
IOSDeviceConnectionInterface interfaceType = IOSDeviceConnectionInterface.usb,
DeviceConnectionInterface interfaceType = DeviceConnectionInterface.attached,
}) {
final Artifacts artifacts = Artifacts.test();
final FakePlatform macPlatform = FakePlatform(
......@@ -598,7 +598,7 @@ IOSDevice setUpIOSDevice({
cache: cache,
),
cpuArchitecture: DarwinArch.arm64,
interfaceType: interfaceType,
connectionInterface: interfaceType,
);
}
......
......@@ -10,8 +10,8 @@ import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/code_signing.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
import 'package:flutter_tools/src/ios/mac.dart';
import 'package:flutter_tools/src/ios/xcresult.dart';
import 'package:flutter_tools/src/project.dart';
......@@ -77,7 +77,7 @@ void main() {
expect(() async => iMobileDevice.takeScreenshot(
outputFile,
'1234',
IOSDeviceConnectionInterface.usb,
DeviceConnectionInterface.attached,
), throwsA(anything));
expect(fakeProcessManager, hasNoRemainingExpectations);
});
......@@ -100,7 +100,7 @@ void main() {
await iMobileDevice.takeScreenshot(
outputFile,
'1234',
IOSDeviceConnectionInterface.usb,
DeviceConnectionInterface.attached,
);
expect(fakeProcessManager, hasNoRemainingExpectations);
});
......@@ -123,7 +123,7 @@ void main() {
await iMobileDevice.takeScreenshot(
outputFile,
'1234',
IOSDeviceConnectionInterface.network,
DeviceConnectionInterface.wireless,
);
expect(fakeProcessManager, hasNoRemainingExpectations);
});
......
......@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
......@@ -480,22 +481,31 @@ void main() {
));
final List<IOSDevice> devices = await xcdevice.getAvailableIOSDevices();
expect(devices, hasLength(4));
expect(devices[0].id, '00008027-00192736010F802E');
expect(devices[0].name, 'An iPhone (Space Gray)');
expect(await devices[0].sdkNameAndVersion, 'iOS 13.3 17C54');
expect(devices[0].cpuArchitecture, DarwinArch.arm64);
expect(devices[0].connectionInterface, DeviceConnectionInterface.attached);
expect(devices[1].id, '98206e7a4afd4aedaff06e687594e089dede3c44');
expect(devices[1].name, 'iPad 1');
expect(await devices[1].sdkNameAndVersion, 'iOS 10.1 14C54');
expect(devices[1].cpuArchitecture, DarwinArch.armv7);
expect(devices[1].connectionInterface, DeviceConnectionInterface.attached);
expect(devices[2].id, '234234234234234234345445687594e089dede3c44');
expect(devices[2].name, 'A networked iPad');
expect(await devices[2].sdkNameAndVersion, 'iOS 10.1 14C54');
expect(devices[2].cpuArchitecture, DarwinArch.arm64); // Defaults to arm64 for unknown architecture.
expect(devices[2].connectionInterface, DeviceConnectionInterface.wireless);
expect(devices[3].id, 'f577a7903cc54959be2e34bc4f7f80b7009efcf4');
expect(devices[3].name, 'iPad 2');
expect(await devices[3].sdkNameAndVersion, 'iOS 10.1 14C54');
expect(devices[3].cpuArchitecture, DarwinArch.arm64); // Defaults to arm64 for unknown architecture.
expect(devices[3].connectionInterface, DeviceConnectionInterface.attached);
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
Platform: () => macPlatform,
......
......@@ -705,15 +705,15 @@ void main() {
});
testUsingContext('finds single device', () async {
testDeviceManager.addDevice(device1);
testDeviceManager.addAttachedDevice(device1);
final DummyFlutterCommand flutterCommand = DummyFlutterCommand();
final Device? device = await flutterCommand.findTargetDevice();
expect(device, device1);
});
testUsingContext('finds multiple devices', () async {
testDeviceManager.addDevice(device1);
testDeviceManager.addDevice(device2);
testDeviceManager.addAttachedDevice(device1);
testDeviceManager.addAttachedDevice(device2);
testDeviceManager.specifiedDeviceId = 'all';
final DummyFlutterCommand flutterCommand = DummyFlutterCommand();
final Device? device = await flutterCommand.findTargetDevice();
......
......@@ -181,7 +181,8 @@ void _printBufferedErrors(AppContext testContext) {
}
class FakeDeviceManager implements DeviceManager {
List<Device> devices = <Device>[];
List<Device> attachedDevices = <Device>[];
List<Device> wirelessDevices = <Device>[];
String? _specifiedDeviceId;
......@@ -209,20 +210,20 @@ class FakeDeviceManager implements DeviceManager {
@override
Future<List<Device>> getAllDevices({
DeviceDiscoveryFilter? filter,
}) async => devices;
}) async => filteredDevices(filter);
@override
Future<List<Device>> refreshAllDevices({
Duration? timeout,
DeviceDiscoveryFilter? filter,
}) async => devices;
}) async => filteredDevices(filter);
@override
Future<List<Device>> getDevicesById(
String deviceId, {
DeviceDiscoveryFilter? filter,
}) async {
return devices.where((Device device) {
return filteredDevices(filter).where((Device device) {
return device.id == deviceId || device.id.startsWith(deviceId);
}).toList();
}
......@@ -236,7 +237,8 @@ class FakeDeviceManager implements DeviceManager {
: getAllDevices(filter: filter);
}
void addDevice(Device device) => devices.add(device);
void addAttachedDevice(Device device) => attachedDevices.add(device);
void addWirelessDevice(Device device) => wirelessDevices.add(device);
@override
bool get canListAnything => true;
......@@ -257,6 +259,16 @@ class FakeDeviceManager implements DeviceManager {
@override
Device? getSingleEphemeralDevice(List<Device> devices) => null;
List<Device> filteredDevices(DeviceDiscoveryFilter? filter) {
if (filter?.deviceConnectionInterface == DeviceConnectionInterface.attached) {
return attachedDevices;
}
if (filter?.deviceConnectionInterface == DeviceConnectionInterface.wireless) {
return wirelessDevices;
}
return attachedDevices + wirelessDevices;
}
}
class TestDeviceDiscoverySupportFilter extends Fake implements DeviceDiscoverySupportFilter {
......
......@@ -54,6 +54,31 @@ List<FakeDeviceJsonData> fakeDevices = <FakeDeviceJsonData>[
},
},
),
FakeDeviceJsonData(
FakeDevice(
'wireless android',
'wireless-android',
type: PlatformType.android,
connectionInterface: DeviceConnectionInterface.wireless,
),
<String, Object>{
'name': 'wireless android',
'id': 'wireless-android',
'isSupported': true,
'targetPlatform': 'android-arm',
'emulator': true,
'sdk': 'Test SDK (1.2.3)',
'capabilities': <String, Object>{
'hotReload': true,
'hotRestart': true,
'screenshot': false,
'fastStart': false,
'flutterExit': true,
'hardwareRendering': true,
'startPaused': true,
},
}
),
];
/// Fake device to test `devices` command.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment