0

[GURL] Add APIs to RoundedIconGenerator for using GURL.

Migrated a bunch of callers from String URLs to GURL,
but some gnarlier ones will have to be done individually.

Specifically this is due to the fallback behaviour where
callers also handle things like "app name" in the same place
as URL and callers don't currently track which it is.

Bug: 783819
Change-Id: Id1fc42ca7566c52bd4c012a652e62e19c8c8e5cb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2857594
Commit-Queue: Yaron Friedman <yfriedman@chromium.org>
Reviewed-by: Clark DuVall <cduvall@chromium.org>
Reviewed-by: Ted Choc <tedchoc@chromium.org>
Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#881082}
This commit is contained in:
Yaron Friedman
2021-05-10 17:52:35 +00:00
committed by Chromium LUCI CQ
parent e8fe9225bb
commit 5c08a48295
37 changed files with 150 additions and 81 deletions
chrome
android
browser
feed
android
java
src
org
chromium
chrome
browser
notifications
BUILD.gn
android
java
src
org
chromium
chrome
touch_to_fill
android
BUILD.gn
internal
java
src
org
chromium
chrome
browser
javatests
src
org
chromium
chrome
junit
src
org
chromium
chrome
browser
touch_to_fill_view_impl.cc
ui
android
favicon
java
src
org
chromium
chrome
browser
components
browser_ui
site_settings
android
BUILD.gn
java
src
org
chromium
components
widget
android
java
src
org
chromium
components
embedder_support
android
java
src
org
chromium
components
embedder_support
util
page_info
android
java
webapps
browser
BUILD.gn
android
java
src
org
chromium
components
webapps_icon_utils.cc
weblayer/browser/java/org/chromium/weblayer_private

