[APS] Update tab container visibility and color on tab hover events
TODO (crbug.com/1469949): Add fade-in animation on the TSR tab container on hover. Demo: https://drive.google.com/file/d/1tuqrtr-LkzOdiYoVv7ORR8yvIbAuSYyo/view?usp=sharing Screenshots: GM2: Light: https://screenshot.googleplex.com/APnXK87WCC56T8s Dark: https://screenshot.googleplex.com/48pRov7iwiiRDg5 Incognito: https://screenshot.googleplex.com/3Xp67zZNxbpbzAB Folio: Light: https://screenshot.googleplex.com/4xpqG8fZ3gwEBoK Dark: https://screenshot.googleplex.com/KbYjZph9AQv5E8c Incognito: https://screenshot.googleplex.com/3Xd3LtjhwM6yjmY Detached: Light: https://screenshot.googleplex.com/39vA7ohVPWkMLGu Dark: https://screenshot.googleplex.com/YAaoz2qf3xZeaw4 Incognito: https://screenshot.googleplex.com/9aE7dgb4tESg8hX Low-Coverage-Reason: Tests for updates in this CL require execution on a tablet, that is not available in the CQ; adequate test coverage has been added for these changes. Bug: 1451925 Change-Id: Ied4a403e46669a5b3bc9f95d33fe482919842411 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4717726 Reviewed-by: Theresa Sullivan <twellington@chromium.org> Commit-Queue: Aishwarya Rajesh <aishwaryarj@google.com> Reviewed-by: Neil Coronado <nemco@google.com> Cr-Commit-Position: refs/heads/main@{#1180649}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
b108bb5010
commit
ea17bbdc76
chrome
android
BUILD.gnchrome_java_sources.gni
features
tab_ui
public
java
src
org
chromium
chrome
browser
compositor
bottombar
layouts
eventfilter
overlays
scene_layer
offlinepages
indicator
payments
javatests
src
org
chromium
chrome
browser
compositor
overlays
strip
junit
src
org
chromium
chrome
browser
compositor
layouts
eventfilter
overlays
scene_layer
browser
ui
android
theme
toolbar
java
src
org
chromium
chrome
browser
toolbar
docs/ui/android
@@ -293,6 +293,7 @@ if (current_toolchain == default_toolchain) {
|
|||||||
"//chrome/android/features/start_surface:public_java",
|
"//chrome/android/features/start_surface:public_java",
|
||||||
"//chrome/android/features/tab_ui:tab_suggestions_java",
|
"//chrome/android/features/tab_ui:tab_suggestions_java",
|
||||||
"//chrome/android/features/tab_ui/public:java",
|
"//chrome/android/features/tab_ui/public:java",
|
||||||
|
"//chrome/android/features/tab_ui/public:ui_java_resources",
|
||||||
"//chrome/android/modules/cablev2_authenticator/public:java",
|
"//chrome/android/modules/cablev2_authenticator/public:java",
|
||||||
"//chrome/android/modules/image_editor/provider:java",
|
"//chrome/android/modules/image_editor/provider:java",
|
||||||
"//chrome/android/modules/stack_unwinder/provider:java",
|
"//chrome/android/modules/stack_unwinder/provider:java",
|
||||||
|
@@ -22,7 +22,6 @@ chrome_java_sources = [
|
|||||||
"java/src/org/chromium/chrome/browser/ChromeInactivityTracker.java",
|
"java/src/org/chromium/chrome/browser/ChromeInactivityTracker.java",
|
||||||
"java/src/org/chromium/chrome/browser/ChromeKeyboardVisibilityDelegate.java",
|
"java/src/org/chromium/chrome/browser/ChromeKeyboardVisibilityDelegate.java",
|
||||||
"java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java",
|
"java/src/org/chromium/chrome/browser/ChromeLocalizationUtils.java",
|
||||||
"java/src/org/chromium/chrome/browser/ChromeSemanticColorUtils.java",
|
|
||||||
"java/src/org/chromium/chrome/browser/ChromeStrictMode.java",
|
"java/src/org/chromium/chrome/browser/ChromeStrictMode.java",
|
||||||
"java/src/org/chromium/chrome/browser/ChromeStringConstants.java",
|
"java/src/org/chromium/chrome/browser/ChromeStringConstants.java",
|
||||||
"java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java",
|
"java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java",
|
||||||
|
@@ -33,6 +33,7 @@ android_library("java") {
|
|||||||
deps = [
|
deps = [
|
||||||
":ui_java_resources",
|
":ui_java_resources",
|
||||||
"//chrome/browser/flags:java",
|
"//chrome/browser/flags:java",
|
||||||
|
"//chrome/browser/ui/android/theme:java",
|
||||||
"//components/browser_ui/styles/android:java",
|
"//components/browser_ui/styles/android:java",
|
||||||
"//components/browser_ui/styles/android:java_resources",
|
"//components/browser_ui/styles/android:java_resources",
|
||||||
"//third_party/androidx:androidx_annotation_annotation_java",
|
"//third_party/androidx:androidx_annotation_annotation_java",
|
||||||
|
@@ -9,4 +9,10 @@ found in the LICENSE file.
|
|||||||
<!-- Tab strip container alpha values -->
|
<!-- Tab strip container alpha values -->
|
||||||
<item name="bg_tabstrip_tab_detached_startup_alpha" format="float" type="dimen">0.03</item>
|
<item name="bg_tabstrip_tab_detached_startup_alpha" format="float" type="dimen">0.03</item>
|
||||||
<item name="bg_tabstrip_tab_folio_startup_alpha" format="float" type="dimen">0.05</item>
|
<item name="bg_tabstrip_tab_folio_startup_alpha" format="float" type="dimen">0.05</item>
|
||||||
|
|
||||||
|
<!-- Tab strip container hover color alpha values -->
|
||||||
|
<item name="gm2_tab_inactive_hover_alpha" format="float" type="dimen">0.08</item>
|
||||||
|
<item name="tsr_detached_tab_inactive_hover_alpha_light" format="float" type="dimen">0.05</item>
|
||||||
|
<item name="tsr_detached_tab_inactive_hover_alpha_dark" format="float" type="dimen">0.12</item>
|
||||||
|
<item name="tsr_folio_tab_inactive_hover_alpha" format="float" type="dimen">0.08</item>
|
||||||
</resources>
|
</resources>
|
@@ -8,8 +8,10 @@ import android.content.Context;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
|
||||||
import androidx.annotation.ColorInt;
|
import androidx.annotation.ColorInt;
|
||||||
|
import androidx.core.content.res.ResourcesCompat;
|
||||||
|
|
||||||
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
||||||
|
import org.chromium.chrome.browser.ui.theme.ChromeSemanticColorUtils;
|
||||||
import org.chromium.components.browser_ui.styles.ChromeColors;
|
import org.chromium.components.browser_ui.styles.ChromeColors;
|
||||||
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
||||||
import org.chromium.ui.util.ColorUtils;
|
import org.chromium.ui.util.ColorUtils;
|
||||||
@@ -54,23 +56,27 @@ public class TabUiThemeUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the color for the tab container based on experiment arm, incognito mode, foreground,
|
* Returns the color for the tab container based on experiment arm, incognito mode, foreground,
|
||||||
* reordering, and placeholder state.
|
* reordering, placeholder, and hover state.
|
||||||
*
|
*
|
||||||
* @param context {@link Context} used to retrieve color.
|
* @param context {@link Context} used to retrieve color.
|
||||||
* @param isIncognito Whether the color is used for incognito mode.
|
* @param isIncognito Whether the color is used for incognito mode.
|
||||||
* @param foreground Whether the tab is in the foreground.
|
* @param foreground Whether the tab is in the foreground.
|
||||||
* @param isReordering Whether the tab is being reordered.
|
* @param isReordering Whether the tab is being reordered.
|
||||||
* @param isPlaceholder Whether the tab is a placeholder "ghost" tab
|
* @param isPlaceholder Whether the tab is a placeholder "ghost" tab.
|
||||||
|
* @param isHovered Whether the tab is hovered on.
|
||||||
* @return The color for the tab container.
|
* @return The color for the tab container.
|
||||||
*/
|
*/
|
||||||
public static @ColorInt int getTabStripContainerColor(Context context, boolean isIncognito,
|
// TODO (crbug.com/1469465): Encapsulate tab properties in a state object.
|
||||||
boolean foreground, boolean isReordering, boolean isPlaceholder) {
|
public static int getTabStripContainerColor(Context context, boolean isIncognito,
|
||||||
|
boolean foreground, boolean isReordering, boolean isPlaceholder, boolean isHovered) {
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
if (TabManagementFieldTrial.isTabStripFolioEnabled()) {
|
if (TabManagementFieldTrial.isTabStripFolioEnabled()) {
|
||||||
return ChromeColors.getDefaultThemeColor(context, isIncognito);
|
return ChromeColors.getDefaultThemeColor(context, isIncognito);
|
||||||
} else if (TabManagementFieldTrial.isTabStripDetachedEnabled()) {
|
} else if (TabManagementFieldTrial.isTabStripDetachedEnabled()) {
|
||||||
return getTabStripDetachedTabColor(context, isIncognito, isReordering);
|
return getTabStripDetachedTabColor(context, isIncognito, isReordering);
|
||||||
}
|
}
|
||||||
|
} else if (isHovered) {
|
||||||
|
return getHoveredTabContainerColor(context, isIncognito);
|
||||||
} else if (isPlaceholder) {
|
} else if (isPlaceholder) {
|
||||||
return getTabStripStartupContainerColor(context);
|
return getTabStripStartupContainerColor(context);
|
||||||
} else {
|
} else {
|
||||||
@@ -85,6 +91,24 @@ public class TabUiThemeUtil {
|
|||||||
return Color.TRANSPARENT;
|
return Color.TRANSPARENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the color for the hovered tab container. */
|
||||||
|
private static @ColorInt int getHoveredTabContainerColor(Context context, boolean isIncognito) {
|
||||||
|
int baseColor = isIncognito ? context.getColor(R.color.baseline_primary_80)
|
||||||
|
: ChromeSemanticColorUtils.getTabInactiveHoverColor(context);
|
||||||
|
float alpha;
|
||||||
|
if (TabManagementFieldTrial.isTabStripFolioEnabled()) {
|
||||||
|
alpha = ResourcesCompat.getFloat(
|
||||||
|
context.getResources(), R.dimen.tsr_folio_tab_inactive_hover_alpha);
|
||||||
|
} else {
|
||||||
|
alpha = ColorUtils.inNightMode(context) || isIncognito
|
||||||
|
? ResourcesCompat.getFloat(context.getResources(),
|
||||||
|
R.dimen.tsr_detached_tab_inactive_hover_alpha_dark)
|
||||||
|
: ResourcesCompat.getFloat(context.getResources(),
|
||||||
|
R.dimen.tsr_detached_tab_inactive_hover_alpha_light);
|
||||||
|
}
|
||||||
|
return ColorUtils.setAlphaComponent(baseColor, (int) (alpha * 255));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the color for the tab strip startup "ghost" containers.
|
* Returns the color for the tab strip startup "ghost" containers.
|
||||||
*/
|
*/
|
||||||
|
@@ -861,7 +861,7 @@ public class OverlayPanel extends OverlayPanelAnimation
|
|||||||
public void onHoverMove(float x, float y) {}
|
public void onHoverMove(float x, float y) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHoverExit(float x, float y) {}
|
public void onHoverExit() {}
|
||||||
|
|
||||||
// SwipeHandler implementation.
|
// SwipeHandler implementation.
|
||||||
|
|
||||||
|
@@ -18,9 +18,9 @@ import org.chromium.base.MathUtils;
|
|||||||
import org.chromium.base.supplier.ObservableSupplier;
|
import org.chromium.base.supplier.ObservableSupplier;
|
||||||
import org.chromium.base.supplier.ObservableSupplierImpl;
|
import org.chromium.base.supplier.ObservableSupplierImpl;
|
||||||
import org.chromium.chrome.R;
|
import org.chromium.chrome.R;
|
||||||
import org.chromium.chrome.browser.ChromeSemanticColorUtils;
|
|
||||||
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelState;
|
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelState;
|
||||||
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason;
|
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason;
|
||||||
|
import org.chromium.chrome.browser.ui.theme.ChromeSemanticColorUtils;
|
||||||
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
||||||
import org.chromium.ui.base.LocalizationUtils;
|
import org.chromium.ui.base.LocalizationUtils;
|
||||||
import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
|
import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
|
||||||
@@ -984,7 +984,6 @@ abstract class OverlayPanelBase {
|
|||||||
// Determine fading element opacities. The arrow icon needs to finish fading out before
|
// Determine fading element opacities. The arrow icon needs to finish fading out before
|
||||||
// the close icon starts fading in. Any other elements fading in or fading out should use
|
// the close icon starts fading in. Any other elements fading in or fading out should use
|
||||||
// the same percentage.
|
// the same percentage.
|
||||||
float fadingOutPercentage = Math.min(percentage, .5f) / .5f;
|
|
||||||
float fadingInPercentage = Math.max(percentage - .5f, 0.f) / .5f;
|
float fadingInPercentage = Math.max(percentage - .5f, 0.f) / .5f;
|
||||||
|
|
||||||
// Close Icon.
|
// Close Icon.
|
||||||
|
@@ -16,7 +16,6 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import org.chromium.base.MathUtils;
|
import org.chromium.base.MathUtils;
|
||||||
import org.chromium.chrome.R;
|
import org.chromium.chrome.R;
|
||||||
import org.chromium.chrome.browser.ChromeSemanticColorUtils;
|
|
||||||
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel;
|
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel;
|
||||||
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelAnimation;
|
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelAnimation;
|
||||||
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelInflater;
|
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelInflater;
|
||||||
@@ -26,6 +25,7 @@ import org.chromium.chrome.browser.contextualsearch.ContextualSearchPreferenceFr
|
|||||||
import org.chromium.chrome.browser.contextualsearch.ContextualSearchUma;
|
import org.chromium.chrome.browser.contextualsearch.ContextualSearchUma;
|
||||||
import org.chromium.chrome.browser.layouts.animation.CompositorAnimator;
|
import org.chromium.chrome.browser.layouts.animation.CompositorAnimator;
|
||||||
import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
|
import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
|
||||||
|
import org.chromium.chrome.browser.ui.theme.ChromeSemanticColorUtils;
|
||||||
import org.chromium.components.browser_ui.settings.SettingsLauncher;
|
import org.chromium.components.browser_ui.settings.SettingsLauncher;
|
||||||
import org.chromium.ui.base.LocalizationUtils;
|
import org.chromium.ui.base.LocalizationUtils;
|
||||||
import org.chromium.ui.base.ViewUtils;
|
import org.chromium.ui.base.ViewUtils;
|
||||||
|
@@ -262,7 +262,7 @@ public class GestureEventFilter extends EventFilter {
|
|||||||
} else if (action == MotionEvent.ACTION_HOVER_MOVE) {
|
} else if (action == MotionEvent.ACTION_HOVER_MOVE) {
|
||||||
mHandler.onHoverMove(e.getX() * mPxToDp, e.getY() * mPxToDp);
|
mHandler.onHoverMove(e.getX() * mPxToDp, e.getY() * mPxToDp);
|
||||||
} else if (action == MotionEvent.ACTION_HOVER_EXIT) {
|
} else if (action == MotionEvent.ACTION_HOVER_EXIT) {
|
||||||
mHandler.onHoverExit(e.getX() * mPxToDp, e.getY() * mPxToDp);
|
mHandler.onHoverExit();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -93,9 +93,6 @@ public interface GestureHandler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called on hover exit event.
|
* Called on hover exit event.
|
||||||
*
|
|
||||||
* @param x The X position at the end of the event in the host view space in dp.
|
|
||||||
* @param y The Y position at the end of the event in the host view space in dp.
|
|
||||||
*/
|
*/
|
||||||
void onHoverExit(float x, float y);
|
void onHoverExit();
|
||||||
}
|
}
|
||||||
|
95
chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
95
chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -142,9 +142,11 @@ public class StripLayoutHelper implements StripLayoutTab.StripLayoutTabDelegate
|
|||||||
private static final float NEW_TAB_BUTTON_BACKGROUND_HEIGHT_DP_TSR = 32.f;
|
private static final float NEW_TAB_BUTTON_BACKGROUND_HEIGHT_DP_TSR = 32.f;
|
||||||
private static final float NEW_TAB_BUTTON_PADDING_DP = 24.f;
|
private static final float NEW_TAB_BUTTON_PADDING_DP = 24.f;
|
||||||
private static final float NEW_TAB_BUTTON_TOUCH_TARGET_OFFSET = 12.f;
|
private static final float NEW_TAB_BUTTON_TOUCH_TARGET_OFFSET = 12.f;
|
||||||
private static final float FOLIO_ATTACHED_BOTTOM_MARGIN_DP = 0.f;
|
@VisibleForTesting
|
||||||
|
static final float FOLIO_ATTACHED_BOTTOM_MARGIN_DP = 0.f;
|
||||||
private static final float FOLIO_ANIM_INTERMEDIATE_MARGIN_DP = -12.f;
|
private static final float FOLIO_ANIM_INTERMEDIATE_MARGIN_DP = -12.f;
|
||||||
private static final float FOLIO_DETACHED_BOTTOM_MARGIN_DP = 4.f;
|
@VisibleForTesting
|
||||||
|
static final float FOLIO_DETACHED_BOTTOM_MARGIN_DP = 4.f;
|
||||||
private static final float BUTTON_DESIRED_TOUCH_TARGET_SIZE = 48.f;
|
private static final float BUTTON_DESIRED_TOUCH_TARGET_SIZE = 48.f;
|
||||||
private static final float NEW_TAB_BUTTON_DEFAULT_PRESSED_OPACITY = 0.2f;
|
private static final float NEW_TAB_BUTTON_DEFAULT_PRESSED_OPACITY = 0.2f;
|
||||||
private static final float NEW_TAB_BUTTON_DARK_DETACHED_OPACITY = 0.15f;
|
private static final float NEW_TAB_BUTTON_DARK_DETACHED_OPACITY = 0.15f;
|
||||||
@@ -258,6 +260,7 @@ public class StripLayoutHelper implements StripLayoutTab.StripLayoutTabDelegate
|
|||||||
private MultiInstanceManager mMultiInstanceManager;
|
private MultiInstanceManager mMultiInstanceManager;
|
||||||
private View mToolbarContainerView;
|
private View mToolbarContainerView;
|
||||||
private StripLayoutTab mActiveClickedTab;
|
private StripLayoutTab mActiveClickedTab;
|
||||||
|
private StripLayoutTab mLastHoveredTab;
|
||||||
private TabDropTarget mTabDropTarget;
|
private TabDropTarget mTabDropTarget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1038,10 +1041,12 @@ public class StripLayoutHelper implements StripLayoutTab.StripLayoutTabDelegate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setForegroundTabContainerVisible(StripLayoutTab tab, boolean selected) {
|
private void setTabContainerVisible(StripLayoutTab tab, boolean selected, boolean hovered) {
|
||||||
// Don't interrupt tab group background tab visibility.
|
// Don't interrupt tab group background tab visibility.
|
||||||
if (tab.getContainerOpacity() != TAB_OPACITY_VISIBLE_BACKGROUND) {
|
if (tab.getContainerOpacity() != TAB_OPACITY_VISIBLE_BACKGROUND) {
|
||||||
float containerOpacity = selected || tab.getIsPlaceholder()
|
// The container will be visible if the tab is selected/hovered on or is a placeholder
|
||||||
|
// tab.
|
||||||
|
float containerOpacity = selected || tab.getIsPlaceholder() || hovered
|
||||||
? TAB_OPACITY_VISIBLE_FOREGROUND
|
? TAB_OPACITY_VISIBLE_FOREGROUND
|
||||||
: TAB_OPACITY_HIDDEN;
|
: TAB_OPACITY_HIDDEN;
|
||||||
tab.setContainerOpacity(containerOpacity);
|
tab.setContainerOpacity(containerOpacity);
|
||||||
@@ -1049,10 +1054,11 @@ public class StripLayoutHelper implements StripLayoutTab.StripLayoutTabDelegate
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to show/hide dividers and the foreground tab container. Dividers are only necessary
|
* Called to show/hide dividers and the foreground/hovered tab container. Dividers are only
|
||||||
* between tabs that both do not have a visible tab container (foreground or background).
|
* necessary between tabs that both do not have a visible tab container (foreground or
|
||||||
|
* background).
|
||||||
*/
|
*/
|
||||||
private void updateForegroundTabContainersAndDividers() {
|
private void updateTabContainersAndDividers() {
|
||||||
if (!ChromeFeatureList.sTabStripRedesign.isEnabled()) return;
|
if (!ChromeFeatureList.sTabStripRedesign.isEnabled()) return;
|
||||||
|
|
||||||
// Validate the index. For example, the index can be {@link TabList.INVALID_TAB_INDEX} when
|
// Validate the index. For example, the index can be {@link TabList.INVALID_TAB_INDEX} when
|
||||||
@@ -1060,9 +1066,12 @@ public class StripLayoutHelper implements StripLayoutTab.StripLayoutTabDelegate
|
|||||||
int selectedIndex = mTabStateInitialized ? mModel.index() : mActiveTabIndexOnStartup;
|
int selectedIndex = mTabStateInitialized ? mModel.index() : mActiveTabIndexOnStartup;
|
||||||
if (selectedIndex < 0 || selectedIndex >= mStripTabs.length) return;
|
if (selectedIndex < 0 || selectedIndex >= mStripTabs.length) return;
|
||||||
|
|
||||||
|
int hoveredIndex = mLastHoveredTab != null ? findIndexForTab(mLastHoveredTab.getId())
|
||||||
|
: TabModel.INVALID_TAB_INDEX;
|
||||||
|
|
||||||
// Divider is never shown for the first tab.
|
// Divider is never shown for the first tab.
|
||||||
mStripTabs[0].setStartDividerVisible(false);
|
mStripTabs[0].setStartDividerVisible(false);
|
||||||
setForegroundTabContainerVisible(mStripTabs[0], selectedIndex == 0);
|
setTabContainerVisible(mStripTabs[0], selectedIndex == 0, hoveredIndex == 0);
|
||||||
// End divider for first tab is only shown in reorder mode when tab has trailing margin and
|
// End divider for first tab is only shown in reorder mode when tab has trailing margin and
|
||||||
// container is not visible.
|
// container is not visible.
|
||||||
boolean endDividerVisible = mInReorderMode
|
boolean endDividerVisible = mInReorderMode
|
||||||
@@ -1074,9 +1083,10 @@ public class StripLayoutHelper implements StripLayoutTab.StripLayoutTabDelegate
|
|||||||
final StripLayoutTab prevTab = mStripTabs[i - 1];
|
final StripLayoutTab prevTab = mStripTabs[i - 1];
|
||||||
final StripLayoutTab currTab = mStripTabs[i];
|
final StripLayoutTab currTab = mStripTabs[i];
|
||||||
boolean currTabSelected = selectedIndex == i;
|
boolean currTabSelected = selectedIndex == i;
|
||||||
|
boolean currTabHovered = hoveredIndex == i;
|
||||||
|
|
||||||
// Set container opacity.
|
// Set container opacity.
|
||||||
setForegroundTabContainerVisible(currTab, currTabSelected);
|
setTabContainerVisible(currTab, currTabSelected, currTabHovered);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start divider should be visible when:
|
* Start divider should be visible when:
|
||||||
@@ -1387,7 +1397,11 @@ public class StripLayoutHelper implements StripLayoutTab.StripLayoutTabDelegate
|
|||||||
*/
|
*/
|
||||||
public void onHoverEnter(float x, float y) {
|
public void onHoverEnter(float x, float y) {
|
||||||
if (!isPeripheralsSupportForTabStripEnabled()) return;
|
if (!isPeripheralsSupportForTabStripEnabled()) return;
|
||||||
// TODO (crbug.com/1451925): Handle tab strip hover enter event.
|
StripLayoutTab hoveredTab = getTabAtPosition(x);
|
||||||
|
// Hovered into a non-tab region on the strip.
|
||||||
|
if (hoveredTab == null) return;
|
||||||
|
updateLastHoveredTab(hoveredTab);
|
||||||
|
mUpdateHost.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1397,17 +1411,66 @@ public class StripLayoutHelper implements StripLayoutTab.StripLayoutTabDelegate
|
|||||||
*/
|
*/
|
||||||
public void onHoverMove(float x, float y) {
|
public void onHoverMove(float x, float y) {
|
||||||
if (!isPeripheralsSupportForTabStripEnabled()) return;
|
if (!isPeripheralsSupportForTabStripEnabled()) return;
|
||||||
// TODO (crbug.com/1451925): Handle tab strip hover move event.
|
StripLayoutTab hoveredTab = getTabAtPosition(x);
|
||||||
|
// Hovered into a non-tab region within the strip.
|
||||||
|
if (hoveredTab == null) {
|
||||||
|
clearLastHoveredTab();
|
||||||
|
mUpdateHost.requestUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hovered within the same tab that was last hovered into.
|
||||||
|
if (hoveredTab == mLastHoveredTab) return;
|
||||||
|
|
||||||
|
// Hovered from one tab to another tab on the strip, clear the former tab's hover state.
|
||||||
|
clearLastHoveredTab();
|
||||||
|
|
||||||
|
updateLastHoveredTab(hoveredTab);
|
||||||
|
mUpdateHost.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called on hover exit event.
|
* Called on hover exit event.
|
||||||
* @param x The x coordinate of the position of the hover exit event.
|
|
||||||
* @param y The y coordinate of the position of the hover exit event.
|
|
||||||
*/
|
*/
|
||||||
public void onHoverExit(float x, float y) {
|
public void onHoverExit() {
|
||||||
if (!isPeripheralsSupportForTabStripEnabled()) return;
|
if (!isPeripheralsSupportForTabStripEnabled()) return;
|
||||||
// TODO (crbug.com/1451925): Handle tab strip hover exit event.
|
clearLastHoveredTab();
|
||||||
|
mUpdateHost.requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLastHoveredTabForTesting(StripLayoutTab tab) {
|
||||||
|
mLastHoveredTab = tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
StripLayoutTab getLastHoveredTab() {
|
||||||
|
return mLastHoveredTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearLastHoveredTab() {
|
||||||
|
if (mLastHoveredTab == null) return;
|
||||||
|
// Remove the highlight from the last hovered tab.
|
||||||
|
updateHoveredFolioTabState(mLastHoveredTab, false);
|
||||||
|
mLastHoveredTab = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLastHoveredTab(StripLayoutTab hoveredTab) {
|
||||||
|
if (hoveredTab == null) return;
|
||||||
|
mLastHoveredTab = hoveredTab;
|
||||||
|
updateHoveredFolioTabState(mLastHoveredTab, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateHoveredFolioTabState(StripLayoutTab tab, boolean hovered) {
|
||||||
|
if (tab == null || !TabManagementFieldTrial.isTabStripFolioEnabled()) return;
|
||||||
|
// Do not update the attached state of a selected folio tab that is hovered on.
|
||||||
|
int selectedTabIndex = mModel != null ? mModel.index() : mActiveTabIndexOnStartup;
|
||||||
|
if (selectedTabIndex >= 0 && mStripTabs[selectedTabIndex] == findTabById(tab.getId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a folio tab is hovered on, detach its container.
|
||||||
|
tab.setFolioAttached(!hovered);
|
||||||
|
tab.setBottomMargin(
|
||||||
|
hovered ? FOLIO_DETACHED_BOTTOM_MARGIN_DP : FOLIO_ATTACHED_BOTTOM_MARGIN_DP);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPeripheralsSupportForTabStripEnabled() {
|
private boolean isPeripheralsSupportForTabStripEnabled() {
|
||||||
@@ -1904,7 +1967,7 @@ public class StripLayoutHelper implements StripLayoutTab.StripLayoutTabDelegate
|
|||||||
updateCloseButtons();
|
updateCloseButtons();
|
||||||
|
|
||||||
// 9. Show dividers between inactive tabs.
|
// 9. Show dividers between inactive tabs.
|
||||||
updateForegroundTabContainersAndDividers();
|
updateTabContainersAndDividers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeTabInitialPositions() {
|
private void computeTabInitialPositions() {
|
||||||
|
@@ -221,8 +221,8 @@ public class StripLayoutHelperManager implements SceneOverlay, PauseResumeWithNa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHoverExit(float x, float y) {
|
public void onHoverExit() {
|
||||||
getActiveStripLayoutHelper().onHoverExit(x, y);
|
getActiveStripLayoutHelper().onHoverExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private long time() {
|
private long time() {
|
||||||
@@ -472,9 +472,12 @@ public class StripLayoutHelperManager implements SceneOverlay, PauseResumeWithNa
|
|||||||
Tab selectedTab = mTabModelSelector.getCurrentModel().getTabAt(
|
Tab selectedTab = mTabModelSelector.getCurrentModel().getTabAt(
|
||||||
mTabModelSelector.getCurrentModel().index());
|
mTabModelSelector.getCurrentModel().index());
|
||||||
int selectedTabId = selectedTab == null ? TabModel.INVALID_TAB_INDEX : selectedTab.getId();
|
int selectedTabId = selectedTab == null ? TabModel.INVALID_TAB_INDEX : selectedTab.getId();
|
||||||
|
int hoveredTabId = getActiveStripLayoutHelper().getLastHoveredTab() == null
|
||||||
|
? TabModel.INVALID_TAB_INDEX
|
||||||
|
: getActiveStripLayoutHelper().getLastHoveredTab().getId();
|
||||||
mTabStripTreeProvider.pushAndUpdateStrip(this, mLayerTitleCacheSupplier.get(),
|
mTabStripTreeProvider.pushAndUpdateStrip(this, mLayerTitleCacheSupplier.get(),
|
||||||
resourceManager, getActiveStripLayoutHelper().getStripLayoutTabsToRender(), yOffset,
|
resourceManager, getActiveStripLayoutHelper().getStripLayoutTabsToRender(), yOffset,
|
||||||
selectedTabId);
|
selectedTabId, hoveredTabId);
|
||||||
return mTabStripTreeProvider;
|
return mTabStripTreeProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,7 +920,11 @@ public class StripLayoutHelperManager implements SceneOverlay, PauseResumeWithNa
|
|||||||
} else if (event == MotionEvent.ACTION_HOVER_MOVE) {
|
} else if (event == MotionEvent.ACTION_HOVER_MOVE) {
|
||||||
mTabStripEventHandler.onHoverMove(x, y);
|
mTabStripEventHandler.onHoverMove(x, y);
|
||||||
} else if (event == MotionEvent.ACTION_HOVER_EXIT) {
|
} else if (event == MotionEvent.ACTION_HOVER_EXIT) {
|
||||||
mTabStripEventHandler.onHoverExit(x, y);
|
mTabStripEventHandler.onHoverExit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setTabStripTreeProviderForTesting(TabStripSceneLayer tabStripTreeProvider) {
|
||||||
|
mTabStripTreeProvider = tabStripTreeProvider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
44
chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
44
chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
@@ -345,6 +345,10 @@ public class StripLayoutTab implements VirtualView {
|
|||||||
mFolioAttached = folioAttached;
|
mFolioAttached = folioAttached;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean getFolioAttachedForTesting() {
|
||||||
|
return mFolioAttached;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the id of the {@link Tab} this {@link StripLayoutTab} represents.
|
* Sets the id of the {@link Tab} this {@link StripLayoutTab} represents.
|
||||||
*/
|
*/
|
||||||
@@ -389,30 +393,48 @@ public class StripLayoutTab implements VirtualView {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param foreground Whether or not this tab is a foreground tab.
|
* @param foreground Whether or not this tab is a foreground tab.
|
||||||
* @return The tint color resource that represents the tab background.
|
* @param hovered Whether or not this tab is hovered on.
|
||||||
|
* @return The tint color resource that represents the tab background. A foreground tab will
|
||||||
|
* have the same tint irrespective of its hover state.
|
||||||
*/
|
*/
|
||||||
public int getTint(boolean foreground) {
|
public int getTint(boolean foreground, boolean hovered) {
|
||||||
|
hovered = ChromeFeatureList.isEnabled(
|
||||||
|
ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP)
|
||||||
|
&& hovered;
|
||||||
// TODO(https://crbug.com/1408276): Avoid calculating every time. Instead, store the tab's
|
// TODO(https://crbug.com/1408276): Avoid calculating every time. Instead, store the tab's
|
||||||
// color and only re-determine when the color could have changed (i.e. on selection).
|
// color and only re-determine when the color could have changed (i.e. on selection).
|
||||||
if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
|
if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
|
||||||
return TabUiThemeUtil.getTabStripContainerColor(
|
return TabUiThemeUtil.getTabStripContainerColor(
|
||||||
mContext, mIncognito, foreground, mIsReordering, mIsPlaceholder);
|
mContext, mIncognito, foreground, mIsReordering, mIsPlaceholder, hovered);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
return ChromeColors.getDefaultThemeColor(mContext, mIncognito);
|
return ChromeColors.getDefaultThemeColor(mContext, mIncognito);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// |defaultColor| represents the color of a background/inactive tab.
|
||||||
|
int defaultColor;
|
||||||
|
int overlayColor;
|
||||||
if (mIncognito) {
|
if (mIncognito) {
|
||||||
return mContext.getResources().getColor(
|
defaultColor = mContext.getResources().getColor(
|
||||||
R.color.baseline_neutral_10_with_neutral_0_alpha_30);
|
R.color.baseline_neutral_10_with_neutral_0_alpha_30);
|
||||||
|
overlayColor = mContext.getColor(R.color.baseline_neutral_90);
|
||||||
|
} else {
|
||||||
|
final int baseColor = ChromeColors.getSurfaceColor(
|
||||||
|
mContext, R.dimen.compositor_background_tab_elevation);
|
||||||
|
final float overlayAlpha = ResourcesCompat.getFloat(
|
||||||
|
mContext.getResources(), R.dimen.compositor_background_tab_overlay_alpha);
|
||||||
|
defaultColor = ColorUtils.getColorWithOverlay(baseColor, Color.BLACK, overlayAlpha);
|
||||||
|
overlayColor = MaterialColors.getColor(mContext, R.attr.colorOnSurface, TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int baseColor =
|
if (hovered) {
|
||||||
ChromeColors.getSurfaceColor(mContext, R.dimen.compositor_background_tab_elevation);
|
return ColorUtils.getColorWithOverlay(defaultColor, overlayColor,
|
||||||
final float overlayAlpha = ResourcesCompat.getFloat(
|
ResourcesCompat.getFloat(
|
||||||
mContext.getResources(), R.dimen.compositor_background_tab_overlay_alpha);
|
mContext.getResources(), R.dimen.gm2_tab_inactive_hover_alpha));
|
||||||
return ColorUtils.getColorWithOverlay(baseColor, Color.BLACK, overlayAlpha);
|
}
|
||||||
|
|
||||||
|
return defaultColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -426,7 +448,7 @@ public class StripLayoutTab implements VirtualView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
return getTint(true);
|
return getTint(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIncognito) {
|
if (mIncognito) {
|
||||||
@@ -434,7 +456,7 @@ public class StripLayoutTab implements VirtualView {
|
|||||||
R.color.baseline_neutral_10_with_neutral_0_alpha_30_with_neutral_variant_60_alpha_15);
|
R.color.baseline_neutral_10_with_neutral_0_alpha_30_with_neutral_variant_60_alpha_15);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int baseColor = getTint(false);
|
final int baseColor = getTint(false, false);
|
||||||
final int overlayColor = MaterialColors.getColor(mContext, R.attr.colorOutline, TAG);
|
final int overlayColor = MaterialColors.getColor(mContext, R.attr.colorOutline, TAG);
|
||||||
final float overlayAlpha = ResourcesCompat.getFloat(
|
final float overlayAlpha = ResourcesCompat.getFloat(
|
||||||
mContext.getResources(), R.dimen.compositor_background_tab_outline_alpha);
|
mContext.getResources(), R.dimen.compositor_background_tab_outline_alpha);
|
||||||
|
30
chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
30
chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
@@ -71,10 +71,14 @@ public class TabStripSceneLayer extends SceneOverlayLayer {
|
|||||||
* @param resourceManager A resource manager.
|
* @param resourceManager A resource manager.
|
||||||
* @param stripLayoutTabsToRender Array of strip layout tabs.
|
* @param stripLayoutTabsToRender Array of strip layout tabs.
|
||||||
* @param yOffset Current browser controls offset in dp.
|
* @param yOffset Current browser controls offset in dp.
|
||||||
|
* @param selectedTabId The ID of the selected tab.
|
||||||
|
* @param hoveredTabId The ID of the hovered tab, if any. If no tab is hovered on, this ID will
|
||||||
|
* be invalid.
|
||||||
*/
|
*/
|
||||||
public void pushAndUpdateStrip(StripLayoutHelperManager layoutHelper,
|
public void pushAndUpdateStrip(StripLayoutHelperManager layoutHelper,
|
||||||
LayerTitleCache layerTitleCache, ResourceManager resourceManager,
|
LayerTitleCache layerTitleCache, ResourceManager resourceManager,
|
||||||
StripLayoutTab[] stripLayoutTabsToRender, float yOffset, int selectedTabId) {
|
StripLayoutTab[] stripLayoutTabsToRender, float yOffset, int selectedTabId,
|
||||||
|
int hoveredTabId) {
|
||||||
if (mNativePtr == 0) return;
|
if (mNativePtr == 0) return;
|
||||||
final boolean visible = yOffset > -layoutHelper.getHeight();
|
final boolean visible = yOffset > -layoutHelper.getHeight();
|
||||||
// This will hide the tab strips if necessary.
|
// This will hide the tab strips if necessary.
|
||||||
@@ -84,7 +88,7 @@ public class TabStripSceneLayer extends SceneOverlayLayer {
|
|||||||
if (visible) {
|
if (visible) {
|
||||||
pushButtonsAndBackground(layoutHelper, resourceManager, yOffset);
|
pushButtonsAndBackground(layoutHelper, resourceManager, yOffset);
|
||||||
pushStripTabs(layoutHelper, layerTitleCache, resourceManager, stripLayoutTabsToRender,
|
pushStripTabs(layoutHelper, layerTitleCache, resourceManager, stripLayoutTabsToRender,
|
||||||
selectedTabId);
|
selectedTabId, hoveredTabId);
|
||||||
}
|
}
|
||||||
TabStripSceneLayerJni.get().finishBuildingFrame(mNativePtr, TabStripSceneLayer.this);
|
TabStripSceneLayerJni.get().finishBuildingFrame(mNativePtr, TabStripSceneLayer.this);
|
||||||
}
|
}
|
||||||
@@ -149,7 +153,7 @@ public class TabStripSceneLayer extends SceneOverlayLayer {
|
|||||||
|
|
||||||
private void pushStripTabs(StripLayoutHelperManager layoutHelper,
|
private void pushStripTabs(StripLayoutHelperManager layoutHelper,
|
||||||
LayerTitleCache layerTitleCache, ResourceManager resourceManager,
|
LayerTitleCache layerTitleCache, ResourceManager resourceManager,
|
||||||
StripLayoutTab[] stripTabs, int selectedTabId) {
|
StripLayoutTab[] stripTabs, int selectedTabId, int hoveredTabId) {
|
||||||
final int tabsCount = stripTabs != null ? stripTabs.length : 0;
|
final int tabsCount = stripTabs != null ? stripTabs.length : 0;
|
||||||
|
|
||||||
// TODO(https://crbug.com/1450380): Cleanup params, as some don't change and others are now
|
// TODO(https://crbug.com/1450380): Cleanup params, as some don't change and others are now
|
||||||
@@ -157,19 +161,21 @@ public class TabStripSceneLayer extends SceneOverlayLayer {
|
|||||||
for (int i = 0; i < tabsCount; i++) {
|
for (int i = 0; i < tabsCount; i++) {
|
||||||
final StripLayoutTab st = stripTabs[i];
|
final StripLayoutTab st = stripTabs[i];
|
||||||
boolean isSelected = st.getId() == selectedTabId;
|
boolean isSelected = st.getId() == selectedTabId;
|
||||||
|
boolean isHovered = st.getId() == hoveredTabId;
|
||||||
|
|
||||||
TabStripSceneLayerJni.get().putStripTabLayer(mNativePtr, TabStripSceneLayer.this,
|
TabStripSceneLayerJni.get().putStripTabLayer(mNativePtr, TabStripSceneLayer.this,
|
||||||
st.getId(), st.getCloseButton().getResourceId(), st.getDividerResourceId(),
|
st.getId(), st.getCloseButton().getResourceId(), st.getDividerResourceId(),
|
||||||
st.getResourceId(), st.getOutlineResourceId(), st.getCloseButton().getTint(),
|
st.getResourceId(), st.getOutlineResourceId(), st.getCloseButton().getTint(),
|
||||||
st.getDividerTint(), st.getTint(isSelected), st.getOutlineTint(isSelected),
|
st.getDividerTint(), st.getTint(isSelected, isHovered),
|
||||||
isSelected, st.getClosePressed(), layoutHelper.getWidth() * mDpToPx,
|
st.getOutlineTint(isSelected), isSelected, st.getClosePressed(),
|
||||||
st.getDrawX() * mDpToPx, st.getDrawY() * mDpToPx, st.getWidth() * mDpToPx,
|
layoutHelper.getWidth() * mDpToPx, st.getDrawX() * mDpToPx,
|
||||||
st.getHeight() * mDpToPx, st.getContentOffsetY() * mDpToPx,
|
st.getDrawY() * mDpToPx, st.getWidth() * mDpToPx, st.getHeight() * mDpToPx,
|
||||||
st.getDividerOffsetX() * mDpToPx, st.getBottomMargin() * mDpToPx,
|
st.getContentOffsetY() * mDpToPx, st.getDividerOffsetX() * mDpToPx,
|
||||||
st.getTopMargin() * mDpToPx, st.getCloseButtonPadding() * mDpToPx,
|
st.getBottomMargin() * mDpToPx, st.getTopMargin() * mDpToPx,
|
||||||
st.getCloseButton().getOpacity(), st.isStartDividerVisible(),
|
st.getCloseButtonPadding() * mDpToPx, st.getCloseButton().getOpacity(),
|
||||||
st.isEndDividerVisible(), st.isLoading(), st.getLoadingSpinnerRotation(),
|
st.isStartDividerVisible(), st.isEndDividerVisible(), st.isLoading(),
|
||||||
st.getBrightness(), st.getContainerOpacity(), layerTitleCache, resourceManager);
|
st.getLoadingSpinnerRotation(), st.getBrightness(), st.getContainerOpacity(),
|
||||||
|
layerTitleCache, resourceManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,8 +20,8 @@ import org.chromium.base.metrics.RecordUserAction;
|
|||||||
import org.chromium.base.supplier.ObservableSupplier;
|
import org.chromium.base.supplier.ObservableSupplier;
|
||||||
import org.chromium.base.supplier.Supplier;
|
import org.chromium.base.supplier.Supplier;
|
||||||
import org.chromium.chrome.R;
|
import org.chromium.chrome.R;
|
||||||
import org.chromium.chrome.browser.ChromeSemanticColorUtils;
|
|
||||||
import org.chromium.chrome.browser.status_indicator.StatusIndicatorCoordinator;
|
import org.chromium.chrome.browser.status_indicator.StatusIndicatorCoordinator;
|
||||||
|
import org.chromium.chrome.browser.ui.theme.ChromeSemanticColorUtils;
|
||||||
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
||||||
import org.chromium.content_public.common.ContentSwitches;
|
import org.chromium.content_public.common.ContentSwitches;
|
||||||
|
|
||||||
@@ -262,7 +262,6 @@ public class OfflineIndicatorControllerV2 {
|
|||||||
surfaceState = mCanAnimateBrowserControlsSupplier.get()
|
surfaceState = mCanAnimateBrowserControlsSupplier.get()
|
||||||
? UmaEnum.CAN_ANIMATE_NATIVE_CONTROLS
|
? UmaEnum.CAN_ANIMATE_NATIVE_CONTROLS
|
||||||
: UmaEnum.CANNOT_ANIMATE_NATIVE_CONTROLS;
|
: UmaEnum.CANNOT_ANIMATE_NATIVE_CONTROLS;
|
||||||
;
|
|
||||||
}
|
}
|
||||||
RecordHistogram.recordEnumeratedHistogram(
|
RecordHistogram.recordEnumeratedHistogram(
|
||||||
"OfflineIndicator.ConnectivityChanged.DeviceState."
|
"OfflineIndicator.ConnectivityChanged.DeviceState."
|
||||||
|
@@ -16,9 +16,9 @@ import android.widget.TextView;
|
|||||||
import androidx.annotation.ColorInt;
|
import androidx.annotation.ColorInt;
|
||||||
|
|
||||||
import org.chromium.chrome.R;
|
import org.chromium.chrome.R;
|
||||||
import org.chromium.chrome.browser.ChromeSemanticColorUtils;
|
|
||||||
import org.chromium.chrome.browser.omnibox.ChromeAutocompleteSchemeClassifier;
|
import org.chromium.chrome.browser.omnibox.ChromeAutocompleteSchemeClassifier;
|
||||||
import org.chromium.chrome.browser.profiles.Profile;
|
import org.chromium.chrome.browser.profiles.Profile;
|
||||||
|
import org.chromium.chrome.browser.ui.theme.ChromeSemanticColorUtils;
|
||||||
import org.chromium.components.browser_ui.widget.TintedDrawable;
|
import org.chromium.components.browser_ui.widget.TintedDrawable;
|
||||||
import org.chromium.components.embedder_support.util.UrlConstants;
|
import org.chromium.components.embedder_support.util.UrlConstants;
|
||||||
import org.chromium.components.omnibox.OmniboxUrlEmphasizer;
|
import org.chromium.components.omnibox.OmniboxUrlEmphasizer;
|
||||||
|
@@ -36,7 +36,7 @@ import androidx.gridlayout.widget.GridLayout;
|
|||||||
|
|
||||||
import org.chromium.base.ApiCompatibilityUtils;
|
import org.chromium.base.ApiCompatibilityUtils;
|
||||||
import org.chromium.chrome.R;
|
import org.chromium.chrome.R;
|
||||||
import org.chromium.chrome.browser.ChromeSemanticColorUtils;
|
import org.chromium.chrome.browser.ui.theme.ChromeSemanticColorUtils;
|
||||||
import org.chromium.components.autofill.EditableOption;
|
import org.chromium.components.autofill.EditableOption;
|
||||||
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
||||||
import org.chromium.components.browser_ui.widget.DualControlLayout;
|
import org.chromium.components.browser_ui.widget.DualControlLayout;
|
||||||
|
63
chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
63
chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
@@ -24,7 +24,6 @@ import org.chromium.base.test.util.Criteria;
|
|||||||
import org.chromium.base.test.util.CriteriaHelper;
|
import org.chromium.base.test.util.CriteriaHelper;
|
||||||
import org.chromium.base.test.util.DisabledTest;
|
import org.chromium.base.test.util.DisabledTest;
|
||||||
import org.chromium.base.test.util.Feature;
|
import org.chromium.base.test.util.Feature;
|
||||||
import org.chromium.base.test.util.Features.EnableFeatures;
|
|
||||||
import org.chromium.base.test.util.Restriction;
|
import org.chromium.base.test.util.Restriction;
|
||||||
import org.chromium.chrome.browser.compositor.layouts.components.CompositorButton;
|
import org.chromium.chrome.browser.compositor.layouts.components.CompositorButton;
|
||||||
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
||||||
@@ -33,11 +32,13 @@ import org.chromium.chrome.browser.tab.Tab;
|
|||||||
import org.chromium.chrome.browser.tabmodel.TabModel;
|
import org.chromium.chrome.browser.tabmodel.TabModel;
|
||||||
import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
|
import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
|
||||||
import org.chromium.chrome.browser.tabmodel.TabModelUtils;
|
import org.chromium.chrome.browser.tabmodel.TabModelUtils;
|
||||||
|
import org.chromium.chrome.browser.tasks.tab_management.TabManagementFieldTrial;
|
||||||
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
|
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
|
||||||
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
|
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
|
||||||
import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
|
import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
|
||||||
import org.chromium.chrome.test.util.ChromeTabUtils;
|
import org.chromium.chrome.test.util.ChromeTabUtils;
|
||||||
import org.chromium.chrome.test.util.TabStripUtils;
|
import org.chromium.chrome.test.util.TabStripUtils;
|
||||||
|
import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
|
||||||
import org.chromium.content_public.browser.test.util.DOMUtils;
|
import org.chromium.content_public.browser.test.util.DOMUtils;
|
||||||
import org.chromium.content_public.browser.test.util.TestThreadUtils;
|
import org.chromium.content_public.browser.test.util.TestThreadUtils;
|
||||||
import org.chromium.ui.base.LocalizationUtils;
|
import org.chromium.ui.base.LocalizationUtils;
|
||||||
@@ -858,45 +859,69 @@ public class TabStripTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests hover events associated with a strip tab.
|
* Tests hover events associated with a strip tab (with the tab strip redesign folio treatment
|
||||||
|
* enabled, for maximum coverage).
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@LargeTest
|
@LargeTest
|
||||||
@EnableFeatures({ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP})
|
@Feature({"TabStrip"})
|
||||||
|
@EnableFeatures({ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP,
|
||||||
|
ChromeFeatureList.TAB_STRIP_REDESIGN})
|
||||||
@Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
|
@Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
|
||||||
public void testHoverOnTab() throws Exception {
|
public void
|
||||||
|
testHoverOnTab() throws Exception {
|
||||||
|
TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_FOLIO.setForTesting(true);
|
||||||
// Open a few regular tabs.
|
// Open a few regular tabs.
|
||||||
ChromeTabUtils.newTabsFromMenu(
|
ChromeTabUtils.newTabsFromMenu(
|
||||||
InstrumentationRegistry.getInstrumentation(), sActivityTestRule.getActivity(), 4);
|
InstrumentationRegistry.getInstrumentation(), sActivityTestRule.getActivity(), 4);
|
||||||
|
|
||||||
// Select a tab to hover on.
|
// Select tabs to hover on.
|
||||||
TabModel model = sActivityTestRule.getActivity().getTabModelSelector().getModel(false);
|
TabModel model = sActivityTestRule.getActivity().getTabModelSelector().getModel(false);
|
||||||
StripLayoutTab tab = TabStripUtils.findStripLayoutTab(
|
StripLayoutTab tab1 = TabStripUtils.findStripLayoutTab(
|
||||||
|
sActivityTestRule.getActivity(), false, model.getTabAt(1).getId());
|
||||||
|
StripLayoutTab tab2 = TabStripUtils.findStripLayoutTab(
|
||||||
sActivityTestRule.getActivity(), false, model.getTabAt(2).getId());
|
sActivityTestRule.getActivity(), false, model.getTabAt(2).getId());
|
||||||
assertTabVisibility(true, tab);
|
assertTabVisibility(true, tab1);
|
||||||
|
assertTabVisibility(true, tab2);
|
||||||
|
|
||||||
// Simulate a hover into this tab.
|
// Simulate a hover into tab1.
|
||||||
StripLayoutHelperManager stripLayoutHelperManager =
|
StripLayoutHelperManager stripLayoutHelperManager =
|
||||||
TabStripUtils.getStripLayoutHelperManager(sActivityTestRule.getActivity());
|
TabStripUtils.getStripLayoutHelperManager(sActivityTestRule.getActivity());
|
||||||
float xEnter = tab.getDrawX() + tab.getWidth() / 2;
|
float xEnter = tab1.getDrawX() + tab1.getWidth() / 2;
|
||||||
float yEnter = tab.getDrawY() + tab.getHeight() / 2;
|
float yEnter = tab1.getDrawY() + tab1.getHeight() / 2;
|
||||||
stripLayoutHelperManager.simulateHoverEventForTesting(
|
stripLayoutHelperManager.simulateHoverEventForTesting(
|
||||||
MotionEvent.ACTION_HOVER_ENTER, xEnter, yEnter);
|
MotionEvent.ACTION_HOVER_ENTER, xEnter, yEnter);
|
||||||
|
StripLayoutTab lastHoveredTab =
|
||||||
|
stripLayoutHelperManager.getActiveStripLayoutHelper().getLastHoveredTab();
|
||||||
|
Assert.assertEquals("The last hovered tab is not set correctly.", tab1, lastHoveredTab);
|
||||||
|
Assert.assertFalse(
|
||||||
|
"|mFolioAttached| for tab1 should be false.", tab1.getFolioAttachedForTesting());
|
||||||
|
Assert.assertEquals("tab1 container bottom margin should match.",
|
||||||
|
StripLayoutHelper.FOLIO_DETACHED_BOTTOM_MARGIN_DP, tab1.getBottomMargin(), 0.f);
|
||||||
|
|
||||||
// Simulate a subsequent hover within the tab.
|
// Simulate a subsequent hover into the adjacent tab (tab2).
|
||||||
float xMove = tab.getDrawX() + tab.getWidth() / 3;
|
float xMove = tab2.getDrawX() + tab2.getWidth() / 3;
|
||||||
float yMove = tab.getDrawY() + tab.getHeight() / 3;
|
float yMove = tab2.getDrawY() + tab2.getHeight() / 3;
|
||||||
stripLayoutHelperManager.simulateHoverEventForTesting(
|
stripLayoutHelperManager.simulateHoverEventForTesting(
|
||||||
MotionEvent.ACTION_HOVER_MOVE, xMove, yMove);
|
MotionEvent.ACTION_HOVER_MOVE, xMove, yMove);
|
||||||
|
lastHoveredTab = stripLayoutHelperManager.getActiveStripLayoutHelper().getLastHoveredTab();
|
||||||
|
Assert.assertEquals("The last hovered tab is not set correctly.", tab2, lastHoveredTab);
|
||||||
|
Assert.assertFalse(
|
||||||
|
"|mFolioAttached| for tab2 should be false.", tab2.getFolioAttachedForTesting());
|
||||||
|
Assert.assertTrue(
|
||||||
|
"|mFolioAttached| for tab1 should be true.", tab1.getFolioAttachedForTesting());
|
||||||
|
Assert.assertEquals("tab1 container bottom margin should match.",
|
||||||
|
StripLayoutHelper.FOLIO_ATTACHED_BOTTOM_MARGIN_DP, tab1.getBottomMargin(), 0.f);
|
||||||
|
|
||||||
// Simulate a subsequent hover outside the tab.
|
// Simulate a subsequent hover outside tab2.
|
||||||
float xExit = tab.getDrawX() + 2 * tab.getWidth();
|
float xExit = tab2.getDrawX() + 2 * tab2.getWidth();
|
||||||
float yExit = tab.getDrawY() + 2 * tab.getHeight();
|
float yExit = tab2.getDrawY() + 2 * tab2.getHeight();
|
||||||
stripLayoutHelperManager.simulateHoverEventForTesting(
|
stripLayoutHelperManager.simulateHoverEventForTesting(
|
||||||
MotionEvent.ACTION_HOVER_EXIT, xExit, yExit);
|
MotionEvent.ACTION_HOVER_EXIT, xExit, yExit);
|
||||||
|
lastHoveredTab = stripLayoutHelperManager.getActiveStripLayoutHelper().getLastHoveredTab();
|
||||||
// TODO (crbug.com/1451925): Update verification in test(s) after hover handling is added in
|
Assert.assertNull("The last hovered tab is not set correctly.", lastHoveredTab);
|
||||||
// StripLayoutHelper.
|
Assert.assertTrue(
|
||||||
|
"|mFolioAttached| for tab2 should be true.", tab2.getFolioAttachedForTesting());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -111,7 +111,7 @@ public class AreaGestureEventFilterUnitTest {
|
|||||||
|
|
||||||
// Handle the hover exit event.
|
// Handle the hover exit event.
|
||||||
mEventFilter.onHoverEvent(mHoverExitEvent);
|
mEventFilter.onHoverEvent(mHoverExitEvent);
|
||||||
verify(mHandler).onHoverExit(mHoverExitEvent.getX(), mHoverExitEvent.getY());
|
verify(mHandler).onHoverExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -128,6 +128,6 @@ public class AreaGestureEventFilterUnitTest {
|
|||||||
mEventFilter.onHoverEvent(mHoverMoveEvent);
|
mEventFilter.onHoverEvent(mHoverMoveEvent);
|
||||||
// Moving outside the filter area will be considered an ACTION_HOVER_EXIT for further
|
// Moving outside the filter area will be considered an ACTION_HOVER_EXIT for further
|
||||||
// handling.
|
// handling.
|
||||||
verify(mHandler).onHoverExit(mHoverMoveEvent.getX(), mHoverMoveEvent.getY());
|
verify(mHandler).onHoverExit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,9 +5,11 @@
|
|||||||
package org.chromium.chrome.browser.compositor.overlays.strip;
|
package org.chromium.chrome.browser.compositor.overlays.strip;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.RectF;
|
||||||
import android.view.ContextThemeWrapper;
|
import android.view.ContextThemeWrapper;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
@@ -44,6 +46,7 @@ import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
|
|||||||
import org.chromium.chrome.browser.multiwindow.MultiInstanceManager;
|
import org.chromium.chrome.browser.multiwindow.MultiInstanceManager;
|
||||||
import org.chromium.chrome.browser.tab.Tab;
|
import org.chromium.chrome.browser.tab.Tab;
|
||||||
import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
|
import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
|
||||||
|
import org.chromium.chrome.browser.tabmodel.TabModel;
|
||||||
import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider;
|
import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider;
|
||||||
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
|
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
|
||||||
import org.chromium.chrome.browser.tasks.tab_management.TabManagementFieldTrial;
|
import org.chromium.chrome.browser.tasks.tab_management.TabManagementFieldTrial;
|
||||||
@@ -64,6 +67,8 @@ public class StripLayoutHelperManagerTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private TabStripSceneLayer.Natives mTabStripSceneMock;
|
private TabStripSceneLayer.Natives mTabStripSceneMock;
|
||||||
@Mock
|
@Mock
|
||||||
|
private TabStripSceneLayer mTabStripTreeProvider;
|
||||||
|
@Mock
|
||||||
private LayoutManagerHost mManagerHost;
|
private LayoutManagerHost mManagerHost;
|
||||||
@Mock
|
@Mock
|
||||||
private LayoutUpdateHost mUpdateHost;
|
private LayoutUpdateHost mUpdateHost;
|
||||||
@@ -83,6 +88,12 @@ public class StripLayoutHelperManagerTest {
|
|||||||
private TabCreatorManager mTabCreatorManager;
|
private TabCreatorManager mTabCreatorManager;
|
||||||
@Mock
|
@Mock
|
||||||
private TabModelFilterProvider mTabModelFilterProvider;
|
private TabModelFilterProvider mTabModelFilterProvider;
|
||||||
|
@Mock
|
||||||
|
private TabModel mTabModel;
|
||||||
|
@Mock
|
||||||
|
private Tab mSelectedTab;
|
||||||
|
@Mock
|
||||||
|
private StripLayoutTab mHoveredStripTab;
|
||||||
|
|
||||||
private StripLayoutHelperManager mStripLayoutHelperManager;
|
private StripLayoutHelperManager mStripLayoutHelperManager;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@@ -376,4 +387,32 @@ public class StripLayoutHelperManagerTest {
|
|||||||
assertEquals("Unexpected incognito active tab index", expectedIncognitoActiveTabIndex,
|
assertEquals("Unexpected incognito active tab index", expectedIncognitoActiveTabIndex,
|
||||||
incognitoHelper.getActiveTabIndexOnStartupForTesting());
|
incognitoHelper.getActiveTabIndexOnStartupForTesting());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUpdatedSceneOverlayTree() {
|
||||||
|
// Setup and stub required mocks.
|
||||||
|
int hoveredTabId = 1;
|
||||||
|
int selectedTabId = 2;
|
||||||
|
mStripLayoutHelperManager.setTabStripTreeProviderForTesting(mTabStripTreeProvider);
|
||||||
|
|
||||||
|
when(mTabModelSelector.getCurrentModel()).thenReturn(mTabModel);
|
||||||
|
when(mTabModel.index()).thenReturn(selectedTabId);
|
||||||
|
when(mTabModel.getTabAt(selectedTabId)).thenReturn(mSelectedTab);
|
||||||
|
when(mSelectedTab.getId()).thenReturn(selectedTabId);
|
||||||
|
|
||||||
|
when(mHoveredStripTab.getId()).thenReturn(hoveredTabId);
|
||||||
|
var activeLayoutHelper = mStripLayoutHelperManager.getActiveStripLayoutHelper();
|
||||||
|
activeLayoutHelper.setLastHoveredTabForTesting(mHoveredStripTab);
|
||||||
|
|
||||||
|
// Invoke the method.
|
||||||
|
mStripLayoutHelperManager.getUpdatedSceneOverlayTree(
|
||||||
|
new RectF(), new RectF(), mRenderHost.getResourceManager(), 0f);
|
||||||
|
|
||||||
|
// Verify the call to #pushAndUpdateStrip.
|
||||||
|
verify(mTabStripTreeProvider)
|
||||||
|
.pushAndUpdateStrip(mStripLayoutHelperManager, mLayerTitleCacheSupplier.get(),
|
||||||
|
mRenderHost.getResourceManager(),
|
||||||
|
activeLayoutHelper.getStripLayoutTabsToRender(), 0f, selectedTabId,
|
||||||
|
hoveredTabId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,9 @@ import org.chromium.base.test.util.Feature;
|
|||||||
import org.chromium.chrome.R;
|
import org.chromium.chrome.R;
|
||||||
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
||||||
import org.chromium.chrome.browser.tasks.tab_management.TabManagementFieldTrial;
|
import org.chromium.chrome.browser.tasks.tab_management.TabManagementFieldTrial;
|
||||||
|
import org.chromium.chrome.browser.ui.theme.ChromeSemanticColorUtils;
|
||||||
import org.chromium.chrome.test.util.browser.Features;
|
import org.chromium.chrome.test.util.browser.Features;
|
||||||
|
import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
|
||||||
import org.chromium.components.browser_ui.styles.ChromeColors;
|
import org.chromium.components.browser_ui.styles.ChromeColors;
|
||||||
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
||||||
import org.chromium.ui.util.ColorUtils;
|
import org.chromium.ui.util.ColorUtils;
|
||||||
@@ -55,91 +57,151 @@ public class StripLayoutTabTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Feature("Tab Strip Redesign")
|
@Feature("Tab Strip Redesign")
|
||||||
|
@EnableFeatures({ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP})
|
||||||
public void testGetTint() {
|
public void testGetTint() {
|
||||||
int expectedColor;
|
int expectedColor;
|
||||||
|
|
||||||
// Normal active tab color.
|
// Normal active tab color.
|
||||||
expectedColor = MaterialColors.getColor(mContext, R.attr.colorSurface, TAG);
|
expectedColor = MaterialColors.getColor(mContext, R.attr.colorSurface, TAG);
|
||||||
assertEquals("Normal active tab should match the Surface-0 color.", expectedColor,
|
assertEquals("Normal active tab should match the Surface-0 color.", expectedColor,
|
||||||
mNormalTab.getTint(true));
|
mNormalTab.getTint(true, false));
|
||||||
|
|
||||||
// Normal inactive tab color.
|
// Normal inactive tab color.
|
||||||
expectedColor =
|
expectedColor =
|
||||||
ChromeColors.getSurfaceColor(mContext, R.dimen.compositor_background_tab_elevation);
|
ChromeColors.getSurfaceColor(mContext, R.dimen.compositor_background_tab_elevation);
|
||||||
assertEquals("Normal inactive tab should match the Surface-4 color.", expectedColor,
|
assertEquals("Normal inactive tab should match the Surface-4 color.", expectedColor,
|
||||||
mNormalTab.getTint(false));
|
mNormalTab.getTint(false, false));
|
||||||
|
|
||||||
|
// Normal inactive tab hover color.
|
||||||
|
expectedColor = ColorUtils.getColorWithOverlay(expectedColor,
|
||||||
|
MaterialColors.getColor(mContext, R.attr.colorOnSurface, TAG),
|
||||||
|
ResourcesCompat.getFloat(
|
||||||
|
mContext.getResources(), R.dimen.gm2_tab_inactive_hover_alpha));
|
||||||
|
assertEquals(
|
||||||
|
"Normal hovered inactive tab should match the Surface-4 color overlain by OnSurface @ 8%.",
|
||||||
|
expectedColor, mNormalTab.getTint(false, true));
|
||||||
|
|
||||||
// Incognito active tab color.
|
// Incognito active tab color.
|
||||||
expectedColor = mContext.getColor(R.color.toolbar_background_primary_dark);
|
expectedColor = mContext.getColor(R.color.toolbar_background_primary_dark);
|
||||||
assertEquals("Incognito active tab should match the baseline color.", expectedColor,
|
assertEquals("Incognito active tab should match the baseline color.", expectedColor,
|
||||||
mIncognitoTab.getTint(true));
|
mIncognitoTab.getTint(true, false));
|
||||||
|
|
||||||
// Incognito inactive tab color.
|
// Incognito inactive tab color.
|
||||||
expectedColor = mContext.getResources().getColor(
|
expectedColor = mContext.getResources().getColor(
|
||||||
R.color.baseline_neutral_10_with_neutral_0_alpha_30);
|
R.color.baseline_neutral_10_with_neutral_0_alpha_30);
|
||||||
assertEquals("Incognito inactive tab should match the baseline color.", expectedColor,
|
assertEquals("Incognito inactive tab should match the baseline color.", expectedColor,
|
||||||
mIncognitoTab.getTint(false));
|
mIncognitoTab.getTint(false, false));
|
||||||
|
|
||||||
|
// Incognito inactive tab hover color.
|
||||||
|
expectedColor = ColorUtils.getColorWithOverlay(expectedColor,
|
||||||
|
mContext.getColor(R.color.baseline_neutral_90),
|
||||||
|
ResourcesCompat.getFloat(
|
||||||
|
mContext.getResources(), R.dimen.gm2_tab_inactive_hover_alpha));
|
||||||
|
assertEquals(
|
||||||
|
"Incognito hovered inactive tab should match the baseline color overlain by the baseline equivalent of OnSurface @ 8%.",
|
||||||
|
expectedColor, mIncognitoTab.getTint(false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Feature("Tab Strip Redesign")
|
@Feature("Tab Strip Redesign")
|
||||||
@Features.EnableFeatures({ChromeFeatureList.TAB_STRIP_REDESIGN})
|
@Features.EnableFeatures({ChromeFeatureList.TAB_STRIP_REDESIGN,
|
||||||
public void testGetTint_TabStripRedesignFolio() {
|
ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP})
|
||||||
|
public void
|
||||||
|
testGetTint_TabStripRedesignFolio() {
|
||||||
TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_FOLIO.setForTesting(true);
|
TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_FOLIO.setForTesting(true);
|
||||||
int expectedColor;
|
int expectedColor;
|
||||||
|
|
||||||
// Normal active tab color.
|
// Normal active tab color.
|
||||||
expectedColor = MaterialColors.getColor(mContext, R.attr.colorSurface, TAG);
|
expectedColor = MaterialColors.getColor(mContext, R.attr.colorSurface, TAG);
|
||||||
assertEquals("Normal active folio should match the Surface-0 color.", expectedColor,
|
assertEquals("Normal active folio should match the Surface-0 color.", expectedColor,
|
||||||
mNormalTab.getTint(true));
|
mNormalTab.getTint(true, false));
|
||||||
|
|
||||||
// Normal inactive tab color.
|
// Normal inactive tab color.
|
||||||
expectedColor = ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_0);
|
expectedColor = ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_0);
|
||||||
assertEquals("Folio inactive tab containers should be Surface-0.", expectedColor,
|
assertEquals("Folio inactive tab containers should be Surface-0.", expectedColor,
|
||||||
mNormalTab.getTint(false));
|
mNormalTab.getTint(false, false));
|
||||||
|
|
||||||
|
// Normal inactive tab hover color.
|
||||||
|
expectedColor = ColorUtils.setAlphaComponent(
|
||||||
|
ChromeSemanticColorUtils.getTabInactiveHoverColor(mContext),
|
||||||
|
(int) (ResourcesCompat.getFloat(
|
||||||
|
mContext.getResources(), R.dimen.tsr_folio_tab_inactive_hover_alpha)
|
||||||
|
* 255));
|
||||||
|
assertEquals("Normal hovered inactive folio should be Primary @ 8%.", expectedColor,
|
||||||
|
mNormalTab.getTint(false, true));
|
||||||
|
|
||||||
// Incognito active tab color.
|
// Incognito active tab color.
|
||||||
expectedColor = mContext.getColor(R.color.toolbar_background_primary_dark);
|
expectedColor = mContext.getColor(R.color.toolbar_background_primary_dark);
|
||||||
assertEquals("Incognito active folio should match the baseline color.", expectedColor,
|
assertEquals("Incognito active folio should match the baseline color.", expectedColor,
|
||||||
mIncognitoTab.getTint(true));
|
mIncognitoTab.getTint(true, false));
|
||||||
|
|
||||||
// Incognito inactive tab color.
|
// Incognito inactive tab color.
|
||||||
expectedColor = mContext.getColor(R.color.default_bg_color_dark);
|
expectedColor = mContext.getColor(R.color.default_bg_color_dark);
|
||||||
assertEquals("Incognito inactive folio should be baseline Surface-0.", expectedColor,
|
assertEquals("Incognito inactive folio should be baseline Surface-0.", expectedColor,
|
||||||
mIncognitoTab.getTint(false));
|
mIncognitoTab.getTint(false, false));
|
||||||
|
|
||||||
|
// Incognito inactive tab hover color.
|
||||||
|
expectedColor = ColorUtils.setAlphaComponent(mContext.getColor(R.color.baseline_primary_80),
|
||||||
|
(int) (ResourcesCompat.getFloat(
|
||||||
|
mContext.getResources(), R.dimen.tsr_folio_tab_inactive_hover_alpha)
|
||||||
|
* 255));
|
||||||
|
assertEquals(
|
||||||
|
"Incognito hovered inactive folio should be the baseline equivalent of Primary @ 8%.",
|
||||||
|
expectedColor, mIncognitoTab.getTint(false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Feature("Tab Strip Redesign")
|
@Feature("Tab Strip Redesign")
|
||||||
@Features.EnableFeatures({ChromeFeatureList.TAB_STRIP_REDESIGN})
|
@Features.EnableFeatures({ChromeFeatureList.TAB_STRIP_REDESIGN,
|
||||||
public void testGetTint_TabStripRedesignDetached() {
|
ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP})
|
||||||
|
public void
|
||||||
|
testGetTint_TabStripRedesignDetached() {
|
||||||
TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_DETACHED.setForTesting(true);
|
TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_DETACHED.setForTesting(true);
|
||||||
int expectedColor;
|
int expectedColor;
|
||||||
|
|
||||||
// Normal active tab color.
|
// Normal active tab color.
|
||||||
expectedColor = ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_5);
|
expectedColor = ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_5);
|
||||||
assertEquals("Detached normal active should match the Surface-5 color.", expectedColor,
|
assertEquals("Detached normal active should match the Surface-5 color.", expectedColor,
|
||||||
mNormalTab.getTint(true));
|
mNormalTab.getTint(true, false));
|
||||||
|
|
||||||
// Normal inactive tab color.
|
// Normal inactive tab color.
|
||||||
expectedColor = ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_5);
|
expectedColor = ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_5);
|
||||||
assertEquals("Detached inactive tab containers should be Surface-5.", expectedColor,
|
assertEquals("Detached inactive tab containers should be Surface-5.", expectedColor,
|
||||||
mNormalTab.getTint(false));
|
mNormalTab.getTint(false, false));
|
||||||
|
|
||||||
|
// Normal inactive tab hover color.
|
||||||
|
expectedColor = ColorUtils.setAlphaComponent(
|
||||||
|
ChromeSemanticColorUtils.getTabInactiveHoverColor(mContext),
|
||||||
|
(int) (ResourcesCompat.getFloat(mContext.getResources(),
|
||||||
|
R.dimen.tsr_detached_tab_inactive_hover_alpha_light)
|
||||||
|
* 255));
|
||||||
|
assertEquals("Normal hovered inactive folio should be Primary @ 5%.", expectedColor,
|
||||||
|
mNormalTab.getTint(false, true));
|
||||||
|
|
||||||
// Incognito active tab color.
|
// Incognito active tab color.
|
||||||
expectedColor = Color.BLACK;
|
expectedColor = Color.BLACK;
|
||||||
assertEquals("Detached incognito active should match the color black.", expectedColor,
|
assertEquals("Detached incognito active should match the color black.", expectedColor,
|
||||||
mIncognitoTab.getTint(true));
|
mIncognitoTab.getTint(true, false));
|
||||||
|
|
||||||
// Incognito inactive tab color.
|
// Incognito inactive tab color.
|
||||||
expectedColor = mContext.getColor(R.color.default_bg_color_dark_elev_5_gm3_baseline);
|
expectedColor = mContext.getColor(R.color.default_bg_color_dark_elev_5_gm3_baseline);
|
||||||
assertEquals("Detached incognito inactive should be baseline Surface-5.", expectedColor,
|
assertEquals("Detached incognito inactive should be baseline Surface-5.", expectedColor,
|
||||||
mIncognitoTab.getTint(false));
|
mIncognitoTab.getTint(false, false));
|
||||||
|
|
||||||
|
// Incognito inactive tab hover color.
|
||||||
|
expectedColor = ColorUtils.setAlphaComponent(mContext.getColor(R.color.baseline_primary_80),
|
||||||
|
(int) (ResourcesCompat.getFloat(mContext.getResources(),
|
||||||
|
R.dimen.tsr_detached_tab_inactive_hover_alpha_dark)
|
||||||
|
* 255));
|
||||||
|
assertEquals(
|
||||||
|
"Incognito hovered inactive folio should be the baseline equivalent of Primary @ 12%.",
|
||||||
|
expectedColor, mIncognitoTab.getTint(false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Features.EnableFeatures(
|
@Features.EnableFeatures(
|
||||||
{ChromeFeatureList.TAB_STRIP_REDESIGN, ChromeFeatureList.TAB_STRIP_STARTUP_REFACTORING})
|
{ChromeFeatureList.TAB_STRIP_REDESIGN, ChromeFeatureList.TAB_STRIP_STARTUP_REFACTORING,
|
||||||
|
ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP})
|
||||||
public void
|
public void
|
||||||
testGetTint_Startup_TabStripRedesign() {
|
testGetTint_Startup_TabStripRedesign() {
|
||||||
TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_DETACHED.setForTesting(true);
|
TabManagementFieldTrial.TAB_STRIP_REDESIGN_ENABLE_DETACHED.setForTesting(true);
|
||||||
@@ -151,26 +213,27 @@ public class StripLayoutTabTest {
|
|||||||
// Normal active tab color.
|
// Normal active tab color.
|
||||||
expectedColor = ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_5);
|
expectedColor = ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_5);
|
||||||
assertEquals("Detached normal active should match the regular foreground color.",
|
assertEquals("Detached normal active should match the regular foreground color.",
|
||||||
expectedColor, mNormalTab.getTint(true));
|
expectedColor, mNormalTab.getTint(true, false));
|
||||||
|
|
||||||
// Normal inactive tab color.
|
// Normal inactive tab color.
|
||||||
expectedColor = mContext.getColor(R.color.bg_tabstrip_tab_detached_startup_tint);
|
expectedColor = mContext.getColor(R.color.bg_tabstrip_tab_detached_startup_tint);
|
||||||
assertEquals("Normal inactive tab should match the placeholder color.", expectedColor,
|
assertEquals("Normal inactive tab should match the placeholder color.", expectedColor,
|
||||||
mNormalTab.getTint(false));
|
mNormalTab.getTint(false, false));
|
||||||
|
|
||||||
// Incognito active tab color.
|
// Incognito active tab color.
|
||||||
expectedColor = Color.BLACK;
|
expectedColor = Color.BLACK;
|
||||||
assertEquals("Detached incognito active should match the regular foreground color.",
|
assertEquals("Detached incognito active should match the regular foreground color.",
|
||||||
expectedColor, mIncognitoTab.getTint(true));
|
expectedColor, mIncognitoTab.getTint(true, false));
|
||||||
|
|
||||||
// Incognito inactive tab color.
|
// Incognito inactive tab color.
|
||||||
expectedColor = mContext.getColor(R.color.bg_tabstrip_tab_detached_startup_tint);
|
expectedColor = mContext.getColor(R.color.bg_tabstrip_tab_detached_startup_tint);
|
||||||
assertEquals("Incognito inactive tab should match the placeholder color.", expectedColor,
|
assertEquals("Incognito inactive tab should match the placeholder color.", expectedColor,
|
||||||
mIncognitoTab.getTint(false));
|
mIncognitoTab.getTint(false, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Feature("Tab Strip Redesign")
|
@Feature("Tab Strip Redesign")
|
||||||
|
@Features.EnableFeatures({ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP})
|
||||||
public void testGetOutlineTint() {
|
public void testGetOutlineTint() {
|
||||||
int expectedColor;
|
int expectedColor;
|
||||||
|
|
||||||
|
@@ -42,6 +42,8 @@ import org.chromium.chrome.browser.compositor.scene_layer.TabStripSceneLayerJni;
|
|||||||
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
||||||
import org.chromium.chrome.browser.layouts.scene_layer.SceneLayer;
|
import org.chromium.chrome.browser.layouts.scene_layer.SceneLayer;
|
||||||
import org.chromium.chrome.test.util.browser.Features;
|
import org.chromium.chrome.test.util.browser.Features;
|
||||||
|
import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
|
||||||
|
import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
|
||||||
import org.chromium.ui.resources.ResourceManager;
|
import org.chromium.ui.resources.ResourceManager;
|
||||||
|
|
||||||
/** Tests for {@link TabStripSceneLayer}. */
|
/** Tests for {@link TabStripSceneLayer}. */
|
||||||
@@ -124,14 +126,16 @@ public class TabStripSceneLayerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Features.DisableFeatures(ChromeFeatureList.TAB_STRIP_REDESIGN)
|
@DisableFeatures(ChromeFeatureList.TAB_STRIP_REDESIGN)
|
||||||
|
@EnableFeatures(ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP)
|
||||||
public void testPushAndUpdateStrip() {
|
public void testPushAndUpdateStrip() {
|
||||||
// Setup
|
// Setup
|
||||||
boolean isSelected = false;
|
boolean isSelected = false;
|
||||||
|
boolean isHovered = false;
|
||||||
|
|
||||||
// Call the method being tested.
|
// Call the method being tested.
|
||||||
mTabStripSceneLayer.pushAndUpdateStrip(mStripLayoutHelperManager, mLayerTitleCache,
|
mTabStripSceneLayer.pushAndUpdateStrip(mStripLayoutHelperManager, mLayerTitleCache,
|
||||||
mResourceManager, mStripLayoutTabs, 1.f, 0);
|
mResourceManager, mStripLayoutTabs, 1.f, 0, -1);
|
||||||
|
|
||||||
// Verify JNI calls.
|
// Verify JNI calls.
|
||||||
verify(mTabStripSceneMock).beginBuildingFrame(1L, mTabStripSceneLayer, true);
|
verify(mTabStripSceneMock).beginBuildingFrame(1L, mTabStripSceneLayer, true);
|
||||||
@@ -165,7 +169,8 @@ public class TabStripSceneLayerTest {
|
|||||||
mStripLayoutTab.getDividerResourceId(), mStripLayoutTab.getResourceId(),
|
mStripLayoutTab.getDividerResourceId(), mStripLayoutTab.getResourceId(),
|
||||||
mStripLayoutTab.getOutlineResourceId(),
|
mStripLayoutTab.getOutlineResourceId(),
|
||||||
mStripLayoutTab.getCloseButton().getTint(),
|
mStripLayoutTab.getCloseButton().getTint(),
|
||||||
mStripLayoutTab.getDividerTint(), mStripLayoutTab.getTint(isSelected),
|
mStripLayoutTab.getDividerTint(),
|
||||||
|
mStripLayoutTab.getTint(isSelected, isHovered),
|
||||||
mStripLayoutTab.getOutlineTint(isSelected), isSelected,
|
mStripLayoutTab.getOutlineTint(isSelected), isSelected,
|
||||||
mStripLayoutTab.getClosePressed(), 0.f * mDpToPx,
|
mStripLayoutTab.getClosePressed(), 0.f * mDpToPx,
|
||||||
mStripLayoutTab.getDrawX() * mDpToPx, mStripLayoutTab.getDrawY() * mDpToPx,
|
mStripLayoutTab.getDrawX() * mDpToPx, mStripLayoutTab.getDrawY() * mDpToPx,
|
||||||
@@ -190,10 +195,11 @@ public class TabStripSceneLayerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Feature("Tab Strip Redesign")
|
@Feature("Tab Strip Redesign")
|
||||||
|
@EnableFeatures(ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP)
|
||||||
public void testPushAndUpdateStrip_TSR() {
|
public void testPushAndUpdateStrip_TSR() {
|
||||||
// Call the method being tested.
|
// Call the method being tested.
|
||||||
mTabStripSceneLayer.pushAndUpdateStrip(mStripLayoutHelperManager, mLayerTitleCache,
|
mTabStripSceneLayer.pushAndUpdateStrip(mStripLayoutHelperManager, mLayerTitleCache,
|
||||||
mResourceManager, mStripLayoutTabs, 1.f, 0);
|
mResourceManager, mStripLayoutTabs, 1.f, 0, -1);
|
||||||
|
|
||||||
// Verify TSR JNI calls.
|
// Verify TSR JNI calls.
|
||||||
verify(mTabStripSceneMock)
|
verify(mTabStripSceneMock)
|
||||||
|
@@ -10,6 +10,7 @@ android_library("java") {
|
|||||||
"java/src/org/chromium/chrome/browser/theme/ThemeUtils.java",
|
"java/src/org/chromium/chrome/browser/theme/ThemeUtils.java",
|
||||||
"java/src/org/chromium/chrome/browser/theme/TopUiThemeColorProvider.java",
|
"java/src/org/chromium/chrome/browser/theme/TopUiThemeColorProvider.java",
|
||||||
"java/src/org/chromium/chrome/browser/ui/theme/BrandedColorScheme.java",
|
"java/src/org/chromium/chrome/browser/ui/theme/BrandedColorScheme.java",
|
||||||
|
"java/src/org/chromium/chrome/browser/ui/theme/ChromeSemanticColorUtils.java",
|
||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
":java_resources",
|
":java_resources",
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
package org.chromium.chrome.browser;
|
package org.chromium.chrome.browser.ui.theme;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
@@ -34,4 +34,9 @@ public class ChromeSemanticColorUtils {
|
|||||||
public static @ColorInt int getOfflineIndicatorBackOnlineColor(Context context) {
|
public static @ColorInt int getOfflineIndicatorBackOnlineColor(Context context) {
|
||||||
return SemanticColorUtils.getDefaultControlColorActive(context);
|
return SemanticColorUtils.getDefaultControlColorActive(context);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/** Returns the semantic color value that corresponds to tab_inactive_hover_color. */
|
||||||
|
public static @ColorInt int getTabInactiveHoverColor(Context context) {
|
||||||
|
return SemanticColorUtils.getDefaultControlColorActive(context);
|
||||||
|
}
|
||||||
|
}
|
@@ -152,7 +152,7 @@ public class ToolbarControlContainer extends OptimizedFrameLayout implements Con
|
|||||||
Drawable bdgTabImage = ResourcesCompat.getDrawable(getContext().getResources(),
|
Drawable bdgTabImage = ResourcesCompat.getDrawable(getContext().getResources(),
|
||||||
TabUiThemeUtil.getTSRTabResource(), getContext().getTheme());
|
TabUiThemeUtil.getTSRTabResource(), getContext().getTheme());
|
||||||
bdgTabImage.setTint(TabUiThemeUtil.getTabStripContainerColor(
|
bdgTabImage.setTint(TabUiThemeUtil.getTabStripContainerColor(
|
||||||
getContext(), incognito, true, false, false));
|
getContext(), incognito, true, false, false, false));
|
||||||
LayerDrawable backgroundDrawable =
|
LayerDrawable backgroundDrawable =
|
||||||
new LayerDrawable(new Drawable[] {bgdColor, bdgTabImage});
|
new LayerDrawable(new Drawable[] {bgdColor, bdgTabImage});
|
||||||
// Set image size to match tab size.
|
// Set image size to match tab size.
|
||||||
|
@@ -41,7 +41,7 @@ At the time of writing, there is no support for macros in Java code. So, we have
|
|||||||
|
|
||||||
##### Location
|
##### Location
|
||||||
|
|
||||||
While the most common semantic names are defined in [`semantic_colors_dynamic.xml`](https://source.chromium.org/chromium/chromium/src/+/main:components/browser_ui/styles/android/java/res/values/semantic_colors_dynamic.xml;drc=efb53ff2cb5ea3db8643840d7a9bde4ecdab1741), feature or surface specific semantic names can be defined in their relative modules or directories. Then, they can reference other macros or directly reference theme attributes. For example, [`suggestion_url_color`](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/android/omnibox/java/res/values/colors.xml;drc=efb53ff2cb5ea3db8643840d7a9bde4ecdab1741;l=10) is defined in `chrome/browser/ui/android/omnibox/` and it references `@macro/default_text_color_link`, a common semantic name. If this semantic color needs to be accessed from Java code, a utility method can be added to the utility class for that directory, e.g. [ChromeSemanticColorUtils](https://source.chromium.org/chromium/chromium/src/+/main:chrome/android/java/src/org/chromium/chrome/browser/ChromeSemanticColorUtils.java;drc=a7ae6c6cf46bfc855c55de34ce319c9b9cab10e9).
|
While the most common semantic names are defined in [`semantic_colors_dynamic.xml`](https://source.chromium.org/chromium/chromium/src/+/main:components/browser_ui/styles/android/java/res/values/semantic_colors_dynamic.xml;drc=efb53ff2cb5ea3db8643840d7a9bde4ecdab1741), feature or surface specific semantic names can be defined in their relative modules or directories. Then, they can reference other macros or directly reference theme attributes. For example, [`suggestion_url_color`](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/android/omnibox/java/res/values/colors.xml;drc=efb53ff2cb5ea3db8643840d7a9bde4ecdab1741;l=10) is defined in `chrome/browser/ui/android/omnibox/` and it references `@macro/default_text_color_link`, a common semantic name. If this semantic color needs to be accessed from Java code, a utility method can be added to the utility class for that directory, e.g. [ChromeSemanticColorUtils](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/ui/theme/ChromeSemanticColorUtils.java).
|
||||||
|
|
||||||
|
|
||||||
#### Color state lists
|
#### Color state lists
|
||||||
|
Reference in New Issue
Block a user