Skip to content

Commit 6c60744

Browse files
committed
Address comments
1 parent 0f3ea7e commit 6c60744

8 files changed

Lines changed: 84 additions & 109 deletions

File tree

flutter-candidate.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
ead0a01bb9707b60097679a43a6262a8979f4a89
1+
ea83a6a072990acc34c482d8e90f4d2bef713344

packages/devtools_app/lib/src/screens/performance/panes/queued_microtasks/queued_microtasks_controller.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ class QueuedMicrotasksController extends PerformanceFeatureController
2929
});
3030
}
3131

32+
ValueListenable<QueuedMicrotasksControllerStatus> get status => _status;
3233
final _status = ValueNotifier<QueuedMicrotasksControllerStatus>(
3334
QueuedMicrotasksControllerStatus.empty,
3435
);
35-
ValueListenable<QueuedMicrotasksControllerStatus> get status => _status;
3636

37-
final _queuedMicrotasks = ValueNotifier<QueuedMicrotasks?>(null);
3837
ValueListenable<QueuedMicrotasks?> get queuedMicrotasks => _queuedMicrotasks;
38+
final _queuedMicrotasks = ValueNotifier<QueuedMicrotasks?>(null);
3939

40-
final _selectedMicrotask = ValueNotifier<Microtask?>(null);
4140
ValueListenable<Microtask?> get selectedMicrotask => _selectedMicrotask;
41+
final _selectedMicrotask = ValueNotifier<Microtask?>(null);
4242

4343
final _refreshWorkTracker = FutureWorkTracker();
4444

packages/devtools_app/lib/src/screens/performance/panes/queued_microtasks/queued_microtasks_view.dart

Lines changed: 60 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
44

5+
import 'package:collection/collection.dart' show ListExtensions;
56
import 'package:devtools_app_shared/ui.dart';
67
import 'package:devtools_app_shared/utils.dart';
78
import 'package:flutter/material.dart';
@@ -12,28 +13,26 @@ import '../../../../shared/analytics/constants.dart' as gac;
1213
import '../../../../shared/primitives/utils.dart' show SortDirection;
1314
import '../../../../shared/table/table.dart' show FlatTable;
1415
import '../../../../shared/table/table_data.dart';
15-
import '../../../../shared/ui/common_widgets.dart' show RefreshButton;
16+
import '../../../../shared/ui/common_widgets.dart'
17+
show CenteredMessage, RefreshButton;
1618
import 'queued_microtasks_controller.dart';
1719

