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 {
|
Future<List<Map<String, Object?>>> getDevices([ Map<String, Object?>? args ]) async {
|
||||||
return <Map<String, Object?>>[
|
return <Map<String, Object?>>[
|
||||||
for (final PollingDeviceDiscovery discoverer in _discoverers)
|
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),
|
await _deviceToMap(device),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -1069,7 +1069,7 @@ class DeviceDomain extends Domain {
|
|||||||
/// Return the device matching the deviceId field in the args.
|
/// Return the device matching the deviceId field in the args.
|
||||||
Future<Device?> _getDevice(String? deviceId) async {
|
Future<Device?> _getDevice(String? deviceId) async {
|
||||||
for (final PollingDeviceDiscovery discoverer in _discoverers) {
|
for (final PollingDeviceDiscovery discoverer in _discoverers) {
|
||||||
final List<Device> devices = await discoverer.devices;
|
final List<Device> devices = await discoverer.devices();
|
||||||
Device? device;
|
Device? device;
|
||||||
for (final Device localDevice in devices) {
|
for (final Device localDevice in devices) {
|
||||||
if (localDevice.id == deviceId) {
|
if (localDevice.id == deviceId) {
|
||||||
|
@ -62,7 +62,7 @@ class DevicesCommand extends FlutterCommand {
|
|||||||
exitCode: 1);
|
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')) {
|
if (boolArgDeprecated('machine')) {
|
||||||
await printDevicesAsJson(devices);
|
await printDevicesAsJson(devices);
|
||||||
|
@ -209,7 +209,9 @@ class DriveCommand extends RunCommandBase {
|
|||||||
String? get applicationBinaryPath => stringArgDeprecated(FlutterOptions.kUseApplicationBinary);
|
String? get applicationBinaryPath => stringArgDeprecated(FlutterOptions.kUseApplicationBinary);
|
||||||
|
|
||||||
Future<Device?> get targetedDevice async {
|
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.
|
// Network devices need `publish-port` to be enabled because it requires mDNS.
|
||||||
|
@ -36,7 +36,7 @@ class LogsCommand extends FlutterCommand {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<FlutterCommandResult> verifyThenRunCommand(String? commandPath) async {
|
Future<FlutterCommandResult> verifyThenRunCommand(String? commandPath) async {
|
||||||
device = await findTargetDevice(includeUnsupportedDevices: true);
|
device = await findTargetDevice(includeDevicesUnsupportedByProject: true);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
throwToolExit(null);
|
throwToolExit(null);
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,19 @@ abstract class DeviceManager {
|
|||||||
/// specifiedDeviceId = 'all'.
|
/// specifiedDeviceId = 'all'.
|
||||||
bool get hasSpecifiedAllDevices => _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();
|
final String lowerDeviceId = deviceId.toLowerCase();
|
||||||
bool exactlyMatchesDeviceId(Device device) =>
|
bool exactlyMatchesDeviceId(Device device) =>
|
||||||
device.id.toLowerCase() == lowerDeviceId ||
|
device.id.toLowerCase() == lowerDeviceId ||
|
||||||
@ -135,7 +147,7 @@ abstract class DeviceManager {
|
|||||||
for (final DeviceDiscovery discoverer in _platformDiscoverers)
|
for (final DeviceDiscovery discoverer in _platformDiscoverers)
|
||||||
if (!hasWellKnownId || discoverer.wellKnownIds.contains(specifiedDeviceId))
|
if (!hasWellKnownId || discoverer.wellKnownIds.contains(specifiedDeviceId))
|
||||||
discoverer
|
discoverer
|
||||||
.devices
|
.devices(filter: filter)
|
||||||
.then((List<Device> devices) {
|
.then((List<Device> devices) {
|
||||||
for (final Device device in devices) {
|
for (final Device device in devices) {
|
||||||
if (exactlyMatchesDeviceId(device)) {
|
if (exactlyMatchesDeviceId(device)) {
|
||||||
@ -165,34 +177,56 @@ abstract class DeviceManager {
|
|||||||
return prefixMatches;
|
return prefixMatches;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the list of connected devices, filtered by any user-specified device id.
|
/// Returns a list of devices filtered by the user-specified device
|
||||||
Future<List<Device>> getDevices() {
|
/// 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;
|
final String? id = specifiedDeviceId;
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
return getAllConnectedDevices();
|
return getAllDevices(filter: filter);
|
||||||
}
|
}
|
||||||
return getDevicesById(id);
|
return getDevicesById(id, filter: filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<DeviceDiscovery> get _platformDiscoverers {
|
Iterable<DeviceDiscovery> get _platformDiscoverers {
|
||||||
return deviceDiscoverers.where((DeviceDiscovery discoverer) => discoverer.supportsPlatform);
|
return deviceDiscoverers.where((DeviceDiscovery discoverer) => discoverer.supportsPlatform);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the list of all connected devices.
|
/// Returns a list of devices filtered by [filter].
|
||||||
Future<List<Device>> getAllConnectedDevices() async {
|
///
|
||||||
|
/// 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>>>[
|
final List<List<Device>> devices = await Future.wait<List<Device>>(<Future<List<Device>>>[
|
||||||
for (final DeviceDiscovery discoverer in _platformDiscoverers)
|
for (final DeviceDiscovery discoverer in _platformDiscoverers)
|
||||||
discoverer.devices,
|
discoverer.devices(filter: filter),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return devices.expand<Device>((List<Device> deviceList) => deviceList).toList();
|
return devices.expand<Device>((List<Device> deviceList) => deviceList).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the list of all connected devices. Discards existing cache of devices.
|
/// Returns a list of devices filtered by [filter]. Discards existing cache of devices.
|
||||||
Future<List<Device>> refreshAllConnectedDevices({ Duration? timeout }) async {
|
///
|
||||||
|
/// 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>>>[
|
final List<List<Device>> devices = await Future.wait<List<Device>>(<Future<List<Device>>>[
|
||||||
for (final DeviceDiscovery discoverer in _platformDiscoverers)
|
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();
|
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
|
/// * If [promptUserToChooseDevice] is true, and there are more than one
|
||||||
/// device after the aforementioned filters, and the user is connected to a
|
/// device after the aforementioned filters, and the user is connected to a
|
||||||
/// terminal, then show a prompt asking the user to choose one.
|
/// terminal, then show a prompt asking the user to choose one.
|
||||||
Future<List<Device>> findTargetDevices(
|
Future<List<Device>> findTargetDevices({
|
||||||
FlutterProject? flutterProject, {
|
bool includeDevicesUnsupportedByProject = false,
|
||||||
Duration? timeout,
|
Duration? timeout,
|
||||||
}) async {
|
}) async {
|
||||||
if (timeout != null) {
|
if (timeout != null) {
|
||||||
// Reset the cache with the specified timeout.
|
// Reset the cache with the specified timeout.
|
||||||
await refreshAllConnectedDevices(timeout: timeout);
|
await refreshAllDevices(timeout: timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Device> devices = (await getDevices())
|
final List<Device> devices = await getDevices(
|
||||||
.where((Device device) => device.isSupported()).toList();
|
filter: DeviceDiscoveryFilter(
|
||||||
|
supportFilter: deviceSupportFilter(
|
||||||
|
includeDevicesUnsupportedByProject: includeDevicesUnsupportedByProject,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
if (hasSpecifiedAllDevices) {
|
if (!hasSpecifiedDeviceId) {
|
||||||
// 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) {
|
|
||||||
// User did not specify the device.
|
// 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 (devices.length > 1) {
|
||||||
// If there are still multiple devices and the user did not specify to run
|
// 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
|
// all, then attempt to prioritize ephemeral devices. For example, if the
|
||||||
@ -287,7 +302,7 @@ abstract class DeviceManager {
|
|||||||
];
|
];
|
||||||
|
|
||||||
if (ephemeralDevices.length == 1) {
|
if (ephemeralDevices.length == 1) {
|
||||||
devices = ephemeralDevices;
|
return ephemeralDevices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,18 +310,166 @@ abstract class DeviceManager {
|
|||||||
return devices;
|
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
|
/// By default, filters to only include devices that are supported by Flutter.
|
||||||
/// [flutterProject] is null then return true.
|
///
|
||||||
bool isDeviceSupportedForProject(Device device, FlutterProject? flutterProject) {
|
/// If the user has not specificied a device, filters to only include devices
|
||||||
if (flutterProject == null) {
|
/// that are supported by Flutter and supported by the project.
|
||||||
return true;
|
///
|
||||||
|
/// 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.
|
/// An abstract class to discover and enumerate a specific type of devices.
|
||||||
abstract class DeviceDiscovery {
|
abstract class DeviceDiscovery {
|
||||||
@ -317,10 +480,13 @@ abstract class DeviceDiscovery {
|
|||||||
bool get canListAnything;
|
bool get canListAnything;
|
||||||
|
|
||||||
/// Return all connected devices, cached on subsequent calls.
|
/// 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.
|
/// 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
|
/// Gets a list of diagnostic messages pertaining to issues with any connected
|
||||||
/// devices (will be an empty list if there are no issues).
|
/// devices (will be an empty list if there are no issues).
|
||||||
@ -352,7 +518,7 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
|
|||||||
|
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
|
|
||||||
Future<List<Device>> pollingGetDevices({ Duration? timeout });
|
Future<List<Device>> pollingGetDevices({Duration? timeout});
|
||||||
|
|
||||||
void startPolling() {
|
void startPolling() {
|
||||||
if (_timer == null) {
|
if (_timer == null) {
|
||||||
@ -380,19 +546,50 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
|
|||||||
_timer = null;
|
_timer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get devices from cache filtered by [filter].
|
||||||
|
///
|
||||||
|
/// If the cache is empty, populate the cache.
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> get devices {
|
Future<List<Device>> devices({DeviceDiscoveryFilter? filter}) {
|
||||||
return _populateDevices();
|
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
|
@override
|
||||||
Future<List<Device>> discoverDevices({ Duration? timeout }) {
|
Future<List<Device>> discoverDevices({
|
||||||
deviceNotifier = null;
|
Duration? timeout,
|
||||||
return _populateDevices(timeout: timeout);
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) {
|
||||||
|
return _populateDevices(timeout: timeout, filter: filter, resetCache: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Device>> _populateDevices({ Duration? timeout }) async {
|
/// Get devices from cache filtered by [filter].
|
||||||
deviceNotifier ??= ItemListNotifier<Device>.from(await pollingGetDevices(timeout: timeout));
|
///
|
||||||
|
/// 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;
|
return deviceNotifier!.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,6 +609,12 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
|
|||||||
String toString() => '$name device discovery';
|
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.
|
/// A device is a physical hardware that can run a Flutter application.
|
||||||
///
|
///
|
||||||
/// This may correspond to a connected iOS or Android device, or represent
|
/// 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.
|
/// Whether this is an ephemeral device.
|
||||||
final bool ephemeral;
|
final bool ephemeral;
|
||||||
|
|
||||||
|
bool get isConnected => true;
|
||||||
|
|
||||||
|
DeviceConnectionInterface get connectionInterface =>
|
||||||
|
DeviceConnectionInterface.attached;
|
||||||
|
|
||||||
|
bool get isWirelesslyConnected =>
|
||||||
|
connectionInterface == DeviceConnectionInterface.wireless;
|
||||||
|
|
||||||
String get name;
|
String get name;
|
||||||
|
|
||||||
bool get supportsStartPaused => true;
|
bool get supportsStartPaused => true;
|
||||||
|
@ -688,7 +688,7 @@ class DeviceValidator extends DoctorValidator {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<ValidationResult> validate() async {
|
Future<ValidationResult> validate() async {
|
||||||
final List<Device> devices = await _deviceManager.getAllConnectedDevices();
|
final List<Device> devices = await _deviceManager.getAllDevices();
|
||||||
List<ValidationMessage> installedMessages = <ValidationMessage>[];
|
List<ValidationMessage> installedMessages = <ValidationMessage>[];
|
||||||
if (devices.isNotEmpty) {
|
if (devices.isNotEmpty) {
|
||||||
installedMessages = (await Device.descriptions(devices))
|
installedMessages = (await Device.descriptions(devices))
|
||||||
|
@ -57,11 +57,14 @@ class ProxiedDevices extends DeviceDiscovery {
|
|||||||
List<Device>? _devices;
|
List<Device>? _devices;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> get devices async =>
|
Future<List<Device>> devices({DeviceDiscoveryFilter? filter}) async =>
|
||||||
_devices ?? await discoverDevices();
|
_devices ?? await discoverDevices(filter: filter);
|
||||||
|
|
||||||
@override
|
@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<Map<String, Object?>> discoveredDevices = _cast<List<dynamic>>(await connection.sendRequest('device.discoverDevices')).cast<Map<String, Object?>>();
|
||||||
final List<ProxiedDevice> devices = <ProxiedDevice>[
|
final List<ProxiedDevice> devices = <ProxiedDevice>[
|
||||||
for (final Map<String, Object?> device in discoveredDevices)
|
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,
|
/// If no device can be found that meets specified criteria,
|
||||||
/// then print an error message and return null.
|
/// then print an error message and return null.
|
||||||
Future<List<Device>?> findAllTargetDevices({
|
Future<List<Device>?> findAllTargetDevices({
|
||||||
bool includeUnsupportedDevices = false,
|
bool includeDevicesUnsupportedByProject = false,
|
||||||
}) async {
|
}) async {
|
||||||
if (!globals.doctor!.canLaunchAnything) {
|
if (!globals.doctor!.canLaunchAnything) {
|
||||||
globals.printError(userMessages.flutterNoDevelopmentDevice);
|
globals.printError(userMessages.flutterNoDevelopmentDevice);
|
||||||
@ -1499,14 +1499,14 @@ abstract class FlutterCommand extends Command<void> {
|
|||||||
}
|
}
|
||||||
final DeviceManager deviceManager = globals.deviceManager!;
|
final DeviceManager deviceManager = globals.deviceManager!;
|
||||||
List<Device> devices = await deviceManager.findTargetDevices(
|
List<Device> devices = await deviceManager.findTargetDevices(
|
||||||
includeUnsupportedDevices ? null : FlutterProject.current(),
|
includeDevicesUnsupportedByProject: includeDevicesUnsupportedByProject,
|
||||||
timeout: deviceDiscoveryTimeout,
|
timeout: deviceDiscoveryTimeout,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (devices.isEmpty) {
|
if (devices.isEmpty) {
|
||||||
if (deviceManager.hasSpecifiedDeviceId) {
|
if (deviceManager.hasSpecifiedDeviceId) {
|
||||||
globals.logger.printStatus(userMessages.flutterNoMatchingDevice(deviceManager.specifiedDeviceId!));
|
globals.logger.printStatus(userMessages.flutterNoMatchingDevice(deviceManager.specifiedDeviceId!));
|
||||||
final List<Device> allDevices = await deviceManager.getAllConnectedDevices();
|
final List<Device> allDevices = await deviceManager.getAllDevices();
|
||||||
if (allDevices.isNotEmpty) {
|
if (allDevices.isNotEmpty) {
|
||||||
globals.logger.printStatus('');
|
globals.logger.printStatus('');
|
||||||
globals.logger.printStatus('The following devices were found:');
|
globals.logger.printStatus('The following devices were found:');
|
||||||
@ -1543,7 +1543,7 @@ abstract class FlutterCommand extends Command<void> {
|
|||||||
} else {
|
} else {
|
||||||
// Show an error message asking the user to specify `-d all` if they
|
// Show an error message asking the user to specify `-d all` if they
|
||||||
// want to run on multiple devices.
|
// 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(userMessages.flutterSpecifyDeviceWithAllOption);
|
||||||
globals.logger.printStatus('');
|
globals.logger.printStatus('');
|
||||||
await Device.printDevices(allDevices, globals.logger);
|
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,
|
/// If a device cannot be found that meets specified criteria,
|
||||||
/// then print an error message and return null.
|
/// 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.
|
/// the list by the current project support list.
|
||||||
Future<Device?> findTargetDevice({
|
Future<Device?> findTargetDevice({
|
||||||
bool includeUnsupportedDevices = false,
|
bool includeDevicesUnsupportedByProject = false,
|
||||||
}) async {
|
}) async {
|
||||||
List<Device>? deviceList = await findAllTargetDevices(includeUnsupportedDevices: includeUnsupportedDevices);
|
List<Device>? deviceList = await findAllTargetDevices(
|
||||||
|
includeDevicesUnsupportedByProject: includeDevicesUnsupportedByProject,
|
||||||
|
);
|
||||||
if (deviceList == null) {
|
if (deviceList == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (deviceList.length > 1) {
|
if (deviceList.length > 1) {
|
||||||
globals.printStatus(userMessages.flutterSpecifyDevice);
|
globals.printStatus(userMessages.flutterSpecifyDevice);
|
||||||
deviceList = await globals.deviceManager!.getAllConnectedDevices();
|
deviceList = await globals.deviceManager!.getAllDevices();
|
||||||
globals.printStatus('');
|
globals.printStatus('');
|
||||||
await Device.printDevices(deviceList, globals.logger);
|
await Device.printDevices(deviceList, globals.logger);
|
||||||
return null;
|
return null;
|
||||||
|
@ -1240,6 +1240,9 @@ class FakeAndroidDevice extends Fake implements AndroidDevice {
|
|||||||
@override
|
@override
|
||||||
bool isSupported() => true;
|
bool isSupported() => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isConnected => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get supportsHotRestart => true;
|
bool get supportsHotRestart => true;
|
||||||
|
|
||||||
@ -1340,6 +1343,9 @@ class FakeIOSDevice extends Fake implements IOSDevice {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool isSupportedForProject(FlutterProject project) => true;
|
bool isSupportedForProject(FlutterProject project) => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isConnected => true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeMDnsClient extends Fake implements MDnsClient {
|
class FakeMDnsClient extends Fake implements MDnsClient {
|
||||||
|
@ -50,7 +50,7 @@ void main() {
|
|||||||
|
|
||||||
testUsingContext("get devices' platform types", () async {
|
testUsingContext("get devices' platform types", () async {
|
||||||
final List<String> platformTypes = Device.devicesPlatformTypes(
|
final List<String> platformTypes = Device.devicesPlatformTypes(
|
||||||
await globals.deviceManager!.getAllConnectedDevices(),
|
await globals.deviceManager!.getAllDevices(),
|
||||||
);
|
);
|
||||||
expect(platformTypes, <String>['android', 'web']);
|
expect(platformTypes, <String>['android', 'web']);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
@ -134,12 +134,14 @@ class _FakeDeviceManager extends DeviceManager {
|
|||||||
_FakeDeviceManager() : super(logger: testLogger);
|
_FakeDeviceManager() : super(logger: testLogger);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> getAllConnectedDevices() =>
|
Future<List<Device>> getAllDevices({DeviceDiscoveryFilter? filter}) =>
|
||||||
Future<List<Device>>.value(fakeDevices.map((FakeDeviceJsonData d) => d.dev).toList());
|
Future<List<Device>>.value(fakeDevices.map((FakeDeviceJsonData d) => d.dev).toList());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> refreshAllConnectedDevices({Duration? timeout}) =>
|
Future<List<Device>> refreshAllDevices({
|
||||||
getAllConnectedDevices();
|
Duration? timeout,
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) => getAllDevices(filter: filter);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getDeviceDiagnostics() => Future<List<String>>.value(
|
Future<List<String>> getDeviceDiagnostics() => Future<List<String>>.value(
|
||||||
@ -154,11 +156,16 @@ class NoDevicesManager extends DeviceManager {
|
|||||||
NoDevicesManager() : super(logger: testLogger);
|
NoDevicesManager() : super(logger: testLogger);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> getAllConnectedDevices() async => <Device>[];
|
Future<List<Device>> getAllDevices({
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) async => <Device>[];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> refreshAllConnectedDevices({Duration? timeout}) =>
|
Future<List<Device>> refreshAllDevices({
|
||||||
getAllConnectedDevices();
|
Duration? timeout,
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) =>
|
||||||
|
getAllDevices();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];
|
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];
|
||||||
|
@ -1192,7 +1192,9 @@ class FakeDeviceManager extends Fake implements DeviceManager {
|
|||||||
List<Device> devices = <Device>[];
|
List<Device> devices = <Device>[];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> getAllConnectedDevices() async => devices;
|
Future<List<Device>> getAllDevices({
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) async => devices;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getDeviceDiagnostics() async => diagnostics;
|
Future<List<String>> getDeviceDiagnostics() async => diagnostics;
|
||||||
|
@ -587,10 +587,16 @@ class FakeDeviceManager extends Fake implements DeviceManager {
|
|||||||
String? specifiedDeviceId;
|
String? specifiedDeviceId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> getDevices() async => devices;
|
Future<List<Device>> getDevices({
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) async => devices;
|
||||||
|
|
||||||
@override
|
@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].
|
/// A [FlutterDriverFactory] that creates a [NeverEndingDriverService].
|
||||||
|
@ -98,7 +98,7 @@ void main() {
|
|||||||
|
|
||||||
final ProxiedDevices proxiedDevices = ProxiedDevices(clientDaemonConnection, logger: bufferLogger);
|
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));
|
expect(devices, hasLength(1));
|
||||||
final Device device = devices[0];
|
final Device device = devices[0];
|
||||||
final bool supportsRuntimeMode = await device.supportsRuntimeMode(BuildMode.release);
|
final bool supportsRuntimeMode = await device.supportsRuntimeMode(BuildMode.release);
|
||||||
@ -121,7 +121,7 @@ void main() {
|
|||||||
final FakeDeviceLogReader fakeLogReader = FakeDeviceLogReader();
|
final FakeDeviceLogReader fakeLogReader = FakeDeviceLogReader();
|
||||||
fakeDevice.logReader = fakeLogReader;
|
fakeDevice.logReader = fakeLogReader;
|
||||||
|
|
||||||
final List<Device> devices = await proxiedDevices.devices;
|
final List<Device> devices = await proxiedDevices.devices();
|
||||||
expect(devices, hasLength(1));
|
expect(devices, hasLength(1));
|
||||||
final Device device = devices[0];
|
final Device device = devices[0];
|
||||||
final DeviceLogReader logReader = await device.getLogReader();
|
final DeviceLogReader logReader = await device.getLogReader();
|
||||||
@ -153,7 +153,7 @@ void main() {
|
|||||||
dummyApplicationBinary.writeAsStringSync('dummy content');
|
dummyApplicationBinary.writeAsStringSync('dummy content');
|
||||||
prebuiltApplicationPackage.applicationPackage = dummyApplicationBinary;
|
prebuiltApplicationPackage.applicationPackage = dummyApplicationBinary;
|
||||||
|
|
||||||
final List<Device> devices = await proxiedDevices.devices;
|
final List<Device> devices = await proxiedDevices.devices();
|
||||||
expect(devices, hasLength(1));
|
expect(devices, hasLength(1));
|
||||||
final Device device = devices[0];
|
final Device device = devices[0];
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ void main() {
|
|||||||
|
|
||||||
final ProxiedDevices proxiedDevices = ProxiedDevices(clientDaemonConnection, logger: bufferLogger);
|
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));
|
expect(devices, hasLength(1));
|
||||||
final Device device = devices[0];
|
final Device device = devices[0];
|
||||||
|
|
||||||
|
@ -1054,6 +1054,9 @@ class FakeDevice extends Fake implements Device {
|
|||||||
@override
|
@override
|
||||||
bool get supportsFastStart => false;
|
bool get supportsFastStart => false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isConnected => true;
|
||||||
|
|
||||||
bool supported = true;
|
bool supported = true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -920,7 +920,9 @@ class _FakeDeviceManager extends DeviceManager {
|
|||||||
final List<Device> _connectedDevices;
|
final List<Device> _connectedDevices;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> getAllConnectedDevices() async => _connectedDevices;
|
Future<List<Device>> getAllDevices({
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) async => _connectedDevices;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];
|
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];
|
||||||
|
@ -88,7 +88,10 @@ class FakeDeviceManager extends Fake implements DeviceManager {
|
|||||||
String? specifiedDeviceId;
|
String? specifiedDeviceId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> refreshAllConnectedDevices({Duration? timeout}) async {
|
Future<List<Device>> refreshAllDevices({
|
||||||
|
Duration? timeout,
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) async {
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ void main() {
|
|||||||
directory: dir,
|
directory: dir,
|
||||||
logger: BufferLogger.test()
|
logger: BufferLogger.test()
|
||||||
)
|
)
|
||||||
).devices, <Device>[]);
|
).devices(), <Device>[]);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('CustomDevice: no devices listed if custom devices feature flag disabled', () async {
|
testWithoutContext('CustomDevice: no devices listed if custom devices feature flag disabled', () async {
|
||||||
@ -184,7 +184,7 @@ void main() {
|
|||||||
directory: dir,
|
directory: dir,
|
||||||
logger: BufferLogger.test()
|
logger: BufferLogger.test()
|
||||||
)
|
)
|
||||||
).devices, <Device>[]);
|
).devices(), <Device>[]);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('CustomDevices.devices', () async {
|
testWithoutContext('CustomDevices.devices', () async {
|
||||||
@ -208,7 +208,7 @@ void main() {
|
|||||||
directory: dir,
|
directory: dir,
|
||||||
logger: BufferLogger.test()
|
logger: BufferLogger.test()
|
||||||
)
|
)
|
||||||
).devices,
|
).devices(),
|
||||||
hasLength(1)
|
hasLength(1)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -16,6 +16,7 @@ import 'package:flutter_tools/src/project.dart';
|
|||||||
import 'package:test/fake.dart';
|
import 'package:test/fake.dart';
|
||||||
|
|
||||||
import '../src/common.dart';
|
import '../src/common.dart';
|
||||||
|
import '../src/context.dart';
|
||||||
import '../src/fake_devices.dart';
|
import '../src/fake_devices.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@ -123,30 +124,47 @@ void main() {
|
|||||||
expect(logger.traceText, contains('Ignored error discovering Nexus'));
|
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 FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
|
||||||
final TestDeviceManager deviceManager = TestDeviceManager(
|
final FakeDevice device2 = FakeDevice('Nexus 5', '01abfc49119c410e');
|
||||||
<Device>[device1],
|
final List<Device> devices = <Device>[device1, device2];
|
||||||
logger: BufferLogger.test(),
|
final BufferLogger logger = BufferLogger.test();
|
||||||
);
|
|
||||||
expect(await deviceManager.getAllConnectedDevices(), <Device>[device1]);
|
|
||||||
|
|
||||||
final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
|
final DeviceManager deviceManager = TestDeviceManager(
|
||||||
deviceManager.resetDevices(<Device>[device2]);
|
devices,
|
||||||
expect(await deviceManager.getAllConnectedDevices(), <Device>[device1]);
|
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 FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
|
||||||
final TestDeviceManager deviceManager = TestDeviceManager(
|
final TestDeviceManager deviceManager = TestDeviceManager(
|
||||||
<Device>[device1],
|
<Device>[device1],
|
||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
);
|
);
|
||||||
expect(await deviceManager.refreshAllConnectedDevices(), <Device>[device1]);
|
expect(await deviceManager.getAllDevices(), <Device>[device1]);
|
||||||
|
|
||||||
final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
|
final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
|
||||||
deviceManager.resetDevices(<Device>[device2]);
|
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);
|
..targetPlatform = Future<TargetPlatform>.value(TargetPlatform.web_javascript);
|
||||||
final FakeDevice fuchsiaDevice = FakeDevice('fuchsiay', 'fuchsiay')
|
final FakeDevice fuchsiaDevice = FakeDevice('fuchsiay', 'fuchsiay')
|
||||||
..targetPlatform = Future<TargetPlatform>.value(TargetPlatform.fuchsia_x64);
|
..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>[
|
final List<Device> devices = <Device>[
|
||||||
ephemeralOne,
|
ephemeralOne,
|
||||||
nonEphemeralOne,
|
nonEphemeralOne,
|
||||||
@ -193,12 +213,14 @@ void main() {
|
|||||||
devices,
|
devices,
|
||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
);
|
);
|
||||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||||
|
|
||||||
expect(filtered.single, ephemeralOne);
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
ephemeralOne,
|
ephemeralOne,
|
||||||
ephemeralTwo,
|
ephemeralTwo,
|
||||||
@ -211,7 +233,7 @@ void main() {
|
|||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
);
|
);
|
||||||
|
|
||||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||||
|
|
||||||
expect(filtered, <Device>[
|
expect(filtered, <Device>[
|
||||||
ephemeralOne,
|
ephemeralOne,
|
||||||
@ -219,9 +241,11 @@ void main() {
|
|||||||
nonEphemeralOne,
|
nonEphemeralOne,
|
||||||
nonEphemeralTwo,
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
unsupported,
|
unsupported,
|
||||||
unsupportedForProject,
|
unsupportedForProject,
|
||||||
@ -231,15 +255,17 @@ void main() {
|
|||||||
devices,
|
devices,
|
||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
);
|
);
|
||||||
final List<Device> filtered = await deviceManager.getAllConnectedDevices();
|
final List<Device> filtered = await deviceManager.getAllDevices();
|
||||||
|
|
||||||
expect(filtered, <Device>[
|
expect(filtered, <Device>[
|
||||||
unsupported,
|
unsupported,
|
||||||
unsupportedForProject,
|
unsupportedForProject,
|
||||||
]);
|
]);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FlutterProject: () => FakeFlutterProject(),
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('Removes a unsupported devices', () async {
|
testUsingContext('Removes unsupported devices', () async {
|
||||||
final List<Device> devices = <Device>[
|
final List<Device> devices = <Device>[
|
||||||
unsupported,
|
unsupported,
|
||||||
unsupportedForProject,
|
unsupportedForProject,
|
||||||
@ -248,12 +274,14 @@ void main() {
|
|||||||
devices,
|
devices,
|
||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
);
|
);
|
||||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||||
|
|
||||||
expect(filtered, <Device>[]);
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
unsupported,
|
unsupported,
|
||||||
unsupportedForProject,
|
unsupportedForProject,
|
||||||
@ -263,12 +291,16 @@ void main() {
|
|||||||
devices,
|
devices,
|
||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
);
|
);
|
||||||
final List<Device> filtered = await deviceManager.findTargetDevices(null);
|
final List<Device> filtered = await deviceManager.findTargetDevices(
|
||||||
|
includeDevicesUnsupportedByProject: true,
|
||||||
|
);
|
||||||
|
|
||||||
expect(filtered, <Device>[unsupportedForProject]);
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
webDevice,
|
webDevice,
|
||||||
fuchsiaDevice,
|
fuchsiaDevice,
|
||||||
@ -279,12 +311,16 @@ void main() {
|
|||||||
);
|
);
|
||||||
deviceManager.specifiedDeviceId = 'all';
|
deviceManager.specifiedDeviceId = 'all';
|
||||||
|
|
||||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
final List<Device> filtered = await deviceManager.findTargetDevices(
|
||||||
|
includeDevicesUnsupportedByProject: true,
|
||||||
|
);
|
||||||
|
|
||||||
expect(filtered, <Device>[]);
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
nonEphemeralOne,
|
nonEphemeralOne,
|
||||||
nonEphemeralTwo,
|
nonEphemeralTwo,
|
||||||
@ -297,15 +333,17 @@ void main() {
|
|||||||
);
|
);
|
||||||
deviceManager.specifiedDeviceId = 'all';
|
deviceManager.specifiedDeviceId = 'all';
|
||||||
|
|
||||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||||
|
|
||||||
expect(filtered, <Device>[
|
expect(filtered, <Device>[
|
||||||
nonEphemeralOne,
|
nonEphemeralOne,
|
||||||
nonEphemeralTwo,
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
nonEphemeralOne,
|
nonEphemeralOne,
|
||||||
];
|
];
|
||||||
@ -315,14 +353,16 @@ void main() {
|
|||||||
);
|
);
|
||||||
deviceManager.specifiedDeviceId = nonEphemeralOne.id;
|
deviceManager.specifiedDeviceId = nonEphemeralOne.id;
|
||||||
|
|
||||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||||
|
|
||||||
expect(filtered, <Device>[
|
expect(filtered, <Device>[
|
||||||
nonEphemeralOne,
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
nonEphemeralOne,
|
nonEphemeralOne,
|
||||||
nonEphemeralTwo,
|
nonEphemeralTwo,
|
||||||
@ -333,15 +373,17 @@ void main() {
|
|||||||
);
|
);
|
||||||
deviceManager.specifiedDeviceId = 'nonEphemeral'; // This prefix matches both devices
|
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>[
|
expect(filtered, <Device>[
|
||||||
nonEphemeralOne,
|
nonEphemeralOne,
|
||||||
nonEphemeralTwo,
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
nonEphemeralOne,
|
nonEphemeralOne,
|
||||||
];
|
];
|
||||||
@ -351,12 +393,14 @@ void main() {
|
|||||||
);
|
);
|
||||||
deviceManager.specifiedDeviceId = nonEphemeralTwo.id;
|
deviceManager.specifiedDeviceId = nonEphemeralTwo.id;
|
||||||
|
|
||||||
final List<Device> filtered = await deviceManager.findTargetDevices(FakeFlutterProject());
|
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||||
|
|
||||||
expect(filtered, <Device>[]);
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
unsupported,
|
unsupported,
|
||||||
unsupportedForProject,
|
unsupportedForProject,
|
||||||
@ -365,16 +409,106 @@ void main() {
|
|||||||
devices,
|
devices,
|
||||||
logger: BufferLogger.test(),
|
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>[
|
expect(filtered, <Device>[
|
||||||
unsupportedForProject,
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
ephemeralOne,
|
ephemeralOne,
|
||||||
];
|
];
|
||||||
@ -389,16 +523,16 @@ void main() {
|
|||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
);
|
);
|
||||||
deviceManager.specifiedDeviceId = ephemeralOne.id;
|
deviceManager.specifiedDeviceId = ephemeralOne.id;
|
||||||
final List<Device> filtered = await deviceManager.findTargetDevices(
|
final List<Device> filtered = await deviceManager.findTargetDevices();
|
||||||
FakeFlutterProject(),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(filtered.single, ephemeralOne);
|
expect(filtered.single, ephemeralOne);
|
||||||
expect(deviceDiscovery.devicesCalled, 1);
|
expect(deviceDiscovery.devicesCalled, 1);
|
||||||
expect(deviceDiscovery.discoverDevicesCalled, 0);
|
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>[
|
final List<Device> devices = <Device>[
|
||||||
ephemeralOne,
|
ephemeralOne,
|
||||||
];
|
];
|
||||||
@ -415,13 +549,161 @@ void main() {
|
|||||||
);
|
);
|
||||||
deviceManager.specifiedDeviceId = ephemeralOne.id;
|
deviceManager.specifiedDeviceId = ephemeralOne.id;
|
||||||
final List<Device> filtered = await deviceManager.findTargetDevices(
|
final List<Device> filtered = await deviceManager.findTargetDevices(
|
||||||
FakeFlutterProject(),
|
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(filtered.single, ephemeralOne);
|
expect(filtered.single, ephemeralOne);
|
||||||
expect(deviceDiscovery.devicesCalled, 1);
|
expect(deviceDiscovery.devicesCalled, 1);
|
||||||
expect(deviceDiscovery.discoverDevicesCalled, 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,
|
List<DeviceDiscovery>? deviceDiscoveryOverrides,
|
||||||
required super.logger,
|
required super.logger,
|
||||||
String? wellKnownId,
|
String? wellKnownId,
|
||||||
}) : _fakeDeviceDiscoverer = FakePollingDeviceDiscovery(),
|
FakePollingDeviceDiscovery? fakeDiscoverer,
|
||||||
|
}) : _fakeDeviceDiscoverer = fakeDiscoverer ?? FakePollingDeviceDiscovery(),
|
||||||
_deviceDiscoverers = <DeviceDiscovery>[],
|
_deviceDiscoverers = <DeviceDiscovery>[],
|
||||||
super() {
|
super() {
|
||||||
if (wellKnownId != null) {
|
if (wellKnownId != null) {
|
||||||
@ -764,16 +1047,6 @@ class TestDeviceManager extends DeviceManager {
|
|||||||
void resetDevices(List<Device> allDevices) {
|
void resetDevices(List<Device> allDevices) {
|
||||||
_fakeDeviceDiscoverer.setDevices(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 {
|
class MockDeviceDiscovery extends Fake implements DeviceDiscovery {
|
||||||
@ -786,13 +1059,16 @@ class MockDeviceDiscovery extends Fake implements DeviceDiscovery {
|
|||||||
List<Device> deviceValues = <Device>[];
|
List<Device> deviceValues = <Device>[];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> get devices async {
|
Future<List<Device>> devices({DeviceDiscoveryFilter? filter}) async {
|
||||||
devicesCalled += 1;
|
devicesCalled += 1;
|
||||||
return deviceValues;
|
return deviceValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> discoverDevices({Duration? timeout}) async {
|
Future<List<Device>> discoverDevices({
|
||||||
|
Duration? timeout,
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) async {
|
||||||
discoverDevicesCalled += 1;
|
discoverDevicesCalled += 1;
|
||||||
return deviceValues;
|
return deviceValues;
|
||||||
}
|
}
|
||||||
@ -801,6 +1077,43 @@ class MockDeviceDiscovery extends Fake implements DeviceDiscovery {
|
|||||||
List<String> get wellKnownIds => <String>[];
|
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 FakeFlutterProject extends Fake implements FlutterProject { }
|
||||||
|
|
||||||
class LongPollingDeviceDiscovery extends PollingDeviceDiscovery {
|
class LongPollingDeviceDiscovery extends PollingDeviceDiscovery {
|
||||||
|
@ -67,7 +67,7 @@ void main() {
|
|||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
processManager: FakeProcessManager.any(),
|
processManager: FakeProcessManager.any(),
|
||||||
operatingSystemUtils: FakeOperatingSystemUtils(),
|
operatingSystemUtils: FakeOperatingSystemUtils(),
|
||||||
).devices, <Device>[]);
|
).devices(), <Device>[]);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('LinuxDevice: no devices listed if Linux feature flag disabled', () async {
|
testWithoutContext('LinuxDevice: no devices listed if Linux feature flag disabled', () async {
|
||||||
@ -78,7 +78,7 @@ void main() {
|
|||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
processManager: FakeProcessManager.any(),
|
processManager: FakeProcessManager.any(),
|
||||||
operatingSystemUtils: FakeOperatingSystemUtils(),
|
operatingSystemUtils: FakeOperatingSystemUtils(),
|
||||||
).devices, <Device>[]);
|
).devices(), <Device>[]);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('LinuxDevice: devices', () async {
|
testWithoutContext('LinuxDevice: devices', () async {
|
||||||
@ -89,7 +89,7 @@ void main() {
|
|||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
processManager: FakeProcessManager.any(),
|
processManager: FakeProcessManager.any(),
|
||||||
operatingSystemUtils: FakeOperatingSystemUtils(),
|
operatingSystemUtils: FakeOperatingSystemUtils(),
|
||||||
).devices, hasLength(1));
|
).devices(), hasLength(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('LinuxDevice has well known id "linux"', () async {
|
testWithoutContext('LinuxDevice has well known id "linux"', () async {
|
||||||
|
@ -93,7 +93,7 @@ void main() {
|
|||||||
featureFlags: TestFeatureFlags(isMacOSEnabled: true),
|
featureFlags: TestFeatureFlags(isMacOSEnabled: true),
|
||||||
platform: linux,
|
platform: linux,
|
||||||
),
|
),
|
||||||
).devices, isEmpty);
|
).devices(), isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('No devices listed if platform is supported and feature is disabled', () async {
|
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 {
|
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 {
|
testWithoutContext('has a well known device id macos', () async {
|
||||||
|
@ -50,7 +50,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
expect(discoverer.supportsPlatform, isTrue);
|
expect(discoverer.supportsPlatform, isTrue);
|
||||||
|
|
||||||
final List<Device> devices = await discoverer.devices;
|
final List<Device> devices = await discoverer.devices();
|
||||||
expect(devices, isEmpty);
|
expect(devices, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
expect(discoverer.supportsPlatform, isTrue);
|
expect(discoverer.supportsPlatform, isTrue);
|
||||||
|
|
||||||
final List<Device> devices = await discoverer.devices;
|
final List<Device> devices = await discoverer.devices();
|
||||||
expect(devices, isEmpty);
|
expect(devices, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
expect(discoverer.supportsPlatform, isTrue);
|
expect(discoverer.supportsPlatform, isTrue);
|
||||||
|
|
||||||
final List<Device> devices = await discoverer.devices;
|
final List<Device> devices = await discoverer.devices();
|
||||||
expect(devices, isEmpty);
|
expect(devices, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
expect(discoverer.supportsPlatform, isTrue);
|
expect(discoverer.supportsPlatform, isTrue);
|
||||||
|
|
||||||
List<Device> devices = await discoverer.devices;
|
List<Device> devices = await discoverer.devices();
|
||||||
expect(devices, hasLength(1));
|
expect(devices, hasLength(1));
|
||||||
|
|
||||||
final Device device = devices.single;
|
final Device device = devices.single;
|
||||||
|
@ -47,7 +47,7 @@ void main() {
|
|||||||
testWithoutContext('no device', () async {
|
testWithoutContext('no device', () async {
|
||||||
final FlutterTesterDevices discoverer = setUpFlutterTesterDevices();
|
final FlutterTesterDevices discoverer = setUpFlutterTesterDevices();
|
||||||
|
|
||||||
final List<Device> devices = await discoverer.devices;
|
final List<Device> devices = await discoverer.devices();
|
||||||
expect(devices, isEmpty);
|
expect(devices, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ void main() {
|
|||||||
FlutterTesterDevices.showFlutterTesterDevice = true;
|
FlutterTesterDevices.showFlutterTesterDevice = true;
|
||||||
final FlutterTesterDevices discoverer = setUpFlutterTesterDevices();
|
final FlutterTesterDevices discoverer = setUpFlutterTesterDevices();
|
||||||
|
|
||||||
final List<Device> devices = await discoverer.devices;
|
final List<Device> devices = await discoverer.devices();
|
||||||
expect(devices, hasLength(1));
|
expect(devices, hasLength(1));
|
||||||
|
|
||||||
final Device device = devices.single;
|
final Device device = devices.single;
|
||||||
|
@ -48,7 +48,7 @@ void main() {
|
|||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
processManager: FakeProcessManager.any(),
|
processManager: FakeProcessManager.any(),
|
||||||
fileSystem: MemoryFileSystem.test(),
|
fileSystem: MemoryFileSystem.test(),
|
||||||
).devices, <Device>[]);
|
).devices(), <Device>[]);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('WindowsDevices lists a devices if the workflow is supported', () async {
|
testWithoutContext('WindowsDevices lists a devices if the workflow is supported', () async {
|
||||||
@ -61,7 +61,7 @@ void main() {
|
|||||||
logger: BufferLogger.test(),
|
logger: BufferLogger.test(),
|
||||||
processManager: FakeProcessManager.any(),
|
processManager: FakeProcessManager.any(),
|
||||||
fileSystem: MemoryFileSystem.test(),
|
fileSystem: MemoryFileSystem.test(),
|
||||||
).devices, hasLength(1));
|
).devices(), hasLength(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('isSupportedForProject is true with editable host app', () async {
|
testWithoutContext('isSupportedForProject is true with editable host app', () async {
|
||||||
|
@ -207,21 +207,31 @@ class FakeDeviceManager implements DeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> getAllConnectedDevices() async => devices;
|
Future<List<Device>> getAllDevices({
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) async => devices;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> refreshAllConnectedDevices({ Duration? timeout }) async => devices;
|
Future<List<Device>> refreshAllDevices({
|
||||||
|
Duration? timeout,
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) async => devices;
|
||||||
|
|
||||||
@override
|
@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();
|
return devices.where((Device device) => device.id == deviceId).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> getDevices() {
|
Future<List<Device>> getDevices({
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) {
|
||||||
return hasSpecifiedDeviceId
|
return hasSpecifiedDeviceId
|
||||||
? getDevicesById(specifiedDeviceId!)
|
? getDevicesById(specifiedDeviceId!, filter: filter)
|
||||||
: getAllConnectedDevices();
|
: getAllDevices(filter: filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDevice(Device device) => devices.add(device);
|
void addDevice(Device device) => devices.add(device);
|
||||||
@ -236,16 +246,27 @@ class FakeDeviceManager implements DeviceManager {
|
|||||||
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];
|
List<DeviceDiscovery> get deviceDiscoverers => <DeviceDiscovery>[];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isDeviceSupportedForProject(Device device, FlutterProject? flutterProject) {
|
Future<List<Device>> findTargetDevices({
|
||||||
return device.isSupportedForProject(flutterProject!);
|
bool includeDevicesUnsupportedByProject = false,
|
||||||
|
Duration? timeout,
|
||||||
|
bool promptUserToChooseDevice = true,
|
||||||
|
}) async {
|
||||||
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> findTargetDevices(FlutterProject? flutterProject, { Duration? timeout, bool promptUserToChooseDevice = true }) async {
|
DeviceDiscoverySupportFilter deviceSupportFilter({
|
||||||
return devices;
|
bool includeDevicesUnsupportedByProject = false,
|
||||||
|
FlutterProject? flutterProject,
|
||||||
|
}) {
|
||||||
|
return TestDeviceDiscoverySupportFilter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestDeviceDiscoverySupportFilter extends Fake implements DeviceDiscoverySupportFilter {
|
||||||
|
TestDeviceDiscoverySupportFilter();
|
||||||
|
}
|
||||||
|
|
||||||
class FakeAndroidLicenseValidator extends Fake implements AndroidLicenseValidator {
|
class FakeAndroidLicenseValidator extends Fake implements AndroidLicenseValidator {
|
||||||
@override
|
@override
|
||||||
Future<LicensesAccepted> get licensesAccepted async => LicensesAccepted.all;
|
Future<LicensesAccepted> get licensesAccepted async => LicensesAccepted.all;
|
||||||
|
@ -62,6 +62,8 @@ class FakeDevice extends Device {
|
|||||||
bool ephemeral = true,
|
bool ephemeral = true,
|
||||||
bool isSupported = true,
|
bool isSupported = true,
|
||||||
bool isSupportedForProject = true,
|
bool isSupportedForProject = true,
|
||||||
|
this.isConnected = true,
|
||||||
|
this.connectionInterface = DeviceConnectionInterface.attached,
|
||||||
PlatformType type = PlatformType.web,
|
PlatformType type = PlatformType.web,
|
||||||
LaunchResult? launchResult,
|
LaunchResult? launchResult,
|
||||||
}) : _isSupported = isSupported,
|
}) : _isSupported = isSupported,
|
||||||
@ -118,6 +120,12 @@ class FakeDevice extends Device {
|
|||||||
@override
|
@override
|
||||||
bool isSupported() => _isSupported;
|
bool isSupported() => _isSupported;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isConnected;
|
||||||
|
|
||||||
|
@override
|
||||||
|
DeviceConnectionInterface connectionInterface;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> isLocalEmulator = Future<bool>.value(true);
|
Future<bool> isLocalEmulator = Future<bool>.value(true);
|
||||||
|
|
||||||
@ -174,7 +182,10 @@ class FakePollingDeviceDiscovery extends PollingDeviceDiscovery {
|
|||||||
bool discoverDevicesCalled = false;
|
bool discoverDevicesCalled = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Device>> discoverDevices({Duration? timeout}) {
|
Future<List<Device>> discoverDevices({
|
||||||
|
Duration? timeout,
|
||||||
|
DeviceDiscoveryFilter? filter,
|
||||||
|
}) {
|
||||||
discoverDevicesCalled = true;
|
discoverDevicesCalled = true;
|
||||||
return super.discoverDevices(timeout: timeout);
|
return super.discoverDevices(timeout: timeout);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user