Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes DialogRoute memory leak #147816

Merged
merged 9 commits into from May 16, 2024
Merged

Conversation

Dimilkalathiya
Copy link
Contributor

@Dimilkalathiya Dimilkalathiya commented May 4, 2024

part of #141198

  • Fixes memory leak on DialogRoute
  • Adds opt-in test

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. f: cupertino flutter/packages/flutter/cupertino repository labels May 4, 2024
Comment on lines 1585 to 1589
Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
_fadeCurve ??= CurvedAnimation(
parent: animation,
curve: Curves.easeOut,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible that buildTransitions is called a 2nd time with an animation parameter that is not the same as the one when it was first called? If yes, the CurvedAnimation _fadeCurve needs to be replaced with a new one to have the correct animation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for pointing it out, i have looked into abstract class ModalRoute and abstract class TransitionRoute and it initialises animation only once and it does not get replaced so using above code snippet is safe :)

@Dimilkalathiya
Copy link
Contributor Author

cc: @polina-c

@polina-c polina-c added a: leak tracking Issues and PRs related to memory leaks detected by leak_tracker autosubmit Merge PR when tree becomes green via auto submit App labels May 5, 2024
@polina-c
Copy link
Contributor

polina-c commented May 5, 2024

@chingjun , can you review to trigger google testing on this?

@polina-c polina-c requested a review from chingjun May 5, 2024 01:30
@auto-submit auto-submit bot removed the autosubmit Merge PR when tree becomes green via auto submit App label May 5, 2024
Copy link
Contributor

auto-submit bot commented May 5, 2024

auto label is removed for flutter/flutter/147816, due to This PR has not met approval requirements for merging. The PR author is not a member of flutter-hackers and needs 2 more review(s) in order to merge this PR.

  • Merge guidelines: A PR needs at least one approved review if the author is already part of flutter-hackers or two member reviews if the author is not a flutter-hacker before re-applying the autosubmit label. Reviewers: If you left a comment approving, please use the "approve" review action instead.

@chingjun
Copy link
Contributor

chingjun commented May 5, 2024

@polina-c when you approve the PR on github, does it trigger Google Testing?

Nope. Google Testing is triggered by autosubmit, that requires two reviews from maintainers. So, I need a second one.
It is ok not to trigger it for simple PRs. For this one I want it to be triggered.

chingjun
chingjun previously approved these changes May 5, 2024
Copy link
Contributor

@chingjun chingjun left a comment

Choose a reason for hiding this comment

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

RSLGTM to trigger Google Testing

@polina-c polina-c added the autosubmit Merge PR when tree becomes green via auto submit App label May 5, 2024
Copy link
Contributor

auto-submit bot commented May 5, 2024

auto label is removed for flutter/flutter/147816, due to - The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label.

@auto-submit auto-submit bot removed the autosubmit Merge PR when tree becomes green via auto submit App label May 5, 2024
@Dimilkalathiya
Copy link
Contributor Author

@polina-c it seems the Google test is failing can you provide a brief idea on what is Google test? And how should I be able to fix the test failing?

I saw logs and it says "Please contact a Google developer to investigate"

@polina-c
Copy link
Contributor

polina-c commented May 5, 2024

Google testing is testing of the change for internal Google projects. Its failure means one of two:

  1. The change introduced a bug to Flutter, and public test coverage is not good enough to catch it. So, we need to fix the bug and maybe add some test coverage.
  2. The internal project is using Flutter in a wrong way and should be fixed.

I checked logs. There is no failures in Flutter code, but there is change of behavior of an application: widget that is expected to be visible, is not.
Unfortunately, I cannot share more details.

Is it possible to fix the leak with less changes to the original code? Without overriding buildTransitions?

@Dimilkalathiya
Copy link
Contributor Author

I see, unfortunately we need to override for disposing CurvedAnimation properly

The previous widget function was outside of class and the curved animation was getting used inside directly so there was no way to dispose it properly

But I'll try to come up with a better solution, and test-out other options

Also if I push code with changes will Google test now re-run itself? Or we have to manually trigger it again?

@polina-c
Copy link
Contributor

polina-c commented May 5, 2024

