Commit 82b6613b authored by spdonghao's avatar spdonghao Committed by Chromium LUCI CQ

[Start Surface] Align headers properly for landscape mode.

Screenshots:
MV tiles & carousel tab switcher:
https://drive.google.com/file/d/1Gnk9tYwa-2zREw7EZaw6E9iTZrxtXe7D/view?usp=sharing&resourcekey=0-uByWJIp7_VoTlTcR1XOk7A
Carousel tab switcher & Feed articles:
https://drive.google.com/file/d/1-Ge1bYU2bp6cwDGTy3UDhONs6VBz2l66/view?usp=sharing&resourcekey=0-vZH4AqM_9w94cwqQtzirfQ

Bug: 1156256
Change-Id: I25c14d962395a4ff44b6d2b3eb38ff6e190a6279
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2595633Reviewed-by: default avatarXi Han <hanxi@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Commit-Queue: Hao Dong <spdonghao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#840243}
parent 91d777af
...@@ -17,9 +17,9 @@ import android.view.ViewGroup; ...@@ -17,9 +17,9 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import org.chromium.chrome.browser.feed.FeedSurfaceCoordinator;
import org.chromium.chrome.browser.feed.shared.FeedFeatures; import org.chromium.chrome.browser.feed.shared.FeedFeatures;
import org.chromium.chrome.start_surface.R; import org.chromium.chrome.start_surface.R;
import org.chromium.components.browser_ui.widget.displaystyle.HorizontalDisplayStyle;
import org.chromium.components.browser_ui.widget.displaystyle.UiConfig; import org.chromium.components.browser_ui.widget.displaystyle.UiConfig;
import org.chromium.components.browser_ui.widget.displaystyle.ViewResizer; import org.chromium.components.browser_ui.widget.displaystyle.ViewResizer;
...@@ -41,18 +41,20 @@ public class FeedLoadingLayout extends LinearLayout { ...@@ -41,18 +41,20 @@ public class FeedLoadingLayout extends LinearLayout {
private final Resources mResources; private final Resources mResources;
private long mLayoutInflationCompleteMs; private long mLayoutInflationCompleteMs;
private int mScreenWidthDp; private int mScreenWidthDp;
private int mPaddingPx;
private boolean mIsFirstCardDense; private boolean mIsFirstCardDense;
private UiConfig mUiConfig;
public FeedLoadingLayout(Context context, AttributeSet attrs) { public FeedLoadingLayout(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
mContext = context; mContext = context;
mResources = mContext.getResources(); mResources = mContext.getResources();
mScreenWidthDp = mResources.getConfiguration().screenWidthDp;
} }
@Override @Override
protected void onFinishInflate() { protected void onFinishInflate() {
super.onFinishInflate(); super.onFinishInflate();
mUiConfig = new UiConfig(this);
setPlaceholders(); setPlaceholders();
mLayoutInflationCompleteMs = SystemClock.elapsedRealtime(); mLayoutInflationCompleteMs = SystemClock.elapsedRealtime();
} }
...@@ -60,7 +62,7 @@ public class FeedLoadingLayout extends LinearLayout { ...@@ -60,7 +62,7 @@ public class FeedLoadingLayout extends LinearLayout {
@Override @Override
public void onConfigurationChanged(Configuration newConfig) { public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig);
setPlaceholders(); mUiConfig.updateDisplayStyle();
} }
/** /**
...@@ -97,7 +99,10 @@ public class FeedLoadingLayout extends LinearLayout { ...@@ -97,7 +99,10 @@ public class FeedLoadingLayout extends LinearLayout {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.setMargins(0, 0, 0, dpToPx(CARD_MARGIN_DP)); int contentPadding = FeedFeatures.cachedIsV2Enabled() ? mResources.getDimensionPixelSize(
R.dimen.content_suggestions_card_modern_padding_v2)
: 0;
lp.setMargins(contentPadding, 0, contentPadding, dpToPx(CARD_MARGIN_DP));
// Set the First placeholder container - an image-right card. // Set the First placeholder container - an image-right card.
// If it's in landscape mode, the placeholder should always show in dense mode. Otherwise, // If it's in landscape mode, the placeholder should always show in dense mode. Otherwise,
...@@ -148,8 +153,8 @@ public class FeedLoadingLayout extends LinearLayout { ...@@ -148,8 +153,8 @@ public class FeedLoadingLayout extends LinearLayout {
} }
private LayerDrawable getLargeImageDrawable() { private LayerDrawable getLargeImageDrawable() {
GradientDrawable[] placeholder = getRectangles( GradientDrawable[] placeholder =
1, dpToPx(mScreenWidthDp) - mPaddingPx * 2, dpToPx(LARGE_IMAGE_HEIGHT_DP)); getRectangles(1, dpToPx(mScreenWidthDp), dpToPx(LARGE_IMAGE_HEIGHT_DP));
return new LayerDrawable(placeholder); return new LayerDrawable(placeholder);
} }
...@@ -157,7 +162,7 @@ public class FeedLoadingLayout extends LinearLayout { ...@@ -157,7 +162,7 @@ public class FeedLoadingLayout extends LinearLayout {
int top = dpToPx(CARD_TOP_PADDING_DP); int top = dpToPx(CARD_TOP_PADDING_DP);
int left = top / 2; int left = top / 2;
int height = dpToPx(TEXT_PLACEHOLDER_HEIGHT_DP); int height = dpToPx(TEXT_PLACEHOLDER_HEIGHT_DP);
int width = dpToPx(mScreenWidthDp) - mPaddingPx * 2; int width = dpToPx(mScreenWidthDp);
int contentHeight = dpToPx(TEXT_CONTENT_HEIGHT_DP); int contentHeight = dpToPx(TEXT_CONTENT_HEIGHT_DP);
LinearLayout.LayoutParams textPlaceholderLp = isSmallCard LinearLayout.LayoutParams textPlaceholderLp = isSmallCard
...@@ -166,9 +171,7 @@ public class FeedLoadingLayout extends LinearLayout { ...@@ -166,9 +171,7 @@ public class FeedLoadingLayout extends LinearLayout {
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
LayerDrawable layerDrawable = isSmallCard LayerDrawable layerDrawable = isSmallCard
? getSmallTextDrawable(top, ? getSmallTextDrawable(top, width, height, contentHeight)
width - dpToPx(IMAGE_PLACEHOLDER_SIZE_DP) - dpToPx(CARD_TOP_PADDING_DP),
height, contentHeight)
: getLargeTextDrawable(top, left, width, height, contentHeight + 2 * top); : getLargeTextDrawable(top, left, width, height, contentHeight + 2 * top);
ImageView textPlaceholder = new ImageView(mContext); ImageView textPlaceholder = new ImageView(mContext);
...@@ -213,6 +216,8 @@ public class FeedLoadingLayout extends LinearLayout { ...@@ -213,6 +216,8 @@ public class FeedLoadingLayout extends LinearLayout {
for (int i = 0; i < num; i++) { for (int i = 0; i < num; i++) {
placeholders[i] = new GradientDrawable(); placeholders[i] = new GradientDrawable();
placeholders[i].setShape(GradientDrawable.RECTANGLE); placeholders[i].setShape(GradientDrawable.RECTANGLE);
// The width here is not deterministic to what the rectangle looks like. It may be also
// affected by layer inset left and right bound and the container padding.
placeholders[i].setSize(width, height); placeholders[i].setSize(width, height);
placeholders[i].setCornerRadius(radius); placeholders[i].setCornerRadius(radius);
placeholders[i].setColor(mResources.getColor(R.color.feed_placeholder_color)); placeholders[i].setColor(mResources.getColor(R.color.feed_placeholder_color));
...@@ -227,39 +232,17 @@ public class FeedLoadingLayout extends LinearLayout { ...@@ -227,39 +232,17 @@ public class FeedLoadingLayout extends LinearLayout {
/** /**
* Make the padding of placeholder consistent with that of native articles recyclerview which * Make the padding of placeholder consistent with that of native articles recyclerview which
* is resized by {@link ViewResizer} in {@link FeedLoadingCoordinator} * is resized by {@link ViewResizer} in {@link FeedSurfaceCoordinator}
*/ */
private void setPadding() { private void setPadding() {
int defaultPadding = mResources.getDimensionPixelSize(FeedFeatures.cachedIsV2Enabled() int defaultPadding = mResources.getDimensionPixelSize(FeedFeatures.cachedIsV2Enabled()
? R.dimen.content_suggestions_card_modern_margin_v2 ? R.dimen.content_suggestions_card_modern_margin_v2
: R.dimen.content_suggestions_card_modern_margin); : R.dimen.content_suggestions_card_modern_margin);
UiConfig uiConfig = new UiConfig(this);
// mUiConfig.getContext().getResources() is used here instead of mView.getResources()
// because lemon compression, somehow, causes the resources to return a different
// configuration.
Resources resources = uiConfig.getContext().getResources();
mScreenWidthDp = resources.getConfiguration().screenWidthDp;
if (uiConfig.getCurrentDisplayStyle().horizontal == HorizontalDisplayStyle.WIDE) {
mPaddingPx = computePadding();
} else {
mPaddingPx = defaultPadding;
}
mPaddingPx += FeedFeatures.cachedIsV2Enabled() ? mResources.getDimensionPixelSize(
R.dimen.content_suggestions_card_modern_padding_v2)
: 0;
setPaddingRelative(mPaddingPx, 0, mPaddingPx, 0);
}
private int computePadding() {
int widePadding = mResources.getDimensionPixelSize(FeedFeatures.cachedIsV2Enabled() int widePadding = mResources.getDimensionPixelSize(FeedFeatures.cachedIsV2Enabled()
? R.dimen.ntp_wide_card_lateral_margins_v2 ? R.dimen.ntp_wide_card_lateral_margins_v2
: R.dimen.ntp_wide_card_lateral_margins); : R.dimen.ntp_wide_card_lateral_margins);
int padding =
dpToPx((int) ((mScreenWidthDp - UiConfig.WIDE_DISPLAY_STYLE_MIN_WIDTH_DP) / 2.f));
padding = Math.max(widePadding, padding);
return padding; ViewResizer.createAndAttach(this, mUiConfig, defaultPadding, widePadding);
} }
long getLayoutInflationCompleteMs() { long getLayoutInflationCompleteMs() {
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
package org.chromium.chrome.features.start_surface; package org.chromium.chrome.features.start_surface;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
...@@ -27,6 +29,7 @@ import static org.chromium.chrome.test.util.ViewUtils.onViewWaiting; ...@@ -27,6 +29,7 @@ import static org.chromium.chrome.test.util.ViewUtils.onViewWaiting;
import static org.chromium.chrome.test.util.ViewUtils.waitForView; import static org.chromium.chrome.test.util.ViewUtils.waitForView;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.os.Build; import android.os.Build;
...@@ -1094,6 +1097,46 @@ public class InstantStartTest { ...@@ -1094,6 +1097,46 @@ public class InstantStartTest {
View.GONE); View.GONE);
} }
@Test
@MediumTest
@Feature({"RenderTest"})
@Restriction({UiRestriction.RESTRICTION_TYPE_PHONE})
// clang-format off
@EnableFeatures({ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<Study,",
ChromeFeatureList.START_SURFACE_ANDROID + "<Study"})
@CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
"force-fieldtrials=Study/Group",
IMMEDIATE_RETURN_PARAMS + "/start_surface_variation/single"})
@ParameterAnnotations.UseMethodParameter(FeedParams.class)
public void renderSingleAsHomepage_Landscape(boolean isFeedV2) throws IOException {
// clang-format on
setFeedVersion(isFeedV2);
createTabStateFile(new int[] {0, 1, 2});
startMainActivityFromLauncher();
CriteriaHelper.pollUiThread(
() -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
// Initializes native.
startAndWaitNativeInitialization();
onViewWaiting(
allOf(withId(org.chromium.chrome.start_surface.R.id.feed_stream_recycler_view),
isDisplayed()));
mActivityTestRule.getActivity().setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
CriteriaHelper.pollUiThread(() -> {
Criteria.checkThat(
mActivityTestRule.getActivity().getResources().getConfiguration().orientation,
is(ORIENTATION_LANDSCAPE));
});
View surface =
mActivityTestRule.getActivity().findViewById(R.id.primary_tasks_surface_view);
mRenderTestRule.render(
surface, "singlePane_landscape" + (isFeedV2 ? "_FeedV2" : "_FeedV1"));
}
/** /**
* Toggles the header and checks whether the header has the right status. * Toggles the header and checks whether the header has the right status.
* *
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
package org.chromium.chrome.browser.tasks; package org.chromium.chrome.browser.tasks;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS; import static com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS;
import static com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL; import static com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Build; import android.os.Build;
import android.util.AttributeSet; import android.util.AttributeSet;
...@@ -26,6 +29,7 @@ import com.google.android.material.appbar.AppBarLayout; ...@@ -26,6 +29,7 @@ import com.google.android.material.appbar.AppBarLayout;
import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.MathUtils; import org.chromium.base.MathUtils;
import org.chromium.chrome.browser.feed.FeedSurfaceCoordinator;
import org.chromium.chrome.browser.feed.shared.FeedFeatures; import org.chromium.chrome.browser.feed.shared.FeedFeatures;
import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
import org.chromium.chrome.browser.ntp.IncognitoDescriptionView; import org.chromium.chrome.browser.ntp.IncognitoDescriptionView;
...@@ -34,6 +38,8 @@ import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; ...@@ -34,6 +38,8 @@ import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration;
import org.chromium.chrome.tab_ui.R; import org.chromium.chrome.tab_ui.R;
import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.browser_ui.styles.ChromeColors;
import org.chromium.components.browser_ui.widget.CoordinatorLayoutForPointer; import org.chromium.components.browser_ui.widget.CoordinatorLayoutForPointer;
import org.chromium.components.browser_ui.widget.displaystyle.UiConfig;
import org.chromium.components.browser_ui.widget.displaystyle.ViewResizer;
import org.chromium.components.content_settings.CookieControlsEnforcement; import org.chromium.components.content_settings.CookieControlsEnforcement;
import org.chromium.ui.base.ViewUtils; import org.chromium.ui.base.ViewUtils;
...@@ -55,6 +61,7 @@ class TasksView extends CoordinatorLayoutForPointer { ...@@ -55,6 +61,7 @@ class TasksView extends CoordinatorLayoutForPointer {
private @CookieControlsEnforcement int mIncognitoCookieControlsToggleEnforcement = private @CookieControlsEnforcement int mIncognitoCookieControlsToggleEnforcement =
CookieControlsEnforcement.NO_ENFORCEMENT; CookieControlsEnforcement.NO_ENFORCEMENT;
private View.OnClickListener mIncognitoCookieControlsIconClickListener; private View.OnClickListener mIncognitoCookieControlsIconClickListener;
private UiConfig mUiConfig;
/** Default constructor needed to inflate via XML. */ /** Default constructor needed to inflate via XML. */
public TasksView(Context context, AttributeSet attrs) { public TasksView(Context context, AttributeSet attrs) {
...@@ -77,6 +84,8 @@ class TasksView extends CoordinatorLayoutForPointer { ...@@ -77,6 +84,8 @@ class TasksView extends CoordinatorLayoutForPointer {
(FrameLayout) findViewById(R.id.carousel_tab_switcher_container); (FrameLayout) findViewById(R.id.carousel_tab_switcher_container);
mSearchBoxCoordinator = new SearchBoxCoordinator(getContext(), this); mSearchBoxCoordinator = new SearchBoxCoordinator(getContext(), this);
mHeaderView = (AppBarLayout) findViewById(R.id.task_surface_header); mHeaderView = (AppBarLayout) findViewById(R.id.task_surface_header);
mUiConfig = new UiConfig(this);
setHeaderPadding();
AppBarLayout.LayoutParams layoutParams = AppBarLayout.LayoutParams layoutParams =
(AppBarLayout.LayoutParams) (findViewById(R.id.scroll_component_container) (AppBarLayout.LayoutParams) (findViewById(R.id.scroll_component_container)
.getLayoutParams()); .getLayoutParams());
...@@ -85,6 +94,13 @@ class TasksView extends CoordinatorLayoutForPointer { ...@@ -85,6 +94,13 @@ class TasksView extends CoordinatorLayoutForPointer {
setTabCarouselTitleStyle(); setTabCarouselTitleStyle();
} }
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mUiConfig.updateDisplayStyle();
alignHeaderForFeedV2();
}
private void adjustScrollMode(AppBarLayout.LayoutParams layoutParams) { private void adjustScrollMode(AppBarLayout.LayoutParams layoutParams) {
if (!StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue().equals("omniboxonly") if (!StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue().equals("omniboxonly")
&& !StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue().equals( && !StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue().equals(
...@@ -437,4 +453,51 @@ class TasksView extends CoordinatorLayoutForPointer { ...@@ -437,4 +453,51 @@ class TasksView extends CoordinatorLayoutForPointer {
fakeSearchBox.setLayoutParams(layoutParams); fakeSearchBox.setLayoutParams(layoutParams);
} }
/**
* Make the padding of header consistent with that of Feed recyclerview which is sized by {@link
* ViewResizer} in {@link FeedSurfaceCoordinator}
*/
private void setHeaderPadding() {
int defaultPadding = 0;
int widePadding = getResources().getDimensionPixelSize(FeedFeatures.cachedIsV2Enabled()
? R.dimen.ntp_wide_card_lateral_margins_v2
: R.dimen.ntp_wide_card_lateral_margins);
ViewResizer.createAndAttach(mHeaderView, mUiConfig, defaultPadding, widePadding);
alignHeaderForFeedV2();
}
/**
* Feed v2 has extra content padding, we need to align the header with it. However, the padding
* of the header is already bound with ViewResizer in setHeaderPadding(), so we update the left
* & right margins of MV tiles container and carousel tab switcher container.
*/
private void alignHeaderForFeedV2() {
if (!FeedFeatures.cachedIsV2Enabled()) {
return;
}
MarginLayoutParams MVParams =
(MarginLayoutParams) mHeaderView.findViewById(R.id.mv_tiles_container)
.getLayoutParams();
MarginLayoutParams carouselTabSwitcherParams =
(MarginLayoutParams) mCarouselTabSwitcherContainer.getLayoutParams();
int margin = getResources().getDimensionPixelSize(
R.dimen.content_suggestions_card_modern_padding_v2);
if (getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE) {
MVParams.leftMargin = margin;
MVParams.rightMargin = margin;
carouselTabSwitcherParams.leftMargin = margin;
carouselTabSwitcherParams.rightMargin = margin;
} else {
MVParams.leftMargin = 0;
MVParams.rightMargin = 0;
carouselTabSwitcherParams.leftMargin =
getResources().getDimensionPixelSize(R.dimen.tab_carousel_start_margin);
carouselTabSwitcherParams.rightMargin = 0;
}
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment