// Copyright 2019 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.os.Build.VERSION_CODES.O_MR1;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
import static androidx.test.espresso.matcher.ViewMatchers.Visibility.GONE;
import static androidx.test.espresso.matcher.ViewMatchers.Visibility.VISIBLE;
import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.core.AllOf.allOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import static org.chromium.base.test.util.CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL;
import static org.chromium.base.test.util.CriteriaHelper.DEFAULT_POLLING_INTERVAL;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.areAnimatorsEnabled;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.closeFirstTabInTabSwitcher;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createTabGroup;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createTabs;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.enterTabSwitcher;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.finishActivity;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.getSwipeToDismissAction;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.leaveTabSwitcher;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.mergeAllNormalTabsToAGroup;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.switchTabModel;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.verifyTabModelTabCount;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.verifyTabSwitcherCardCount;
import static org.chromium.components.embedder_support.util.UrlConstants.NTP_URL;
import static org.chromium.ui.test.util.ViewUtils.onViewWaiting;
import static org.chromium.ui.test.util.ViewUtils.waitForView;

import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
import android.view.View;
import android.widget.ImageView;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.espresso.Espresso;
import androidx.test.espresso.NoMatchingViewException;
import androidx.test.espresso.ViewAssertion;
import androidx.test.espresso.contrib.AccessibilityChecks;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.filters.MediumTest;

import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.chromium.base.Callback;
import org.chromium.base.GarbageCollectionTestUtils;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.test.util.ApplicationTestUtils;
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.FlakyTest;
import org.chromium.base.test.util.MinAndroidSdkLevel;
import org.chromium.base.test.util.Restriction;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.compositor.layouts.Layout;
import org.chromium.chrome.browser.compositor.layouts.StaticLayout;
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
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.night_mode.ChromeNightModeTestUtils;
import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tab.TabStateExtractor;
import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils;
import org.chromium.chrome.browser.tabmodel.TabCreator;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
import org.chromium.chrome.browser.tasks.pseudotab.PseudoTab;
import org.chromium.chrome.browser.tasks.pseudotab.TabAttributeCache;
import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
import org.chromium.chrome.browser.tasks.tab_management.TabProperties;
import org.chromium.chrome.browser.tasks.tab_management.TabSelectionEditorTestingRobot;
import org.chromium.chrome.browser.tasks.tab_management.TabSuggestionMessageService;
import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher;
import org.chromium.chrome.browser.tasks.tab_management.TabSwitcherCoordinator;
import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
import org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper;
import org.chromium.chrome.browser.tasks.tab_management.TabUiThemeProvider;
import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
import org.chromium.chrome.browser.undo_tab_close_snackbar.UndoBarController;
import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
import org.chromium.chrome.tab_ui.R;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
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.ChromeTabUtils;
import org.chromium.chrome.test.util.MenuUtils;
import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher;
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.components.embedder_support.util.UrlUtilities;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.content_public.browser.test.util.WebContentsUtils;
import org.chromium.net.test.EmbeddedTestServer;
import org.chromium.ui.base.PageTransition;
import org.chromium.ui.test.util.DisableAnimationsTestRule;
import org.chromium.ui.test.util.UiRestriction;
import org.chromium.ui.util.ColorUtils;
import org.chromium.ui.widget.ChipView;
import org.chromium.ui.widget.ChromeImageView;
import org.chromium.ui.widget.ViewLookupCachingFrameLayout;

import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

// clang-format off
/** Tests for the {@link StartSurfaceLayout} */
@SuppressWarnings("ConstantConditions")
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
        "force-fieldtrials=Study/Group"})
@EnableFeatures({ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + "<Study"})
@Restriction(
        {UiRestriction.RESTRICTION_TYPE_PHONE, Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE})
@DisableIf.Build(message = "Flaky on emulators; see https://crbug.com/1130830",
        supported_abis_includes = "x86")
public class StartSurfaceLayoutTest {
    // clang-format on
    private static final String BASE_PARAMS = "force-fieldtrial-params="
            + "Study.Group:soft-cleanup-delay/0/cleanup-delay/0/skip-slow-zooming/false"
            + "/zooming-min-sdk-version/19/zooming-min-memory-mb/512";

    // Tests need animation on.
    @ClassRule
    public static DisableAnimationsTestRule sEnableAnimationsRule =
            new DisableAnimationsTestRule(true);

    @Rule
    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();

    @Rule
    public ChromeRenderTestRule mRenderTestRule =
            ChromeRenderTestRule.Builder.withPublicCorpus().setRevision(1).build();

    @SuppressWarnings("FieldCanBeLocal")
    private EmbeddedTestServer mTestServer;
    private StartSurfaceLayout mStartSurfaceLayout;
    private String mUrl;
    private int mRepeat;
    private List<WeakReference<Bitmap>> mAllBitmaps = new LinkedList<>();
    private Callback<Bitmap> mBitmapListener =
            (bitmap) -> mAllBitmaps.add(new WeakReference<>(bitmap));
    private TabSwitcher.TabListDelegate mTabListDelegate;

    @Before
    public void setUp() {
        AccessibilityChecks.enable();
        mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
        // After setUp, Chrome is launched and has one NTP.
        mActivityTestRule.startMainActivityFromLauncher();

        Layout layout = mActivityTestRule.getActivity().getLayoutManager().getOverviewLayout();
        assertTrue(layout instanceof StartSurfaceLayout);
        mStartSurfaceLayout = (StartSurfaceLayout) layout;
        mUrl = mTestServer.getURL("/chrome/test/data/android/navigate/simple.html");
        mRepeat = 1;

        mTabListDelegate = mStartSurfaceLayout.getStartSurfaceForTesting().getGridTabListDelegate();
        mTabListDelegate.setBitmapCallbackForTesting(mBitmapListener);
        assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting());

        mActivityTestRule.getActivity().getTabContentManager().setCaptureMinRequestTimeForTesting(
                0);

        CriteriaHelper.pollUiThread(
                mActivityTestRule.getActivity().getTabModelSelector()::isTabStateInitialized);

        assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting());
    }

    @After
    public void tearDown() {
        ActivityTestUtils.clearActivityOrientation(mActivityTestRule.getActivity());
        TestThreadUtils.runOnUiThreadBlocking(
                ChromeNightModeTestUtils::tearDownNightModeAfterChromeActivityDestroyed);
        TestThreadUtils.runOnUiThreadBlocking(
                () -> ChromeAccessibilityUtil.get().setAccessibilityEnabledForTesting(null));
    }

    @Test
    @MediumTest
    @Feature({"RenderTest"})
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    public void testRenderGrid_3WebTabs() throws IOException {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        prepareTabs(3, 0, "about:blank");
        // Make sure all thumbnails are there before switching tabs.
        enterGTSWithThumbnailRetry();
        leaveTabSwitcher(cta);

        ChromeTabUtils.switchTabInCurrentTabModel(cta, 0);
        enterTabSwitcher(cta);
        mRenderTestRule.render(cta.findViewById(R.id.tab_list_view), "3_web_tabs");
    }

    @Test
    @MediumTest
    @Feature({"RenderTest"})
    // clang-format off
    @CommandLineFlags.Add({BASE_PARAMS})
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @DisableIf.Build(sdk_is_greater_than = O_MR1, message = "crbug.com/1077552")
    public void testRenderGrid_10WebTabs() throws IOException {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        prepareTabs(10, 0, "about:blank");
        // Make sure all thumbnails are there before switching tabs.
        enterGTSWithThumbnailRetry();
        leaveTabSwitcher(cta);

        ChromeTabUtils.switchTabInCurrentTabModel(cta, 0);
        enterTabSwitcher(cta);
        mRenderTestRule.render(cta.findViewById(R.id.tab_list_view), "10_web_tabs");
    }

    @Test
    @MediumTest
    @Feature({"RenderTest"})
    // clang-format off
    @CommandLineFlags.Add({BASE_PARAMS})
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @DisabledTest(message = "https://crbug.com/1139807")
    @DisableIf.Build(sdk_is_greater_than = O_MR1, message = "crbug.com/1077552")
    public void testRenderGrid_10WebTabs_InitialScroll() throws IOException {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        prepareTabs(10, 0, "about:blank");
        assertEquals(9, cta.getTabModelSelector().getCurrentModel().index());
        enterGTSWithThumbnailRetry();
        // Make sure the grid tab switcher is scrolled down to show the selected tab.
        mRenderTestRule.render(cta.findViewById(R.id.tab_list_view), "10_web_tabs-select_last");
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    public void testSwitchTabModel_ScrollToSelectedTab() throws IOException {
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        prepareTabs(10, 0, "about:blank");
        assertEquals(9, cta.getCurrentTabModel().index());
        createTabs(cta, true, 1);
        CriteriaHelper.pollUiThread(() -> cta.getCurrentTabModel().isIncognito());
        enterTabSwitcher(cta);
        switchTabModel(cta, false);
        TabUiTestHelper.verifyAllTabsHaveThumbnail(cta.getCurrentTabModel());
        // Make sure the grid tab switcher is scrolled down to show the selected tab.
        onView(tabSwitcherViewMatcher()).check((v, noMatchException) -> {
            if (noMatchException != null) throw noMatchException;
            assertTrue(v instanceof RecyclerView);
            LinearLayoutManager layoutManager =
                    (LinearLayoutManager) ((RecyclerView) v).getLayoutManager();
            assertEquals(9, layoutManager.findLastVisibleItemPosition());
        });
    }

    @Test
    @MediumTest
    @Feature({"RenderTest"})
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    public void testRenderGrid_Incognito() throws IOException {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        // Prepare some incognito tabs and enter tab switcher.
        prepareTabs(1, 3, "about:blank");
        assertTrue(cta.getCurrentTabModel().isIncognito());
        // Make sure all thumbnails are there before switching tabs.
        enterGTSWithThumbnailRetry();
        leaveTabSwitcher(cta);

        ChromeTabUtils.switchTabInCurrentTabModel(cta, 0);
        enterTabSwitcher(cta);
        mRenderTestRule.render(cta.findViewById(R.id.tab_list_view), "3_incognito_web_tabs");
    }

    @Test
    @MediumTest
    @Feature({"RenderTest"})
    @DisableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION})
    // clang-format off
    @CommandLineFlags.Add({BASE_PARAMS})
    public void testRenderGrid_3NativeTabs() throws IOException {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        // Prepare some incognito native tabs and enter tab switcher.
        // NTP in incognito mode is chosen for its consistency in look, and we don't have to mock
        // away the MV tiles, login promo, feed, etc.
        prepareTabs(1, 3, null);
        assertTrue(cta.getCurrentTabModel().isIncognito());
        // Make sure all thumbnails are there before switching tabs.
        enterGTSWithThumbnailRetry();
        leaveTabSwitcher(cta);
        // Espresso.pressBack();

        ChromeTabUtils.switchTabInCurrentTabModel(cta, 0);
        enterTabSwitcher(cta);
        mRenderTestRule.render(cta.findViewById(R.id.tab_list_view), "3_incognito_ntps");
    }

    @Test
    @MediumTest
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    @CommandLineFlags.Add({BASE_PARAMS})
    public void testTabToGridFromLiveTab() throws InterruptedException {
        assertFalse(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        assertEquals(0, mTabListDelegate.getSoftCleanupDelayForTesting());
        assertEquals(0, mTabListDelegate.getCleanupDelayForTesting());

        prepareTabs(2, 0, NTP_URL);
        testTabToGrid(mUrl);
    }

    @Test
    @MediumTest
    @EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study")
    @CommandLineFlags.Add({BASE_PARAMS})
    @DisabledTest(message = "crbug.com/991852 This test is flaky")
    public void testTabToGridFromLiveTabAnimation() throws InterruptedException {
        assertTrue(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());

        prepareTabs(2, 0, NTP_URL);
        testTabToGrid(mUrl);
    }

    @Test
    @MediumTest
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    @CommandLineFlags.Add({BASE_PARAMS + "/soft-cleanup-delay/2000/cleanup-delay/10000"})
    public void testTabToGridFromLiveTabWarm() throws InterruptedException {
        assertFalse(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        assertEquals(2000, mTabListDelegate.getSoftCleanupDelayForTesting());
        assertEquals(10000, mTabListDelegate.getCleanupDelayForTesting());

        prepareTabs(2, 0, NTP_URL);
        testTabToGrid(mUrl);
    }

    @Test
    @MediumTest
    @EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study")
    @CommandLineFlags.Add({BASE_PARAMS + "/soft-cleanup-delay/2000/cleanup-delay/10000"})
    @MinAndroidSdkLevel(Build.VERSION_CODES.M) // TODO(crbug.com/997065#c8): remove SDK restriction.
    @DisabledTest(message = "https://crbug.com/1207875")
    public void testTabToGridFromLiveTabWarmAnimation() throws InterruptedException {
        assertTrue(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        prepareTabs(2, 0, NTP_URL);
        testTabToGrid(mUrl);
    }

    @Test
    @MediumTest
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    @CommandLineFlags.Add({BASE_PARAMS + "/cleanup-delay/10000"})
    public void testTabToGridFromLiveTabSoft() throws InterruptedException {
        assertFalse(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        assertEquals(0, mTabListDelegate.getSoftCleanupDelayForTesting());
        assertEquals(10000, mTabListDelegate.getCleanupDelayForTesting());

        prepareTabs(2, 0, NTP_URL);
        testTabToGrid(mUrl);
    }

    @Test
    @MediumTest
    @EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study")
    @CommandLineFlags.Add({BASE_PARAMS + "/cleanup-delay/10000"})
    @MinAndroidSdkLevel(Build.VERSION_CODES.M) // TODO(crbug.com/997065#c8): remove SDK restriction.
    public void testTabToGridFromLiveTabSoftAnimation() throws InterruptedException {
        assertTrue(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        prepareTabs(2, 0, NTP_URL);
        testTabToGrid(mUrl);
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    @FlakyTest(message = "crbug.com/1075804")
    public void testTabToGridFromNtp() throws InterruptedException {
        prepareTabs(2, 0, NTP_URL);
        testTabToGrid(NTP_URL);
    }

    /**
     * Make Chrome have {@code numTabs} of regular Tabs and {@code numIncognitoTabs} of incognito
     * tabs with {@code url} loaded, and assert no bitmap fetching occurred.
     *
     * @param numTabs The number of regular tabs.
     * @param numIncognitoTabs The number of incognito tabs.
     * @param url The URL to load.
     */
    private void prepareTabs(int numTabs, int numIncognitoTabs, @Nullable String url) {
        int oldCount = mTabListDelegate.getBitmapFetchCountForTesting();
        TabUiTestHelper.prepareTabsWithThumbnail(mActivityTestRule, numTabs, numIncognitoTabs, url);
        assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting() - oldCount);
    }

    private void testTabToGrid(String fromUrl) throws InterruptedException {
        mActivityTestRule.loadUrl(fromUrl);

        final int initCount = getCaptureCount();

        for (int i = 0; i < mRepeat; i++) {
            enterGTSWithThumbnailChecking();
            leaveGTSAndVerifyThumbnailsAreReleased();
        }
        checkFinalCaptureCount(false, initCount);
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    public void testGridToTabToCurrentNTP() throws InterruptedException {
        prepareTabs(1, 0, NTP_URL);
        testGridToTab(false, false);
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    public void testGridToTabToOtherNTP() throws InterruptedException {
        prepareTabs(2, 0, NTP_URL);
        testGridToTab(true, false);
    }

    @Test
    @MediumTest
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    public void testGridToTabToCurrentLive() throws InterruptedException {
        assertFalse(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        prepareTabs(1, 0, mUrl);
        testGridToTab(false, false);
    }

    // From https://stackoverflow.com/a/21505193
    private static boolean isEmulator() {
        return Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.startsWith("unknown")
                || Build.MODEL.contains("google_sdk") || Build.MODEL.contains("Emulator")
                || Build.MODEL.contains("Android SDK built for x86")
                || Build.MANUFACTURER.contains("Genymotion")
                || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
                || "google_sdk".equals(Build.PRODUCT);
    }

    /**
     * Test that even if there are tabs with stuck pending thumbnail readback, it doesn't block
     * thumbnail readback for the current tab.
     */
    @Test
    @MediumTest
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    public void testGridToTabToCurrentLiveDetached() throws Exception {
        assertFalse(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        // This works on emulators but not on real devices. See crbug.com/986047.
        if (!isEmulator()) return;

        for (int i = 0; i < 10; i++) {
            ChromeTabbedActivity cta = mActivityTestRule.getActivity();
            // Quickly create some tabs, navigate to web pages, and don't wait for thumbnail
            // capturing.
            mActivityTestRule.loadUrl(mUrl);
            ChromeTabUtils.newTabFromMenu(
                    InstrumentationRegistry.getInstrumentation(), cta, false, false);
            mActivityTestRule.loadUrl(mUrl);
            // Hopefully we are in a state where some pending readbacks are stuck because their tab
            // is not attached to the view.
            if (cta.getTabContentManager().getPendingReadbacksForTesting() > 0) {
                break;
            }

            // Restart Chrome.
            // Although we're destroying the activity, the Application will still live on since its
            // in the same process as this test.
            TestThreadUtils.runOnUiThreadBlocking(() -> cta.getTabModelSelector().closeAllTabs());
            TabUiTestHelper.finishActivity(cta);
            mActivityTestRule.startMainActivityOnBlankPage();
            assertEquals(1, mActivityTestRule.tabsCount(false));
        }
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        assertNotEquals(0, cta.getTabContentManager().getPendingReadbacksForTesting());
        assertEquals(1, cta.getCurrentTabModel().index());

        // The last tab should still get thumbnail even though readbacks for other tabs are stuck.
        enterTabSwitcher(cta);
        TabUiTestHelper.checkThumbnailsExist(cta.getTabModelSelector().getCurrentTab());
    }

    @Test
    @MediumTest
    @EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study")
    @DisabledTest(message = "crbug.com/993201 This test fails deterministically on Nexus 5X")
    public void testGridToTabToCurrentLiveWithAnimation() throws InterruptedException {
        assertTrue(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        prepareTabs(1, 0, mUrl);
        testGridToTab(false, false);
    }

    @Test
    @MediumTest
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    public void testGridToTabToOtherLive() throws InterruptedException {
        assertFalse(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        prepareTabs(2, 0, mUrl);
        testGridToTab(true, false);
    }

    @Test
    @MediumTest
    @EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study")
    @DisabledTest(message = "crbug.com/993201 This test fails deterministically on Nexus 5X")
    public void testGridToTabToOtherLiveWithAnimation() throws InterruptedException {
        assertTrue(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        prepareTabs(2, 0, mUrl);
        testGridToTab(true, false);
    }

    @Test
    @MediumTest
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    public void testGridToTabToOtherFrozen() throws InterruptedException {
        assertFalse(TabUiFeatureUtilities.isTabToGtsAnimationEnabled());
        prepareTabs(2, 0, mUrl);
        testGridToTab(true, true);
    }

    private void testGridToTab(boolean switchToAnotherTab, boolean killBeforeSwitching)
            throws InterruptedException {
        final int initCount = getCaptureCount();

        for (int i = 0; i < mRepeat; i++) {
            enterGTSWithThumbnailChecking();

            final int index = mActivityTestRule.getActivity().getCurrentTabModel().index();
            final int targetIndex = switchToAnotherTab ? 1 - index : index;
            Tab targetTab =
                    mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(targetIndex);
            if (killBeforeSwitching) {
                WebContentsUtils.simulateRendererKilled(targetTab.getWebContents(), false);
            }

            if (switchToAnotherTab) {
                waitForCaptureRateControl();
            }
            int count = getCaptureCount();
            onView(tabSwitcherViewMatcher()).perform(actionOnItemAtPosition(targetIndex, click()));
            CriteriaHelper.pollUiThread(() -> {
                boolean doneHiding =
                        !mActivityTestRule.getActivity().getLayoutManager().overviewVisible();
                if (!doneHiding) {
                    // Before overview hiding animation is done, the tab index should not change.
                    Criteria.checkThat(mActivityTestRule.getActivity().getCurrentTabModel().index(),
                            Matchers.is(index));
                }
                return doneHiding;
            }, "Overview not hidden yet");
            int delta;
            if (switchToAnotherTab
                    && !UrlUtilities.isNTPUrl(mActivityTestRule.getActivity()
                                                      .getCurrentWebContents()
                                                      .getLastCommittedUrl())) {
                // Capture the original tab.
                delta = 1;
            } else {
                delta = 0;
            }
            checkCaptureCount(delta, count);
        }
        checkFinalCaptureCount(switchToAnotherTab, initCount);
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    public void testRestoredTabsDontFetch() throws Exception {
        prepareTabs(2, 0, mUrl);
        int oldCount = mTabListDelegate.getBitmapFetchCountForTesting();

        // Restart Chrome.
        // Although we're destroying the activity, the Application will still live on since its in
        // the same process as this test.
        TabUiTestHelper.finishActivity(mActivityTestRule.getActivity());
        mActivityTestRule.startMainActivityOnBlankPage();
        assertEquals(3, mActivityTestRule.tabsCount(false));

        Layout layout = mActivityTestRule.getActivity().getLayoutManager().getOverviewLayout();
        assertTrue(layout instanceof StartSurfaceLayout);
        mStartSurfaceLayout = (StartSurfaceLayout) layout;
        assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting() - oldCount);
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    public void testInvisibleTabsDontFetch() throws InterruptedException {
        // Open a few new tabs.
        final int count = mTabListDelegate.getBitmapFetchCountForTesting();
        for (int i = 0; i < 3; i++) {
            MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
                    mActivityTestRule.getActivity(), org.chromium.chrome.R.id.new_tab_menu_id);
        }
        // Fetching might not happen instantly.
        Thread.sleep(1000);

        // No fetching should happen.
        assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting() - count);
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/soft-cleanup-delay/2000/cleanup-delay/10000"})
    @FlakyTest(message = "crbug.com/1075804")
    public void testInvisibleTabsDontFetchWarm() throws InterruptedException {
        // Get the GTS in the warm state.
        prepareTabs(2, 0, NTP_URL);
        testTabToGrid(NTP_URL);

        Thread.sleep(1000);

        // Open a few new tabs.
        final int count = mTabListDelegate.getBitmapFetchCountForTesting();
        for (int i = 0; i < 3; i++) {
            MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
                    mActivityTestRule.getActivity(), org.chromium.chrome.R.id.new_tab_menu_id);
        }
        // Fetching might not happen instantly.
        Thread.sleep(1000);

        // No fetching should happen.
        assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting() - count);
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/cleanup-delay/10000"})
    @FlakyTest(message = "crbug.com/1075804")
    public void testInvisibleTabsDontFetchSoft() throws InterruptedException {
        // Get the GTS in the soft cleaned up state.
        prepareTabs(2, 0, NTP_URL);
        testTabToGrid(NTP_URL);

        Thread.sleep(1000);

        // Open a few new tabs.
        final int count = mTabListDelegate.getBitmapFetchCountForTesting();
        for (int i = 0; i < 3; i++) {
            MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
                    mActivityTestRule.getActivity(), org.chromium.chrome.R.id.new_tab_menu_id);
        }
        // Fetching might not happen instantly.
        Thread.sleep(1000);

        // No fetching should happen.
        assertEquals(0, mTabListDelegate.getBitmapFetchCountForTesting() - count);
    }

    @Test
    @MediumTest
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    @DisabledTest(message = "http://crbug/1005865 - Test was previously flaky but only on bots."
            + "Was not locally reproducible. Disabling until verified that it's deflaked on bots.")
    public void testIncognitoEnterGts() throws InterruptedException {
        // clang-format on
        prepareTabs(1, 1, null);
        enterGTSWithThumbnailChecking();
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));

        onView(tabSwitcherViewMatcher()).perform(actionOnItemAtPosition(0, click()));
        CriteriaHelper.pollUiThread(
                () -> !mActivityTestRule.getActivity().getLayoutManager().overviewVisible());

        enterGTSWithThumbnailChecking();
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    public void testIncognitoToggle_tabCount() {
        mActivityTestRule.loadUrl(mUrl);
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();

        // Prepare two incognito tabs and enter tab switcher.
        createTabs(cta, true, 2);
        enterTabSwitcher(cta);
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(2));

        for (int i = 0; i < mRepeat; i++) {
            switchTabModel(cta, false);
            onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));

            switchTabModel(cta, true);
            onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(2));
        }
        leaveGTSAndVerifyThumbnailsAreReleased();
    }

    @Test
    @MediumTest
    // clang-format off
    @CommandLineFlags.Add({BASE_PARAMS})
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.M,
            message = "https://crbug.com/1023833")
    public void testIncognitoToggle_thumbnailFetchCount() throws InterruptedException {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        int oldFetchCount = mTabListDelegate.getBitmapFetchCountForTesting();

        // Prepare two incognito tabs and enter tab switcher.
        prepareTabs(1, 2, mUrl);
        enterGTSWithThumbnailChecking();

        int currentFetchCount = mTabListDelegate.getBitmapFetchCountForTesting();
        assertEquals(2, currentFetchCount - oldFetchCount);
        oldFetchCount = currentFetchCount;
        int oldHistogramRecord = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_JPEG);

        for (int i = 0; i < mRepeat; i++) {
            switchTabModel(cta, false);
            currentFetchCount = mTabListDelegate.getBitmapFetchCountForTesting();
            int currentHistogramRecord = RecordHistogram.getHistogramValueCountForTesting(
                    TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                    TabContentManager.ThumbnailFetchingResult.GOT_JPEG);
            assertEquals(1, currentFetchCount - oldFetchCount);
            assertEquals(1, currentHistogramRecord - oldHistogramRecord);
            oldFetchCount = currentFetchCount;
            oldHistogramRecord = currentHistogramRecord;

            switchTabModel(cta, true);
            currentFetchCount = mTabListDelegate.getBitmapFetchCountForTesting();
            currentHistogramRecord = RecordHistogram.getHistogramValueCountForTesting(
                    TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                    TabContentManager.ThumbnailFetchingResult.GOT_JPEG);
            assertEquals(2, currentFetchCount - oldFetchCount);
            assertEquals(2, currentHistogramRecord - oldHistogramRecord);
            oldFetchCount = currentFetchCount;
            oldHistogramRecord = currentHistogramRecord;
        }
        leaveGTSAndVerifyThumbnailsAreReleased();
    }

    @Test
    @MediumTest
    // clang-format off
    @CommandLineFlags.Add({BASE_PARAMS})
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
                    ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID,
                    ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    public void testUrlUpdatedNotCrashing_ForUndoableClosedTab() throws Exception {
        // clang-format on
        mActivityTestRule.getActivity().getSnackbarManager().disableForTesting();
        prepareTabs(2, 0, null);
        enterGTSWithThumbnailChecking();

        Tab tab = mActivityTestRule.getActivity().getTabModelSelector().getCurrentTab();
        TestThreadUtils.runOnUiThreadBlocking(() -> {
            mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().closeTab(
                    tab, false, false, true);
        });
        mActivityTestRule.loadUrlInTab(
                mUrl, PageTransition.TYPED | PageTransition.FROM_ADDRESS_BAR, tab);
    }

    @Test
    @MediumTest
    // clang-format off
    @CommandLineFlags.Add({BASE_PARAMS})
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
            ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID,
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    public void testUrlUpdatedNotCrashing_ForTabNotInCurrentModel() throws Exception {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        prepareTabs(1, 1, null);
        enterGTSWithThumbnailChecking();

        Tab tab = cta.getTabModelSelector().getCurrentTab();
        switchTabModel(cta, false);

        mActivityTestRule.loadUrlInTab(
                mUrl, PageTransition.TYPED | PageTransition.FROM_ADDRESS_BAR, tab);
    }

    private int getTabCountInCurrentTabModel() {
        return mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().getCount();
    }

    @Test
    @MediumTest
    @Feature("TabSuggestion")
    // clang-format off
    @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0/"
        + "thumbnail_aspect_ratio/1.0"})
    public void testTabSuggestionMessageCard_dismiss() throws InterruptedException {
        // clang-format on
        prepareTabs(3, 0, null);

        // TODO(meiliang): Avoid using static variable for tracking state,
        // TabSuggestionMessageService.isSuggestionAvailableForTesting(). Instead, we can add a
        // dummy MessageObserver to track the availability of the suggestions.
        CriteriaHelper.pollUiThread(TabSuggestionMessageService::isSuggestionAvailableForTesting);
        CriteriaHelper.pollUiThread(
                () -> Criteria.checkThat(getTabCountInCurrentTabModel(), Matchers.is(3)));

        enterGTSWithThumbnailChecking();

        // TODO(meiliang): Avoid using static variable for tracking state,
        // TabSwitcherCoordinator::hasAppendedMessagesForTesting. Instead, we can query the number
        // of items that the inner model of the TabSwitcher has.
        CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
        onView(withId(R.id.tab_grid_message_item)).check(matches(isDisplayed()));
        onView(allOf(withId(R.id.close_button), withParent(withId(R.id.tab_grid_message_item))))
                .perform(click());
        onView(withId(R.id.tab_grid_message_item)).check(doesNotExist());
    }

    @Test
    @MediumTest
    @Feature("TabSuggestion")
    // clang-format off
    @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0"
        + "/thumbnail_aspect_ratio/1.0"})
    public void testTabSuggestionMessageCard_review() throws InterruptedException {
        // clang-format on
        prepareTabs(3, 0, null);

        CriteriaHelper.pollUiThread(TabSuggestionMessageService::isSuggestionAvailableForTesting);
        CriteriaHelper.pollUiThread(
                () -> Criteria.checkThat(getTabCountInCurrentTabModel(), Matchers.is(3)));

        enterGTSWithThumbnailChecking();

        CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
        onView(withId(R.id.tab_grid_message_item)).check(matches(isDisplayed()));
        onView(allOf(withId(R.id.action_button), withParent(withId(R.id.tab_grid_message_item))))
                .perform(click());

        TabSelectionEditorTestingRobot tabSelectionEditorTestingRobot =
                new TabSelectionEditorTestingRobot();
        tabSelectionEditorTestingRobot.resultRobot.verifyTabSelectionEditorIsVisible();

        Espresso.pressBack();
        tabSelectionEditorTestingRobot.resultRobot.verifyTabSelectionEditorIsHidden();
    }

    @Test
    @MediumTest
    @Feature("TabSuggestion")
    @FlakyTest(message = "https://crbug.com/1230107")
    // clang-format off
    @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0/"
        + "thumbnail_aspect_ratio/1.0"})
    public void testShowOnlyOneTabSuggestionMessageCard_withSoftCleanup()
            throws InterruptedException {
        // clang-format on
        verifyOnlyOneTabSuggestionMessageCardIsShowing();
    }

    @Test
    @MediumTest
    @Feature("TabSuggestion")
    // clang-format off
    @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0/"
        + "thumbnail_aspect_ratio/1.0"})
    @FlakyTest(message = "https://crbug.com/1198484")
    public void testShowOnlyOneTabSuggestionMessageCard_withHardCleanup()
            throws InterruptedException {
        // clang-format on
        verifyOnlyOneTabSuggestionMessageCardIsShowing();
    }

    @Test
    @MediumTest
    @Feature("TabSuggestion")
    // clang-format off
    @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0/"
        + "thumbnail_aspect_ratio/1.0"})
    public void testTabSuggestionMessageCardDismissAfterTabClosing() throws InterruptedException {
        // clang-format on
        prepareTabs(3, 0, mUrl);
        CriteriaHelper.pollUiThread(TabSuggestionMessageService::isSuggestionAvailableForTesting);
        CriteriaHelper.pollUiThread(
                () -> Criteria.checkThat(getTabCountInCurrentTabModel(), Matchers.is(3)));

        enterGTSWithThumbnailChecking();
        CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
        onView(withId(R.id.tab_grid_message_item)).check(matches(isDisplayed()));

        closeFirstTabInTabSwitcher();

        CriteriaHelper.pollUiThread(
                () -> !TabSuggestionMessageService.isSuggestionAvailableForTesting());
        CriteriaHelper.pollUiThread(
                () -> Criteria.checkThat(getTabCountInCurrentTabModel(), Matchers.is(2)));

        onView(tabSwitcherViewMatcher())
                .check(TabUiTestHelper.ChildrenCountAssertion.havingTabSuggestionMessageCardCount(
                        0));
        onView(withId(R.id.tab_grid_message_item)).check(doesNotExist());
    }

    @Test
    @MediumTest
    @Feature("NewTabTile")
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @DisableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS})
    @CommandLineFlags.Add({BASE_PARAMS + "/tab_grid_layout_android_new_tab_tile/NewTabTile"
            + "/tab_grid_layout_android_new_tab/false"})
    public void testNewTabTile() throws InterruptedException {
        // clang-format on
        // TODO(yuezhanggg): Modify TabUiTestHelper.verifyTabSwitcherCardCount so that it can be
        // used here to verify card count. Right now it doesn't work because when switching between
        // normal/incognito, the tab list fading-in animation has not finished when check happens.
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        prepareTabs(2, 0, null);

        // New tab tile should be showing.
        enterGTSWithThumbnailChecking();
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(3));
        onView(withId(R.id.new_tab_tile)).check(matches(isDisplayed()));
        verifyTabModelTabCount(cta, 2, 0);

        // Clicking new tab tile in normal mode should create a normal tab.
        onView(withId(R.id.new_tab_tile)).perform(click());
        CriteriaHelper.pollUiThread(() -> !cta.getOverviewModeBehavior().overviewVisible());
        enterGTSWithThumbnailChecking();
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(4));
        onView(withId(R.id.new_tab_tile)).check(matches(isDisplayed()));
        verifyTabModelTabCount(cta, 3, 0);

        // New tab tile should be showing in incognito mode.
        switchTabModel(cta, true);
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(withId(R.id.new_tab_tile)).check(matches(isDisplayed()));

        // Clicking new tab tile in incognito mode should create an incognito tab.
        onView(withId(R.id.new_tab_tile)).perform(click());
        CriteriaHelper.pollUiThread(() -> !cta.getOverviewModeBehavior().overviewVisible());
        enterGTSWithThumbnailChecking();
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(2));
        onView(withId(R.id.new_tab_tile)).check(matches(isDisplayed()));
        verifyTabModelTabCount(cta, 3, 1);

        // Close all normal tabs and incognito tabs, the new tab tile should still show in both
        // modes.
        switchTabModel(cta, false);
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(4));
        MenuUtils.invokeCustomMenuActionSync(
                InstrumentationRegistry.getInstrumentation(), cta, R.id.close_all_tabs_menu_id);
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(withId(R.id.new_tab_tile)).check(matches(isDisplayed()));
        switchTabModel(cta, true);
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(withId(R.id.new_tab_tile)).check(matches(isDisplayed()));
    }

    @Test
    @MediumTest
    @Feature("TabSuggestion")
    // clang-format off
    @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0/"
        + "thumbnail_aspect_ratio/1.0"})
    public void testTabSuggestionMessageCard_orientation() throws InterruptedException {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        prepareTabs(3, 0, null);

        CriteriaHelper.pollUiThread(TabSuggestionMessageService::isSuggestionAvailableForTesting);
        CriteriaHelper.pollUiThread(
                () -> Criteria.checkThat(getTabCountInCurrentTabModel(), Matchers.is(3)));

        enterGTSWithThumbnailChecking();
        CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);

        // Force portrait mode since the device can be wrongly in landscape. See crbug/1063639.
        ActivityTestUtils.rotateActivityToOrientation(cta, Configuration.ORIENTATION_PORTRAIT);

        onView(tabSwitcherViewMatcher())
                .check(MessageCardWidthAssertion.checkMessageItemSpanSize(3, 2));

        ActivityTestUtils.rotateActivityToOrientation(cta, Configuration.ORIENTATION_LANDSCAPE);

        onView(tabSwitcherViewMatcher())
                .check(MessageCardWidthAssertion.checkMessageItemSpanSize(3, 3));
    }

    private static class MessageCardWidthAssertion implements ViewAssertion {
        private int mIndex;
        private int mSpanCount;

        public static MessageCardWidthAssertion checkMessageItemSpanSize(int index, int spanCount) {
            return new MessageCardWidthAssertion(index, spanCount);
        }

        public MessageCardWidthAssertion(int index, int spanCount) {
            mIndex = index;
            mSpanCount = spanCount;
        }

        @Override
        public void check(View view, NoMatchingViewException noMatchException) {
            if (noMatchException != null) throw noMatchException;
            int tabListPadding =
                    (int) TabUiThemeProvider.getTabCardPaddingDimension(view.getContext());

            assertTrue(view instanceof RecyclerView);
            RecyclerView recyclerView = (RecyclerView) view;
            GridLayoutManager layoutManager = (GridLayoutManager) recyclerView.getLayoutManager();
            assertEquals(mSpanCount, layoutManager.getSpanCount());

            RecyclerView.ViewHolder messageItemViewHolder =
                    recyclerView.findViewHolderForAdapterPosition(mIndex);
            assertNotNull(messageItemViewHolder);
            assertEquals(TabProperties.UiType.MESSAGE, messageItemViewHolder.getItemViewType());
            View messageItemView = messageItemViewHolder.itemView;

            // The message card item width should always be recyclerView width minus padding.
            assertEquals(recyclerView.getWidth() - 2 * tabListPadding, messageItemView.getWidth());
        }
    }

    @Test
    @MediumTest
    @Feature("NewTabTile")
    // clang-format off
    @DisableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION,
            ChromeFeatureList.CLOSE_TAB_SUGGESTIONS})
    @CommandLineFlags.Add({BASE_PARAMS + "/tab_grid_layout_android_new_tab_tile/false"
            + "/tab_grid_layout_android_new_tab/false"})
    public void testNewTabTile_Disabled() throws InterruptedException {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        prepareTabs(2, 0, null);

        enterGTSWithThumbnailChecking();

        onView(withId(R.id.new_tab_tile)).check(doesNotExist());
        verifyTabSwitcherCardCount(cta, 2);

        switchTabModel(cta, true);
        onView(withId(R.id.new_tab_tile)).check(doesNotExist());
        verifyTabSwitcherCardCount(cta, 0);
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    @DisabledTest(message = "https://crbug.com/1122657")
    public void testThumbnailAspectRatio_default() {
        prepareTabs(2, 0, mUrl);
        enterTabSwitcher(mActivityTestRule.getActivity());
        onView(tabSwitcherViewMatcher())
                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(1.0));
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.75"})
    @DisabledTest(message = "https://crbug.com/1122657")
    public void testThumbnailAspectRatio_point75() {
        prepareTabs(2, 0, mUrl);
        enterTabSwitcher(mActivityTestRule.getActivity());
        onView(tabSwitcherViewMatcher())
                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.75));
        leaveGTSAndVerifyThumbnailsAreReleased();

        Tab tab = mActivityTestRule.getActivity().getTabModelSelector().getCurrentTab();
        mActivityTestRule.loadUrlInTab(
                NTP_URL, PageTransition.TYPED | PageTransition.FROM_ADDRESS_BAR, tab);
        enterTabSwitcher(mActivityTestRule.getActivity());
        onView(tabSwitcherViewMatcher())
                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.75));
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/2.0/allow_to_refetch/true"})
    @DisabledTest(message = "Flaky - https://crbug.com/1124041")
    public void testThumbnailAspectRatio_fromTwoToPoint75() throws Exception {
        prepareTabs(2, 0, mUrl);
        enterTabSwitcher(mActivityTestRule.getActivity());
        onView(tabSwitcherViewMatcher())
                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0));
        TabModel currentTabModel =
                mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel();
        for (int i = 0; i < currentTabModel.getCount(); i++) {
            TabUiTestHelper.checkThumbnailsExist(currentTabModel.getTabAt(i));
        }
        leaveGTSAndVerifyThumbnailsAreReleased();

        simulateAspectRatioChangedToPoint75();
        verifyAllThumbnailHasAspectRatio(0.75);

        enterTabSwitcher(mActivityTestRule.getActivity());
        onView(tabSwitcherViewMatcher())
                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0));
        TabUiTestHelper.finishActivity(mActivityTestRule.getActivity());
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    @DisabledTest(message = "https://crbug.com/1138739")
    public void testThumbnailFetchingResult_defaultAspectRatio() throws Exception {
        prepareTabs(2, 0, mUrl);
        int oldJpegCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_JPEG);
        int oldEtc1Count = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_ETC1);
        int oldNothingCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_NOTHING);
        int oldDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG);

        enterTabSwitcher(mActivityTestRule.getActivity());
        int currentJpegCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_JPEG);
        int currentEtc1Count = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_ETC1);
        int currentNothingCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_NOTHING);
        int currentDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG);

        assertEquals(1, currentJpegCount - oldJpegCount);
        assertEquals(0, currentEtc1Count - oldEtc1Count);
        assertEquals(0, currentDifferentAspectRatioJpegCount - oldDifferentAspectRatioJpegCount);
        // Get thumbnail from a live layer.
        assertEquals(1, currentNothingCount - oldNothingCount);

        oldJpegCount = currentJpegCount;
        oldEtc1Count = currentEtc1Count;
        oldNothingCount = currentNothingCount;
        oldDifferentAspectRatioJpegCount = currentDifferentAspectRatioJpegCount;

        TabModel currentTabModel =
                mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel();
        for (int i = 0; i < currentTabModel.getCount(); i++) {
            TabUiTestHelper.checkThumbnailsExist(currentTabModel.getTabAt(i));
        }

        TabUiTestHelper.finishActivity(mActivityTestRule.getActivity());
        mActivityTestRule.startMainActivityFromLauncher();

        enterTabSwitcher(mActivityTestRule.getActivity());
        assertEquals(2,
                RecordHistogram.getHistogramValueCountForTesting(
                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                        TabContentManager.ThumbnailFetchingResult.GOT_JPEG)
                        - oldJpegCount);
        assertEquals(0,
                RecordHistogram.getHistogramValueCountForTesting(
                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                        TabContentManager.ThumbnailFetchingResult.GOT_ETC1)
                        - oldEtc1Count);
        assertEquals(0,
                RecordHistogram.getHistogramValueCountForTesting(
                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                        TabContentManager.ThumbnailFetchingResult.GOT_NOTHING)
                        - oldNothingCount);
        assertEquals(0,
                RecordHistogram.getHistogramValueCountForTesting(
                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                        TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG)
                        - oldDifferentAspectRatioJpegCount);
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/2.0/allow_to_refetch/true"})
    @DisabledTest(message = "http://crbug/1119527 - Flaky on bots.")
    public void testThumbnailFetchingResult_changingAspectRatio() throws Exception {
        prepareTabs(2, 0, mUrl);
        int oldJpegCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_JPEG);
        int oldEtc1Count = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_ETC1);
        int oldNothingCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_NOTHING);
        int oldDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG);

        enterTabSwitcher(mActivityTestRule.getActivity());
        int currentJpegCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_JPEG);
        int currentEtc1Count = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_ETC1);
        int currentNothingCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_NOTHING);
        int currentDifferentAspectRatioJpegCount = RecordHistogram.getHistogramValueCountForTesting(
                TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG);

        assertEquals(1, currentJpegCount - oldJpegCount);
        assertEquals(0, currentEtc1Count - oldEtc1Count);
        assertEquals(0, currentDifferentAspectRatioJpegCount - oldDifferentAspectRatioJpegCount);
        // Get thumbnail from a live layer.
        assertEquals(1, currentNothingCount - oldNothingCount);

        oldJpegCount = currentJpegCount;
        oldEtc1Count = currentEtc1Count;
        oldNothingCount = currentNothingCount;
        oldDifferentAspectRatioJpegCount = currentDifferentAspectRatioJpegCount;

        onView(tabSwitcherViewMatcher())
                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0));

        TabModel currentTabModel =
                mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel();
        for (int i = 0; i < currentTabModel.getCount(); i++) {
            TabUiTestHelper.checkThumbnailsExist(currentTabModel.getTabAt(i));
        }
        leaveGTSAndVerifyThumbnailsAreReleased();

        simulateAspectRatioChangedToPoint75();
        verifyAllThumbnailHasAspectRatio(0.75);

        enterTabSwitcher(mActivityTestRule.getActivity());
        assertEquals(0,
                RecordHistogram.getHistogramValueCountForTesting(
                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                        TabContentManager.ThumbnailFetchingResult.GOT_JPEG)
                        - oldJpegCount);
        assertEquals(2,
                RecordHistogram.getHistogramValueCountForTesting(
                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                        TabContentManager.ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG)
                        - oldDifferentAspectRatioJpegCount);
        assertEquals(0,
                RecordHistogram.getHistogramValueCountForTesting(
                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                        TabContentManager.ThumbnailFetchingResult.GOT_ETC1)
                        - oldEtc1Count);
        assertEquals(0,
                RecordHistogram.getHistogramValueCountForTesting(
                        TabContentManager.UMA_THUMBNAIL_FETCHING_RESULT,
                        TabContentManager.ThumbnailFetchingResult.GOT_NOTHING)
                        - oldNothingCount);
        onView(tabSwitcherViewMatcher())
                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0));
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS})
    public void testRecycling_defaultAspectRatio() {
        prepareTabs(10, 0, mUrl);
        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);
        enterTabSwitcher(mActivityTestRule.getActivity());
        onView(tabSwitcherViewMatcher()).perform(RecyclerViewActions.scrollToPosition(9));
    }

    @Test
    @MediumTest
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.75"})
    public void testRecycling_aspectRatioPoint75() {
        // clang-format on
        prepareTabs(10, 0, mUrl);
        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);
        enterTabSwitcher(mActivityTestRule.getActivity());
        onView(tabSwitcherViewMatcher()).perform(RecyclerViewActions.scrollToPosition(9));
    }

    @Test
    @MediumTest
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.75"})
    public void testExpandTab_withAspectRatioPoint75() {
        // clang-format on
        prepareTabs(1, 0, mUrl);
        enterTabSwitcher(mActivityTestRule.getActivity());
        leaveGTSAndVerifyThumbnailsAreReleased();
    }

    @Test
    @MediumTest
    @Feature({"RenderTest"})
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/1.0"})
    @DisabledTest(message = "https://crbug.com/1205952")
    public void testRenderGrid_withAspectRatioOfOne() throws IOException {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        prepareTabs(3, 0, "about:blank");
        TabModel normalTabModel = cta.getTabModelSelector().getModel(false);
        List<Tab> tabGroup = new ArrayList<>(
                Arrays.asList(normalTabModel.getTabAt(0), normalTabModel.getTabAt(1)));
        createTabGroup(cta, false, tabGroup);
        // Make sure all tabs have thumbnail.
        enterGTSWithThumbnailRetry();
        mRenderTestRule.render(cta.findViewById(R.id.tab_list_view), "aspect_ratio_of_one");
    }

    @Test
    @MediumTest
    @Feature("NewTabVariation")
    @DisabledTest(message = "https://crbug.com/1144666")
    // clang-format off
    @Features.DisableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION,
            ChromeFeatureList.CLOSE_TAB_SUGGESTIONS})
    @CommandLineFlags.Add({BASE_PARAMS + "/tab_grid_layout_android_new_tab/NewTabVariation"})
    public void testNewTabVariation() {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        prepareTabs(2, 0, null);
        enterTabSwitcher(cta);
        verifyTabModelTabCount(cta, 2, 0);
        checkNewTabVariationVisibility(true);

        createTabs(cta, true, 1);
        verifyTabModelTabCount(cta, 2, 1);
        enterTabSwitcher(cta);
        checkNewTabVariationVisibility(false);

        switchTabModel(cta, false);
        checkNewTabVariationVisibility(false);

        switchTabModel(cta, true);
        checkNewTabVariationVisibility(false);

        closeFirstTabInTabSwitcher();
        verifyTabModelTabCount(cta, 2, 0);
        checkNewTabVariationVisibility(true);

        createTabs(cta, true, 2);
        verifyTabModelTabCount(cta, 2, 2);
        enterTabSwitcher(cta);
        checkNewTabVariationVisibility(false);

        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), cta,
                R.id.close_all_incognito_tabs_menu_id);
        verifyTabModelTabCount(cta, 2, 0);
        checkNewTabVariationVisibility(true);
    }

    private void checkNewTabVariationVisibility(boolean isVisible) {
        if (isVisible) {
            onView(allOf(withId(R.id.incognito_toggle_tabs),
                           withParent(withId(R.id.tab_switcher_toolbar))))
                    .check(matches(withEffectiveVisibility(GONE)));
            onView(allOf(withId(R.id.new_tab_button),
                           withParent(withId(R.id.tab_switcher_toolbar))))
                    .check(matches(withEffectiveVisibility(GONE)));
            onView(allOf(withId(R.id.new_tab_view), withParent(withId(R.id.tab_switcher_toolbar))))
                    .check(matches(isDisplayed()));
        } else {
            onView(allOf(withId(R.id.incognito_toggle_tabs),
                           withParent(withId(R.id.tab_switcher_toolbar))))
                    .check(matches(isDisplayed()));
            onView(allOf(withId(R.id.new_tab_button),
                           withParent(withId(R.id.tab_switcher_toolbar))))
                    .check(matches(isDisplayed()));
            onView(allOf(withId(R.id.new_tab_view), withParent(withId(R.id.tab_switcher_toolbar))))
                    .check(matches(withEffectiveVisibility(GONE)));
        }
    }

    @Test
    @MediumTest
    // clang-format off
    @CommandLineFlags.Add({BASE_PARAMS})
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
            ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID,
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<study"})
    @DisabledTest
    public void testCloseTabViaCloseButton() throws Exception {
        // clang-format on
        mActivityTestRule.getActivity().getSnackbarManager().disableForTesting();
        prepareTabs(1, 0, null);
        enterGTSWithThumbnailChecking();

        onView(allOf(withId(R.id.action_button), withParent(withId(R.id.content_view)),
                       withEffectiveVisibility(VISIBLE)))
                .perform(click());
    }

    @Test
    @MediumTest
    // clang-format off
    @CommandLineFlags.Add({BASE_PARAMS})
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<study"})
    @DisabledTest(message = "Flaky - https://crbug.com/1124041")
    public void testSwipeToDismiss_GTS() {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        // Create 3 tabs and merge the first two tabs into one group.
        createTabs(cta, false, 3);
        enterTabSwitcher(cta);
        TabModel normalTabModel = cta.getTabModelSelector().getModel(false);
        List<Tab> tabGroup = new ArrayList<>(
                Arrays.asList(normalTabModel.getTabAt(0), normalTabModel.getTabAt(1)));
        createTabGroup(cta, false, tabGroup);
        verifyTabSwitcherCardCount(cta, 2);
        verifyTabModelTabCount(cta, 3, 0);

        // Swipe to dismiss a single tab card.
        onView(tabSwitcherViewMatcher())
                .perform(RecyclerViewActions.actionOnItemAtPosition(
                        1, getSwipeToDismissAction(false)));
        verifyTabSwitcherCardCount(cta, 1);
        verifyTabModelTabCount(cta, 2, 0);

        // Swipe to dismiss a tab group card.
        onView(tabSwitcherViewMatcher())
                .perform(RecyclerViewActions.actionOnItemAtPosition(
                        0, getSwipeToDismissAction(true)));
        verifyTabSwitcherCardCount(cta, 0);
        verifyTabModelTabCount(cta, 0, 0);
    }

    @Test
    @MediumTest
    // clang-format off
    @DisabledTest(message = "https://crbug.com/1144666")
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
            ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID + "<study",
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<study"})
    @CommandLineFlags.Add({BASE_PARAMS + "/enable_launch_polish/true"})
    public void testCloseButtonDescription() {
        String expectedDescription = "Close New tab tab";
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        enterTabSwitcher(cta);

        // Test single tab.
        onView(allOf(withParent(withId(R.id.content_view)), withId(R.id.action_button),
                       withEffectiveVisibility(VISIBLE)))
                .check(ViewContentDescription.havingDescription(expectedDescription));

        // Create 2 tabs and merge them into one group.
        createTabs(cta, false, 2);
        enterTabSwitcher(cta);
        TabModel normalTabModel = cta.getTabModelSelector().getModel(false);
        List<Tab> tabGroup = new ArrayList<>(
                Arrays.asList(normalTabModel.getTabAt(0), normalTabModel.getTabAt(1)));
        createTabGroup(cta, false, tabGroup);
        verifyTabSwitcherCardCount(cta, 1);

        // Test group tab.
        expectedDescription = "Close tab group with 2 tabs";
        onView(allOf(withParent(withId(R.id.content_view)), withId(R.id.action_button),
                       withEffectiveVisibility(VISIBLE)))
                .check(ViewContentDescription.havingDescription(expectedDescription));
    }

    private static class ViewContentDescription implements ViewAssertion {
        private String mExpectedDescription;

        public static ViewContentDescription havingDescription(String description) {
            return new ViewContentDescription(description);
        }

        public ViewContentDescription(String description) {
            mExpectedDescription = description;
        }

        @Override
        public void check(View view, NoMatchingViewException noMatchException) {
            if (noMatchException != null) throw noMatchException;

            assertEquals(mExpectedDescription, view.getContentDescription());
        }
    }

    private static class TabCountAssertion implements ViewAssertion {
        private int mExpectedCount;

        public static TabCountAssertion havingTabCount(int tabCount) {
            return new TabCountAssertion(tabCount);
        }

        public TabCountAssertion(int expectedCount) {
            mExpectedCount = expectedCount;
        }

        @Override
        public void check(View view, NoMatchingViewException noMatchException) {
            if (noMatchException != null) throw noMatchException;

            RecyclerView.Adapter adapter = ((RecyclerView) view).getAdapter();
            assertEquals(mExpectedCount, adapter.getItemCount());
        }
    }

    private static class ThumbnailAspectRatioAssertion implements ViewAssertion {
        private double mExpectedRatio;

        public static ThumbnailAspectRatioAssertion havingAspectRatio(double ratio) {
            return new ThumbnailAspectRatioAssertion(ratio);
        }

        private ThumbnailAspectRatioAssertion(double expectedRatio) {
            mExpectedRatio = expectedRatio;
        }

        @Override
        public void check(View view, NoMatchingViewException noMatchException) {
            if (noMatchException != null) throw noMatchException;

            RecyclerView recyclerView = (RecyclerView) view;

            RecyclerView.Adapter adapter = recyclerView.getAdapter();
            for (int i = 0; i < adapter.getItemCount(); i++) {
                RecyclerView.ViewHolder viewHolder =
                        recyclerView.findViewHolderForAdapterPosition(i);
                if (viewHolder != null) {
                    ViewLookupCachingFrameLayout tabView =
                            (ViewLookupCachingFrameLayout) viewHolder.itemView;
                    ImageView thumbnail = (ImageView) tabView.fastFindViewById(R.id.tab_thumbnail);
                    BitmapDrawable drawable = (BitmapDrawable) thumbnail.getDrawable();
                    Bitmap bitmap = drawable.getBitmap();
                    double bitmapRatio = bitmap.getWidth() * 1.0 / bitmap.getHeight();
                    assertTrue(
                            "Actual ratio: " + bitmapRatio + "; Expected ratio: " + mExpectedRatio,
                            Math.abs(bitmapRatio - mExpectedRatio)
                                    <= TabContentManager.ASPECT_RATIO_PRECISION);
                }
            }
        }
    }

    private void waitForLastSearchTerm(Tab tab, String expected) {
        CriteriaHelper.pollUiThread(() -> {
            Criteria.checkThat(
                    TabAttributeCache.getLastSearchTerm(tab.getId()), Matchers.is(expected));
        });
    }

    @Test
    @MediumTest
    // Disable TAB_TO_GTS_ANIMATION to make it less flaky.
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    @CommandLineFlags.Add({BASE_PARAMS + "/enable_search_term_chip/true"})
    public void testSearchTermChip_noChip() throws InterruptedException {
        assertTrue(TabUiFeatureUtilities.ENABLE_SEARCH_CHIP.getValue());
        prepareTabs(1, 0, mUrl);
        enterTabSwitcher(mActivityTestRule.getActivity());

        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(allOf(withId(R.id.page_info_button),
                       isDescendantOfA(withId(R.id.compositor_view_holder))))
                .check(matches(not(isDisplayed())));
    }

    @Test
    @MediumTest
    // Disable TAB_TO_GTS_ANIMATION to make it less flaky.
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    @CommandLineFlags.Add({BASE_PARAMS + "/enable_search_term_chip/true"})
    @DisabledTest(message = "http://crbug/1120822 - Flaky on bots.")
    public void testSearchTermChip_withChip() throws InterruptedException {
        assertTrue(TabUiFeatureUtilities.ENABLE_SEARCH_CHIP.getValue());
        // Make sure we support RTL and CJKV languages.
        String searchTermWithSpecialCodePoints = "a\n ئۇيغۇرچە\u200E漢字";
        // Special code points like new line (\n) and left-to-right marker (‎‎‎\u200E) should
        // be stripped out. See TabAttributeCache#removeEscapedCodePoints for more details.
        String expectedTerm = "a ئۇيغۇرچە漢字";

        String anotherTerm = "hello world";

        // Do search, and verify the chip is still not shown.
        AtomicReference<String> searchUrl = new AtomicReference<>();
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        Tab currentTab = cta.getTabModelSelector().getCurrentTab();
        TestThreadUtils.runOnUiThreadBlocking(() -> {
            TemplateUrlServiceFactory.get().setSearchEngine("google.com");
            searchUrl.set(TemplateUrlServiceFactory.get().getUrlForSearchQuery(
                    searchTermWithSpecialCodePoints));
            currentTab.loadUrl(new LoadUrlParams(searchUrl.get()));
        });
        ChromeTabUtils.waitForTabPageLoaded(currentTab, null);
        enterTabSwitcher(mActivityTestRule.getActivity());

        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(withId(R.id.page_info_button)).check(matches(not(isDisplayed())));
        Espresso.pressBack();

        // Navigate, and verify the chip is shown.
        mActivityTestRule.loadUrl(mUrl);
        waitForLastSearchTerm(currentTab, expectedTerm);
        enterTabSwitcher(mActivityTestRule.getActivity());

        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(withId(R.id.page_info_button))
                .check(waitForView(allOf(withText(expectedTerm), isDisplayed())));
        Espresso.pressBack();

        // Do another search, and verify the chip is gone.
        AtomicReference<String> searchUrl2 = new AtomicReference<>();
        TestThreadUtils.runOnUiThreadBlocking(() -> {
            TemplateUrlServiceFactory.get().setSearchEngine("google.com");
            searchUrl2.set(TemplateUrlServiceFactory.get().getUrlForSearchQuery(anotherTerm));
            currentTab.loadUrl(new LoadUrlParams(searchUrl2.get()));
        });
        ChromeTabUtils.waitForTabPageLoaded(currentTab, null);
        waitForLastSearchTerm(currentTab, null);
        enterTabSwitcher(mActivityTestRule.getActivity());

        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(withId(R.id.page_info_button)).check(matches(not(isDisplayed())));
        Espresso.pressBack();

        // Back to previous page, and verify the chip is back.
        Espresso.pressBack();
        waitForLastSearchTerm(currentTab, expectedTerm);
        enterTabSwitcher(mActivityTestRule.getActivity());

        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(withId(R.id.page_info_button))
                .check(waitForView(allOf(withText(expectedTerm), isDisplayed())));

        // Click the chip and check the tab navigates back to the search result page.
        assertEquals(mUrl, ChromeTabUtils.getUrlStringOnUiThread(currentTab));
        OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta);
        onView(withId(R.id.page_info_button))
                .check(waitForView(allOf(withText(expectedTerm), isDisplayed())));
        onView(withId(R.id.page_info_button)).perform(click());
        hideWatcher.waitForBehavior();
        ChromeTabUtils.waitForTabPageLoaded(currentTab, searchUrl.get());

        // Verify the chip is gone.
        waitForLastSearchTerm(currentTab, null);
        enterTabSwitcher(mActivityTestRule.getActivity());

        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(withId(R.id.page_info_button)).check(matches(not(isDisplayed())));
    }

    @Test
    @MediumTest
    // clang-format off
    // Disable TAB_TO_GTS_ANIMATION to make it less flaky.
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    @CommandLineFlags.Add({BASE_PARAMS +
            "/enable_search_term_chip/true/enable_search_term_chip_adaptive_icon/true"})
    public void testSearchTermChip_adaptiveIcon() throws InterruptedException {
        // clang-format on
        assertTrue(TabUiFeatureUtilities.ENABLE_SEARCH_CHIP.getValue());
        assertTrue(TabUiFeatureUtilities.ENABLE_SEARCH_CHIP_ADAPTIVE.getValue());
        String searchTerm = "hello world";

        // Do search, and verify the chip is still not shown.
        AtomicReference<String> searchUrl = new AtomicReference<>();
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        Tab currentTab = cta.getTabModelSelector().getCurrentTab();
        TestThreadUtils.runOnUiThreadBlocking(() -> {
            TemplateUrlServiceFactory.get().setSearchEngine("google.com");
            searchUrl.set(TemplateUrlServiceFactory.get().getUrlForSearchQuery(searchTerm));
            currentTab.loadUrl(new LoadUrlParams(searchUrl.get()));
        });
        ChromeTabUtils.waitForTabPageLoaded(currentTab, null);
        enterTabSwitcher(mActivityTestRule.getActivity());

        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(allOf(withId(R.id.page_info_button),
                       isDescendantOfA(withId(R.id.compositor_view_holder))))
                .check(matches(not(isDisplayed())));
        Espresso.pressBack();

        // Navigate, and verify the chip is shown.
        mActivityTestRule.loadUrl(mUrl);
        waitForLastSearchTerm(currentTab, searchTerm);
        enterTabSwitcher(mActivityTestRule.getActivity());

        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
        onView(allOf(withId(R.id.page_info_button),
                       isDescendantOfA(withId(R.id.compositor_view_holder))))
                .check(waitForView(allOf(withText(searchTerm), isDisplayed())));

        // Switch the default search engine from google.com to yahoo.com, the search chip icon
        // should change.
        RecyclerView tabListRecyclerView = cta.findViewById(R.id.tab_list_view);
        ChipView chipView =
                tabListRecyclerView.findViewHolderForAdapterPosition(0).itemView.findViewById(
                        R.id.page_info_button);
        ChromeImageView iconImageView = (ChromeImageView) chipView.getChildAt(0);
        Drawable googleDrawable = iconImageView.getDrawable();

        TestThreadUtils.runOnUiThreadBlocking(
                () -> TemplateUrlServiceFactory.get().setSearchEngine("yahoo.com"));

        assertNotEquals(googleDrawable, iconImageView.getDrawable());
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID})
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    @FlakyTest(message = "crbug.com/1096997")
    public void testTabGroupManualSelection() throws InterruptedException {
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        TabSelectionEditorTestingRobot robot = new TabSelectionEditorTestingRobot();
        createTabs(cta, false, 3);
        enterTabSwitcher(cta);
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(3));

        enterTabGroupManualSelection(cta);
        robot.resultRobot.verifyTabSelectionEditorIsVisible();

        // Group first two tabs.
        robot.actionRobot.clickItemAtAdapterPosition(0);
        robot.actionRobot.clickItemAtAdapterPosition(1);
        robot.actionRobot.clickToolbarActionButton();

        // Exit manual selection mode, back to tab switcher.
        robot.resultRobot.verifyTabSelectionEditorIsHidden();
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(2));
        onViewWaiting(withText("2 tabs grouped"));
    }

    @Test
    @MediumTest
    // clang-format off
    @DisabledTest(message = "https://crbug.com/1144666")
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    public void testTabGroupManualSelection_DisabledForSingleTab() {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        enterTabSwitcher(cta);
        verifyTabSwitcherCardCount(cta, 1);

        // Group option should be disabled when there is only one single tab.
        // We are using UiDevice to finish the click here since there seems to be more than one menu
        // button in the view hierarchy, and we couldn't locate it using espresso approach. Also,
        // performClick() won't work as the logic that handles menu button lies in onTouchListener.
        View menuButton =
                cta.findViewById(R.id.tab_switcher_toolbar).findViewById(R.id.menu_button);
        int[] location = new int[2];
        menuButton.getLocationOnScreen(location);
        UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
                .click(location[0], location[1]);
        onView(withText("Group tabs"))
                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
                .check(matches(not(isEnabled())));

        // Group option should be enabled when there is more than one single tab.
        createTabs(cta, false, 2);
        enterTabSwitcher(cta);
        verifyTabSwitcherCardCount(cta, 2);
        UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
                .click(location[0], location[1]);
        onView(withText("Group tabs"))
                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
                .check(matches(isEnabled()));
    }

    @Test
    @MediumTest
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    public void testTabGroupManualSelection_SystemBackDismiss() {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        TabSelectionEditorTestingRobot robot = new TabSelectionEditorTestingRobot();
        createTabs(cta, false, 2);
        enterTabSwitcher(cta);
        onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(2));
        enterTabGroupManualSelection(cta);
        robot.resultRobot.verifyTabSelectionEditorIsVisible();

        // Pressing system back should dismiss the selection editor.
        Espresso.pressBack();
        robot.resultRobot.verifyTabSelectionEditorIsHidden();
    }

    @Test
    @MediumTest
    @Feature("TabSuggestion")
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
            ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study"})
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0" +
            "/thumbnail_aspect_ratio/1.0"})
    public void testTabGroupManualSelection_AfterReviewTabSuggestion() throws InterruptedException {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        TabSelectionEditorTestingRobot robot = new TabSelectionEditorTestingRobot();
        createTabs(cta, false, 3);

        // Review closing tab suggestion.
        CriteriaHelper.pollUiThread(TabSuggestionMessageService::isSuggestionAvailableForTesting);
        CriteriaHelper.pollUiThread(
                () -> Criteria.checkThat(getTabCountInCurrentTabModel(), Matchers.is(3)));

        // Entering GTS with thumbnail checking here is trying to reduce flakiness that is caused by
        // the TabContextObserver. TabContextObserver listens to
        // TabObserver#didFirstVisuallyNonEmptyPaint and invalidates the suggestion. Do the
        // thumbnail checking here is to ensure the suggestion is valid when entering tab switcher.
        enterGTSWithThumbnailChecking();
        CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
        onView(withId(R.id.tab_grid_message_item)).check(matches(isDisplayed()));
        onView(allOf(withId(R.id.action_button), withParent(withId(R.id.tab_grid_message_item))))
                .perform(click());

        robot.resultRobot.verifyTabSelectionEditorIsVisible()
                .verifyToolbarActionButtonWithResourceId(
                        R.string.tab_suggestion_close_tab_action_button);

        robot.actionRobot.clickToolbarActionButton();
        robot.resultRobot.verifyTabSelectionEditorIsHidden();
        CriteriaHelper.pollUiThread(() -> {
            Criteria.checkThat(mActivityTestRule.getActivity().getCurrentTabModel().getCount(),
                    Matchers.is(0));
        });

        // Show Manual Selection Mode.
        createTabs(cta, false, 3);

        TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity());
        enterTabGroupManualSelection(cta);
        robot.resultRobot.verifyTabSelectionEditorIsVisible()
                .verifyToolbarActionButtonWithResourceId(R.string.tab_selection_editor_group);

        // Group first two tabs.
        robot.actionRobot.clickItemAtAdapterPosition(0);
        robot.actionRobot.clickItemAtAdapterPosition(1);
        robot.actionRobot.clickToolbarActionButton();

        // Exit manual selection mode, back to tab switcher.
        robot.resultRobot.verifyTabSelectionEditorIsHidden();
        onViewWaiting(withText("2 tabs grouped"));
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    @DisabledTest(message = "crbug.com/1187320 This doesn't work with FeedV2.")
    public void testActivityCanBeGarbageCollectedAfterFinished() throws Exception {
        prepareTabs(1, 0, "about:blank");

        WeakReference<ChromeTabbedActivity> activityRef =
                new WeakReference<>(mActivityTestRule.getActivity());

        ChromeTabbedActivity activity =
                ApplicationTestUtils.recreateActivity(mActivityTestRule.getActivity());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();

        mStartSurfaceLayout = null;
        mTabListDelegate = null;
        mActivityTestRule.setActivity(activity);

        // A longer timeout is needed. Achieve that by using the CriteriaHelper.pollUiThread.
        CriteriaHelper.pollUiThread(
                () -> GarbageCollectionTestUtils.canBeGarbageCollected(activityRef));
    }

    /**
     * This test is to simulate closing all incognito tabs during the activity recreation stage.
     * This is a regression test for crbug.com/1044557. The test ensures all incognito tabs closed,
     * which leads to a TabModel switching event, before the first normal tab is restored.
     */
    @Test
    @MediumTest
    @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
    // clang-format off
    @DisabledTest(message = "crbug.com/1044557 This regression test fails deterministically with" +
            " the bot, but passes with local emulator. Disable the test for now.")
    public void
    closeAllIncognitoTabsBeforeRestoreCompleted() {
        // clang-format on
        prepareTabs(3, 1, "about:blank");

        assertTrue(mActivityTestRule.getActivity().getCurrentTabModel().isIncognito());

        // Need to wait for contentsState to be initialized for the tab to restore correctly.
        CriteriaHelper.pollUiThread(
                ()
                        -> TabStateExtractor.from(mActivityTestRule.getActivity().getActivityTab())
                                   .contentsState
                        != null,
                "Incognito tab contentsState is null");

        ChromeTabUtils.newTabFromMenu(InstrumentationRegistry.getInstrumentation(),
                mActivityTestRule.getActivity(), true, false);

        mActivityTestRule.loadUrl("about:blank");

        // Need to wait for contentsState to be initialized for the tab to restore correctly.
        CriteriaHelper.pollUiThread(
                ()
                        -> TabStateExtractor.from(mActivityTestRule.getActivity().getActivityTab())
                                   .contentsState
                        != null,
                "Incognito tab contentsState is null");

        PseudoTab.clearForTesting();

        AtomicBoolean tabModelRestoreCompleted = new AtomicBoolean(false);
        AtomicBoolean normalModelIsEmpty = new AtomicBoolean(true);

        mActivityTestRule.recreateActivity();
        ChromeTabbedActivity newActivity = mActivityTestRule.getActivity();

        new TabModelSelectorTabModelObserver(newActivity.getTabModelSelector()) {
            @Override
            public void restoreCompleted() {
                tabModelRestoreCompleted.set(true);
            }

            @Override
            public void willAddTab(Tab tab, int type) {
                if (tab.isIncognito() || !normalModelIsEmpty.get()) return;

                // Ensure normal tab model is active before its first tab restores.
                CriteriaHelper.pollUiThread(
                        ()
                                -> !newActivity.getCurrentTabModel().isIncognito(),
                        "Had not switched to Normal TabModel before the first normal Tab restored");
            }

            @Override
            public void didAddTab(Tab tab, int type, int creationState) {
                if (tab.isIncognito()) return;
                normalModelIsEmpty.set(false);
            }
        };

        CriteriaHelper.pollUiThread(()
                                            -> newActivity.didFinishNativeInitialization(),
                "New Activity has not finished initialized yet");
        CriteriaHelper.pollUiThread(()
                                            -> newActivity.getCurrentTabModel().isIncognito(),
                "New Activity current TabModel is not incognito");
        TestThreadUtils.runOnUiThreadBlocking(IncognitoTabHostUtils::closeAllIncognitoTabs);

        assertTrue("Deferred startup never completed", mActivityTestRule.waitForDeferredStartup());

        CriteriaHelper.pollUiThread(()
                                            -> tabModelRestoreCompleted.get(),
                "New Activity normal TabModel has never restored");

        assertFalse(newActivity.getCurrentTabModel().isIncognito());
        assertNotNull(newActivity.getTabModelSelector().getCurrentTab());
        // With the fix, StaticLayout guarantees to be shown. Otherwise, StartSurfaceLayout could be
        // shown, not guaranteed.
        assertTrue(newActivity.getLayoutManager().getActiveLayout() instanceof StaticLayout);
    }

    @Test
    @MediumTest
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID,
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    public void testTabGroupNotFormDuringRestore() throws Exception {
        // clang-format on
        // Finish the activity and disable the ChromeFeatureList.TAB_GROUPS_ANDROID flag.
        finishActivity(mActivityTestRule.getActivity());
        CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GROUPS_ANDROID, false);

        mActivityTestRule.startMainActivityOnBlankPage();
        final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        mActivityTestRule.loadUrl(mUrl);
        Tab parentTab = cta.getTabModelSelector().getCurrentTab();

        // Create a tab whose parent tab is parentTab.
        TabCreator tabCreator =
                TestThreadUtils.runOnUiThreadBlockingNoException(() -> cta.getTabCreator(false));
        LoadUrlParams loadUrlParams = new LoadUrlParams(mUrl);
        TestThreadUtils.runOnUiThreadBlocking(
                ()
                        -> tabCreator.createNewTab(
                                loadUrlParams, TabLaunchType.FROM_LONGPRESS_BACKGROUND, parentTab));
        enterTabSwitcher(cta);
        verifyTabSwitcherCardCount(cta, 2);

        // Restart activity with tab group enabled, and the tabs should remain as single tabs.
        finishActivity(cta);
        CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GROUPS_ANDROID, true);
        mActivityTestRule.startMainActivityOnBlankPage();
        final ChromeTabbedActivity ctaRestarted = mActivityTestRule.getActivity();
        assertTrue(ctaRestarted.getTabModelSelector()
                           .getTabModelFilterProvider()
                           .getCurrentTabModelFilter()
                           instanceof TabGroupModelFilter);
        enterTabSwitcher(ctaRestarted);
        verifyTabSwitcherCardCount(ctaRestarted, 3);
    }

    @Test
    @MediumTest
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    public void verifyTabGroupStateAfterReparenting() throws Exception {
        // clang-format on
        final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        assertTrue(cta.getTabModelSelector().getTabModelFilterProvider().getCurrentTabModelFilter()
                           instanceof TabGroupModelFilter);
        mActivityTestRule.loadUrl(mUrl);
        Tab parentTab = cta.getTabModelSelector().getCurrentTab();

        // Create a tab whose parent tab is parentTab.
        TabCreator tabCreator =
                TestThreadUtils.runOnUiThreadBlockingNoException(() -> cta.getTabCreator(false));
        LoadUrlParams loadUrlParams = new LoadUrlParams(mUrl);
        TestThreadUtils.runOnUiThreadBlocking(
                ()
                        -> tabCreator.createNewTab(
                                loadUrlParams, TabLaunchType.FROM_LONGPRESS_BACKGROUND, parentTab));
        Tab childTab = cta.getTabModelSelector().getCurrentModel().getTabAt(1);
        enterTabSwitcher(cta);
        verifyTabSwitcherCardCount(cta, 1);
        TabGroupModelFilter filter = (TabGroupModelFilter) cta.getTabModelSelector()
                                             .getTabModelFilterProvider()
                                             .getCurrentTabModelFilter();
        TestThreadUtils.runOnUiThreadBlocking(() -> filter.moveTabOutOfGroup(childTab.getId()));
        verifyTabSwitcherCardCount(cta, 2);

        TestThreadUtils.runOnUiThreadBlocking(
                () -> ChromeNightModeTestUtils.setUpNightModeForChromeActivity(true));
        final ChromeTabbedActivity ctaNightMode = ActivityTestUtils.waitForActivity(
                InstrumentationRegistry.getInstrumentation(), ChromeTabbedActivity.class);
        assertTrue(ColorUtils.inNightMode(ctaNightMode));
        CriteriaHelper.pollUiThread(ctaNightMode.getTabModelSelector()::isTabStateInitialized);
        enterTabSwitcher(ctaNightMode);
        verifyTabSwitcherCardCount(ctaNightMode, 2);
    }

    @Test
    @MediumTest
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
            ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID,
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    public void testUndoClosure_AccessibilityMode() throws Exception {
        // clang-format on
        TestThreadUtils.runOnUiThreadBlocking(
                () -> ChromeAccessibilityUtil.get().setAccessibilityEnabledForTesting(true));
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        SnackbarManager snackbarManager = mActivityTestRule.getActivity().getSnackbarManager();
        createTabs(cta, false, 3);

        // When grid tab switcher is enabled for accessibility mode, tab closure should still show
        // undo snack bar.
        enterTabSwitcher(cta);
        verifyTabSwitcherCardCount(cta, 3);
        assertNull(snackbarManager.getCurrentSnackbarForTesting());
        closeFirstTabInTabSwitcher();
        assertTrue(snackbarManager.getCurrentSnackbarForTesting().getController()
                           instanceof UndoBarController);
        verifyTabSwitcherCardCount(cta, 2);
        CriteriaHelper.pollInstrumentationThread(TabUiTestHelper::verifyUndoBarShowingAndClickUndo);
        verifyTabSwitcherCardCount(cta, 3);
    }

    @Test
    @MediumTest
    // clang-format off
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID, ChromeFeatureList.INSTANT_START,
            ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
    // TODO(crbug.com/1112557): Remove this test when critical tests in StartSurfaceLayoutTest are
    // running with InstantStart on.
    public void testSetup_WithInstantStart() throws Exception {
        // clang-format on
        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        enterTabSwitcher(cta);
        verifyTabSwitcherCardCount(cta, 1);

        // Verify TabModelObserver is correctly setup by checking if tab switcher changes with tab
        // closure.
        closeFirstTabInTabSwitcher();
        verifyTabSwitcherCardCount(cta, 0);

        // Verify TabGroupModelFilter is correctly setup by checking if tab switcher changes with
        // tab grouping.
        createTabs(cta, false, 3);
        enterTabSwitcher(cta);
        verifyTabSwitcherCardCount(cta, 2);
        mergeAllNormalTabsToAGroup(cta);
        verifyTabSwitcherCardCount(cta, 1);
    }

    @Test
    @MediumTest
    @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID})
    public void testUndoGroupClosureInTabSwitcher() {
        final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
        SnackbarManager snackbarManager = mActivityTestRule.getActivity().getSnackbarManager();
        createTabs(cta, false, 2);
        enterTabSwitcher(cta);
        verifyTabSwitcherCardCount(cta, 2);
        // Create a tab group.
        mergeAllNormalTabsToAGroup(cta);
        verifyTabSwitcherCardCount(cta, 1);
        assertNull(snackbarManager.getCurrentSnackbarForTesting());

        // Verify close this tab group and undo in tab switcher.
        closeFirstTabInTabSwitcher();
        assertTrue(snackbarManager.getCurrentSnackbarForTesting().getController()
                           instanceof UndoBarController);
        verifyTabSwitcherCardCount(cta, 0);
        CriteriaHelper.pollInstrumentationThread(TabUiTestHelper::verifyUndoBarShowingAndClickUndo);
        verifyTabSwitcherCardCount(cta, 1);
    }

    private void enterTabGroupManualSelection(ChromeTabbedActivity cta) {
        MenuUtils.invokeCustomMenuActionSync(
                InstrumentationRegistry.getInstrumentation(), cta, R.id.menu_group_tabs);
    }

    /**
     * TODO(wychen): move some of the callers to {@link TabUiTestHelper#enterTabSwitcher}.
     */
    private void enterGTSWithThumbnailChecking() throws InterruptedException {
        Tab currentTab = mActivityTestRule.getActivity().getTabModelSelector().getCurrentTab();
        // Native tabs need to be invalidated first to trigger thumbnail taking, so skip them.
        boolean checkThumbnail = !currentTab.isNativePage();

        if (checkThumbnail) {
            mActivityTestRule.getActivity().getTabContentManager().removeTabThumbnail(
                    currentTab.getId());
        }

        int count = getCaptureCount();
        waitForCaptureRateControl();
        // TODO(wychen): use TabUiTestHelper.enterTabSwitcher() instead.
        //  Might increase flakiness though. See crbug.com/1024742.
        TestThreadUtils.runOnUiThreadBlocking(
                () -> mActivityTestRule.getActivity().getLayoutManager().showOverview(true));
        assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());

        // Make sure the fading animation is done.
        int delta;
        if (UrlUtilities.isNTPUrl(mActivityTestRule.getActivity()
                                          .getCurrentWebContents()
                                          .getLastCommittedUrl())) {
            // NTP is not invalidated, so no new captures.
            delta = 0;
        } else {
            // The final capture at StartSurfaceLayout#finishedShowing time.
            delta = 1;
            if (ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
                    && areAnimatorsEnabled()) {
                // The faster capturing without writing back to cache.
                delta += 1;
            }
        }
        checkCaptureCount(delta, count);
        TabUiTestHelper.verifyAllTabsHaveThumbnail(
                mActivityTestRule.getActivity().getCurrentTabModel());
    }

    /**
     * Like {@link TabUiTestHelper#enterTabSwitcher}, but make sure all tabs have thumbnail.
     */
    private void enterGTSWithThumbnailRetry() {
        enterTabSwitcher(mActivityTestRule.getActivity());
        try {
            TabUiTestHelper.verifyAllTabsHaveThumbnail(
                    mActivityTestRule.getActivity().getCurrentTabModel());
        } catch (AssertionError ae) {
            // If the last thumbnail is missing, try without animation.
            Espresso.pressBack();
            TestThreadUtils.runOnUiThreadBlocking(
                    () -> mActivityTestRule.getActivity().getLayoutManager().showOverview(false));
            TabUiTestHelper.verifyAllTabsHaveThumbnail(
                    mActivityTestRule.getActivity().getCurrentTabModel());
        }
    }

    /**
     * If thumbnail checking is not needed, use {@link TabUiTestHelper#leaveTabSwitcher} instead.
     */
    private void leaveGTSAndVerifyThumbnailsAreReleased() {
        assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());

        StartSurface startSurface = mStartSurfaceLayout.getStartSurfaceForTesting();
        TestThreadUtils.runOnUiThreadBlocking(
                () -> { startSurface.getController().onBackPressed(); });
        // TODO(wychen): using default timeout or even converting to
        //  OverviewModeBehaviorWatcher shouldn't increase flakiness.
        CriteriaHelper.pollUiThread(
                ()
                        -> !mActivityTestRule.getActivity().getLayoutManager().overviewVisible(),
                "Overview not hidden yet", DEFAULT_MAX_TIME_TO_POLL * 10, DEFAULT_POLLING_INTERVAL);
        assertThumbnailsAreReleased();
    }

    private void checkFinalCaptureCount(boolean switchToAnotherTab, int initCount) {
        int expected;
        if (UrlUtilities.isNTPUrl(mActivityTestRule.getActivity()
                                          .getCurrentWebContents()
                                          .getLastCommittedUrl())) {
            expected = 0;
        } else {
            expected = mRepeat;
            if (ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
                    && areAnimatorsEnabled()) {
                expected += mRepeat;
            }
            if (switchToAnotherTab) {
                expected += mRepeat;
            }
        }
        checkCaptureCount(expected, initCount);
    }

    private void checkCaptureCount(int expectedDelta, int initCount) {
        // TODO(wychen): With animation, the 2nd capture might be skipped if the 1st takes too long.
        CriteriaHelper.pollUiThread(() -> {
            Criteria.checkThat(getCaptureCount() - initCount, Matchers.is(expectedDelta));
        });
    }

    private int getCaptureCount() {
        // TODO(crbug/1110961): Find a replacement for depending on Compositing.CopyFromSurfaceTime.
        return RecordHistogram.getHistogramTotalCountForTesting("Compositing.CopyFromSurfaceTime");
    }

    private void waitForCaptureRateControl() throws InterruptedException {
        // Needs to wait for at least |kCaptureMinRequestTimeMs| in order to capture another one.
        // TODO(wychen): find out why waiting is still needed after setting
        //               |kCaptureMinRequestTimeMs| to 0.
        Thread.sleep(2000);
    }

    private void assertThumbnailsAreReleased() {
        // Could not directly assert canAllBeGarbageCollected() because objects can be in Cleaner.
        CriteriaHelper.pollUiThread(() -> canAllBeGarbageCollected(mAllBitmaps));
    }

    private boolean canAllBeGarbageCollected(List<WeakReference<Bitmap>> bitmaps) {
        for (WeakReference<Bitmap> bitmap : bitmaps) {
            if (!GarbageCollectionTestUtils.canBeGarbageCollected(bitmap)) {
                return false;
            }
        }
        return true;
    }

    private void simulateAspectRatioChangedToPoint75() throws IOException {
        TabModel currentModel = mActivityTestRule.getActivity().getCurrentTabModel();
        for (int i = 0; i < currentModel.getCount(); i++) {
            Tab tab = currentModel.getTabAt(i);
            Bitmap bitmap = TabContentManager.getJpegForTab(tab.getId());
            bitmap = Bitmap.createScaledBitmap(
                    bitmap, bitmap.getWidth(), (int) (bitmap.getWidth() * 1.0 / 0.75), false);
            encodeJpeg(tab, bitmap);
        }
    }

    private void encodeJpeg(Tab tab, Bitmap bitmap) throws IOException {
        FileOutputStream outputStream =
                new FileOutputStream(TabContentManager.getTabThumbnailFileJpeg(tab.getId()));
        bitmap.compress(Bitmap.CompressFormat.JPEG, 50, outputStream);
        outputStream.close();
    }

    private void verifyAllThumbnailHasAspectRatio(double ratio) {
        TabModel currentModel = mActivityTestRule.getActivity().getCurrentTabModel();
        for (int i = 0; i < currentModel.getCount(); i++) {
            Tab tab = currentModel.getTabAt(i);
            Bitmap bitmap = TabContentManager.getJpegForTab(tab.getId());
            double bitmapRatio = bitmap.getWidth() * 1.0 / bitmap.getHeight();
            assertTrue("Actual ratio: " + bitmapRatio + "; Expected ratio: " + ratio,
                    Math.abs(bitmapRatio - ratio) <= TabContentManager.ASPECT_RATIO_PRECISION);
        }
    }

    private void verifyOnlyOneTabSuggestionMessageCardIsShowing() throws InterruptedException {
        String suggestionMessageTemplate = mActivityTestRule.getActivity().getString(
                org.chromium.chrome.tab_ui.R.string.tab_suggestion_close_stale_message);
        String suggestionMessage =
                String.format(Locale.getDefault(), suggestionMessageTemplate, "3");
        prepareTabs(3, 0, mUrl);
        CriteriaHelper.pollUiThread(TabSuggestionMessageService::isSuggestionAvailableForTesting);
        CriteriaHelper.pollUiThread(
                () -> Criteria.checkThat(getTabCountInCurrentTabModel(), Matchers.is(3)));

        enterGTSWithThumbnailChecking();
        CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
        onView(allOf(withText(suggestionMessage), withParent(withId(R.id.tab_grid_message_item))))
                .check(matches(isDisplayed()));
        leaveGTSAndVerifyThumbnailsAreReleased();

        // With soft or hard clean up depends on the soft-cleanup-delay and cleanup-delay params.
        enterGTSWithThumbnailChecking();
        CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
        // This will fail with error "matched multiple views" when there is more than one suggestion
        // message card.
        onView(allOf(withText(suggestionMessage), withParent(withId(R.id.tab_grid_message_item))))
                .check(matches(isDisplayed()));
    }

    private Matcher<View> tabSwitcherViewMatcher() {
        return allOf(withParent(withId(R.id.compositor_view_holder)), withId(R.id.tab_list_view));
    }
}