I see, unfortunately we need to override for disposing CurvedAnimation properly

The previous widget function was outside of class and the curved animation was getting used inside directly so there was no way to dispose it properly

But I'll try to come up with a better solution, and test-out other options

Also if I push code with changes will Google test now re-run itself? Or we have to manually trigger it again?

Thanks for explanation.
To be clear, I am not confident that your change is wrong. It may be that application is doing something wrong. We just do not know.

Can you explain why override is needed? Why the methid cannot be just moved inside and the animation stored as a new member variable?

I think google testing will re-run, but I can be wrong.

@Dimilkalathiya
Copy link
Contributor Author

Previous implementation was passing the widget function into the super constructor so handling variable initialisation and disposal was not possible since we can't initialise them while not constructed.

So the best solution i thought was to override it.

@polina-c
Copy link
Contributor

polina-c commented May 6, 2024

How about

  1. Putting the builder into separate class like _DialogRouteAnimation, that would also hold the instance of the CurvedAnimation.

  2. Creating private constructor like

DialogRoute._(this._animation, {required super.pageBuilder, super.barrierLabel, super.transitionDuration,  super.transitionBuilder, ... });
  1. Converting existing constructor to factory constructor:
factory DialogRoute({
...
  }) {
    final animation = _DialogRouteAnimation();
    return DialogRoute._(animation,
         transitionBuilder: animation.buildMaterialDialogTransitions,
...

Then you will be able to dispose the animation:

  @override
  void dispose() {
    _animation.dispose();
    super.dispose();
  }

I hope this will preserve existing functionality better, and app behavior will not change.

@Dimilkalathiya
Copy link
Contributor Author

Seems like an awesome idea, I'll try this

@Dimilkalathiya
Copy link
Contributor Author

@polina-c seems like it's not related to override logic as the test is still failing.

I am still not sure, I think it's most likely a new animation handling snippet.

Since now the google test will initiate automatically, I'll test-out some ideas I have.

@chingjun chingjun dismissed their stale review May 7, 2024 05:27

Revoke approval to prevent Google Testing from being triggered automatically.

@chingjun
Copy link
Contributor

chingjun commented May 7, 2024

Revoking approval on "Google Testing" since changes are supposed to be reviewed by Googlers before Google Testing can be initiated. It wouldn't be useful without a way to see the actual result anyway.

I just looked at the test result, I think your latest change has fixed the original issue. The test that used to fail has now passed.

But it is introducing new error for classes that extends DialogRoute<T>, now that the constructor has become a factory.

Something that looks like:

class SubDialogRoute<T> extends DialogRoute<T> {
  SubDialogRoute({
    required BuildContext context,
    required WidgetBuilder builder,
    CapturedThemes? themes,
    Color? barrierColor,
    bool barrierDismissible = true,
    String? barrierLabel,
    bool useSafeArea = true,
    RouteSettings? settings,
  }) : super(
          context: context,
          builder: builder,
          themes: themes,
          barrierColor: barrierColor,
          barrierDismissible: barrierDismissible,
          barrierLabel: barrierLabel,
          useSafeArea: useSafeArea,
          settings: settings,
        );
}

Will now trigger a compiler error:

ERROR: xxx.dart:xx
The generative constructor 'DialogRoute<T> DialogRoute({required BuildContext context, required Widget Function(BuildContext) builder, CapturedThemes? themes, Color? barrierColor = Colors.black54, bool barrierDismissible = true, String? barrierLabel, bool useSafeArea = true, RouteSettings? settings, Offset? anchorPoint, TraversalEdgeBehavior? traversalEdgeBehavior})' is expected, but a factory was found. #non_generative_constructor

  }) : super(
       ^^^^^^


xxx.dart:xxx: Error: Superclass has no constructor named 'DialogRoute'.
  }) : super(
       ^^^^^

@Dimilkalathiya
Copy link
Contributor Author

@chingjun @polina-c I see it's bit tricky, if we override buildTransitions it does not display a widget that should be visible, Adding factory constructor fixed this issue but that mean it will break any other class that extends to DialogRoute

How about if we make override less invasive?

previously we were overriding entire widget which may have been cause of missing widget?

instead of:

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    _fadeCurve ??= CurvedAnimation(
      parent: animation,
      curve: Curves.easeOut,
    );
   return FadeTransition(
      opacity: _fadeCurve!,
      child: child,
    );
  }

