Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Conversation

@amirh
Copy link
Contributor

@amirh amirh commented Aug 9, 2019

Description

Works around an Android WebView bug that was causing a crash by filtering some DisplayListener invocations.

Older Android WebView versions had assumed that when DisplayListener#onDisplayChanged is invoked, the display ID it is provided is of a valid display. However it turns out that when a display is removed Android may call onDisplayChanged with the ID of the removed display, in this case the Android WebView code tries to fetch and use the display with this ID and crashes with an NPE.

The issue was fixed in the Android WebView code in https://chromium-review.googlesource.com/517913 which is available starting WebView version 58.0.3029.125 however older webviews in the wild still have this issue.

Since Flutter removes virtual displays whenever a platform view is resized the webview crash is more likely to happen than other apps. And users were reporting this issue see: flutter/flutter#30420

This change works around the webview bug by unregistering the WebView's DisplayListener, and instead registering our own DisplayListener which delegates the callbacks to the WebView's listener unless it's a onDisplayChanged for an invalid display.

Related Issues

Fixes flutter/flutter#30420

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • My PR includes unit or integration tests for all changed/updated/fixed behaviors (See [Contributor Guide]).
  • All existing and new tests are passing.
  • I updated/added relevant documentation (doc comments with ///).
  • The analyzer (flutter analyze) does not report any problems on my PR.
  • I read and followed the [Flutter Style Guide].
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I updated pubspec.yaml with an appropriate new version according to the [pub versioning philosophy].
  • I updated CHANGELOG.md to add a description of the change.
  • I signed the [CLA].
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require plugin users to manually update their apps to accommodate your change?

  • Yes, this is a breaking change (please indicate a breaking change in CHANGELOG.md and increment major revision).
  • No, this is not a breaking change.

@mklim mklim self-assigned this Aug 9, 2019
Copy link
Contributor

@mklim mklim left a comment

Choose a reason for hiding this comment

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

LGTM


/** Should be called prior to the webview's initialization. */
void onPreWebViewInitialization(DisplayManager displayManager) {
listenersBeforeWebView = yoinkDisplayListeners(displayManager);
Copy link
Contributor

Choose a reason for hiding this comment

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

😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Learned from the best 😄

/** Should be called after the webview's initialization. */
void onPostWebViewInitialization(final DisplayManager displayManager) {
final ArrayList<DisplayListener> listeners = yoinkDisplayListeners(displayManager);
// We recorded
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Is this comment incomplete?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oops, completed it.

name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: The changes in this file look like they could be reverted.

@amirh amirh merged commit 40ef139 into flutter:master Aug 9, 2019
@amirh amirh deleted the investigate_display_npe branch August 9, 2019 23:35
sungmin-park pushed a commit to sungmin-park/flutter-plugins that referenced this pull request Dec 17, 2019
…er#1964)

Works around an Android WebView bug that was causing a crash by filtering some DisplayListener invocations.

Older Android WebView versions had assumed that when DisplayListener#onDisplayChanged is invoked, the display ID it is provided is of a valid display. However it turns out that when a display is removed Android may call onDisplayChanged with the ID of the removed display, in this case the Android WebView code tries to fetch and use the display with this ID and crashes with an NPE.

The issue was fixed in the Android WebView code in https://chromium-review.googlesource.com/517913 which is available starting WebView version 58.0.3029.125 however older webviews in the wild still have this issue.

Since Flutter removes virtual displays whenever a platform view is resized the webview crash is more likely to happen than other apps. And users were reporting this issue see: flutter/flutter#30420

This change works around the webview bug by unregistering the WebView's DisplayListener, and instead registering our own DisplayListener which delegates the callbacks to the WebView's listener unless it's a onDisplayChanged for an invalid display.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

webview_flutter crash: Attempt to invoke virtual method 'void android.view.Display.getSize(android.graphics.Point)' on a null object reference

3 participants