Skip to content

Commit bd2f846

Browse files
Show debug-mode message for widget rebuilds in profile mode (#9755)
When running in profile mode, the Performance panel showed a disabled 'Count widget builds' checkbox which was misleading. Widget rebuild counts rely on debugOnRebuildDirtyWidget which is only available in debug mode. This change: - Removes the checkbox when running in profile mode - Shows a clear message: 'Rebuild information is not available for this frame. Widget rebuild counts are only available when running an app in debug-mode.' - Adds widget tests for both profile mode and debug mode behavior Fixes #9730 --------- Co-authored-by: Sam Rawlins <srawlins@google.com>
1 parent fd39ed6 commit bd2f846

3 files changed

Lines changed: 85 additions & 11 deletions

File tree

‎packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ import '../../../../shared/ui/common_widgets.dart';
2020
import '../flutter_frames/flutter_frame_model.dart';
2121
import 'rebuild_stats_model.dart';
2222

23+
@visibleForTesting
24+
const debugModeOnlyMessage =
25+
'Rebuild information is not available for this frame.\n'
26+
'Widget rebuild counts are only available when running '
27+
'an app in debug mode.';
28+
2329
class RebuildStatsView extends StatefulWidget {
2430
const RebuildStatsView({
2531
super.key,
@@ -92,6 +98,12 @@ class _RebuildStatsViewState extends State<RebuildStatsView>
9298

9399
@override
94100
Widget build(BuildContext context) {
101+
final isProfileBuild =
102+
serviceConnection.serviceManager.connectedApp?.isProfileBuildNow ??
103+
false;
104+
if (isProfileBuild) {
105+
return const CenteredMessage(message: debugModeOnlyMessage);
106+
}
95107
return Column(
96108
crossAxisAlignment: CrossAxisAlignment.start,
97109
children: [

‎packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ To learn more about DevTools, check out the
3131
* Fixed a bug where the Flutter frames chart could appear frozen after
3232
switching away from the Performance screen and coming back.
3333
[#9960](https://github.com/flutter/devtools/pull/9960)
34+
* Added a message in the Performance panel when widget rebuild tracking is
35+
unavailable because the app is running in profile mode.
36+
[#9755](https://github.com/flutter/devtools/pull/9755)
3437

3538
## CPU profiler updates
3639

@@ -40,15 +43,16 @@ To learn more about DevTools, check out the
4043

4144
## Memory updates
4245

43-
* Added the ability to pin classes to the top of the Profile Memory table. [#8898](https://github.com/flutter/devtools/issues/8898)
46+
* Added the ability to pin classes to the top of the Profile Memory table.
47+
[#8898](https://github.com/flutter/devtools/issues/8898)
4448

4549
## Debugger updates
4650

47-
* Prevent values from being garbage-collected, while being evaluated.
51+
* Prevented values from being garbage-collected, while being evaluated.
4852
[#9885](https://github.com/flutter/devtools/pull/9885)
4953
* Update to latest version of the Dart syntax highlighting grammar
5054
[#9920](https://github.com/flutter/devtools/pull/9920).
51-
* Fix a bug in the TextMate grammar parser that could result in code after
55+
* Fixed a bug in the TextMate grammar parser that could result in code after
5256
comments being classified as comments.
5357
[#9921](https://github.com/flutter/devtools/pull/9921).
5458
* Fixed an overflow in the debugging controls when the Debugger screen is
@@ -70,7 +74,7 @@ To learn more about DevTools, check out the
7074

7175
## Logging updates
7276

73-
* Correct time units and cumulative nature of GC events.
77+
* Corrected time units and cumulative nature of GC events.
7478
[#9890](https://github.com/flutter/devtools/pull/9890)
7579
* Fixed a bug where long `dart:developer` log messages lost their structured
7680
Details view. -
@@ -83,7 +87,7 @@ TODO: Remove this section if there are not any updates.
8387
## Deep links tool updates
8488

8589
* Added a "Watch tutorial" link to the status line that points to the
86-
[deep links video tutorial](https://youtu.be/d7sZL6h1Elw).
90+
[deep links video tutorial](https://youtu.be/d7sZL6hIElw).
8791
[#9925](https://github.com/flutter/devtools/pull/9925)
8892

8993
## VS Code sidebar updates
@@ -92,12 +96,13 @@ TODO: Remove this section if there are not any updates.
9296

9397
## DevTools extension updates
9498

95-
* Hide the DevTools extensions menu button in single-screen embedded mode (`EmbedMode.embedOne`) on standard screens.
99+
* Hide the DevTools extensions menu button in single-screen embedded mode
100+
(`EmbedMode.embedOne`) on standard screens.
96101
[#8507](https://github.com/flutter/devtools/issues/8507)
97102
* Added iframe sandboxing for embedded DevTools extensions to enforce origin
98103
isolation. [#9967](https://github.com/flutter/devtools/pull/9967)
99-
* Improved DevTools extension isolation by tracking the providing package name for
100-
enablement, deduplication, and asset loading.
104+
* Improved DevTools extension isolation by tracking the providing package
105+
name for enablement, deduplication, and asset loading.
101106
[#9981](https://github.com/flutter/devtools/pull/9981)
102107

103108
## Advanced developer mode updates
@@ -107,4 +112,4 @@ TODO: Remove this section if there are not any updates.
107112
## Full commit history
108113

109114
To find a complete list of changes in this release, check out the
110-
[DevTools git log](https://github.com/flutter/devtools/tree/v2.61.0).
115+
[DevTools git log](https://github.com/flutter/devtools/tree/v2.61.0).

‎packages/devtools_app/test/screens/performance/performance_screen_test.dart‎

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'dart:async';
99

1010
import 'package:devtools_app/devtools_app.dart';
1111
import 'package:devtools_app/src/screens/performance/panes/controls/performance_controls.dart';
12+
import 'package:devtools_app/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart';
1213
import 'package:devtools_app/src/screens/performance/panes/timeline_events/timeline_events_view.dart';
1314
import 'package:devtools_app/src/screens/performance/tabbed_performance_view.dart';
1415
import 'package:devtools_app/src/shared/feature_flags.dart';
@@ -218,7 +219,6 @@ void main() {
218219
await tester.runAsync(() async {
219220
await pumpPerformanceScreen(tester, runAsync: true);
220221
await tester.pumpAndSettle();
221-
222222
final chartButtonFinder = find.byType(VisibilityButton);
223223
expect(chartButtonFinder, findsOneWidget);
224224

@@ -231,7 +231,6 @@ void main() {
231231

232232
await tester.tap(chartButtonFinder);
233233
await tester.pumpAndSettle();
234-
235234
// The flutter frames chart should no longer be visible.
236235
expect(find.byType(FramesChartControls), findsNothing);
237236
expect(
@@ -395,6 +394,64 @@ void main() {
395394
},
396395
);
397396
});
397+
398+
group('RebuildStatsView', () {
399+
late FakeServiceConnectionManager fakeServiceConnection;
400+
late RebuildCountModel model;
401+
late ValueNotifier<FlutterFrame?> selectedFrame;
402+
403+
setUp(() {
404+
fakeServiceConnection = FakeServiceConnectionManager();
405+
mockConnectedApp(fakeServiceConnection.serviceManager.connectedApp!);
406+
setGlobal(ServiceConnectionManager, fakeServiceConnection);
407+
setGlobal(IdeTheme, IdeTheme());
408+
setGlobal(NotificationService, NotificationService());
409+
setGlobal(BannerMessagesController, BannerMessagesController());
410+
setGlobal(PreferencesController, PreferencesController());
411+
setGlobal(OfflineDataController, OfflineDataController());
412+
model = RebuildCountModel();
413+
selectedFrame = ValueNotifier<FlutterFrame?>(null);
414+
});
415+
416+
testWidgets('shows message when running in profile mode', (
417+
WidgetTester tester,
418+
) async {
419+
mockConnectedApp(
420+
fakeServiceConnection.serviceManager.connectedApp!,
421+
isProfileBuild: true,
422+
);
423+
424+
await tester.pumpWidget(
425+
wrapWithControllers(
426+
RebuildStatsView(model: model, selectedFrame: selectedFrame),
427+
),
428+
);
429+
await tester.pump();
430+
431+
expect(
432+
find.textContaining('Widget rebuild counts are only available'),
433+
findsOneWidget,
434+
);
435+
});
436+
437+
testWidgets('shows normal UI when running in debug mode', (
438+
WidgetTester tester,
439+
) async {
440+
mockConnectedApp(fakeServiceConnection.serviceManager.connectedApp!);
441+
442+
await tester.pumpWidget(
443+
wrapWithControllers(
444+
RebuildStatsView(model: model, selectedFrame: selectedFrame),
445+
),
446+
);
447+
await tester.pump();
448+
449+
expect(
450+
find.textContaining('Widget rebuild counts are only available'),
451+
findsNothing,
452+
);
453+
});
454+
});
398455
});
399456
}
400457

0 commit comments

Comments
 (0)