Unverified Commit e18533e7 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] remove globals from android_workflow (#69548)

parent ef288c17
...@@ -16,7 +16,7 @@ import '../device.dart'; ...@@ -16,7 +16,7 @@ import '../device.dart';
import 'adb.dart'; import 'adb.dart';
import 'android_device.dart'; import 'android_device.dart';
import 'android_sdk.dart'; import 'android_sdk.dart';
import 'android_workflow.dart' hide androidWorkflow; import 'android_workflow.dart';
/// Device discovery for Android physical devices and emulators. /// Device discovery for Android physical devices and emulators.
/// ///
......
...@@ -382,7 +382,7 @@ class AndroidSdk { ...@@ -382,7 +382,7 @@ class AndroidSdk {
return fileSystem.path.join(javaHome, 'bin', 'java'); return fileSystem.path.join(javaHome, 'bin', 'java');
} }
} }
} on Exception catch (_) { /* ignore */ } } on Exception { /* ignore */ }
} }
// Fallback to PATH based lookup. // Fallback to PATH based lookup.
......
...@@ -12,12 +12,11 @@ import '../base/io.dart'; ...@@ -12,12 +12,11 @@ import '../base/io.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../base/os.dart'; import '../base/os.dart';
import '../base/platform.dart'; import '../base/platform.dart';
import '../base/user_messages.dart'; import '../base/user_messages.dart' hide userMessages;
import '../base/version.dart'; import '../base/version.dart';
import '../convert.dart'; import '../convert.dart';
import '../doctor.dart'; import '../doctor.dart';
import '../features.dart'; import '../features.dart';
import '../globals.dart' as globals;
import 'android_sdk.dart'; import 'android_sdk.dart';
import 'android_studio.dart'; import 'android_studio.dart';
...@@ -252,7 +251,36 @@ class AndroidValidator extends DoctorValidator { ...@@ -252,7 +251,36 @@ class AndroidValidator extends DoctorValidator {
/// A subvalidator that checks if the licenses within the detected Android /// A subvalidator that checks if the licenses within the detected Android
/// SDK have been accepted. /// SDK have been accepted.
class AndroidLicenseValidator extends DoctorValidator { class AndroidLicenseValidator extends DoctorValidator {
AndroidLicenseValidator() : super('Android license subvalidator',); AndroidLicenseValidator({
@required AndroidSdk androidSdk,
@required Platform platform,
@required OperatingSystemUtils operatingSystemUtils,
@required FileSystem fileSystem,
@required ProcessManager processManager,
@required Logger logger,
@required AndroidStudio androidStudio,
@required Stdio stdio,
@required UserMessages userMessages,
}) : _androidSdk = androidSdk,
_platform = platform,
_operatingSystemUtils = operatingSystemUtils,
_fileSystem = fileSystem,
_processManager = processManager,
_logger = logger,
_androidStudio = androidStudio,
_stdio = stdio,
_userMessages = userMessages,
super('Android license subvalidator');
final AndroidSdk _androidSdk;
final AndroidStudio _androidStudio;
final Stdio _stdio;
final OperatingSystemUtils _operatingSystemUtils;
final Platform _platform;
final FileSystem _fileSystem;
final ProcessManager _processManager;
final Logger _logger;
final UserMessages _userMessages;
@override @override
String get slowWarning => 'Checking Android licenses is taking an unexpectedly long time...'; String get slowWarning => 'Checking Android licenses is taking an unexpectedly long time...';
...@@ -262,27 +290,27 @@ class AndroidLicenseValidator extends DoctorValidator { ...@@ -262,27 +290,27 @@ class AndroidLicenseValidator extends DoctorValidator {
final List<ValidationMessage> messages = <ValidationMessage>[]; final List<ValidationMessage> messages = <ValidationMessage>[];
// Match pre-existing early termination behavior // Match pre-existing early termination behavior
if (globals.androidSdk == null || globals.androidSdk.latestVersion == null || if (_androidSdk == null || _androidSdk.latestVersion == null ||
globals.androidSdk.validateSdkWellFormed().isNotEmpty || _androidSdk.validateSdkWellFormed().isNotEmpty ||
! await _checkJavaVersionNoOutput()) { ! await _checkJavaVersionNoOutput()) {
return ValidationResult(ValidationType.missing, messages); return ValidationResult(ValidationType.missing, messages);
} }
final String sdkVersionText = userMessages.androidStatusInfo(globals.androidSdk.latestVersion.buildToolsVersionName); final String sdkVersionText = _userMessages.androidStatusInfo(_androidSdk.latestVersion.buildToolsVersionName);
// Check for licenses. // Check for licenses.
switch (await licensesAccepted) { switch (await licensesAccepted) {
case LicensesAccepted.all: case LicensesAccepted.all:
messages.add(ValidationMessage(userMessages.androidLicensesAll)); messages.add(ValidationMessage(_userMessages.androidLicensesAll));
break; break;
case LicensesAccepted.some: case LicensesAccepted.some:
messages.add(ValidationMessage.hint(userMessages.androidLicensesSome)); messages.add(ValidationMessage.hint(_userMessages.androidLicensesSome));
return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText); return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText);
case LicensesAccepted.none: case LicensesAccepted.none:
messages.add(ValidationMessage.error(userMessages.androidLicensesNone)); messages.add(ValidationMessage.error(_userMessages.androidLicensesNone));
return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText); return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText);
case LicensesAccepted.unknown: case LicensesAccepted.unknown:
messages.add(ValidationMessage.error(userMessages.androidLicensesUnknown(globals.platform))); messages.add(ValidationMessage.error(_userMessages.androidLicensesUnknown(_platform)));
return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText); return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText);
} }
return ValidationResult(ValidationType.installed, messages, statusInfo: sdkVersionText); return ValidationResult(ValidationType.installed, messages, statusInfo: sdkVersionText);
...@@ -290,26 +318,26 @@ class AndroidLicenseValidator extends DoctorValidator { ...@@ -290,26 +318,26 @@ class AndroidLicenseValidator extends DoctorValidator {
Future<bool> _checkJavaVersionNoOutput() async { Future<bool> _checkJavaVersionNoOutput() async {
final String javaBinary = AndroidSdk.findJavaBinary( final String javaBinary = AndroidSdk.findJavaBinary(
androidStudio: globals.androidStudio, androidStudio: _androidStudio,
fileSystem: globals.fs, fileSystem: _fileSystem,
operatingSystemUtils: globals.os, operatingSystemUtils: _operatingSystemUtils,
platform: globals.platform, platform: _platform,
); );
if (javaBinary == null) { if (javaBinary == null) {
return false; return false;
} }
if (!globals.processManager.canRun(javaBinary)) { if (!_processManager.canRun(javaBinary)) {
return false; return false;
} }
String javaVersion; String javaVersion;
try { try {
final ProcessResult result = await globals.processManager.run(<String>[javaBinary, '-version']); final ProcessResult result = await _processManager.run(<String>[javaBinary, '-version']);
if (result.exitCode == 0) { if (result.exitCode == 0) {
final List<String> versionLines = (result.stderr as String).split('\n'); final List<String> versionLines = (result.stderr as String).split('\n');
javaVersion = versionLines.length >= 2 ? versionLines[1] : versionLines[0]; javaVersion = versionLines.length >= 2 ? versionLines[1] : versionLines[0];
} }
} on Exception catch (error) { } on Exception catch (error) {
globals.printTrace(error.toString()); _logger.printTrace(error.toString());
} }
if (javaVersion == null) { if (javaVersion == null) {
// Could not determine the java version. // Could not determine the java version.
...@@ -344,9 +372,9 @@ class AndroidLicenseValidator extends DoctorValidator { ...@@ -344,9 +372,9 @@ class AndroidLicenseValidator extends DoctorValidator {
} }
try { try {
final Process process = await globals.processUtils.start( final Process process = await _processManager.start(
<String>[globals.androidSdk.sdkManagerPath, '--licenses'], <String>[_androidSdk.sdkManagerPath, '--licenses'],
environment: globals.androidSdk.sdkManagerEnv, environment: _androidSdk.sdkManagerEnv,
); );
process.stdin.write('n\n'); process.stdin.write('n\n');
// We expect logcat streams to occasionally contain invalid utf-8, // We expect logcat streams to occasionally contain invalid utf-8,
...@@ -364,36 +392,36 @@ class AndroidLicenseValidator extends DoctorValidator { ...@@ -364,36 +392,36 @@ class AndroidLicenseValidator extends DoctorValidator {
await Future.wait<void>(<Future<void>>[output, errors]); await Future.wait<void>(<Future<void>>[output, errors]);
return status ?? LicensesAccepted.unknown; return status ?? LicensesAccepted.unknown;
} on ProcessException catch (e) { } on ProcessException catch (e) {
globals.printTrace('Failed to run Android sdk manager: $e'); _logger.printTrace('Failed to run Android sdk manager: $e');
return LicensesAccepted.unknown; return LicensesAccepted.unknown;
} }
} }
/// Run the Android SDK manager tool in order to accept SDK licenses. /// Run the Android SDK manager tool in order to accept SDK licenses.
static Future<bool> runLicenseManager() async { Future<bool> runLicenseManager() async {
if (globals.androidSdk == null) { if (_androidSdk == null) {
globals.printStatus(userMessages.androidSdkShort); _logger.printStatus(_userMessages.androidSdkShort);
return false; return false;
} }
if (!_canRunSdkManager()) { if (!_canRunSdkManager()) {
throwToolExit(userMessages.androidMissingSdkManager(globals.androidSdk.sdkManagerPath, globals.platform)); throwToolExit(_userMessages.androidMissingSdkManager(_androidSdk.sdkManagerPath, _platform));
} }
try { try {
final Process process = await globals.processUtils.start( final Process process = await _processManager.start(
<String>[globals.androidSdk.sdkManagerPath, '--licenses'], <String>[_androidSdk.sdkManagerPath, '--licenses'],
environment: globals.androidSdk.sdkManagerEnv, environment: _androidSdk.sdkManagerEnv,
); );
// The real stdin will never finish streaming. Pipe until the child process // The real stdin will never finish streaming. Pipe until the child process
// finishes. // finishes.
unawaited(process.stdin.addStream(globals.stdio.stdin) unawaited(process.stdin.addStream(_stdio.stdin)
// If the process exits unexpectedly with an error, that will be // If the process exits unexpectedly with an error, that will be
// handled by the caller. // handled by the caller.
.catchError((dynamic err, StackTrace stack) { .catchError((dynamic err, StackTrace stack) {
globals.printTrace('Echoing stdin to the licenses subprocess failed:'); _logger.printTrace('Echoing stdin to the licenses subprocess failed:');
globals.printTrace('$err\n$stack'); _logger.printTrace('$err\n$stack');
} }
)); ));
...@@ -401,29 +429,28 @@ class AndroidLicenseValidator extends DoctorValidator { ...@@ -401,29 +429,28 @@ class AndroidLicenseValidator extends DoctorValidator {
// may complete first. // may complete first.
try { try {
await Future.wait<void>(<Future<void>>[ await Future.wait<void>(<Future<void>>[
globals.stdio.addStdoutStream(process.stdout), _stdio.addStdoutStream(process.stdout),
globals.stdio.addStderrStream(process.stderr), _stdio.addStderrStream(process.stderr),
]); ]);
} on Exception catch (err, stack) { } on Exception catch (err, stack) {
globals.printTrace('Echoing stdout or stderr from the license subprocess failed:'); _logger.printTrace('Echoing stdout or stderr from the license subprocess failed:');
globals.printTrace('$err\n$stack'); _logger.printTrace('$err\n$stack');
} }
final int exitCode = await process.exitCode; final int exitCode = await process.exitCode;
return exitCode == 0; return exitCode == 0;
} on ProcessException catch (e) { } on ProcessException catch (e) {
throwToolExit(userMessages.androidCannotRunSdkManager( throwToolExit(_userMessages.androidCannotRunSdkManager(
globals.androidSdk.sdkManagerPath, _androidSdk.sdkManagerPath,
e.toString(), e.toString(),
globals.platform, _platform,
)); ));
return false; return false;
} }
} }
static bool _canRunSdkManager() { bool _canRunSdkManager() {
assert(globals.androidSdk != null); final String sdkManagerPath = _androidSdk.sdkManagerPath;
final String sdkManagerPath = globals.androidSdk.sdkManagerPath; return _processManager.canRun(sdkManagerPath);
return globals.processManager.canRun(sdkManagerPath);
} }
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import '../android/android_workflow.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
...@@ -44,7 +45,11 @@ class DoctorCommand extends FlutterCommand { ...@@ -44,7 +45,11 @@ class DoctorCommand extends FlutterCommand {
'git hash.'); 'git hash.');
} }
} }
final bool success = await globals.doctor.diagnose(androidLicenses: boolArg('android-licenses'), verbose: verbose); final bool success = await globals.doctor.diagnose(
androidLicenses: boolArg('android-licenses'),
verbose: verbose,
androidLicenseValidator: androidLicenseValidator,
);
return FlutterCommandResult(success ? ExitStatus.success : ExitStatus.warning); return FlutterCommandResult(success ? ExitStatus.success : ExitStatus.warning);
} }
} }
...@@ -72,7 +72,17 @@ Future<T> runInContext<T>( ...@@ -72,7 +72,17 @@ Future<T> runInContext<T>(
body: runnerWrapper, body: runnerWrapper,
overrides: overrides, overrides: overrides,
fallbacks: <Type, Generator>{ fallbacks: <Type, Generator>{
AndroidLicenseValidator: () => AndroidLicenseValidator(), AndroidLicenseValidator: () => AndroidLicenseValidator(
operatingSystemUtils: globals.os,
platform: globals.platform,
userMessages: globals.userMessages,
processManager: globals.processManager,
androidStudio: globals.androidStudio,
androidSdk: globals.androidSdk,
logger: globals.logger,
fileSystem: globals.fs,
stdio: globals.stdio,
),
AndroidSdk: AndroidSdk.locateAndroidSdk, AndroidSdk: AndroidSdk.locateAndroidSdk,
AndroidStudio: AndroidStudio.latestValid, AndroidStudio: AndroidStudio.latestValid,
AndroidValidator: () => AndroidValidator( AndroidValidator: () => AndroidValidator(
......
...@@ -288,9 +288,14 @@ class Doctor { ...@@ -288,9 +288,14 @@ class Doctor {
} }
/// Print information about the state of installed tooling. /// Print information about the state of installed tooling.
Future<bool> diagnose({ bool androidLicenses = false, bool verbose = true, bool showColor = true }) async { Future<bool> diagnose({
if (androidLicenses) { bool androidLicenses = false,
return AndroidLicenseValidator.runLicenseManager(); bool verbose = true,
bool showColor = true,
AndroidLicenseValidator androidLicenseValidator,
}) async {
if (androidLicenses && androidLicenseValidator != null) {
return androidLicenseValidator.runLicenseManager();
} }
if (!verbose) { if (!verbose) {
......
...@@ -7,6 +7,7 @@ import 'dart:async'; ...@@ -7,6 +7,7 @@ import 'dart:async';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_studio_validator.dart'; import 'package:flutter_tools/src/android/android_studio_validator.dart';
import 'package:flutter_tools/src/android/android_workflow.dart';
import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
...@@ -704,7 +705,12 @@ class NoOpDoctor implements Doctor { ...@@ -704,7 +705,12 @@ class NoOpDoctor implements Doctor {
Future<bool> checkRemoteArtifacts(String engineRevision) async => true; Future<bool> checkRemoteArtifacts(String engineRevision) async => true;
@override @override
Future<bool> diagnose({ bool androidLicenses = false, bool verbose = true, bool showColor = true }) async => true; Future<bool> diagnose({
bool androidLicenses = false,
bool verbose = true,
bool showColor = true,
AndroidLicenseValidator androidLicenseValidator,
}) async => true;
@override @override
List<ValidatorTask> startValidatorTasks() => <ValidatorTask>[]; List<ValidatorTask> startValidatorTasks() => <ValidatorTask>[];
......
...@@ -173,6 +173,7 @@ void main() { ...@@ -173,6 +173,7 @@ void main() {
when(mockDoctor.diagnose( when(mockDoctor.diagnose(
androidLicenses: false, androidLicenses: false,
verbose: false, verbose: false,
androidLicenseValidator: anyNamed('androidLicenseValidator')
)).thenAnswer((_) async => true); )).thenAnswer((_) async => true);
final DoctorCommand command = DoctorCommand(); final DoctorCommand command = DoctorCommand();
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
...@@ -197,7 +198,8 @@ void main() { ...@@ -197,7 +198,8 @@ void main() {
testUsingContext('doctor fail sends warning', () async { testUsingContext('doctor fail sends warning', () async {
mockTimes = <int>[1000, 2000]; mockTimes = <int>[1000, 2000];
when(mockDoctor.diagnose(androidLicenses: false, verbose: false)).thenAnswer((_) async => false); when(mockDoctor.diagnose(androidLicenses: false, verbose: false, androidLicenseValidator: anyNamed('androidLicenseValidator')))
.thenAnswer((_) async => false);
final DoctorCommand command = DoctorCommand(); final DoctorCommand command = DoctorCommand();
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['doctor']); await runner.run(<String>['doctor']);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment