diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md index c7cb39c690e6..9192e3c14bfc 100644 --- a/pkg/dds/CHANGELOG.md +++ b/pkg/dds/CHANGELOG.md @@ -3,6 +3,8 @@ and prepared DDS for using `unified_analytics` through the Dart Tooling Daemon. - Internal change: removed `analytics` parameter from the DevTools server `defaultHandler` method. - Updated `README.md` and added contributing guide (`CONTRIBUTING.md`). +- Updated `package:dds_service_extensions` constraint to ^2.0.0. +- Determine default `requireUserPermissionToResume` values from the `pause_isolates_on_start` and `pause_isolates_on_exit` flags. # 4.0.0 - Updated DDS protocol to version 2.0. diff --git a/pkg/dds/lib/src/isolate_manager.dart b/pkg/dds/lib/src/isolate_manager.dart index e5f8363b8b15..668fecff5623 100644 --- a/pkg/dds/lib/src/isolate_manager.dart +++ b/pkg/dds/lib/src/isolate_manager.dart @@ -280,6 +280,7 @@ class IsolateManager { ); } } + await _determineRequireUserPermissionToResumeFromFlags(); _initialized = true; } @@ -383,14 +384,10 @@ class IsolateManager { DartDevelopmentServiceClient client, json_rpc.Parameters parameters, ) async { - int pauseTypeMask = 0; - if (parameters['onPauseStart'].asBoolOr(false)) { - pauseTypeMask |= PauseTypeMasks.pauseOnStartMask; - } - if (parameters['onPauseExit'].asBoolOr(false)) { - pauseTypeMask |= PauseTypeMasks.pauseOnExitMask; - } - _requireUserPermissionToResumeMask = pauseTypeMask; + _setRequireUserPermissionToResume( + onPauseStart: parameters['onPauseStart'].asBoolOr(false), + onPauseExit: parameters['onPauseExit'].asBoolOr(false), + ); // Check if isolates have been waiting for a user resume and resume any // isolates that no longer need to wait for a user resume. @@ -415,6 +412,51 @@ class IsolateManager { }; } + Future _determineRequireUserPermissionToResumeFromFlags() async { + try { + final result = await dds.vmServiceClient.sendRequest('getFlagList') + as Map; + final flagList = FlagList.parse(result); + final flags = flagList!.flags!; + + bool? pauseOnStartValue; + bool? pauseOnExitValue; + for (final flag in flags) { + if (flag.name == 'pause_isolates_on_start') { + pauseOnStartValue = flag.valueAsString == 'true'; + } + if (flag.name == 'pause_isolates_on_exit') { + pauseOnExitValue = flag.valueAsString == 'true'; + } + if (pauseOnStartValue != null && pauseOnExitValue != null) { + break; + } + } + + _setRequireUserPermissionToResume( + onPauseStart: pauseOnStartValue ?? false, + onPauseExit: pauseOnExitValue ?? false, + ); + } catch (_) { + // Swallow any errors. Otherwise, this will cause initialization to + // silently fail. + } + } + + void _setRequireUserPermissionToResume({ + required bool onPauseStart, + required bool onPauseExit, + }) { + int pauseTypeMask = 0; + if (onPauseStart) { + pauseTypeMask |= PauseTypeMasks.pauseOnStartMask; + } + if (onPauseExit) { + pauseTypeMask |= PauseTypeMasks.pauseOnExitMask; + } + _requireUserPermissionToResumeMask = pauseTypeMask; + } + Future> getCachedCpuSamples( json_rpc.Parameters parameters) async { final isolateId = parameters['isolateId'].asString; diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml index 987ea344c96f..61489083e0b0 100644 --- a/pkg/dds/pubspec.yaml +++ b/pkg/dds/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: async: ^2.4.1 browser_launcher: ^1.0.0 collection: ^1.15.0 - dds_service_extensions: ^1.6.0 + dds_service_extensions: ^2.0.0 dap: ^1.2.0 extension_discovery: ^2.0.0 devtools_shared: ^8.0.1 diff --git a/pkg/dds/test/client_resume_approvals_approve_then_disconnect_test.dart b/pkg/dds/test/client_resume_approvals_approve_then_disconnect_test.dart index 98ea607d1c87..61ae0f5d3796 100644 --- a/pkg/dds/test/client_resume_approvals_approve_then_disconnect_test.dart +++ b/pkg/dds/test/client_resume_approvals_approve_then_disconnect_test.dart @@ -20,6 +20,7 @@ void fooBar() { final test = [ hasPausedAtStart, (VmService service, IsolateRef isolate) async { + service.requireUserPermissionToResume(onPauseStart: false); final isolateId = isolate.id!; final client1 = await createClient( service: service, diff --git a/pkg/dds/test/client_resume_approvals_disconnect_test.dart b/pkg/dds/test/client_resume_approvals_disconnect_test.dart index a2ae9fc797be..f0b113688053 100644 --- a/pkg/dds/test/client_resume_approvals_disconnect_test.dart +++ b/pkg/dds/test/client_resume_approvals_disconnect_test.dart @@ -21,6 +21,7 @@ final test = [ // Multiple clients, disconnect client awaiting approval. hasPausedAtStart, (VmService service, IsolateRef isolate) async { + service.requireUserPermissionToResume(onPauseStart: false); final isolateId = isolate.id!; final client1 = await createClient( service: service, @@ -43,8 +44,7 @@ final test = [ await hasPausedAtStart(service, isolate); // Once client2 disconnects, there are no clients which require resume - // approval. Ensure we resume immediately so we don't deadlock waiting for - // approvals from disconnected clients. + // approval. await client2.dispose(); }, hasStoppedAtExit, diff --git a/pkg/dds/test/client_resume_approvals_identical_names_test.dart b/pkg/dds/test/client_resume_approvals_identical_names_test.dart index 6183ff75d0fd..69b11c63ffd1 100644 --- a/pkg/dds/test/client_resume_approvals_identical_names_test.dart +++ b/pkg/dds/test/client_resume_approvals_identical_names_test.dart @@ -19,6 +19,7 @@ void fooBar() { final test = [ // Multiple clients, same client names. (VmService service, IsolateRef isolateRef) async { + service.requireUserPermissionToResume(onPauseStart: false); // ignore: unused_local_variable final client1 = await createClient( service: service, diff --git a/pkg/dds/test/client_resume_approvals_multiple_names_test.dart b/pkg/dds/test/client_resume_approvals_multiple_names_test.dart index 6d2d897a09f0..307672762579 100644 --- a/pkg/dds/test/client_resume_approvals_multiple_names_test.dart +++ b/pkg/dds/test/client_resume_approvals_multiple_names_test.dart @@ -21,6 +21,7 @@ void fooBar() { final test = [ // Multiple clients, different client names. (VmService service, IsolateRef isolateRef) async { + service.requireUserPermissionToResume(onPauseStart: false); final isolateId = isolateRef.id!; final client1 = await createClient( service: service, diff --git a/pkg/dds/test/client_resume_approvals_name_change_test.dart b/pkg/dds/test/client_resume_approvals_name_change_test.dart index a54b25eff949..3bc0e04216e3 100644 --- a/pkg/dds/test/client_resume_approvals_name_change_test.dart +++ b/pkg/dds/test/client_resume_approvals_name_change_test.dart @@ -22,6 +22,7 @@ void fooBar() { final test = [ // Remove required approvals via name change. (VmService service, IsolateRef isolateRef) async { + service.requireUserPermissionToResume(onPauseStart: false); final isolateId = isolateRef.id!; // Create two clients with the same name.