Update device filtering and introduce isConnected and connectionInterface (#121359)
Update device filtering and introduce isConnected and connectionInterface
This commit is contained in:
parent
c590086bcc
commit
cc26a1aa0c
@ -883,7 +883,7 @@ class DeviceDomain extends Domain {
|
||||
Future<List<Map<String, Object?>>> getDevices([ Map<String, Object?>? args ]) async {
|
||||
return <Map<String, Object?>>[
|
||||
for (final PollingDeviceDiscovery discoverer in _discoverers)
|
||||
for (final Device device in await discoverer.devices)
|
||||
for (final Device device in await discoverer.devices())
|
||||
await _deviceToMap(device),
|
||||
];
|
||||
}
|
||||
@ -1069,7 +1069,7 @@ class DeviceDomain extends Domain {
|
||||
/// Return the device matching the deviceId field in the args.
|
||||
Future<Device?> _getDevice(String? deviceId) async {
|
||||
for (final PollingDeviceDiscovery discoverer in _discoverers) {
|
||||
final List<Device> devices = await discoverer.devices;
|
||||
final List<Device> devices = await discoverer.devices();
|
||||
Device? device;
|
||||
for (final Device localDevice in devices) {
|
||||
if (localDevice.id == deviceId) {
|
||||
|
@ -62,7 +62,7 @@ class DevicesCommand extends FlutterCommand {
|
||||
exitCode: 1);
|
||||
}
|
||||
|
||||
final List<Device> devices = await globals.deviceManager?.refreshAllConnectedDevices(timeout: deviceDiscoveryTimeout) ?? <Device>[];
|
||||
final List<Device> devices = await globals.deviceManager?.refreshAllDevices(timeout: deviceDiscoveryTimeout) ?? <Device>[];
|
||||
|
||||
if (boolArgDeprecated('machine')) {
|
||||
await printDevicesAsJson(devices);
|
||||
|
@ -209,7 +209,9 @@ class DriveCommand extends RunCommandBase {
|
||||
String? get applicationBinaryPath => stringArgDeprecated(FlutterOptions.kUseApplicationBinary);
|
||||
|
||||
Future<Device?> get targetedDevice async {
|
||||
return findTargetDevice(includeUnsupportedDevices: applicationBinaryPath == null);
|
||||
return findTargetDevice(
|
||||
includeDevicesUnsupportedByProject: applicationBinaryPath == null,
|
||||
);
|
||||
}
|
||||
|
||||
// Network devices need `publish-port` to be enabled because it requires mDNS.
|
||||
|
@ -36,7 +36,7 @@ class LogsCommand extends FlutterCommand {
|
||||
|
||||
@override
|
||||
Future<FlutterCommandResult> verifyThenRunCommand(String? commandPath) async {
|
||||
device = await findTargetDevice(includeUnsupportedDevices: true);
|
||||
device = await findTargetDevice(includeDevicesUnsupportedByProject: true);
|
||||
if (device == null) {
|
||||
throwToolExit(null);
|
||||
}
|
||||
|
@ -110,7 +110,19 @@ abstract class DeviceManager {
|
||||
/// specifiedDeviceId = 'all'.
|
||||
bool get hasSpecifiedAllDevices => _specifiedDeviceId == 'all';
|
||||
|
||||
Future<List<Device>> getDevicesById(String deviceId) async {
|
||||
/// Get devices filtered by [filter] that match the given device id/name.
|
||||
///
|
||||
/// If [filter] is not provided, a default filter that requires devices to be
|
||||
/// connected will be used.
|
||||
///
|
||||
/// If an exact match is found, return it immediately. Otherwise wait for all
|
||||
/// discoverers to complete and return any partial matches.
|
||||
Future<List<Device>> getDevicesById(
|
||||
String deviceId, {
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async {
|
||||
filter ??= DeviceDiscoveryFilter();
|
||||
|
||||
final String lowerDeviceId = deviceId.toLowerCase();
|
||||
bool exactlyMatchesDeviceId(Device device) =>
|
||||
device.id.toLowerCase() == lowerDeviceId ||
|
||||
@ -135,7 +147,7 @@ abstract class DeviceManager {
|
||||
for (final DeviceDiscovery discoverer in _platformDiscoverers)
|
||||
if (!hasWellKnownId || discoverer.wellKnownIds.contains(specifiedDeviceId))
|
||||
discoverer
|
||||
.devices
|
||||
.devices(filter: filter)
|
||||
.then((List<Device> devices) {
|
||||
for (final Device device in devices) {
|
||||
if (exactlyMatchesDeviceId(device)) {
|
||||
@ -165,34 +177,56 @@ abstract class DeviceManager {
|
||||
return prefixMatches;
|
||||
}
|
||||
|
||||
/// Returns the list of connected devices, filtered by any user-specified device id.
|
||||
Future<List<Device>> getDevices() {
|
||||
/// Returns a list of devices filtered by the user-specified device
|
||||
/// id/name (if applicable) and [filter].
|
||||
///
|
||||
/// If [filter] is not provided, a default filter that requires devices to be
|
||||
/// connected will be used.
|
||||
Future<List<Device>> getDevices({
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) {
|
||||
filter ??= DeviceDiscoveryFilter();
|
||||
final String? id = specifiedDeviceId;
|
||||
if (id == null) {
|
||||
return getAllConnectedDevices();
|
||||
return getAllDevices(filter: filter);
|
||||
}
|
||||
return getDevicesById(id);
|
||||
return getDevicesById(id, filter: filter);
|
||||
}
|
||||
|
||||
Iterable<DeviceDiscovery> get _platformDiscoverers {
|
||||
return deviceDiscoverers.where((DeviceDiscovery discoverer) => discoverer.supportsPlatform);
|
||||
}
|
||||
|
||||
/// Returns the list of all connected devices.
|
||||
Future<List<Device>> getAllConnectedDevices() async {
|
||||
/// Returns a list of devices filtered by [filter].
|
||||
///
|
||||
/// If [filter] is not provided, a default filter that requires devices to be
|
||||
/// connected will be used.
|
||||
Future<List<Device>> getAllDevices({
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async {
|
||||
filter ??= DeviceDiscoveryFilter();
|
||||
final List<List<Device>> devices = await Future.wait<List<Device>>(<Future<List<Device>>>[
|
||||
for (final DeviceDiscovery discoverer in _platformDiscoverers)
|
||||
discoverer.devices,
|
||||
discoverer.devices(filter: filter),
|
||||
]);
|
||||
|
||||
return devices.expand<Device>((List<Device> deviceList) => deviceList).toList();
|
||||
}
|
||||
|
||||
/// Returns the list of all connected devices. Discards existing cache of devices.
|
||||
Future<List<Device>> refreshAllConnectedDevices({ Duration? timeout }) async {
|
||||
/// Returns a list of devices filtered by [filter]. Discards existing cache of devices.
|
||||
///
|
||||
/// If [filter] is not provided, a default filter that requires devices to be
|
||||
/// connected will be used.
|
||||
///
|
||||
/// Search for devices to populate the cache for no longer than [timeout].
|
||||
Future<List<Device>> refreshAllDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async {
|
||||
filter ??= DeviceDiscoveryFilter();
|
||||
final List<List<Device>> devices = await Future.wait<List<Device>>(<Future<List<Device>>>[
|
||||
for (final DeviceDiscovery discoverer in _platformDiscoverers)
|
||||
discoverer.discoverDevices(timeout: timeout),
|
||||
discoverer.discoverDevices(filter: filter, timeout: timeout),
|
||||
]);
|
||||
|
||||
return devices.expand<Device>((List<Device> deviceList) => deviceList).toList();
|
||||
@ -233,45 +267,26 @@ abstract class DeviceManager {
|
||||
/// * If [promptUserToChooseDevice] is true, and there are more than one
|
||||
/// device after the aforementioned filters, and the user is connected to a
|
||||
/// terminal, then show a prompt asking the user to choose one.
|
||||
Future<List<Device>> findTargetDevices(
|
||||
FlutterProject? flutterProject, {
|
||||
Future<List<Device>> findTargetDevices({
|
||||
bool includeDevicesUnsupportedByProject = false,
|
||||
Duration? timeout,
|
||||
}) async {
|
||||
if (timeout != null) {
|
||||
// Reset the cache with the specified timeout.
|
||||
await refreshAllConnectedDevices(timeout: timeout);
|
||||
await refreshAllDevices(timeout: timeout);
|
||||
}
|
||||
|
||||
List<Device> devices = (await getDevices())
|
||||
.where((Device device) => device.isSupported()).toList();
|
||||
final List<Device> devices = await getDevices(
|
||||
filter: DeviceDiscoveryFilter(
|
||||
supportFilter: deviceSupportFilter(
|
||||
includeDevicesUnsupportedByProject: includeDevicesUnsupportedByProject,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (hasSpecifiedAllDevices) {
|
||||
// User has specified `--device all`.
|
||||
//
|
||||
// Always remove web and fuchsia devices from `--all`. This setting
|
||||
// currently requires devices to share a frontend_server and resident
|
||||
// runner instance. Both web and fuchsia require differently configured
|
||||
// compilers, and web requires an entirely different resident runner.
|
||||
devices = <Device>[
|
||||
for (final Device device in devices)
|
||||
if (await device.targetPlatform != TargetPlatform.fuchsia_arm64 &&
|
||||
await device.targetPlatform != TargetPlatform.fuchsia_x64 &&
|
||||
await device.targetPlatform != TargetPlatform.web_javascript &&
|
||||
isDeviceSupportedForProject(device, flutterProject))
|
||||
device,
|
||||
];
|
||||
} else if (!hasSpecifiedDeviceId) {
|
||||
if (!hasSpecifiedDeviceId) {
|
||||
// User did not specify the device.
|
||||
|
||||
// Remove all devices which are not supported by the current application.
|
||||
// For example, if there was no 'android' folder then don't attempt to
|
||||
// launch with an Android device.
|
||||
devices = <Device>[
|
||||
for (final Device device in devices)
|
||||
if (isDeviceSupportedForProject(device, flutterProject))
|
||||
device,
|
||||
];
|
||||
|
||||
if (devices.length > 1) {
|
||||
// If there are still multiple devices and the user did not specify to run
|
||||
// all, then attempt to prioritize ephemeral devices. For example, if the
|
||||
@ -287,7 +302,7 @@ abstract class DeviceManager {
|
||||
];
|
||||
|
||||
if (ephemeralDevices.length == 1) {
|
||||
devices = ephemeralDevices;
|
||||
return ephemeralDevices;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -295,18 +310,166 @@ abstract class DeviceManager {
|
||||
return devices;
|
||||
}
|
||||
|
||||
/// Returns whether the device is supported for the project.
|
||||
/// Determines how to filter devices.
|
||||
///
|
||||
/// This exists to allow the check to be overridden for google3 clients. If
|
||||
/// [flutterProject] is null then return true.
|
||||
bool isDeviceSupportedForProject(Device device, FlutterProject? flutterProject) {
|
||||
if (flutterProject == null) {
|
||||
return true;
|
||||
/// By default, filters to only include devices that are supported by Flutter.
|
||||
///
|
||||
/// If the user has not specificied a device, filters to only include devices
|
||||
/// that are supported by Flutter and supported by the project.
|
||||
///
|
||||
/// If the user has specified `--device all`, filters to only include devices
|
||||
/// that are supported by Flutter, supported by the project, and supported for `all`.
|
||||
///
|
||||
/// If [includeDevicesUnsupportedByProject] is true, all devices will be
|
||||
/// considered supported by the project, regardless of user specifications.
|
||||
///
|
||||
/// This also exists to allow the check to be overridden for google3 clients.
|
||||
DeviceDiscoverySupportFilter deviceSupportFilter({
|
||||
bool includeDevicesUnsupportedByProject = false,
|
||||
}) {
|
||||
FlutterProject? flutterProject;
|
||||
if (includeDevicesUnsupportedByProject == false) {
|
||||
flutterProject = FlutterProject.current();
|
||||
}
|
||||
if (hasSpecifiedAllDevices) {
|
||||
return DeviceDiscoverySupportFilter.excludeDevicesUnsupportedByFlutterOrProjectOrAll(
|
||||
flutterProject: flutterProject,
|
||||
);
|
||||
} else if (!hasSpecifiedDeviceId) {
|
||||
return DeviceDiscoverySupportFilter.excludeDevicesUnsupportedByFlutterOrProject(
|
||||
flutterProject: flutterProject,
|
||||
);
|
||||
} else {
|
||||
return DeviceDiscoverySupportFilter.excludeDevicesUnsupportedByFlutter();
|
||||
}
|
||||
return device.isSupportedForProject(flutterProject);
|
||||
}
|
||||
}
|
||||
|
||||
/// A class for determining how to filter devices based on if they are supported.
|
||||
class DeviceDiscoverySupportFilter {
|
||||
/// Filter devices to only include those supported by Flutter.
|
||||
DeviceDiscoverySupportFilter.excludeDevicesUnsupportedByFlutter()
|
||||
: _excludeDevicesNotSupportedByProject = false,
|
||||
_excludeDevicesNotSupportedByAll = false,
|
||||
_flutterProject = null;
|
||||
|
||||
/// Filter devices to only include those supported by Flutter and the
|
||||
/// provided [flutterProject].
|
||||
///
|
||||
/// If [flutterProject] is null, all devices will be considered supported by
|
||||
/// the project.
|
||||
DeviceDiscoverySupportFilter.excludeDevicesUnsupportedByFlutterOrProject({
|
||||
required FlutterProject? flutterProject,
|
||||
}) : _flutterProject = flutterProject,
|
||||
_excludeDevicesNotSupportedByProject = true,
|
||||
_excludeDevicesNotSupportedByAll = false;
|
||||
|
||||
/// Filter devices to only include those supported by Flutter, the provided
|
||||
/// [flutterProject], and `--device all`.
|
||||
///
|
||||
/// If [flutterProject] is null, all devices will be considered supported by
|
||||
/// the project.
|
||||
DeviceDiscoverySupportFilter.excludeDevicesUnsupportedByFlutterOrProjectOrAll({
|
||||
required FlutterProject? flutterProject,
|
||||
}) : _flutterProject = flutterProject,
|
||||
_excludeDevicesNotSupportedByProject = true,
|
||||
_excludeDevicesNotSupportedByAll = true;
|
||||
|
||||
final FlutterProject? _flutterProject;
|
||||
final bool _excludeDevicesNotSupportedByProject;
|
||||
final bool _excludeDevicesNotSupportedByAll;
|
||||
|
||||
Future<bool> matchesRequirements(Device device) async {
|
||||
final bool meetsSupportByFlutterRequirement = device.isSupported();
|
||||
final bool meetsSupportForProjectRequirement = !_excludeDevicesNotSupportedByProject || isDeviceSupportedForProject(device);
|
||||
final bool meetsSupportForAllRequirement = !_excludeDevicesNotSupportedByAll || await isDeviceSupportedForAll(device);
|
||||
|
||||
return meetsSupportByFlutterRequirement &&
|
||||
meetsSupportForProjectRequirement &&
|
||||
meetsSupportForAllRequirement;
|
||||
}
|
||||
|
||||
/// User has specified `--device all`.
|
||||
///
|
||||
/// Always remove web and fuchsia devices from `all`. This setting
|
||||
/// currently requires devices to share a frontend_server and resident
|
||||
/// runner instance. Both web and fuchsia require differently configured
|
||||
/// compilers, and web requires an entirely different resident runner.
|
||||
Future<bool> isDeviceSupportedForAll(Device device) async {
|
||||
final TargetPlatform devicePlatform = await device.targetPlatform;
|
||||
return device.isSupported() &&
|
||||
devicePlatform != TargetPlatform.fuchsia_arm64 &&
|
||||
devicePlatform != TargetPlatform.fuchsia_x64 &&
|
||||
devicePlatform != TargetPlatform.web_javascript &&
|
||||
isDeviceSupportedForProject(device);
|
||||
}
|
||||
|
||||
/// Returns whether the device is supported for the project.
|
||||
///
|
||||
/// A device can be supported by Flutter but not supported for the project
|
||||
/// (e.g. when the user has removed the iOS directory from their project).
|
||||
///
|
||||
/// This also exists to allow the check to be overridden for google3 clients. If
|
||||
/// [_flutterProject] is null then return true.
|
||||
bool isDeviceSupportedForProject(Device device) {
|
||||
if (!device.isSupported()) {
|
||||
return false;
|
||||
}
|
||||
if (_flutterProject == null) {
|
||||
return true;
|
||||
}
|
||||
return device.isSupportedForProject(_flutterProject!);
|
||||
}
|
||||
}
|
||||
|
||||
/// A class for filtering devices.
|
||||
///
|
||||
/// If [excludeDisconnected] is true, only devices detected as connected will be included.
|
||||
///
|
||||
/// If [supportFilter] is provided, only devices matching the requirements will be included.
|
||||
///
|
||||
/// If [deviceConnectionInterface] is provided, only devices matching the DeviceConnectionInterface will be included.
|
||||
class DeviceDiscoveryFilter {
|
||||
DeviceDiscoveryFilter({
|
||||
this.excludeDisconnected = true,
|
||||
this.supportFilter,
|
||||
this.deviceConnectionInterface,
|
||||
});
|
||||
|
||||
final bool excludeDisconnected;
|
||||
final DeviceDiscoverySupportFilter? supportFilter;
|
||||
final DeviceConnectionInterface? deviceConnectionInterface;
|
||||
|
||||
Future<bool> matchesRequirements(Device device) async {
|
||||
final DeviceDiscoverySupportFilter? localSupportFilter = supportFilter;
|
||||
|
||||
final bool meetsConnectionRequirement = !excludeDisconnected || device.isConnected;
|
||||
final bool meetsSupportRequirements = localSupportFilter == null || (await localSupportFilter.matchesRequirements(device));
|
||||
final bool meetsConnectionInterfaceRequirement = matchesDeviceConnectionInterface(device, deviceConnectionInterface);
|
||||
|
||||
return meetsConnectionRequirement &&
|
||||
meetsSupportRequirements &&
|
||||
meetsConnectionInterfaceRequirement;
|
||||
}
|
||||
|
||||
Future<List<Device>> filterDevices(List<Device> devices) async {
|
||||
devices = <Device>[
|
||||
for (final Device device in devices)
|
||||
if (await matchesRequirements(device)) device,
|
||||
];
|
||||
return devices;
|
||||
}
|
||||
|
||||
bool matchesDeviceConnectionInterface(
|
||||
Device device,
|
||||
DeviceConnectionInterface? deviceConnectionInterface,
|
||||
) {
|
||||
if (deviceConnectionInterface == null) {
|
||||
return true;
|
||||
}
|
||||
return device.connectionInterface == deviceConnectionInterface;
|
||||
}
|
||||
}
|
||||
|
||||
/// An abstract class to discover and enumerate a specific type of devices.
|
||||
abstract class DeviceDiscovery {
|
||||
@ -317,10 +480,13 @@ abstract class DeviceDiscovery {
|
||||
bool get canListAnything;
|
||||
|
||||
/// Return all connected devices, cached on subsequent calls.
|
||||
Future<List<Device>> get devices;
|
||||
Future<List<Device>> devices({DeviceDiscoveryFilter? filter});
|
||||
|
||||
/// Return all connected devices. Discards existing cache of devices.
|
||||
Future<List<Device>> discoverDevices({ Duration? timeout });
|
||||
Future<List<Device>> discoverDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter,
|
||||
});
|
||||
|
||||
/// Gets a list of diagnostic messages pertaining to issues with any connected
|
||||
/// devices (will be an empty list if there are no issues).
|
||||
@ -352,7 +518,7 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
|
||||
|
||||
Timer? _timer;
|
||||
|
||||
Future<List<Device>> pollingGetDevices({ Duration? timeout });
|
||||
Future<List<Device>> pollingGetDevices({Duration? timeout});
|
||||
|
||||
void startPolling() {
|
||||
if (_timer == null) {
|
||||
@ -380,19 +546,50 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
|
||||
_timer = null;
|
||||
}
|
||||
|
||||
/// Get devices from cache filtered by [filter].
|
||||
///
|
||||
/// If the cache is empty, populate the cache.
|
||||
@override
|
||||
Future<List<Device>> get devices {
|
||||
return _populateDevices();
|
||||
Future<List<Device>> devices({DeviceDiscoveryFilter? filter}) {
|
||||
return _populateDevices(filter: filter);
|
||||
}
|
||||
|
||||
/// Empty the cache and repopulate it before getting devices from cache filtered by [filter].
|
||||
///
|
||||
/// Search for devices to populate the cache for no longer than [timeout].
|
||||
@override
|
||||
Future<List<Device>> discoverDevices({ Duration? timeout }) {
|
||||
deviceNotifier = null;
|
||||
return _populateDevices(timeout: timeout);
|
||||
Future<List<Device>> discoverDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) {
|
||||
return _populateDevices(timeout: timeout, filter: filter, resetCache: true);
|
||||
}
|
||||
|
||||
Future<List<Device>> _populateDevices({ Duration? timeout }) async {
|
||||
deviceNotifier ??= ItemListNotifier<Device>.from(await pollingGetDevices(timeout: timeout));
|
||||
/// Get devices from cache filtered by [filter].
|
||||
///
|
||||
/// If the cache is empty or [resetCache] is true, populate the cache.
|
||||
///
|
||||
/// Search for devices to populate the cache for no longer than [timeout].
|
||||
Future<List<Device>> _populateDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter,
|
||||
bool resetCache = false,
|
||||
}) async {
|
||||
if (deviceNotifier == null || resetCache) {
|
||||
final List<Device> devices = await pollingGetDevices(timeout: timeout);
|
||||
// If the cache was populated while the polling was ongoing, do not
|
||||
// overwrite the cache unless it's explicitly refreshing the cache.
|
||||
if (resetCache) {
|
||||
deviceNotifier = ItemListNotifier<Device>.from(devices);
|
||||
} else {
|
||||
deviceNotifier ??= ItemListNotifier<Device>.from(devices);
|
||||
}
|
||||
}
|
||||
|
||||
// If a filter is provided, filter cache to only return devices matching.
|
||||
if (filter != null) {
|
||||
return filter.filterDevices(deviceNotifier!.items);
|
||||
}
|
||||
return deviceNotifier!.items;
|
||||
}
|
||||
|
||||
@ -412,6 +609,12 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
|
||||
String toString() => '$name device discovery';
|
||||
}
|
||||
|
||||
/// How a device is connected.
|
||||
enum DeviceConnectionInterface {
|
||||
attached,
|
||||
wireless,
|
||||
}
|
||||
|
||||
/// A device is a physical hardware that can run a Flutter application.
|
||||
///
|
||||
/// This may correspond to a connected iOS or Android device, or represent
|
||||
@ -434,6 +637,14 @@ abstract class Device {
|
||||
/// Whether this is an ephemeral device.
|
||||
final bool ephemeral;
|
||||
|
||||
bool get isConnected => true;
|
||||
|
||||
DeviceConnectionInterface get connectionInterface =>
|
||||
DeviceConnectionInterface.attached;
|
||||
|
||||
bool get isWirelesslyConnected =>
|
||||
connectionInterface == DeviceConnectionInterface.wireless;
|
||||
|
||||
String get name;
|
||||
|
||||
bool get supportsStartPaused => true;
|
||||
|
@ -688,7 +688,7 @@ class DeviceValidator extends DoctorValidator {
|
||||
|
||||
@override
|
||||
Future<ValidationResult> validate() async {
|
||||
final List<Device> devices = await _deviceManager.getAllConnectedDevices();
|
||||
final List<Device> devices = await _deviceManager.getAllDevices();
|
||||
List<ValidationMessage> installedMessages = <ValidationMessage>[];
|
||||
if (devices.isNotEmpty) {
|
||||
installedMessages = (await Device.descriptions(devices))
|
||||
|
@ -57,11 +57,14 @@ class ProxiedDevices extends DeviceDiscovery {
|
||||
List<Device>? _devices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> get devices async =>
|
||||
_devices ?? await discoverDevices();
|
||||
Future<List<Device>> devices({DeviceDiscoveryFilter? filter}) async =>
|
||||
_devices ?? await discoverDevices(filter: filter);
|
||||
|
||||
@override
|
||||
Future<List<Device>> discoverDevices({Duration? timeout}) async {
|
||||
Future<List<Device>> discoverDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter
|
||||
}) async {
|
||||
final List<Map<String, Object?>> discoveredDevices = _cast<List<dynamic>>(await connection.sendRequest('device.discoverDevices')).cast<Map<String, Object?>>();
|
||||
final List<ProxiedDevice> devices = <ProxiedDevice>[
|
||||
for (final Map<String, Object?> device in discoveredDevices)
|
||||
|
@ -1491,7 +1491,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// If no device can be found that meets specified criteria,
|
||||
/// then print an error message and return null.
|
||||
Future<List<Device>?> findAllTargetDevices({
|
||||
bool includeUnsupportedDevices = false,
|
||||
bool includeDevicesUnsupportedByProject = false,
|
||||
}) async {
|
||||
if (!globals.doctor!.canLaunchAnything) {
|
||||
globals.printError(userMessages.flutterNoDevelopmentDevice);
|
||||
@ -1499,14 +1499,14 @@ abstract class FlutterCommand extends Command<void> {
|
||||
}
|
||||
final DeviceManager deviceManager = globals.deviceManager!;
|
||||
List<Device> devices = await deviceManager.findTargetDevices(
|
||||
includeUnsupportedDevices ? null : FlutterProject.current(),
|
||||
includeDevicesUnsupportedByProject: includeDevicesUnsupportedByProject,
|
||||
timeout: deviceDiscoveryTimeout,
|
||||
);
|
||||
|
||||
if (devices.isEmpty) {
|
||||
if (deviceManager.hasSpecifiedDeviceId) {
|
||||
globals.logger.printStatus(userMessages.flutterNoMatchingDevice(deviceManager.specifiedDeviceId!));
|
||||
final List<Device> allDevices = await deviceManager.getAllConnectedDevices();
|
||||
final List<Device> allDevices = await deviceManager.getAllDevices();
|
||||
if (allDevices.isNotEmpty) {
|
||||
globals.logger.printStatus('');
|
||||
globals.logger.printStatus('The following devices were found:');
|
||||
@ -1543,7 +1543,7 @@ abstract class FlutterCommand extends Command<void> {
|
||||
} else {
|
||||
// Show an error message asking the user to specify `-d all` if they
|
||||
// want to run on multiple devices.
|
||||
final List<Device> allDevices = await deviceManager.getAllConnectedDevices();
|
||||
final List<Device> allDevices = await deviceManager.getAllDevices();
|
||||
globals.logger.printStatus(userMessages.flutterSpecifyDeviceWithAllOption);
|
||||
globals.logger.printStatus('');
|
||||
await Device.printDevices(allDevices, globals.logger);
|
||||
@ -1607,18 +1607,20 @@ abstract class FlutterCommand extends Command<void> {
|
||||
/// If a device cannot be found that meets specified criteria,
|
||||
/// then print an error message and return null.
|
||||
///
|
||||
/// If [includeUnsupportedDevices] is true, the tool does not filter
|
||||
/// If [includeDevicesUnsupportedByProject] is true, the tool does not filter
|
||||
/// the list by the current project support list.
|
||||
Future<Device?> findTargetDevice({
|
||||
bool includeUnsupportedDevices = false,
|
||||
bool includeDevicesUnsupportedByProject = false,
|
||||
}) async {
|
||||
List<Device>? deviceList = await findAllTargetDevices(includeUnsupportedDevices: includeUnsupportedDevices);
|
||||
List<Device>? deviceList = await findAllTargetDevices(
|
||||
includeDevicesUnsupportedByProject: includeDevicesUnsupportedByProject,
|
||||
);
|
||||
if (deviceList == null) {
|
||||
return null;
|
||||
}
|
||||
if (deviceList.length > 1) {
|
||||
globals.printStatus(userMessages.flutterSpecifyDevice);
|
||||
deviceList = await globals.deviceManager!.getAllConnectedDevices();
|
||||
deviceList = await globals.deviceManager!.getAllDevices();
|
||||
globals.printStatus('');
|
||||
await Device.printDevices(deviceList, globals.logger);
|
||||
return null;
|
||||
|
@ -1240,6 +1240,9 @@ class FakeAndroidDevice extends Fake implements AndroidDevice {
|
||||
@override
|
||||
bool isSupported() => true;
|
||||
|
||||
@override
|
||||
bool get isConnected => true;
|
||||
|
||||
@override
|
||||
bool get supportsHotRestart => true;
|
||||
|
||||
@ -1340,6 +1343,9 @@ class FakeIOSDevice extends Fake implements IOSDevice {
|
||||
|
||||
@override
|
||||
bool isSupportedForProject(FlutterProject project) => true;
|
||||
|
||||
@override
|
||||
bool get isConnected => true;
|
||||
}
|
||||
|
||||
class FakeMDnsClient extends Fake implements MDnsClient {
|
||||
|
@ -50,7 +50,7 @@ void main() {
|
||||
|
||||
testUsingContext("get devices' platform types", () async {
|
||||
final List<String> platformTypes = Device.devicesPlatformTypes(
|
||||
await globals.deviceManager!.getAllConnectedDevices(),
|
||||
await globals.deviceManager!.getAllDevices(),
|
||||
);
|
||||
expect(platformTypes, <String>['android', 'web']);
|
||||
}, overrides: <Type, Generator>{
|
||||
@ -134,12 +134,14 @@ class _FakeDeviceManager extends DeviceManager {
|
||||
_FakeDeviceManager() : super(logger: testLogger);
|
||||
|
||||
@override
|
||||
Future<List<Device>> getAllConnectedDevices() =>
|
||||
Future<List<Device>> getAllDevices({DeviceDiscoveryFilter? filter}) =>
|
||||
Future<List<Device>>.value(fakeDevices.map((FakeDeviceJsonData d) => d.dev).toList());
|
||||
|
||||
@override
|
||||
Future<List<Device>> refreshAllConnectedDevices({Duration? timeout}) =>
|
||||
getAllConnectedDevices();
|
||||
Future<List<Device>> refreshAllDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) => getAllDevices(filter: filter);
|
||||
|
||||
@override
|
||||
Future<List<String>> getDeviceDiagnostics() => Future<List<String>>.value(
|
||||
@ -154,11 +156,16 @@ class NoDevicesManager extends DeviceManager {
|
||||
NoDevicesManager() : super(logger: testLogger);
|
||||
|
||||
@override
|
||||
Future<List<Device>> getAllConnectedDevices() async => <Device>[];
|
||||
Future<List<Device>> getAllDevices({
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async => <Device>[];
|
||||
|
||||
@override
|
||||
Future<List<Device>> refreshAllConnectedDevices({Duration? timeout}) =>
|
||||
getAllConnectedDevices();
|
||||
Future<List<Device>> refreshAllDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) =>
|
||||
getAllDevices();
|
||||
|
||||
@override
|
||||
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];
|
||||
|
@ -1192,7 +1192,9 @@ class FakeDeviceManager extends Fake implements DeviceManager {
|
||||
List<Device> devices = <Device>[];
|
||||
|
||||
@override
|
||||
Future<List<Device>> getAllConnectedDevices() async => devices;
|
||||
Future<List<Device>> getAllDevices({
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async => devices;
|
||||
|
||||
@override
|
||||
Future<List<String>> getDeviceDiagnostics() async => diagnostics;
|
||||
|
@ -587,10 +587,16 @@ class FakeDeviceManager extends Fake implements DeviceManager {
|
||||
String? specifiedDeviceId;
|
||||
|
||||
@override
|
||||
Future<List<Device>> getDevices() async => devices;
|
||||
Future<List<Device>> getDevices({
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async => devices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> findTargetDevices(FlutterProject? flutterProject, {Duration? timeout, bool promptUserToChooseDevice = true}) async => devices;
|
||||
Future<List<Device>> findTargetDevices({
|
||||
bool includeDevicesUnsupportedByProject = false,
|
||||
Duration? timeout,
|
||||
bool promptUserToChooseDevice = true,
|
||||
}) async => devices;
|
||||
}
|
||||
|
||||
/// A [FlutterDriverFactory] that creates a [NeverEndingDriverService].
|
||||
|
@ -98,7 +98,7 @@ void main() {
|
||||
|
||||
final ProxiedDevices proxiedDevices = ProxiedDevices(clientDaemonConnection, logger: bufferLogger);
|
||||
|
||||
final List<Device> devices = await proxiedDevices.devices;
|
||||
final List<Device> devices = await proxiedDevices.devices();
|
||||
expect(devices, hasLength(1));
|
||||
final Device device = devices[0];
|
||||
final bool supportsRuntimeMode = await device.supportsRuntimeMode(BuildMode.release);
|
||||
@ -121,7 +121,7 @@ void main() {
|
||||
final FakeDeviceLogReader fakeLogReader = FakeDeviceLogReader();
|
||||
fakeDevice.logReader = fakeLogReader;
|
||||
|
||||
final List<Device> devices = await proxiedDevices.devices;
|
||||
final List<Device> devices = await proxiedDevices.devices();
|
||||
expect(devices, hasLength(1));
|
||||
final Device device = devices[0];
|
||||
final DeviceLogReader logReader = await device.getLogReader();
|
||||
@ -153,7 +153,7 @@ void main() {
|
||||
dummyApplicationBinary.writeAsStringSync('dummy content');
|
||||
prebuiltApplicationPackage.applicationPackage = dummyApplicationBinary;
|
||||
|
||||
final List<Device> devices = await proxiedDevices.devices;
|
||||
final List<Device> devices = await proxiedDevices.devices();
|
||||
expect(devices, hasLength(1));
|
||||
final Device device = devices[0];
|
||||
|
||||
@ -200,7 +200,7 @@ void main() {
|
||||
|
||||
final ProxiedDevices proxiedDevices = ProxiedDevices(clientDaemonConnection, logger: bufferLogger);
|
||||
|
||||
final List<Device> devices = await proxiedDevices.devices;
|
||||
final List<Device> devices = await proxiedDevices.devices();
|
||||
expect(devices, hasLength(1));
|
||||
final Device device = devices[0];
|
||||
|
||||
|
@ -1054,6 +1054,9 @@ class FakeDevice extends Fake implements Device {
|
||||
@override
|
||||
bool get supportsFastStart => false;
|
||||
|
||||
@override
|
||||
bool get isConnected => true;
|
||||
|
||||
bool supported = true;
|
||||
|
||||
@override
|
||||
|
@ -920,7 +920,9 @@ class _FakeDeviceManager extends DeviceManager {
|
||||
final List<Device> _connectedDevices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> getAllConnectedDevices() async => _connectedDevices;
|
||||
Future<List<Device>> getAllDevices({
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async => _connectedDevices;
|
||||
|
||||
@override
|
||||
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];
|
||||
|
@ -88,7 +88,10 @@ class FakeDeviceManager extends Fake implements DeviceManager {
|
||||
String? specifiedDeviceId;
|
||||
|
||||
@override
|
||||
Future<List<Device>> refreshAllConnectedDevices({Duration? timeout}) async {
|
||||
Future<List<Device>> refreshAllDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async {
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ void main() {
|
||||
directory: dir,
|
||||
logger: BufferLogger.test()
|
||||
)
|
||||
).devices, <Device>[]);
|
||||
).devices(), <Device>[]);
|
||||
});
|
||||
|
||||
testWithoutContext('CustomDevice: no devices listed if custom devices feature flag disabled', () async {
|
||||
@ -184,7 +184,7 @@ void main() {
|
||||
directory: dir,
|
||||
logger: BufferLogger.test()
|
||||
)
|
||||
).devices, <Device>[]);
|
||||
).devices(), <Device>[]);
|
||||
});
|
||||
|
||||
testWithoutContext('CustomDevices.devices', () async {
|
||||
@ -208,7 +208,7 @@ void main() {
|
||||
directory: dir,
|
||||
logger: BufferLogger.test()
|
||||
)
|
||||
).devices,
|
||||
).devices(),
|
||||
hasLength(1)
|
||||
);
|
||||
});
|
||||
|
@ -16,6 +16,7 @@ import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:test/fake.dart';
|
||||
|
||||
import '../src/common.dart';
|
||||
import '../src/context.dart';
|
||||
import '../src/fake_devices.dart';
|
||||
|
||||
void main() {
|
||||
@ -123,30 +124,47 @@ void main() {
|
||||
expect(logger.traceText, contains('Ignored error discovering Nexus'));
|
||||
});
|
||||
|
||||
testWithoutContext('getAllConnectedDevices caches', () async {
|
||||
testWithoutContext('getDeviceById two exact matches, matches on first', () async {
|
||||
final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
|
||||
final TestDeviceManager deviceManager = TestDeviceManager(
|
||||
<Device>[device1],
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
expect(await deviceManager.getAllConnectedDevices(), <Device>[device1]);
|
||||
final FakeDevice device2 = FakeDevice('Nexus 5', '01abfc49119c410e');
|
||||
final List<Device> devices = <Device>[device1, device2];
|
||||
final BufferLogger logger = BufferLogger.test();
|
||||
|
||||
final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
|
||||
deviceManager.resetDevices(<Device>[device2]);
|
||||
expect(await deviceManager.getAllConnectedDevices(), <Device>[device1]);
|
||||
final DeviceManager deviceManager = TestDeviceManager(
|
||||
devices,
|
||||
logger: logger,
|
||||
);
|
||||
|
||||
Future<void> expectDevice(String id, List<Device> expected) async {
|
||||
expect(await deviceManager.getDevicesById(id), expected);
|
||||
}
|
||||
await expectDevice('Nexus 5', <Device>[device1]);
|
||||
});
|
||||
|
||||
testWithoutContext('refreshAllConnectedDevices does not cache', () async {
|
||||
testWithoutContext('getAllDevices caches', () async {
|
||||
final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
|
||||
final TestDeviceManager deviceManager = TestDeviceManager(
|
||||
<Device>[device1],
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
expect(await deviceManager.refreshAllConnectedDevices(), <Device>[device1]);
|
||||
expect(await deviceManager.getAllDevices(), <Device>[device1]);
|
||||
|
||||
final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
|
||||
deviceManager.resetDevices(<Device>[device2]);
|
||||
expect(await deviceManager.refreshAllConnectedDevices(), <Device>[device2]);
|
||||
expect(await deviceManager.getAllDevices(), <Device>[device1]);
|
||||
});
|
||||
|
||||
testWithoutContext('refreshAllDevices does not cache', () async {
|
||||
final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
|
||||
final TestDeviceManager deviceManager = TestDeviceManager(
|
||||
<Device>[device1],
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
expect(await deviceManager.refreshAllDevices(), <Device>[device1]);
|
||||
|
||||
final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
|
||||
deviceManager.resetDevices(<Device>[device2]);
|
||||
expect(await deviceManager.refreshAllDevices(), <Device>[device2]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -179,8 +197,10 @@ void main() {
|
||||
..targetPlatform = Future<TargetPlatform>.value(TargetPlatform.web_javascript);
|
||||
final FakeDevice fuchsiaDevice = FakeDevice('fuchsiay', 'fuchsiay')
|
||||
..targetPlatform = Future<TargetPlatform>.value(TargetPlatform.fuchsia_x64);
|
||||
final FakeDevice unconnectedDevice = FakeDevice('ephemeralTwo', 'ephemeralTwo', isConnected: false);
|
||||
final FakeDevice wirelessDevice = FakeDevice('ephemeralTwo', 'ephemeralTwo', connectionInterface: DeviceConnectionInterface.wireless);
|
||||
|
||||
testWithoutContext('chooses ephemeral device', () async {
|
||||
testUsingContext('chooses ephemeral device', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
ephemeralOne,
|
||||
nonEphemeralOne,
|
||||
@ -193,12 +213,14 @@ void main() {
|
||||
devices,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||
|
||||
expect(filtered.single, ephemeralOne);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('returns all devices when multiple non ephemeral devices are found', () async {
|
||||
testUsingContext('returns all devices when multiple non ephemeral devices are found', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
ephemeralOne,
|
||||
ephemeralTwo,
|
||||
@ -211,7 +233,7 @@ void main() {
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||
|
||||
expect(filtered, <Device>[
|
||||
ephemeralOne,
|
||||
@ -219,9 +241,11 @@ void main() {
|
||||
nonEphemeralOne,
|
||||
nonEphemeralTwo,
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('Unsupported devices listed in all connected devices', () async {
|
||||
testUsingContext('Unsupported devices listed in all devices', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
unsupported,
|
||||
unsupportedForProject,
|
||||
@ -231,15 +255,17 @@ void main() {
|
||||
devices,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
final List<Device> filtered = await deviceManager.getAllConnectedDevices();
|
||||
final List<Device> filtered = await deviceManager.getAllDevices();
|
||||
|
||||
expect(filtered, <Device>[
|
||||
unsupported,
|
||||
unsupportedForProject,
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('Removes a unsupported devices', () async {
|
||||
testUsingContext('Removes unsupported devices', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
unsupported,
|
||||
unsupportedForProject,
|
||||
@ -248,12 +274,14 @@ void main() {
|
||||
devices,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||
|
||||
expect(filtered, <Device>[]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('Retains devices unsupported by the project if FlutterProject is null', () async {
|
||||
testUsingContext('Retains devices unsupported by the project if FlutterProject is null', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
unsupported,
|
||||
unsupportedForProject,
|
||||
@ -263,12 +291,16 @@ void main() {
|
||||
devices,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(null);
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(
|
||||
includeDevicesUnsupportedByProject: true,
|
||||
);
|
||||
|
||||
expect(filtered, <Device>[unsupportedForProject]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('Removes web and fuchsia from --all', () async {
|
||||
testUsingContext('Removes web and fuchsia from --all', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
webDevice,
|
||||
fuchsiaDevice,
|
||||
@ -279,12 +311,16 @@ void main() {
|
||||
);
|
||||
deviceManager.specifiedDeviceId = 'all';
|
||||
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(
|
||||
includeDevicesUnsupportedByProject: true,
|
||||
);
|
||||
|
||||
expect(filtered, <Device>[]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('Removes devices unsupported by the project from --all', () async {
|
||||
testUsingContext('Removes devices unsupported by the project from --all', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
nonEphemeralOne,
|
||||
nonEphemeralTwo,
|
||||
@ -297,15 +333,17 @@ void main() {
|
||||
);
|
||||
deviceManager.specifiedDeviceId = 'all';
|
||||
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||
|
||||
expect(filtered, <Device>[
|
||||
nonEphemeralOne,
|
||||
nonEphemeralTwo,
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('Returns device with the specified id', () async {
|
||||
testUsingContext('Returns device with the specified id', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
nonEphemeralOne,
|
||||
];
|
||||
@ -315,14 +353,16 @@ void main() {
|
||||
);
|
||||
deviceManager.specifiedDeviceId = nonEphemeralOne.id;
|
||||
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||
|
||||
expect(filtered, <Device>[
|
||||
nonEphemeralOne,
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('Returns multiple devices when multiple devices matches the specified id', () async {
|
||||
testUsingContext('Returns multiple devices when multiple devices matches the specified id', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
nonEphemeralOne,
|
||||
nonEphemeralTwo,
|
||||
@ -333,15 +373,17 @@ void main() {
|
||||
);
|
||||
deviceManager.specifiedDeviceId = 'nonEphemeral'; // This prefix matches both devices
|
||||
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||
|
||||
expect(filtered, <Device>[
|
||||
nonEphemeralOne,
|
||||
nonEphemeralTwo,
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('Returns empty when device of specified id is not found', () async {
|
||||
testUsingContext('Returns empty when device of specified id is not found', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
nonEphemeralOne,
|
||||
];
|
||||
@ -351,12 +393,14 @@ void main() {
|
||||
);
|
||||
deviceManager.specifiedDeviceId = nonEphemeralTwo.id;
|
||||
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||
|
||||
expect(filtered, <Device>[]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('uses DeviceManager.isDeviceSupportedForProject instead of device.isSupportedForProject', () async {
|
||||
testWithoutContext('uses DeviceDiscoverySupportFilter.isDeviceSupportedForProject instead of device.isSupportedForProject', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
unsupported,
|
||||
unsupportedForProject,
|
||||
@ -365,16 +409,106 @@ void main() {
|
||||
devices,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
deviceManager.isAlwaysSupportedForProjectOverride = true;
|
||||
final TestDeviceDiscoverySupportFilter supportFilter =
|
||||
TestDeviceDiscoverySupportFilter.excludeDevicesUnsupportedByFlutterOrProject(
|
||||
flutterProject: FakeFlutterProject(),
|
||||
);
|
||||
supportFilter.isAlwaysSupportedForProjectOverride = true;
|
||||
final DeviceDiscoveryFilter filter = DeviceDiscoveryFilter(
|
||||
supportFilter: supportFilter,
|
||||
);
|
||||
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
||||
final List<Device> filtered = await deviceManager.getDevices(
|
||||
filter: filter,
|
||||
);
|
||||
|
||||
expect(filtered, <Device>[
|
||||
unsupportedForProject,
|
||||
]);
|
||||
});
|
||||
|
||||
testWithoutContext('does not refresh device cache without a timeout', () async {
|
||||
testUsingContext('Unconnencted devices filtered out by default', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
unconnectedDevice,
|
||||
];
|
||||
final DeviceManager deviceManager = TestDeviceManager(
|
||||
devices,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
|
||||
final List<Device> filtered = await deviceManager.getDevices();
|
||||
|
||||
expect(filtered, <Device>[]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testUsingContext('Return unconnected devices when filter allows', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
unconnectedDevice,
|
||||
];
|
||||
final DeviceManager deviceManager = TestDeviceManager(
|
||||
devices,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
final DeviceDiscoveryFilter filter = DeviceDiscoveryFilter(
|
||||
excludeDisconnected: false,
|
||||
);
|
||||
|
||||
final List<Device> filtered = await deviceManager.getDevices(
|
||||
filter: filter,
|
||||
);
|
||||
|
||||
expect(filtered, <Device>[unconnectedDevice]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testUsingContext('Filter to only include wireless devices', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
ephemeralOne,
|
||||
wirelessDevice,
|
||||
];
|
||||
final DeviceManager deviceManager = TestDeviceManager(
|
||||
devices,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
final DeviceDiscoveryFilter filter = DeviceDiscoveryFilter(
|
||||
deviceConnectionInterface: DeviceConnectionInterface.wireless,
|
||||
);
|
||||
|
||||
final List<Device> filtered = await deviceManager.getDevices(
|
||||
filter: filter,
|
||||
);
|
||||
|
||||
expect(filtered, <Device>[wirelessDevice]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testUsingContext('Filter to only include attached devices', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
ephemeralOne,
|
||||
wirelessDevice,
|
||||
];
|
||||
final DeviceManager deviceManager = TestDeviceManager(
|
||||
devices,
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
final DeviceDiscoveryFilter filter = DeviceDiscoveryFilter(
|
||||
deviceConnectionInterface: DeviceConnectionInterface.attached,
|
||||
);
|
||||
|
||||
final List<Device> filtered = await deviceManager.getDevices(
|
||||
filter: filter,
|
||||
);
|
||||
|
||||
expect(filtered, <Device>[ephemeralOne]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testUsingContext('does not refresh device cache without a timeout', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
ephemeralOne,
|
||||
];
|
||||
@ -389,16 +523,16 @@ void main() {
|
||||
logger: BufferLogger.test(),
|
||||
);
|
||||
deviceManager.specifiedDeviceId = ephemeralOne.id;
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(
|
||||
FakeFlutterProject(),
|
||||
);
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||
|
||||
expect(filtered.single, ephemeralOne);
|
||||
expect(deviceDiscovery.devicesCalled, 1);
|
||||
expect(deviceDiscovery.discoverDevicesCalled, 0);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
|
||||
testWithoutContext('refreshes device cache with a timeout', () async {
|
||||
testUsingContext('refreshes device cache with a timeout', () async {
|
||||
final List<Device> devices = <Device>[
|
||||
ephemeralOne,
|
||||
];
|
||||
@ -415,13 +549,161 @@ void main() {
|
||||
);
|
||||
deviceManager.specifiedDeviceId = ephemeralOne.id;
|
||||
final List<Device> filtered = await deviceManager.findTargetDevices(
|
||||
FakeFlutterProject(),
|
||||
timeout: timeout,
|
||||
);
|
||||
|
||||
expect(filtered.single, ephemeralOne);
|
||||
expect(deviceDiscovery.devicesCalled, 1);
|
||||
expect(deviceDiscovery.discoverDevicesCalled, 1);
|
||||
}, overrides: <Type, Generator>{
|
||||
FlutterProject: () => FakeFlutterProject(),
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
group('Simultaneous device discovery', () {
|
||||
testWithoutContext('Run getAllDevices and refreshAllDevices at same time with refreshAllDevices finishing last', () async {
|
||||
FakeAsync().run((FakeAsync time) {
|
||||
final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
|
||||
final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
|
||||
|
||||
const Duration timeToGetInitialDevices = Duration(seconds: 1);
|
||||
const Duration timeToRefreshDevices = Duration(seconds: 5);
|
||||
final List<Device> initialDevices = <Device>[device2];
|
||||
final List<Device> refreshDevices = <Device>[device1];
|
||||
|
||||
final TestDeviceManager deviceManager = TestDeviceManager(
|
||||
<Device>[],
|
||||
logger: BufferLogger.test(),
|
||||
fakeDiscoverer: FakePollingDeviceDiscoveryWithTimeout(
|
||||
<List<Device>>[
|
||||
initialDevices,
|
||||
refreshDevices,
|
||||
],
|
||||
timeout: timeToGetInitialDevices,
|
||||
),
|
||||
);
|
||||
|
||||
// Expect that the cache is set by getOrSetCache process (1 second timeout)
|
||||
// and then later updated by refreshCache process (5 second timeout).
|
||||
// Ending with devices from the refreshCache process.
|
||||
final Future<List<Device>> refreshCache = deviceManager.refreshAllDevices(
|
||||
timeout: timeToRefreshDevices,
|
||||
);
|
||||
final Future<List<Device>> getOrSetCache = deviceManager.getAllDevices();
|
||||
|
||||
// After 1 second, the getAllDevices should be done
|
||||
time.elapse(const Duration(seconds: 1));
|
||||
expect(getOrSetCache, completion(<Device>[device2]));
|
||||
// double check values in cache are as expected
|
||||
Future<List<Device>> getFromCache = deviceManager.getAllDevices();
|
||||
expect(getFromCache, completion(<Device>[device2]));
|
||||
|
||||
// After 5 seconds, getOrSetCache should be done
|
||||
time.elapse(const Duration(seconds: 5));
|
||||
expect(refreshCache, completion(<Device>[device1]));
|
||||
// double check values in cache are as expected
|
||||
getFromCache = deviceManager.getAllDevices();
|
||||
expect(getFromCache, completion(<Device>[device1]));
|
||||
|
||||
time.flushMicrotasks();
|
||||
});
|
||||
});
|
||||
|
||||
testWithoutContext('Run getAllDevices and refreshAllDevices at same time with refreshAllDevices finishing first', () async {
|
||||
fakeAsync((FakeAsync async) {
|
||||
final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
|
||||
final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
|
||||
|
||||
const Duration timeToGetInitialDevices = Duration(seconds: 5);
|
||||
const Duration timeToRefreshDevices = Duration(seconds: 1);
|
||||
final List<Device> initialDevices = <Device>[device2];
|
||||
final List<Device> refreshDevices = <Device>[device1];
|
||||
|
||||
final TestDeviceManager deviceManager = TestDeviceManager(
|
||||
<Device>[],
|
||||
logger: BufferLogger.test(),
|
||||
fakeDiscoverer: FakePollingDeviceDiscoveryWithTimeout(
|
||||
<List<Device>>[
|
||||
initialDevices,
|
||||
refreshDevices,
|
||||
],
|
||||
timeout: timeToGetInitialDevices,
|
||||
),
|
||||
);
|
||||
|
||||
// Expect that the cache is set by refreshCache process (1 second timeout).
|
||||
// Then later when getOrSetCache finishes (5 second timeout), it does not update the cache.
|
||||
// Ending with devices from the refreshCache process.
|
||||
final Future<List<Device>> refreshCache = deviceManager.refreshAllDevices(
|
||||
timeout: timeToRefreshDevices,
|
||||
);
|
||||
final Future<List<Device>> getOrSetCache = deviceManager.getAllDevices();
|
||||
|
||||
// After 1 second, the refreshCache should be done
|
||||
async.elapse(const Duration(seconds: 1));
|
||||
expect(refreshCache, completion(<Device>[device2]));
|
||||
// double check values in cache are as expected
|
||||
Future<List<Device>> getFromCache = deviceManager.getAllDevices();
|
||||
expect(getFromCache, completion(<Device>[device2]));
|
||||
|
||||
// After 5 seconds, getOrSetCache should be done
|
||||
async.elapse(const Duration(seconds: 5));
|
||||
expect(getOrSetCache, completion(<Device>[device2]));
|
||||
// double check values in cache are as expected
|
||||
getFromCache = deviceManager.getAllDevices();
|
||||
expect(getFromCache, completion(<Device>[device2]));
|
||||
|
||||
async.flushMicrotasks();
|
||||
});
|
||||
});
|
||||
|
||||
testWithoutContext('refreshAllDevices twice', () async {
|
||||
fakeAsync((FakeAsync async) {
|
||||
final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
|
||||
final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
|
||||
|
||||
const Duration timeToFirstRefresh = Duration(seconds: 1);
|
||||
const Duration timeToSecondRefresh = Duration(seconds: 5);
|
||||
final List<Device> firstRefreshDevices = <Device>[device2];
|
||||
final List<Device> secondRefreshDevices = <Device>[device1];
|
||||
|
||||
final TestDeviceManager deviceManager = TestDeviceManager(
|
||||
<Device>[],
|
||||
logger: BufferLogger.test(),
|
||||
fakeDiscoverer: FakePollingDeviceDiscoveryWithTimeout(
|
||||
<List<Device>>[
|
||||
firstRefreshDevices,
|
||||
secondRefreshDevices,
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
// Expect that the cache is updated by each refresh in order of completion.
|
||||
final Future<List<Device>> firstRefresh = deviceManager.refreshAllDevices(
|
||||
timeout: timeToFirstRefresh,
|
||||
);
|
||||
final Future<List<Device>> secondRefresh = deviceManager.refreshAllDevices(
|
||||
timeout: timeToSecondRefresh,
|
||||
);
|
||||
|
||||
// After 1 second, the firstRefresh should be done
|
||||
async.elapse(const Duration(seconds: 1));
|
||||
expect(firstRefresh, completion(<Device>[device2]));
|
||||
// double check values in cache are as expected
|
||||
Future<List<Device>> getFromCache = deviceManager.getAllDevices();
|
||||
expect(getFromCache, completion(<Device>[device2]));
|
||||
|
||||
// After 5 seconds, secondRefresh should be done
|
||||
async.elapse(const Duration(seconds: 5));
|
||||
expect(secondRefresh, completion(<Device>[device1]));
|
||||
// double check values in cache are as expected
|
||||
getFromCache = deviceManager.getAllDevices();
|
||||
expect(getFromCache, completion(<Device>[device1]));
|
||||
|
||||
async.flushMicrotasks();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -744,7 +1026,8 @@ class TestDeviceManager extends DeviceManager {
|
||||
List<DeviceDiscovery>? deviceDiscoveryOverrides,
|
||||
required super.logger,
|
||||
String? wellKnownId,
|
||||
}) : _fakeDeviceDiscoverer = FakePollingDeviceDiscovery(),
|
||||
FakePollingDeviceDiscovery? fakeDiscoverer,
|
||||
}) : _fakeDeviceDiscoverer = fakeDiscoverer ?? FakePollingDeviceDiscovery(),
|
||||
_deviceDiscoverers = <DeviceDiscovery>[],
|
||||
super() {
|
||||
if (wellKnownId != null) {
|
||||
@ -764,16 +1047,6 @@ class TestDeviceManager extends DeviceManager {
|
||||
void resetDevices(List<Device> allDevices) {
|
||||
_fakeDeviceDiscoverer.setDevices(allDevices);
|
||||
}
|
||||
|
||||
bool? isAlwaysSupportedForProjectOverride;
|
||||
|
||||
@override
|
||||
bool isDeviceSupportedForProject(Device device, FlutterProject? flutterProject) {
|
||||
if (isAlwaysSupportedForProjectOverride != null) {
|
||||
return isAlwaysSupportedForProjectOverride!;
|
||||
}
|
||||
return super.isDeviceSupportedForProject(device, flutterProject);
|
||||
}
|
||||
}
|
||||
|
||||
class MockDeviceDiscovery extends Fake implements DeviceDiscovery {
|
||||
@ -786,13 +1059,16 @@ class MockDeviceDiscovery extends Fake implements DeviceDiscovery {
|
||||
List<Device> deviceValues = <Device>[];
|
||||
|
||||
@override
|
||||
Future<List<Device>> get devices async {
|
||||
Future<List<Device>> devices({DeviceDiscoveryFilter? filter}) async {
|
||||
devicesCalled += 1;
|
||||
return deviceValues;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Device>> discoverDevices({Duration? timeout}) async {
|
||||
Future<List<Device>> discoverDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async {
|
||||
discoverDevicesCalled += 1;
|
||||
return deviceValues;
|
||||
}
|
||||
@ -801,6 +1077,43 @@ class MockDeviceDiscovery extends Fake implements DeviceDiscovery {
|
||||
List<String> get wellKnownIds => <String>[];
|
||||
}
|
||||
|
||||
class TestDeviceDiscoverySupportFilter extends DeviceDiscoverySupportFilter {
|
||||
TestDeviceDiscoverySupportFilter.excludeDevicesUnsupportedByFlutterOrProject({
|
||||
required super.flutterProject,
|
||||
}) : super.excludeDevicesUnsupportedByFlutterOrProject();
|
||||
|
||||
|
||||
bool? isAlwaysSupportedForProjectOverride;
|
||||
|
||||
@override
|
||||
bool isDeviceSupportedForProject(Device device) {
|
||||
if (isAlwaysSupportedForProjectOverride != null) {
|
||||
return isAlwaysSupportedForProjectOverride!;
|
||||
}
|
||||
return super.isDeviceSupportedForProject(device);
|
||||
}
|
||||
}
|
||||
|
||||
class FakePollingDeviceDiscoveryWithTimeout extends FakePollingDeviceDiscovery {
|
||||
FakePollingDeviceDiscoveryWithTimeout(
|
||||
this._devices, {
|
||||
Duration? timeout,
|
||||
}): defaultTimeout = timeout ?? const Duration(seconds: 2);
|
||||
|
||||
final List<List<Device>> _devices;
|
||||
int index = 0;
|
||||
|
||||
Duration defaultTimeout;
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices({ Duration? timeout }) async {
|
||||
timeout ??= defaultTimeout;
|
||||
await Future<void>.delayed(timeout);
|
||||
final List<Device> results = _devices[index];
|
||||
index += 1;
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
class FakeFlutterProject extends Fake implements FlutterProject { }
|
||||
|
||||
class LongPollingDeviceDiscovery extends PollingDeviceDiscovery {
|
||||
|
@ -67,7 +67,7 @@ void main() {
|
||||
logger: BufferLogger.test(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
operatingSystemUtils: FakeOperatingSystemUtils(),
|
||||
).devices, <Device>[]);
|
||||
).devices(), <Device>[]);
|
||||
});
|
||||
|
||||
testWithoutContext('LinuxDevice: no devices listed if Linux feature flag disabled', () async {
|
||||
@ -78,7 +78,7 @@ void main() {
|
||||
logger: BufferLogger.test(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
operatingSystemUtils: FakeOperatingSystemUtils(),
|
||||
).devices, <Device>[]);
|
||||
).devices(), <Device>[]);
|
||||
});
|
||||
|
||||
testWithoutContext('LinuxDevice: devices', () async {
|
||||
@ -89,7 +89,7 @@ void main() {
|
||||
logger: BufferLogger.test(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
operatingSystemUtils: FakeOperatingSystemUtils(),
|
||||
).devices, hasLength(1));
|
||||
).devices(), hasLength(1));
|
||||
});
|
||||
|
||||
testWithoutContext('LinuxDevice has well known id "linux"', () async {
|
||||
|
@ -93,7 +93,7 @@ void main() {
|
||||
featureFlags: TestFeatureFlags(isMacOSEnabled: true),
|
||||
platform: linux,
|
||||
),
|
||||
).devices, isEmpty);
|
||||
).devices(), isEmpty);
|
||||
});
|
||||
|
||||
testWithoutContext('No devices listed if platform is supported and feature is disabled', () async {
|
||||
@ -109,7 +109,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(await macOSDevices.devices, isEmpty);
|
||||
expect(await macOSDevices.devices(), isEmpty);
|
||||
});
|
||||
|
||||
testWithoutContext('devices listed if platform is supported and feature is enabled', () async {
|
||||
@ -125,7 +125,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(await macOSDevices.devices, hasLength(1));
|
||||
expect(await macOSDevices.devices(), hasLength(1));
|
||||
});
|
||||
|
||||
testWithoutContext('has a well known device id macos', () async {
|
||||
|
@ -50,7 +50,7 @@ void main() {
|
||||
);
|
||||
expect(discoverer.supportsPlatform, isTrue);
|
||||
|
||||
final List<Device> devices = await discoverer.devices;
|
||||
final List<Device> devices = await discoverer.devices();
|
||||
expect(devices, isEmpty);
|
||||
});
|
||||
|
||||
@ -66,7 +66,7 @@ void main() {
|
||||
);
|
||||
expect(discoverer.supportsPlatform, isTrue);
|
||||
|
||||
final List<Device> devices = await discoverer.devices;
|
||||
final List<Device> devices = await discoverer.devices();
|
||||
expect(devices, isEmpty);
|
||||
});
|
||||
|
||||
@ -82,7 +82,7 @@ void main() {
|
||||
);
|
||||
expect(discoverer.supportsPlatform, isTrue);
|
||||
|
||||
final List<Device> devices = await discoverer.devices;
|
||||
final List<Device> devices = await discoverer.devices();
|
||||
expect(devices, isEmpty);
|
||||
});
|
||||
|
||||
@ -98,7 +98,7 @@ void main() {
|
||||
);
|
||||
expect(discoverer.supportsPlatform, isTrue);
|
||||
|
||||
List<Device> devices = await discoverer.devices;
|
||||
List<Device> devices = await discoverer.devices();
|
||||
expect(devices, hasLength(1));
|
||||
|
||||
final Device device = devices.single;
|
||||
|
@ -47,7 +47,7 @@ void main() {
|
||||
testWithoutContext('no device', () async {
|
||||
final FlutterTesterDevices discoverer = setUpFlutterTesterDevices();
|
||||
|
||||
final List<Device> devices = await discoverer.devices;
|
||||
final List<Device> devices = await discoverer.devices();
|
||||
expect(devices, isEmpty);
|
||||
});
|
||||
|
||||
@ -55,7 +55,7 @@ void main() {
|
||||
FlutterTesterDevices.showFlutterTesterDevice = true;
|
||||
final FlutterTesterDevices discoverer = setUpFlutterTesterDevices();
|
||||
|
||||
final List<Device> devices = await discoverer.devices;
|
||||
final List<Device> devices = await discoverer.devices();
|
||||
expect(devices, hasLength(1));
|
||||
|
||||
final Device device = devices.single;
|
||||
|
@ -48,7 +48,7 @@ void main() {
|
||||
logger: BufferLogger.test(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
fileSystem: MemoryFileSystem.test(),
|
||||
).devices, <Device>[]);
|
||||
).devices(), <Device>[]);
|
||||
});
|
||||
|
||||
testWithoutContext('WindowsDevices lists a devices if the workflow is supported', () async {
|
||||
@ -61,7 +61,7 @@ void main() {
|
||||
logger: BufferLogger.test(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
fileSystem: MemoryFileSystem.test(),
|
||||
).devices, hasLength(1));
|
||||
).devices(), hasLength(1));
|
||||
});
|
||||
|
||||
testWithoutContext('isSupportedForProject is true with editable host app', () async {
|
||||
|
@ -207,21 +207,31 @@ class FakeDeviceManager implements DeviceManager {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Device>> getAllConnectedDevices() async => devices;
|
||||
Future<List<Device>> getAllDevices({
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async => devices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> refreshAllConnectedDevices({ Duration? timeout }) async => devices;
|
||||
Future<List<Device>> refreshAllDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async => devices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> getDevicesById(String deviceId) async {
|
||||
Future<List<Device>> getDevicesById(
|
||||
String deviceId, {
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) async {
|
||||
return devices.where((Device device) => device.id == deviceId).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Device>> getDevices() {
|
||||
Future<List<Device>> getDevices({
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) {
|
||||
return hasSpecifiedDeviceId
|
||||
? getDevicesById(specifiedDeviceId!)
|
||||
: getAllConnectedDevices();
|
||||
? getDevicesById(specifiedDeviceId!, filter: filter)
|
||||
: getAllDevices(filter: filter);
|
||||
}
|
||||
|
||||
void addDevice(Device device) => devices.add(device);
|
||||
@ -236,16 +246,27 @@ class FakeDeviceManager implements DeviceManager {
|
||||
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];
|
||||
|
||||
@override
|
||||
bool isDeviceSupportedForProject(Device device, FlutterProject? flutterProject) {
|
||||
return device.isSupportedForProject(flutterProject!);
|
||||
Future<List<Device>> findTargetDevices({
|
||||
bool includeDevicesUnsupportedByProject = false,
|
||||
Duration? timeout,
|
||||
bool promptUserToChooseDevice = true,
|
||||
}) async {
|
||||
return devices;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Device>> findTargetDevices(FlutterProject? flutterProject, { Duration? timeout, bool promptUserToChooseDevice = true }) async {
|
||||
return devices;
|
||||
DeviceDiscoverySupportFilter deviceSupportFilter({
|
||||
bool includeDevicesUnsupportedByProject = false,
|
||||
FlutterProject? flutterProject,
|
||||
}) {
|
||||
return TestDeviceDiscoverySupportFilter();
|
||||
}
|
||||
}
|
||||
|
||||
class TestDeviceDiscoverySupportFilter extends Fake implements DeviceDiscoverySupportFilter {
|
||||
TestDeviceDiscoverySupportFilter();
|
||||
}
|
||||
|
||||
class FakeAndroidLicenseValidator extends Fake implements AndroidLicenseValidator {
|
||||
@override
|
||||
Future<LicensesAccepted> get licensesAccepted async => LicensesAccepted.all;
|
||||
|
@ -62,6 +62,8 @@ class FakeDevice extends Device {
|
||||
bool ephemeral = true,
|
||||
bool isSupported = true,
|
||||
bool isSupportedForProject = true,
|
||||
this.isConnected = true,
|
||||
this.connectionInterface = DeviceConnectionInterface.attached,
|
||||
PlatformType type = PlatformType.web,
|
||||
LaunchResult? launchResult,
|
||||
}) : _isSupported = isSupported,
|
||||
@ -118,6 +120,12 @@ class FakeDevice extends Device {
|
||||
@override
|
||||
bool isSupported() => _isSupported;
|
||||
|
||||
@override
|
||||
bool isConnected;
|
||||
|
||||
@override
|
||||
DeviceConnectionInterface connectionInterface;
|
||||
|
||||
@override
|
||||
Future<bool> isLocalEmulator = Future<bool>.value(true);
|
||||
|
||||
@ -174,7 +182,10 @@ class FakePollingDeviceDiscovery extends PollingDeviceDiscovery {
|
||||
bool discoverDevicesCalled = false;
|
||||
|
||||
@override
|
||||
Future<List<Device>> discoverDevices({Duration? timeout}) {
|
||||
Future<List<Device>> discoverDevices({
|
||||
Duration? timeout,
|
||||
DeviceDiscoveryFilter? filter,
|
||||
}) {
|
||||
discoverDevicesCalled = true;
|
||||
return super.discoverDevices(timeout: timeout);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user