diff --git a/packages/flutter_tools/lib/src/android/android_workflow.dart b/packages/flutter_tools/lib/src/android/android_workflow.dart index 4b3649dc5f..14cc860a4e 100644 --- a/packages/flutter_tools/lib/src/android/android_workflow.dart +++ b/packages/flutter_tools/lib/src/android/android_workflow.dart @@ -185,10 +185,23 @@ class AndroidWorkflow extends DoctorValidator implements Workflow { } } - final Process process = await runCommand([androidSdk.sdkManagerPath, '--licenses'], environment: androidSdk.sdkManagerEnv); + _ensureCanRunSdkManager(); + + final Process process = await runCommand( + [androidSdk.sdkManagerPath, '--licenses'], + environment: androidSdk.sdkManagerEnv, + ); process.stdin.write('n\n'); - final Future output = process.stdout.transform(const Utf8Decoder(allowMalformed: true)).transform(const LineSplitter()).listen(_onLine).asFuture(null); - final Future errors = process.stderr.transform(const Utf8Decoder(allowMalformed: true)).transform(const LineSplitter()).listen(_onLine).asFuture(null); + final Future output = process.stdout + .transform(const Utf8Decoder(allowMalformed: true)) + .transform(const LineSplitter()) + .listen(_onLine) + .asFuture(null); + final Future errors = process.stderr + .transform(const Utf8Decoder(allowMalformed: true)) + .transform(const LineSplitter()) + .listen(_onLine) + .asFuture(null); try { await Future.wait(>[output, errors]).timeout(const Duration(seconds: 30)); } catch (TimeoutException) { @@ -205,12 +218,7 @@ class AndroidWorkflow extends DoctorValidator implements Workflow { return false; } - if (!processManager.canRun(androidSdk.sdkManagerPath)) - throwToolExit( - 'Android sdkmanager tool not found.\n' - 'Try re-installing or updating your Android SDK,\n' - 'visit https://flutter.io/setup/#android-setup for detailed instructions.' - ); + _ensureCanRunSdkManager(); final Version sdkManagerVersion = new Version.parse(androidSdk.sdkManagerVersion); if (sdkManagerVersion == null || sdkManagerVersion.major < 26) @@ -234,4 +242,15 @@ class AndroidWorkflow extends DoctorValidator implements Workflow { final int exitCode = await process.exitCode; return exitCode == 0; } + + static void _ensureCanRunSdkManager() { + assert(androidSdk != null); + final String sdkManagerPath = androidSdk.sdkManagerPath; + if (!processManager.canRun(sdkManagerPath)) + throwToolExit( + 'Android sdkmanager tool not found ($sdkManagerPath).\n' + 'Try re-installing or updating your Android SDK,\n' + 'visit https://flutter.io/setup/#android-setup for detailed instructions.' + ); + } } diff --git a/packages/flutter_tools/test/android/android_workflow_test.dart b/packages/flutter_tools/test/android/android_workflow_test.dart index d5d65bf290..80e1fdc0d8 100644 --- a/packages/flutter_tools/test/android/android_workflow_test.dart +++ b/packages/flutter_tools/test/android/android_workflow_test.dart @@ -38,6 +38,20 @@ void main() { return (List command) => new MockProcess(stdout: stdoutStream); } + testUsingContext('licensesAccepted throws if cannot run sdkmanager', () async { + processManager.succeed = false; + MockAndroidSdk.createSdkDirectory(); + when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager'); + final AndroidWorkflow androidWorkflow = new AndroidWorkflow(); + expect(androidWorkflow.licensesAccepted, throwsToolExit()); + }, overrides: { + AndroidSdk: () => sdk, + FileSystem: () => fs, + Platform: () => new FakePlatform()..environment = {'HOME': '/home/me'}, + ProcessManager: () => processManager, + Stdio: () => stdio, + }); + testUsingContext('licensesAccepted handles garbage/no output', () async { MockAndroidSdk.createSdkDirectory(); when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');