@@ -9,13 +9,10 @@ import 'package:meta/meta.dart';
99
1010import 'application_package.dart' ;
1111import 'artifacts.dart' ;
12- import 'base/common.dart' ;
1312import 'base/context.dart' ;
1413import 'base/dds.dart' ;
1514import 'base/file_system.dart' ;
1615import 'base/logger.dart' ;
17- import 'base/terminal.dart' ;
18- import 'base/user_messages.dart' hide userMessages;
1916import 'base/utils.dart' ;
2017import 'build_info.dart' ;
2118import 'devfs.dart' ;
@@ -83,15 +80,9 @@ class PlatformType {
8380abstract class DeviceManager {
8481 DeviceManager ({
8582 required Logger logger,
86- required Terminal terminal,
87- required UserMessages userMessages,
88- }) : _logger = logger,
89- _terminal = terminal,
90- _userMessages = userMessages;
83+ }) : _logger = logger;
9184
9285 final Logger _logger;
93- final Terminal _terminal;
94- final UserMessages _userMessages;
9586
9687 /// Constructing DeviceManagers is cheap; they only do expensive work if some
9788 /// of their methods are called.
@@ -219,7 +210,12 @@ abstract class DeviceManager {
219210 ];
220211 }
221212
222- /// Find and return a list of devices based on the current project and environment.
213+ /// Find and return all target [Device] s based upon currently connected
214+ /// devices, the current project, and criteria entered by the user on
215+ /// the command line.
216+ ///
217+ /// If no device can be found that meets specified criteria,
218+ /// then print an error message and return null.
223219 ///
224220 /// Returns a list of devices specified by the user.
225221 ///
@@ -233,9 +229,13 @@ abstract class DeviceManager {
233229 /// device connected, then filter out unsupported devices and prioritize
234230 /// ephemeral devices.
235231 ///
236- /// * If [flutterProject] is null, then assume the project supports all
237- /// device types.
238- Future <List <Device >> findTargetDevices (FlutterProject ? flutterProject, { Duration ? timeout }) async {
232+ /// * If [promptUserToChooseDevice] is true, and there are more than one
233+ /// device after the aforementioned filters, and the user is connected to a
234+ /// terminal, then show a prompt asking the user to choose one.
235+ Future <List <Device >> findTargetDevices (
236+ FlutterProject ? flutterProject, {
237+ Duration ? timeout,
238+ }) async {
239239 if (timeout != null ) {
240240 // Reset the cache with the specified timeout.
241241 await refreshAllConnectedDevices (timeout: timeout);
@@ -244,95 +244,54 @@ abstract class DeviceManager {
244244 List <Device > devices = (await getDevices ())
245245 .where ((Device device) => device.isSupported ()).toList ();
246246
247- // Always remove web and fuchsia devices from `--all`. This setting
248- // currently requires devices to share a frontend_server and resident
249- // runner instance. Both web and fuchsia require differently configured
250- // compilers, and web requires an entirely different resident runner.
251247 if (hasSpecifiedAllDevices) {
248+ // User has specified `--device all`.
249+ //
250+ // Always remove web and fuchsia devices from `--all`. This setting
251+ // currently requires devices to share a frontend_server and resident
252+ // runner instance. Both web and fuchsia require differently configured
253+ // compilers, and web requires an entirely different resident runner.
252254 devices = < Device > [
253255 for (final Device device in devices)
254256 if (await device.targetPlatform != TargetPlatform .fuchsia_arm64 &&
255257 await device.targetPlatform != TargetPlatform .fuchsia_x64 &&
256- await device.targetPlatform != TargetPlatform .web_javascript)
258+ await device.targetPlatform != TargetPlatform .web_javascript &&
259+ isDeviceSupportedForProject (device, flutterProject))
257260 device,
258261 ];
259- }
262+ } else if (! hasSpecifiedDeviceId) {
263+ // User did not specify the device.
260264
261- // If there is no specified device, the remove all devices which are not
262- // supported by the current application. For example, if there was no
263- // 'android' folder then don't attempt to launch with an Android device.
264- if (devices.length > 1 && ! hasSpecifiedDeviceId) {
265+ // Remove all devices which are not supported by the current application.
266+ // For example, if there was no 'android' folder then don't attempt to
267+ // launch with an Android device.
265268 devices = < Device > [
266269 for (final Device device in devices)
267270 if (isDeviceSupportedForProject (device, flutterProject))
268271 device,
269272 ];
270- } else if (devices.length == 1 &&
271- ! hasSpecifiedDeviceId &&
272- ! isDeviceSupportedForProject (devices.single, flutterProject)) {
273- // If there is only a single device but it is not supported, then return
274- // early.
275- return < Device > [];
276- }
277273
278- // If there are still multiple devices and the user did not specify to run
279- // all, then attempt to prioritize ephemeral devices. For example, if the
280- // user only typed 'flutter run' and both an Android device and desktop
281- // device are available, choose the Android device.
282- if (devices.length > 1 && ! hasSpecifiedAllDevices) {
283- // Note: ephemeral is nullable for device types where this is not well
284- // defined.
285- if (devices.any ((Device device) => device.ephemeral == true )) {
286- // if there is only one ephemeral device, get it
287- final List <Device > ephemeralDevices = devices
288- .where ((Device device) => device.ephemeral == true )
289- .toList ();
290-
291- if (ephemeralDevices.length == 1 ) {
292- devices = ephemeralDevices;
293- }
274+ if (devices.length > 1 ) {
275+ // If there are still multiple devices and the user did not specify to run
276+ // all, then attempt to prioritize ephemeral devices. For example, if the
277+ // user only typed 'flutter run' and both an Android device and desktop
278+ // device are available, choose the Android device.
279+
280+ // Note: ephemeral is nullable for device types where this is not well
281+ // defined.
282+ final List <Device > ephemeralDevices = < Device > [
283+ for (final Device device in devices)
284+ if (device.ephemeral == true )
285+ device,
286+ ];
287+
288+ if (ephemeralDevices.length == 1 ) {
289+ devices = ephemeralDevices;
290+ }
294291 }
295- // If it was not able to prioritize a device. For example, if the user
296- // has two active Android devices running, then we request the user to
297- // choose one. If the user has two nonEphemeral devices running, we also
298- // request input to choose one.
299- if (devices.length > 1 && _terminal.stdinHasTerminal) {
300- _logger.printStatus (_userMessages.flutterMultipleDevicesFound);
301- await Device .printDevices (devices, _logger);
302- final Device chosenDevice = await _chooseOneOfAvailableDevices (devices);
303- specifiedDeviceId = chosenDevice.id;
304- devices = < Device > [chosenDevice];
305- }
306- }
307- return devices;
308- }
309-
310- Future <Device > _chooseOneOfAvailableDevices (List <Device > devices) async {
311- _displayDeviceOptions (devices);
312- final String userInput = await _readUserInput (devices.length);
313- if (userInput.toLowerCase () == 'q' ) {
314- throwToolExit ('' );
315- }
316- return devices[int .parse (userInput) - 1 ];
317- }
318-
319- void _displayDeviceOptions (List <Device > devices) {
320- int count = 1 ;
321- for (final Device device in devices) {
322- _logger.printStatus (_userMessages.flutterChooseDevice (count, device.name, device.id));
323- count++ ;
324292 }
325- }
326293
327- Future <String > _readUserInput (int deviceCount) async {
328- _terminal.usesTerminalUi = true ;
329- final String result = await _terminal.promptForCharInput (
330- < String > [ for (int i = 0 ; i < deviceCount; i++ ) '${i + 1 }' , 'q' , 'Q' ],
331- displayAcceptedCharacters: false ,
332- logger: _logger,
333- prompt: _userMessages.flutterChooseOne,
334- );
335- return result;
294+ return devices;
336295 }
337296
338297 /// Returns whether the device is supported for the project.
0 commit comments