diff --git a/packages/devtools_app/lib/devtools_app.dart b/packages/devtools_app/lib/devtools_app.dart index 0243492953f..73826495f00 100644 --- a/packages/devtools_app/lib/devtools_app.dart +++ b/packages/devtools_app/lib/devtools_app.dart @@ -54,7 +54,6 @@ export 'src/screens/vm_developer/vm_developer_tools_controller.dart'; export 'src/screens/vm_developer/vm_developer_tools_screen.dart'; export 'src/screens/vm_developer/vm_service_private_extensions.dart'; export 'src/service/json_to_service_cache.dart'; -export 'src/service/resolved_uri_manager.dart'; export 'src/service/service_extensions.dart'; export 'src/service/service_manager.dart'; export 'src/service/service_registrations.dart'; diff --git a/packages/devtools_app/lib/src/screens/debugger/codeview.dart b/packages/devtools_app/lib/src/screens/debugger/codeview.dart index ef5150d55cf..36aa8980844 100644 --- a/packages/devtools_app/lib/src/screens/debugger/codeview.dart +++ b/packages/devtools_app/lib/src/screens/debugger/codeview.dart @@ -1498,16 +1498,18 @@ Future fetchScriptLocationFullFilePath( if (packagePath != null) { final isolateId = serviceConnection .serviceManager.isolateManager.selectedIsolate.value!.id!; - filePath = serviceConnection.resolvedUriManager.lookupFileUri( + filePath = + serviceConnection.serviceManager.resolvedUriManager.lookupFileUri( isolateId, packagePath, ); if (filePath == null) { - await serviceConnection.resolvedUriManager.fetchFileUris( + await serviceConnection.serviceManager.resolvedUriManager.fetchFileUris( isolateId, [packagePath], ); - filePath = serviceConnection.resolvedUriManager.lookupFileUri( + filePath = + serviceConnection.serviceManager.resolvedUriManager.lookupFileUri( isolateId, packagePath, ); diff --git a/packages/devtools_app/lib/src/screens/profiler/cpu_profile_model.dart b/packages/devtools_app/lib/src/screens/profiler/cpu_profile_model.dart index bf94f26c7cd..7a0da58f705 100644 --- a/packages/devtools_app/lib/src/screens/profiler/cpu_profile_model.dart +++ b/packages/devtools_app/lib/src/screens/profiler/cpu_profile_model.dart @@ -613,7 +613,7 @@ class CpuProfileData { final resolvedUrl = stackFrameJson[CpuProfileData.resolvedUrlKey] as String?; if (resolvedUrl != null && resolvedUrl.isNotEmpty) { - final packageUri = serviceConnection.resolvedUriManager + final packageUri = serviceConnection.serviceManager.resolvedUriManager .lookupPackageUri(isolateId, resolvedUrl); if (packageUri != null) { stackFrameJson[CpuProfileData.resolvedPackageUriKey] = packageUri; @@ -624,14 +624,14 @@ class CpuProfileData { } } - await serviceConnection.resolvedUriManager.fetchPackageUris( + await serviceConnection.serviceManager.resolvedUriManager.fetchPackageUris( isolateId, urisWithoutPackageUri.toList(), ); for (var stackFrameJson in stackFramesWaitingOnPackageUri) { final resolvedUri = stackFrameJson[CpuProfileData.resolvedUrlKey]; - final packageUri = serviceConnection.resolvedUriManager + final packageUri = serviceConnection.serviceManager.resolvedUriManager .lookupPackageUri(isolateId, resolvedUri); if (packageUri != null) { stackFrameJson[CpuProfileData.resolvedPackageUriKey] = packageUri; diff --git a/packages/devtools_app/lib/src/service/service_manager.dart b/packages/devtools_app/lib/src/service/service_manager.dart index e4da8214a76..4f01aabe20e 100644 --- a/packages/devtools_app/lib/src/service/service_manager.dart +++ b/packages/devtools_app/lib/src/service/service_manager.dart @@ -19,7 +19,6 @@ import '../shared/feature_flags.dart'; import '../shared/globals.dart'; import '../shared/title.dart'; import '../shared/utils.dart'; -import 'resolved_uri_manager.dart'; import 'service_registrations.dart' as registrations; import 'timeline_streams.dart'; import 'vm_flags.dart'; @@ -75,8 +74,6 @@ class ServiceConnectionManager { final consoleService = ConsoleService(); - final resolvedUriManager = ResolvedUriManager(); - InspectorServiceBase? get inspectorService => _inspectorService; InspectorServiceBase? _inspectorService; @@ -92,7 +89,6 @@ class ServiceConnectionManager { Future _beforeOpenVmService(VmServiceWrapper? service) async { consoleService.vmServiceOpened(service!); - resolvedUriManager.vmServiceOpened(); await vmFlagManager.vmServiceOpened(service); timelineStreamManager.vmServiceOpened( service, @@ -149,7 +145,6 @@ class ServiceConnectionManager { generateDevToolsTitle(); vmFlagManager.vmServiceClosed(); timelineStreamManager.vmServiceClosed(); - resolvedUriManager.vmServiceClosed(); consoleService.handleVmServiceClosed(); _inspectorService?.onIsolateStopped(); _inspectorService?.dispose(); @@ -185,8 +180,9 @@ class ServiceConnectionManager { if (rootLib == null) return null; final selectedIsolateRefId = mainIsolateRef.id!; - await resolvedUriManager.fetchFileUris(selectedIsolateRefId, [rootLib]); - return resolvedUriManager.lookupFileUri( + await serviceManager.resolvedUriManager + .fetchFileUris(selectedIsolateRefId, [rootLib]); + return serviceManager.resolvedUriManager.lookupFileUri( selectedIsolateRefId, rootLib, ); diff --git a/packages/devtools_app/test/debugger/debugger_codeview_test.dart b/packages/devtools_app/test/debugger/debugger_codeview_test.dart index f743a157545..0dda5659899 100644 --- a/packages/devtools_app/test/debugger/debugger_codeview_test.dart +++ b/packages/devtools_app/test/debugger/debugger_codeview_test.dart @@ -170,7 +170,7 @@ void main() { ), ); // Prefetch File Uris - await serviceConnection.resolvedUriManager.fetchFileUris( + await serviceConnection.serviceManager.resolvedUriManager.fetchFileUris( serviceConnection .serviceManager.isolateManager.selectedIsolate.value!.id!, [mockScriptRef.uri!], diff --git a/packages/devtools_app/test/shared/resolved_uri_manager_test.dart b/packages/devtools_app/test/shared/resolved_uri_manager_test.dart index 64d30325df1..3a0b1629fd7 100644 --- a/packages/devtools_app/test/shared/resolved_uri_manager_test.dart +++ b/packages/devtools_app/test/shared/resolved_uri_manager_test.dart @@ -4,8 +4,7 @@ import 'dart:async'; -import 'package:devtools_app/devtools_app.dart'; -import 'package:devtools_app_shared/utils.dart'; +import 'package:devtools_app_shared/service.dart'; import 'package:devtools_test/devtools_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; @@ -13,13 +12,7 @@ import 'package:vm_service/vm_service.dart'; void main() { late ResolvedUriManager resolvedUriManager; - final service = createMockVmServiceWrapperWithDefaults(); - - setGlobal( - ServiceConnectionManager, - FakeServiceConnectionManager(service: service), - ); - resolvedUriManager = ResolvedUriManager(); + late MockVmServiceWrapper service; const String isolateId = 'anIsolateId'; const uri1 = 'this/is/a/uri1'; @@ -27,14 +20,14 @@ void main() { const packageUri1 = 'uri/am/i1'; const packageUri2 = 'uri/am/i2'; + setUp(() { + service = createMockVmServiceWrapperWithDefaults(); + resolvedUriManager = ResolvedUriManager(); + }); + group('lifecycle', () { setUp(() { - when( - unawaited( - serviceConnection.serviceManager.service! - .lookupPackageUris(isolateId, [uri1]), - ), - ).thenAnswer( + when(unawaited(service.lookupPackageUris(isolateId, [uri1]))).thenAnswer( (realInvocation) => Future.value(UriList(uris: [packageUri1])), ); }); @@ -50,7 +43,7 @@ void main() { }); test('does nothing after vmServiceClosed', () async { - resolvedUriManager.vmServiceOpened(); + resolvedUriManager.vmServiceOpened(service); resolvedUriManager.vmServiceClosed(); await resolvedUriManager.fetchPackageUris(isolateId, [uri1]); @@ -65,7 +58,7 @@ void main() { group('file to package mappings', () { setUp(() { - resolvedUriManager.vmServiceOpened(); + resolvedUriManager.vmServiceOpened(service); }); test('lookupPackageUri when uri is unknown', () { @@ -75,10 +68,7 @@ void main() { }); test('lookupPackageUris', () async { - when( - serviceConnection.serviceManager.service! - .lookupPackageUris(isolateId, [uri1, uri2]), - ).thenAnswer( + when(service.lookupPackageUris(isolateId, [uri1, uri2])).thenAnswer( (realInvocation) => Future.value(UriList(uris: [packageUri1, packageUri2])), ); @@ -96,16 +86,10 @@ void main() { }); test('remembers already fetched uris', () async { - when( - serviceConnection.serviceManager.service! - .lookupPackageUris(isolateId, [uri1]), - ).thenAnswer( + when(service.lookupPackageUris(isolateId, [uri1])).thenAnswer( (realInvocation) => Future.value(UriList(uris: [packageUri1])), ); - when( - serviceConnection.serviceManager.service! - .lookupPackageUris(isolateId, [uri2]), - ).thenAnswer( + when(service.lookupPackageUris(isolateId, [uri2])).thenAnswer( (realInvocation) => Future.value(UriList(uris: [packageUri2])), ); @@ -130,16 +114,10 @@ void main() { const String isolateId2 = 'anIsolateId2'; const String packageUriFromDifferentIsolate = 'this/is/a/third/packageUri3'; - when( - serviceConnection.serviceManager.service! - .lookupPackageUris(isolateId, [uri1]), - ).thenAnswer( + when(service.lookupPackageUris(isolateId, [uri1])).thenAnswer( (realInvocation) => Future.value(UriList(uris: [packageUri1])), ); - when( - serviceConnection.serviceManager.service! - .lookupPackageUris(isolateId2, [uri1]), - ).thenAnswer( + when(service.lookupPackageUris(isolateId2, [uri1])).thenAnswer( (realInvocation) => Future.value(UriList(uris: [packageUriFromDifferentIsolate])), ); @@ -158,12 +136,7 @@ void main() { }); test('preserves the reverse package to file mapping', () async { - when( - serviceConnection.serviceManager.service!.lookupPackageUris( - isolateId, - [uri1], - ), - ).thenAnswer( + when(service.lookupPackageUris(isolateId, [uri1])).thenAnswer( (realInvocation) => Future.value(UriList(uris: [packageUri1])), ); @@ -182,7 +155,7 @@ void main() { group('package to file mappings', () { setUp(() { - resolvedUriManager.vmServiceOpened(); + resolvedUriManager.vmServiceOpened(service); }); test('lookupFileUri when package is unknown', () { @@ -193,10 +166,8 @@ void main() { test('lookupFileUri', () async { when( - serviceConnection.serviceManager.service!.lookupResolvedPackageUris( - isolateId, - [packageUri1, packageUri2], - ), + service + .lookupResolvedPackageUris(isolateId, [packageUri1, packageUri2]), ).thenAnswer( (realInvocation) => Future.value(UriList(uris: [uri1, uri2])), ); @@ -215,16 +186,12 @@ void main() { }); test('remembers already fetched file paths', () async { - when( - serviceConnection.serviceManager.service! - .lookupResolvedPackageUris(isolateId, [packageUri1]), - ).thenAnswer( + when(service.lookupResolvedPackageUris(isolateId, [packageUri1])) + .thenAnswer( (realInvocation) => Future.value(UriList(uris: [uri1])), ); - when( - serviceConnection.serviceManager.service! - .lookupResolvedPackageUris(isolateId, [packageUri2]), - ).thenAnswer( + when(service.lookupResolvedPackageUris(isolateId, [packageUri2])) + .thenAnswer( (realInvocation) => Future.value(UriList(uris: [uri2])), ); @@ -249,16 +216,12 @@ void main() { const String isolateId2 = 'anIsolateId2'; const String fileUriFromDifferentIsolate = 'file:///this/is/a/third/fileUri3'; - when( - serviceConnection.serviceManager.service! - .lookupResolvedPackageUris(isolateId, [packageUri1]), - ).thenAnswer( + when(service.lookupResolvedPackageUris(isolateId, [packageUri1])) + .thenAnswer( (realInvocation) => Future.value(UriList(uris: [uri1])), ); - when( - serviceConnection.serviceManager.service! - .lookupResolvedPackageUris(isolateId2, [packageUri1]), - ).thenAnswer( + when(service.lookupResolvedPackageUris(isolateId2, [packageUri1])) + .thenAnswer( (realInvocation) => Future.value(UriList(uris: [fileUriFromDifferentIsolate])), ); @@ -277,12 +240,8 @@ void main() { }); test('preserves the reverse file to package mapping', () async { - when( - serviceConnection.serviceManager.service!.lookupResolvedPackageUris( - isolateId, - [packageUri1], - ), - ).thenAnswer( + when(service.lookupResolvedPackageUris(isolateId, [packageUri1])) + .thenAnswer( (realInvocation) => Future.value(UriList(uris: [uri1])), ); diff --git a/packages/devtools_app_shared/CHANGELOG.md b/packages/devtools_app_shared/CHANGELOG.md index f0bbb81b9d9..df089f34802 100644 --- a/packages/devtools_app_shared/CHANGELOG.md +++ b/packages/devtools_app_shared/CHANGELOG.md @@ -1,4 +1,6 @@ ## 0.0.8 +* Add `ServiceManager.resolvedUriManager` for looking up package and file uris from +a VM service connection. * Migrate from `dart:html` to `package:web`. ## 0.0.7 diff --git a/packages/devtools_app_shared/lib/service.dart b/packages/devtools_app_shared/lib/service.dart index cdad65412d2..ddf36501a23 100644 --- a/packages/devtools_app_shared/lib/service.dart +++ b/packages/devtools_app_shared/lib/service.dart @@ -7,6 +7,7 @@ export 'src/service/eval_on_dart_library.dart'; export 'src/service/flutter_version.dart'; export 'src/service/isolate_manager.dart' hide TestIsolateManager; export 'src/service/isolate_state.dart'; +export 'src/service/resolved_uri_manager.dart'; export 'src/service/service_extension_manager.dart' hide TestServiceExtensionManager; export 'src/service/service_manager.dart'; diff --git a/packages/devtools_app/lib/src/service/resolved_uri_manager.dart b/packages/devtools_app_shared/lib/src/service/resolved_uri_manager.dart similarity index 91% rename from packages/devtools_app/lib/src/service/resolved_uri_manager.dart rename to packages/devtools_app_shared/lib/src/service/resolved_uri_manager.dart index e1cd9176184..948772f871f 100644 --- a/packages/devtools_app/lib/src/service/resolved_uri_manager.dart +++ b/packages/devtools_app_shared/lib/src/service/resolved_uri_manager.dart @@ -2,19 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import '../shared/globals.dart'; +import 'package:vm_service/vm_service.dart'; /// Manager for handling package Uri lookup and caching. -class ResolvedUriManager { +final class ResolvedUriManager { + VmService? _service; + _PackagePathMappings? _packagePathMappings; /// Initializes the [ResolvedUriManager] - void vmServiceOpened() { + void vmServiceOpened(VmService service) { + _service = service; _packagePathMappings = _PackagePathMappings(); } /// Cleans up the resources of the [ResolvedUriManager] void vmServiceClosed() { + _service = null; _packagePathMappings = null; } @@ -27,9 +31,8 @@ class ResolvedUriManager { Future fetchPackageUris(String isolateId, List uris) async { if (uris.isEmpty) return; if (_packagePathMappings != null) { - final packageUris = (await serviceConnection.serviceManager.service! - .lookupPackageUris(isolateId, uris)) - .uris; + final packageUris = + (await _service!.lookupPackageUris(isolateId, uris)).uris; if (packageUris != null) { _packagePathMappings!.addMappings( @@ -50,9 +53,9 @@ class ResolvedUriManager { /// [packageUris] List of uris to fetch full file paths for. Future fetchFileUris(String isolateId, List packageUris) async { if (_packagePathMappings != null) { - final fileUris = (await serviceConnection.serviceManager.service! - .lookupResolvedPackageUris(isolateId, packageUris)) - .uris; + final fileUris = + (await _service!.lookupResolvedPackageUris(isolateId, packageUris)) + .uris; // [_packagePathMappings] could have been set to null during the async gap // so check that it is non-null again here. diff --git a/packages/devtools_app_shared/lib/src/service/service_manager.dart b/packages/devtools_app_shared/lib/src/service/service_manager.dart index 1022b2dbbaa..dc006ecc8ec 100644 --- a/packages/devtools_app_shared/lib/src/service/service_manager.dart +++ b/packages/devtools_app_shared/lib/src/service/service_manager.dart @@ -15,6 +15,7 @@ import 'connected_app.dart'; import 'flutter_version.dart'; import 'isolate_manager.dart'; import 'isolate_state.dart'; +import 'resolved_uri_manager.dart'; import 'service_extension_manager.dart'; import 'service_extensions.dart'; import 'service_utils.dart'; @@ -80,6 +81,8 @@ class ServiceManager { final isolateManager = IsolateManager(); + final resolvedUriManager = ResolvedUriManager(); + /// Proxy to state inside the isolateManager, for code consizeness. /// /// Defaults to false if there is no main isolate. @@ -223,6 +226,7 @@ class ServiceManager { // race conditions where managers cannot listen for events soon enough. isolateManager.vmServiceOpened(service); serviceExtensionManager.vmServiceOpened(service, connectedApp!); + resolvedUriManager.vmServiceOpened(service); await callLifecycleCallbacks( ServiceManagerLifecycle.beforeOpenVmService, @@ -254,6 +258,7 @@ class ServiceManager { this.service, ); + resolvedUriManager.vmServiceClosed(); serviceExtensionManager.vmServiceClosed(); isolateManager.handleVmServiceClosed(); _registeredMethodsForService.clear(); diff --git a/packages/devtools_test/lib/src/mocks/fake_service_manager.dart b/packages/devtools_test/lib/src/mocks/fake_service_manager.dart index 8493b473cf7..54a489452da 100644 --- a/packages/devtools_test/lib/src/mocks/fake_service_manager.dart +++ b/packages/devtools_test/lib/src/mocks/fake_service_manager.dart @@ -36,7 +36,6 @@ class FakeServiceConnectionManager extends Fake connectedAppInitialized: connectedAppInitialized, availableLibraries: availableLibraries, availableServices: availableServices, - onVmServiceOpened: resolvedUriManager.vmServiceOpened, ); for (var screenId in screenIds) { when(errorBadgeManager.erroredItemsForPage(screenId)).thenReturn( @@ -52,9 +51,6 @@ class FakeServiceConnectionManager extends Fake _serviceManager as FakeServiceManager; late final ServiceManager _serviceManager; - @override - final resolvedUriManager = ResolvedUriManager(); - @override late final AppState appState = AppState(serviceManager.isolateManager.selectedIsolate);