@ -240,7 +240,7 @@ public class BookmarkWidgetServiceImpl extends BookmarkWidgetService.Impl {
boolean isFallbackColorDefault, @IconType int iconType) {
if (icon == null) {
mIconGenerator.setBackgroundColor(fallbackColor);
icon = mIconGenerator.generateIconForUrl(bookmark.url.getSpec());
icon = mIconGenerator.generateIconForUrl(bookmark.url);
} else {
icon = Bitmap.createScaledBitmap(
icon, mDisplayedIconSize, mDisplayedIconSize, true);

@ -85,8 +85,7 @@ class ContextMenuHeaderMediator implements View.OnClickListener {
// If we didn't get a favicon, generate a monogram instead
if (icon == null) {
final RoundedIconGenerator iconGenerator = createRoundedIconGenerator(fallbackColor);
// TODO(https://crbug.com/783819): Migrate IconGenerator to GURL.
icon = iconGenerator.generateIconForUrl(mPlainUrl.getSpec());
icon = iconGenerator.generateIconForUrl(mPlainUrl);
// generateIconForUrl might return null if the URL is empty or the domain cannot be
// resolved. See https://crbug.com/987101
// TODO(sinansahin): Handle the case where generating an icon fails.

@ -252,7 +252,7 @@ public class CustomTabTaskDescriptionHelper implements NativeInitObserver, Destr
Bitmap bitmap = null;
if (!currentTab.isIncognito()) {
bitmap = mIconGenerator.getBitmap(currentTab.getUrlString(), mLargestFavicon);
bitmap = mIconGenerator.getBitmap(currentTab.getUrl(), mLargestFavicon);
}
return bitmap;
}

@ -6,9 +6,9 @@ package org.chromium.chrome.browser.customtabs;
import android.content.Context;
import android.graphics.Bitmap;
import android.text.TextUtils;
import org.chromium.components.browser_ui.widget.RoundedIconGenerator;
import org.chromium.url.GURL;
/**
* Generates icons suitable for Custom Tabs in the recent tasks list.
@ -26,7 +26,7 @@ public class CustomTabTaskDescriptionIconGenerator {
/**
* The page URL for which {@link #mGeneratedIcon} was generated.
*/
private String mGeneratedPageUrl;
private GURL mGeneratedPageUrl;
/**
* The most recently generated icon.
@ -53,13 +53,13 @@ public class CustomTabTaskDescriptionIconGenerator {
* @param largestFavicon The largest favicon available at the page URL.
* @return The icon to use in the recent tasks list.
*/
public Bitmap getBitmap(String pageUrl, Bitmap largestFavicon) {
public Bitmap getBitmap(GURL pageUrl, Bitmap largestFavicon) {
if (largestFavicon != null && largestFavicon.getWidth() >= mMinSizePx
&& largestFavicon.getHeight() >= mMinSizePx) {
return largestFavicon;
}
if (TextUtils.equals(pageUrl, mGeneratedPageUrl)) {
if (pageUrl.equals(mGeneratedPageUrl)) {
return mGeneratedIcon;
}

@ -29,6 +29,7 @@ import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
import org.chromium.url.GURL;
import java.util.Arrays;
import java.util.HashSet;
@ -105,7 +106,7 @@ class NavigationSheetMediator {
*/
void populateEntries(NavigationHistory history) {
mHistory = history;
Set<String> requestedUrls = new HashSet<String>();
Set<GURL> requestedUrls = new HashSet<>();
for (int i = 0; i < mHistory.getEntryCount(); i++) {
PropertyModel model = new PropertyModel(Arrays.asList(ItemProperties.ALL_KEYS));
NavigationEntry entry = mHistory.getEntryAtIndex(i);
@ -115,11 +116,11 @@ class NavigationSheetMediator {
(view) -> { mClickListener.click(position, entry.getIndex()); });
mModelList.add(new ListItem(NAVIGATION_LIST_ITEM_TYPE_ID, model));
if (entry.getFavicon() != null) continue;
final String pageUrl = entry.getUrl().getSpec();
final GURL pageUrl = entry.getUrl();
if (!requestedUrls.contains(pageUrl)) {
FaviconHelper.FaviconImageCallback imageCallback =
(bitmap, iconUrl) -> onFaviconAvailable(pageUrl, bitmap);
if (!pageUrl.equals(UrlConstants.HISTORY_URL)) {
if (!pageUrl.getSpec().equals(UrlConstants.HISTORY_URL)) {
mFaviconHelper.getLocalFaviconImageForURL(
mProfile, pageUrl, mFaviconSize, imageCallback);
requestedUrls.add(pageUrl);
@ -142,12 +143,12 @@ class NavigationSheetMediator {
* @param pageUrl the page for which the favicon was retrieved.
* @param favicon the favicon data.
*/
private void onFaviconAvailable(String pageUrl, Bitmap favicon) {
private void onFaviconAvailable(GURL pageUrl, Bitmap favicon) {
// This callback can come after the sheet is hidden (which clears modelList).
// Do nothing if that happens.
if (mModelList.size() == 0) return;
for (int i = 0; i < mHistory.getEntryCount(); i++) {
if (TextUtils.equals(pageUrl, mHistory.getEntryAtIndex(i).getUrl().getSpec())) {
if (pageUrl.equals(mHistory.getEntryAtIndex(i).getUrl())) {
Drawable drawable;
if (favicon == null) {
drawable = UrlUtilities.isNTPUrl(pageUrl)

@ -126,7 +126,7 @@ public class MostVisitedTilesProcessor extends BaseCarouselSuggestionProcessor {
// used very infrequently - only to offer zero-prefix URL suggestions on URL visit).
// This must be addressed before MV Carousel can be offered in more contexts.
// Consider unifying cache with LargeIconBridge if possible.
Bitmap fallbackIcon = mIconGenerator.generateIconForUrl(url.getSpec());
Bitmap fallbackIcon = mIconGenerator.generateIconForUrl(url);
tileModel.set(TileViewProperties.ICON, new BitmapDrawable(fallbackIcon));
if (iconBridge != null) {

@ -252,13 +252,13 @@ public class ChromePageInfoControllerDelegate extends PageInfoControllerDelegate
@NonNull
@Override
public void getFavicon(String url, Callback<Drawable> callback) {
public void getFavicon(GURL url, Callback<Drawable> callback) {
Resources resources = mContext.getResources();
int size = resources.getDimensionPixelSize(R.dimen.page_info_favicon_size);
new FaviconHelper().getLocalFaviconImageForURL(mProfile, url, size, (image, iconUrl) -> {
if (image != null) {
callback.onResult(new BitmapDrawable(resources, image));
} else if (UrlUtilities.isInternalScheme(new GURL(url))) {
} else if (UrlUtilities.isInternalScheme(url)) {
callback.onResult(
AppCompatResources.getDrawable(mContext, R.drawable.chromelogo16));
} else {

@ -92,7 +92,7 @@ public class ChromeSiteSettingsDelegate implements SiteSettingsDelegate {
}
@Override
public void getFaviconImageForURL(String faviconUrl, Callback<Bitmap> callback) {
public void getFaviconImageForURL(GURL faviconUrl, Callback<Bitmap> callback) {
new FaviconLoader(faviconUrl, callback);
}
@ -104,13 +104,13 @@ public class ChromeSiteSettingsDelegate implements SiteSettingsDelegate {
* has been called.
*/
private class FaviconLoader implements FaviconImageCallback {
private final String mFaviconUrl;
private final GURL mFaviconUrl;
private final Callback<Bitmap> mCallback;
private final int mFaviconSizePx;
// Loads the favicons asynchronously.
private final FaviconHelper mFaviconHelper;
private FaviconLoader(String faviconUrl, Callback<Bitmap> callback) {
private FaviconLoader(GURL faviconUrl, Callback<Bitmap> callback) {
mFaviconUrl = faviconUrl;
mCallback = callback;
mFaviconSizePx =

@ -257,7 +257,7 @@ public class TileRenderer {
return;
}
mIconGenerator.setBackgroundColor(fallbackColor);
Bitmap icon = mIconGenerator.generateIconForUrl(tile.getUrl().getSpec());
Bitmap icon = mIconGenerator.generateIconForUrl(tile.getUrl());
tile.setIcon(new BitmapDrawable(mResources, icon));
tile.setType(
isFallbackColorDefault ? TileVisualType.ICON_DEFAULT : TileVisualType.ICON_COLOR);

@ -53,6 +53,7 @@ import org.chromium.components.url_formatter.SchemeDisplay;
import org.chromium.components.url_formatter.UrlFormatter;
import org.chromium.components.user_prefs.UserPrefs;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.url.GURL;
import java.net.URL;
import java.util.ArrayList;
@ -643,7 +644,8 @@ public class NotificationPlatformBridgeTest {
RoundedIconGenerator generator =
NotificationBuilderBase.createIconGenerator(context.getResources());
Bitmap generatedIcon = generator.generateIconForUrl(mPermissionTestRule.getOrigin());
Bitmap generatedIcon =
generator.generateIconForUrl(new GURL(mPermissionTestRule.getOrigin()));
Assert.assertNotNull(generatedIcon);
// Starts from Android O MR1, large icon can be downscaled by Android platform code.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {

@ -26,6 +26,7 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
import org.chromium.content_public.browser.UiThreadTaskTraits;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.url.GURL;
import java.util.concurrent.TimeoutException;
@ -61,10 +62,11 @@ public class ChromeSiteSettingsDelegateTest {
Bitmap[] holder = new Bitmap[1];
CallbackHelper helper = new CallbackHelper();
PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> {
mSiteSettingsDelegate.getFaviconImageForURL("url.with.no.favicon", favicon -> {
holder[0] = favicon;
helper.notifyCalled();
});
mSiteSettingsDelegate.getFaviconImageForURL(
new GURL("http://url.with.no.favicon"), favicon -> {
holder[0] = favicon;
helper.notifyCalled();
});
});
helper.waitForCallback(helper.getCallCount());

@ -218,7 +218,7 @@ public class WebFeedMainMenuItem extends FrameLayout {
if (icon == null) {
// TODO(crbug/1152592): Update monogram according to specs.
RoundedIconGenerator iconGenerator = createRoundedIconGenerator(fallbackColor);
icon = iconGenerator.generateIconForUrl(mUrl.getSpec());
icon = iconGenerator.generateIconForUrl(mUrl);
mIcon.setImageBitmap(icon);
// generateIconForUrl() might return null if the URL is empty or the domain cannot be
// resolved. See https://crbug.com/987101

@ -154,6 +154,7 @@ if (is_android) {
"//third_party/hamcrest:hamcrest_library_java",
"//third_party/junit",
"//third_party/mockito:mockito_java",
"//url:gurl_java",
]
}

@ -42,6 +42,7 @@ import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
import org.chromium.components.browser_ui.notifications.NotificationMetadata;
import org.chromium.components.browser_ui.notifications.PendingIntentProvider;
import org.chromium.content_public.browser.test.NativeLibraryTestUtils;
import org.chromium.url.GURL;
import java.util.ArrayList;
import java.util.Arrays;
@ -340,7 +341,7 @@ public class CustomNotificationBuilderTest {
Notification notification = buildNotification(notificationBuilder);
Bitmap expectedIcon = NotificationBuilderBase.createIconGenerator(context.getResources())
.generateIconForUrl("https://www.google.com");
.generateIconForUrl(new GURL("https://www.google.com"));
assertLargeNotificationIconAsExpected(context, notification, expectedIcon);
}
@ -360,7 +361,7 @@ public class CustomNotificationBuilderTest {
Notification notification = buildNotification(notificationBuilder);
Bitmap expectedIcon = NotificationBuilderBase.createIconGenerator(context.getResources())
.generateIconForUrl("https://www.chromium.org");
.generateIconForUrl(new GURL("https://www.chromium.org"));
assertLargeNotificationIconAsExpected(context, notification, expectedIcon);
}

@ -20,6 +20,7 @@ source_set("android") {
"//ui/android",
"//ui/gfx",
"//url",
"//url:gurl_android",
]
}
@ -36,6 +37,7 @@ android_library("public_java") {
"//components/browser_ui/bottomsheet/android:java",
"//third_party/androidx:androidx_annotation_annotation_java",
"//ui/android:ui_java",
"//url:gurl_java",
]
sources = [
@ -69,6 +71,8 @@ junit_binary("touch_to_fill_junit_tests") {
"//third_party/junit",
"//third_party/mockito:mockito_java",
"//ui/android:ui_full_java",
"//url:gurl_java",
"//url:gurl_junit_test_support",
]
}
@ -101,5 +105,6 @@ android_library("test_java") {
"//third_party/mockito:mockito_java",
"//ui/android:ui_full_java",
"//ui/android:ui_utils_java",
"//url:gurl_java",
]
}

@ -24,6 +24,7 @@ android_library("java") {
"//third_party/androidx:androidx_annotation_annotation_java",
"//third_party/androidx:androidx_recyclerview_recyclerview_java",
"//ui/android:ui_java",
"//url:gurl_java",
]
sources = [

@ -12,6 +12,7 @@ import org.chromium.chrome.browser.touch_to_fill.data.Credential;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.url.GURL;
import java.util.Arrays;
@ -60,7 +61,7 @@ class TouchToFillBridge implements TouchToFillComponent.Delegate {
}
@CalledByNative
private void showCredentials(String url, boolean isOriginSecure, Credential[] credentials) {
private void showCredentials(GURL url, boolean isOriginSecure, Credential[] credentials) {
mTouchToFillComponent.showCredentials(url, isOriginSecure, Arrays.asList(credentials));
}

@ -14,6 +14,7 @@ import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.components.favicon.LargeIconBridge;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
import org.chromium.url.GURL;
import java.util.List;
@ -36,7 +37,7 @@ public class TouchToFillCoordinator implements TouchToFillComponent {
}
@Override
public void showCredentials(String url, boolean isOriginSecure, List<Credential> credentials) {
public void showCredentials(GURL url, boolean isOriginSecure, List<Credential> credentials) {
mMediator.showCredentials(url, isOriginSecure, credentials);
}

@ -32,6 +32,7 @@ import org.chromium.components.url_formatter.UrlFormatter;
import org.chromium.ui.modelutil.ListModel;
import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.url.GURL;
import java.util.List;
@ -61,7 +62,7 @@ class TouchToFillMediator {
mDesiredIconSize = desiredIconSize;
}
void showCredentials(String url, boolean isOriginSecure, List<Credential> credentials) {
void showCredentials(GURL url, boolean isOriginSecure, List<Credential> credentials) {
assert credentials != null;
mModel.set(ON_CLICK_MANAGE, this::onManagePasswordSelected);
@ -90,7 +91,7 @@ class TouchToFillMediator {
mModel.set(VISIBLE, true);
}
private void requestIconOrFallbackImage(PropertyModel credentialModel, String url) {
private void requestIconOrFallbackImage(PropertyModel credentialModel, GURL url) {
Credential credential = credentialModel.get(CREDENTIAL);
final String iconOrigin = getIconOrigin(credential.getOriginUrl(), url);
@ -101,7 +102,7 @@ class TouchToFillMediator {
};
final LargeIconCallback setIconOrRetry = (icon, fallbackColor, hasDefaultColor, type) -> {
if (icon == null && iconOrigin.equals(credential.getOriginUrl())) {
mLargeIconBridge.getLargeIconForStringUrl(url, mDesiredIconSize, setIcon);
mLargeIconBridge.getLargeIconForUrl(url, mDesiredIconSize, setIcon);
return; // Unlikely but retry for exact path if there is no icon for the origin.
}
setIcon.onLargeIconAvailable(icon, fallbackColor, hasDefaultColor, type);
@ -109,10 +110,10 @@ class TouchToFillMediator {
mLargeIconBridge.getLargeIconForStringUrl(iconOrigin, mDesiredIconSize, setIconOrRetry);
}
private String getIconOrigin(String credentialOrigin, String siteUrl) {
private String getIconOrigin(String credentialOrigin, GURL siteUrl) {
final Origin o = Origin.create(credentialOrigin);
// TODO(crbug.com/1030230): assert o != null as soon as credential Origin must be valid.
return o != null && !o.uri().isOpaque() ? credentialOrigin : siteUrl;
return o != null && !o.uri().isOpaque() ? credentialOrigin : siteUrl.getSpec();
}
private void onSelectedCredential(Credential credential) {

@ -10,6 +10,7 @@ import androidx.annotation.IntDef;
import org.chromium.chrome.browser.touch_to_fill.data.Credential;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.url.GURL;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -74,5 +75,5 @@ public interface TouchToFillComponent {
* @param isOriginSecure A {@link boolean} that indicates whether the current origin is secure.
* @param credentials A list of {@link Credential}s that will be displayed.
*/
void showCredentials(String url, boolean isOriginSecure, List<Credential> credentials);
void showCredentials(GURL url, boolean isOriginSecure, List<Credential> credentials);
}

@ -45,6 +45,7 @@ import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
import org.chromium.content_public.browser.test.util.TouchCommon;
import org.chromium.url.GURL;
import java.util.Arrays;
import java.util.Collections;
@ -57,12 +58,10 @@ import java.util.Collections;
@Batch(Batch.PER_CLASS)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class TouchToFillIntegrationTest {
private static final String EXAMPLE_URL = "https://www.example.xyz";
private static GURL sExampleUrl;
private static final String MOBILE_URL = "https://m.example.xyz";
private static final Credential ANA =
new Credential("Ana", "S3cr3t", "Ana", EXAMPLE_URL, false, false, 0);
private static final Credential BOB =
new Credential("Bob", "*****", "Bob", MOBILE_URL, true, false, 0);
private static Credential sAna;
private static Credential sBob;
private final TouchToFillComponent mTouchToFill = new TouchToFillCoordinator();
@ -80,6 +79,11 @@ public class TouchToFillIntegrationTest {
@Before
public void setUp() throws InterruptedException {
sExampleUrl = new GURL("https://www.example.xyz");
// TODO(https://crbug.com/783819): Migrate Credential to GURL.
sAna = new Credential("Ana", "S3cr3t", "Ana", sExampleUrl.getSpec(), false, false, 0);
sBob = new Credential("Bob", "*****", "Bob", MOBILE_URL, true, false, 0);
mActivityTestRule.startMainActivityOnBlankPage();
runOnUiThreadBlocking(() -> {
mBottomSheetController = BottomSheetControllerProvider.from(
@ -93,14 +97,14 @@ public class TouchToFillIntegrationTest {
@MediumTest
public void testClickingSuggestionsTriggersCallback() {
runOnUiThreadBlocking(() -> {
mTouchToFill.showCredentials(EXAMPLE_URL, true, Collections.singletonList(ANA));
mTouchToFill.showCredentials(sExampleUrl, true, Collections.singletonList(sAna));
});
pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
pollUiThread(() -> getCredentials().getChildAt(1) != null);
TouchCommon.singleClickView(getCredentials().getChildAt(1));
waitForEvent(mMockBridge).onCredentialSelected(ANA);
waitForEvent(mMockBridge).onCredentialSelected(sAna);
verify(mMockBridge, never()).onDismissed();
}
@ -108,7 +112,7 @@ public class TouchToFillIntegrationTest {
@MediumTest
public void testBackDismissesAndCallsCallback() {
runOnUiThreadBlocking(() -> {
mTouchToFill.showCredentials(EXAMPLE_URL, true, Arrays.asList(ANA, BOB));
mTouchToFill.showCredentials(sExampleUrl, true, Arrays.asList(sAna, sBob));
});
pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@ -183,7 +187,7 @@ public class TouchToFillIntegrationTest {
Espresso.onView(withText("Another bottom sheet content")).check(matches(isDisplayed()));
runOnUiThreadBlocking(() -> {
mTouchToFill.showCredentials(EXAMPLE_URL, true, Arrays.asList(ANA, BOB));
mTouchToFill.showCredentials(sExampleUrl, true, Arrays.asList(sAna, sBob));
});
waitForEvent(mMockBridge).onDismissed();
verify(mMockBridge, never()).onCredentialSelected(any());

@ -61,6 +61,8 @@ import org.chromium.components.url_formatter.UrlFormatterJni;
import org.chromium.ui.modelutil.ListModel;
import org.chromium.ui.modelutil.MVCListAdapter;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.url.GURL;
import org.chromium.url.JUnitTestGURLs;
import java.util.Arrays;
import java.util.Collections;
@ -72,14 +74,14 @@ import java.util.Collections;
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE, shadows = {ShadowRecordHistogram.class})
public class TouchToFillControllerTest {
private static final String TEST_URL = "https://www.example.xyz";
private static final GURL TEST_URL = JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL);
private static final String TEST_SUBDOMAIN_URL = "https://subdomain.example.xyz";
private static final Credential ANA =
new Credential("Ana", "S3cr3t", "Ana", "https://m.a.xyz/", true, false, 0);
private static final Credential BOB =
new Credential("Bob", "*****", "Bob", TEST_SUBDOMAIN_URL, true, false, 0);
private static final Credential CARL =
new Credential("Carl", "G3h3!m", "Carl", TEST_URL, false, false, 0);
new Credential("Carl", "G3h3!m", "Carl", TEST_URL.getSpec(), false, false, 0);
private static final @Px int DESIRED_FAVICON_SIZE = 64;
@Rule
@ -112,8 +114,11 @@ public class TouchToFillControllerTest {
mJniMocker.mock(RecordHistogramJni.TEST_HOOKS, mMockRecordHistogram);
when(mUrlFormatterJniMock.formatUrlForDisplayOmitScheme(anyString()))
.then(inv -> format(inv.getArgument(0)));
when(mUrlFormatterJniMock.formatUrlForSecurityDisplay(
any(), eq(SchemeDisplay.OMIT_HTTP_AND_HTTPS)))
.then(inv -> formatForSecurityDisplay(inv.getArgument(0)));
when(mUrlFormatterJniMock.formatStringUrlForSecurityDisplay(
anyString(), eq(SchemeDisplay.OMIT_HTTP_AND_HTTPS)))
any(), eq(SchemeDisplay.OMIT_HTTP_AND_HTTPS)))
.then(inv -> formatForSecurityDisplay(inv.getArgument(0)));
mMediator.initialize(mMockDelegate, mModel, mMockIconBridge, DESIRED_FAVICON_SIZE);
@ -181,15 +186,15 @@ public class TouchToFillControllerTest {
// ANA and CARL both have TEST_URL as their origin URL
verify(mMockIconBridge)
.getLargeIconForStringUrl(
eq(TEST_URL), eq(DESIRED_FAVICON_SIZE), mCallbackArgumentCaptor.capture());
.getLargeIconForStringUrl(eq(TEST_URL.getSpec()), eq(DESIRED_FAVICON_SIZE),
mCallbackArgumentCaptor.capture());
LargeIconBridge.LargeIconCallback callback = mCallbackArgumentCaptor.getValue();
Bitmap bitmap = Bitmap.createBitmap(
DESIRED_FAVICON_SIZE, DESIRED_FAVICON_SIZE, Bitmap.Config.ARGB_8888);
callback.onLargeIconAvailable(bitmap, 333, true, IconType.FAVICON);
FaviconOrFallback iconData = itemList.get(1).model.get(FAVICON_OR_FALLBACK);
assertThat(iconData.mIcon, is(bitmap));
assertThat(iconData.mUrl, is(TEST_URL));
assertThat(iconData.mUrl, is(TEST_URL.getSpec()));
assertThat(iconData.mIconSize, is(DESIRED_FAVICON_SIZE));
assertThat(iconData.mFallbackColor, is(333));
assertThat(iconData.mIsFallbackColorDefault, is(true));
@ -313,7 +318,7 @@ public class TouchToFillControllerTest {
* @param originUrl A URL {@link String} to "format".
* @return A "formatted" URL {@link String}.
*/
private static String formatForSecurityDisplay(String originUrl) {
return "formatted_for_security_" + originUrl + "_formatted_for_security";
private static String formatForSecurityDisplay(GURL originUrl) {
return "formatted_for_security_" + originUrl.getSpec() + "_formatted_for_security";
}
}

@ -18,6 +18,7 @@
#include "components/password_manager/core/browser/origin_credential_store.h"
#include "ui/android/view_android.h"
#include "ui/android/window_android.h"
#include "url/android/gurl_android.h"
#include "url/gurl.h"
#include "url/origin.h"
@ -92,7 +93,8 @@ void TouchToFillViewImpl::Show(
}
Java_TouchToFillBridge_showCredentials(
env, java_object_internal_, ConvertUTF8ToJavaString(env, url.spec()),
env, java_object_internal_, url::GURLAndroid::FromNativeGURL(env, url),
is_origin_secure.value(), credential_array);
}

@ -121,8 +121,7 @@ public class FaviconUtils {
return defaultFaviconHelper.getDefaultFaviconDrawable(resources, url, true);
}
if (icon == null) {
// TODO(crbug/783819): Migrate RoundedIconGenerator to GURL.
icon = iconGenerator.generateIconForUrl(url.getSpec());
icon = iconGenerator.generateIconForUrl(url);
return new BitmapDrawable(
resources, Bitmap.createScaledBitmap(icon, iconSize, iconSize, true));
}

@ -97,6 +97,7 @@ android_library("java") {
"//third_party/androidx:androidx_preference_preference_java",
"//ui/android:ui_full_java",
"//ui/android:ui_utils_java",
"//url:gurl_java",
]
srcjar_deps =
[ "//components/content_settings/android:java_pref_names_srcjar" ]

@ -14,6 +14,7 @@ import org.chromium.components.browser_ui.settings.ManagedPreferenceDelegate;
import org.chromium.components.content_settings.ContentSettingsType;
import org.chromium.components.embedder_support.browser_context.BrowserContextHandle;
import org.chromium.components.embedder_support.util.Origin;
import org.chromium.url.GURL;
import java.util.Set;
@ -42,7 +43,7 @@ public interface SiteSettingsDelegate {
* @param callback A callback that will be called with the favicon bitmap, or null if no
* favicon could be found or generated.
*/
void getFaviconImageForURL(String faviconUrl, Callback<Bitmap> callback);
void getFaviconImageForURL(GURL faviconUrl, Callback<Bitmap> callback);
/**
* @return true if the given category type should be shown in the SiteSettings Fragment.

@ -9,7 +9,6 @@ import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.text.format.Formatter;
import android.view.View;
import android.widget.TextView;
@ -18,6 +17,8 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import org.chromium.components.browser_ui.settings.ChromeImageViewPreference;
import org.chromium.components.embedder_support.util.UrlUtilities;
import org.chromium.url.GURL;
/**
* A preference that displays a website's favicon and URL and, optionally, the amount of local
@ -73,14 +74,10 @@ class WebsitePreference extends ChromeImageViewPreference {
/**
* Returns the url of the site to fetch a favicon for.
*/
private String faviconUrl() {
private GURL faviconUrl() {
String origin = mSite.getAddress().getOrigin();
Uri uri = Uri.parse(origin);
if (uri.getPort() != -1) {
// Remove the port.
uri = uri.buildUpon().authority(uri.getHost()).build();
}
return uri.toString();
GURL uri = new GURL(origin);
return UrlUtilities.clearPort(uri);
}
private void refresh() {

@ -20,6 +20,7 @@ import androidx.annotation.VisibleForTesting;
import org.chromium.base.Log;
import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.components.embedder_support.util.UrlUtilities;
import org.chromium.url.GURL;
import org.chromium.url.URI;
import java.util.Locale;
@ -122,6 +123,18 @@ public class RoundedIconGenerator {
return icon;
}
/** {@link #generateIconForUrl(GURL, boolean)} */
@Nullable
@Deprecated // TODO(https://crbug.com/783819): Use GURL-variant or #generateIconForText
public Bitmap generateIconForUrl(String url, boolean includePrivateRegistries) {
if (TextUtils.isEmpty(url)) return null;
String text = getIconTextForUrl(url, includePrivateRegistries);
if (TextUtils.isEmpty(text)) return null;
return generateIconForText(text);
}
/**
* Returns a Bitmap representing the icon to be used for |url|.
*
@ -130,13 +143,16 @@ public class RoundedIconGenerator {
* @return The generated icon, or NULL if |url| is empty or the domain cannot be resolved.
*/
@Nullable
public Bitmap generateIconForUrl(String url, boolean includePrivateRegistries) {
if (TextUtils.isEmpty(url)) return null;
public Bitmap generateIconForUrl(GURL url, boolean includePrivateRegistries) {
if (url == null) return null;
return generateIconForUrl(url.getSpec(), includePrivateRegistries);
}
String text = getIconTextForUrl(url, includePrivateRegistries);
if (TextUtils.isEmpty(text)) return null;
return generateIconForText(text);
/** {@link #generateIconForUrl(GURL)} */
@Nullable
@Deprecated // TODO(https://crbug.com/783819): Use GURL-variant or #generateIconForText
public Bitmap generateIconForUrl(String url) {
return generateIconForUrl(url, false);
}
/**
@ -151,8 +167,8 @@ public class RoundedIconGenerator {
* @return The generated icon, or NULL if |url| is empty or the domain cannot be resolved.
*/
@Nullable
public Bitmap generateIconForUrl(String url) {
return generateIconForUrl(url, false);
public Bitmap generateIconForUrl(GURL url) {
return generateIconForUrl(url.getSpec(), false);
}
/**

@ -174,6 +174,17 @@ public class UrlUtilities {
primaryUrl, secondaryUrl, includePrivateRegistries);
}
/**
* Returns a new URL without the port in the hostname if it was present.
* @param url The url to process.
* @return
*/
// TODO(crbug/783819): Expose GURL::Replacements to Java.
public static GURL clearPort(GURL url) {
if (url == null || TextUtils.isEmpty(url.getPort())) return url;
return UrlUtilitiesJni.get().clearPort(url);
}
/**
* This function works by calling net::registry_controlled_domains::GetDomainAndRegistry
*
@ -342,5 +353,7 @@ public class UrlUtilities {
String escapeQueryParamValue(String url, boolean usePlus);
String getValueForKeyInQuery(GURL url, String key);
GURL clearPort(GURL url);
}
}

@ -192,4 +192,14 @@ static ScopedJavaLocalRef<jstring> JNI_UrlUtilities_GetValueForKeyInQuery(
return base::android::ConvertUTF8ToJavaString(env, out);
}
ScopedJavaLocalRef<jobject> JNI_UrlUtilities_ClearPort(
JNIEnv* env,
const JavaParamRef<jobject>& j_url) {
std::unique_ptr<GURL> gurl = url::GURLAndroid::ToNativeGURL(env, j_url);
GURL::Replacements remove_port;
remove_port.ClearPort();
return url::GURLAndroid::FromNativeGURL(env,
gurl->ReplaceComponents(remove_port));
}
} // namespace embedder_support

@ -233,7 +233,7 @@ public class PageInfoController implements PageInfoMainController, ModalDialogPr
viewParams.httpsImageCompressionMessageShown = mDelegate.isHttpsImageCompressionApplied();
mView = new PageInfoView(mContext, viewParams);
if (isSheet(mContext)) mView.setBackgroundColor(Color.WHITE);
mDelegate.getFavicon(mFullUrl.getSpec(), favicon -> {
mDelegate.getFavicon(mFullUrl, favicon -> {
// Return early if PageInfo has been dismissed.
if (mContext == null) return;

@ -20,6 +20,7 @@ import org.chromium.components.content_settings.CookieControlsObserver;
import org.chromium.components.embedder_support.browser_context.BrowserContextHandle;
import org.chromium.components.omnibox.AutocompleteSchemeClassifier;
import org.chromium.ui.modaldialog.ModalDialogManager;
import org.chromium.url.GURL;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -199,7 +200,7 @@ public abstract class PageInfoControllerDelegate {
* Fetches a favicon for the current page and passes it to callback.
* The UI will use a fallback icon if null is supplied.
*/
public abstract void getFavicon(String url, Callback<Drawable> callback);
public abstract void getFavicon(GURL url, Callback<Drawable> callback);
/**
* Checks to see that touch exploration or an accessibility service that can perform gestures

@ -95,6 +95,7 @@ source_set("browser") {
"//services/device/public/mojom",
"//ui/base",
"//ui/gfx",
"//url:gurl_android",
]
}
}

@ -24,6 +24,7 @@ import org.chromium.base.Log;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.components.browser_ui.widget.RoundedIconGenerator;
import org.chromium.ui.base.ViewUtils;
import org.chromium.url.GURL;
/**
* This class contains functions related to adding shortcuts to the Android Home
@ -226,7 +227,7 @@ public class WebappsIconUtils {
* @return Bitmap Either the touch-icon or the newly created favicon.
*/
@CalledByNative
public static Bitmap generateHomeScreenIcon(String url, int red, int green, int blue) {
public static Bitmap generateHomeScreenIcon(GURL url, int red, int green, int blue) {
Context context = ContextUtils.getApplicationContext();
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
final int outerSize = am.getLauncherLargeIconSize();

@ -12,6 +12,7 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/android/java_bitmap.h"
#include "ui/gfx/color_analysis.h"
#include "url/android/gurl_android.h"
#include "url/gurl.h"
using base::android::JavaParamRef;
@ -120,8 +121,8 @@ SkBitmap WebappsIconUtils::FinalizeLauncherIconInBackground(
}
if (result.is_null()) {
ScopedJavaLocalRef<jstring> java_url =
base::android::ConvertUTF8ToJavaString(env, url.spec());
ScopedJavaLocalRef<jobject> java_url =
url::GURLAndroid::FromNativeGURL(env, url);
SkColor mean_color = SkColorSetRGB(0x91, 0x91, 0x91);
if (!bitmap.isNull())

@ -127,9 +127,9 @@ public class PageInfoControllerDelegateImpl extends PageInfoControllerDelegate {
}
@Override
public void getFavicon(String url, Callback<Drawable> callback) {
public void getFavicon(GURL url, Callback<Drawable> callback) {
mProfile.getCachedFaviconForPageUri(
url, ObjectWrapper.wrap((ValueCallback<Bitmap>) (bitmap) -> {
url.getSpec(), ObjectWrapper.wrap((ValueCallback<Bitmap>) (bitmap) -> {
if (bitmap != null) {
callback.onResult(new BitmapDrawable(mContext.getResources(), bitmap));
} else {

@ -18,6 +18,7 @@ import org.chromium.components.browser_ui.site_settings.SiteSettingsDelegate;
import org.chromium.components.content_settings.ContentSettingsType;
import org.chromium.components.embedder_support.browser_context.BrowserContextHandle;
import org.chromium.components.embedder_support.util.Origin;
import org.chromium.url.GURL;
import org.chromium.weblayer_private.WebLayerImpl;
import java.util.Collections;
@ -47,7 +48,7 @@ public class WebLayerSiteSettingsDelegate
}
@Override
public void getFaviconImageForURL(String faviconUrl, Callback<Bitmap> callback) {
public void getFaviconImageForURL(GURL faviconUrl, Callback<Bitmap> callback) {
// We don't currently support favicons on WebLayer.
callback.onResult(null);
}