diff --git a/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart b/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart index a19d2502276..6b7ec334148 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart @@ -20,6 +20,12 @@ import '../../../../shared/ui/common_widgets.dart'; import '../flutter_frames/flutter_frame_model.dart'; import 'rebuild_stats_model.dart'; +@visibleForTesting +const debugModeOnlyMessage = + 'Rebuild information is not available for this frame.\n' + 'Widget rebuild counts are only available when running ' + 'an app in debug mode.'; + class RebuildStatsView extends StatefulWidget { const RebuildStatsView({ super.key, @@ -92,6 +98,12 @@ class _RebuildStatsViewState extends State @override Widget build(BuildContext context) { + final isProfileBuild = + serviceConnection.serviceManager.connectedApp?.isProfileBuildNow ?? + false; + if (isProfileBuild) { + return const CenteredMessage(message: debugModeOnlyMessage); + } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index 2d797c8109e..be9c11b9c56 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -5,38 +5,25 @@ found in the LICENSE file or at https://developers.google.com/open-source/licens --> This is a draft for future release notes that are going to land on [the Flutter website](https://docs.flutter.dev/tools/devtools/release-notes). - # DevTools 2.61.0 release notes - The 2.61.0 release of the Dart and Flutter DevTools includes the following changes among other general improvements. To learn more about DevTools, check out the [DevTools overview](/tools/devtools). - ## General updates - TODO: Remove this section if there are not any updates. - ## Inspector updates - TODO: Remove this section if there are not any updates. - ## Performance updates - -TODO: Remove this section if there are not any updates. - +- Added a message in the Performance panel when widget rebuild tracking is + unavailable because the app is running in profile mode. [#9755](https://github.com/flutter/devtools/pull/9755) ## CPU profiler updates - * Fixed a bug where resizing the CPU flame chart changes the timing values across the top of the chart. [#9915](https://github.com/flutter/devtools/pull/9915) - ## Memory updates - TODO: Remove this section if there are not any updates. - ## Debugger updates - * Prevent values from being garbage-collected, while being evaluated. [#9885](https://github.com/flutter/devtools/pull/9885) * Update to latest version of the Dart syntax highlighting grammar @@ -44,38 +31,22 @@ TODO: Remove this section if there are not any updates. * Fix a bug in the TextMate grammar parser that could result in code after comments being classified as comments. [#9921](https://github.com/flutter/devtools/pull/9921). - ## Network profiler updates - * Fixed exported response status in HAR files so that they parse as integers instead of strings. [#9900](https://github.com/flutter/devtools/pull/9900) - ## Logging updates - * Correct time units and cumulative nature of GC events. [#9890](https://github.com/flutter/devtools/pull/9890) - ## App size tool updates - TODO: Remove this section if there are not any updates. - ## Deep links tool updates - TODO: Remove this section if there are not any updates. - ## VS Code sidebar updates - TODO: Remove this section if there are not any updates. - ## DevTools extension updates - TODO: Remove this section if there are not any updates. - ## Advanced developer mode updates - TODO: Remove this section if there are not any updates. - ## Full commit history - To find a complete list of changes in this release, check out the -[DevTools git log](https://github.com/flutter/devtools/tree/v2.61.0). +[DevTools git log](https://github.com/flutter/devtools/tree/v2.61.0). \ No newline at end of file diff --git a/packages/devtools_app/test/screens/performance/performance_screen_test.dart b/packages/devtools_app/test/screens/performance/performance_screen_test.dart index 6f23218ee51..667169b67fd 100644 --- a/packages/devtools_app/test/screens/performance/performance_screen_test.dart +++ b/packages/devtools_app/test/screens/performance/performance_screen_test.dart @@ -9,6 +9,7 @@ import 'dart:async'; import 'package:devtools_app/devtools_app.dart'; import 'package:devtools_app/src/screens/performance/panes/controls/performance_controls.dart'; +import 'package:devtools_app/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart'; import 'package:devtools_app/src/screens/performance/panes/timeline_events/timeline_events_view.dart'; import 'package:devtools_app/src/screens/performance/tabbed_performance_view.dart'; import 'package:devtools_app/src/shared/feature_flags.dart'; @@ -218,7 +219,6 @@ void main() { await tester.runAsync(() async { await pumpPerformanceScreen(tester, runAsync: true); await tester.pumpAndSettle(); - final chartButtonFinder = find.byType(VisibilityButton); expect(chartButtonFinder, findsOneWidget); @@ -231,7 +231,6 @@ void main() { await tester.tap(chartButtonFinder); await tester.pumpAndSettle(); - // The flutter frames chart should no longer be visible. expect(find.byType(FramesChartControls), findsNothing); expect( @@ -252,46 +251,6 @@ void main() { }, ); - // testWidgetsWithWindowSize( - // 'clears timeline on clear', - // windowSize, - // (WidgetTester tester) async { - // await tester.runAsync(() async { - // await pumpPerformanceScreen(tester, runAsync: true); - // await tester.pumpAndSettle(); - - // // Ensure the Timeline Events tab is selected. - // final timelineEventsTabFinder = find.text('Timeline Events'); - // expect(timelineEventsTabFinder, findsOneWidget); - // await tester.tap(timelineEventsTabFinder); - // await tester.pumpAndSettle(); - - // expect( - // controller.timelineEventsController.allTraceEvents, - // isNotEmpty, - // ); - // expect(find.byType(FlutterFramesChart), findsOneWidget); - // expect(find.byType(TimelineFlameChart), findsOneWidget); - // expect( - // find.byKey(TimelineEventsView.emptyTimelineKey), - // findsNothing, - // ); - // expect(find.byType(EventDetails), findsOneWidget); - - // await tester.tap(find.byIcon(Icons.block)); - // await tester.pumpAndSettle(); - // expect(controller.timelineEventsController.allTraceEvents, isEmpty); - // expect(find.byType(FlutterFramesChart), findsOneWidget); - // expect(find.byType(TimelineFlameChart), findsNothing); - // expect( - // find.byKey(TimelineEventsView.emptyTimelineKey), - // findsOneWidget, - // ); - // expect(find.byType(EventDetails), findsNothing); - // }); - // }, - // ); - testWidgetsWithWindowSize('opens enhance tracing overlay', windowSize, ( WidgetTester tester, ) async { @@ -395,6 +354,64 @@ void main() { }, ); }); + + group('RebuildStatsView', () { + late FakeServiceConnectionManager fakeServiceConnection; + late RebuildCountModel model; + late ValueNotifier selectedFrame; + + setUp(() { + fakeServiceConnection = FakeServiceConnectionManager(); + mockConnectedApp(fakeServiceConnection.serviceManager.connectedApp!); + setGlobal(ServiceConnectionManager, fakeServiceConnection); + setGlobal(IdeTheme, IdeTheme()); + setGlobal(NotificationService, NotificationService()); + setGlobal(BannerMessagesController, BannerMessagesController()); + setGlobal(PreferencesController, PreferencesController()); + setGlobal(OfflineDataController, OfflineDataController()); + model = RebuildCountModel(); + selectedFrame = ValueNotifier(null); + }); + + testWidgets('shows message when running in profile mode', ( + WidgetTester tester, + ) async { + mockConnectedApp( + fakeServiceConnection.serviceManager.connectedApp!, + isProfileBuild: true, + ); + + await tester.pumpWidget( + wrapWithControllers( + RebuildStatsView(model: model, selectedFrame: selectedFrame), + ), + ); + await tester.pump(); + + expect( + find.textContaining('Widget rebuild counts are only available'), + findsOneWidget, + ); + }); + + testWidgets('shows normal UI when running in debug mode', ( + WidgetTester tester, + ) async { + mockConnectedApp(fakeServiceConnection.serviceManager.connectedApp!); + + await tester.pumpWidget( + wrapWithControllers( + RebuildStatsView(model: model, selectedFrame: selectedFrame), + ), + ); + await tester.pump(); + + expect( + find.textContaining('Widget rebuild counts are only available'), + findsNothing, + ); + }); + }); }); }