diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index fca1f52f19..75d417668d 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart @@ -495,7 +495,7 @@ class RunCommand extends RunCommandBase { } if (userIdentifier != null - && devices!.every((Device device) => device is! AndroidDevice)) { + && devices!.every((Device device) => device.platformType != PlatformType.android)) { throwToolExit( '--${FlutterOptions.kDeviceUser} is only supported for Android. At least one Android device is required.' ); diff --git a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart index 3047ce8b03..7eb2d8263c 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart @@ -221,16 +221,13 @@ void main() { }); testUsingContext('fails when targeted device is not Android with --device-user', () async { - fs.file('pubspec.yaml').createSync(); - fs.file('.packages').writeAsStringSync('\n'); - fs.file('lib/main.dart').createSync(recursive: true); final FakeDevice device = FakeDevice(isLocalEmulator: true); mockDeviceManager ..devices = [device] ..targetDevices = [device]; - final RunCommand command = RunCommand(); + final TestRunCommandThatOnlyValidates command = TestRunCommandThatOnlyValidates(); await expectLater(createTestCommandRunner(command).run([ 'run', '--no-pub', @@ -245,6 +242,29 @@ void main() { Cache: () => Cache.test(processManager: FakeProcessManager.any()), }); + testUsingContext('succeeds when targeted device is an Android device with --device-user', () async { + final FakeDevice device = FakeDevice(isLocalEmulator: true, platformType: PlatformType.android); + + mockDeviceManager + ..devices = [device] + ..targetDevices = [device]; + + final TestRunCommandThatOnlyValidates command = TestRunCommandThatOnlyValidates(); + await createTestCommandRunner(command).run([ + 'run', + '--no-pub', + '--device-user', + '10', + ]); + // Finishes normally without error. + }, overrides: { + FileSystem: () => fs, + ProcessManager: () => FakeProcessManager.any(), + DeviceManager: () => mockDeviceManager, + Stdio: () => FakeStdio(), + Cache: () => Cache.test(processManager: FakeProcessManager.any()), + }); + testUsingContext('fails when v1 FlutterApplication is detected', () async { fs.file('pubspec.yaml').createSync(); fs.file('android/AndroidManifest.xml') @@ -876,16 +896,22 @@ class FakeAndroidSdk extends Fake implements AndroidSdk { // Until we fix that, we have to also ignore related lints here. // ignore: avoid_implementing_value_types class FakeDevice extends Fake implements Device { - FakeDevice({bool isLocalEmulator = false, TargetPlatform targetPlatform = TargetPlatform.ios, String sdkNameAndVersion = ''}) - : _isLocalEmulator = isLocalEmulator, - _targetPlatform = targetPlatform, - _sdkNameAndVersion = sdkNameAndVersion; + FakeDevice({ + bool isLocalEmulator = false, + TargetPlatform targetPlatform = TargetPlatform.ios, + String sdkNameAndVersion = '', + PlatformType platformType = PlatformType.ios, + }): _isLocalEmulator = isLocalEmulator, + _targetPlatform = targetPlatform, + _sdkNameAndVersion = sdkNameAndVersion, + _platformType = platformType; static const int kSuccess = 1; static const int kFailure = -1; final TargetPlatform _targetPlatform; final bool _isLocalEmulator; final String _sdkNameAndVersion; + final PlatformType _platformType; @override Category get category => Category.mobile; @@ -943,7 +969,7 @@ class FakeDevice extends Fake implements Device { Future get targetPlatform async => _targetPlatform; @override - final PlatformType platformType = PlatformType.ios; + PlatformType get platformType => _platformType; bool startAppSuccess; @@ -1012,6 +1038,13 @@ class TestRunCommandWithFakeResidentRunner extends RunCommand { } } +class TestRunCommandThatOnlyValidates extends RunCommand { + @override + Future runCommand() async { + return FlutterCommandResult.success(); + } +} + class FakeResidentRunner extends Fake implements ResidentRunner { RPCError rpcError;