Skip to content

Commit 66c8316

Browse files
authored
Android doctor: more robust canrun (flutter#167489)
Fixes error found in rolling to google. ``` [☠] Android toolchain - develop for Android devices (the doctor check crashed) ✗ Due to an error, the doctor check did not complete. If the error message below is not helpful, please let us know about this issue at https://github.com/flutter/flutter/issues. ✗ type 'Null' is not a subtype of type 'String' of 'executable' • #0 LocalProcessManager.canRun (package:process/src/interface/local_process_manager.dart:124) #1 getEmulatorVersion (package:flutter_tools/src/android/android_workflow.dart:64) #2 AndroidValidator.validateImpl (package:flutter_tools/src/android/android_workflow.dart:200) #3 DoctorValidator.validate (package:flutter_tools/src/doctor_validator.dart:58) flutter#4 Doctor.startValidatorTasks.<anonymous closure> (package:flutter_tools/src/doctor.dart:244) flutter#5 asyncGuard.<anonymous closure> (package:flutter_tools/src/base/async_guard.dart:109) flutter#6 _rootRun (dart:async/zone.dart:1525) flutter#7 _CustomZone.run (dart:async/zone.dart:1422) flutter#8 _runZoned (dart:async/zone.dart:2033) flutter#9 runZonedGuarded (dart:async/zone.dart:2019) flutter#10 runZoned (dart:async/zone.dart:1952) flutter#11 asyncGuard (package:flutter_tools/src/base/async_guard.dart:106) flutter#12 Doctor.startValidatorTasks (package:flutter_tools/src/doctor.dart:234) flutter#13 Doctor.diagnose (package:flutter_tools/src/doctor.dart:372) flutter#14 DoctorCommand.runCommand (package:flutter_tools/src/commands/doctor.dart:59) flutter#15 FlutterCommand.verifyThenRunCommand (package:flutter_tools/src/runner/flutter_command.dart:1897) <asynchronous suspension> flutter#16 FlutterCommand.run.<anonymous closure> (package:flutter_tools/src/runner/flutter_command.dart:1551) <asynchronous suspension> flutter#17 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:154) <asynchronous suspension> flutter#18 CommandRunner.runCommand (package:args/command_runner.dart:212) <asynchronous suspension> flutter#19 FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:501) <asynchronous suspension> flutter#20 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:154) <asynchronous suspension> flutter#21 FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:438) <asynchronous suspension> flutter#22 run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:98) <asynchronous suspension> flutter#23 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:154) <asynchronous suspension> flutter#24 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:154) <asynchronous suspension> flutter#25 run (package:mobile.flutter.cli/flutter_tools.dart:106) <asynchronous suspension> flutter#26 main (google3:///mobile/flutter/cli/bin/cli_usage_aot.dart:4) ``` ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent c169a17 commit 66c8316

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

packages/flutter_tools/lib/src/android/android_workflow.dart

+6-4
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ class AndroidWorkflow implements Workflow {
6161
}
6262

6363
Future<String?> getEmulatorVersion(AndroidSdk androidSdk, ProcessManager processManager) async {
64-
if (!processManager.canRun(androidSdk.emulatorPath)) {
65-
return null;
66-
}
67-
6864
try {
65+
if (!processManager.canRun(androidSdk.emulatorPath)) {
66+
return null;
67+
}
68+
6969
final ProcessResult result = await processManager.run(<Object>[
7070
androidSdk.emulatorPath!,
7171
'-version',
@@ -94,6 +94,8 @@ Future<String?> getEmulatorVersion(AndroidSdk androidSdk, ProcessManager process
9494
}
9595
} on Exception catch (e, _) {
9696
return null;
97+
} on Error catch (_) {
98+
return null;
9799
}
98100
}
99101

packages/flutter_tools/test/general.shard/android/android_workflow_test.dart

+24
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,30 @@ Review licenses that have not been accepted (y/N)?
455455
expect(sdkMessage.message, 'Emulator version 35.2.10.0 (build_id 12414864) (CL:N/A)');
456456
});
457457

458+
testUsingContext('includes emulator version - no emulator path', () async {
459+
sdk
460+
..licensesAvailable = true
461+
..platformToolsAvailable = false
462+
..cmdlineToolsAvailable = true
463+
..directory = fileSystem.directory('/foo/bar')
464+
..emulatorPath = null;
465+
final ValidationResult validationResult =
466+
await AndroidValidator(
467+
java: FakeJava(),
468+
androidSdk: sdk,
469+
logger: logger,
470+
platform: FakePlatform()..environment = <String, String>{'HOME': '/home/me'},
471+
userMessages: UserMessages(),
472+
processManager: processManager,
473+
).validate();
474+
475+
expect(validationResult.type, ValidationType.partial);
476+
expect(validationResult.messages.length > 2, isTrue);
477+
final ValidationMessage sdkMessage = validationResult.messages[1];
478+
expect(sdkMessage.type, ValidationMessageType.information);
479+
expect(sdkMessage.message, 'Emulator version unknown');
480+
});
481+
458482
testUsingContext('detects license-only SDK installation with cmdline-tools', () async {
459483
sdk
460484
..licensesAvailable = true

0 commit comments

Comments
 (0)