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

iOS PlatformViewsController needs to be more resilient when creating the same view multiple times. #125913

Open
cyanglaz opened this issue May 2, 2023 · 1 comment
Labels
a: platform-views Embedding Android/iOS views in Flutter apps engine flutter/engine repository. See also e: labels. P2 Important issues not at the top of the work list platform-ios iOS applications specifically team-ios Owned by iOS platform team triaged-ios Triaged by iOS platform team

Comments

@cyanglaz
Copy link
Contributor

cyanglaz commented May 2, 2023

Background

PlatformViews are created asynchronizely through method channel via a onCreate message.

OnCreate essentially constructs a UIView and put it in to the root_view_ map with an id. If the same id is "created" again, the root_view_[$id] is replaced with a newly constructed UIView.

Skip forward to how the root_views are ordered and added to the view tree, the logics are in BringLayersIntoView. We rely on the fact that [UIView addSubview] reorders the view to the top most if the subview is already in the view tree. See: https://github.com/flutter/engine/blob/main/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm#L786-L796. So it doesn't matter if the view is in the view tree, [UIView addSubvIew] takes care adding the view and putting the views at the correct order.

Bug

This causes a potential race condition. Consider the below situation:

root_view_[0] is viewA. And viewA is currently in the view tree, or in another word, a subview of flutter view.
OnCreate is called with id 0, viewB is created, root_view_[0] is changed from viewA to viewB.
During the same frame, BringLayersIntoView is going to get the view from root_view_[0], which is now viewB. Because the view representing id 0 was viewA, viewB is not in the view tree, [UIView addSubview] will add viewB to the view tree. And now we have both viewA and viewB representing id 0 in the view tree. The correct behavior is to only have viewB in this situation.

@cyanglaz
Copy link
Contributor Author

cyanglaz commented May 2, 2023

cc @hellohuanlin

@cyanglaz cyanglaz added platform-ios iOS applications specifically engine flutter/engine repository. See also e: labels. a: platform-views Embedding Android/iOS views in Flutter apps labels May 2, 2023
@cyanglaz cyanglaz self-assigned this May 3, 2023
@cyanglaz cyanglaz added the P1 High-priority issues at the top of the work list label May 3, 2023
@flutter-triage-bot flutter-triage-bot bot added multiteam-retriage-candidate team-ios Owned by iOS platform team triaged-ios Triaged by iOS platform team labels Jul 8, 2023
@cyanglaz cyanglaz added P2 Important issues not at the top of the work list and removed P1 High-priority issues at the top of the work list labels Jul 18, 2023
@cyanglaz cyanglaz removed their assignment Nov 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: platform-views Embedding Android/iOS views in Flutter apps engine flutter/engine repository. See also e: labels. P2 Important issues not at the top of the work list platform-ios iOS applications specifically team-ios Owned by iOS platform team triaged-ios Triaged by iOS platform team
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants