diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index 30dbedcdd9f279..a424873a9b4553 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -186,6 +186,7 @@ class FlutterDevice { Restart restart, CompileExpression compileExpression, ReloadMethod reloadMethod, + GetSkSLMethod getSkSLMethod, }) { final Completer completer = Completer(); StreamSubscription subscription; @@ -204,6 +205,7 @@ class FlutterDevice { restart: restart, compileExpression: compileExpression, reloadMethod: reloadMethod, + getSkSLMethod: getSkSLMethod, device: device, ); } on Exception catch (exception) { @@ -853,7 +855,9 @@ abstract class ResidentRunner { } /// Write the SkSL shaders to a zip file in build directory. - Future writeSkSL() async { + /// + /// Returns the name of the file, or `null` on failures. + Future writeSkSL() async { if (!supportsWriteSkSL) { throw Exception('writeSkSL is not supported by this runner.'); } @@ -870,7 +874,7 @@ abstract class ResidentRunner { ' 1. Pass "--cache-sksl" as an argument to flutter run.\n' ' 2. Interact with the application to force shaders to be compiled.\n' ); - return; + return null; } final File outputFile = globals.fsUtils.getUniqueFile( globals.fs.currentDirectory, @@ -899,6 +903,7 @@ abstract class ResidentRunner { }; outputFile.writeAsStringSync(json.encode(manifest)); globals.logger.printStatus('Wrote SkSL data to ${outputFile.path}.'); + return outputFile.path; } /// The resident runner API for interaction with the reloadMethod vmservice @@ -1103,6 +1108,7 @@ abstract class ResidentRunner { Restart restart, CompileExpression compileExpression, ReloadMethod reloadMethod, + GetSkSLMethod getSkSLMethod, }) async { if (!debuggingOptions.debuggingEnabled) { throw 'The service protocol is not enabled.'; @@ -1115,6 +1121,7 @@ abstract class ResidentRunner { restart: restart, compileExpression: compileExpression, reloadMethod: reloadMethod, + getSkSLMethod: getSkSLMethod ); // This will wait for at least one flutter view before returning. final Status status = globals.logger.startProgress( diff --git a/packages/flutter_tools/lib/src/run_cold.dart b/packages/flutter_tools/lib/src/run_cold.dart index 8bfd230b467a63..81d7fb91284ccf 100644 --- a/packages/flutter_tools/lib/src/run_cold.dart +++ b/packages/flutter_tools/lib/src/run_cold.dart @@ -129,7 +129,9 @@ class ColdRunner extends ResidentRunner { }) async { _didAttach = true; try { - await connectToServiceProtocol(); + await connectToServiceProtocol( + getSkSLMethod: writeSkSL, + ); } on Exception catch (error) { globals.printError('Error connecting to the service protocol: $error'); // https://github.com/flutter/flutter/issues/33050 diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index 33bd40e30bae5e..76fc6e20d066a3 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -225,6 +225,7 @@ class HotRunner extends ResidentRunner { restart: _restartService, compileExpression: _compileExpressionService, reloadMethod: reloadMethod, + getSkSLMethod: writeSkSL, ); // Catches all exceptions, non-Exception objects are rethrown. } catch (error) { // ignore: avoid_catches_without_on_clauses diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart index 14bc858cff44bc..ce743b41895b6a 100644 --- a/packages/flutter_tools/lib/src/vmservice.dart +++ b/packages/flutter_tools/lib/src/vmservice.dart @@ -81,6 +81,12 @@ typedef ReloadMethod = Future Function({ String libraryId, }); + +/// A method that pulls an SkSL shader from the device and writes it to a file. +/// +/// The name of the file returned as a result. +typedef GetSkSLMethod = Future Function(); + Future _defaultOpenChannel(String url, { io.CompressionOptions compression = io.CompressionOptions.compressionDefault }) async { @@ -126,6 +132,7 @@ typedef VMServiceConnector = Future Function(Uri httpUri, Restart restart, CompileExpression compileExpression, ReloadMethod reloadMethod, + GetSkSLMethod getSkSLMethod, io.CompressionOptions compression, Device device, }); @@ -151,6 +158,7 @@ vm_service.VmService setUpVmService( CompileExpression compileExpression, Device device, ReloadMethod reloadMethod, + GetSkSLMethod skSLMethod, vm_service.VmService vmService ) { if (reloadSources != null) { @@ -257,6 +265,18 @@ vm_service.VmService setUpVmService( }); vmService.registerService('flutterMemoryInfo', 'Flutter Tools'); } + if (skSLMethod != null) { + vmService.registerServiceCallback('flutterGetSkSL', (Map params) async { + final String filename = await skSLMethod(); + return { + 'result': { + 'type': 'Success', + 'filename': filename, + } + }; + }); + vmService.registerService('flutterGetSkSL', 'Flutter Tools'); + } return vmService; } @@ -274,6 +294,7 @@ Future connectToVmService( Restart restart, CompileExpression compileExpression, ReloadMethod reloadMethod, + GetSkSLMethod getSkSLMethod, io.CompressionOptions compression = io.CompressionOptions.compressionDefault, Device device, }) async { @@ -285,6 +306,7 @@ Future connectToVmService( compression: compression, device: device, reloadMethod: reloadMethod, + getSkSLMethod: getSkSLMethod, ); } @@ -294,6 +316,7 @@ Future _connect( Restart restart, CompileExpression compileExpression, ReloadMethod reloadMethod, + GetSkSLMethod getSkSLMethod, io.CompressionOptions compression = io.CompressionOptions.compressionDefault, Device device, }) async { @@ -320,6 +343,7 @@ Future _connect( compileExpression, device, reloadMethod, + getSkSLMethod, delegateService, ); _httpAddressExpando[service] = httpUri; diff --git a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart index f5e8649f821138..4b48cdb3117870 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart @@ -678,6 +678,7 @@ VMServiceConnector getFakeVmServiceFactory({ Restart restart, CompileExpression compileExpression, ReloadMethod reloadMethod, + GetSkSLMethod getSkSLMethod, CompressionOptions compression, Device device, }) async { diff --git a/packages/flutter_tools/test/general.shard/cold_test.dart b/packages/flutter_tools/test/general.shard/cold_test.dart index e8a331c04acf87..c7e9b2807aa378 100644 --- a/packages/flutter_tools/test/general.shard/cold_test.dart +++ b/packages/flutter_tools/test/general.shard/cold_test.dart @@ -184,6 +184,7 @@ class TestFlutterDevice extends FlutterDevice { Restart restart, CompileExpression compileExpression, ReloadMethod reloadMethod, + GetSkSLMethod getSkSLMethod, }) async { throw exception; } diff --git a/packages/flutter_tools/test/general.shard/hot_test.dart b/packages/flutter_tools/test/general.shard/hot_test.dart index 9c18f5693ce1ec..099094348768e0 100644 --- a/packages/flutter_tools/test/general.shard/hot_test.dart +++ b/packages/flutter_tools/test/general.shard/hot_test.dart @@ -541,6 +541,7 @@ class TestFlutterDevice extends FlutterDevice { Restart restart, CompileExpression compileExpression, ReloadMethod reloadMethod, + GetSkSLMethod getSkSLMethod, }) async { throw exception; } 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 2635ba66fb62e3..319df1a121fb02 100644 --- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart @@ -144,6 +144,7 @@ void main() { reloadSources: anyNamed('reloadSources'), restart: anyNamed('restart'), compileExpression: anyNamed('compileExpression'), + getSkSLMethod: anyNamed('getSkSLMethod'), )).thenAnswer((Invocation invocation) async { }); when(mockFlutterDevice.setupDevFS(any, any, packagesFilePath: anyNamed('packagesFilePath'))) .thenAnswer((Invocation invocation) async { @@ -1191,6 +1192,7 @@ void main() { Restart restart, CompileExpression compileExpression, ReloadMethod reloadMethod, + GetSkSLMethod getSkSLMethod, io.CompressionOptions compression, Device device, }) async => mockVMService, diff --git a/packages/flutter_tools/test/general.shard/vmservice_test.dart b/packages/flutter_tools/test/general.shard/vmservice_test.dart index 3ae406206f5999..3378b054940b52 100644 --- a/packages/flutter_tools/test/general.shard/vmservice_test.dart +++ b/packages/flutter_tools/test/general.shard/vmservice_test.dart @@ -101,6 +101,7 @@ void main() { null, null, null, + null, mockVMService, ); @@ -119,6 +120,7 @@ void main() { null, null, reloadMethod, + null, mockVMService, ); @@ -137,6 +139,7 @@ void main() { null, mockDevice, null, + null, mockVMService, ); @@ -145,6 +148,23 @@ void main() { Logger: () => BufferLogger.test() }); + testUsingContext('VmService registers flutterGetSkSL service', () async { + final MockVMService mockVMService = MockVMService(); + setUpVmService( + null, + null, + null, + null, + null, + () async => 'hello', + mockVMService, + ); + + verify(mockVMService.registerService('flutterGetSkSL', 'Flutter Tools')).called(1); + }, overrides: { + Logger: () => BufferLogger.test() + }); + testUsingContext('VMService returns correct FlutterVersion', () async { final MockVMService mockVMService = MockVMService(); setUpVmService( @@ -153,6 +173,7 @@ void main() { null, null, null, + null, mockVMService, ); diff --git a/packages/flutter_tools/test/integration.shard/vmservice_integration_test.dart b/packages/flutter_tools/test/integration.shard/vmservice_integration_test.dart index 998ddd7038904e..9345f93c102704 100644 --- a/packages/flutter_tools/test/integration.shard/vmservice_integration_test.dart +++ b/packages/flutter_tools/test/integration.shard/vmservice_integration_test.dart @@ -82,6 +82,12 @@ void main() { expect(response, throwsA(const TypeMatcher())); }); + test('flutterGetSkSL can be called', () async { + final Response response = await vmService.callMethod('s0.flutterGetSkSL'); + + expect(response.type, 'Success'); + }); + // TODO(devoncarew): These tests fail on cirrus-ci windows. }, skip: Platform.isWindows); }