[Android] Fixes a crash in FaviconUtils.getIconDrawableWithFilter when an icon is not available for a particular URL by falling back to the default globe icon. (#33569)

[Android] Fixes a crash in FaviconUtils.getIconDrawableWithFilter
when an icon is not available for a particular URL by falling back
to the default globe icon.

Resolves: https://github.com/brave/brave-browser/issues/52458
This commit is contained in:
Serg
2026-02-02 23:49:25 +00:00
committed by GitHub
parent f7bfe68046
commit bd7950d53a
10 changed files with 106 additions and 0 deletions
+4
View File
@@ -718,6 +718,10 @@
public <init>(...);
}
-keep class org.chromium.chrome.browser.ui.favicon.FaviconUtils {
*** getIconDrawableWithFilter(...);
}
-keep class org.chromium.chrome.browser.document.ChromeLauncherActivity {
public <init>(...);
}
@@ -158,6 +158,7 @@ import org.chromium.chrome.browser.ui.appmenu.AppMenuDelegate;
import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate;
import org.chromium.chrome.browser.ui.appmenu.BraveAppMenu;
import org.chromium.chrome.browser.ui.desktop_windowing.AppHeaderCoordinator;
import org.chromium.chrome.browser.ui.favicon.FaviconHelper;
import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
import org.chromium.chrome.browser.ui.native_page.NativePageHost;
import org.chromium.chrome.browser.ui.system.StatusBarColorController;
@@ -181,6 +182,7 @@ import org.chromium.components.browser_ui.util.motion.MotionEventInfo;
import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController;
import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
import org.chromium.components.browser_ui.widget.RoundedIconGenerator;
import org.chromium.components.browser_ui.widget.displaystyle.UiConfig;
import org.chromium.components.browser_ui.widget.dragreorder.DragReorderableRecyclerViewAdapter;
import org.chromium.components.browser_ui.widget.scrim.ScrimManager;
@@ -362,6 +364,7 @@ public class BytecodeTest {
Assert.assertTrue(classExists("org/chromium/components/cached_flags/CachedFeatureParam"));
Assert.assertTrue(classExists("org/chromium/components/cached_flags/CachedFlagUtils"));
Assert.assertTrue(classExists("org/chromium/chrome/browser/logo/LogoMediator"));
Assert.assertTrue(classExists("org/chromium/chrome/browser/ui/favicon/FaviconUtils"));
Assert.assertTrue(
classExists("org/chromium/chrome/browser/tracing/settings/DeveloperSettings"));
Assert.assertTrue(
@@ -795,6 +798,18 @@ public class BytecodeTest {
"updateVisibility",
MethodModifier.REGULAR,
void.class));
Assert.assertTrue(
methodExists(
"org/chromium/chrome/browser/ui/favicon/FaviconUtils",
"getIconDrawableWithFilter",
MethodModifier.STATIC,
Drawable.class,
Bitmap.class,
GURL.class,
RoundedIconGenerator.class,
FaviconHelper.DefaultFaviconHelper.class,
Context.class,
int.class));
Assert.assertTrue(
methodExists(
"org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator",
+20
View File
@@ -0,0 +1,20 @@
# Copyright (c) 2026 The Brave Authors. All rights reserved.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at https://mozilla.org/MPL/2.0/.
import("//build/config/android/rules.gni")
android_library("java") {
sources = [
"java/src/org/chromium/chrome/browser/ui/favicon/BraveFaviconUtils.java",
]
deps = [
"//base:base_java",
"//build/android:build_java",
"//chrome/browser/ui/android/favicon:java",
"//components/browser_ui/widget/android:java",
"//url:gurl_java",
]
}
@@ -0,0 +1,41 @@
/* Copyright (c) 2026 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
package org.chromium.chrome.browser.ui.favicon;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import org.chromium.build.annotations.NullUnmarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.components.browser_ui.widget.RoundedIconGenerator;
import org.chromium.url.GURL;
/** Brave's fix for FaviconUtils to handle null bitmap from icon generator. */
public class BraveFaviconUtils {
/**
* Wrapper for {@link FaviconUtils#getIconDrawableWithFilter} that catches NullPointerException
* when RoundedIconGenerator.generateIconForUrl returns null.
*/
@NullUnmarked
public static Drawable getIconDrawableWithFilter(
@Nullable Bitmap icon,
@Nullable GURL url,
RoundedIconGenerator iconGenerator,
FaviconHelper.DefaultFaviconHelper defaultFaviconHelper,
Context context,
int iconSize) {
try {
return FaviconUtils.getIconDrawableWithFilter(
icon, url, iconGenerator, defaultFaviconHelper, context, iconSize);
} catch (NullPointerException e) {
// Fix for crash when generateIconForUrl returns null.
// Check https://github.com/brave/brave-browser/issues/52458 for more details.
// Fall back to default favicon.
return defaultFaviconHelper.getDefaultFaviconDrawable(context, url, true);
}
}
}
+1
View File
@@ -56,6 +56,7 @@ java_binary("java_bytecode_rewriter") {
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveEditUrlSuggestionProcessorBaseClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveEditUrlSuggestionProcessorClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveExternalNavigationHandlerClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveFaviconUtilsClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveFeedSurfaceCoordinatorClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveFeedSurfaceMediatorClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveForegroundServiceUtilsClassAdapter.java",
@@ -11,6 +11,7 @@ brave_bytecode_jars = [
"obj/brave/android/features/tab_ui/java.javac.jar",
"obj/brave/android/java/org/chromium/chrome/browser/search_engines/java.javac.jar",
"obj/brave/browser/notifications/java.javac.jar",
"obj/brave/browser/ui/android/favicon/java.javac.jar",
"obj/brave/browser/ui/android/logo/java.javac.jar",
"obj/brave/browser/ui/android/omnibox/java.javac.jar",
"obj/brave/browser/ui/android/theme/java.javac.jar",
@@ -60,6 +60,7 @@ public class BraveClassAdapter {
chain = new BraveEditUrlSuggestionProcessorBaseClassAdapter(chain);
chain = new BraveEditUrlSuggestionProcessorClassAdapter(chain);
chain = new BraveExternalNavigationHandlerClassAdapter(chain);
chain = new BraveFaviconUtilsClassAdapter(chain);
chain = new BraveFeedSurfaceCoordinatorClassAdapter(chain);
chain = new BraveFeedSurfaceMediatorClassAdapter(chain);
chain = new BraveForegroundServiceUtilsClassAdapter(chain);
@@ -0,0 +1,21 @@
/* Copyright (c) 2026 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
package org.brave.bytecode;
import org.objectweb.asm.ClassVisitor;
public class BraveFaviconUtilsClassAdapter extends BraveClassVisitor {
static String sFaviconUtilsClassName = "org/chromium/chrome/browser/ui/favicon/FaviconUtils";
static String sBraveFaviconUtilsClassName =
"org/chromium/chrome/browser/ui/favicon/BraveFaviconUtils";
public BraveFaviconUtilsClassAdapter(ClassVisitor visitor) {
super(visitor);
changeMethodOwner(
sFaviconUtilsClassName, "getIconDrawableWithFilter", sBraveFaviconUtilsClassName);
}
}
+1
View File
@@ -36,6 +36,7 @@ brave_chrome_java_deps = [
"//brave/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/settings:java",
"//brave/browser/skus/android:java",
"//brave/browser/tab_group_sync:java",
"//brave/browser/ui/android/favicon:java",
"//brave/browser/ui/android/logo:java",
"//brave/browser/ui/android/omnibox:java",
"//brave/browser/ui/android/theme:java",
+1
View File
@@ -1466,6 +1466,7 @@ if (is_android) {
"//chrome/browser/ui/android/desktop_windowing:java",
"//chrome/browser/ui/android/edge_to_edge:java",
"//chrome/browser/ui/android/extensions:java",
"//chrome/browser/ui/android/favicon:java",
"//chrome/browser/ui/android/layouts:java",
"//chrome/browser/ui/android/logo:java",
"//chrome/browser/ui/android/multiwindow:java",