Skip to content

Commit 57cb9b8

Browse files
authored
Use isolateManager as source of truth for isPaused. (#5018)
1 parent ab13047 commit 57cb9b8

23 files changed

+86
-71
lines changed

packages/devtools_app/lib/src/screens/debugger/codeview.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,7 @@ class _LineItemState extends State<LineItem>
11451145
// ignore: avoid-unused-parameters
11461146
required bool Function() isHoverStale,
11471147
}) async {
1148-
if (!serviceManager.appState.isPaused.value) return null;
1148+
if (!serviceManager.isMainIsolatePaused) return null;
11491149

11501150
final word = wordForHover(
11511151
event.localPosition.dx,

packages/devtools_app/lib/src/screens/debugger/controls.dart

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,31 @@ class _DebuggingControlsState extends State<DebuggingControls>
3333
void didChangeDependencies() {
3434
super.didChangeDependencies();
3535
if (!initController()) return;
36-
addAutoDisposeListener(serviceManager.appState.isPaused);
36+
addAutoDisposeListener(
37+
serviceManager.isolateManager.mainIsolateState!.isPaused,
38+
);
3739
addAutoDisposeListener(controller.resuming);
3840
addAutoDisposeListener(controller.stackFramesWithLocation);
3941
}
4042

4143
@override
4244
Widget build(BuildContext context) {
43-
final isPaused = serviceManager.appState.isPaused.value;
4445
final resuming = controller.resuming.value;
4546
final hasStackFrames = controller.stackFramesWithLocation.value.isNotEmpty;
4647
final isSystemIsolate = controller.isSystemIsolate;
47-
final canStep = isPaused && !resuming && hasStackFrames && !isSystemIsolate;
48+
final canStep = serviceManager.isMainIsolatePaused &&
49+
!resuming &&
50+
hasStackFrames &&
51+
!isSystemIsolate;
4852
final isVmApp = serviceManager.connectedApp?.isRunningOnDartVM ?? false;
4953
return SizedBox(
5054
height: defaultButtonHeight,
5155
child: Row(
5256
children: [
53-
_pauseAndResumeButtons(isPaused: isPaused, resuming: resuming),
57+
_pauseAndResumeButtons(
58+
isPaused: serviceManager.isMainIsolatePaused,
59+
resuming: resuming,
60+
),
5461
const SizedBox(width: denseSpacing),
5562
_stepButtons(canStep: canStep),
5663
const SizedBox(width: denseSpacing),

packages/devtools_app/lib/src/screens/debugger/debugger_controller.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ class DebuggerController extends DisposableController
7979

8080
final appState = serviceManager.appState;
8181

82-
appState.setPausedOnBreakpoint(false);
8382
_resuming.value = false;
8483
_lastEvent = null;
8584
_stackFramesWithLocation.value = [];
@@ -168,7 +167,6 @@ class DebuggerController extends DisposableController
168167
// and modify to detect if app is paused from the isolate
169168
// https://github.com/flutter/devtools/pull/4993#discussion_r1060845351
170169

171-
serviceManager.appState.setPausedOnBreakpoint(false);
172170
await _pause(false);
173171

174172
_clearCaches();
@@ -373,7 +371,6 @@ class DebuggerController extends DisposableController
373371
// serviceManager.isolateManager.selectedIsolateState.isPaused.value;
374372
// listening for changes there instead of having separate logic.
375373
await _getStackOperation?.cancel();
376-
serviceManager.appState.setPausedOnBreakpoint(paused);
377374

378375
_log.log('_pause(running: ${!paused})');
379376

packages/devtools_app/lib/src/screens/debugger/debugger_screen.dart

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -360,27 +360,29 @@ class DebuggerStatus extends StatefulWidget {
360360
class _DebuggerStatusState extends State<DebuggerStatus> with AutoDisposeMixin {
361361
String _status = '';
362362

363+
bool get _isPaused => serviceManager.isMainIsolatePaused;
364+
363365
@override
364366
void initState() {
365367
super.initState();
366368

367-
addAutoDisposeListener(
368-
serviceManager.appState.isPaused,
369-
() => unawaited(
370-
_updateStatus(),
371-
),
372-
);
373-
369+
_updateStatusOnPause();
374370
unawaited(_updateStatus());
375371
}
376372

377373
@override
378374
void didUpdateWidget(DebuggerStatus oldWidget) {
379375
super.didUpdateWidget(oldWidget);
380376

381-
// todo: should we check that widget.controller != oldWidget.controller?
377+
if (widget.controller == oldWidget.controller) return;
378+
379+
cancelListeners();
380+
_updateStatusOnPause();
381+
}
382+
383+
void _updateStatusOnPause() {
382384
addAutoDisposeListener(
383-
serviceManager.appState.isPaused,
385+
serviceManager.isolateManager.mainIsolateState!.isPaused,
384386
() => unawaited(
385387
_updateStatus(),
386388
),
@@ -406,9 +408,7 @@ class _DebuggerStatusState extends State<DebuggerStatus> with AutoDisposeMixin {
406408
}
407409

408410
Future<String> _computeStatus() async {
409-
final paused = serviceManager.appState.isPaused.value;
410-
411-
if (!paused) {
411+
if (!_isPaused) {
412412
return 'running';
413413
}
414414

@@ -447,20 +447,21 @@ class _FloatingDebuggerControlsState extends State<FloatingDebuggerControls>
447447
with
448448
AutoDisposeMixin,
449449
ProvidedControllerMixin<DebuggerController, FloatingDebuggerControls> {
450-
late bool paused;
451-
452450
late double controlHeight;
453451

452+
bool get _isPaused => serviceManager.isMainIsolatePaused;
453+
454454
@override
455455
void didChangeDependencies() {
456456
super.didChangeDependencies();
457457
if (!initController()) return;
458-
paused = serviceManager.appState.isPaused.value;
459-
controlHeight = paused ? defaultButtonHeight : 0.0;
460-
addAutoDisposeListener(serviceManager.appState.isPaused, () {
458+
cancelListeners();
459+
460+
controlHeight = _isPaused ? defaultButtonHeight : 0.0;
461+
addAutoDisposeListener(
462+
serviceManager.isolateManager.mainIsolateState!.isPaused, () {
461463
setState(() {
462-
paused = serviceManager.appState.isPaused.value;
463-
if (paused) {
464+
if (_isPaused) {
464465
controlHeight = defaultButtonHeight;
465466
}
466467
});
@@ -470,10 +471,10 @@ class _FloatingDebuggerControlsState extends State<FloatingDebuggerControls>
470471
@override
471472
Widget build(BuildContext context) {
472473
return AnimatedOpacity(
473-
opacity: paused ? 1.0 : 0.0,
474+
opacity: _isPaused ? 1.0 : 0.0,
474475
duration: longDuration,
475476
onEnd: () {
476-
if (!paused) {
477+
if (!_isPaused) {
477478
setState(() {
478479
controlHeight = 0.0;
479480
});

packages/devtools_app/lib/src/screens/debugger/program_explorer_controller.dart

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ class ProgramExplorerController extends DisposableController
4848
ValueListenable<int> get selectedNodeIndex => _selectedNodeIndex;
4949
final _selectedNodeIndex = ValueNotifier<int>(0);
5050

51-
IsolateRef? _isolate;
52-
5351
/// Notifies that the controller has finished initializing.
5452
ValueListenable<bool> get initialized => _initialized;
5553
final _initialized = ValueNotifier<bool>(false);
@@ -76,10 +74,10 @@ class ProgramExplorerController extends DisposableController
7674
}
7775
_initializing = true;
7876

79-
_isolate = serviceManager.isolateManager.selectedIsolate.value;
80-
final libraries = _isolate != null
77+
final isolate = serviceManager.isolateManager.selectedIsolate.value;
78+
final libraries = isolate != null
8179
? serviceManager.isolateManager
82-
.isolateDebuggerState(_isolate)!
80+
.isolateState(isolate)
8381
.isolateNow!
8482
.libraries!
8583
: <LibraryRef>[];

packages/devtools_app/lib/src/screens/debugger/program_explorer_model.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class VMServiceObjectNode extends TreeNode<VMServiceObjectNode> {
8686
final service = serviceManager.service!;
8787
final isolate = serviceManager.isolateManager.selectedIsolate.value!;
8888
final libRef = serviceManager.isolateManager
89-
.isolateDebuggerState(isolate)!
89+
.isolateState(isolate)
9090
.isolateNow!
9191
.libraries!
9292
.firstWhere(
@@ -194,7 +194,7 @@ class VMServiceObjectNode extends TreeNode<VMServiceObjectNode> {
194194
// part of a package. Otherwise, it's a file path and its directory should
195195
// appear near the top of the list anyway.
196196
final rootLibUri = serviceManager
197-
.isolateManager.mainIsolateDebuggerState?.isolateNow?.rootLib?.uri;
197+
.isolateManager.mainIsolateState?.isolateNow?.rootLib?.uri;
198198
if (rootLibUri != null) {
199199
if (rootLibUri.startsWith('package:') ||
200200
rootLibUri.startsWith('google3:')) {

packages/devtools_app/lib/src/screens/inspector/inspector_tree_controller.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ class _InspectorTreeState extends State<InspectorTree>
775775
autoDisposeFocusNode(_focusNode);
776776

777777
callOnceWhenReady(
778-
trigger: serviceManager.isolateManager.mainIsolateDebuggerState!.isPaused,
778+
trigger: serviceManager.isolateManager.mainIsolateState!.isPaused,
779779
callback: _bindToController,
780780
readyWhen: (triggerValue) => triggerValue == false,
781781
);

packages/devtools_app/lib/src/service/isolate_manager.dart

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,12 @@ class IsolateManager extends Disposer {
6060
await _initIsolates(isolates);
6161
}
6262

63-
IsolateState? get mainIsolateDebuggerState {
63+
IsolateState? get mainIsolateState {
6464
return _mainIsolate.value != null
6565
? _isolateStates[_mainIsolate.value!]
6666
: null;
6767
}
6868

69-
IsolateState? isolateDebuggerState(IsolateRef? isolate) {
70-
return isolate != null ? _isolateStates[isolate] : null;
71-
}
72-
7369
/// Return a unique, monotonically increasing number for this Isolate.
7470
int? isolateIndex(IsolateRef isolateRef) {
7571
if (!_isolateIndexMap.containsKey(isolateRef.id)) {

packages/devtools_app/lib/src/service/service_manager.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ class ServiceConnectionManager {
7878

7979
final isolateManager = IsolateManager();
8080

81+
/// Proxy to state inside the isolateManager, for code consizeness.
82+
///
83+
/// Defaults to false if there is no main isolate.
84+
bool get isMainIsolatePaused =>
85+
isolateManager.mainIsolateState?.isPaused.value ?? false;
86+
8187
final consoleService = ConsoleService();
8288

8389
final resolvedUriManager = ResolvedUriManager();
@@ -547,7 +553,7 @@ class ServiceConnectionManager {
547553
if (uri == null) return false;
548554
assert(_serviceAvailable.isCompleted);
549555
assert(serviceManager.isolateManager.mainIsolate.value != null);
550-
final isolate = isolateManager.mainIsolateDebuggerState!.isolateNow;
556+
final isolate = isolateManager.mainIsolateState!.isolateNow;
551557
return (isolate?.libraries ?? [])
552558
.map((ref) => ref.uri)
553559
.toList()

packages/devtools_app/lib/src/shared/connected_app.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,6 @@ class AppState extends DisposableController with AutoDisposeControllerMixin {
250250
final _variables = ValueNotifier<List<DartObjectNode>>([]);
251251
void setVariables(List<DartObjectNode> value) => _variables.value = value;
252252

253-
ValueListenable<bool> get isPaused => _isPaused;
254-
final _isPaused = ValueNotifier<bool>(false);
255-
256-
/// This setter should be invoked only by debugger.
257-
void setPausedOnBreakpoint(bool value) => _isPaused.value = value;
258-
259253
ValueListenable<Frame?> get currentFrame => _currentFrame;
260254
final _currentFrame = ValueNotifier<Frame?>(null);
261255
void setCurrentFrame(Frame? value) => _currentFrame.value = value;
@@ -267,7 +261,6 @@ class AppState extends DisposableController with AutoDisposeControllerMixin {
267261
@override
268262
void dispose() {
269263
_variables.dispose();
270-
_isPaused.dispose();
271264
_currentFrame.dispose();
272265
super.dispose();
273266
}

packages/devtools_app/lib/src/shared/console/eval/eval_service.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class EvalService extends DisposableController with AutoDisposeControllerMixin {
6868
Future<Response> evalAtCurrentFrame(String expression) {
6969
final appState = serviceManager.appState;
7070

71-
if (!appState.isPaused.value) {
71+
if (!serviceManager.isMainIsolatePaused) {
7272
return Future.error(
7373
RPCError.withDetails(
7474
'evaluateInFrame',

packages/devtools_app/lib/src/shared/console/widgets/evaluate.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,7 @@ class ExpressionEvalFieldState extends State<ExpressionEvalField>
300300
if (expressionText.isEmpty) return;
301301

302302
// Only try to eval if we are paused.
303-
if (!serviceManager
304-
.isolateManager.mainIsolateDebuggerState!.isPaused.value) {
303+
if (!serviceManager.isMainIsolatePaused) {
305304
notificationService
306305
.push('Application must be paused to support expression evaluation.');
307306
return;

packages/devtools_app/lib/src/shared/inspector_service.dart

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,7 @@ abstract class InspectorServiceBase extends DisposableController
9797
/// The VM Service protocol must be used when paused at a breakpoint as the
9898
/// Daemon API calls won't execute until after the current frame is done
9999
/// rendering.
100-
bool get useDaemonApi {
101-
return !(serviceManager
102-
.isolateManager.mainIsolateDebuggerState?.isPaused.value ??
103-
false);
104-
}
100+
bool get useDaemonApi => !serviceManager.isMainIsolatePaused;
105101

106102
@override
107103
void dispose() {

packages/devtools_app/lib/src/shared/preferences.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,7 @@ class InspectorPreferencesController extends DisposableController
154154
() {
155155
if (_mainScriptDir != null &&
156156
serviceManager.isolateManager.mainIsolate.value != null) {
157-
final debuggerState =
158-
serviceManager.isolateManager.mainIsolateDebuggerState;
157+
final debuggerState = serviceManager.isolateManager.mainIsolateState;
159158

160159
if (debuggerState?.isPaused.value == false) {
161160
// the isolate is already unpaused, we can try to load

packages/devtools_app/test/debugger/debugger_floating_test.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ void main() {
2727
setGlobal(NotificationService, NotificationService());
2828
fakeServiceManager.consoleService.ensureServiceInitialized();
2929

30-
fakeServiceManager.appState.setPausedOnBreakpoint(true);
30+
setUp(() {
31+
fakeServiceManager.isMainIsolatePaused = true;
32+
});
3133

3234
Future<void> pumpControls(WidgetTester tester) async {
3335
await tester.pumpWidget(
@@ -41,6 +43,7 @@ void main() {
4143

4244
testWidgets('display as expected', (WidgetTester tester) async {
4345
await pumpControls(tester);
46+
4447
final animatedOpacityFinder = find.byType(AnimatedOpacity);
4548
expect(animatedOpacityFinder, findsOneWidget);
4649
final animatedOpacity =
@@ -85,7 +88,9 @@ void main() {
8588
});
8689

8790
testWidgets('are hidden when app is not paused', (WidgetTester tester) async {
88-
fakeServiceManager.appState.setPausedOnBreakpoint(false);
91+
final state =
92+
fakeServiceManager.isolateManager.mainIsolateState! as MockIsolateState;
93+
state.isPaused.value = false;
8994
await pumpControls(tester);
9095
final animatedOpacityFinder = find.byType(AnimatedOpacity);
9196
expect(animatedOpacityFinder, findsOneWidget);

packages/devtools_app/test/debugger/debugger_screen_paused_test.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ void main() {
8080
}
8181

8282
setUp(() {
83-
fakeServiceManager.appState.setPausedOnBreakpoint(true);
83+
final state =
84+
fakeServiceManager.isolateManager.mainIsolateState! as MockIsolateState;
85+
state.isPaused.value = true;
8486
});
8587

8688
testWidgetsWithWindowSize(

packages/devtools_app/test/shared/scaffold_debugger_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ void main() {
2727
when(mockServiceManager.errorBadgeManager).thenReturn(mockErrorBadgeManager);
2828
when(mockErrorBadgeManager.errorCountNotifier(any))
2929
.thenReturn(ValueNotifier<int>(0));
30+
when(mockServiceManager.isMainIsolatePaused).thenReturn(false);
3031

3132
setGlobal(ServiceConnectionManager, mockServiceManager);
3233
setGlobal(FrameworkController, FrameworkController());

packages/devtools_app/test/shared/scaffold_debugging_controls_test.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ void main() {
5555
AppState(mockServiceManager.isolateManager.selectedIsolate),
5656
);
5757
final mockDebuggerController = MockDebuggerController();
58-
mockServiceManager.appState.setPausedOnBreakpoint(true);
58+
final state =
59+
serviceManager.isolateManager.mainIsolateState! as MockIsolateState;
60+
state.isPaused.value = true;
61+
when(mockServiceManager.isMainIsolatePaused).thenReturn(false);
5962

6063
await tester.pumpWidget(
6164
wrapWithControllers(

packages/devtools_app/test/shared/scaffold_profile_test.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ void main() {
5252
when(mockServiceManager.connectedApp).thenReturn(mockConnectedApp);
5353
final mockDebuggerController = MockDebuggerController();
5454

55-
mockServiceManager.appState.setPausedOnBreakpoint(true);
55+
final state =
56+
serviceManager.isolateManager.mainIsolateState! as MockIsolateState;
57+
state.isPaused.value = true;
5658

5759
await tester.pumpWidget(
5860
wrapWithControllers(

packages/devtools_app/test/shared/service_extension_widgets_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Future<void> main() async {
2828
.thenReturn(AppState(mockServiceManager.isolateManager.selectedIsolate));
2929
when(mockServiceManager.runDeviceBusyTask(Future<void>.value()))
3030
.thenAnswer((_) => Future<void>.value());
31+
when(mockServiceManager.isMainIsolatePaused).thenReturn(false);
3132
setGlobal(ServiceConnectionManager, mockServiceManager);
3233
setGlobal(NotificationService, NotificationService());
3334

0 commit comments

Comments
 (0)