Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -92,6 +98,12 @@ class _RebuildStatsViewState extends State<RebuildStatsView>

@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: [
Expand Down
23 changes: 14 additions & 9 deletions packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ To learn more about DevTools, check out the
* Fixed a bug where the Flutter frames chart could appear frozen after
switching away from the Performance screen and coming back.
[#9960](https://github.com/flutter/devtools/pull/9960)
* 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

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

## Memory updates

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

## Debugger updates

* Prevent values from being garbage-collected, while being evaluated.
* Prevented 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
[#9920](https://github.com/flutter/devtools/pull/9920).
* Fix a bug in the TextMate grammar parser that could result in code after
* Fixed 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).
* Fixed an overflow in the debugging controls when the Debugger screen is
Expand All @@ -70,7 +74,7 @@ To learn more about DevTools, check out the

## Logging updates

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

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

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

## DevTools extension updates

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

## Advanced developer mode updates
Expand All @@ -107,4 +112,4 @@ 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).
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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);

Expand All @@ -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(
Expand Down Expand Up @@ -395,6 +394,64 @@ void main() {
},
);
});

group('RebuildStatsView', () {
late FakeServiceConnectionManager fakeServiceConnection;
late RebuildCountModel model;
late ValueNotifier<FlutterFrame?> 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<FlutterFrame?>(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,
);
});
});
});
}

Expand Down
Loading