Unverified Commit 1e4d9f85 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] add --write-sksl-on-exit to flutter drive (#58743)

Allow dumping sksl files on driver exit when a file path is provided to drive's --write-sksl-on-exit
parent 70f2d757
......@@ -5,6 +5,8 @@
import 'dart:async';
import 'dart:math' as math;
import 'package:vm_service/vm_service_io.dart' as vm_service;
import 'package:vm_service/vm_service.dart' as vm_service;
import 'package:meta/meta.dart';
import 'package:webdriver/async_io.dart' as async_io;
......@@ -21,6 +23,7 @@ import '../globals.dart' as globals;
import '../project.dart';
import '../resident_runner.dart';
import '../runner/flutter_command.dart' show FlutterCommandResult;
import '../vmservice.dart';
import '../web/web_runner.dart';
import 'run.dart';
......@@ -111,7 +114,12 @@ class DriveCommand extends RunCommandBase {
'Works only if \'browser-name\' is set to \'android-chrome\'')
..addOption('chrome-binary',
help: 'Location of Chrome binary. '
'Works only if \'browser-name\' is set to \'chrome\'');
'Works only if \'browser-name\' is set to \'chrome\'')
..addOption('write-sksl-on-exit',
help:
'Attempts to write an SkSL file when the drive process is finished '
'to the provided file, overwriting it if necessary.',
);
}
@override
......@@ -303,6 +311,17 @@ $ex
} finally {
await residentRunner?.exit();
await driver?.quit();
if (stringArg('write-sksl-on-exit') != null) {
final File outputFile = globals.fs.file(stringArg('write-sksl-on-exit'));
final vm_service.VmService vmService = await connectToVmService(
Uri.parse(observatoryUri),
);
final FlutterView flutterView = (await vmService.getFlutterViews()).first;
final Map<String, Object> result = await vmService.getSkSLs(
viewId: flutterView.id
);
await sharedSkSlWriter(_device, result, outputFile: outputFile);
}
if (boolArg('keep-app-running') ?? (argResults['use-existing-app'] != null)) {
globals.printStatus('Leaving the application running.');
} else {
......
......@@ -27,7 +27,6 @@ import 'bundle.dart';
import 'cache.dart';
import 'codegen.dart';
import 'compile.dart';
import 'convert.dart';
import 'dart/package_map.dart';
import 'devfs.dart';
import 'device.dart';
......@@ -850,43 +849,8 @@ abstract class ResidentRunner {
final Map<String, Object> data = await flutterDevices.first.vmService.getSkSLs(
viewId: views.first.id,
);
if (data.isEmpty) {
globals.logger.printStatus(
'No data was receieved. To ensure SkSL data can be generated use a '
'physical device then:\n'
' 1. Pass "--cache-sksl" as an argument to flutter run.\n'
' 2. Interact with the application to force shaders to be compiled.\n'
);
return null;
}
final File outputFile = globals.fsUtils.getUniqueFile(
globals.fs.currentDirectory,
'flutter',
'sksl.json',
);
final Device device = flutterDevices.first.device;
// Convert android sub-platforms to single target platform.
TargetPlatform targetPlatform = await flutterDevices.first.device.targetPlatform;
switch (targetPlatform) {
case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
targetPlatform = TargetPlatform.android;
break;
default:
break;
}
final Map<String, Object> manifest = <String, Object>{
'platform': getNameForTargetPlatform(targetPlatform),
'name': device.name,
'engineRevision': globals.flutterVersion.engineRevision,
'data': data,
};
outputFile.writeAsStringSync(json.encode(manifest));
globals.logger.printStatus('Wrote SkSL data to ${outputFile.path}.');
return outputFile.path;
return sharedSkSlWriter(device, data);
}
/// The resident runner API for interaction with the reloadMethod vmservice
......
......@@ -4,11 +4,14 @@
import 'dart:async';
import 'package:file/file.dart';
import 'package:meta/meta.dart' show required, visibleForTesting;
import 'package:vm_service/vm_service.dart' as vm_service;
import 'base/context.dart';
import 'base/io.dart' as io;
import 'build_info.dart';
import 'convert.dart';
import 'device.dart';
import 'globals.dart' as globals;
import 'version.dart';
......@@ -800,3 +803,49 @@ bool isPauseEvent(String kind) {
kind == vm_service.EventKind.kPausePostRequest ||
kind == vm_service.EventKind.kNone;
}
// TODO(jonahwilliams): either refactor drive to use the resident runner
// or delete it.
Future<String> sharedSkSlWriter(Device device, Map<String, Object> data, {
File outputFile,
}) async {
if (data.isEmpty) {
globals.logger.printStatus(
'No data was receieved. To ensure SkSL data can be generated use a '
'physical device then:\n'
' 1. Pass "--cache-sksl" as an argument to flutter run.\n'
' 2. Interact with the application to force shaders to be compiled.\n'
);
return null;
}
if (outputFile == null) {
outputFile = globals.fsUtils.getUniqueFile(
globals.fs.currentDirectory,
'flutter',
'sksl.json',
);
} else if (!outputFile.parent.existsSync()) {
outputFile.parent.createSync(recursive: true);
}
// Convert android sub-platforms to single target platform.
TargetPlatform targetPlatform = await device.targetPlatform;
switch (targetPlatform) {
case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
targetPlatform = TargetPlatform.android;
break;
default:
break;
}
final Map<String, Object> manifest = <String, Object>{
'platform': getNameForTargetPlatform(targetPlatform),
'name': device.name,
'engineRevision': globals.flutterVersion.engineRevision,
'data': data,
};
outputFile.writeAsStringSync(json.encode(manifest));
globals.logger.printStatus('Wrote SkSL data to ${outputFile.path}.');
return outputFile.path;
}
......@@ -5,6 +5,7 @@
import 'dart:async';
import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/android/android_device.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
......@@ -17,6 +18,7 @@ import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:mockito/mockito.dart';
import 'package:webdriver/sync_io.dart' as sync_io;
import 'package:flutter_tools/src/vmservice.dart';
import '../../src/common.dart';
import '../../src/context.dart';
......@@ -729,6 +731,28 @@ void main() {
expect(getDesiredCapabilities(Browser.androidChrome, false), expected);
});
});
testUsingContext('Can write SkSL file with provided output file', () async {
final MockDevice device = MockDevice();
when(device.name).thenReturn('foo');
when(device.targetPlatform).thenAnswer((Invocation invocation) async {
return TargetPlatform.android_arm;
});
final File outputFile = globals.fs.file('out/foo');
final String result = await sharedSkSlWriter(
device,
<String, Object>{'foo': 'bar'},
outputFile: outputFile,
);
expect(result, 'out/foo');
expect(outputFile, exists);
expect(outputFile.readAsStringSync(), '{"platform":"android","name":"foo","engineRevision":null,"data":{"foo":"bar"}}');
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
});
}
class MockDevice extends Mock implements Device {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment