diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index a978f94c4359c2..71a233fc73d1bf 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn @@ -28,12 +28,7 @@ android_resources("java_resources") { "java/res/anim/iph_touch_point_background_alpha_animation.xml", "java/res/anim/iph_touch_point_background_animation.xml", "java/res/color/dark_text_color_list.xml", - "java/res/drawable-hdpi/tabstrip_selected.png", - "java/res/drawable-mdpi/tabstrip_selected.png", "java/res/drawable-v21/fake_search_box_bg_incognito.xml", - "java/res/drawable-xhdpi/tabstrip_selected.png", - "java/res/drawable-xxhdpi/tabstrip_selected.png", - "java/res/drawable-xxxhdpi/tabstrip_selected.png", "java/res/drawable/fake_search_box_text_box_bg_incognito.xml", "java/res/drawable/hovered_tab_grid_card_background.xml", "java/res/drawable/ic_check_googblue_20dp_animated.xml", @@ -49,6 +44,9 @@ android_resources("java_resources") { "java/res/drawable/tab_grid_selection_list_icon.xml", "java/res/drawable/tab_strip_fading_edge_end.xml", "java/res/drawable/tab_strip_fading_edge_start.xml", + "java/res/drawable/tab_strip_favicon_circle.xml", + "java/res/drawable/tab_strip_selected_ring.xml", + "java/res/drawable/tab_strip_selected_ring_incognito.xml", "java/res/drawable/tabstrip_favicon_background.xml", "java/res/drawable/ungroup_bar_background.xml", "java/res/layout/bottom_tab_grid_toolbar.xml", diff --git a/chrome/android/features/tab_ui/java/res/drawable-hdpi/tabstrip_selected.png b/chrome/android/features/tab_ui/java/res/drawable-hdpi/tabstrip_selected.png deleted file mode 100644 index 0ff59dd0b73f70..00000000000000 Binary files a/chrome/android/features/tab_ui/java/res/drawable-hdpi/tabstrip_selected.png and /dev/null differ diff --git a/chrome/android/features/tab_ui/java/res/drawable-mdpi/tabstrip_selected.png b/chrome/android/features/tab_ui/java/res/drawable-mdpi/tabstrip_selected.png deleted file mode 100644 index a756a16b0ac396..00000000000000 Binary files a/chrome/android/features/tab_ui/java/res/drawable-mdpi/tabstrip_selected.png and /dev/null differ diff --git a/chrome/android/features/tab_ui/java/res/drawable-xhdpi/tabstrip_selected.png b/chrome/android/features/tab_ui/java/res/drawable-xhdpi/tabstrip_selected.png deleted file mode 100644 index 7a3241de33e318..00000000000000 Binary files a/chrome/android/features/tab_ui/java/res/drawable-xhdpi/tabstrip_selected.png and /dev/null differ diff --git a/chrome/android/features/tab_ui/java/res/drawable-xxhdpi/tabstrip_selected.png b/chrome/android/features/tab_ui/java/res/drawable-xxhdpi/tabstrip_selected.png deleted file mode 100644 index ac25ec72ebbf42..00000000000000 Binary files a/chrome/android/features/tab_ui/java/res/drawable-xxhdpi/tabstrip_selected.png and /dev/null differ diff --git a/chrome/android/features/tab_ui/java/res/drawable-xxxhdpi/tabstrip_selected.png b/chrome/android/features/tab_ui/java/res/drawable-xxxhdpi/tabstrip_selected.png deleted file mode 100644 index fdfd3838f1ba5f..00000000000000 Binary files a/chrome/android/features/tab_ui/java/res/drawable-xxxhdpi/tabstrip_selected.png and /dev/null differ diff --git a/chrome/android/features/tab_ui/java/res/drawable/tab_strip_favicon_circle.xml b/chrome/android/features/tab_ui/java/res/drawable/tab_strip_favicon_circle.xml new file mode 100644 index 00000000000000..bb9f8bc233acc4 --- /dev/null +++ b/chrome/android/features/tab_ui/java/res/drawable/tab_strip_favicon_circle.xml @@ -0,0 +1,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/chrome/android/features/tab_ui/java/res/drawable/tab_strip_selected_ring.xml b/chrome/android/features/tab_ui/java/res/drawable/tab_strip_selected_ring.xml new file mode 100644 index 00000000000000..2d128e3f41a3ce --- /dev/null +++ b/chrome/android/features/tab_ui/java/res/drawable/tab_strip_selected_ring.xml @@ -0,0 +1,43 @@ + + + + + + diff --git a/chrome/android/features/tab_ui/java/res/drawable/tab_strip_selected_ring_incognito.xml b/chrome/android/features/tab_ui/java/res/drawable/tab_strip_selected_ring_incognito.xml new file mode 100644 index 00000000000000..9175b491d99c9e --- /dev/null +++ b/chrome/android/features/tab_ui/java/res/drawable/tab_strip_selected_ring_incognito.xml @@ -0,0 +1,43 @@ + + + + + + diff --git a/chrome/android/features/tab_ui/java/res/drawable/tabstrip_favicon_background.xml b/chrome/android/features/tab_ui/java/res/drawable/tabstrip_favicon_background.xml index ea4aa9f42a7263..19dada8e057227 100644 --- a/chrome/android/features/tab_ui/java/res/drawable/tabstrip_favicon_background.xml +++ b/chrome/android/features/tab_ui/java/res/drawable/tabstrip_favicon_background.xml @@ -6,9 +6,9 @@ diff --git a/chrome/android/features/tab_ui/java/res/layout/tab_strip_item.xml b/chrome/android/features/tab_ui/java/res/layout/tab_strip_item.xml index cfdb441547196f..d4c5fb223e93db 100644 --- a/chrome/android/features/tab_ui/java/res/layout/tab_strip_item.xml +++ b/chrome/android/features/tab_ui/java/res/layout/tab_strip_item.xml @@ -9,6 +9,5 @@ diff --git a/chrome/android/features/tab_ui/java/res/values/dimens.xml b/chrome/android/features/tab_ui/java/res/values/dimens.xml index 77418764acf1bd..ec237af1399fe3 100644 --- a/chrome/android/features/tab_ui/java/res/values/dimens.xml +++ b/chrome/android/features/tab_ui/java/res/values/dimens.xml @@ -29,8 +29,9 @@ 56dp 8dp 8dp - 46dp 48dp + 3dp + 14dp 144dp 14dp 18dp diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherCoordinator.java index 09b44cded6ef2b..936dfca2f9f6c4 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherCoordinator.java @@ -39,7 +39,7 @@ class SingleTabSwitcherCoordinator implements TabSwitcher { container.addView(singleTabView); mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create( propertyModel, singleTabView, SingleTabViewBinder::bind); - mTabListFaviconProvider = new TabListFaviconProvider(activity); + mTabListFaviconProvider = new TabListFaviconProvider(activity, false); mMediator = new SingleTabSwitcherMediator( propertyModel, activity.getTabModelSelector(), mTabListFaviconProvider); diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java index 73b91b0e29df1d..e70cfad2a9793a 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java @@ -205,7 +205,7 @@ private void fetch() { // TODO (https://crbug.com/1048632): Use the current profile (i.e., regular profile or // incognito profile) instead of always using regular profile. It works correctly now, but // it is not safe. - mTabListFaviconProvider = new TabListFaviconProvider(context); + mTabListFaviconProvider = new TabListFaviconProvider(context, false); // Initialize Paints to use. mEmptyThumbnailPaint = new Paint(); diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java index 71d0fbad457d91..616f9c45a876b0 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java @@ -230,7 +230,8 @@ public class TabListCoordinator implements Destroyable { // TODO (https://crbug.com/1048632): Use the current profile (i.e., regular profile or // incognito profile) instead of always using regular profile. It works correctly now, but // it is not safe. - TabListFaviconProvider tabListFaviconProvider = new TabListFaviconProvider(mContext); + TabListFaviconProvider tabListFaviconProvider = + new TabListFaviconProvider(mContext, mMode == TabListMode.STRIP); mMediator = new TabListMediator(context, mModel, tabModelSelector, thumbnailProvider, titleProvider, tabListFaviconProvider, actionOnRelatedTabs, diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListFaviconProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListFaviconProvider.java index 7000dc13f5bf7e..8980d1b0f8fade 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListFaviconProvider.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListFaviconProvider.java @@ -10,6 +10,7 @@ import android.graphics.Canvas; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; +import android.graphics.drawable.LayerDrawable; import androidx.annotation.ColorInt; import androidx.appcompat.content.res.AppCompatResources; @@ -20,6 +21,7 @@ import org.chromium.chrome.browser.ui.favicon.FaviconHelper; import org.chromium.chrome.browser.ui.favicon.FaviconUtils; import org.chromium.chrome.tab_ui.R; +import org.chromium.ui.base.ViewUtils; import java.util.List; @@ -27,10 +29,19 @@ * Provider for processed favicons in Tab list. */ public class TabListFaviconProvider { + static final int FAVICON_BACKGROUND_DEFAULT_ALPHA = 255; + static final int FAVICON_BACKGROUND_SELECTED_ALPHA = 0; + private static Drawable sRoundedGlobeDrawable; + private static Drawable sRoundedGlobeDrawableForStrip; private static Drawable sRoundedChromeDrawable; + private static Drawable sRoundedChromeDrawableForStrip; private static Drawable sRoundedComposedDefaultDrawable; + private final int mStripFaviconSize; + private final int mDefaultFaviconSize; private final int mFaviconSize; + private final int mFaviconInset; + private final boolean mIsTabStrip; private final Context mContext; @ColorInt private final int mDefaultIconColor; @@ -43,29 +54,45 @@ public class TabListFaviconProvider { /** * Construct the provider that provides favicons for tab list. - * @param context The context to use for accessing {@link android.content.res.Resources} + * @param context The context to use for accessing {@link android.content.res.Resources} + * @param isTabStrip Indicator for whether this class provides favicons for tab strip or not. * */ - public TabListFaviconProvider(Context context) { + public TabListFaviconProvider(Context context, boolean isTabStrip) { mContext = context; - mFaviconSize = context.getResources().getDimensionPixelSize(R.dimen.default_favicon_size); + mDefaultFaviconSize = + context.getResources().getDimensionPixelSize(R.dimen.default_favicon_size); + mStripFaviconSize = + context.getResources().getDimensionPixelSize(R.dimen.tab_strip_favicon_size); + mFaviconSize = isTabStrip ? mStripFaviconSize : mDefaultFaviconSize; + mFaviconInset = ViewUtils.dpToPx(context, + context.getResources().getDimensionPixelSize(R.dimen.tab_strip_favicon_inset)); + mIsTabStrip = isTabStrip; if (sRoundedGlobeDrawable == null) { // TODO(crbug.com/1066709): From Android Developer Documentation, we should avoid // resizing vector drawable. Drawable globeDrawable = AppCompatResources.getDrawable(context, R.drawable.ic_globe_24dp); - Bitmap globeBitmap = - Bitmap.createBitmap(mFaviconSize, mFaviconSize, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(globeBitmap); - globeDrawable.setBounds(0, 0, mFaviconSize, mFaviconSize); - globeDrawable.draw(canvas); - sRoundedGlobeDrawable = processBitmap(globeBitmap); + sRoundedGlobeDrawable = processBitmap( + getResizedBitmapFromDrawable(globeDrawable, mDefaultFaviconSize), false); + } + if (sRoundedGlobeDrawableForStrip == null) { + Drawable globeDrawable = + AppCompatResources.getDrawable(context, R.drawable.ic_globe_24dp); + sRoundedGlobeDrawableForStrip = processBitmap( + getResizedBitmapFromDrawable(globeDrawable, mStripFaviconSize), true); } if (sRoundedChromeDrawable == null) { Bitmap chromeBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.chromelogo16); - sRoundedChromeDrawable = processBitmap(chromeBitmap); + sRoundedChromeDrawable = processBitmap(chromeBitmap, false); + } + if (sRoundedChromeDrawableForStrip == null) { + Drawable chromeDrawable = + AppCompatResources.getDrawable(context, R.drawable.chromelogo16); + sRoundedChromeDrawableForStrip = processBitmap( + getResizedBitmapFromDrawable(chromeDrawable, mStripFaviconSize), true); } if (sRoundedComposedDefaultDrawable == null) { sRoundedComposedDefaultDrawable = @@ -87,9 +114,27 @@ public boolean isInitialized() { return mIsInitialized; } - private Drawable processBitmap(Bitmap bitmap) { - return FaviconUtils.createRoundedBitmapDrawable(mContext.getResources(), - Bitmap.createScaledBitmap(bitmap, mFaviconSize, mFaviconSize, true)); + private Bitmap getResizedBitmapFromDrawable(Drawable drawable, int size) { + Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, size, size); + drawable.draw(canvas); + return bitmap; + } + + private Drawable processBitmap(Bitmap bitmap, boolean isTabStrip) { + int size = isTabStrip ? mStripFaviconSize : mDefaultFaviconSize; + Drawable favicon = FaviconUtils.createRoundedBitmapDrawable( + mContext.getResources(), Bitmap.createScaledBitmap(bitmap, size, size, true)); + if (!isTabStrip) { + return favicon; + } + Drawable circleBackground = + AppCompatResources.getDrawable(mContext, R.drawable.tab_strip_favicon_circle); + Drawable[] layers = {circleBackground, favicon}; + LayerDrawable layerDrawable = new LayerDrawable(layers); + layerDrawable.setLayerInset(1, mFaviconInset, mFaviconInset, mFaviconInset, mFaviconInset); + return layerDrawable; } /** @@ -116,7 +161,7 @@ public void getFaviconForUrlAsync( if (image == null) { faviconCallback.onResult(getRoundedGlobeDrawable(isIncognito)); } else { - faviconCallback.onResult(processBitmap(image)); + faviconCallback.onResult(processBitmap(image, mIsTabStrip)); } }); } @@ -135,7 +180,7 @@ public Drawable getFaviconForUrlSync(String url, boolean isIncognito, Bitmap ico return isNativeUrl ? getRoundedChromeDrawable(isIncognito) : getRoundedGlobeDrawable(isIncognito); } else { - return processBitmap(icon); + return processBitmap(icon, mIsTabStrip); } } @@ -153,7 +198,7 @@ public void getComposedFaviconImageAsync( if (image == null) { faviconCallback.onResult(getDefaultComposedImage(isIncognito)); } else { - faviconCallback.onResult(processBitmap(image)); + faviconCallback.onResult(processBitmap(image, mIsTabStrip)); } }); } @@ -163,10 +208,16 @@ private Drawable getDefaultComposedImage(boolean isIncognito) { } private Drawable getRoundedChromeDrawable(boolean isIncognito) { + if (mIsTabStrip) { + return sRoundedChromeDrawableForStrip; + } return getTintedDrawable(sRoundedChromeDrawable, isIncognito); } private Drawable getRoundedGlobeDrawable(boolean isIncognito) { + if (mIsTabStrip) { + return sRoundedGlobeDrawableForStrip; + } return getTintedDrawable(sRoundedGlobeDrawable, isIncognito); } diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java index 62b3f254448eee..3d656c6bbd5fd6 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java @@ -120,5 +120,5 @@ public class TabProperties { public static final PropertyKey[] ALL_KEYS_TAB_STRIP = new PropertyKey[] {TAB_ID, TAB_SELECTED_LISTENER, TAB_CLOSED_LISTENER, FAVICON, - IS_SELECTED, TITLE, TABSTRIP_FAVICON_BACKGROUND_COLOR_ID}; + IS_SELECTED, TITLE, TABSTRIP_FAVICON_BACKGROUND_COLOR_ID, IS_INCOGNITO}; } diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java index ccca39884dd472..4cc2a63d57353d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java @@ -4,6 +4,9 @@ package org.chromium.chrome.browser.tasks.tab_management; +import static org.chromium.chrome.browser.tasks.tab_management.TabListFaviconProvider.FAVICON_BACKGROUND_DEFAULT_ALPHA; +import static org.chromium.chrome.browser.tasks.tab_management.TabListFaviconProvider.FAVICON_BACKGROUND_SELECTED_ALPHA; + import android.graphics.drawable.Drawable; import android.view.ViewGroup; import android.widget.ImageButton; @@ -39,10 +42,14 @@ public static void bind( } if (TabProperties.IS_SELECTED == propertyKey) { ImageButton button = (ImageButton) view.fastFindViewById(R.id.tab_strip_item_button); + int selectedDrawableId = model.get(TabProperties.IS_INCOGNITO) + ? R.drawable.tab_strip_selected_ring_incognito + : R.drawable.tab_strip_selected_ring; view.setForeground(model.get(TabProperties.IS_SELECTED) - ? ResourcesCompat.getDrawable(view.getResources(), - R.drawable.tabstrip_selected, view.getContext().getTheme()) + ? ResourcesCompat.getDrawable(view.getResources(), selectedDrawableId, + view.getContext().getTheme()) : null); + String title = model.get(TabProperties.TITLE); if (model.get(TabProperties.IS_SELECTED)) { button.setOnClickListener(v -> { @@ -51,6 +58,7 @@ public static void bind( }); button.setContentDescription(view.getContext().getString( R.string.accessibility_tabstrip_btn_close_tab, title)); + button.getBackground().setAlpha(FAVICON_BACKGROUND_SELECTED_ALPHA); } else { button.setOnClickListener(v -> { model.get(TabProperties.TAB_SELECTED_LISTENER) @@ -58,6 +66,7 @@ public static void bind( }); button.setContentDescription( view.getContext().getString(R.string.accessibility_tabstrip_tab, title)); + button.getBackground().setAlpha(FAVICON_BACKGROUND_DEFAULT_ALPHA); } } else if (TabProperties.FAVICON == propertyKey) { Drawable faviconDrawable = model.get(TabProperties.FAVICON); @@ -66,6 +75,11 @@ public static void bind( ViewCompat.setBackgroundTintList(button, AppCompatResources.getColorStateList(view.getContext(), model.get(TabProperties.TABSTRIP_FAVICON_BACKGROUND_COLOR_ID))); + if (!model.get(TabProperties.IS_SELECTED)) { + button.getBackground().setAlpha(FAVICON_BACKGROUND_DEFAULT_ALPHA); + } else { + button.getBackground().setAlpha(FAVICON_BACKGROUND_SELECTED_ALPHA); + } if (faviconDrawable != null) { button.setImageDrawable(faviconDrawable); } diff --git a/chrome/test/data/android/render_tests/TabGroupUiTest.10th_tab_selected.Nexus_5X-23.png.sha1 b/chrome/test/data/android/render_tests/TabGroupUiTest.10th_tab_selected.Nexus_5X-23.png.sha1 index 9ba4b27a5ec537..f853464584c0cd 100644 --- a/chrome/test/data/android/render_tests/TabGroupUiTest.10th_tab_selected.Nexus_5X-23.png.sha1 +++ b/chrome/test/data/android/render_tests/TabGroupUiTest.10th_tab_selected.Nexus_5X-23.png.sha1 @@ -1 +1 @@ -2cc69816ea9b0f6bbb765297d4d3fde54dae3a3d \ No newline at end of file +5713f6c62cefc91492f211a5badb30ca86a455c7 \ No newline at end of file diff --git a/chrome/test/data/android/render_tests/TabGroupUiTest.11th_tab_selected.Nexus_5X-23.png.sha1 b/chrome/test/data/android/render_tests/TabGroupUiTest.11th_tab_selected.Nexus_5X-23.png.sha1 index 9ba4b27a5ec537..f853464584c0cd 100644 --- a/chrome/test/data/android/render_tests/TabGroupUiTest.11th_tab_selected.Nexus_5X-23.png.sha1 +++ b/chrome/test/data/android/render_tests/TabGroupUiTest.11th_tab_selected.Nexus_5X-23.png.sha1 @@ -1 +1 @@ -2cc69816ea9b0f6bbb765297d4d3fde54dae3a3d \ No newline at end of file +5713f6c62cefc91492f211a5badb30ca86a455c7 \ No newline at end of file diff --git a/chrome/test/data/android/render_tests/TabGroupUiTest.5th_tab_selected.Nexus_5X-23.png.sha1 b/chrome/test/data/android/render_tests/TabGroupUiTest.5th_tab_selected.Nexus_5X-23.png.sha1 index 99f3ac07ff6dab..89bdff875bcf69 100644 --- a/chrome/test/data/android/render_tests/TabGroupUiTest.5th_tab_selected.Nexus_5X-23.png.sha1 +++ b/chrome/test/data/android/render_tests/TabGroupUiTest.5th_tab_selected.Nexus_5X-23.png.sha1 @@ -1 +1 @@ -5598051527fc6b8e3302a6923b35c5ef2b50446d \ No newline at end of file +c449c79435992d4082fe2ece1bf5c1da933b7745 \ No newline at end of file