we could try this:

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    _fadeCurve ??= CurvedAnimation(
      parent: animation,
      curve: Curves.easeOut,
    );
   return FadeTransition(
      opacity: _fadeCurve!,
      child: super.buildTransitions(context, animation, secondaryAnimation, child),
    );
  }

Let me know if we have better way to handle it or if above mentioned solution worth try. :)

}
}
/// Holds [DialogRoute] animation curves.
class _DialogRouteAnimation {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you move this class to the place of the method? It will make code review easier.

class _DialogRouteAnimation {
_DialogRouteAnimation();
CurvedAnimation? _fadeCurve;

Copy link
Contributor

Choose a reason for hiding this comment

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

Indentation issues.

CurvedAnimation? _fadeCurve;

Widget buildMaterialDialogTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
_fadeCurve ??= CurvedAnimation(parent: animation, curve: Curves.easeOut);
Copy link
Contributor

Choose a reason for hiding this comment

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

What if previously created _fadeCurve used different animation. Should we check the equality somehow and recreate _fadeCurve, if it is different?

@polina-c
Copy link
Contributor

polina-c commented May 7, 2024

@chingjun , it is good learning that change of type of constructor is a breaking change. Thanks.

Okay, as we got failure, my previous comments are not relevant.
We can give a try to what you, @Dimilkalathiya , suggest. Let's see how it works.

@Dimilkalathiya
Copy link
Contributor Author

@chingjun @polina-c Google test is passing now

@polina-c polina-c merged commit 0d22d91 into flutter:master May 16, 2024
72 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 16, 2024
auto-submit bot pushed a commit to flutter/packages that referenced this pull request May 16, 2024
flutter/flutter@39651e8...0d22d91

2024-05-16 [email protected] fixes `DialogRoute` memory leak (flutter/flutter#147816)
2024-05-16 [email protected] Roll Flutter Engine from 9bc449ee2e8b to 460df6caef0e (1 revision) (flutter/flutter#148476)
2024-05-16 [email protected] Roll Flutter Engine from 1ebad3a6179d to 9bc449ee2e8b (1 revision) (flutter/flutter#148469)
2024-05-16 [email protected] Roll Flutter Engine from 9e17588b330c to 1ebad3a6179d (1 revision) (flutter/flutter#148465)
2024-05-16 [email protected] ThemeData minor spring cleaning (flutter/flutter#148408)
2024-05-16 [email protected] Marks Mac_pixel_7pro native_assets_android to be flaky (flutter/flutter#148403)
2024-05-16 [email protected] plugin_ffi template comment fix (flutter/flutter#148378)
2024-05-16 [email protected] Roll Flutter Engine from 942d7c35de75 to 9e17588b330c (2 revisions) (flutter/flutter#148455)
2024-05-16 [email protected] Reland fix TextField helper top padding on M3 (flutter/flutter#146754)
2024-05-16 [email protected] Removing duplicate assert on `VisualDensity` constructor (flutter/flutter#148281)
2024-05-16 [email protected] Roll Flutter Engine from 65ac4bf96ed7 to 942d7c35de75 (1 revision) (flutter/flutter#148450)
2024-05-16 [email protected] Roll Flutter Engine from c11d64be5102 to 65ac4bf96ed7 (3 revisions) (flutter/flutter#148448)
2024-05-16 [email protected] Roll Flutter Engine from f6195e9d4b4b to c11d64be5102 (1 revision) (flutter/flutter#148445)
2024-05-16 [email protected] Roll Flutter Engine from cd150986ae63 to f6195e9d4b4b (2 revisions) (flutter/flutter#148441)
2024-05-15 [email protected] Fix leaky tests. (flutter/flutter#148434)
2024-05-15 [email protected] Roll Flutter Engine from 41b86b59f0ab to cd150986ae63 (2 revisions) (flutter/flutter#148430)
2024-05-15 [email protected] Roll Flutter Engine from bf1c6da0dd31 to 41b86b59f0ab (15 revisions) (flutter/flutter#148428)
2024-05-15 [email protected] Update _handlePushRouteInformation to Future<bool>  to indicate whether any of the observer has handled the route or not (flutter/flutter#147901)
2024-05-15 [email protected] Fix memory leaks in `_PopupMenuRoute` (flutter/flutter#148373)
2024-05-15 [email protected] Add `clipBehavior` to `DrawerThemeData` (flutter/flutter#148061)
2024-05-15 [email protected] Reland Native ios context menu (#143002) (#148238) (flutter/flutter#148265)
2024-05-15 [email protected] Roll Packages from fd714bd to 87a02e3 (8 revisions) (flutter/flutter#148419)
2024-05-15 [email protected] Stop running module_test_ios in devicelab and x64 Macs (flutter/flutter#148264)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
TecHaxter pushed a commit to TecHaxter/flutter_packages that referenced this pull request May 22, 2024
…r#6748)

flutter/flutter@39651e8...0d22d91

2024-05-16 [email protected] fixes `DialogRoute` memory leak (flutter/flutter#147816)
2024-05-16 [email protected] Roll Flutter Engine from 9bc449ee2e8b to 460df6caef0e (1 revision) (flutter/flutter#148476)
2024-05-16 [email protected] Roll Flutter Engine from 1ebad3a6179d to 9bc449ee2e8b (1 revision) (flutter/flutter#148469)
2024-05-16 [email protected] Roll Flutter Engine from 9e17588b330c to 1ebad3a6179d (1 revision) (flutter/flutter#148465)
2024-05-16 [email protected] ThemeData minor spring cleaning (flutter/flutter#148408)
2024-05-16 [email protected] Marks Mac_pixel_7pro native_assets_android to be flaky (flutter/flutter#148403)
2024-05-16 [email protected] plugin_ffi template comment fix (flutter/flutter#148378)
2024-05-16 [email protected] Roll Flutter Engine from 942d7c35de75 to 9e17588b330c (2 revisions) (flutter/flutter#148455)
2024-05-16 [email protected] Reland fix TextField helper top padding on M3 (flutter/flutter#146754)
2024-05-16 [email protected] Removing duplicate assert on `VisualDensity` constructor (flutter/flutter#148281)
2024-05-16 [email protected] Roll Flutter Engine from 65ac4bf96ed7 to 942d7c35de75 (1 revision) (flutter/flutter#148450)
2024-05-16 [email protected] Roll Flutter Engine from c11d64be5102 to 65ac4bf96ed7 (3 revisions) (flutter/flutter#148448)
2024-05-16 [email protected] Roll Flutter Engine from f6195e9d4b4b to c11d64be5102 (1 revision) (flutter/flutter#148445)
2024-05-16 [email protected] Roll Flutter Engine from cd150986ae63 to f6195e9d4b4b (2 revisions) (flutter/flutter#148441)
2024-05-15 [email protected] Fix leaky tests. (flutter/flutter#148434)
2024-05-15 [email protected] Roll Flutter Engine from 41b86b59f0ab to cd150986ae63 (2 revisions) (flutter/flutter#148430)
2024-05-15 [email protected] Roll Flutter Engine from bf1c6da0dd31 to 41b86b59f0ab (15 revisions) (flutter/flutter#148428)
2024-05-15 [email protected] Update _handlePushRouteInformation to Future<bool>  to indicate whether any of the observer has handled the route or not (flutter/flutter#147901)
2024-05-15 [email protected] Fix memory leaks in `_PopupMenuRoute` (flutter/flutter#148373)
2024-05-15 [email protected] Add `clipBehavior` to `DrawerThemeData` (flutter/flutter#148061)
2024-05-15 [email protected] Reland Native ios context menu (#143002) (#148238) (flutter/flutter#148265)
2024-05-15 [email protected] Roll Packages from fd714bd to 87a02e3 (8 revisions) (flutter/flutter#148419)
2024-05-15 [email protected] Stop running module_test_ios in devicelab and x64 Macs (flutter/flutter#148264)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: leak tracking Issues and PRs related to memory leaks detected by leak_tracker f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants