Prefer ephemeral devices from command line run (#34802)

diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index 245ca6d..8443ba4 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -517,12 +517,8 @@
     }
 
     devices = devices.where((Device device) => device.isSupported()).toList();
-    // If the user has not specified all devices and has multiple connected
-    // then filter then list by those supported in the current project. If
-    // this ends up with a single device we can proceed as normal.
     if (devices.length > 1 && !deviceManager.hasSpecifiedAllDevices && !deviceManager.hasSpecifiedDeviceId) {
-      final FlutterProject flutterProject = FlutterProject.current();
-      devices.removeWhere((Device device) => !device.isSupportedForProject(flutterProject));
+      devices = filterDevices(devices);
     }
 
     if (devices.isEmpty) {
@@ -698,3 +694,24 @@
     );
   }
 }
+
+// If the user has not specified all devices and has multiple connected
+// then filter the list by those supported in the current project and
+// remove non-ephemeral device types. If this ends up with a single
+// device we can proceed as normal.
+@visibleForTesting
+List<Device> filterDevices(List<Device> devices) {
+  final FlutterProject flutterProject = FlutterProject.current();
+  devices = devices
+      .where((Device device) => device.isSupportedForProject(flutterProject))
+      .toList();
+
+  // Note: ephemeral is nullable for device types where this is not well
+  // defined.
+  if (devices.any((Device device) => device.ephemeral == true)) {
+    devices = devices
+        .where((Device device) => device.ephemeral == true)
+        .toList();
+  }
+  return devices;
+}
diff --git a/packages/flutter_tools/test/runner/flutter_command_test.dart b/packages/flutter_tools/test/runner/flutter_command_test.dart
index a402b1d..bc6582b 100644
--- a/packages/flutter_tools/test/runner/flutter_command_test.dart
+++ b/packages/flutter_tools/test/runner/flutter_command_test.dart
@@ -4,6 +4,8 @@
 
 import 'package:flutter_tools/src/cache.dart';
 import 'package:flutter_tools/src/base/time.dart';
+import 'package:flutter_tools/src/device.dart';
+import 'package:flutter_tools/src/project.dart';
 import 'package:flutter_tools/src/usage.dart';
 import 'package:flutter_tools/src/base/common.dart';
 import 'package:flutter_tools/src/runner/flutter_command.dart';
@@ -289,6 +291,43 @@
       FlutterVersion: () => betaVersion,
     });
   });
+
+  group('Filter devices', () {
+    MockDevice ephemeral;
+    MockDevice nonEphemeralOne;
+    MockDevice nonEphemeralTwo;
+    MockDevice unsupported;
+
+    setUp(() {
+      ephemeral = MockDevice(true);
+      nonEphemeralOne = MockDevice(false);
+      nonEphemeralTwo = MockDevice(false);
+      unsupported = MockDevice(true, false);
+    });
+
+    test('chooses ephemeral device', () {
+      final List<Device> filtered = filterDevices(<Device>[
+        ephemeral,
+        nonEphemeralOne,
+        nonEphemeralTwo,
+        unsupported,
+      ]);
+
+      expect(filtered.single, ephemeral);
+    });
+
+    test('does not remove all non-ephemeral', () {
+      final List<Device> filtered = filterDevices(<Device>[
+        nonEphemeralOne,
+        nonEphemeralTwo,
+      ]);
+
+      expect(filtered, <Device>[
+        nonEphemeralOne,
+        nonEphemeralTwo,
+      ]);
+    });
+  });
 }
 
 
@@ -309,3 +348,15 @@
 }
 
 class MockVersion extends Mock implements FlutterVersion {}
+
+class MockDevice extends Mock implements Device {
+  MockDevice(this.ephemeral, [this._isSupported = true]);
+
+  @override
+  final bool ephemeral;
+
+  bool _isSupported;
+
+  @override
+  bool isSupportedForProject(FlutterProject flutterProject) => _isSupported;
+}