Refactor core resident runner logic (#80462)
diff --git a/packages/flutter_tools/lib/src/base/file_system.dart b/packages/flutter_tools/lib/src/base/file_system.dart
index 6cf75ad..11b5046 100644
--- a/packages/flutter_tools/lib/src/base/file_system.dart
+++ b/packages/flutter_tools/lib/src/base/file_system.dart
@@ -41,18 +41,7 @@
/// Appends a number to a filename in order to make it unique under a
/// directory.
File getUniqueFile(Directory dir, String baseName, String ext) {
- final FileSystem fs = dir.fileSystem;
- int i = 1;
-
- while (true) {
- final String name = '${baseName}_${i.toString().padLeft(2, '0')}.$ext';
- final File file = fs.file(_fileSystem.path.join(dir.path, name));
- if (!file.existsSync()) {
- file.createSync(recursive: true);
- return file;
- }
- i += 1;
- }
+ return _getUniqueFile(dir, baseName, ext);
}
/// Appends a number to a directory name in order to make it unique under a
@@ -157,6 +146,27 @@
}
}
+File _getUniqueFile(Directory dir, String baseName, String ext) {
+ final FileSystem fs = dir.fileSystem;
+ int i = 1;
+
+ while (true) {
+ final String name = '${baseName}_${i.toString().padLeft(2, '0')}.$ext';
+ final File file = fs.file(dir.fileSystem.path.join(dir.path, name));
+ if (!file.existsSync()) {
+ file.createSync(recursive: true);
+ return file;
+ }
+ i += 1;
+ }
+}
+
+/// Appends a number to a filename in order to make it unique under a
+/// directory.
+File getUniqueFile(Directory dir, String baseName, String ext) {
+ return _getUniqueFile(dir, baseName, ext);
+}
+
/// This class extends [local_fs.LocalFileSystem] in order to clean up
/// directories and files that the tool creates under the system temporary
/// directory when the tool exits either normally or when killed by a signal.
diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart
index ea92183..f6a3f1f 100644
--- a/packages/flutter_tools/lib/src/commands/daemon.dart
+++ b/packages/flutter_tools/lib/src/commands/daemon.dart
@@ -29,6 +29,7 @@
import '../run_cold.dart';
import '../run_hot.dart';
import '../runner/flutter_command.dart';
+import '../vmservice.dart';
import '../web/web_runner.dart';
const String protocolVersion = '0.6.0';
@@ -687,9 +688,16 @@
if (app == null) {
throw "app '$appId' not found";
}
-
- final Map<String, dynamic> result = await app.runner
- .invokeFlutterExtensionRpcRawOnFirstIsolate(methodName, params: params);
+ final FlutterDevice device = app.runner.flutterDevices.first;
+ final List<FlutterView> views = await device.vmService.getFlutterViews();
+ final Map<String, dynamic> result = await device
+ .vmService
+ .invokeFlutterExtensionRpcRaw(
+ methodName,
+ args: params,
+ isolateId: views
+ .first.uiIsolate.id
+ );
if (result == null) {
throw 'method not available: $methodName';
}
diff --git a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
index e988bc1..13ee47a 100644
--- a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
+++ b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
@@ -76,7 +76,6 @@
systemClock: systemClock,
fileSystem: fileSystem,
logger: logger,
- featureFlags: featureFlags,
);
}
}
@@ -99,14 +98,12 @@
@required SystemClock systemClock,
@required Usage usage,
@required UrlTunneller urlTunneller,
- @required FeatureFlags featureFlags,
ResidentDevtoolsHandlerFactory devtoolsHandler = createDefaultHandler,
}) : _fileSystem = fileSystem,
_logger = logger,
_systemClock = systemClock,
_usage = usage,
_urlTunneller = urlTunneller,
- _featureFlags = featureFlags,
super(
<FlutterDevice>[device],
target: target ?? fileSystem.path.join('lib', 'main.dart'),
@@ -122,7 +119,6 @@
final SystemClock _systemClock;
final Usage _usage;
final UrlTunneller _urlTunneller;
- final FeatureFlags _featureFlags;
FlutterDevice get device => flutterDevices.first;
final FlutterProject flutterProject;
@@ -167,20 +163,7 @@
FlutterVmService _instance;
@override
- bool get canHotRestart {
- return true;
- }
-
- @override
- Future<Map<String, dynamic>> invokeFlutterExtensionRpcRawOnFirstIsolate(
- String method, {
- FlutterDevice device,
- Map<String, dynamic> params,
- }) async {
- final vmservice.Response response =
- await _vmService.service.callServiceExtension(method, args: params);
- return response.toJson();
- }
+ bool get supportsRestart => true;
@override
Future<void> cleanupAfterSignal() async {
@@ -313,7 +296,7 @@
?.flutterPlatformOverride(
isolateId: null,
);
- final String platform = nextPlatform(currentPlatform, _featureFlags);
+ final String platform = nextPlatform(currentPlatform);
await _vmService
?.flutterPlatformOverride(
platform: platform,
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index 01cabab..8f2f73c 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -192,11 +192,11 @@
);
}
+ final TargetPlatform targetPlatform;
final Device device;
final ResidentCompiler generator;
final BuildInfo buildInfo;
final String userIdentifier;
- final TargetPlatform targetPlatform;
DevFSWriter devFSWriter;
Stream<Uri> observatoryUris;
@@ -401,138 +401,16 @@
return devFS.create();
}
- Future<void> debugDumpApp() async {
+ Future<List<vm_service.IsolateRef>> _getCurrentIsolates() async {
+ if (targetPlatform == TargetPlatform.web_javascript) {
+ final vm_service.VM vm = await vmService.service.getVM();
+ return vm.isolates;
+ }
final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- final String data = await vmService.flutterDebugDumpApp(
- isolateId: view.uiIsolate.id,
- );
- globals.printStatus(data);
- }
- }
-
- Future<void> debugDumpRenderTree() async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- final String data = await vmService.flutterDebugDumpRenderTree(
- isolateId: view.uiIsolate.id,
- );
- globals.printStatus(data);
- }
- }
-
- Future<void> debugDumpLayerTree() async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- final String data = await vmService.flutterDebugDumpLayerTree(
- isolateId: view.uiIsolate.id,
- );
- globals.printStatus(data);
- }
- }
-
- Future<void> debugDumpSemanticsTreeInTraversalOrder() async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- final String data = await vmService.flutterDebugDumpSemanticsTreeInTraversalOrder(
- isolateId: view.uiIsolate.id,
- );
- globals.printStatus(data);
- }
- }
-
- Future<void> debugDumpSemanticsTreeInInverseHitTestOrder() async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- final String data = await vmService.flutterDebugDumpSemanticsTreeInInverseHitTestOrder(
- isolateId: view.uiIsolate.id,
- );
- globals.printStatus(data);
- }
- }
-
- Future<void> toggleDebugPaintSizeEnabled() async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- await vmService.flutterToggleDebugPaintSizeEnabled(
- isolateId: view.uiIsolate.id,
- );
- }
- }
-
- Future<void> toggleDebugCheckElevationsEnabled() async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- await vmService.flutterToggleDebugCheckElevationsEnabled(
- isolateId: view.uiIsolate.id,
- );
- }
- }
-
- Future<void> debugTogglePerformanceOverlayOverride() async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- await vmService.flutterTogglePerformanceOverlayOverride(
- isolateId: view.uiIsolate.id,
- );
- }
- }
-
- Future<void> toggleWidgetInspector() async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- await vmService.flutterToggleWidgetInspector(
- isolateId: view.uiIsolate.id,
- );
- }
- }
-
- Future<void> toggleInvertOversizedImages() async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- await vmService.flutterToggleInvertOversizedImages(
- isolateId: view.uiIsolate.id,
- );
- }
- }
-
- Future<void> toggleProfileWidgetBuilds() async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- for (final FlutterView view in views) {
- await vmService.flutterToggleProfileWidgetBuilds(
- isolateId: view.uiIsolate.id,
- );
- }
- }
-
- Future<Brightness> toggleBrightness({ Brightness current }) async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- Brightness next;
- if (current == Brightness.light) {
- next = Brightness.dark;
- } else if (current == Brightness.dark) {
- next = Brightness.light;
- }
-
- for (final FlutterView view in views) {
- next = await vmService.flutterBrightnessOverride(
- isolateId: view.uiIsolate.id,
- brightness: next,
- );
- }
- return next;
- }
-
- Future<String> togglePlatform({ String from }) async {
- final List<FlutterView> views = await vmService.getFlutterViews();
- final String to = nextPlatform(from, featureFlags);
- for (final FlutterView view in views) {
- await vmService.flutterPlatformOverride(
- platform: to,
- isolateId: view.uiIsolate.id,
- );
- }
- return to;
+ return <vm_service.IsolateRef>[
+ for (FlutterView view in views)
+ view.uiIsolate,
+ ];
}
Future<void> startEchoingDeviceLog() async {
@@ -629,7 +507,6 @@
return 0;
}
-
Future<int> runCold({
ColdRunner coldRunner,
String route,
@@ -755,8 +632,389 @@
}
}
+/// A subset of the [ResidentRunner] for delegating to attached flutter devices.
+abstract class ResidentHandlers {
+ List<FlutterDevice> get flutterDevices;
+
+ /// Whether the resident runner has hot reload and restart enabled.
+ bool get hotMode;
+
+ /// Whether the resident runner is connect to the device's VM Service.
+ bool get supportsServiceProtocol;
+
+ /// The application is running in debug mode.
+ bool get isRunningDebug;
+
+ /// The application is running in profile mode.
+ bool get isRunningProfile;
+
+ /// The application is running in release mode.
+ bool get isRunningRelease;
+
+ /// The resident runner should stay resident after establishing a connection with the
+ /// application.
+ bool get stayResident;
+
+ /// Whether all of the connected devices support hot restart.
+ ///
+ /// To prevent scenarios where only a subset of devices are hot restarted,
+ /// the runner requires that all attached devices can support hot restart
+ /// before enabling it.
+ bool get supportsRestart;
+
+ /// Whether all of the connected devices support gathering SkSL.
+ bool get supportsWriteSkSL;
+
+ /// Whether all of the connected devices support hot reload.
+ bool get canHotReload;
+
+ @protected
+ Logger get logger;
+
+ @protected
+ FileSystem get fileSystem;
+
+ /// Called to print help to the terminal.
+ void printHelp({ @required bool details });
+
+ /// Perfor a hot reload or hot restart of all attached applications.
+ ///
+ /// If [fullRestart] is true, a hot restart is performed. Otherwise a hot reload
+ /// is run instead. On web devices, this only performs a hot restart regardless of
+ /// the value of [fullRestart].
+ Future<OperationResult> restart({ bool fullRestart = false, bool pause = false, String reason }) {
+ final String mode = isRunningProfile ? 'profile' :isRunningRelease ? 'release' : 'this';
+ throw '${fullRestart ? 'Restart' : 'Reload'} is not supported in $mode mode';
+ }
+
+ /// Dump the application's current widget tree to the terminal.
+ Future<bool> debugDumpApp() async {
+ if (!supportsServiceProtocol) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ final String data = await device.vmService.flutterDebugDumpApp(
+ isolateId: view.id,
+ );
+ logger.printStatus(data);
+ }
+ }
+ return true;
+ }
+
+ /// Dump the application's current render tree to the terminal.
+ Future<bool> debugDumpRenderTree() async {
+ if (!supportsServiceProtocol) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ final String data = await device.vmService.flutterDebugDumpRenderTree(
+ isolateId: view.id,
+ );
+ logger.printStatus(data);
+ }
+ }
+ return true;
+ }
+
+ /// Dump the application's current layer tree to the terminal.
+ Future<bool> debugDumpLayerTree() async {
+ if (!supportsServiceProtocol || !isRunningDebug) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ final String data = await device.vmService.flutterDebugDumpLayerTree(
+ isolateId: view.id,
+ );
+ logger.printStatus(data);
+ }
+ }
+ return true;
+ }
+
+ /// Dump the application's current semantics tree to the terminal.
+ ///
+ /// If semantics are not enabled, nothing is returned.
+ Future<bool> debugDumpSemanticsTreeInTraversalOrder() async {
+ if (!supportsServiceProtocol) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ final String data = await device.vmService.flutterDebugDumpSemanticsTreeInTraversalOrder(
+ isolateId: view.id,
+ );
+ logger.printStatus(data);
+ }
+ }
+ return true;
+ }
+
+ /// Dump the application's current semantics tree to the terminal.
+ ///
+ /// If semantics are not enabled, nothing is returned.
+ Future<bool> debugDumpSemanticsTreeInInverseHitTestOrder() async {
+ if (!supportsServiceProtocol) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ final String data = await device.vmService.flutterDebugDumpSemanticsTreeInInverseHitTestOrder(
+ isolateId: view.id,
+ );
+ logger.printStatus(data);
+ }
+ }
+ return true;
+ }
+
+ /// Toggle the "paint size" debugging feature.
+ Future<bool> debugToggleDebugPaintSizeEnabled() async {
+ if (!supportsServiceProtocol || !isRunningDebug) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ await device.vmService.flutterToggleDebugPaintSizeEnabled(
+ isolateId: view.id,
+ );
+ }
+ }
+ return true;
+ }
+
+ /// Toggle the "elevation check" debugging feature.
+ Future<bool> debugToggleDebugCheckElevationsEnabled() async {
+ if (!supportsServiceProtocol) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ await device.vmService.flutterToggleDebugCheckElevationsEnabled(
+ isolateId: view.id,
+ );
+ }
+ }
+ return true;
+ }
+
+ /// Toggle the performance overlay.
+ ///
+ /// This is not supported in web mode.
+ Future<bool> debugTogglePerformanceOverlayOverride() async {
+ if (!supportsServiceProtocol) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ if (device.targetPlatform == TargetPlatform.web_javascript) {
+ continue;
+ }
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ await device.vmService.flutterTogglePerformanceOverlayOverride(
+ isolateId: view.id,
+ );
+ }
+ }
+ return true;
+ }
+
+ /// Toggle the widget inspector.
+ Future<bool> debugToggleWidgetInspector() async {
+ if (!supportsServiceProtocol) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ await device.vmService.flutterToggleWidgetInspector(
+ isolateId: view.id,
+ );
+ }
+ }
+ return true;
+ }
+
+ /// Toggle the "invert images" debugging feature.
+ Future<bool> debugToggleInvertOversizedImages() async {
+ if (!supportsServiceProtocol || !isRunningDebug) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ await device.vmService.flutterToggleInvertOversizedImages(
+ isolateId: view.id,
+ );
+ }
+ }
+ return true;
+ }
+
+ /// Toggle the "profile widget builds" debugging feature.
+ Future<bool> debugToggleProfileWidgetBuilds() async {
+ if (!supportsServiceProtocol) {
+ return false;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ await device.vmService.flutterToggleProfileWidgetBuilds(
+ isolateId: view.id,
+ );
+ }
+ }
+ return true;
+ }
+
+ /// Toggle the operating system brightness (light or dart).
+ Future<bool> debugToggleBrightness() async {
+ if (!supportsServiceProtocol) {
+ return false;
+ }
+ final List<vm_service.IsolateRef> views = await flutterDevices.first._getCurrentIsolates();
+ final Brightness current = await flutterDevices.first.vmService.flutterBrightnessOverride(
+ isolateId: views.first.id,
+ );
+ Brightness next;
+ if (current == Brightness.light) {
+ next = Brightness.dark;
+ } else {
+ next = Brightness.light;
+ }
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ await device.vmService.flutterBrightnessOverride(
+ isolateId: view.id,
+ brightness: next,
+ );
+ }
+ logger.printStatus('Changed brightness to $next.');
+ }
+ return true;
+ }
+
+ /// Rotate the application through different `defaultTargetPlatform` values.
+ Future<bool> debugTogglePlatform() async {
+ if (!supportsServiceProtocol || !isRunningDebug) {
+ return false;
+ }
+ final List<vm_service.IsolateRef> views = await flutterDevices.first._getCurrentIsolates();
+ final String from = await flutterDevices
+ .first.vmService.flutterPlatformOverride(
+ isolateId: views.first.id,
+ );
+ final String to = nextPlatform(from);
+ for (final FlutterDevice device in flutterDevices) {
+ for (final vm_service.IsolateRef view in await device._getCurrentIsolates()) {
+ await device.vmService.flutterPlatformOverride(
+ platform: to,
+ isolateId: view.id,
+ );
+ }
+ }
+ logger.printStatus('Switched operating system to $to');
+ return true;
+ }
+
+ /// Write the SkSL shaders to a zip file in build directory.
+ ///
+ /// Returns the name of the file, or `null` on failures.
+ Future<String> writeSkSL() async {
+ if (!supportsWriteSkSL) {
+ throw Exception('writeSkSL is not supported by this runner.');
+ }
+ final List<FlutterView> views = await flutterDevices
+ .first
+ .vmService.getFlutterViews();
+ final Map<String, Object> data = await flutterDevices.first.vmService.getSkSLs(
+ viewId: views.first.id,
+ );
+ final Device device = flutterDevices.first.device;
+ return sharedSkSlWriter(device, data);
+ }
+
+ /// Take a screenshot on the provided [device].
+ ///
+ /// If the device has a connected vmservice, this method will attempt to hide
+ /// and restore the debug banner before taking the screenshot.
+ ///
+ /// Throws an [AssertionError] if [Device.supportsScreenshot] is not true.
+ Future<void> screenshot(FlutterDevice device) async {
+ assert(device.device.supportsScreenshot);
+
+ final Status status = logger.startProgress(
+ 'Taking screenshot for ${device.device.name}...',
+ );
+ final File outputFile = getUniqueFile(
+ fileSystem.currentDirectory,
+ 'flutter',
+ 'png',
+ );
+ List<FlutterView> views = <FlutterView>[];
+ Future<bool> setDebugBanner(bool value) async {
+ try {
+ for (final FlutterView view in views) {
+ await device.vmService.flutterDebugAllowBanner(
+ value,
+ isolateId: view.uiIsolate.id,
+ );
+ }
+ return true;
+ } on Exception catch (error) {
+ status.cancel();
+ logger.printError('Error communicating with Flutter on the device: $error');
+ return false;
+ }
+ }
+
+ try {
+ if (supportsServiceProtocol && isRunningDebug) {
+ // Ensure that the vmService access is guarded by supportsServiceProtocol, it
+ // will be null in release mode.
+ views = await device.vmService.getFlutterViews();
+ if (!await setDebugBanner(false)) {
+ return;
+ }
+ }
+ try {
+ await device.device.takeScreenshot(outputFile);
+ } finally {
+ if (supportsServiceProtocol && isRunningDebug) {
+ await setDebugBanner(true);
+ }
+ }
+ final int sizeKB = outputFile.lengthSync() ~/ 1024;
+ status.stop();
+ logger.printStatus(
+ 'Screenshot written to ${fileSystem.path.relative(outputFile.path)} (${sizeKB}kB).',
+ );
+ } on Exception catch (error) {
+ status.cancel();
+ logger.printError('Error taking screenshot: $error');
+ }
+ }
+
+ /// Remove sigusr signal handlers.
+ Future<void> cleanupAfterSignal();
+
+ /// Tear down the runner and leave the application running.
+ ///
+ /// This is not supported on web devices where the runner is running
+ /// the application server as well.
+ Future<void> detach();
+
+ /// Tear down the runner and exit the application.
+ Future<void> exit();
+
+ /// Run any source generators, such as localizations.
+ ///
+ /// These are automatically run during hot restart, but can be
+ /// triggered manually to see the updated generated code.
+ Future<void> runSourceGenerators();
+}
+
// Shared code between different resident application runners.
-abstract class ResidentRunner {
+abstract class ResidentRunner extends ResidentHandlers {
ResidentRunner(
this.flutterDevices, {
@required this.target,
@@ -788,12 +1046,19 @@
_residentDevtoolsHandler = devtoolsHandler(DevtoolsLauncher.instance, this, globals.logger);
}
- @protected
- @visibleForTesting
+ @override
+ Logger get logger => globals.logger;
+
+ @override
+ FileSystem get fileSystem => globals.fs;
+
+ @override
final List<FlutterDevice> flutterDevices;
final String target;
final DebuggingOptions debuggingOptions;
+
+ @override
final bool stayResident;
final bool ipv6;
final String _dillOutputPath;
@@ -812,6 +1077,10 @@
bool _exited = false;
Completer<int> _finished = Completer<int>();
+ BuildResult _lastBuild;
+ Environment _environment;
+
+ @override
bool hotMode;
/// Returns true if every device is streaming observatory URIs.
@@ -833,11 +1102,22 @@
}
bool get debuggingEnabled => debuggingOptions.debuggingEnabled;
+
+ @override
bool get isRunningDebug => debuggingOptions.buildInfo.isDebug;
+
+ @override
bool get isRunningProfile => debuggingOptions.buildInfo.isProfile;
+
+ @override
bool get isRunningRelease => debuggingOptions.buildInfo.isRelease;
+
+ @override
bool get supportsServiceProtocol => isRunningDebug || isRunningProfile;
+
+ @override
bool get supportsWriteSkSL => supportsServiceProtocol;
+
bool get trackWidgetCreation => debuggingOptions.buildInfo.trackWidgetCreation;
// Returns the Uri of the first connected device for mobile,
@@ -850,38 +1130,14 @@
/// Returns [true] if the resident runner exited after invoking [exit()].
bool get exited => _exited;
- /// Whether this runner can hot restart.
- ///
- /// To prevent scenarios where only a subset of devices are hot restarted,
- /// the runner requires that all attached devices can support hot restart
- /// before enabling it.
- bool get canHotRestart {
- return flutterDevices.every((FlutterDevice device) {
+ @override
+ bool get supportsRestart {
+ return isRunningDebug && flutterDevices.every((FlutterDevice device) {
return device.device.supportsHotRestart;
});
}
- /// Invoke an RPC extension method on the first attached ui isolate of the first device.
- // TODO(jonahwilliams): Update/Remove this method when refactoring the resident
- // runner to support a single flutter device.
- Future<Map<String, dynamic>> invokeFlutterExtensionRpcRawOnFirstIsolate(
- String method, {
- FlutterDevice device,
- Map<String, dynamic> params,
- }) async {
- device ??= flutterDevices.first;
- final List<FlutterView> views = await device.vmService.getFlutterViews();
- return device
- .vmService
- .invokeFlutterExtensionRpcRaw(
- method,
- args: params,
- isolateId: views
- .first.uiIsolate.id
- );
- }
-
- /// Whether this runner can hot reload.
+ @override
bool get canHotReload => hotMode;
/// Start the app and keep the process running during its lifetime.
@@ -902,17 +1158,7 @@
bool enableDevTools = false,
});
- bool get supportsRestart => false;
-
- Future<OperationResult> restart({ bool fullRestart = false, bool pause = false, String reason }) {
- final String mode = isRunningProfile ? 'profile' :
- isRunningRelease ? 'release' : 'this';
- throw '${fullRestart ? 'Restart' : 'Reload'} is not supported in $mode mode';
- }
-
-
- BuildResult _lastBuild;
- Environment _environment;
+ @override
Future<void> runSourceGenerators() async {
_environment ??= Environment(
artifacts: globals.artifacts,
@@ -944,23 +1190,6 @@
globals.logger.printTrace('complete');
}
- /// Write the SkSL shaders to a zip file in build directory.
- ///
- /// Returns the name of the file, or `null` on failures.
- Future<String> writeSkSL() async {
- if (!supportsWriteSkSL) {
- throw Exception('writeSkSL is not supported by this runner.');
- }
- final List<FlutterView> views = await flutterDevices
- .first
- .vmService.getFlutterViews();
- final Map<String, Object> data = await flutterDevices.first.vmService.getSkSLs(
- viewId: views.first.id,
- );
- final Device device = flutterDevices.first.device;
- return sharedSkSlWriter(device, data);
- }
-
@protected
void writeVmServiceFile() {
if (debuggingOptions.vmserviceOutFile != null) {
@@ -975,6 +1204,7 @@
}
}
+ @override
Future<void> exit() async {
_exited = true;
await residentDevtoolsHandler.shutdown();
@@ -984,6 +1214,7 @@
await shutdownDartDevelopmentService();
}
+ @override
Future<void> detach() async {
await residentDevtoolsHandler.shutdown();
await stopEchoingDeviceLog();
@@ -992,212 +1223,6 @@
appFinished();
}
- Future<bool> debugDumpApp() async {
- if (!supportsServiceProtocol) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.debugDumpApp();
- }
- return true;
- }
-
- Future<bool> debugDumpRenderTree() async {
- if (!supportsServiceProtocol) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.debugDumpRenderTree();
- }
- return true;
- }
-
- Future<bool> debugDumpLayerTree() async {
- if (!supportsServiceProtocol || !isRunningDebug) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.debugDumpLayerTree();
- }
- return true;
- }
-
- Future<bool> debugDumpSemanticsTreeInTraversalOrder() async {
- if (!supportsServiceProtocol) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.debugDumpSemanticsTreeInTraversalOrder();
- }
- return true;
- }
-
- Future<bool> debugDumpSemanticsTreeInInverseHitTestOrder() async {
- if (!supportsServiceProtocol) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.debugDumpSemanticsTreeInInverseHitTestOrder();
- }
- return true;
- }
-
- Future<bool> debugToggleDebugPaintSizeEnabled() async {
- if (!supportsServiceProtocol || !isRunningDebug) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.toggleDebugPaintSizeEnabled();
- }
- return true;
- }
-
- Future<bool> debugToggleDebugCheckElevationsEnabled() async {
- if (!supportsServiceProtocol) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.toggleDebugCheckElevationsEnabled();
- }
- return true;
- }
-
- Future<bool> debugTogglePerformanceOverlayOverride() async {
- if (!supportsServiceProtocol) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.debugTogglePerformanceOverlayOverride();
- }
- return true;
- }
-
- Future<bool> debugToggleWidgetInspector() async {
- if (!supportsServiceProtocol) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.toggleWidgetInspector();
- }
- return true;
- }
-
- Future<bool> debugToggleInvertOversizedImages() async {
- if (!supportsServiceProtocol || !isRunningDebug) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.toggleInvertOversizedImages();
- }
- return true;
- }
-
- Future<bool> debugToggleProfileWidgetBuilds() async {
- if (!supportsServiceProtocol) {
- return false;
- }
- for (final FlutterDevice device in flutterDevices) {
- await device.toggleProfileWidgetBuilds();
- }
- return true;
- }
-
- Future<bool> debugToggleBrightness() async {
- if (!supportsServiceProtocol) {
- return false;
- }
- final Brightness brightness = await flutterDevices.first.toggleBrightness();
- Brightness next;
- for (final FlutterDevice device in flutterDevices) {
- next = await device.toggleBrightness(
- current: brightness,
- );
- globals.logger.printStatus('Changed brightness to $next.');
- }
- return true;
- }
-
- /// Take a screenshot on the provided [device].
- ///
- /// If the device has a connected vmservice, this method will attempt to hide
- /// and restore the debug banner before taking the screenshot.
- ///
- /// Throws an [AssertionError] if [Device.supportsScreenshot] is not true.
- Future<void> screenshot(FlutterDevice device) async {
- assert(device.device.supportsScreenshot);
-
- final Status status = globals.logger.startProgress(
- 'Taking screenshot for ${device.device.name}...',
- );
- final File outputFile = globals.fsUtils.getUniqueFile(
- globals.fs.currentDirectory,
- 'flutter',
- 'png',
- );
- List<FlutterView> views = <FlutterView>[];
- Future<bool> setDebugBanner(bool value) async {
- try {
- for (final FlutterView view in views) {
- await device.vmService.flutterDebugAllowBanner(
- value,
- isolateId: view.uiIsolate.id,
- );
- }
- return true;
- } on Exception catch (error) {
- status.cancel();
- globals.printError('Error communicating with Flutter on the device: $error');
- return false;
- }
- }
-
- try {
- if (supportsServiceProtocol && isRunningDebug) {
- // Ensure that the vmService access is guarded by supportsServiceProtocol, it
- // will be null in release mode.
- views = await device.vmService.getFlutterViews();
- if (!await setDebugBanner(false)) {
- return;
- }
- }
- try {
- await device.device.takeScreenshot(outputFile);
- } finally {
- if (supportsServiceProtocol && isRunningDebug) {
- await setDebugBanner(true);
- }
- }
- final int sizeKB = outputFile.lengthSync() ~/ 1024;
- status.stop();
- globals.printStatus(
- 'Screenshot written to ${globals.fs.path.relative(outputFile.path)} (${sizeKB}kB).',
- );
- } on Exception catch (error) {
- status.cancel();
- globals.printError('Error taking screenshot: $error');
- }
- }
-
- Future<bool> debugTogglePlatform() async {
- if (!supportsServiceProtocol || !isRunningDebug) {
- return false;
- }
- final List<FlutterView> views = await flutterDevices
- .first
- .vmService.getFlutterViews();
- final String isolateId = views.first.uiIsolate.id;
- final String from = await flutterDevices
- .first.vmService.flutterPlatformOverride(
- isolateId: isolateId,
- );
- String to;
- for (final FlutterDevice device in flutterDevices) {
- to = await device.togglePlatform(from: from);
- }
- globals.printStatus('Switched operating system to $to');
- return true;
- }
-
Future<void> stopEchoingDeviceLog() async {
await Future.wait<void>(
flutterDevices.map<Future<void>>((FlutterDevice device) => device.stopEchoingDeviceLog())
@@ -1379,9 +1404,6 @@
_reportedDebuggers = true;
}
- /// Called to print help to the terminal.
- void printHelp({ @required bool details });
-
void printHelpDetails() {
if (flutterDevices.any((FlutterDevice d) => d.device.supportsScreenshot)) {
commandHelp.s.print();
@@ -1413,14 +1435,11 @@
}
}
- /// Called when a signal has requested we exit.
+ @override
Future<void> cleanupAfterSignal();
/// Called right before we exit.
Future<void> cleanupAtFinish();
-
- // Clears the screen.
- void clearScreen() => globals.logger.clear();
}
class OperationResult {
@@ -1479,7 +1498,7 @@
final bool _reportReady;
final String _pidFile;
- final ResidentRunner residentRunner;
+ final ResidentHandlers residentRunner;
bool _processingUserRequest = false;
StreamSubscription<void> subscription;
File _actualPidFile;
@@ -1487,6 +1506,10 @@
@visibleForTesting
String lastReceivedCommand;
+ /// This is only a buffer logger in unit tests
+ @visibleForTesting
+ BufferLogger get logger => _logger as BufferLogger;
+
void setupTerminal() {
if (!_logger.quiet) {
_logger.printStatus('');
@@ -1544,7 +1567,7 @@
case 'b':
return residentRunner.debugToggleBrightness();
case 'c':
- residentRunner.clearScreen();
+ _logger.clear();
return true;
case 'd':
case 'D':
@@ -1597,7 +1620,7 @@
return true;
case 'R':
// If hot restart is not supported for all devices, ignore the command.
- if (!residentRunner.canHotRestart || !residentRunner.hotMode) {
+ if (!residentRunner.supportsRestart || !residentRunner.hotMode) {
return false;
}
final OperationResult result = await residentRunner.restart(fullRestart: true);
@@ -1694,17 +1717,14 @@
///
/// These values must match what is available in
/// `packages/flutter/lib/src/foundation/binding.dart`.
-String nextPlatform(String currentPlatform, FeatureFlags featureFlags) {
+String nextPlatform(String currentPlatform) {
switch (currentPlatform) {
case 'android':
return 'iOS';
case 'iOS':
return 'fuchsia';
case 'fuchsia':
- if (featureFlags.isMacOSEnabled) {
- return 'macOS';
- }
- return 'android';
+ return 'macOS';
case 'macOS':
return 'android';
default:
diff --git a/packages/flutter_tools/lib/src/run_cold.dart b/packages/flutter_tools/lib/src/run_cold.dart
index 5bcd6a6..198fc93 100644
--- a/packages/flutter_tools/lib/src/run_cold.dart
+++ b/packages/flutter_tools/lib/src/run_cold.dart
@@ -10,6 +10,7 @@
import 'base/common.dart';
import 'base/file_system.dart';
+import 'base/logger.dart';
import 'build_info.dart';
import 'device.dart';
import 'globals_null_migrated.dart' as globals;
@@ -51,7 +52,10 @@
bool get canHotReload => false;
@override
- bool get canHotRestart => false;
+ Logger get logger => globals.logger;
+
+ @override
+ FileSystem get fileSystem => globals.fs;
@override
Future<int> run({
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart
index 22d9a4a..d53ac8d 100644
--- a/packages/flutter_tools/lib/src/run_hot.dart
+++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -599,9 +599,6 @@
}
@override
- bool get supportsRestart => true;
-
- @override
Future<OperationResult> restart({
bool fullRestart = false,
String reason,
@@ -670,7 +667,7 @@
String reason,
bool silent,
}) async {
- if (!canHotRestart) {
+ if (!supportsRestart) {
return OperationResult(1, 'hotRestart not supported');
}
Status status;
@@ -1089,7 +1086,7 @@
void printHelp({ @required bool details }) {
globals.printStatus('Flutter run key commands.');
commandHelp.r.print();
- if (canHotRestart) {
+ if (supportsRestart) {
commandHelp.R.print();
}
commandHelp.h.print(); // TODO(ianh): print different message if "details" is false
diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
index 64aaf80..d84fdc9 100644
--- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
@@ -1684,16 +1684,6 @@
expect(testLogger.statusText, contains('1kB'));
}));
- testUsingContext('ResidentRunner clears the screen when it should', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- const String message = 'This should be cleared';
- expect(testLogger.statusText, equals(''));
- testLogger.printStatus(message);
- expect(testLogger.statusText, equals(message + '\n')); // printStatus makes a newline
- residentRunner.clearScreen();
- expect(testLogger.statusText, equals(''));
- }));
-
testUsingContext('ResidentRunner bails taking screenshot on debug device if debugAllowBanner throws RpcError', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
listViews,
@@ -1906,361 +1896,6 @@
expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
- testUsingContext('ResidentRunner debugDumpApp calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugDumpApp(), true);
- verify(mockFlutterDevice.debugDumpApp()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugDumpApp does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugDumpApp(), false);
- verifyNever(mockFlutterDevice.debugDumpApp());
- }));
-
- testUsingContext('ResidentRunner debugDumpRenderTree calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugDumpRenderTree(), true);
- verify(mockFlutterDevice.debugDumpRenderTree()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugDumpRenderTree does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugDumpRenderTree(), false);
- verifyNever(mockFlutterDevice.debugDumpRenderTree());
- }));
-
- testUsingContext('ResidentRunner debugDumpLayerTree calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugDumpLayerTree(), true);
- verify(mockFlutterDevice.debugDumpLayerTree()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugDumpLayerTree does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugDumpLayerTree(), false);
- verifyNever(mockFlutterDevice.debugDumpLayerTree());
- }));
-
- testUsingContext('ResidentRunner debugDumpLayerTree does not call flutter device if not running in debug mode', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugDumpLayerTree(), false);
- verifyNever(mockFlutterDevice.debugDumpLayerTree());
- }));
-
- testUsingContext('ResidentRunner debugDumpSemanticsTreeInTraversalOrder calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugDumpSemanticsTreeInTraversalOrder(), true);
- verify(mockFlutterDevice.debugDumpSemanticsTreeInTraversalOrder()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugDumpSemanticsTreeInTraversalOrder does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugDumpSemanticsTreeInTraversalOrder(), false);
- verifyNever(mockFlutterDevice.debugDumpSemanticsTreeInTraversalOrder());
- }));
-
- testUsingContext('ResidentRunner debugDumpSemanticsTreeInInverseHitTestOrder calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugDumpSemanticsTreeInInverseHitTestOrder(), true);
- verify(mockFlutterDevice.debugDumpSemanticsTreeInInverseHitTestOrder()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugDumpSemanticsTreeInInverseHitTestOrder does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugDumpSemanticsTreeInInverseHitTestOrder(), false);
- verifyNever(mockFlutterDevice.debugDumpSemanticsTreeInInverseHitTestOrder());
- }));
-
- testUsingContext('ResidentRunner debugToggleDebugPaintSizeEnabled calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugToggleDebugPaintSizeEnabled(), true);
- verify(mockFlutterDevice.toggleDebugPaintSizeEnabled()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugToggleDebugPaintSizeEnabled does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugToggleDebugPaintSizeEnabled(), false);
- verifyNever(mockFlutterDevice.toggleDebugPaintSizeEnabled());
- }));
-
- testUsingContext('ResidentRunner debugToggleBrightness calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugToggleBrightness(), true);
- verify(mockFlutterDevice.toggleBrightness()).called(2);
- }));
-
- testUsingContext('ResidentRunner debugToggleBrightness does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugToggleBrightness(), false);
- verifyNever(mockFlutterDevice.toggleBrightness());
- }));
-
- testUsingContext('FlutterDevice.toggleBrightness invokes correct VM service request', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
- listViews,
- const FakeVmServiceRequest(
- method: 'ext.flutter.brightnessOverride',
- args: <String, Object>{
- 'isolateId': '1',
- },
- jsonResponse: <String, Object>{
- 'value': 'Brightness.dark'
- },
- ),
- ]);
- final FlutterDevice flutterDevice = FlutterDevice(
- mockDevice,
- buildInfo: BuildInfo.debug,
- );
- flutterDevice.vmService = fakeVmServiceHost.vmService;
-
- expect(await flutterDevice.toggleBrightness(), Brightness.dark);
- expect(fakeVmServiceHost.hasRemainingExpectations, false);
- }));
-
- testUsingContext('ResidentRunner debugToggleInvertOversizedImages calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugToggleInvertOversizedImages(), true);
- verify(mockFlutterDevice.toggleInvertOversizedImages()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugToggleInvertOversizedImages does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugToggleInvertOversizedImages(), false);
- verifyNever(mockFlutterDevice.toggleInvertOversizedImages());
- }));
-
- testUsingContext('ResidentRunner debugToggleInvertOversizedImages does not call flutter device if in profile mode', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugToggleInvertOversizedImages(), false);
- verifyNever(mockFlutterDevice.toggleInvertOversizedImages());
- }));
-
- testUsingContext('FlutterDevice.toggleInvertOversizedImages invokes correct VM service request', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
- listViews,
- const FakeVmServiceRequest(
- method: 'ext.flutter.invertOversizedImages',
- args: <String, Object>{
- 'isolateId': '1',
- },
- jsonResponse: <String, Object>{
- 'value': 'false'
- },
- ),
- ]);
- final FlutterDevice flutterDevice = FlutterDevice(
- mockDevice,
- buildInfo: BuildInfo.debug,
- );
- flutterDevice.vmService = fakeVmServiceHost.vmService;
-
- await flutterDevice.toggleInvertOversizedImages();
- expect(fakeVmServiceHost.hasRemainingExpectations, false);
- }));
-
- testUsingContext('ResidentRunner debugToggleDebugCheckElevationsEnabled calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugToggleDebugCheckElevationsEnabled(), true);
- verify(mockFlutterDevice.toggleDebugCheckElevationsEnabled()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugToggleDebugCheckElevationsEnabled does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugToggleDebugCheckElevationsEnabled(), false);
- verifyNever(mockFlutterDevice.toggleDebugCheckElevationsEnabled());
- }));
-
- testUsingContext('ResidentRunner debugTogglePerformanceOverlayOverride calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugTogglePerformanceOverlayOverride(), true);
- verify(mockFlutterDevice.debugTogglePerformanceOverlayOverride()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugTogglePerformanceOverlayOverride does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugTogglePerformanceOverlayOverride(), false);
- verifyNever(mockFlutterDevice.debugTogglePerformanceOverlayOverride());
- }));
-
-
- testUsingContext('ResidentRunner debugToggleWidgetInspector calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
-
- expect(await residentRunner.debugToggleWidgetInspector(), true);
- verify(mockFlutterDevice.toggleWidgetInspector()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugToggleWidgetInspector does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugToggleWidgetInspector(), false);
- verifyNever(mockFlutterDevice.toggleWidgetInspector());
- }));
-
- testUsingContext('ResidentRunner debugToggleProfileWidgetBuilds calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- await residentRunner.debugToggleProfileWidgetBuilds();
-
- verify(mockFlutterDevice.toggleProfileWidgetBuilds()).called(1);
- }));
-
- testUsingContext('ResidentRunner debugToggleProfileWidgetBuilds does not call flutter device if service protocol is unsupported', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- residentRunner = HotRunner(
- <FlutterDevice>[
- mockFlutterDevice,
- ],
- stayResident: false,
- debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
- target: 'main.dart',
- devtoolsHandler: createNoOpHandler,
- );
-
- expect(await residentRunner.debugToggleProfileWidgetBuilds(), false);
- verifyNever(mockFlutterDevice.toggleProfileWidgetBuilds());
- }));
-
testUsingContext('HotRunner writes vm service file when providing debugging option', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
listViews,
@@ -2811,11 +2446,11 @@
}));
testUsingContext('nextPlatform moves through expected platforms', () {
- expect(nextPlatform('android', TestFeatureFlags()), 'iOS');
- expect(nextPlatform('iOS', TestFeatureFlags()), 'fuchsia');
- expect(nextPlatform('fuchsia', TestFeatureFlags()), 'android');
- expect(nextPlatform('fuchsia', TestFeatureFlags(isMacOSEnabled: true)), 'macOS');
- expect(() => nextPlatform('unknown', TestFeatureFlags()), throwsAssertionError);
+ expect(nextPlatform('android'), 'iOS');
+ expect(nextPlatform('iOS'), 'fuchsia');
+ expect(nextPlatform('fuchsia'), 'macOS');
+ expect(nextPlatform('macOS'), 'android');
+ expect(() => nextPlatform('unknown'), throwsAssertionError);
});
}
diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart
index 2033450..ad93839 100644
--- a/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart
@@ -55,7 +55,6 @@
ipv6: true,
stayResident: true,
urlTunneller: null,
- featureFlags: TestFeatureFlags(),
fileSystem: globals.fs,
logger: globals.logger,
systemClock: globals.systemClock,
diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
index f12042d..f65a4a4 100644
--- a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
@@ -195,7 +195,6 @@
fileSystem: fileSystem,
logger: BufferLogger.test(),
usage: globals.flutterUsage,
- featureFlags: TestFeatureFlags(),
systemClock: globals.systemClock,
);
@@ -229,7 +228,7 @@
fileSystem: fileSystem,
logger: BufferLogger.test(),
usage: globals.flutterUsage,
- featureFlags: TestFeatureFlags(),
+
systemClock: globals.systemClock,
);
@@ -253,7 +252,6 @@
fileSystem: fileSystem,
logger: BufferLogger.test(),
usage: globals.flutterUsage,
- featureFlags: TestFeatureFlags(),
systemClock: globals.systemClock,
);
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
@@ -268,7 +266,6 @@
fileSystem: fileSystem,
logger: BufferLogger.test(),
usage: globals.flutterUsage,
- featureFlags: TestFeatureFlags(),
systemClock: globals.systemClock,
);
@@ -373,7 +370,6 @@
fileSystem: fileSystem,
logger: logger,
usage: globals.flutterUsage,
- featureFlags: TestFeatureFlags(),
systemClock: globals.systemClock,
);
@@ -398,7 +394,6 @@
fileSystem: fileSystem,
logger: BufferLogger.test(),
usage: globals.flutterUsage,
- featureFlags: TestFeatureFlags(),
systemClock: globals.systemClock,
);
@@ -517,7 +512,6 @@
fileSystem: fileSystem,
logger: BufferLogger.test(),
usage: globals.flutterUsage,
- featureFlags: TestFeatureFlags(),
systemClock: globals.systemClock,
);
fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList());
@@ -1439,7 +1433,6 @@
fileSystem: fileSystem,
logger: logger,
usage: globals.flutterUsage,
- featureFlags: TestFeatureFlags(),
systemClock: globals.systemClock,
);
@@ -1487,7 +1480,6 @@
fileSystem: fileSystem,
logger: logger,
usage: globals.flutterUsage,
- featureFlags: TestFeatureFlags(),
systemClock: globals.systemClock,
);
@@ -1606,7 +1598,6 @@
systemClock: systemClock ?? SystemClock.fixed(DateTime.now()),
fileSystem: globals.fs,
logger: logger ?? BufferLogger.test(),
- featureFlags: TestFeatureFlags(),
);
}
diff --git a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart
index 7b7d59f..8a4408a 100644
--- a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart
+++ b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart
@@ -240,7 +240,7 @@
});
testWithoutContext('R - hotRestart supported and succeeds', () async {
- when(mockResidentRunner.canHotRestart).thenReturn(true);
+ when(mockResidentRunner.supportsRestart).thenReturn(true);
when(mockResidentRunner.hotMode).thenReturn(true);
when(mockResidentRunner.restart(fullRestart: true))
.thenAnswer((Invocation invocation) async {
@@ -252,7 +252,7 @@
});
testWithoutContext('R - hotRestart supported and fails', () async {
- when(mockResidentRunner.canHotRestart).thenReturn(true);
+ when(mockResidentRunner.supportsRestart).thenReturn(true);
when(mockResidentRunner.hotMode).thenReturn(true);
when(mockResidentRunner.restart(fullRestart: true))
.thenAnswer((Invocation invocation) async {
@@ -266,7 +266,7 @@
});
testWithoutContext('R - hotRestart supported and fails fatally', () async {
- when(mockResidentRunner.canHotRestart).thenReturn(true);
+ when(mockResidentRunner.supportsRestart).thenReturn(true);
when(mockResidentRunner.hotMode).thenReturn(true);
when(mockResidentRunner.restart(fullRestart: true))
.thenAnswer((Invocation invocation) async {
@@ -276,12 +276,23 @@
});
testWithoutContext('R - hot restart unsupported', () async {
- when(mockResidentRunner.canHotRestart).thenReturn(false);
+ when(mockResidentRunner.supportsRestart).thenReturn(false);
await terminalHandler.processTerminalInput('R');
verifyNever(mockResidentRunner.restart(fullRestart: true));
});
+ testWithoutContext('ResidentRunner clears the screen when it should', () async {
+ const String message = 'This should be cleared';
+
+ expect(testLogger.statusText, equals(''));
+ testLogger.printStatus(message);
+ expect(testLogger.statusText, equals(message + '\n')); // printStatus makes a newline
+
+ await terminalHandler.processTerminalInput('c');
+ expect(testLogger.statusText, equals(''));
+ });
+
testWithoutContext('S - debugDumpSemanticsTreeInTraversalOrder with service protocol', () async {
await terminalHandler.processTerminalInput('S');