1820
class RefreshQueuedMicrotasksButton extends StatelessWidget {
19-
const RefreshQueuedMicrotasksButton({
20-
super.key,
21-
required QueuedMicrotasksController controller,
22-
}) : _controller = controller;
21+
const RefreshQueuedMicrotasksButton({super.key, required this.controller});
2322

24-
final QueuedMicrotasksController _controller;
23+
final QueuedMicrotasksController controller;
2524

2625
@override
2726
Widget build(BuildContext context) {
2827
return ValueListenableBuilder<QueuedMicrotasksControllerStatus>(
29-
valueListenable: _controller.status,
28+
valueListenable: controller.status,
3029
builder: (_, status, _) {
3130
return RefreshButton(
3231
iconOnly: true,
3332
outlined: false,
3433
onPressed: status == QueuedMicrotasksControllerStatus.refreshing
3534
? null
36-
: _controller.refresh,
35+
: controller.refresh,
3736
tooltip:
3837
"Take a new snapshot of the selected isolate's microtask queue.",
3938
gaScreen: gac.performance,
@@ -44,23 +43,6 @@ class RefreshQueuedMicrotasksButton extends StatelessWidget {
4443
}
4544
}
4645

47-
class QueuedMicrotasksTabControls extends StatelessWidget {
48-
const QueuedMicrotasksTabControls({
49-
super.key,
50-
required QueuedMicrotasksController controller,
51-
}) : _controller = controller;
52-
53-
final QueuedMicrotasksController _controller;
54-
55-
@override
56-
Widget build(BuildContext context) {
57-
return Row(
58-
mainAxisAlignment: MainAxisAlignment.end,
59-
children: [RefreshQueuedMicrotasksButton(controller: _controller)],
60-
);
61-
}
62-
}
63-
6446
class RefreshQueuedMicrotasksInstructions extends StatelessWidget {
6547
const RefreshQueuedMicrotasksInstructions({super.key});
6648

@@ -85,60 +67,52 @@ class RefreshQueuedMicrotasksInstructions extends StatelessWidget {
8567
}
8668
}
8769

88-
// In the response returned by the VM Service, microtasks are sorted in
89-
// ascending order of when they will be dequeued, i.e. the microtask that will
90-
// run earliest is at index 0 of the returned list. We use those indices of the
91-
// returned list to sort the entries of the microtask selector, so that they
92-
// they also appear in ascending order of when they will be dequeued.
93-
typedef IndexedMicrotask = (int, Microtask);
70+
/// In the response returned by the VM Service, microtasks are sorted in
71+
/// ascending order of when they will be dequeued, i.e. the microtask that will
72+
/// run earliest is at index 0 of the returned list. We use those indices of the
73+
/// returned list to sort the entries of the microtask selector, so that they
74+
/// they also appear in ascending order of when they will be dequeued.
75+
typedef IndexedMicrotask = ({int index, Microtask microtask});
9476

9577
class _MicrotaskIdColumn extends ColumnData<IndexedMicrotask> {
9678
_MicrotaskIdColumn()
9779
: super.wide('Microtask ID', alignment: ColumnAlignment.center);
9880

9981
@override
100-
int getValue(IndexedMicrotask indexedMicrotask) => indexedMicrotask.$1;
82+
int getValue(IndexedMicrotask indexedMicrotask) => indexedMicrotask.index;
10183

10284
@override
10385
String getDisplayValue(IndexedMicrotask indexedMicrotask) =>
104-
indexedMicrotask.$2.id!.toString();
86+
indexedMicrotask.microtask.id!.toString();
10587
}
10688

10789
class QueuedMicrotaskSelector extends StatelessWidget {
10890
const QueuedMicrotaskSelector({
10991
super.key,
11092
required List<IndexedMicrotask> indexedMicrotasks,
111-
required void Function(Microtask?) setSelectedMicrotask,
93+
required void Function(Microtask?) onMicrotaskSelected,
11294
}) : _indexedMicrotasks = indexedMicrotasks,
113-
_setSelectedMicrotask = setSelectedMicrotask;
95+
_setSelectedMicrotask = onMicrotaskSelected;
11496

11597
static final _idColumn = _MicrotaskIdColumn();
11698
final List<IndexedMicrotask> _indexedMicrotasks;
11799
final void Function(Microtask?) _setSelectedMicrotask;
118100

119101
@override
120-
Widget build(BuildContext context) => Column(
121-
crossAxisAlignment: CrossAxisAlignment.start,
122-
children: [
123-
Expanded(
124-
child: FlatTable<IndexedMicrotask>(
125-
keyFactory: (IndexedMicrotask microtask) =>
126-
ValueKey<int>(microtask.$1),
127-
data: _indexedMicrotasks,
128-
dataKey: 'queued-microtask-selector',
129-
columns: [_idColumn],
130-
defaultSortColumn: _idColumn,
131-
defaultSortDirection: SortDirection.ascending,
132-
onItemSelected: (indexedMicrotask) =>
133-
_setSelectedMicrotask(indexedMicrotask?.$2),
134-
),
135-
),
136-
],
102+
Widget build(BuildContext context) => FlatTable<IndexedMicrotask>(
103+
keyFactory: (IndexedMicrotask microtask) => ValueKey<int>(microtask.index),
104+
data: _indexedMicrotasks,
105+
dataKey: 'queued-microtask-selector',
106+
columns: [_idColumn],
107+
defaultSortColumn: _idColumn,
108+
defaultSortDirection: SortDirection.ascending,
109+
onItemSelected: (indexedMicrotask) =>
110+
_setSelectedMicrotask(indexedMicrotask?.microtask),
137111
);
138112
}
139113

140-
class StackTraceView extends StatelessWidget {
141-
const StackTraceView({super.key, required selectedMicrotask})
114+
class MicrotaskStackTraceView extends StatelessWidget {
115+
const MicrotaskStackTraceView({super.key, required selectedMicrotask})
142116
: _selectedMicrotask = selectedMicrotask;
143117

144118
final Microtask? _selectedMicrotask;
@@ -149,14 +123,11 @@ class StackTraceView extends StatelessWidget {
149123

150124
return Column(
151125
children: [
152-
SizedBox.fromSize(
153-
size: Size.fromHeight(defaultHeaderHeight),
154-
child: Container(
155-
decoration: BoxDecoration(
156-
border: Border(bottom: defaultBorderSide(theme)),
157-
),
158-
padding: const EdgeInsets.only(left: defaultSpacing),
159-
alignment: Alignment.centerLeft,
126+
Container(
127+
height: defaultHeaderHeight,
128+
padding: const EdgeInsets.only(left: defaultSpacing),
129+
alignment: Alignment.centerLeft,
130+
child: OutlineDecoration.onlyBottom(
160131
child: const Row(
161132
children: [
162133
Text('Stack trace captured when microtask was enqueued'),
@@ -207,20 +178,20 @@ class _QueuedMicrotasksTabViewState extends State<QueuedMicrotasksTabView>
207178
if (status == QueuedMicrotasksControllerStatus.empty) {
208179
return const RefreshQueuedMicrotasksInstructions();
209180
} else if (status == QueuedMicrotasksControllerStatus.refreshing) {
210-
return Center(
211-
child: Text(
212-
style: Theme.of(context).regularTextStyle,
213-
'Refreshing...',
214-
),
215-
);
181+
return const CenteredMessage(message: 'Refreshing...');
216182
} else {
217183
return ValueListenableBuilder(
218184
valueListenable: widget.controller.queuedMicrotasks,
219185
builder: (_, queuedMicrotasks, _) {
220186
assert(queuedMicrotasks != null);
221-
222-
final indexedMicrotasks = queuedMicrotasks!.microtasks!.indexed
223-
.cast<IndexedMicrotask>()
187+
if (queuedMicrotasks == null) {
188+
return const CenteredMessage(message: 'Unexpected null value');
189+
}
190+
191+
final indexedMicrotasks = queuedMicrotasks.microtasks!
192+
.mapIndexed(
193+
(index, microtask) => (index: index, microtask: microtask),
194+
)
224195
.toList();
225196
final formattedTimestamp = _dateTimeFormat.format(
226197
DateTime.fromMicrosecondsSinceEpoch(
@@ -244,25 +215,28 @@ class _QueuedMicrotasksTabViewState extends State<QueuedMicrotasksTabView>
244215
axis: Axis.horizontal,
245216
initialFractions: const [0.15, 0.85],
246217
children: [
247-
QueuedMicrotaskSelector(
248-
indexedMicrotasks: indexedMicrotasks,
249-
setSelectedMicrotask:
250-
widget.controller.setSelectedMicrotask,
218+
OutlineDecoration(
219+
child: QueuedMicrotaskSelector(
220+
indexedMicrotasks: indexedMicrotasks,
221+
onMicrotaskSelected:
222+
widget.controller.setSelectedMicrotask,
223+
),
251224
),
252225
ValueListenableBuilder(
253226
valueListenable: widget.controller.selectedMicrotask,
254227
builder: (_, selectedMicrotask, _) =>
255-
selectedMicrotask == null
256-
? const Center(
257-
child: Text(
258-
'Select a microtask ID on the left '
259-
'to see information about the '
260-
'corresponding microtask.',
261-
),
262-
)
263-
: StackTraceView(
264-
selectedMicrotask: selectedMicrotask,
265-
),
228+
OutlineDecoration(
229+
child: selectedMicrotask == null
230+
? const CenteredMessage(
231+
message:
232+
'Select a microtask ID on the left '
233+
'to see information about the '
234+
'corresponding microtask.',
235+
)
236+
: MicrotaskStackTraceView(
237+
selectedMicrotask: selectedMicrotask,
238+
),
239+
),
266240
),
267241
],
268242
),

packages/devtools_app/lib/src/screens/performance/tabbed_performance_view.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class _TabbedPerformanceViewState extends State<TabbedPerformanceView>
181181
(
182182
tab: _buildTab(
183183
tabName: 'Queued Microtasks',
184-
trailing: QueuedMicrotasksTabControls(
184+
trailing: RefreshQueuedMicrotasksButton(
185185
controller: controller.queuedMicrotasksController,
186186
),
187187
),

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const profiler = 'profiler';
1616
// Defined in SDK: https://github.com/dart-lang/sdk/blob/master/runtime/vm/profiler.cc#L36
1717
const profilePeriod = 'profile_period';
1818

19-
// Defined in SDK: https://github.com/dart-lang/sdk/blob/main/runtime/vm/microtask_mirror_queues.cc#L18-L23.
19+
// Defined in SDK: https://github.com/dart-lang/sdk/blob/main/runtime/vm/microtask_mirror_queues.cc.
2020
const profileMicrotasks = 'profile_microtasks';
2121

2222
class VmFlagManager with DisposerMixin {

packages/devtools_app/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ dependencies:
2222
collection: ^1.15.0
2323
dap: ^1.1.0
2424
dart_service_protocol_shared: ^0.0.3
25-
dds_service_extensions: ^2.0.0
25+
dds_service_extensions: ^2.0.2
2626
devtools_app_shared:
2727
devtools_extensions:
2828
devtools_shared:
@@ -53,7 +53,7 @@ dependencies:
5353
stack_trace: ^1.12.0
5454
string_scanner: ^1.4.0
5555
unified_analytics: ^7.0.0
56-
vm_service: '>=15.0.0 <16.0.0'
56+
vm_service: ^15.0.2
5757
vm_service_protos: ^1.0.0
5858
vm_snapshot_analysis: ^0.7.6
5959
web: ^1.0.0

packages/devtools_app/test/screens/performance/queued_microtasks/queued_microtasks_controller_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ void main() {
2828
});
2929

3030
test('refresh', () async {
31+
expect(controller.status.value, QueuedMicrotasksControllerStatus.empty);
32+
expect(controller.queuedMicrotasks.value, null);
33+
3134
await controller.refresh();
35+
3236
expect(controller.status.value, QueuedMicrotasksControllerStatus.ready);
3337
expect(controller.queuedMicrotasks.value, testQueuedMicrotasks);
3438
});

packages/devtools_app/test/screens/performance/tabbed_performance_view_test.dart

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ void main() {
3434
vmFlags: [
3535
(
3636
flagName: profileMicrotasks,
37-
value: shouldEnableMicrotaskProfiling ? 'true' : 'false',
37+
value: shouldEnableMicrotaskProfiling.toString(),
3838
),
3939
],
4040
),
@@ -260,11 +260,14 @@ void main() {
260260
final mockQueuedMicrotasksController =
261261
controller.queuedMicrotasksController
262262
as MockQueuedMicrotasksController;
263-
when(mockQueuedMicrotasksController.status).thenReturn(
264-
const FixedValueListenable<QueuedMicrotasksControllerStatus>(
265-
QueuedMicrotasksControllerStatus.empty,
266-
),
267-
);
263+
264+
final mockQueuedMicrotasksControllerStatus =
265+
ValueNotifier<QueuedMicrotasksControllerStatus>(
266+
QueuedMicrotasksControllerStatus.empty,
267+
);
268+
when(
269+
mockQueuedMicrotasksController.status,
270+
).thenReturn(mockQueuedMicrotasksControllerStatus);
268271

269272
await pumpView(tester);
270273

@@ -284,25 +287,19 @@ void main() {
284287
// Then, we verify that details about the queued microtasks are shown
285288
// when [controller.queuedMicrotasksController]'s status is ready.
286289

287-
when(mockQueuedMicrotasksController.status).thenReturn(
288-
const FixedValueListenable<QueuedMicrotasksControllerStatus>(
289-
QueuedMicrotasksControllerStatus.ready,
290-
),
291-
);
290+
mockQueuedMicrotasksControllerStatus.value =
291+
QueuedMicrotasksControllerStatus.ready;
292292
when(
293293
mockQueuedMicrotasksController.selectedMicrotask,
294294
).thenReturn(FixedValueListenable(testMicrotask));
295295
when(
296296
mockQueuedMicrotasksController.queuedMicrotasks,
297297
).thenReturn(FixedValueListenable(testQueuedMicrotasks));
298298

299-
await tester.tap(find.text('Timeline Events'));
300-
await tester.pumpAndSettle();
301-
await tester.tap(find.text('Queued Microtasks'));
302299
await tester.pumpAndSettle();
303300

304301
expect(find.byType(QueuedMicrotaskSelector), findsOneWidget);
305-
expect(find.byType(StackTraceView), findsOneWidget);
302+
expect(find.byType(MicrotaskStackTraceView), findsOneWidget);
306303
});
307304
},
308305
);

0 commit comments

Comments
 (0)