Skip to content

Fix Android platform view creation flow#109232

Merged
auto-submit[bot] merged 2 commits intoflutter:masterfrom
stuartmorgan-g:android-platform-view-double-create
Aug 11, 2022
Merged

Fix Android platform view creation flow#109232
auto-submit[bot] merged 2 commits intoflutter:masterfrom
stuartmorgan-g:android-platform-view-double-create

Conversation

@stuartmorgan-g
Copy link
Contributor

Fixes regressions from #101399:

  • For Hybrid Composition, there is a common race where create will be
    called by the PlatformViewLink even though it has already been
    successfully called by the plugin itself. This causes exceptions on
    use of many Hybrid Composition plugins, and blocks adopting the new
    forced-HC mode in the google_maps_flutter plugin, for instance.
  • The documented behavior of AndroidViewController, which is that
    setSize would create it on demand, was removed. That logic had been
    moved to an internal call site in the referenced PR, but there may have
    been public callers expecting that behavior as well so it's better to keep
    the logic in the code documented to have that behavior.

Fixes (at least part of) #107297

Pre-launch 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 and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

Fixes regressions from flutter#101399:
- For Hybrid Composition, there is a common race where `create` will be
  called by the `PlatformViewLink` even though it has already been
  successfully called by the plugin itself. This causes exceptions on
  use of many Hybrid Composition plugins, and blocks adopting the new
  forced-HC mode in the google_maps_flutter plugin, for instance.
- The documented behavior of `AndroidViewController`, which is that
  `setSize` would create it on demand, was removed. That logic had been
  moved to an internal call site, but there may have been public callers
  expecting that behavior as well so it's better to keep the logic in
  the code documented to have that behavior.

Part of flutter#107297
@flutter-dashboard flutter-dashboard bot added the framework flutter/packages/flutter repository. See also f: labels. label Aug 9, 2022
@stuartmorgan-g
Copy link
Contributor Author

@cyanglaz You reviewed the initial PR, so if you could do the primary review that would be great since you have the most context.

@bparrishMines @dnfield If either or both of you could take a look that would be great. This is fixing a regression on beta, so will need to be cherry-picked, so extra eyes certainly wouldn't hurt.

// Depending on the implementation, the initial size can be used to size
// the platform view.
return _PlatformViewPlaceHolder(onLayout: (Size size) {
if (controller.awaitingCreation) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change (and the new awaitCreation logic) is the core of the fix. Hybrid Composition was pretty broken because plugins call create is called in the initial view build, per our docs, and if onLayout here fired before that async operation was completed (which is when _platformViewCreated will actually change, down in _onPlatformViewCreated), then it would start a second call to create.

TLHC and VD weren't affected by this because the initial create doesn't have a size, and thus in those implementations doesn't do anything.

Size targetSize;
do {
targetSize = size;
if (_viewController.isCreated) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This conditional logic moved back into setSize, so no longer needed to exist here.

Copy link
Contributor

Choose a reason for hiding this comment

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

consider adding an assert, e.g. assert(_viewController.isCreated); // created in setSize

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm pretty sure that's not a valid assertion, for the same reason that you had added the _isDisposed check just after create in the code I'm removing: setSize is guaranteed to start creating it if necessary, but there's no guarantee that it's not then disposed later in the await.

Copy link
Contributor

@dnfield dnfield left a comment

Choose a reason for hiding this comment

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

LGTM with nit

Size targetSize;
do {
targetSize = size;
if (_viewController.isCreated) {
Copy link
Contributor

Choose a reason for hiding this comment

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

consider adding an assert, e.g. assert(_viewController.isCreated); // created in setSize

Copy link
Contributor

@cyanglaz cyanglaz left a comment

Choose a reason for hiding this comment

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

LGTM

@cyanglaz
Copy link
Contributor

This is reverted at #109389 due to an internal test failure

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

Labels

autosubmit Merge PR when tree becomes green via auto submit App framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants