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..41e64aae318 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 @@ -92,6 +92,19 @@ class _RebuildStatsViewState extends State @override Widget build(BuildContext context) { + final isProfileBuild = + serviceConnection.serviceManager.connectedApp?.isProfileBuildNow ?? + false; + if (isProfileBuild) { + return const Center( + child: Text( + 'Rebuild information is not available for this frame.\n' + 'Widget rebuild counts are only available when running ' + 'an app in debug-mode.', + textAlign: TextAlign.center, + ), + ); + } 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 05805dbad6f..77f15372264 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -23,7 +23,8 @@ TODO: Remove this section if there are not any updates. ## Performance updates -TODO: Remove this section if there are not any updates. +- Showed a message in the Performance panel when widget rebuild tracking was unavailable because the app was running in profile mode. + unavailable because the app is running in profile mode. [#9755](https://github.com/flutter/devtools/pull/9755) ## CPU profiler updates 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..f4c5493ec63 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,69 @@ void main() { }, ); }); + + group('RebuildStatsView', () { + late FakeServiceConnectionManager fakeServiceConnection; + late RebuildCountModel model; + late ValueNotifier selectedFrame; + + setUp(() { + fakeServiceConnection = FakeServiceConnectionManager(); + final app = fakeServiceConnection.serviceManager.connectedApp!; + when(app.initialized).thenReturn(Completer()..complete(true)); + when(app.isDartWebAppNow).thenReturn(false); + when(app.isFlutterAppNow).thenReturn(true); + when(app.isDartCliAppNow).thenReturn(false); + when(app.isDartWebApp).thenAnswer((_) async => false); + when(app.isProfileBuild).thenAnswer((_) async => false); + 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 { + final app = fakeServiceConnection.serviceManager.connectedApp!; + when(app.isProfileBuildNow).thenReturn(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 { + final app = fakeServiceConnection.serviceManager.connectedApp!; + when(app.isProfileBuildNow).thenReturn(false); + + await tester.pumpWidget( + wrapWithControllers( + RebuildStatsView(model: model, selectedFrame: selectedFrame), + ), + ); + await tester.pump(); + + expect( + find.textContaining('Widget rebuild counts are only available'), + findsNothing, + ); + }); + }); }); }