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