Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -245,44 +245,56 @@ final class ServiceExtensionManager with DisposerMixin {
}

Future<void> _addServiceExtension(String name) async {
if (!_serviceExtensions.add(name)) {
if (_serviceExtensions.contains(name)) {
// If the service extension was already added we do not need to add it
// again. This can happen depending on the timing between when extension
// added events were received and when we requested the list of all
// service extensions already defined for the isolate.
return;
}
_hasServiceExtension(name).value = true;

if (_enabledServiceExtensions.containsKey(name)) {
final enabledServiceExtension = _enabledServiceExtensions[name];
if (enabledServiceExtension != null) {
// Restore any previously enabled states by calling their service
// extension. This will restore extension states on the device after a hot
// restart. [_enabledServiceExtensions] will be empty on page refresh or
// initial start.
try {
return await _callServiceExtension(
final called = await _callServiceExtension(
name,
_enabledServiceExtensions[name]!.value,
enabledServiceExtension.value,
);
if (called) {
Comment thread
srawlins marked this conversation as resolved.
_serviceExtensions.add(name);
_hasServiceExtension(name).value = true;
Comment thread
srawlins marked this conversation as resolved.
Outdated
}
return;
} on SentinelException catch (_) {
// Service extension stopped existing while calling, so do nothing.
// This typically happens during hot restarts.
}
} else {
// Set any extensions that are already enabled on the device. This will
// enable extension states in DevTools on page refresh or initial start.
return await _restoreExtensionFromDevice(name);
final restored = await _restoreExtensionFromDevice(name);
if (restored) {
_serviceExtensions.add(name);
Comment thread
srawlins marked this conversation as resolved.
_hasServiceExtension(name).value = true;
}
}
}

IsolateRef? get _mainIsolate => _isolateManager.mainIsolate.value;

Future<void> _restoreExtensionFromDevice(String name) async {
/// Restores the service extension named [name] from the device.
///
/// Returns whether the service extension was actually restored.
Future<bool> _restoreExtensionFromDevice(String name) async {
Comment thread
srawlins marked this conversation as resolved.
Outdated
final isolateRef = _isolateManager.mainIsolate.value;
if (isolateRef == null) return;
if (isolateRef == null) return false;

if (!extensions.serviceExtensionsAllowlist.containsKey(name)) {
return;
return false;
}
final expectedValueType =
extensions.serviceExtensionsAllowlist[name]!.values.first.runtimeType;
Expand Down Expand Up @@ -327,10 +339,10 @@ final class ServiceExtensionManager with DisposerMixin {
}
}

if (isolateRef != _mainIsolate) return;
if (isolateRef != _mainIsolate) return false;

final isolate = await _isolateManager.isolateState(isolateRef).isolate;
if (isolateRef != _mainIsolate) return;
if (isolateRef != _mainIsolate) return false;

// Do not try to restore Dart IO extensions for a paused isolate.
if (extensions.isDartIoExtension(name) &&
Expand All @@ -339,6 +351,8 @@ final class ServiceExtensionManager with DisposerMixin {
} else {
await restore();
Comment thread
srawlins marked this conversation as resolved.
Outdated
Comment thread
srawlins marked this conversation as resolved.
Outdated
}

return true;
}

Future<void> _maybeRestoreExtension(String name, Object? value) async {
Expand All @@ -362,14 +376,15 @@ final class ServiceExtensionManager with DisposerMixin {
}
}

Future<void> _callServiceExtension(String name, Object? value) async {
if (_service == null) {
return;
}
/// Calls the service extension named [name] with [value].
///
/// Returns whether the service extension was successfully called.
Future<bool> _callServiceExtension(String name, Object? value) async {
if (_service == null) return false;

final mainIsolate = _isolateManager.mainIsolate.value;
Future<void> callExtension() async {
if (_isolateManager.mainIsolate.value != mainIsolate) return;
final mainIsolate = _mainIsolate;
Future<bool> callExtension() async {
if (_mainIsolate != mainIsolate) return false;

assert(value != null);
try {
Expand Down Expand Up @@ -411,16 +426,19 @@ final class ServiceExtensionManager with DisposerMixin {
}
Comment thread
srawlins marked this conversation as resolved.
} on RPCError catch (e) {
if (e.code == RPCErrorKind.kServerError.code) {
// Connection disappeared
return;
// The connection disappeared.
return false;
}
rethrow;
}

return true;
}

if (mainIsolate == null) return;
if (mainIsolate == null) return false;

final isolate = await _isolateManager.isolateState(mainIsolate).isolate;
if (_isolateManager.mainIsolate.value != mainIsolate) return;
if (_mainIsolate != mainIsolate) return false;

// Do not try to call Dart IO extensions for a paused isolate.
if (extensions.isDartIoExtension(name) &&
Expand All @@ -431,6 +449,7 @@ final class ServiceExtensionManager with DisposerMixin {
} else {
await callExtension();
Comment thread
srawlins marked this conversation as resolved.
Outdated
}
return true;
Comment thread
srawlins marked this conversation as resolved.
Outdated
}

void vmServiceClosed() {
Expand Down
Loading