Skip to content

Fix stale "no timeline event analysis data" message in Frame Analysis tab - #10050

Open
ishaquehassan wants to merge 2 commits into
flutter:masterfrom
ishaquehassan:fix/9729-frame-analysis-stale-no-data-message
Open

ishaquehassan wants to merge 2 commits into
flutter:masterfrom
ishaquehassan:fix/9729-frame-analysis-stale-no-data-message

Conversation

@ishaquehassan

@ishaquehassan ishaquehassan commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #9729

The Frame Analysis tab renders frame.frameAnalysis, which stays null until timeline event data has been assigned to that FlutterFrame. FlutterFramesController.handleSelectedFrame publishes the selected frame right away and then loads the timeline events in the background, so when the events for the frame still have to be pulled from the VM, they land on the frame object after the tab has already been built. The frame instance itself never changes, so selectedFrame does not fire again and the tab keeps showing "No timeline event analysis data available for this frame." Selecting a different frame and coming back changes the notifier value, the tab rebuilds, and the analysis shows up, which is why the message is gone on the second visit.

This PR notifies selectedFrame listeners again from assignEventToFrame when the events are being assigned to the frame that is currently selected. I put it at the assignment site rather than after TimelineEventsController.handleSelectedFrame completes, because that method's processMoreEventsOrExitHelper is a fire-and-forget void ... async helper, so its returned future resolves before the forced refresh has produced any events. To re-notify without changing the value, _selectedFrameNotifier is now a small private ValueNotifier subclass with a notifyFrameDataChanged() method, because notifyListeners is @protected and @visibleForTesting on ChangeNotifier and calling it on a plain ValueNotifier from the controller is an analyzer warning. The current listeners are the performance tab view and the frames chart (both just setState) and RebuildStatsView (recomputes its metrics), so the extra notification only causes a rebuild with the same selection.

The new test in flutter_frames_controller_test.dart selects a frame that has no timeline events, checks that frameAnalysis is null, then assigns a UI event and checks that the notifier fired once and the analysis is now available. It also checks that assigning an event to a frame that is not selected does not notify. With the controller change reverted, it fails with Expected: <1> Actual: <0>. flutter test test/screens/performance/ passes 111/111, and dart analyze and dart format are clean on both changed Dart files.

Pre-launch Checklist

General checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read the Flutter Style Guide recently, and have followed its advice.
  • I signed the CLA.
  • I updated/added relevant documentation (doc comments with ///).

Issues checklist

Tests checklist

  • I added new tests to check the change I am making...
  • OR there is a reason for not adding tests, which I explained in the PR description.

AI-tooling checklist

  • I did not use any AI tooling in creating this PR.
  • OR I did use AI tooling, and...
    • I read the AI contributions guidelines and agree to follow them.
    • I reviewed all AI-generated code before opening this PR.
    • I understand and am able to discuss the code in this PR.
    • I have verifed the accuracy of any AI-generated text included in the PR description.
    • I commit to verifying the accuracy of any AI-generated code or text that I upload in response to review comments.

Feature-change checklist

  • This PR does not change the DevTools UI or behavior and...
    • I added the release-notes-not-required label or left a comment requesting the label be added.
  • OR this PR does change the DevTools UI or behavior and...
    • I added an entry to packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md.
    • I included before/after screenshots and/or a GIF demo of the new UI to my PR description.
    • I ran the DevTools app locally to manually verify my changes.

No screenshots since the layout doesn't change: the Frame Analysis tab already renders the analysis correctly once it rebuilds, the bug is only that the rebuild never happened. I haven't checked this against a running app, so for now the unit test above is what covers the behavior.

build.yaml badge

If you need help, consider asking for help on Discord.

… tab

The selected frame is published before its timeline events are loaded.
When the events have to be pulled from the VM they are assigned to the
same FlutterFrame instance later, so selectedFrame never fires again and
the Frame Analysis tab keeps showing the no-data message. Notify
selectedFrame listeners again when events are assigned to the selected
frame.

Fixes flutter#9729
@ishaquehassan
ishaquehassan requested review from a team and kenzieschmoll as code owners October 21, 2026 07:49
@ishaquehassan
ishaquehassan requested review from srawlins and removed request for a team October 21, 2026 07:49
@ishaquehassan
ishaquehassan marked this pull request as draft October 21, 2026 07:50

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a custom _SelectedFrameNotifier to trigger listener notifications when timeline event data is assigned to an already selected FlutterFrame, fixing a bug where the Frame Analysis tab would not update. It also adds a unit test and updates the release notes. The review feedback correctly identifies a potential crash if notifyListeners() is called after the notifier is disposed, and suggests adding a disposal guard.

Comment on lines +238 to +246
class _SelectedFrameNotifier extends ValueNotifier<FlutterFrame?> {
_SelectedFrameNotifier(super.value);

@override
// This override is needed to change visibility of the method.
void notifyListeners() {
super.notifyListeners();
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

[MUST-FIX] Calling notifyListeners() on a disposed ValueNotifier will throw an assertion error or exception. Since assignEventToFrame can be called asynchronously (e.g., when a pending timeline poll completes after the controller has been disposed), we should guard notifyListeners() to ensure it is not called after dispose().

Suggested change
class _SelectedFrameNotifier extends ValueNotifier<FlutterFrame?> {
_SelectedFrameNotifier(super.value);
@override
// This override is needed to change visibility of the method.
void notifyListeners() {
super.notifyListeners();
}
}
class _SelectedFrameNotifier extends ValueNotifier<FlutterFrame?> {
_SelectedFrameNotifier(super.value);
bool _disposed = false;
@override
void dispose() {
_disposed = true;
super.dispose();
}
@override
// This override is needed to change visibility of the method.
void notifyListeners() {
if (!_disposed) {
super.notifyListeners();
}
}
}

@ishaquehassan
ishaquehassan marked this pull request as ready for review October 21, 2026 09:18

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses an issue where the Frame Analysis tab displays a "No timeline event analysis data available" message if a frame is selected before its timeline events are fetched. It introduces a custom _SelectedFrameNotifier to allow notifying listeners when events are assigned to an already selected frame, and adds corresponding unit tests. The review feedback suggests formatting the release notes entry to keep the PR link on the same line as the text and ensuring it points to the pull request rather than the issue.

Comment thread packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md Outdated
/// Timeline event data can be assigned to a [FlutterFrame] after the frame has
/// been selected, so listeners need to be notified even when the selected
/// [FlutterFrame] instance itself has not changed.
class _SelectedFrameNotifier extends ValueNotifier<FlutterFrame?> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this class is introduced. It only contains a controller which passes the value to super, and overrides notifyListeners to call super. On the surface, it looks like a complete no-op from just using ValueNotifier<FlutterFrame?>.

@ishaquehassan ishaquehassan Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah fair, by itself it does look like a no-op. notifyListeners is @protected and @visibleForTesting on ChangeNotifier, so calling it on a plain ValueNotifier from the controller trips invalid_use_of_protected_member and analyze fails. the override was only there to re-expose it (same as ListValueNotifier), but agree that was too hidden, so i swapped it for a named notifyFrameDataChanged() and put the reason in the doc comment 👍

Replace the notifyListeners visibility override in _SelectedFrameNotifier with notifyFrameDataChanged, and document why the subclass is needed. Also link the release note entry to the PR.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Erroneous "No timeline event analysis data available for this frame"

2 participants