blob: 04b36015486597394359b72bfb5421f8ba13a7a7 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
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.action.ViewActions.swipeUp;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
import static androidx.test.espresso.matcher.ViewMatchers.withTagValue;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.chromium.chrome.features.start_surface.StartSurfaceTestUtils.INSTANT_START_TEST_BASE_PARAMS;
import static org.chromium.ui.test.util.ViewUtils.onViewWaiting;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.view.View;
import android.widget.ImageView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.filters.LargeTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import org.junit.After;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.MathUtils;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.test.params.ParameterAnnotations;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
import org.chromium.base.test.params.ParameterProvider;
import org.chromium.base.test.params.ParameterSet;
import org.chromium.base.test.params.ParameterizedRunner;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Criteria;
import org.chromium.base.test.util.CriteriaHelper;
import org.chromium.base.test.util.DisableIf;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.Restriction;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.feed.FeedPlaceholderLayout;
import org.chromium.chrome.browser.flags.CachedFeatureFlags;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.homepage.HomepageManager;
import org.chromium.chrome.browser.tabmodel.TabModelFilter;
import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil;
import org.chromium.chrome.browser.tasks.pseudotab.PseudoTab;
import org.chromium.chrome.browser.tasks.pseudotab.TabAttributeCache;
import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
import org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper;
import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.ActivityTestUtils;
import org.chromium.chrome.test.util.ChromeRenderTestRule;
import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
import org.chromium.components.embedder_support.util.UrlUtilitiesJni;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.ui.test.util.UiRestriction;
import org.chromium.ui.test.util.ViewUtils;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Integration tests of tab switcher with Instant Start which requires 2-stage initialization for
* Clank startup.
*/
@RunWith(ParameterizedRunner.class)
@ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
// clang-format off
@CommandLineFlags.
Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "force-fieldtrials=Study/Group"})
@EnableFeatures({ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID,
ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<Study,",
ChromeFeatureList.START_SURFACE_ANDROID + "<Study", ChromeFeatureList.INSTANT_START})
@Restriction({Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE,
UiRestriction.RESTRICTION_TYPE_PHONE})
public class InstantStartTabSwitcherTest {
// clang-format on
private static final String SHADOW_VIEW_TAG = "TabListViewShadow";
private static final long MAX_TIMEOUT_MS = 30000L;
@Rule
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
@Rule
public ChromeRenderTestRule mRenderTestRule =
ChromeRenderTestRule.Builder.withPublicCorpus().setRevision(1).build();
/**
* {@link ParameterProvider} used for parameterized test that provides whether it's single tab
* switcher or carousel tab switcher and whether last visited tab is a search result page.
*/
public static class LVTIsSRPTestParams implements ParameterProvider {
private static final List<ParameterSet> sLVTIsSRPTestParams =
Arrays.asList(new ParameterSet().value(false, false).name("CarouselTab_NotSRP"),
new ParameterSet().value(true, false).name("SingleTab_NotSRP"),
new ParameterSet().value(false, true).name("CarouselTab_SRP"),
new ParameterSet().value(true, true).name("SingleTab_SRP"));
@Override
public List<ParameterSet> getParameters() {
return sLVTIsSRPTestParams;
}
}
@After
public void tearDown() {
if (mActivityTestRule.getActivity() != null) {
ActivityTestUtils.clearActivityOrientation(mActivityTestRule.getActivity());
}
}
/**
* Tests that clicking the "more_tabs" button won't make Omnibox get focused when single tab is
* shown on the StartSurface.
*/
@Test
@MediumTest
@CommandLineFlags.Add({INSTANT_START_TEST_BASE_PARAMS + "/show_last_active_tab_only/true"})
public void startSurfaceMoreTabsButtonTest() throws IOException {
StartSurfaceTestUtils.createTabStateFile(new int[] {0});
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(0);
TabAttributeCache.setTitleForTesting(0, "Google");
StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
ChromeTabbedActivity cta = mActivityTestRule.getActivity();
Assert.assertFalse(cta.isTablet());
Assert.assertTrue(CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START));
Assert.assertEquals("single", StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue());
Assert.assertTrue(ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(-1));
Assert.assertTrue(StartSurfaceConfiguration.START_SURFACE_LAST_ACTIVE_TAB_ONLY.getValue());
mActivityTestRule.waitForActivityNativeInitializationComplete();
StartSurfaceTestUtils.clickMoreTabs(cta);
onViewWaiting(allOf(withParent(withId(org.chromium.chrome.test.R.id.tasks_surface_body)),
withId(org.chromium.chrome.test.R.id.tab_list_view)));
Assert.assertFalse(cta.findViewById(org.chromium.chrome.test.R.id.url_bar).isFocused());
}
@Test
@SmallTest
@Feature({"RenderTest"})
// clang-format off
@CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
INSTANT_START_TEST_BASE_PARAMS})
@DisabledTest(message = "Test doesn't work with FeedV2. FeedV1 is removed crbug.com/1165828.")
public void renderTabSwitcher() throws IOException, InterruptedException {
// clang-format on
StartSurfaceTestUtils.createTabStateFile(new int[] {0, 1, 2});
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(0);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(1);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(2);
TabAttributeCache.setTitleForTesting(0, "title");
TabAttributeCache.setTitleForTesting(1, "漢字");
TabAttributeCache.setTitleForTesting(2, "اَلْعَرَبِيَّةُ");
// Must be after StartSurfaceTestUtils.createTabStateFile() to read these files.
StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
ChromeTabbedActivity cta = mActivityTestRule.getActivity();
StartSurfaceTestUtils.waitForOverviewVisible(cta);
RecyclerView recyclerView = cta.findViewById(org.chromium.chrome.test.R.id.tab_list_view);
CriteriaHelper.pollUiThread(() -> allCardsHaveThumbnail(recyclerView));
mRenderTestRule.render(recyclerView, "tabSwitcher_3tabs");
// Resume native initialization and make sure the GTS looks the same.
StartSurfaceTestUtils.startAndWaitNativeInitialization(mActivityTestRule);
Assert.assertEquals(3, cta.getTabModelSelector().getCurrentModel().getCount());
// TODO(crbug.com/1065314): find a better way to wait for a stable rendering.
Thread.sleep(2000);
// The titles on the tab cards changes to "Google" because we use M26_GOOGLE_COM.
mRenderTestRule.render(recyclerView, "tabSwitcher_3tabs_postNative");
}
@Test
@SmallTest
@Feature({"RenderTest"})
// clang-format off
@EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID})
@CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
INSTANT_START_TEST_BASE_PARAMS})
@DisableIf.Build(message = "Flaky. See https://crbug.com/1091311",
sdk_is_greater_than = Build.VERSION_CODES.O)
public void renderTabGroups() throws IOException {
// clang-format on
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(0);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(1);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(2);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(3);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(4);
TabAttributeCache.setRootIdForTesting(0, 0);
TabAttributeCache.setRootIdForTesting(1, 0);
TabAttributeCache.setRootIdForTesting(2, 0);
TabAttributeCache.setRootIdForTesting(3, 3);
TabAttributeCache.setRootIdForTesting(4, 3);
// StartSurfaceTestUtils.createTabStateFile() has to be after setRootIdForTesting() to get
// root IDs.
StartSurfaceTestUtils.createTabStateFile(new int[] {0, 1, 2, 3, 4});
// Must be after StartSurfaceTestUtils.createTabStateFile() to read these files.
StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
ChromeTabbedActivity cta = mActivityTestRule.getActivity();
StartSurfaceTestUtils.waitForOverviewVisible(cta);
RecyclerView recyclerView = cta.findViewById(org.chromium.chrome.test.R.id.tab_list_view);
CriteriaHelper.pollUiThread(() -> allCardsHaveThumbnail(recyclerView));
// TODO(crbug.com/1065314): Tab group cards should not have favicons.
mRenderTestRule.render(cta.findViewById(org.chromium.chrome.test.R.id.tab_list_view),
"tabSwitcher_tabGroups_aspect_ratio_point85");
// Resume native initialization and make sure the GTS looks the same.
StartSurfaceTestUtils.startAndWaitNativeInitialization(mActivityTestRule);
Assert.assertEquals(5, cta.getTabModelSelector().getCurrentModel().getCount());
Assert.assertEquals(2,
cta.getTabModelSelector()
.getTabModelFilterProvider()
.getCurrentTabModelFilter()
.getCount());
Assert.assertEquals(3,
getRelatedTabListSizeOnUiThread(cta.getTabModelSelector()
.getTabModelFilterProvider()
.getCurrentTabModelFilter()));
// TODO(crbug.com/1065314): fix thumbnail changing in post-native rendering and make sure
// post-native GTS looks the same.
}
@Test
@SmallTest
@Feature({"RenderTest"})
// clang-format off
@EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID})
@CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
INSTANT_START_TEST_BASE_PARAMS})
@DisableIf.Build(message = "Flaky. See https://crbug.com/1091311",
sdk_is_greater_than = Build.VERSION_CODES.O)
public void renderTabGroups_ThemeRefactor() throws IOException {
// clang-format on
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(0);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(1);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(2);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(3);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(4);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(5);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(6);
TabAttributeCache.setRootIdForTesting(0, 0);
TabAttributeCache.setRootIdForTesting(1, 0);
TabAttributeCache.setRootIdForTesting(2, 0);
TabAttributeCache.setRootIdForTesting(3, 0);
TabAttributeCache.setRootIdForTesting(4, 0);
TabAttributeCache.setRootIdForTesting(5, 5);
TabAttributeCache.setRootIdForTesting(6, 5);
// StartSurfaceTestUtils.createTabStateFile() has to be after setRootIdForTesting() to get
// root IDs.
StartSurfaceTestUtils.createTabStateFile(new int[] {0, 1, 2, 3, 4, 5, 6});
// Must be after StartSurfaceTestUtils.createTabStateFile() to read these files.
StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
ChromeTabbedActivity cta = mActivityTestRule.getActivity();
StartSurfaceTestUtils.waitForOverviewVisible(cta);
RecyclerView recyclerView = cta.findViewById(org.chromium.chrome.test.R.id.tab_list_view);
CriteriaHelper.pollUiThread(() -> allCardsHaveThumbnail(recyclerView));
mRenderTestRule.render(cta.findViewById(org.chromium.chrome.test.R.id.tab_list_view),
"tabSwitcher_tabGroups_theme_enforcement");
}
@Test
@MediumTest
// clang-format off
@CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
INSTANT_START_TEST_BASE_PARAMS})
public void testSingleAsHomepage_CloseTabInCarouselTabSwitcher()
throws IOException, ExecutionException {
// clang-format on
StartSurfaceTestUtils.createTabStateFile(new int[] {0});
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(0);
TabAttributeCache.setTitleForTesting(0, "Google");
StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
ChromeTabbedActivity cta = mActivityTestRule.getActivity();
StartSurfaceTestUtils.waitForOverviewVisible(cta);
// Initializes native.
StartSurfaceTestUtils.startAndWaitNativeInitialization(mActivityTestRule);
StartSurfaceTestUtils.waitForTabModel(cta);
TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0);
onView(allOf(withParent(
withId(org.chromium.chrome.test.R.id.carousel_tab_switcher_container)),
withId(org.chromium.chrome.test.R.id.tab_list_view)))
.check(matches(isDisplayed()));
RecyclerView tabListView = cta.findViewById(org.chromium.chrome.test.R.id.tab_list_view);
TestThreadUtils.runOnUiThreadBlocking(
()
-> tabListView.getChildAt(0)
.findViewById(org.chromium.chrome.test.R.id.action_button)
.performClick());
TabUiTestHelper.verifyTabModelTabCount(cta, 0, 0);
assertEquals(
cta.findViewById(org.chromium.chrome.test.R.id.tab_switcher_title).getVisibility(),
View.GONE);
}
@Test
@LargeTest
// clang-format off
@CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
INSTANT_START_TEST_BASE_PARAMS,
FeedPlaceholderLayout.DISABLE_ANIMATION_SWITCH})
public void testScrollToSelectedTab() throws IOException {
// clang-format on
StartSurfaceTestUtils.createTabStateFile(new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, null, 5);
StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
ChromeTabbedActivity cta = mActivityTestRule.getActivity();
StartSurfaceTestUtils.waitForOverviewVisible(cta);
StartSurfaceTestUtils.startAndWaitNativeInitialization(mActivityTestRule);
StartSurfaceTestUtils.waitForOverviewVisible(cta);
StartSurfaceTestUtils.clickMoreTabs(cta);
onViewWaiting(withId(org.chromium.chrome.test.R.id.secondary_tasks_surface_view));
// Make sure the grid tab switcher is scrolled down to show the selected tab.
onView(allOf(withId(org.chromium.chrome.test.R.id.tab_list_view),
withParent(withId(org.chromium.chrome.test.R.id.tasks_surface_body))))
.check((v, noMatchException) -> {
if (noMatchException != null) throw noMatchException;
Assert.assertTrue(v instanceof RecyclerView);
LinearLayoutManager layoutManager =
(LinearLayoutManager) ((RecyclerView) v).getLayoutManager();
assertEquals(7, layoutManager.findLastVisibleItemPosition());
});
// On tab switcher page, shadow is handled by TabListRecyclerView itself, so toolbar shadow
// shouldn't show.
onView(withId(org.chromium.chrome.test.R.id.toolbar_shadow))
.check(matches(not(isDisplayed())));
// Scroll the tab list a little bit and shadow should show.
onView(allOf(withId(org.chromium.chrome.test.R.id.tab_list_view),
withParent(withId(org.chromium.chrome.test.R.id.tasks_surface_body))))
.perform(swipeUp());
onView(allOf(withTagValue(is(SHADOW_VIEW_TAG)),
isDescendantOfA(withId(org.chromium.chrome.test.R.id.tasks_surface_body))))
.check(matches(isDisplayed()));
}
@Test
@MediumTest
// clang-format off
@CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
INSTANT_START_TEST_BASE_PARAMS})
public void doNotRestoreEmptyTabs() throws IOException {
// clang-format on
StartSurfaceTestUtils.createTabStateFile(
new int[] {0, 1}, new String[] {"", "about:blank"});
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(0);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(1);
TabAttributeCache.setTitleForTesting(0, "");
TabAttributeCache.setTitleForTesting(0, "Google");
StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
StartSurfaceTestUtils.waitForOverviewVisible(mActivityTestRule.getActivity());
ViewUtils.onViewWaiting(withId(org.chromium.chrome.test.R.id.tab_list_view));
Assert.assertEquals(
1, PseudoTab.getAllPseudoTabsFromStateFile(mActivityTestRule.getActivity()).size());
}
@Test
@MediumTest
// clang-format off
@CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
INSTANT_START_TEST_BASE_PARAMS})
public void testSingleAsHomepage_Landscape_TabSize() {
// clang-format on
StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
ChromeTabbedActivity cta = mActivityTestRule.getActivity();
StartSurfaceTestUtils.waitForOverviewVisible(cta);
// Initializes native.
StartSurfaceTestUtils.startAndWaitNativeInitialization(mActivityTestRule);
onViewWaiting(
allOf(withId(org.chromium.chrome.start_surface.R.id.feed_stream_recycler_view),
isDisplayed()));
// Rotate to landscape mode.
ActivityTestUtils.rotateActivityToOrientation(cta, ORIENTATION_LANDSCAPE);
CriteriaHelper.pollUiThread(() -> {
Criteria.checkThat(
cta.getResources().getConfiguration().orientation, is(ORIENTATION_LANDSCAPE));
});
// Launch the first MV tile to open a tab.
StartSurfaceTestUtils.launchFirstMVTile(cta, /* currentTabCount = */ 0);
StartSurfaceTestUtils.pressHomePageButton(cta);
// Wait for thumbnail to show.
StartSurfaceTestUtils.waitForOverviewVisible(cta);
onViewWaiting(allOf(withId(org.chromium.chrome.test.R.id.tab_thumbnail), isDisplayed()));
View tabThumbnail = cta.findViewById(org.chromium.chrome.test.R.id.tab_thumbnail);
float defaultRatio = (float) TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO.getValue();
defaultRatio = MathUtils.clamp(defaultRatio, 0.5f, 2.0f);
assertEquals(tabThumbnail.getMeasuredHeight(),
(int) (tabThumbnail.getMeasuredWidth() * 1.0 / defaultRatio), 2);
}
@Test
@MediumTest
@CommandLineFlags.Add({INSTANT_START_TEST_BASE_PARAMS})
public void testShowTabSwitcherWhenHomepageDisabled() throws IOException {
// clang-format on
Assert.assertTrue(CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START));
Assert.assertEquals(0, ReturnToChromeExperimentsUtil.TAB_SWITCHER_ON_RETURN_MS.getValue());
testShowTabSwitcherWhenHomepageDisabledWithImmediateReturnImpl();
}
@Test
@MediumTest
@DisableFeatures(ChromeFeatureList.INSTANT_START)
@CommandLineFlags.Add({INSTANT_START_TEST_BASE_PARAMS})
public void testShowTabSwitcherWhenHomepageDisabled_NoInstant() throws IOException {
Assert.assertFalse(CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START));
Assert.assertEquals(0, ReturnToChromeExperimentsUtil.TAB_SWITCHER_ON_RETURN_MS.getValue());
testShowTabSwitcherWhenHomepageDisabledWithImmediateReturnImpl();
}
private void testShowTabSwitcherWhenHomepageDisabledWithImmediateReturnImpl()
throws IOException {
StartSurfaceTestUtils.createTabStateFile(new int[] {0});
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(0);
TabAttributeCache.setTitleForTesting(0, "Google");
TestThreadUtils.runOnUiThreadBlocking(
() -> HomepageManager.getInstance().setPrefHomepageEnabled(false));
Assert.assertFalse(HomepageManager.isHomepageEnabled());
// Launches Chrome and verifies that the Tab switcher is showing.
StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
ChromeTabbedActivity cta = mActivityTestRule.getActivity();
StartSurfaceTestUtils.waitForTabModel(cta);
TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0);
Assert.assertTrue(cta.getLayoutManager().overviewVisible());
StartSurfaceCoordinator startSurfaceCoordinator =
StartSurfaceTestUtils.getStartSurfaceFromUIThread(cta);
TestThreadUtils.runOnUiThreadBlocking(() -> {
Assert.assertEquals(startSurfaceCoordinator.getController().getStartSurfaceState(),
StartSurfaceState.NOT_SHOWN);
});
}
@Test
@MediumTest
// clang-format off
@CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
INSTANT_START_TEST_BASE_PARAMS + "/show_last_active_tab_only/true"})
@UseMethodParameter(LVTIsSRPTestParams.class)
public void testRecordLastVisitedTabIsSRPHistogram(boolean isSingleTabSwitcher, boolean isSRP)
throws IOException {
// clang-format on
testRecordLastVisitedTabIsSRP(isSingleTabSwitcher, isSRP);
}
@Test
@MediumTest
@DisableFeatures(ChromeFeatureList.INSTANT_START)
@UseMethodParameter(LVTIsSRPTestParams.class)
// clang-format off
@CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
INSTANT_START_TEST_BASE_PARAMS})
// clang-format on
public void testRecordLastVisitedTabIsSRPHistogram_NoInstant(
boolean isSingleTabSwitcher, boolean isSRP) throws IOException {
testRecordLastVisitedTabIsSRP(isSingleTabSwitcher, isSRP);
}
private void testRecordLastVisitedTabIsSRP(boolean isSingleTabSwitcher, boolean isSRP)
throws IOException {
StartSurfaceConfiguration.START_SURFACE_LAST_ACTIVE_TAB_ONLY.setForTesting(
isSingleTabSwitcher);
StartSurfaceTestUtils.createTabStateFile(new int[] {0, 1},
new String[] {"https://www.google.com/search?q=test", "https://www.google.com"},
isSRP ? 0 : 1);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(0);
StartSurfaceTestUtils.createThumbnailBitmapAndWriteToFile(1);
TabAttributeCache.setTitleForTesting(0, "Google SRP");
TabAttributeCache.setTitleForTesting(1, "Google Homepage");
StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
StartSurfaceTestUtils.startAndWaitNativeInitialization(mActivityTestRule);
ChromeTabbedActivity cta = mActivityTestRule.getActivity();
StartSurfaceTestUtils.waitForOverviewVisible(cta);
StartSurfaceTestUtils.waitForDeferredStartup(mActivityTestRule);
Assert.assertEquals(isSRP,
UrlUtilitiesJni.get().isGoogleSearchUrl(
StartSurfaceUserData.getInstance().getLastVisitedTabAtStartupUrl()));
Assert.assertEquals(1,
RecordHistogram.getHistogramTotalCountForTesting(
ReturnToChromeExperimentsUtil
.LAST_VISITED_TAB_IS_SRP_WHEN_OVERVIEW_IS_SHOWN_AT_LAUNCH_UMA));
Assert.assertEquals(1,
RecordHistogram.getHistogramValueCountForTesting(
ReturnToChromeExperimentsUtil
.LAST_VISITED_TAB_IS_SRP_WHEN_OVERVIEW_IS_SHOWN_AT_LAUNCH_UMA,
isSRP ? 1 : 0));
}
private boolean allCardsHaveThumbnail(RecyclerView recyclerView) {
RecyclerView.Adapter adapter = recyclerView.getAdapter();
assert adapter != null;
for (int i = 0; i < adapter.getItemCount(); i++) {
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(i);
if (viewHolder != null) {
ImageView thumbnail = viewHolder.itemView.findViewById(
org.chromium.chrome.test.R.id.tab_thumbnail);
if (!(thumbnail.getDrawable() instanceof BitmapDrawable)) return false;
BitmapDrawable drawable = (BitmapDrawable) thumbnail.getDrawable();
Bitmap bitmap = drawable.getBitmap();
if (bitmap == null) return false;
}
}
return true;
}
private int getRelatedTabListSizeOnUiThread(TabModelFilter tabModelFilter) {
AtomicInteger res = new AtomicInteger();
TestThreadUtils.runOnUiThreadBlocking(
() -> { res.set(tabModelFilter.getRelatedTabList(2).size()); });
return res.get();
}
}