Android: Implement favicons for Password Manager entries (#33868)
* Android: Implement favicons for Password Manager entries We now display favicons for Password Manager as happens for our desktop edition. In order to do this, the C++ side now passes in the full origin so that we have the clean, proper URI in order to fetch the favicon. Resolves brave/brave-browser#52775
This commit is contained in:
+67
@@ -0,0 +1,67 @@
|
||||
// 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.password_manager.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import org.chromium.build.annotations.NullMarked;
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.profiles.Profile;
|
||||
import org.chromium.chrome.browser.ui.favicon.FaviconHelper;
|
||||
import org.chromium.url.GURL;
|
||||
|
||||
/**
|
||||
* A Preference that lazily loads a favicon when it becomes visible on screen. The favicon is
|
||||
* fetched only once when the view is first bound, and cached via {@link Preference#setIcon} for
|
||||
* subsequent rebinds.
|
||||
*/
|
||||
@NullMarked
|
||||
public class PasswordEntryPreference extends Preference {
|
||||
private final GURL mOriginUrl;
|
||||
private final FaviconHelper mFaviconHelper;
|
||||
private final FaviconHelper.DefaultFaviconHelper mDefaultFaviconHelper;
|
||||
private final Profile mProfile;
|
||||
|
||||
public PasswordEntryPreference(
|
||||
Context context,
|
||||
String originUrl,
|
||||
FaviconHelper faviconHelper,
|
||||
FaviconHelper.DefaultFaviconHelper defaultFaviconHelper,
|
||||
Profile profile) {
|
||||
super(context);
|
||||
mOriginUrl = new GURL(originUrl);
|
||||
mFaviconHelper = faviconHelper;
|
||||
mDefaultFaviconHelper = defaultFaviconHelper;
|
||||
mProfile = profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
if (getIcon() == null) {
|
||||
int faviconSizePixels =
|
||||
getContext()
|
||||
.getResources()
|
||||
.getDimensionPixelSize(R.dimen.omnibox_suggestion_favicon_size);
|
||||
mFaviconHelper.getForeignFaviconImageForURL(
|
||||
mProfile,
|
||||
mOriginUrl,
|
||||
faviconSizePixels,
|
||||
(bitmap, iconUrl) -> {
|
||||
if (bitmap == null) {
|
||||
bitmap =
|
||||
mDefaultFaviconHelper.getDefaultFaviconBitmap(
|
||||
getContext(), iconUrl, true, false);
|
||||
}
|
||||
setIcon(new BitmapDrawable(getContext().getResources(), bitmap));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-1
@@ -34,6 +34,7 @@ import org.chromium.base.metrics.RecordHistogram;
|
||||
import org.chromium.base.supplier.MonotonicObservableSupplier;
|
||||
import org.chromium.base.supplier.ObservableSuppliers;
|
||||
import org.chromium.base.supplier.SettableMonotonicObservableSupplier;
|
||||
import org.chromium.build.annotations.EnsuresNonNull;
|
||||
import org.chromium.build.annotations.Initializer;
|
||||
import org.chromium.build.annotations.MonotonicNonNull;
|
||||
import org.chromium.build.annotations.NullMarked;
|
||||
@@ -47,6 +48,7 @@ import org.chromium.chrome.browser.settings.ChromeBaseSettingsFragment;
|
||||
import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate;
|
||||
import org.chromium.chrome.browser.settings.MainSettings;
|
||||
import org.chromium.chrome.browser.settings.search.ChromeBaseSearchIndexProvider;
|
||||
import org.chromium.chrome.browser.ui.favicon.FaviconHelper;
|
||||
import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
|
||||
import org.chromium.components.browser_ui.settings.SearchUtils;
|
||||
import org.chromium.components.browser_ui.settings.SearchViewProvider;
|
||||
@@ -116,6 +118,8 @@ public class PasswordSettings extends ChromeBaseSettingsFragment
|
||||
private @Nullable Preference mLinkPref;
|
||||
private /*@Nullable*/ Menu mMenu;
|
||||
private @Nullable Preference mExportPasswordsPreference;
|
||||
private @MonotonicNonNull FaviconHelper mFaviconHelper;
|
||||
private @MonotonicNonNull FaviconHelper.DefaultFaviconHelper mDefaultFaviconHelper;
|
||||
|
||||
private @ManagePasswordsReferrer int mManagePasswordsReferrer;
|
||||
private final SettableMonotonicObservableSupplier<String> mPageTitle =
|
||||
@@ -134,6 +138,7 @@ public class PasswordSettings extends ChromeBaseSettingsFragment
|
||||
}
|
||||
|
||||
@Override
|
||||
@EnsuresNonNull({"mFaviconHelper", "mDefaultFaviconHelper"})
|
||||
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
|
||||
mExportFlow.onCreate(
|
||||
savedInstanceState,
|
||||
@@ -190,6 +195,9 @@ public class PasswordSettings extends ChromeBaseSettingsFragment
|
||||
});
|
||||
mPageTitle.set(getString(R.string.password_manager_settings_title));
|
||||
|
||||
mFaviconHelper = new FaviconHelper();
|
||||
mDefaultFaviconHelper = new FaviconHelper.DefaultFaviconHelper();
|
||||
|
||||
// Load preferences from XML instead of creating programmatically
|
||||
SettingsUtils.addPreferencesFromResource(this, R.xml.brave_password_settings_preferences);
|
||||
|
||||
@@ -540,7 +548,13 @@ public class PasswordSettings extends ChromeBaseSettingsFragment
|
||||
if (shouldBeFiltered(url, name)) {
|
||||
continue; // The current password won't show with the active filter, try the next.
|
||||
}
|
||||
Preference preference = new Preference(getStyledContext());
|
||||
PasswordEntryPreference preference =
|
||||
new PasswordEntryPreference(
|
||||
getStyledContext(),
|
||||
saved.getOriginUrl(),
|
||||
assumeNonNull(mFaviconHelper),
|
||||
assumeNonNull(mDefaultFaviconHelper),
|
||||
getProfile());
|
||||
preference.setTitle(url);
|
||||
preference.setOnPreferenceClickListener(this);
|
||||
preference.setSummary(name);
|
||||
@@ -671,6 +685,7 @@ public class PasswordSettings extends ChromeBaseSettingsFragment
|
||||
// by the system.
|
||||
if (getActivity().isFinishing()) {
|
||||
PasswordManagerHandlerProvider.getForProfile(getProfile()).removeObserver(this);
|
||||
assumeNonNull(mFaviconHelper).destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user