Unverified Commit 6c8d7b00 authored by JustWe's avatar JustWe Committed by GitHub

Show unsupported devices when no supported devices are connected (#56531)

parent 91e7678f
......@@ -237,6 +237,9 @@ class UserMessages {
"matching '$deviceId'";
String get flutterNoDevicesFound => 'No devices found';
String get flutterNoSupportedDevices => 'No supported devices connected.';
String flutterMissPlatformProjects(List<String> unsupportedDevicesType) =>
'If you would like your app to run on ${unsupportedDevicesType.join(' or ')}, consider running `flutter create .` to generate projects for these platforms.';
String get flutterFoundButUnsupportedDevices => 'The following devices were found, but are not supported by this project:';
String flutterFoundSpecifiedDevices(int count, String deviceId) =>
'Found $count devices with name or id matching $deviceId:';
String get flutterSpecifyDeviceWithAllOption =>
......
......@@ -557,6 +557,13 @@ abstract class Device {
await descriptions(devices).forEach(globals.printStatus);
}
static List<String> devicesPlatformTypes(List<Device> devices) {
return devices
.map(
(Device d) => d.platformType.toString(),
).toSet().toList()..sort();
}
/// Convert the Device object to a JSON representation suitable for serialization.
Future<Map<String, Object>> toJson() async {
final bool isLocalEmu = await isLocalEmulator;
......
......@@ -823,11 +823,28 @@ abstract class FlutterCommand extends Command<void> {
if (devices.isEmpty && deviceManager.hasSpecifiedDeviceId) {
globals.printStatus(userMessages.flutterNoMatchingDevice(deviceManager.specifiedDeviceId));
return null;
} else if (devices.isEmpty && deviceManager.hasSpecifiedAllDevices) {
globals.printStatus(userMessages.flutterNoDevicesFound);
return null;
} else if (devices.isEmpty) {
globals.printStatus(userMessages.flutterNoSupportedDevices);
if (deviceManager.hasSpecifiedAllDevices) {
globals.printStatus(userMessages.flutterNoDevicesFound);
} else {
globals.printStatus(userMessages.flutterNoSupportedDevices);
}
final List<Device> unsupportedDevices = await deviceManager.getDevices();
if (unsupportedDevices.isNotEmpty) {
final StringBuffer result = StringBuffer();
result.writeln(userMessages.flutterFoundButUnsupportedDevices);
result.writeAll(
await Device.descriptions(unsupportedDevices)
.map((String desc) => desc)
.toList(),
'\n',
);
result.writeln('');
result.writeln(userMessages.flutterMissPlatformProjects(
Device.devicesPlatformTypes(unsupportedDevices),
));
globals.printStatus(result.toString());
}
return null;
} else if (devices.length > 1 && !deviceManager.hasSpecifiedAllDevices) {
if (deviceManager.hasSpecifiedDeviceId) {
......
......@@ -38,6 +38,16 @@ void main() {
ProcessManager: () => MockProcessManager(),
});
testUsingContext('get devices\' platform types', () async {
final List<String> platformTypes = Device.devicesPlatformTypes(
await deviceManager.getAllConnectedDevices(),
);
expect(platformTypes, <String>['android', 'web']);
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(),
ProcessManager: () => MockProcessManager(),
});
testUsingContext('Outputs parsable JSON with --machine flag', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--machine']);
......
......@@ -241,6 +241,62 @@ void main() {
ProcessManager: () => mockProcessManager,
});
testUsingContext('shows unsupported devices when no supported devices are found', () async {
final RunCommand command = RunCommand();
applyMocksToCommand(command);
final MockDevice mockDevice = MockDevice(TargetPlatform.android_arm);
when(mockDevice.isLocalEmulator).thenAnswer((Invocation invocation) => Future<bool>.value(true));
when(mockDevice.isSupported()).thenAnswer((Invocation invocation) => true);
when(mockDevice.supportsFastStart).thenReturn(true);
when(mockDevice.id).thenReturn('mock-id');
when(mockDevice.name).thenReturn('mock-name');
when(mockDevice.platformType).thenReturn(PlatformType.android);
when(mockDevice.sdkNameAndVersion).thenAnswer((Invocation invocation) => Future<String>.value('api-14'));
when(mockDeviceManager.getDevices()).thenAnswer((Invocation invocation) {
return Future<List<Device>>.value(<Device>[
mockDevice,
]);
});
when(mockDeviceManager.findTargetDevices(any)).thenAnswer(
(Invocation invocation) => Future<List<Device>>.value(<Device>[]),
);
try {
await createTestCommandRunner(command).run(<String>[
'run',
'--no-pub',
'--no-hot',
]);
fail('Expect exception');
} on ToolExit catch (e) {
expect(e.message, null);
}
expect(
testLogger.statusText,
containsIgnoringWhitespace(userMessages.flutterNoSupportedDevices),
);
expect(
testLogger.statusText,
containsIgnoringWhitespace(userMessages.flutterFoundButUnsupportedDevices),
);
expect(
testLogger.statusText,
containsIgnoringWhitespace(
userMessages.flutterMissPlatformProjects(
Device.devicesPlatformTypes(<Device>[mockDevice]),
),
),
);
}, overrides: <Type, Generator>{
DeviceManager: () => mockDeviceManager,
FileSystem: () => fs,
ProcessManager: () => mockProcessManager,
});
testUsingContext('updates cache before checking for devices', () async {
final RunCommand command = RunCommand();
applyMocksToCommand(command);
......
......@@ -11,7 +11,7 @@ import 'package:flutter_tools/src/project.dart';
/// (`Device.toJson()` and `--machine` flag for `devices` command)
List<FakeDeviceJsonData> fakeDevices = <FakeDeviceJsonData>[
FakeDeviceJsonData(
FakeDevice('ephemeral', 'ephemeral', true),
FakeDevice('ephemeral', 'ephemeral', true, true, PlatformType.android),
<String, Object>{
'name': 'ephemeral',
'id': 'ephemeral',
......@@ -56,9 +56,9 @@ List<FakeDeviceJsonData> fakeDevices = <FakeDeviceJsonData>[
/// Fake device to test `devices` command
class FakeDevice extends Device {
FakeDevice(this.name, String id, [bool ephemeral = true, this._isSupported = true]) : super(
FakeDevice(this.name, String id, [bool ephemeral = true, this._isSupported = true, PlatformType type = PlatformType.web]) : super(
id,
platformType: PlatformType.web,
platformType: type,
category: Category.mobile,
ephemeral: ephemeral,
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment