Inject iOS, Android workflows via context (#10750)
Eliminates the need for the device/daemon code to get at the iOS/Android
tooling indirectly via Doctor. In tests, we now inject the workflow
objects (or mocks) directly.
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart
index b4dd532..f6ed675 100644
--- a/packages/flutter_tools/lib/src/android/android_device.dart
+++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -6,6 +6,7 @@
import 'dart:convert';
import '../android/android_sdk.dart';
+import '../android/android_workflow.dart';
import '../application_package.dart';
import '../base/common.dart' show throwToolExit;
import '../base/file_system.dart';
@@ -17,7 +18,6 @@
import '../build_info.dart';
import '../commands/build_apk.dart';
import '../device.dart';
-import '../doctor.dart';
import '../globals.dart';
import '../protocol_discovery.dart';
@@ -45,7 +45,7 @@
bool get supportsPlatform => true;
@override
- bool get canListAnything => doctor.androidWorkflow.canListDevices;
+ bool get canListAnything => androidWorkflow.canListDevices;
@override
List<Device> pollingGetDevices() => getAdbDevices();
diff --git a/packages/flutter_tools/lib/src/android/android_workflow.dart b/packages/flutter_tools/lib/src/android/android_workflow.dart
index aedfca7..c01d5af 100644
--- a/packages/flutter_tools/lib/src/android/android_workflow.dart
+++ b/packages/flutter_tools/lib/src/android/android_workflow.dart
@@ -4,6 +4,7 @@
import 'dart:async';
+import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/os.dart';
@@ -15,6 +16,8 @@
import 'android_sdk.dart';
import 'android_studio.dart' as android_studio;
+AndroidWorkflow get androidWorkflow => context.putIfAbsent(AndroidWorkflow, () => new AndroidWorkflow());
+
class AndroidWorkflow extends DoctorValidator implements Workflow {
AndroidWorkflow() : super('Android toolchain - develop for Android devices');
diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart
index d01e42f..39eba57 100644
--- a/packages/flutter_tools/lib/src/doctor.dart
+++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -27,18 +27,6 @@
Doctor get doctor => context[Doctor];
class Doctor {
- Doctor() {
- _androidWorkflow = new AndroidWorkflow();
- _iosWorkflow = new IOSWorkflow();
- }
-
- IOSWorkflow _iosWorkflow;
- AndroidWorkflow _androidWorkflow;
-
- IOSWorkflow get iosWorkflow => _iosWorkflow;
-
- AndroidWorkflow get androidWorkflow => _androidWorkflow;
-
List<DoctorValidator> _validators;
List<DoctorValidator> get validators {
@@ -46,11 +34,11 @@
_validators = <DoctorValidator>[];
_validators.add(new _FlutterValidator());
- if (_androidWorkflow.appliesToHostPlatform)
- _validators.add(_androidWorkflow);
+ if (androidWorkflow.appliesToHostPlatform)
+ _validators.add(androidWorkflow);
- if (_iosWorkflow.appliesToHostPlatform)
- _validators.add(_iosWorkflow);
+ if (iosWorkflow.appliesToHostPlatform)
+ _validators.add(iosWorkflow);
final List<DoctorValidator> ideValidators = <DoctorValidator>[];
ideValidators.addAll(AndroidStudioValidator.allValidators);
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index 396266f..dc170ec 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -14,9 +14,9 @@
import '../base/process_manager.dart';
import '../build_info.dart';
import '../device.dart';
-import '../doctor.dart';
import '../globals.dart';
import '../protocol_discovery.dart';
+import 'ios_workflow.dart';
import 'mac.dart';
const String _kIdeviceinstallerInstructions =
@@ -33,7 +33,7 @@
bool get supportsPlatform => platform.isMacOS;
@override
- bool get canListAnything => doctor.iosWorkflow.canListDevices;
+ bool get canListAnything => iosWorkflow.canListDevices;
@override
List<Device> pollingGetDevices() => IOSDevice.getAttachedDevices();
@@ -97,7 +97,7 @@
bool get supportsStartPaused => false;
static List<IOSDevice> getAttachedDevices() {
- if (!doctor.iosWorkflow.hasIDeviceId)
+ if (!iosWorkflow.hasIDeviceId)
return <IOSDevice>[];
final List<IOSDevice> devices = <IOSDevice>[];
diff --git a/packages/flutter_tools/lib/src/ios/ios_workflow.dart b/packages/flutter_tools/lib/src/ios/ios_workflow.dart
index 696048b..4c640aa 100644
--- a/packages/flutter_tools/lib/src/ios/ios_workflow.dart
+++ b/packages/flutter_tools/lib/src/ios/ios_workflow.dart
@@ -5,6 +5,7 @@
import 'dart:async';
import '../base/common.dart';
+import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/os.dart';
@@ -14,6 +15,8 @@
import '../doctor.dart';
import 'mac.dart';
+IOSWorkflow get iosWorkflow => context.putIfAbsent(IOSWorkflow, () => new IOSWorkflow());
+
Xcode get xcode => Xcode.instance;
class IOSWorkflow extends DoctorValidator implements Workflow {
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index 16430aa..ef9188a 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -17,12 +17,12 @@
import '../base/process.dart';
import '../base/process_manager.dart';
import '../build_info.dart';
-import '../doctor.dart';
import '../flx.dart' as flx;
import '../globals.dart';
import '../plugins.dart';
import '../services.dart';
import 'code_signing.dart';
+import 'ios_workflow.dart';
import 'xcodeproj.dart';
const int kXcodeRequiredVersionMajor = 7;
@@ -354,8 +354,8 @@
Future<Null> _runPodInstall(Directory bundle, String engineDirectory) async {
if (fs.file(fs.path.join(bundle.path, 'Podfile')).existsSync()) {
- if (!await doctor.iosWorkflow.isCocoaPodsInstalledAndMeetsVersionCheck) {
- final String minimumVersion = doctor.iosWorkflow.cocoaPodsMinimumVersion;
+ if (!await iosWorkflow.isCocoaPodsInstalledAndMeetsVersionCheck) {
+ final String minimumVersion = iosWorkflow.cocoaPodsMinimumVersion;
printError(
'Warning: CocoaPods version $minimumVersion or greater not installed. Skipping pod install.\n'
'$noCocoaPodsConsequence\n'
@@ -365,7 +365,7 @@
);
return;
}
- if (!await doctor.iosWorkflow.isCocoaPodsInitialized) {
+ if (!await iosWorkflow.isCocoaPodsInitialized) {
printError(
'Warning: CocoaPods installed but not initialized. Skipping pod install.\n'
'$noCocoaPodsConsequence\n'
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart
index d4ec64f..d67213b 100644
--- a/packages/flutter_tools/lib/src/ios/simulators.dart
+++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -16,10 +16,10 @@
import '../base/process_manager.dart';
import '../build_info.dart';
import '../device.dart';
-import '../doctor.dart';
import '../flx.dart' as flx;
import '../globals.dart';
import '../protocol_discovery.dart';
+import 'ios_workflow.dart';
import 'mac.dart';
const String _xcrunPath = '/usr/bin/xcrun';
@@ -34,7 +34,7 @@
bool get supportsPlatform => platform.isMacOS;
@override
- bool get canListAnything => doctor.iosWorkflow.canListDevices;
+ bool get canListAnything => iosWorkflow.canListDevices;
@override
List<Device> pollingGetDevices() => IOSSimulatorUtils.instance.getAttachedDevices();
diff --git a/packages/flutter_tools/test/commands/daemon_test.dart b/packages/flutter_tools/test/commands/daemon_test.dart
index e55d7dd..10a864b 100644
--- a/packages/flutter_tools/test/commands/daemon_test.dart
+++ b/packages/flutter_tools/test/commands/daemon_test.dart
@@ -8,7 +8,6 @@
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/commands/daemon.dart';
-import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/globals.dart';
import 'package:flutter_tools/src/ios/ios_workflow.dart';
import 'package:test/test.dart';
@@ -220,7 +219,8 @@
expect(response['params'], containsPair('title', 'Unable to list devices'));
expect(response['params'], containsPair('message', contains('Unable to discover Android devices')));
}, overrides: <Type, Generator>{
- Doctor: () => new MockDoctor(androidCanListDevices: false),
+ AndroidWorkflow: () => new MockAndroidWorkflow(canListDevices: false),
+ IOSWorkflow: () => new MockIOSWorkflow(),
});
testUsingContext('device.getDevices should respond with list', () async {
@@ -263,36 +263,24 @@
commands.close();
});
}, overrides: <Type, Generator>{
- Doctor: () => new MockDoctor(),
+ AndroidWorkflow: () => new MockAndroidWorkflow(),
+ IOSWorkflow: () => new MockIOSWorkflow(),
});
});
}
bool _notEvent(Map<String, dynamic> map) => map['event'] == null;
-class MockDoctor extends Doctor {
- final bool androidCanListDevices;
- final bool iosCanListDevices;
-
- MockDoctor({this.androidCanListDevices: true, this.iosCanListDevices: true});
-
- @override
- AndroidWorkflow get androidWorkflow => new MockAndroidWorkflow(androidCanListDevices);
-
- @override
- IOSWorkflow get iosWorkflow => new MockIosWorkflow(iosCanListDevices);
-}
-
class MockAndroidWorkflow extends AndroidWorkflow {
+ MockAndroidWorkflow({ this.canListDevices: true });
+
@override
final bool canListDevices;
-
- MockAndroidWorkflow(this.canListDevices);
}
-class MockIosWorkflow extends IOSWorkflow {
+class MockIOSWorkflow extends IOSWorkflow {
+ MockIOSWorkflow({ this.canListDevices:true });
+
@override
final bool canListDevices;
-
- MockIosWorkflow(this.canListDevices);
}