Skip to content

Commit

Permalink
[flutter_tools] add vm service method to pull SkSL (#57813)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahwilliams committed May 27, 2020
1 parent f640ad6 commit 6003382
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 3 deletions.
11 changes: 9 additions & 2 deletions packages/flutter_tools/lib/src/resident_runner.dart
Expand Up @@ -186,6 +186,7 @@ class FlutterDevice {
Restart restart,
CompileExpression compileExpression,
ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod,
}) {
final Completer<void> completer = Completer<void>();
StreamSubscription<void> subscription;
Expand All @@ -204,6 +205,7 @@ class FlutterDevice {
restart: restart,
compileExpression: compileExpression,
reloadMethod: reloadMethod,
getSkSLMethod: getSkSLMethod,
device: device,
);
} on Exception catch (exception) {
Expand Down Expand Up @@ -853,7 +855,9 @@ abstract class ResidentRunner {
}

/// Write the SkSL shaders to a zip file in build directory.
Future<void> writeSkSL() async {
///
/// 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.');
}
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.';
Expand All @@ -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(
Expand Down
4 changes: 3 additions & 1 deletion packages/flutter_tools/lib/src/run_cold.dart
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/flutter_tools/lib/src/run_hot.dart
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions packages/flutter_tools/lib/src/vmservice.dart
Expand Up @@ -81,6 +81,12 @@ typedef ReloadMethod = Future<void> 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<String> Function();

Future<io.WebSocket> _defaultOpenChannel(String url, {
io.CompressionOptions compression = io.CompressionOptions.compressionDefault
}) async {
Expand Down Expand Up @@ -139,6 +145,7 @@ typedef VMServiceConnector = Future<vm_service.VmService> Function(Uri httpUri,
Restart restart,
CompileExpression compileExpression,
ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod,
io.CompressionOptions compression,
Device device,
});
Expand All @@ -164,6 +171,7 @@ vm_service.VmService setUpVmService(
CompileExpression compileExpression,
Device device,
ReloadMethod reloadMethod,
GetSkSLMethod skSLMethod,
vm_service.VmService vmService
) {
if (reloadSources != null) {
Expand Down Expand Up @@ -270,6 +278,18 @@ vm_service.VmService setUpVmService(
});
vmService.registerService('flutterMemoryInfo', 'Flutter Tools');
}
if (skSLMethod != null) {
vmService.registerServiceCallback('flutterGetSkSL', (Map<String, dynamic> params) async {
final String filename = await skSLMethod();
return <String, dynamic>{
'result': <String, Object>{
'type': 'Success',
'filename': filename,
}
};
});
vmService.registerService('flutterGetSkSL', 'Flutter Tools');
}
return vmService;
}

Expand All @@ -287,6 +307,7 @@ Future<vm_service.VmService> connectToVmService(
Restart restart,
CompileExpression compileExpression,
ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device device,
}) async {
Expand All @@ -298,6 +319,7 @@ Future<vm_service.VmService> connectToVmService(
compression: compression,
device: device,
reloadMethod: reloadMethod,
getSkSLMethod: getSkSLMethod,
);
}

Expand All @@ -307,6 +329,7 @@ Future<vm_service.VmService> _connect(
Restart restart,
CompileExpression compileExpression,
ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device device,
}) async {
Expand All @@ -333,6 +356,7 @@ Future<vm_service.VmService> _connect(
compileExpression,
device,
reloadMethod,
getSkSLMethod,
delegateService,
);
_httpAddressExpando[service] = httpUri;
Expand Down
Expand Up @@ -678,6 +678,7 @@ VMServiceConnector getFakeVmServiceFactory({
Restart restart,
CompileExpression compileExpression,
ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod,
CompressionOptions compression,
Device device,
}) async {
Expand Down
1 change: 1 addition & 0 deletions packages/flutter_tools/test/general.shard/cold_test.dart
Expand Up @@ -184,6 +184,7 @@ class TestFlutterDevice extends FlutterDevice {
Restart restart,
CompileExpression compileExpression,
ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod,
}) async {
throw exception;
}
Expand Down
1 change: 1 addition & 0 deletions packages/flutter_tools/test/general.shard/hot_test.dart
Expand Up @@ -541,6 +541,7 @@ class TestFlutterDevice extends FlutterDevice {
Restart restart,
CompileExpression compileExpression,
ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod,
}) async {
throw exception;
}
Expand Down
Expand Up @@ -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 {
Expand Down Expand Up @@ -1191,6 +1192,7 @@ void main() {
Restart restart,
CompileExpression compileExpression,
ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod,
io.CompressionOptions compression,
Device device,
}) async => mockVMService,
Expand Down
21 changes: 21 additions & 0 deletions packages/flutter_tools/test/general.shard/vmservice_test.dart
Expand Up @@ -103,6 +103,7 @@ void main() {
null,
null,
null,
null,
mockVMService,
);

Expand All @@ -121,6 +122,7 @@ void main() {
null,
null,
reloadMethod,
null,
mockVMService,
);

Expand All @@ -139,6 +141,7 @@ void main() {
null,
mockDevice,
null,
null,
mockVMService,
);

Expand All @@ -147,6 +150,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: <Type, Generator>{
Logger: () => BufferLogger.test()
});

testUsingContext('VMService returns correct FlutterVersion', () async {
final MockVMService mockVMService = MockVMService();
setUpVmService(
Expand All @@ -155,6 +175,7 @@ void main() {
null,
null,
null,
null,
mockVMService,
);

Expand Down
Expand Up @@ -82,6 +82,12 @@ void main() {
expect(response, throwsA(const TypeMatcher<RPCError>()));
});

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);
}

0 comments on commit 6003382

Please sign in to comment.