Add ability to record & replay VMService connection (#8355)
diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart
index b3114d8..cc6ded4 100644
--- a/packages/flutter_tools/lib/src/vmservice.dart
+++ b/packages/flutter_tools/lib/src/vmservice.dart
@@ -5,9 +5,9 @@
import 'dart:async';
import 'dart:convert' show BASE64;
+import 'package:file/file.dart';
import 'package:json_rpc_2/error_code.dart' as rpc_error_code;
import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
-import 'package:meta/meta.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
@@ -15,14 +15,17 @@
import 'base/common.dart';
import 'base/file_system.dart';
import 'globals.dart';
+import 'vmservice_record_replay.dart';
/// A function that opens a two-way communication channel to the specified [uri].
-typedef StreamChannel<dynamic> OpenChannel(Uri uri);
+typedef StreamChannel<String> _OpenChannel(Uri uri);
-OpenChannel _openChannel = _defaultOpenChannel;
+_OpenChannel _openChannel = _defaultOpenChannel;
-StreamChannel<dynamic> _defaultOpenChannel(Uri uri) =>
- new IOWebSocketChannel.connect(uri.toString());
+const String _kRecordingType = 'vmservice';
+
+StreamChannel<String> _defaultOpenChannel(Uri uri) =>
+ new IOWebSocketChannel.connect(uri.toString()).cast();
/// The default VM service request timeout.
const Duration kDefaultRequestTimeout = const Duration(seconds: 10);
@@ -43,9 +46,29 @@
});
}
- @visibleForTesting
- static void setOpenChannelForTesting(OpenChannel openChannel) {
- _openChannel = openChannel;
+ /// Enables recording of VMService JSON-rpc activity to the specified base
+ /// recording [location].
+ ///
+ /// Activity will be recorded in a subdirectory of [location] named
+ /// `"vmservice"`. It is permissible for [location] to represent an existing
+ /// non-empty directory as long as there is no collision with the
+ /// `"vmservice"` subdirectory.
+ static void enableRecordingConnection(String location) {
+ Directory dir = getRecordingSink(location, _kRecordingType);
+ _openChannel = (Uri uri) {
+ StreamChannel<String> delegate = _defaultOpenChannel(uri);
+ return new RecordingVMServiceChannel(delegate, dir);
+ };
+ }
+
+ /// Enables VMService JSON-rpc replay mode.
+ ///
+ /// [location] must represent a directory to which VMService JSON-rpc
+ /// activity has been recorded (i.e. the result of having been previously
+ /// passed to [enableRecordingConnection]), or a [ToolExit] will be thrown.
+ static void enableReplayConnection(String location) {
+ Directory dir = getReplaySource(location, _kRecordingType);
+ _openChannel = (Uri uri) => new ReplayVMServiceChannel(dir);
}
/// Connect to a Dart VM Service at [httpUri].
@@ -57,8 +80,8 @@
Duration requestTimeout: kDefaultRequestTimeout,
}) {
Uri wsUri = httpUri.replace(scheme: 'ws', path: fs.path.join(httpUri.path, 'ws'));
- StreamChannel<dynamic> channel = _openChannel(wsUri);
- rpc.Peer peer = new rpc.Peer.withoutJson(jsonDocument.bind(channel.cast()));
+ StreamChannel<String> channel = _openChannel(wsUri);
+ rpc.Peer peer = new rpc.Peer.withoutJson(jsonDocument.bind(channel));
return new VMService._(peer, httpUri, wsUri, requestTimeout);
}