mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

Reland of https://github.com/flutter/flutter/pull/142709. The revert of the revert is in the first commit, the fix in the commit on top. The move of the fakes for packages/flutter_tools/test/general.shard/resident_runner_test.dart was erroneous before, as it was trying to use setters instead of a private field. This PR changes the private `_devFS` field in the fake to be a public `fakeDevFS` in line with other fakes. ## Original PR description Native assets in other build systems are not built with `package:native_assets_builder` invoking `build.dart` scripts. Instead all packages have their own blaze rules. Therefore we'd like to not depend on `package:native_assets_builder` from flutter tools in g3 at all. This PR aims to move the imports of `native_assets_builder` and `native_assets_cli` into the `isolated/` directory and into the files with a `main` function that are not used in with other build systems. In order to be able to remove all imports in files used by other build systems, two new interfaces are added `HotRunnerNativeAssetsBuilder` and `TestCompilerNativeAssetsBuilder`. New parameters are then piped all the way through from the entry points: * bin/fuchsia_tester.dart * lib/executable.dart The build_system/targets dir is already excluded in other build systems. So, after this PR only the two above files and build_system/targets import from `isolated/native_assets/` and only `isolated/native_assets/` import `package:native_assets_cli` and `package:native_assets_builder`. Context: * https://github.com/flutter/flutter/issues/142041
530 lines
13 KiB
Dart
530 lines
13 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 'dart:async';
|
|
|
|
import 'package:dds/dds.dart' as dds;
|
|
import 'package:flutter_tools/src/application_package.dart';
|
|
import 'package:flutter_tools/src/asset.dart';
|
|
import 'package:flutter_tools/src/base/dds.dart';
|
|
import 'package:flutter_tools/src/base/file_system.dart';
|
|
import 'package:flutter_tools/src/build_info.dart';
|
|
import 'package:flutter_tools/src/build_system/tools/scene_importer.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/device_port_forwarder.dart';
|
|
import 'package:flutter_tools/src/project.dart';
|
|
import 'package:flutter_tools/src/resident_runner.dart';
|
|
import 'package:flutter_tools/src/run_cold.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;
|
|
|
|
import '../src/fake_vm_services.dart';
|
|
|
|
final vm_service.Event fakeUnpausedEvent = vm_service.Event(
|
|
kind: vm_service.EventKind.kResume,
|
|
timestamp: 0
|
|
);
|
|
|
|
final vm_service.Event fakePausedEvent = vm_service.Event(
|
|
kind: vm_service.EventKind.kPauseException,
|
|
timestamp: 0
|
|
);
|
|
|
|
final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
|
|
id: '1',
|
|
pauseEvent: fakeUnpausedEvent,
|
|
breakpoints: <vm_service.Breakpoint>[],
|
|
extensionRPCs: <String>[],
|
|
libraries: <vm_service.LibraryRef>[
|
|
vm_service.LibraryRef(
|
|
id: '1',
|
|
uri: 'file:///hello_world/main.dart',
|
|
name: '',
|
|
),
|
|
],
|
|
livePorts: 0,
|
|
name: 'test',
|
|
number: '1',
|
|
pauseOnExit: false,
|
|
runnable: true,
|
|
startTime: 0,
|
|
isSystemIsolate: false,
|
|
isolateFlags: <vm_service.IsolateFlag>[],
|
|
);
|
|
|
|
final vm_service.Isolate fakePausedIsolate = vm_service.Isolate(
|
|
id: '1',
|
|
pauseEvent: fakePausedEvent,
|
|
breakpoints: <vm_service.Breakpoint>[
|
|
vm_service.Breakpoint(
|
|
breakpointNumber: 123,
|
|
id: 'test-breakpoint',
|
|
location: vm_service.SourceLocation(
|
|
tokenPos: 0,
|
|
script: vm_service.ScriptRef(id: 'test-script', uri: 'foo.dart'),
|
|
),
|
|
enabled: true,
|
|
resolved: true,
|
|
),
|
|
],
|
|
libraries: <vm_service.LibraryRef>[],
|
|
livePorts: 0,
|
|
name: 'test',
|
|
number: '1',
|
|
pauseOnExit: false,
|
|
runnable: true,
|
|
startTime: 0,
|
|
isSystemIsolate: false,
|
|
isolateFlags: <vm_service.IsolateFlag>[],
|
|
);
|
|
|
|
final vm_service.VM fakeVM = vm_service.VM(
|
|
isolates: <vm_service.IsolateRef>[fakeUnpausedIsolate],
|
|
pid: 1,
|
|
hostCPU: '',
|
|
isolateGroups: <vm_service.IsolateGroupRef>[],
|
|
targetCPU: '',
|
|
startTime: 0,
|
|
name: 'dart',
|
|
architectureBits: 64,
|
|
operatingSystem: '',
|
|
version: '',
|
|
systemIsolateGroups: <vm_service.IsolateGroupRef>[],
|
|
systemIsolates: <vm_service.IsolateRef>[],
|
|
);
|
|
|
|
final FlutterView fakeFlutterView = FlutterView(
|
|
id: 'a',
|
|
uiIsolate: fakeUnpausedIsolate,
|
|
);
|
|
|
|
final FakeVmServiceRequest listViews = FakeVmServiceRequest(
|
|
method: kListViewsMethod,
|
|
jsonResponse: <String, Object>{
|
|
'views': <Object>[
|
|
fakeFlutterView.toJson(),
|
|
],
|
|
},
|
|
);
|
|
|
|
const FakeVmServiceRequest setAssetBundlePath = FakeVmServiceRequest(
|
|
method: '_flutter.setAssetBundlePath',
|
|
args: <String, Object>{
|
|
'viewId': 'a',
|
|
'assetDirectory': 'build/flutter_assets',
|
|
'isolateId': '1',
|
|
}
|
|
);
|
|
|
|
const FakeVmServiceRequest evict = FakeVmServiceRequest(
|
|
method: 'ext.flutter.evict',
|
|
args: <String, Object>{
|
|
'value': 'asset',
|
|
'isolateId': '1',
|
|
}
|
|
);
|
|
|
|
const FakeVmServiceRequest evictShader = FakeVmServiceRequest(
|
|
method: 'ext.ui.window.reinitializeShader',
|
|
args: <String, Object>{
|
|
'assetKey': 'foo.frag',
|
|
'isolateId': '1',
|
|
}
|
|
);
|
|
|
|
final Uri testUri = Uri.parse('foo://bar');
|
|
|
|
// This implements [dds.DartDevelopmentService], not the [DartDevelopmentService]
|
|
// interface from package:flutter_tools.
|
|
class FakeDartDevelopmentService extends Fake implements dds.DartDevelopmentService {
|
|
@override
|
|
Future<void> get done => Future<void>.value();
|
|
|
|
@override
|
|
Uri? get uri => null;
|
|
}
|
|
|
|
class FakeDartDevelopmentServiceException implements dds.DartDevelopmentServiceException {
|
|
FakeDartDevelopmentServiceException({this.message = defaultMessage});
|
|
|
|
@override
|
|
final int errorCode = dds.DartDevelopmentServiceException.existingDdsInstanceError;
|
|
|
|
@override
|
|
final String message;
|
|
static const String defaultMessage = 'A DDS instance is already connected at http://localhost:8181';
|
|
}
|
|
|
|
class TestFlutterDevice extends FlutterDevice {
|
|
TestFlutterDevice(super.device, { Stream<Uri>? vmServiceUris })
|
|
: _vmServiceUris = vmServiceUris, super(buildInfo: BuildInfo.debug, developmentShaderCompiler: const FakeShaderCompiler());
|
|
|
|
final Stream<Uri>? _vmServiceUris;
|
|
|
|
@override
|
|
Stream<Uri> get vmServiceUris => _vmServiceUris!;
|
|
}
|
|
|
|
class ThrowingForwardingFileSystem extends ForwardingFileSystem {
|
|
ThrowingForwardingFileSystem(super.delegate);
|
|
|
|
@override
|
|
File file(dynamic path) {
|
|
if (path == 'foo') {
|
|
throw const FileSystemException();
|
|
}
|
|
return delegate.file(path);
|
|
}
|
|
}
|
|
|
|
class FakeFlutterDevice extends Fake implements FlutterDevice {
|
|
FakeVmServiceHost? Function()? vmServiceHost;
|
|
Uri? testUri;
|
|
UpdateFSReport report = UpdateFSReport(
|
|
success: true,
|
|
invalidatedSourcesCount: 1,
|
|
);
|
|
Exception? reportError;
|
|
Exception? runColdError;
|
|
int runHotCode = 0;
|
|
int runColdCode = 0;
|
|
|
|
@override
|
|
ResidentCompiler? generator;
|
|
|
|
@override
|
|
DevelopmentShaderCompiler get developmentShaderCompiler => const FakeShaderCompiler();
|
|
|
|
@override
|
|
TargetPlatform targetPlatform = TargetPlatform.android;
|
|
|
|
@override
|
|
Stream<Uri?> get vmServiceUris => Stream<Uri?>.value(testUri);
|
|
|
|
@override
|
|
FlutterVmService? get vmService => vmServiceHost?.call()?.vmService;
|
|
|
|
DevFS? fakeDevFS;
|
|
|
|
@override
|
|
DevFS? get devFS => fakeDevFS;
|
|
|
|
@override
|
|
set devFS(DevFS? value) { }
|
|
|
|
@override
|
|
Device? device;
|
|
|
|
@override
|
|
Future<void> stopEchoingDeviceLog() async { }
|
|
|
|
@override
|
|
Future<void> initLogReader() async { }
|
|
|
|
@override
|
|
Future<Uri> setupDevFS(String fsName, Directory rootDirectory) async {
|
|
return testUri!;
|
|
}
|
|
|
|
@override
|
|
Future<int> runHot({required HotRunner hotRunner, String? route}) async {
|
|
return runHotCode;
|
|
}
|
|
|
|
@override
|
|
Future<int> runCold({required ColdRunner coldRunner, String? route}) async {
|
|
if (runColdError != null) {
|
|
throw runColdError!;
|
|
}
|
|
return runColdCode;
|
|
}
|
|
|
|
@override
|
|
Future<void> connect({
|
|
ReloadSources? reloadSources,
|
|
Restart? restart,
|
|
CompileExpression? compileExpression,
|
|
GetSkSLMethod? getSkSLMethod,
|
|
FlutterProject? flutterProject,
|
|
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
|
|
int? hostVmServicePort,
|
|
int? ddsPort,
|
|
bool disableServiceAuthCodes = false,
|
|
bool enableDds = true,
|
|
bool cacheStartupProfile = false,
|
|
required bool allowExistingDdsInstance,
|
|
bool ipv6 = false,
|
|
}) async { }
|
|
|
|
@override
|
|
Future<UpdateFSReport> updateDevFS({
|
|
required Uri mainUri,
|
|
String? target,
|
|
AssetBundle? bundle,
|
|
DateTime? firstBuildTime,
|
|
bool bundleFirstUpload = false,
|
|
bool bundleDirty = false,
|
|
bool fullRestart = false,
|
|
String? projectRootPath,
|
|
required String pathToReload,
|
|
required String dillOutputPath,
|
|
required List<Uri> invalidatedFiles,
|
|
required PackageConfig packageConfig,
|
|
}) async {
|
|
if (reportError != null) {
|
|
throw reportError!;
|
|
}
|
|
return report;
|
|
}
|
|
|
|
@override
|
|
Future<void> updateReloadStatus(bool wasReloadSuccessful) async { }
|
|
}
|
|
|
|
class FakeDelegateFlutterDevice extends FlutterDevice {
|
|
FakeDelegateFlutterDevice(
|
|
super.device,
|
|
BuildInfo buildInfo,
|
|
ResidentCompiler residentCompiler,
|
|
this.fakeDevFS,
|
|
) : super(buildInfo: buildInfo, generator: residentCompiler, developmentShaderCompiler: const FakeShaderCompiler());
|
|
|
|
@override
|
|
Future<void> connect({
|
|
ReloadSources? reloadSources,
|
|
Restart? restart,
|
|
bool enableDds = true,
|
|
bool cacheStartupProfile = false,
|
|
bool disableServiceAuthCodes = false,
|
|
bool ipv6 = false,
|
|
CompileExpression? compileExpression,
|
|
GetSkSLMethod? getSkSLMethod,
|
|
FlutterProject? flutterProject,
|
|
int? hostVmServicePort,
|
|
int? ddsPort,
|
|
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
|
|
bool allowExistingDdsInstance = false,
|
|
}) async { }
|
|
|
|
|
|
final DevFS fakeDevFS;
|
|
|
|
@override
|
|
DevFS? get devFS => fakeDevFS;
|
|
|
|
@override
|
|
set devFS(DevFS? value) {}
|
|
}
|
|
|
|
class FakeResidentCompiler extends Fake implements ResidentCompiler {
|
|
CompilerOutput? nextOutput;
|
|
bool didSuppressErrors = false;
|
|
Uri? receivedNativeAssetsYaml;
|
|
bool recompileCalled = false;
|
|
|
|
@override
|
|
Future<CompilerOutput?> recompile(
|
|
Uri mainUri,
|
|
List<Uri>? invalidatedFiles, {
|
|
required String outputPath,
|
|
required PackageConfig packageConfig,
|
|
String? projectRootPath,
|
|
required FileSystem fs,
|
|
bool suppressErrors = false,
|
|
bool checkDartPluginRegistry = false,
|
|
File? dartPluginRegistrant,
|
|
Uri? nativeAssetsYaml,
|
|
}) async {
|
|
recompileCalled = true;
|
|
receivedNativeAssetsYaml = nativeAssetsYaml;
|
|
didSuppressErrors = suppressErrors;
|
|
return nextOutput ?? const CompilerOutput('foo.dill', 0, <Uri>[]);
|
|
}
|
|
|
|
@override
|
|
void accept() { }
|
|
|
|
@override
|
|
void reset() { }
|
|
}
|
|
|
|
class FakeProjectFileInvalidator extends Fake implements ProjectFileInvalidator {
|
|
@override
|
|
Future<InvalidationResult> findInvalidated({
|
|
required DateTime? lastCompiled,
|
|
required List<Uri> urisToMonitor,
|
|
required String packagesPath,
|
|
required PackageConfig packageConfig,
|
|
bool asyncScanning = false,
|
|
}) async {
|
|
return InvalidationResult(
|
|
packageConfig: packageConfig,
|
|
uris: <Uri>[Uri.parse('file:///hello_world/main.dart'),
|
|
]);
|
|
}
|
|
}
|
|
|
|
class FakeDevice extends Fake implements Device {
|
|
FakeDevice({
|
|
String sdkNameAndVersion = 'Android',
|
|
TargetPlatform targetPlatform = TargetPlatform.android_arm,
|
|
bool isLocalEmulator = false,
|
|
this.supportsHotRestart = true,
|
|
this.supportsScreenshot = true,
|
|
this.supportsFlutterExit = true,
|
|
}) : _isLocalEmulator = isLocalEmulator,
|
|
_targetPlatform = targetPlatform,
|
|
_sdkNameAndVersion = sdkNameAndVersion;
|
|
|
|
final bool _isLocalEmulator;
|
|
final TargetPlatform _targetPlatform;
|
|
final String _sdkNameAndVersion;
|
|
|
|
bool disposed = false;
|
|
bool appStopped = false;
|
|
bool failScreenshot = false;
|
|
|
|
@override
|
|
bool supportsHotRestart;
|
|
|
|
@override
|
|
bool supportsScreenshot;
|
|
|
|
@override
|
|
bool supportsFlutterExit;
|
|
|
|
@override
|
|
PlatformType get platformType => _targetPlatform == TargetPlatform.web_javascript
|
|
? PlatformType.web
|
|
: PlatformType.android;
|
|
|
|
@override
|
|
Future<String> get sdkNameAndVersion async => _sdkNameAndVersion;
|
|
|
|
@override
|
|
Future<TargetPlatform> get targetPlatform async => _targetPlatform;
|
|
|
|
@override
|
|
Future<bool> get isLocalEmulator async => _isLocalEmulator;
|
|
|
|
@override
|
|
String get name => 'FakeDevice';
|
|
|
|
@override
|
|
late DartDevelopmentService dds;
|
|
|
|
@override
|
|
Future<void> dispose() async {
|
|
disposed = true;
|
|
}
|
|
|
|
@override
|
|
Future<bool> stopApp(ApplicationPackage? app, {String? userIdentifier}) async {
|
|
appStopped = true;
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
Future<void> takeScreenshot(File outputFile) async {
|
|
if (failScreenshot) {
|
|
throw Exception();
|
|
}
|
|
outputFile.writeAsBytesSync(List<int>.generate(1024, (int i) => i));
|
|
}
|
|
|
|
@override
|
|
FutureOr<DeviceLogReader> getLogReader({
|
|
ApplicationPackage? app,
|
|
bool includePastLogs = false,
|
|
}) => NoOpDeviceLogReader(name);
|
|
|
|
@override
|
|
DevicePortForwarder portForwarder = const NoOpDevicePortForwarder();
|
|
}
|
|
|
|
class FakeDevFS extends Fake implements DevFS {
|
|
@override
|
|
DateTime? lastCompiled = DateTime(2000);
|
|
|
|
@override
|
|
PackageConfig? lastPackageConfig = PackageConfig.empty;
|
|
|
|
@override
|
|
List<Uri> sources = <Uri>[];
|
|
|
|
@override
|
|
Uri baseUri = Uri();
|
|
|
|
@override
|
|
Future<void> destroy() async { }
|
|
|
|
@override
|
|
Set<String> assetPathsToEvict = <String>{};
|
|
|
|
@override
|
|
Set<String> shaderPathsToEvict = <String>{};
|
|
|
|
@override
|
|
Set<String> scenePathsToEvict = <String>{};
|
|
|
|
@override
|
|
bool didUpdateFontManifest = false;
|
|
|
|
UpdateFSReport nextUpdateReport = UpdateFSReport(success: true);
|
|
|
|
@override
|
|
bool hasSetAssetDirectory = false;
|
|
|
|
@override
|
|
Future<Uri> create() async {
|
|
return Uri();
|
|
}
|
|
|
|
@override
|
|
void resetLastCompiled() {
|
|
lastCompiled = null;
|
|
}
|
|
|
|
@override
|
|
Future<UpdateFSReport> update({
|
|
required Uri mainUri,
|
|
required ResidentCompiler generator,
|
|
required bool trackWidgetCreation,
|
|
required String pathToReload,
|
|
required List<Uri> invalidatedFiles,
|
|
required PackageConfig packageConfig,
|
|
required String dillOutputPath,
|
|
required DevelopmentShaderCompiler shaderCompiler,
|
|
DevelopmentSceneImporter? sceneImporter,
|
|
DevFSWriter? devFSWriter,
|
|
String? target,
|
|
AssetBundle? bundle,
|
|
DateTime? firstBuildTime,
|
|
bool bundleFirstUpload = false,
|
|
bool fullRestart = false,
|
|
String? projectRootPath,
|
|
File? dartPluginRegistrant,
|
|
}) async {
|
|
return nextUpdateReport;
|
|
}
|
|
}
|
|
|
|
class FakeShaderCompiler implements DevelopmentShaderCompiler {
|
|
const FakeShaderCompiler();
|
|
|
|
@override
|
|
void configureCompiler(TargetPlatform? platform) { }
|
|
|
|
@override
|
|
Future<DevFSContent> recompileShader(DevFSContent inputShader) {
|
|
throw UnimplementedError();
|
|
}
|
|
}
|