-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fix(WebViewClientDelegate): supply non-null favicon placeholder to delegates (#490) #1083
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
base: androidx
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -68,13 +68,43 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request | |||||||||||||
| return super.shouldOverrideUrlLoading(view, request); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * One-pixel transparent placeholder used in place of a null favicon when | ||||||||||||||
| * forwarding {@link #onPageStarted(WebView, String, Bitmap)} to a delegate | ||||||||||||||
| * whose Kotlin signature declares favicon as a non-null {@code Bitmap}. | ||||||||||||||
| * Allocated lazily so there is no cost when the platform supplies a real | ||||||||||||||
| * favicon. See issue #490. | ||||||||||||||
| */ | ||||||||||||||
| private static volatile Bitmap sFaviconPlaceholder; | ||||||||||||||
|
|
||||||||||||||
| private static Bitmap faviconPlaceholder() { | ||||||||||||||
| Bitmap placeholder = sFaviconPlaceholder; | ||||||||||||||
| if (placeholder == null) { | ||||||||||||||
| synchronized (WebViewClientDelegate.class) { | ||||||||||||||
| placeholder = sFaviconPlaceholder; | ||||||||||||||
| if (placeholder == null) { | ||||||||||||||
| placeholder = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); | ||||||||||||||
| sFaviconPlaceholder = placeholder; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| return placeholder; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| @Override | ||||||||||||||
| public void onPageStarted(WebView view, String url, Bitmap favicon) { | ||||||||||||||
| // Issue #490: WebView may deliver a null favicon at page-start. Kotlin | ||||||||||||||
| // delegates whose signature declares favicon as non-null Bitmap will | ||||||||||||||
| // crash at the synthetic Intrinsics.checkParameterIsNotNull check. | ||||||||||||||
| // Substitute a tiny transparent placeholder so non-null Kotlin | ||||||||||||||
| // signatures keep working; nullable signatures see no observable | ||||||||||||||
| // change beyond receiving a non-null bitmap. | ||||||||||||||
|
Comment on lines
+100
to
+101
|
||||||||||||||
| // signatures keep working; nullable signatures see no observable | |
| // change beyond receiving a non-null bitmap. | |
| // signatures keep working. This is an observable change for nullable | |
| // consumers because they receive the shared placeholder instead of | |
| // null; callers that need to detect "no favicon yet" can compare the | |
| // received Bitmap by identity with faviconPlaceholder(). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The placeholder bitmap is cached statically and the same instance is forwarded to external delegates. Because this instance escapes library ownership, a delegate could mutate or call
recycle()on it, which would leavesFaviconPlaceholderin a bad state and potentially crash later calls. Consider either recreating the placeholder whenplaceholder.isRecycled()is true, or returning a fresh/copy placeholder per callback to avoid sharing a mutable/recyclable Bitmap instance with user code.