
This change is a major step towards moving away from shipping DDS via Pub. The first component of this PR is the move away from importing package:dds to launch DDS. Instead, DDS is launched out of process using the `dart development-service` command shipped with the Dart SDK. This makes Flutter's handling of DDS consistent with the standalone Dart VM. The second component of this PR is the initial work to prepare for the removal of instances of DevTools being served manually by the flutter_tool, instead relying on DDS to serve DevTools. This will be consistent with how the standalone Dart VM serves DevTools, tying the DevTools lifecycle to a live DDS instance. This will allow for the removal of much of the logic needed to properly manage the lifecycle of the DevTools server in a future PR. Also, by serving DevTools from DDS, users will no longer need to forward a secondary port in remote workflows as DevTools will be available on the DDS port. This code is currently commented out and will be enabled in a future PR. There's two remaining circumstances that will prevent us from removing DevtoolsRunner completely: - The daemon's `devtools.serve` endpoint - `flutter drive`'s `--profile-memory` flag used for recording memory profiles This PR also includes some refactoring around `DebuggingOptions` to reduce the number of debugging related arguments being passed as parameters adjacent to a `DebuggingOptions` instance.
233 lines
5.9 KiB
Dart
233 lines
5.9 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:flutter_tools/src/application_package.dart';
|
|
import 'package:flutter_tools/src/asset.dart';
|
|
import 'package:flutter_tools/src/build_info.dart';
|
|
import 'package:flutter_tools/src/build_system/tools/shader_compiler.dart';
|
|
import 'package:flutter_tools/src/compile.dart';
|
|
import 'package:flutter_tools/src/devfs.dart';
|
|
import 'package:flutter_tools/src/device.dart';
|
|
import 'package:flutter_tools/src/project.dart';
|
|
import 'package:flutter_tools/src/resident_runner.dart';
|
|
import 'package:flutter_tools/src/run_hot.dart';
|
|
import 'package:flutter_tools/src/vmservice.dart';
|
|
import 'package:package_config/package_config.dart';
|
|
import 'package:test/fake.dart';
|
|
import 'package:vm_service/vm_service.dart' as vm_service;
|
|
|
|
class FakeDevFs extends Fake implements DevFS {
|
|
@override
|
|
Future<void> destroy() async { }
|
|
|
|
@override
|
|
List<Uri> sources = <Uri>[];
|
|
|
|
@override
|
|
DateTime? lastCompiled;
|
|
|
|
@override
|
|
PackageConfig? lastPackageConfig;
|
|
|
|
@override
|
|
Set<String> assetPathsToEvict = <String>{};
|
|
|
|
@override
|
|
Set<String> shaderPathsToEvict= <String>{};
|
|
|
|
@override
|
|
Set<String> scenePathsToEvict= <String>{};
|
|
|
|
@override
|
|
Uri? baseUri;
|
|
}
|
|
|
|
class FakeDevice extends Fake implements Device {
|
|
FakeDevice({
|
|
TargetPlatform targetPlatform = TargetPlatform.tester,
|
|
}) : _targetPlatform = targetPlatform;
|
|
|
|
final TargetPlatform _targetPlatform;
|
|
|
|
bool disposed = false;
|
|
|
|
@override
|
|
bool isSupported() => true;
|
|
|
|
@override
|
|
bool supportsHotReload = true;
|
|
|
|
@override
|
|
bool supportsHotRestart = true;
|
|
|
|
@override
|
|
bool supportsFlutterExit = true;
|
|
|
|
@override
|
|
Future<TargetPlatform> get targetPlatform async => _targetPlatform;
|
|
|
|
@override
|
|
Future<String> get sdkNameAndVersion async => 'Tester';
|
|
|
|
@override
|
|
Future<bool> get isLocalEmulator async => false;
|
|
|
|
@override
|
|
String get name => 'Fake Device';
|
|
|
|
@override
|
|
Future<bool> stopApp(
|
|
ApplicationPackage? app, {
|
|
String? userIdentifier,
|
|
}) async {
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
Future<void> dispose() async {
|
|
disposed = true;
|
|
}
|
|
}
|
|
|
|
class FakeFlutterDevice extends Fake implements FlutterDevice {
|
|
FakeFlutterDevice(this.device);
|
|
|
|
bool stoppedEchoingDeviceLog = false;
|
|
late Future<UpdateFSReport> Function() updateDevFSReportCallback;
|
|
|
|
@override
|
|
final FakeDevice device;
|
|
|
|
@override
|
|
Future<void> stopEchoingDeviceLog() async {
|
|
stoppedEchoingDeviceLog = true;
|
|
}
|
|
|
|
@override
|
|
DevFS? devFS = FakeDevFs();
|
|
|
|
@override
|
|
FlutterVmService get vmService => FakeFlutterVmService();
|
|
|
|
@override
|
|
ResidentCompiler? generator;
|
|
|
|
@override
|
|
Future<UpdateFSReport> updateDevFS({
|
|
Uri? mainUri,
|
|
String? target,
|
|
AssetBundle? bundle,
|
|
bool bundleFirstUpload = false,
|
|
bool bundleDirty = false,
|
|
bool fullRestart = false,
|
|
String? projectRootPath,
|
|
String? pathToReload,
|
|
required String dillOutputPath,
|
|
required List<Uri> invalidatedFiles,
|
|
required PackageConfig packageConfig,
|
|
}) => updateDevFSReportCallback();
|
|
|
|
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
|
|
// @override
|
|
// Future<void> handleHotRestart() async {}
|
|
|
|
@override
|
|
TargetPlatform? get targetPlatform => device._targetPlatform;
|
|
}
|
|
|
|
class TestFlutterDevice extends FlutterDevice {
|
|
TestFlutterDevice({
|
|
required Device device,
|
|
required this.exception,
|
|
required ResidentCompiler generator,
|
|
}) : super(device, buildInfo: BuildInfo.debug, generator: generator, developmentShaderCompiler: const FakeShaderCompiler());
|
|
|
|
/// The exception to throw when the connect method is called.
|
|
final Exception exception;
|
|
|
|
@override
|
|
Future<void> connect({
|
|
ReloadSources? reloadSources,
|
|
Restart? restart,
|
|
CompileExpression? compileExpression,
|
|
GetSkSLMethod? getSkSLMethod,
|
|
FlutterProject? flutterProject,
|
|
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
|
|
required DebuggingOptions debuggingOptions,
|
|
int? hostVmServicePort,
|
|
bool? ipv6 = false,
|
|
bool enableDevTools = false,
|
|
bool allowExistingDdsInstance = false,
|
|
}) async {
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
class TestHotRunnerConfig extends HotRunnerConfig {
|
|
TestHotRunnerConfig({this.successfulHotRestartSetup, this.successfulHotReloadSetup});
|
|
bool? successfulHotRestartSetup;
|
|
bool? successfulHotReloadSetup;
|
|
bool shutdownHookCalled = false;
|
|
bool updateDevFSCompleteCalled = false;
|
|
|
|
@override
|
|
Future<bool?> setupHotRestart() async {
|
|
assert(successfulHotRestartSetup != null, 'setupHotRestart is not expected to be called in this test.');
|
|
return successfulHotRestartSetup;
|
|
}
|
|
|
|
@override
|
|
Future<bool?> setupHotReload() async {
|
|
assert(successfulHotReloadSetup != null, 'setupHotReload is not expected to be called in this test.');
|
|
return successfulHotReloadSetup;
|
|
}
|
|
|
|
@override
|
|
void updateDevFSComplete() {
|
|
updateDevFSCompleteCalled = true;
|
|
}
|
|
|
|
@override
|
|
Future<void> runPreShutdownOperations() async {
|
|
shutdownHookCalled = true;
|
|
}
|
|
}
|
|
|
|
class FakeResidentCompiler extends Fake implements ResidentCompiler {
|
|
@override
|
|
void accept() {}
|
|
}
|
|
|
|
class FakeFlutterVmService extends Fake implements FlutterVmService {
|
|
@override
|
|
vm_service.VmService get service => FakeVmService();
|
|
|
|
@override
|
|
Future<List<FlutterView>> getFlutterViews({bool returnEarly = false, Duration delay = const Duration(milliseconds: 50)}) async {
|
|
return <FlutterView>[];
|
|
}
|
|
}
|
|
|
|
class FakeVmService extends Fake implements vm_service.VmService {
|
|
@override
|
|
Future<vm_service.VM> getVM() async => FakeVm();
|
|
}
|
|
|
|
class FakeVm extends Fake implements vm_service.VM {
|
|
@override
|
|
List<vm_service.IsolateRef> get isolates => <vm_service.IsolateRef>[];
|
|
}
|
|
|
|
class FakeShaderCompiler implements DevelopmentShaderCompiler {
|
|
const FakeShaderCompiler();
|
|
|
|
@override
|
|
void configureCompiler(TargetPlatform? platform) { }
|
|
|
|
@override
|
|
Future<DevFSContent> recompileShader(DevFSContent inputShader) {
|
|
throw UnimplementedError();
|
|
}
|
|
}
|