Unverified Commit 4ae68a3a authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] Move sksl writing out of vm_service (#79455)

parent 0d0ea524
......@@ -132,7 +132,7 @@ class ScreenshotCommand extends FlutterCommand {
Future<bool> runSkia(File outputFile) async {
final Uri observatoryUri = Uri.parse(stringArg(_kObservatoryUri));
final FlutterVmService vmService = await connectToVmService(observatoryUri);
final FlutterVmService vmService = await connectToVmService(observatoryUri, logger: globals.logger);
final vm_service.Response skp = await vmService.screenshotSkp();
if (skp == null) {
globals.printError(
......@@ -156,7 +156,7 @@ class ScreenshotCommand extends FlutterCommand {
Future<bool> runRasterizer(File outputFile) async {
final Uri observatoryUri = Uri.parse(stringArg(_kObservatoryUri));
final FlutterVmService vmService = await connectToVmService(observatoryUri);
final FlutterVmService vmService = await connectToVmService(observatoryUri, logger: globals.logger);
final vm_service.Response response = await vmService.screenshot();
if (response == null) {
globals.printError(
......
......@@ -16,6 +16,7 @@ import '../base/logger.dart';
import '../base/process.dart';
import '../build_info.dart';
import '../device.dart';
import '../sksl_writer.dart';
import '../vmservice.dart';
import 'web_driver_service.dart';
......
......@@ -51,7 +51,7 @@ final String _ipv6Loopback = InternetAddress.loopbackIPv6.address;
// Enables testing the fuchsia isolate discovery
Future<FlutterVmService> _kDefaultFuchsiaIsolateDiscoveryConnector(Uri uri) {
return connectToVmService(uri);
return connectToVmService(uri, logger: globals.logger);
}
Future<void> _kDefaultDartDevelopmentServiceStarter(
......@@ -699,7 +699,7 @@ class FuchsiaDevice extends Device {
// netstat shows that the local port is actually being used on the IPv6
// loopback (::1).
final Uri uri = Uri.parse('http://[$_ipv6Loopback]:$port');
final FlutterVmService vmService = await connectToVmService(uri);
final FlutterVmService vmService = await connectToVmService(uri, logger: globals.logger);
final List<FlutterView> flutterViews = await vmService.getFlutterViews();
for (final FlutterView flutterView in flutterViews) {
if (flutterView.uiIsolate == null) {
......
......@@ -38,6 +38,7 @@ import 'project.dart';
import 'resident_devtools_handler.dart';
import 'run_cold.dart';
import 'run_hot.dart';
import 'sksl_writer.dart';
import 'vmservice.dart';
class FlutterDevice {
......@@ -252,7 +253,7 @@ class FlutterDevice {
// this may not be the case when scraping logcat for URIs. If this URI is
// from an old application instance, we shouldn't try and start DDS.
try {
service = await connectToVmService(observatoryUri);
service = await connectToVmService(observatoryUri, logger: globals.logger);
await service.dispose();
} on Exception catch (exception) {
globals.printTrace('Fail to connect to service protocol: $observatoryUri: $exception');
......@@ -303,6 +304,7 @@ class FlutterDevice {
getSkSLMethod: getSkSLMethod,
printStructuredErrorLogMethod: printStructuredErrorLogMethod,
device: device,
logger: globals.logger,
),
if (!existingDds)
device.dds.done.whenComplete(() => throw Exception('DDS shut down too early')),
......
// 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.
// @dart = 2.8
import 'dart:async';
import 'package:file/file.dart';
import 'base/file_system.dart';
import 'base/logger.dart';
import 'build_info.dart';
import 'convert.dart';
import 'device.dart';
import 'globals.dart' as globals;
Future<String> sharedSkSlWriter(Device device, Map<String, Object> data, {
File outputFile,
Logger logger,
}) async {
logger ??= globals.logger;
if (data.isEmpty) {
logger.printStatus(
'No data was received. 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));
logger.printStatus('Wrote SkSL data to ${outputFile.path}.');
return outputFile.path;
}
......@@ -204,7 +204,7 @@ class CoverageCollector extends TestWatcher {
Future<FlutterVmService> _defaultConnect(Uri serviceUri) {
return connectToVmService(
serviceUri, compression: CompressionOptions.compressionOff);
serviceUri, compression: CompressionOptions.compressionOff, logger: globals.logger,);
}
Future<Map<String, dynamic>> collect(Uri serviceUri, bool Function(String) libraryPredicate, {
......
......@@ -171,6 +171,7 @@ class FlutterTesterTestDevice extends TestDevice {
final Future<FlutterVmService> localVmService = connectToVmService(
forwardingUri,
compileExpression: compileExpression,
logger: logger,
);
unawaited(localVmService.then((FlutterVmService vmservice) {
logger.printTrace('test $id: Successfully connected to service protocol: $forwardingUri');
......
......@@ -70,7 +70,7 @@ class IntegrationTestTestDevice implements TestDevice {
_gotProcessObservatoryUri.complete(launchResult.observatoryUri);
globals.printTrace('test $id: Connecting to vm service');
final FlutterVmService vmService = await connectToVmService(launchResult.observatoryUri).timeout(
final FlutterVmService vmService = await connectToVmService(launchResult.observatoryUri, logger: globals.logger).timeout(
const Duration(seconds: 5),
onTimeout: () => throw TimeoutException('Connecting to the VM Service timed out.'),
);
......
......@@ -6,7 +6,6 @@
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;
......@@ -15,10 +14,8 @@ import 'base/context.dart';
import 'base/io.dart' as io;
import 'base/logger.dart';
import 'base/utils.dart';
import 'build_info.dart';
import 'convert.dart';
import 'device.dart';
import 'globals.dart' as globals;
import 'version.dart';
const String kGetSkSLsMethod = '_flutter.getSkSLs';
......@@ -34,7 +31,7 @@ const int kIsolateReloadBarred = 1005;
/// Override `WebSocketConnector` in [context] to use a different constructor
/// for [WebSocket]s (used by tests).
typedef WebSocketConnector = Future<io.WebSocket> Function(String url, {io.CompressionOptions compression});
typedef WebSocketConnector = Future<io.WebSocket> Function(String url, {io.CompressionOptions compression, @required Logger logger});
typedef PrintStructuredErrorLogMethod = void Function(vm_service.Event);
......@@ -106,28 +103,29 @@ typedef CompileExpression = Future<String> Function(
typedef GetSkSLMethod = Future<String> Function();
Future<io.WebSocket> _defaultOpenChannel(String url, {
io.CompressionOptions compression = io.CompressionOptions.compressionDefault
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
@required Logger logger,
}) async {
Duration delay = const Duration(milliseconds: 100);
int attempts = 0;
io.WebSocket socket;
Future<void> handleError(dynamic e) async {
void Function(String) printVisibleTrace = globals.printTrace;
void Function(String) printVisibleTrace = logger.printTrace;
if (attempts == 10) {
globals.printStatus('Connecting to the VM Service is taking longer than expected...');
logger.printStatus('Connecting to the VM Service is taking longer than expected...');
} else if (attempts == 20) {
globals.printStatus('Still attempting to connect to the VM Service...');
globals.printStatus(
logger.printStatus('Still attempting to connect to the VM Service...');
logger.printStatus(
'If you do NOT see the Flutter application running, it might have '
'crashed. The device logs (e.g. from adb or XCode) might have more '
'details.');
globals.printStatus(
logger.printStatus(
'If you do see the Flutter application running on the device, try '
're-running with --host-vmservice-port to use a specific port known to '
'be available.');
} else if (attempts % 50 == 0) {
printVisibleTrace = globals.printStatus;
printVisibleTrace = logger.printStatus;
}
printVisibleTrace('Exception attempting to connect to the VM Service: $e');
......@@ -142,7 +140,11 @@ Future<io.WebSocket> _defaultOpenChannel(String url, {
}
}
final WebSocketConnector constructor = context.get<WebSocketConnector>() ?? io.WebSocket.connect;
final WebSocketConnector constructor = context.get<WebSocketConnector>() ?? (String url, {
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
@required Logger logger,
}) => io.WebSocket.connect(url, compression: compression);
while (socket == null) {
attempts += 1;
try {
......@@ -166,6 +168,7 @@ typedef VMServiceConnector = Future<FlutterVmService> Function(Uri httpUri, {
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
io.CompressionOptions compression,
Device device,
Logger logger,
});
/// Set up the VM Service client by attaching services for each of the provided
......@@ -308,6 +311,7 @@ Future<FlutterVmService> connectToVmService(
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device device,
@required Logger logger,
}) async {
final VMServiceConnector connector = context.get<VMServiceConnector>() ?? _connect;
return connector(httpUri,
......@@ -318,6 +322,7 @@ Future<FlutterVmService> connectToVmService(
device: device,
getSkSLMethod: getSkSLMethod,
printStructuredErrorLogMethod: printStructuredErrorLogMethod,
logger: logger,
);
}
......@@ -330,9 +335,10 @@ Future<FlutterVmService> _connect(
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device device,
@required Logger logger,
}) async {
final Uri wsUri = httpUri.replace(scheme: 'ws', path: urlContext.join(httpUri.path, 'ws'));
final io.WebSocket channel = await _openChannel(wsUri.toString(), compression: compression);
final io.WebSocket channel = await _openChannel(wsUri.toString(), compression: compression, logger: logger);
final vm_service.VmService delegateService = vm_service.VmService(
channel,
channel.add,
......@@ -692,7 +698,6 @@ class FlutterVmService {
'ext.flutter.exit',
isolateId: isolateId,
).catchError((dynamic error, StackTrace stackTrace) {
globals.logger.printTrace('Failure in ext.flutter.exit: $error\n$stackTrace');
// Do nothing on sentinel or exception, the isolate already exited.
}, test: (dynamic error) => error is vm_service.SentinelException || error is vm_service.RPCError);
}
......@@ -934,54 +939,6 @@ bool isPauseEvent(String kind) {
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,
Logger logger,
}) async {
logger ??= globals.logger;
if (data.isEmpty) {
logger.printStatus(
'No data was received. 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));
logger.printStatus('Wrote SkSL data to ${outputFile.path}.');
return outputFile.path;
}
/// A brightness enum that matches the values https://github.com/flutter/engine/blob/3a96741247528133c0201ab88500c0c3c036e64e/lib/ui/window.dart#L1328
/// Describes the contrast of a theme or color palette.
enum Brightness {
......
......@@ -840,6 +840,7 @@ VMServiceConnector getFakeVmServiceFactory({
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
CompressionOptions compression,
Device device,
Logger logger,
}) async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
......
......@@ -389,6 +389,7 @@ FlutterDriverService setUpDriverService({
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
Object compression,
Device device,
Logger logger,
}) async {
if (httpUri.scheme != 'http') {
fail('Expected an HTTP scheme, found $httpUri');
......
......@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:flutter_tools/src/base/io.dart' as io;
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/test/integration_test_device.dart';
......@@ -133,6 +134,7 @@ void main() {
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
io.CompressionOptions compression,
Device device,
Logger logger,
}) async => fakeVmServiceHost.vmService,
});
......@@ -150,6 +152,7 @@ void main() {
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
io.CompressionOptions compression,
Device device,
Logger logger,
}) async => fakeVmServiceHost.vmService,
});
......
......@@ -8,6 +8,7 @@ import 'dart:async';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/dds.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/device_port_forwarder.dart';
import 'package:flutter_tools/src/features.dart';
......@@ -2691,6 +2692,7 @@ void main() {
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
io.CompressionOptions compression,
Device device,
Logger logger,
}) async => mockVMService,
}));
......@@ -2721,6 +2723,7 @@ void main() {
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
io.CompressionOptions compression,
Device device,
Logger logger,
}) async => mockVMService,
}));
......@@ -2762,6 +2765,7 @@ void main() {
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
io.CompressionOptions compression,
Device device,
Logger logger,
}) async => mockVMService,
}));
......@@ -2803,6 +2807,7 @@ void main() {
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
io.CompressionOptions compression,
Device device,
Logger logger,
}) async => mockVMService,
}));
......
......@@ -8,6 +8,7 @@ import 'dart:async';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/io.dart' as io;
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:test/fake.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
......@@ -17,7 +18,7 @@ import 'package:flutter_tools/src/vmservice.dart';
import 'package:fake_async/fake_async.dart';
import '../src/common.dart';
import '../src/context.dart';
import '../src/context.dart' hide testLogger;
final Map<String, Object> vm = <String, dynamic>{
'type': 'VM',
......@@ -198,16 +199,17 @@ void main() {
});
testUsingContext('VMService prints messages for connection failures', () {
final BufferLogger logger = BufferLogger.test();
FakeAsync().run((FakeAsync time) {
final Uri uri = Uri.parse('ws://127.0.0.1:12345/QqL7EFEDNG0=/ws');
unawaited(connectToVmService(uri));
unawaited(connectToVmService(uri, logger: logger));
time.elapse(const Duration(seconds: 5));
expect(testLogger.statusText, isEmpty);
expect(logger.statusText, isEmpty);
time.elapse(const Duration(minutes: 2));
final String statusText = testLogger.statusText;
final String statusText = logger.statusText;
expect(
statusText,
containsIgnoringWhitespace('Connecting to the VM Service is taking longer than expected...'),
......@@ -646,13 +648,13 @@ void main() {
testUsingContext('WebSocket URL construction uses correct URI join primitives', () async {
final Completer<String> completer = Completer<String>();
openChannelForTesting = (String url, {io.CompressionOptions compression}) async {
openChannelForTesting = (String url, {io.CompressionOptions compression, Logger logger}) async {
completer.complete(url);
throw Exception('');
};
// Construct a URL that does not end in a `/`.
await expectLater(() => connectToVmService(Uri.parse('http://localhost:8181/foo')), throwsException);
await expectLater(() => connectToVmService(Uri.parse('http://localhost:8181/foo'), logger: BufferLogger.test()), throwsException);
expect(await completer.future, 'ws://localhost:8181/foo/ws');
openChannelForTesting = null;
});
......@@ -696,6 +698,7 @@ class FakeFlutterVersion extends Fake implements FlutterVersion {
Future<io.WebSocket> failingWebSocketConnector(
String url, {
io.CompressionOptions compression,
Logger logger,
}) {
throw const io.SocketException('Failed WebSocket connection');
}
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