Unverified Commit 33bfa6a7 authored by Kenzie Schmoll's avatar Kenzie Schmoll Committed by GitHub

Register hotRestart service in flutter_tools. (#26669)

* Register hot restart service in flutter_tools.
parent 244b077b
......@@ -68,7 +68,11 @@ class FlutterDevice {
/// expressions requested during debugging of the application.
/// This ensures that the reload process follows the normal orchestration of
/// the Flutter Tools and not just the VM internal service.
Future<void> _connect({ReloadSources reloadSources, CompileExpression compileExpression}) async {
Future<void> _connect({
ReloadSources reloadSources,
Restart restart,
CompileExpression compileExpression,
}) async {
if (vmServices != null)
return;
final List<VMService> localVmServices = List<VMService>(observatoryUris.length);
......@@ -76,6 +80,7 @@ class FlutterDevice {
printTrace('Connecting to service protocol: ${observatoryUris[i]}');
localVmServices[i] = await VMService.connect(observatoryUris[i],
reloadSources: reloadSources,
restart: restart,
compileExpression: compileExpression);
printTrace('Successfully connected to service protocol: ${observatoryUris[i]}');
}
......@@ -677,14 +682,21 @@ abstract class ResidentRunner {
/// If the [reloadSources] parameter is not null the 'reloadSources' service
/// will be registered
Future<void> connectToServiceProtocol({ReloadSources reloadSources, CompileExpression compileExpression}) async {
Future<void> connectToServiceProtocol({
ReloadSources reloadSources,
Restart restart,
CompileExpression compileExpression,
}) async {
if (!debuggingOptions.debuggingEnabled)
return Future<void>.error('Error the service protocol is not enabled.');
bool viewFound = false;
for (FlutterDevice device in flutterDevices) {
await device._connect(reloadSources: reloadSources,
compileExpression: compileExpression);
await device._connect(
reloadSources: reloadSources,
restart: restart,
compileExpression: compileExpression,
);
await device.getVMs();
await device.refreshViews();
if (device.views.isEmpty)
......
......@@ -143,6 +143,17 @@ class HotRunner extends ResidentRunner {
}
}
Future<void> _restartService({ bool pause = false }) async {
final OperationResult result =
await restart(fullRestart: true, pauseAfterRestart: pause);
if (!result.isOk) {
throw rpc.RpcException(
rpc_error_code.INTERNAL_ERROR,
'Unable to restart',
);
}
}
Future<String> _compileExpressionService(String isolateId, String expression,
List<String> definitions, List<String> typeDefinitions,
String libraryUri, String klass, bool isStatic,
......@@ -168,6 +179,7 @@ class HotRunner extends ResidentRunner {
try {
await connectToServiceProtocol(
reloadSources: _reloadSourcesService,
restart: _restartService,
compileExpression: _compileExpressionService,
);
} catch (error) {
......
......@@ -43,6 +43,8 @@ typedef ReloadSources = Future<void> Function(
bool pause,
});
typedef Restart = Future<void> Function({ bool pause });
typedef CompileExpression = Future<String> Function(
String isolateId,
String expression,
......@@ -111,6 +113,7 @@ class VMService {
this.wsAddress,
this._requestTimeout,
ReloadSources reloadSources,
Restart restart,
CompileExpression compileExpression,
) {
_vm = VM._empty(this);
......@@ -148,7 +151,33 @@ class VMService {
// have no effect
_peer.sendNotification('_registerService', <String, String>{
'service': 'reloadSources',
'alias': 'Flutter Tools'
'alias': 'Flutter Tools',
});
}
if (restart != null) {
_peer.registerMethod('hotRestart', (rpc.Parameters params) async {
final bool pause = params.asMap['pause'] ?? false;
if (pause is! bool)
throw rpc.RpcException.invalidParams('Invalid \'pause\': $pause');
try {
await restart(pause: pause);
return <String, String>{'type': 'Success'};
} on rpc.RpcException {
rethrow;
} catch (e, st) {
throw rpc.RpcException(rpc_error_code.SERVER_ERROR,
'Error during Hot Restart: $e\n$st');
}
});
// If the Flutter Engine doesn't support service registration this will
// have no effect
_peer.sendNotification('_registerService', <String, String>{
'service': 'hotRestart',
'alias': 'Flutter Tools',
});
}
......@@ -231,12 +260,13 @@ class VMService {
Uri httpUri, {
Duration requestTimeout = kDefaultRequestTimeout,
ReloadSources reloadSources,
Restart restart,
CompileExpression compileExpression,
}) async {
final Uri wsUri = httpUri.replace(scheme: 'ws', path: fs.path.join(httpUri.path, 'ws'));
final StreamChannel<String> channel = await _openChannel(wsUri);
final rpc.Peer peer = rpc.Peer.withoutJson(jsonDocument.bind(channel));
final VMService service = VMService(peer, httpUri, wsUri, requestTimeout, reloadSources, compileExpression);
final VMService service = VMService(peer, httpUri, wsUri, requestTimeout, reloadSources, restart, compileExpression);
// This call is to ensure we are able to establish a connection instead of
// keeping on trucking and failing farther down the process.
await service._sendRequest('getVersion', const <String, dynamic>{});
......
......@@ -167,7 +167,7 @@ void main() {
bool done = false;
final MockPeer mockPeer = MockPeer();
expect(mockPeer.returnedFromSendRequest, 0);
final VMService vmService = VMService(mockPeer, null, null, const Duration(seconds: 1), null, null);
final VMService vmService = VMService(mockPeer, null, null, const Duration(seconds: 1), null, null, null);
vmService.getVM().then((void value) { done = true; });
expect(done, isFalse);
expect(mockPeer.returnedFromSendRequest, 0);
......
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