// Copyright (c) 2012 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.

#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/memory/fake_memory_pressure_monitor.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/devtools/devtools_window_testing.h"
#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
#include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
#include "chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.h"
#include "chrome/browser/resource_coordinator/tab_lifecycle_unit.h"
#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h"
#include "chrome/browser/resource_coordinator/tab_manager.h"
#include "chrome/browser/resource_coordinator/tab_manager_features.h"
#include "chrome/browser/resource_coordinator/tab_manager_web_contents_data.h"
#include "chrome/browser/resource_coordinator/time.h"
#include "chrome/browser/resource_coordinator/utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "net/dns/mock_host_resolver.h"
#include "url/gurl.h"

using content::OpenURLParams;

#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) || \
    defined(OS_CHROMEOS)

namespace resource_coordinator {

namespace {

constexpr char kBlinkPageLifecycleFeature[] = "PageLifecycle";
constexpr base::TimeDelta kShortDelay = base::TimeDelta::FromSeconds(1);

constexpr char kMainFrameFrozenStateJS[] =
    "window.domAutomationController.send(mainFrameFreezeCount);";
constexpr char kChildFrameFrozenStateJS[] =
    "window.domAutomationController.send(childFrameFreezeCount);";

bool ObserveNavEntryCommitted(const GURL& expected_url,
                              const content::NotificationSource& source,
                              const content::NotificationDetails& details) {
  return content::Details<content::LoadCommittedDetails>(details)
             ->entry->GetURL() == expected_url;
}

bool IsTabDiscarded(content::WebContents* web_contents) {
  return TabLifecycleUnitExternal::FromWebContents(web_contents)->IsDiscarded();
}

class ExpectStateTransitionObserver : public LifecycleUnitObserver {
 public:
  ExpectStateTransitionObserver(LifecycleUnit* lifecyle_unit,
                                LifecycleUnitState expected_state)
      : lifecycle_unit_(lifecyle_unit), expected_state_(expected_state) {
    lifecycle_unit_->AddObserver(this);
  }

  ~ExpectStateTransitionObserver() override {
    lifecycle_unit_->RemoveObserver(this);
  }

  void AllowState(LifecycleUnitState allowed_state) {
    allowed_states_.insert(allowed_state);
  }

  void Wait() {
    EXPECT_NE(expected_state_, lifecycle_unit_->GetState());
    run_loop_.Run();
    EXPECT_EQ(expected_state_, lifecycle_unit_->GetState());
  }

 private:
  // LifecycleUnitObserver:
  void OnLifecycleUnitStateChanged(
      LifecycleUnit* lifecycle_unit,
      LifecycleUnitState last_state,
      LifecycleUnitStateChangeReason reason) override {
    EXPECT_EQ(lifecycle_unit, lifecycle_unit_);
    if (lifecycle_unit_->GetState() == expected_state_) {
      run_loop_.Quit();
    } else {
      LOG(ERROR) << "transition to state "
                 << static_cast<int>(lifecycle_unit_->GetState());
      EXPECT_TRUE(
          base::ContainsKey(allowed_states_, lifecycle_unit_->GetState()));
    }
  }

  LifecycleUnit* const lifecycle_unit_;
  const LifecycleUnitState expected_state_;
  std::set<LifecycleUnitState> allowed_states_;
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(ExpectStateTransitionObserver);
};

}  // namespace

class TabManagerTest : public InProcessBrowserTest {
 public:
  TabManagerTest() : scoped_set_tick_clock_for_testing_(&test_clock_) {
    // Start with a non-null TimeTicks, as there is no discard protection for
    // a tab with a null focused timestamp.
    test_clock_.Advance(kShortDelay);
    scoped_feature_list_.InitAndEnableFeature(
        features::kSiteCharacteristicsDatabase);
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
                                    kBlinkPageLifecycleFeature);
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
  }

  void OpenTwoTabs(const GURL& first_url, const GURL& second_url) {
    // Open two tabs. Wait for both of them to load.
    content::WindowedNotificationObserver load1(
        content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
        content::NotificationService::AllSources());
    OpenURLParams open1(first_url, content::Referrer(),
                        WindowOpenDisposition::CURRENT_TAB,
                        ui::PAGE_TRANSITION_TYPED, false);
    content::WebContents* web_contents = browser()->OpenURL(open1);
    load1.Wait();
    if (URLShouldBeStoredInLocalDatabase(first_url))
      testing::ExpireLocalDBObservationWindows(web_contents);

    content::WindowedNotificationObserver load2(
        content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
        content::NotificationService::AllSources());
    OpenURLParams open2(second_url, content::Referrer(),
                        WindowOpenDisposition::NEW_BACKGROUND_TAB,
                        ui::PAGE_TRANSITION_TYPED, false);
    web_contents = browser()->OpenURL(open2);
    load2.Wait();
    // Expire all the observation windows to prevent the discarding and freezing
    // interventions to fail because of a lack of observations.
    if (URLShouldBeStoredInLocalDatabase(second_url))
      testing::ExpireLocalDBObservationWindows(web_contents);

    ASSERT_EQ(2, tsm()->count());
  }

  // Opens 2 tabs. Calls Freeze() on the background tab. Verifies that it
  // transitions to the PENDING_FREEZE, and that onfreeze callbacks runs on the
  // page. The background tab is PENDING_FREEZE when this returns.
  void TestTransitionFromActiveToPendingFreeze() {
    // Setup the embedded_test_server to serve a cross-site frame.
    content::SetupCrossSiteRedirector(embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());

    // Opening two tabs, where the second tab is backgrounded.
    GURL main_url(
        embedded_test_server()->GetURL("a.com", "/iframe_cross_site.html"));
    OpenTwoTabs(GURL(chrome::kChromeUIAboutURL), main_url);
    constexpr int kFreezingIndex = 1;
    LifecycleUnit* const lifecycle_unit = GetLifecycleUnitAt(kFreezingIndex);
    content::WebContents* const content = GetWebContentsAt(kFreezingIndex);

    // Grab the frames.
    content::RenderFrameHost* main_frame = content->GetMainFrame();
    ASSERT_EQ(3u, content->GetAllFrames().size());
    // The page has 2 iframes, we will use the first one.
    content::RenderFrameHost* child_frame = content->GetAllFrames()[1];
    // Verify that the main frame and subframe are cross-site.
    EXPECT_NE(main_frame->GetLastCommittedURL().GetOrigin(),
              child_frame->GetLastCommittedURL().GetOrigin());
    if (content::AreAllSitesIsolatedForTesting()) {
      EXPECT_NE(main_frame->GetSiteInstance(), child_frame->GetSiteInstance());
      EXPECT_NE(main_frame->GetProcess()->GetID(),
                child_frame->GetProcess()->GetID());
    }

    // Ensure that the tab is hidden or backgrounded.
    bool hidden_state_result;
    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
        main_frame,
        "window.domAutomationController.send("
        "window.document.hidden);",
        &hidden_state_result));
    EXPECT_TRUE(hidden_state_result);

    EXPECT_TRUE(content::ExecuteScript(
        main_frame,
        "if (window.location.pathname != '/iframe_cross_site.html')"
        "  throw 'Incorrect frame';"
        "mainFrameFreezeCount = 0;"
        "window.document.onfreeze = function(){ mainFrameFreezeCount++; };"));

    EXPECT_TRUE(content::ExecuteScript(
        child_frame,
        "if (window.location.pathname != '/title1.html') throw 'Incorrect "
        "frame';"
        "childFrameFreezeCount = 0;"
        "window.document.onfreeze = function(){ childFrameFreezeCount++; };"));

    // freeze_count_result should be 0 for both frames, if it is undefined then
    // we are in the wrong frame/tab.
    int freeze_count_result;
    EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
        main_frame, kMainFrameFrozenStateJS, &freeze_count_result));
    EXPECT_EQ(0, freeze_count_result);
    EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
        child_frame, kChildFrameFrozenStateJS, &freeze_count_result));
    EXPECT_EQ(0, freeze_count_result);

    // Freeze the tab. If it fails then we might be freezing a visible tab.
    EXPECT_EQ(LifecycleUnitState::ACTIVE, lifecycle_unit->GetState());
    EXPECT_TRUE(lifecycle_unit->Freeze());
    EXPECT_EQ(LifecycleUnitState::PENDING_FREEZE, lifecycle_unit->GetState());
  }

  // Opens 2 tabs. Calls Freeze() on the background tab. Verifies that it
  // transitions to the PENDING_FREEZE and FROZEN states, and that onfreeze
  // callbacks runs on the page. The background tabs is FROZEN when this
  // returns.
  void TestTransitionFromActiveToFrozen() {
    TestTransitionFromActiveToPendingFreeze();

    {
      ExpectStateTransitionObserver expect_state_transition(
          GetLifecycleUnitAt(1), LifecycleUnitState::FROZEN);
      expect_state_transition.Wait();
    }

    content::WebContents* const content = GetWebContentsAt(1);
    content::RenderFrameHost* main_frame = content->GetMainFrame();
    content::RenderFrameHost* child_frame = content->GetAllFrames()[1];

    // freeze_count_result should be exactly 1 for both frames. The value is
    // incremented in the onfreeze callback. If it is >1, then the callback was
    // called more than once.
    int freeze_count_result = 0;
    EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
        main_frame, kMainFrameFrozenStateJS, &freeze_count_result));
    EXPECT_EQ(1, freeze_count_result);
    EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
        child_frame, kChildFrameFrozenStateJS, &freeze_count_result));
    EXPECT_EQ(1, freeze_count_result);
  }

  // Gets the TabLifecycleUnit from |contents| and sends the signal that
  // indicates that the page is frozen. In production, this is sent by the
  // renderer process. This is done to finish a proactive tab discard.
  void SimulateFreezeSignal(content::WebContents* contents) {
    GetTabLifecycleUnitSource()
        ->GetTabLifecycleUnit(contents)
        ->UpdateLifecycleState(mojom::LifecycleState::kFrozen);
  }

  TabManager* tab_manager() { return g_browser_process->GetTabManager(); }
  TabStripModel* tsm() { return browser()->tab_strip_model(); }

  content::WebContents* GetWebContentsAt(int index) {
    return tsm()->GetWebContentsAt(index);
  }

  LifecycleUnit* GetLifecycleUnitAt(int index) {
    return GetTabLifecycleUnitSource()->GetTabLifecycleUnit(
        GetWebContentsAt(index));
  }

  base::test::FakeMemoryPressureMonitor fake_memory_pressure_monitor_;
  base::SimpleTestTickClock test_clock_;
  ScopedSetTickClockForTesting scoped_set_tick_clock_for_testing_;
  base::test::ScopedFeatureList scoped_feature_list_;
};

class TabManagerTestWithTwoTabs : public TabManagerTest {
 public:
  TabManagerTestWithTwoTabs() = default;

  void SetUpOnMainThread() override {
    TabManagerTest::SetUpOnMainThread();

    // Open 2 tabs with default URLs in a focused tab strip.
    GetTabLifecycleUnitSource()->SetFocusedTabStripModelForTesting(tsm());
    OpenTwoTabs(GURL(chrome::kChromeUIAboutURL),
                GURL(chrome::kChromeUICreditsURL));
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TabManagerTestWithTwoTabs);
};

// Flaky on Mac. http://crbug.com/857418
#if defined(OS_MACOSX)
#define MAYBE_TabManagerBasics DISABLED_TabManagerBasics
#else
#define MAYBE_TabManagerBasics TabManagerBasics
#endif
IN_PROC_BROWSER_TEST_F(TabManagerTest, MAYBE_TabManagerBasics) {
  using content::WindowedNotificationObserver;

  // Get three tabs open.

  test_clock_.Advance(kShortDelay);
  WindowedNotificationObserver load1(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
                      WindowOpenDisposition::CURRENT_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open1);
  load1.Wait();

  test_clock_.Advance(kShortDelay);
  WindowedNotificationObserver load2(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(),
                      WindowOpenDisposition::NEW_FOREGROUND_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open2);
  load2.Wait();

  test_clock_.Advance(kShortDelay);
  WindowedNotificationObserver load3(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open3(GURL(chrome::kChromeUITermsURL), content::Referrer(),
                      WindowOpenDisposition::NEW_FOREGROUND_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open3);
  load3.Wait();
  EXPECT_EQ(3, tsm()->count());

  // Navigate the current (third) tab to a different URL, so we can test
  // back/forward later.
  WindowedNotificationObserver load4(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open4(GURL(chrome::kChromeUIVersionURL), content::Referrer(),
                      WindowOpenDisposition::CURRENT_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open4);
  load4.Wait();

  // Navigate the third tab again, such that we have three navigation entries.
  WindowedNotificationObserver load5(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open5(GURL("chrome://dns"), content::Referrer(),
                      WindowOpenDisposition::CURRENT_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open5);
  load5.Wait();
  EXPECT_EQ(3, tsm()->count());

  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  // Discard a tab.
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT));
  EXPECT_EQ(3, tsm()->count());
  if (base::FeatureList::IsEnabled(features::kTabRanker)) {
    // In testing configs with TabRanker enabled, we don't always know which tab
    // it will kill. But exactly one of the first two tabs should be killed.
    EXPECT_TRUE(IsTabDiscarded(GetWebContentsAt(0)) ^
                IsTabDiscarded(GetWebContentsAt(1)));
  } else {
    // With TabRanker disabled, it should kill the first tab, since it was the
    // oldest and was not selected.
    EXPECT_TRUE(IsTabDiscarded(GetWebContentsAt(0)));
    EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(1)));
  }
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(2)));

  // Run discard again. Both unselected tabs should now be killed.
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT));
  EXPECT_EQ(3, tsm()->count());
  EXPECT_TRUE(IsTabDiscarded(GetWebContentsAt(0)));
  EXPECT_TRUE(IsTabDiscarded(GetWebContentsAt(1)));
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(2)));

  // Run discard again. It should not kill the last tab, since it is active.
  EXPECT_FALSE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT));
  EXPECT_TRUE(IsTabDiscarded(GetWebContentsAt(0)));
  EXPECT_TRUE(IsTabDiscarded(GetWebContentsAt(1)));
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(2)));

  // Kill the third tab after making second tab active.
  tsm()->ActivateTabAt(1, true);

  // Advance time so everything is urgent discardable again.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  EXPECT_EQ(1, tsm()->active_index());
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(1)));
  tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT);
  EXPECT_TRUE(IsTabDiscarded(GetWebContentsAt(2)));

  // Force creation of the FindBarController.
  browser()->GetFindBarController();

  // Select the first tab.  It should reload.
  WindowedNotificationObserver reload1(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      base::Bind(&ObserveNavEntryCommitted,
                 GURL(chrome::kChromeUIChromeURLsURL)));
  chrome::SelectNumberedTab(browser(), 0);
  reload1.Wait();
  // Make sure the FindBarController gets the right WebContents.
  EXPECT_EQ(browser()->GetFindBarController()->web_contents(),
            tsm()->GetActiveWebContents());
  EXPECT_EQ(0, tsm()->active_index());
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(0)));
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(1)));
  EXPECT_TRUE(IsTabDiscarded(GetWebContentsAt(2)));

  // Select the third tab. It should reload.
  WindowedNotificationObserver reload2(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      base::Bind(&ObserveNavEntryCommitted, GURL("chrome://dns")));
  chrome::SelectNumberedTab(browser(), 2);
  reload2.Wait();
  EXPECT_EQ(2, tsm()->active_index());
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(0)));
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(1)));
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(2)));

  // Navigate the third tab back twice.  We used to crash here due to
  // crbug.com/121373.
  EXPECT_TRUE(chrome::CanGoBack(browser()));
  EXPECT_FALSE(chrome::CanGoForward(browser()));
  WindowedNotificationObserver back1(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      base::Bind(&ObserveNavEntryCommitted, GURL(chrome::kChromeUIVersionURL)));
  chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
  back1.Wait();
  EXPECT_TRUE(chrome::CanGoBack(browser()));
  EXPECT_TRUE(chrome::CanGoForward(browser()));
  WindowedNotificationObserver back2(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      base::Bind(&ObserveNavEntryCommitted, GURL(chrome::kChromeUITermsURL)));
  chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
  back2.Wait();
  EXPECT_FALSE(chrome::CanGoBack(browser()));
  EXPECT_TRUE(chrome::CanGoForward(browser()));
}

// On Linux, memory pressure listener is not implemented yet.
#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)

// Test that the MemoryPressureListener event is properly triggering a tab
// discard upon |MEMORY_PRESSURE_LEVEL_CRITICAL| event.
IN_PROC_BROWSER_TEST_F(TabManagerTest, OomPressureListener) {
  // Get two tabs open.
  content::WindowedNotificationObserver load1(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
                      WindowOpenDisposition::CURRENT_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open1);
  load1.Wait();

  content::WindowedNotificationObserver load2(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(),
                      WindowOpenDisposition::NEW_FOREGROUND_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open2);
  load2.Wait();

  ASSERT_EQ(tsm()->count(), 2);

  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(0)));
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(1)));

  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  // Nothing should happen with a moderate memory pressure event.
  fake_memory_pressure_monitor_.SetAndNotifyMemoryPressure(
      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(0)));
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(1)));

  // A critical memory pressure event should discard a tab.
  fake_memory_pressure_monitor_.SetAndNotifyMemoryPressure(
      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
  // Coming here, an asynchronous operation will collect system stats. Once in,
  // a tab should get discarded. As such we need to give it 10s time to discard.
  const int kTimeoutTimeInMS = 10000;
  const int kIntervalTimeInMS = 5;
  int timeout = kTimeoutTimeInMS / kIntervalTimeInMS;
  while (--timeout) {
    base::PlatformThread::Sleep(
        base::TimeDelta::FromMilliseconds(kIntervalTimeInMS));
    base::RunLoop().RunUntilIdle();
    if (IsTabDiscarded(GetWebContentsAt(0)))
      break;
  }
  EXPECT_TRUE(IsTabDiscarded(GetWebContentsAt(0)));
  EXPECT_FALSE(IsTabDiscarded(GetWebContentsAt(1)));
}

#endif

IN_PROC_BROWSER_TEST_F(TabManagerTest, InvalidOrEmptyURL) {
  // Open two tabs. Wait for the foreground one to load but do not wait for the
  // background one.
  content::WindowedNotificationObserver load1(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
                      WindowOpenDisposition::CURRENT_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open1);
  load1.Wait();

  content::WindowedNotificationObserver load2(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(),
                      WindowOpenDisposition::NEW_BACKGROUND_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open2);

  ASSERT_EQ(2, tsm()->count());

  // This shouldn't be able to discard a tab as the background tab has not yet
  // started loading (its URL is not committed).
  EXPECT_FALSE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));

  // Wait for the background tab to load which then allows it to be discarded.
  load2.Wait();
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));
}

// Makes sure that PDF pages are protected.
IN_PROC_BROWSER_TEST_F(TabManagerTest, ProtectPDFPages) {
  // Start the embedded test server so we can get served the required PDF page.
  ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
  embedded_test_server()->StartAcceptingConnections();

  // Get two tabs open, the first one being a PDF page and the second one being
  // the foreground tab.
  GURL url1 = embedded_test_server()->GetURL("/pdf/test.pdf");
  ui_test_utils::NavigateToURL(browser(), url1);

  GURL url2(chrome::kChromeUIAboutURL);
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url2, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  // No discarding should be possible as the only background tab is displaying a
  // PDF page, hence protected.
  EXPECT_FALSE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));
}

#if !defined(OS_CHROMEOS)
// Makes sure that recently opened or used tabs are protected.
IN_PROC_BROWSER_TEST_F(TabManagerTest,
                       ProtectRecentlyUsedTabsFromUrgentDiscarding) {
  TabManager* tab_manager = g_browser_process->GetTabManager();

  auto* tsm = browser()->tab_strip_model();

  // Open 2 tabs, the second one being in the background.
  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIAboutURL));
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), GURL(chrome::kChromeUIAboutURL),
      WindowOpenDisposition::NEW_BACKGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
  EXPECT_EQ(2, tsm->count());

  // Advance the clock for less than the protection time.
  test_clock_.Advance(kBackgroundUrgentProtectionTime / 2);

  // Should not be able to discard a tab.
  ASSERT_FALSE(tab_manager->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT));

  // Advance the clock for more than the protection time.
  test_clock_.Advance(kBackgroundUrgentProtectionTime / 2 +
                      base::TimeDelta::FromSeconds(1));

  // Should be able to discard the background tab now.
  EXPECT_TRUE(tab_manager->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT));

  // Activate the 2nd tab.
  tsm->ActivateTabAt(1, true);
  EXPECT_EQ(1, tsm->active_index());

  // Advance the clock for less than the protection time.
  test_clock_.Advance(kBackgroundUrgentProtectionTime / 2);

  // Should not be able to urgent discard the tab.
  ASSERT_FALSE(tab_manager->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT));

  // But should be able to proactive discard the tab.
  EXPECT_TRUE(
      tab_manager->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));

  // This is necessary otherwise the test crashes in
  // WebContentsData::WebContentsDestroyed.
  tsm->CloseAllTabs();
}
#endif  // !defined(OS_CHROMEOS)

// Makes sure that tabs using media devices are protected.
IN_PROC_BROWSER_TEST_F(TabManagerTest, ProtectVideoTabs) {
  // Open 2 tabs, the second one being in the background.
  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIAboutURL));
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), GURL(chrome::kChromeUIAboutURL),
      WindowOpenDisposition::NEW_BACKGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  auto* tab = GetWebContentsAt(1);

  // Simulate that a video stream is now being captured.
  blink::MediaStreamDevices video_devices(1);
  video_devices[0] =
      blink::MediaStreamDevice(blink::MEDIA_DEVICE_VIDEO_CAPTURE,
                               "fake_media_device", "fake_media_device");
  MediaCaptureDevicesDispatcher* dispatcher =
      MediaCaptureDevicesDispatcher::GetInstance();
  dispatcher->SetTestVideoCaptureDevices(video_devices);
  std::unique_ptr<content::MediaStreamUI> video_stream_ui =
      dispatcher->GetMediaStreamCaptureIndicator()->RegisterMediaStream(
          tab, video_devices);
  video_stream_ui->OnStarted(base::OnceClosure(), base::RepeatingClosure());

  // Should not be able to discard a tab.
  ASSERT_FALSE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));

  // Remove the video stream.
  video_stream_ui.reset();

  // Should be able to discard the background tab now.
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));
}

// Makes sure that tabs using DevTools are protected from discarding.
IN_PROC_BROWSER_TEST_F(TabManagerTest, ProtectDevToolsTabsFromDiscarding) {
  // Get two tabs open, the second one being the foreground tab.
  GURL test_page(ui_test_utils::GetTestUrl(
      base::FilePath(), base::FilePath(FILE_PATH_LITERAL("simple.html"))));
  ui_test_utils::NavigateToURL(browser(), test_page);
  // Open a DevTools window for the first.
  DevToolsWindow* devtool = DevToolsWindowTesting::OpenDevToolsWindowSync(
      GetWebContentsAt(0), true /* is_docked */);
  EXPECT_TRUE(devtool);

  GURL url2(chrome::kChromeUIAboutURL);
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), GURL(chrome::kChromeUIAboutURL),
      WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  // No discarding should be possible as the only background tab is currently
  // using DevTools.
  EXPECT_FALSE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));

  // Close the DevTools window and repeat the test, this time use a non-docked
  // window.
  DevToolsWindowTesting::CloseDevToolsWindowSync(devtool);
  devtool = DevToolsWindowTesting::OpenDevToolsWindowSync(
      GetWebContentsAt(0), false /* is_docked */);
  EXPECT_TRUE(devtool);
  EXPECT_FALSE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));

  // TODO(sebmarchand): Also ensure that the tab can't be frozen.

  // Close the DevTools window, ensure that the tab can be discarded.
  DevToolsWindowTesting::CloseDevToolsWindowSync(devtool);
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));
}

IN_PROC_BROWSER_TEST_F(TabManagerTest, CanPurgeBackgroundedRenderer) {
  // Open 2 tabs, the second one being in the background.
  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIAboutURL));
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), GURL(chrome::kChromeUIAboutURL),
      WindowOpenDisposition::NEW_BACKGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  auto* tab = GetWebContentsAt(1);
  // Simulate that a video stream is now being captured.
  blink::MediaStreamDevices video_devices(1);
  video_devices[0] =
      blink::MediaStreamDevice(blink::MEDIA_DEVICE_VIDEO_CAPTURE,
                               "fake_media_device", "fake_media_device");
  MediaCaptureDevicesDispatcher* dispatcher =
      MediaCaptureDevicesDispatcher::GetInstance();
  dispatcher->SetTestVideoCaptureDevices(video_devices);
  std::unique_ptr<content::MediaStreamUI> video_stream_ui =
      dispatcher->GetMediaStreamCaptureIndicator()->RegisterMediaStream(
          tab, video_devices);
  video_stream_ui->OnStarted(base::OnceClosure(), base::RepeatingClosure());

  // Should not be able to suspend a tab which plays a video.
  int render_process_id = tab->GetMainFrame()->GetProcess()->GetID();
  ASSERT_FALSE(tab_manager()->CanPurgeBackgroundedRenderer(render_process_id));

  // Remove the video stream.
  video_stream_ui.reset();

  // Should be able to suspend the background tab now.
  EXPECT_TRUE(tab_manager()->CanPurgeBackgroundedRenderer(render_process_id));
}

IN_PROC_BROWSER_TEST_F(TabManagerTest, AutoDiscardable) {
  using content::WindowedNotificationObserver;

  // Get two tabs open.
  WindowedNotificationObserver load1(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
                      WindowOpenDisposition::CURRENT_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open1);
  load1.Wait();

  WindowedNotificationObserver load2(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(),
                      WindowOpenDisposition::NEW_FOREGROUND_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open2);
  load2.Wait();
  ASSERT_EQ(2, tsm()->count());

  // Set the auto-discardable state of the first tab to false.
  TabLifecycleUnitExternal::FromWebContents(GetWebContentsAt(0))
      ->SetAutoDiscardable(false);

  // Shouldn't discard the tab, since auto-discardable is deactivated.
  EXPECT_FALSE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));

  // Reset auto-discardable state to true.
  TabLifecycleUnitExternal::FromWebContents(GetWebContentsAt(0))
      ->SetAutoDiscardable(true);

  // Now it should be able to discard the tab.
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));
  EXPECT_TRUE(IsTabDiscarded(GetWebContentsAt(0)));
}

IN_PROC_BROWSER_TEST_F(TabManagerTest, PurgeBackgroundRenderer) {
  // Get three tabs open.
  content::WindowedNotificationObserver load1(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
                      WindowOpenDisposition::CURRENT_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open1);
  load1.Wait();

  content::WindowedNotificationObserver load2(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(),
                      WindowOpenDisposition::NEW_FOREGROUND_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open2);
  load2.Wait();

  content::WindowedNotificationObserver load3(
      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
      content::NotificationService::AllSources());
  OpenURLParams open3(GURL(chrome::kChromeUITermsURL), content::Referrer(),
                      WindowOpenDisposition::NEW_FOREGROUND_TAB,
                      ui::PAGE_TRANSITION_TYPED, false);
  browser()->OpenURL(open3);
  load3.Wait();

  TabManager::WebContentsData* tab1_contents_data =
      tab_manager()->GetWebContentsData(GetWebContentsAt(0));
  TabManager::WebContentsData* tab2_contents_data =
      tab_manager()->GetWebContentsData(GetWebContentsAt(1));
  TabManager::WebContentsData* tab3_contents_data =
      tab_manager()->GetWebContentsData(GetWebContentsAt(2));

  // The time-to-purge initialized at ActiveTabChanged should be in the
  // right default range.
  EXPECT_GE(tab1_contents_data->time_to_purge(),
            base::TimeDelta::FromMinutes(1));
  EXPECT_LE(tab1_contents_data->time_to_purge(),
            base::TimeDelta::FromMinutes(4));
  EXPECT_GE(tab2_contents_data->time_to_purge(),
            base::TimeDelta::FromMinutes(1));
  EXPECT_LE(tab2_contents_data->time_to_purge(),
            base::TimeDelta::FromMinutes(4));

  EXPECT_GE(tab3_contents_data->time_to_purge(),
            base::TimeDelta::FromMinutes(30));
  EXPECT_LE(tab3_contents_data->time_to_purge(),
            base::TimeDelta::FromMinutes(60));

  // To make it easy to test, configure time-to-purge here.
  base::TimeDelta time_to_purge1 = base::TimeDelta::FromMinutes(30);
  base::TimeDelta time_to_purge2 = base::TimeDelta::FromMinutes(40);
  tab1_contents_data->set_time_to_purge(time_to_purge1);
  tab2_contents_data->set_time_to_purge(time_to_purge2);
  tab3_contents_data->set_time_to_purge(time_to_purge1);

  // No tabs are not purged yet.
  ASSERT_FALSE(tab1_contents_data->is_purged());
  ASSERT_FALSE(tab2_contents_data->is_purged());
  ASSERT_FALSE(tab3_contents_data->is_purged());

  // Advance the clock for time_to_purge1.
  test_clock_.Advance(time_to_purge1);
  tab_manager()->PurgeBackgroundedTabsIfNeeded();

  ASSERT_FALSE(tab1_contents_data->is_purged());
  ASSERT_FALSE(tab2_contents_data->is_purged());
  ASSERT_FALSE(tab3_contents_data->is_purged());

  // Advance the clock for 1 minutes.
  test_clock_.Advance(base::TimeDelta::FromMinutes(1));
  tab_manager()->PurgeBackgroundedTabsIfNeeded();

  // Since tab1 is kept inactive and background for more than
  // time_to_purge1, tab1 should be purged.
  ASSERT_TRUE(tab1_contents_data->is_purged());
  ASSERT_FALSE(tab2_contents_data->is_purged());
  ASSERT_FALSE(tab3_contents_data->is_purged());

  // Advance the clock.
  test_clock_.Advance(time_to_purge2 - time_to_purge1);
  tab_manager()->PurgeBackgroundedTabsIfNeeded();

  // Since tab2 is kept inactive and background for more than
  // time_to_purge2, tab1 should be purged.
  // Since tab3 is active, tab3 should not be purged.
  ASSERT_TRUE(tab1_contents_data->is_purged());
  ASSERT_TRUE(tab2_contents_data->is_purged());
  ASSERT_FALSE(tab3_contents_data->is_purged());

  tsm()->CloseAllTabs();
}

IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs,
                       ProactiveFastShutdownSingleTabProcess) {
  // The Tab Manager should be able to fast-kill a process for the discarded tab
  // on all platforms, as each tab will be running in a separate process by
  // itself regardless of the discard reason.
  content::WindowedNotificationObserver observer(
      content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
      content::NotificationService::AllSources());
  base::HistogramTester tester;
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));
  SimulateFreezeSignal(GetWebContentsAt(1));

  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldFastShutdown", true, 1);
  observer.Wait();
}

IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs,
                       UrgentFastShutdownSingleTabProcess) {
  // The Tab Manager should be able to fast-kill a process for the discarded tab
  // on all platforms, as each tab will be running in a separate process by
  // itself regardless of the discard reason.
  content::WindowedNotificationObserver observer(
      content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
      content::NotificationService::AllSources());
  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);
  base::HistogramTester tester;
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT));
  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldFastShutdown", true, 1);
  observer.Wait();
}

IN_PROC_BROWSER_TEST_F(TabManagerTest, ProactiveFastShutdownSharedTabProcess) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // Set max renderers to 1 before opening tabs to force running out of
  // processes and for both these tabs to share a renderer.
  content::RenderProcessHost::SetMaxRendererProcessCount(1);
  OpenTwoTabs(embedded_test_server()->GetURL("a.com", "/title1.html"),
              embedded_test_server()->GetURL("a.com", "/title2.html"));
  EXPECT_EQ(tsm()->GetWebContentsAt(0)->GetMainFrame()->GetProcess(),
            tsm()->GetWebContentsAt(1)->GetMainFrame()->GetProcess());

  // The Tab Manager will not be able to fast-kill either of the tabs since they
  // share the same process regardless of the discard reason. No unsafe attempts
  // will be made.
  base::HistogramTester tester;
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));
  SimulateFreezeSignal(GetWebContentsAt(1));

  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldFastShutdown", false, 1);
}

IN_PROC_BROWSER_TEST_F(TabManagerTest, UrgentFastShutdownSharedTabProcess) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // Set max renderers to 1 before opening tabs to force running out of
  // processes and for both these tabs to share a renderer.
  content::RenderProcessHost::SetMaxRendererProcessCount(1);
  OpenTwoTabs(embedded_test_server()->GetURL("a.com", "/title1.html"),
              embedded_test_server()->GetURL("a.com", "/title2.html"));
  EXPECT_EQ(tsm()->GetWebContentsAt(0)->GetMainFrame()->GetProcess(),
            tsm()->GetWebContentsAt(1)->GetMainFrame()->GetProcess());

  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  // The Tab Manager will not be able to fast-kill either of the tabs since they
  // share the same process regardless of the discard reason. An unsafe attempt
  // will be made on some platforms.
  base::HistogramTester tester;
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT));
#ifdef OS_CHROMEOS
  // The unsafe killing attempt will fail for the same reason.
  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldUnsafeFastShutdown", false, 1);
#endif  // OS_CHROMEOS
  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldFastShutdown", false, 1);
}

IN_PROC_BROWSER_TEST_F(TabManagerTest,
                       DISABLED_ProactiveFastShutdownWithUnloadHandler) {
  ASSERT_TRUE(embedded_test_server()->Start());
  // Disable the protection of recent tabs.
  OpenTwoTabs(GURL(chrome::kChromeUIAboutURL),
              GURL(embedded_test_server()->GetURL("/unload.html")));

  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  base::HistogramTester tester;
  // The Tab Manager will not be able to safely fast-kill either of the tabs as
  // one of them is current, and the other has an unload handler. No unsafe
  // attempts will be made.
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));
  SimulateFreezeSignal(GetWebContentsAt(1));

  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldFastShutdown", false, 1);
}

IN_PROC_BROWSER_TEST_F(TabManagerTest, UrgentFastShutdownWithUnloadHandler) {
  ASSERT_TRUE(embedded_test_server()->Start());
  // Disable the protection of recent tabs.
  OpenTwoTabs(GURL(chrome::kChromeUIAboutURL),
              GURL(embedded_test_server()->GetURL("/unload.html")));

  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  // The Tab Manager will not be able to safely fast-kill either of the tabs as
  // one of them is current, and the other has an unload handler. An unsafe
  // attempt will be made on some platforms.
  base::HistogramTester tester;
#ifdef OS_CHROMEOS
  // The unsafe attempt for ChromeOS should succeed as ChromeOS ignores unload
  // handlers when in critical condition.
  content::WindowedNotificationObserver observer(
      content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
      content::NotificationService::AllSources());
#endif  // OS_CHROMEOS
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT));
#ifdef OS_CHROMEOS
  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldUnsafeFastShutdown", true, 1);
  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldFastShutdown", true, 1);
  observer.Wait();
#else
  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldFastShutdown", false, 1);
#endif  // OS_CHROMEOS
}

// https://crbug.com/874915, flaky on all platform
IN_PROC_BROWSER_TEST_F(TabManagerTest,
                       DISABLED_ProactiveFastShutdownWithBeforeunloadHandler) {
  ASSERT_TRUE(embedded_test_server()->Start());
  // Disable the protection of recent tabs.
  OpenTwoTabs(GURL(chrome::kChromeUIAboutURL),
              GURL(embedded_test_server()->GetURL("/beforeunload.html")));

  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  // The Tab Manager will not be able to safely fast-kill either of the tabs as
  // one of them is current, and the other has a beforeunload handler. No unsafe
  // attempts will be made.
  base::HistogramTester tester;
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::PROACTIVE));
  SimulateFreezeSignal(GetWebContentsAt(1));

  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldFastShutdown", false, 1);
}

IN_PROC_BROWSER_TEST_F(TabManagerTest,
                       UrgentFastShutdownWithBeforeunloadHandler) {
  ASSERT_TRUE(embedded_test_server()->Start());
  // Disable the protection of recent tabs.
  OpenTwoTabs(GURL(chrome::kChromeUIAboutURL),
              GURL(embedded_test_server()->GetURL("/beforeunload.html")));

  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  // The Tab Manager will not be able to safely fast-kill either of the tabs as
  // one of them is current, and the other has a beforeunload handler. An unsafe
  // attempt will be made on some platforms.
  base::HistogramTester tester;
  EXPECT_TRUE(
      tab_manager()->DiscardTabImpl(LifecycleUnitDiscardReason::URGENT));
#ifdef OS_CHROMEOS
  // The unsafe killing attempt will fail as ChromeOS does not ignore
  // beforeunload handlers.
  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldUnsafeFastShutdown", false, 1);
#endif  // OS_CHROMEOS
  tester.ExpectUniqueSample(
      "TabManager.Discarding.DiscardedTabCouldFastShutdown", false, 1);
}

// Verifies the following state transitions for a tab:
// - Initial state: ACTIVE
// - Freeze(): ACTIVE->PENDING_FREEZE
// - Freeze happens in renderer: PENDING_FREEZE->FROZEN
// - Tab is made visible: FROZEN->ACTIVE
IN_PROC_BROWSER_TEST_F(TabManagerTest, TabFreezeAndMakeVisible) {
  TestTransitionFromActiveToFrozen();

  // Make the tab visible. It should transition to the ACTIVE state.
  GetWebContentsAt(1)->WasShown();
  {
    ExpectStateTransitionObserver expect_state_transition(
        GetLifecycleUnitAt(1), LifecycleUnitState::ACTIVE);
    expect_state_transition.Wait();
  }
}

// Verifies the following state transitions for a tab:
// - Initial state: ACTIVE
// - Freeze(): ACTIVE->PENDING_FREEZE
// - Freeze happens in renderer: PENDING_FREEZE->FROZEN
// - Unfreeze(): FROZEN->ACTIVE
IN_PROC_BROWSER_TEST_F(TabManagerTest, TabFreezeAndUnfreeze) {
  TestTransitionFromActiveToFrozen();

  // Unfreeze the tab. It should immediately transition to the PENDING_FREEZE
  // state. Then, it shuold transition to the ACTIVE state once the "onresume"
  // callback has run.
  EXPECT_TRUE(GetLifecycleUnitAt(1)->Unfreeze());
  EXPECT_EQ(LifecycleUnitState::PENDING_UNFREEZE,
            GetLifecycleUnitAt(1)->GetState());
  {
    ExpectStateTransitionObserver expect_state_transition(
        GetLifecycleUnitAt(1), LifecycleUnitState::ACTIVE);
    expect_state_transition.Wait();
  }
}

// Verifies the following state transitions for a tab:
// - Initial state: ACTIVE
// - Freeze(): ACTIVE->PENDING_FREEZE
// - Unfreeze(): PENDING_FREEZE->FROZEN
IN_PROC_BROWSER_TEST_F(TabManagerTest, TabPendingFreezeAndUnfreeze) {
  TestTransitionFromActiveToPendingFreeze();

  EXPECT_EQ(LifecycleUnitState::PENDING_FREEZE,
            GetLifecycleUnitAt(1)->GetState());

  {
    ExpectStateTransitionObserver expect_state_transition(
        GetLifecycleUnitAt(1), LifecycleUnitState::FROZEN);
    expect_state_transition.Wait();
  }
}

// Verifies the following state transitions for a tab:
// - Initial state: ACTIVE
// - Freeze(): ACTIVE->PENDING_FREEZE
// - Discard(kProactive): PENDING_FREEZE->PENDING_DISCARD
// - Freeze happens in renderer: PENDING_DISCARD->DISCARDED
IN_PROC_BROWSER_TEST_F(TabManagerTest,
                       TabFreezeAndProactiveDiscardBeforeFreezeCompletes) {
  TestTransitionFromActiveToPendingFreeze();

  // Proactively discard the background tab.
  EXPECT_TRUE(
      GetLifecycleUnitAt(1)->Discard(LifecycleUnitDiscardReason::PROACTIVE));
  EXPECT_EQ(LifecycleUnitState::PENDING_DISCARD,
            GetLifecycleUnitAt(1)->GetState());

  // The tab should transition to DISCARDED after the renderer freezes the page.
  ExpectStateTransitionObserver expect_state_transition(
      GetLifecycleUnitAt(1), LifecycleUnitState::DISCARDED);
  expect_state_transition.Wait();
}

// Verifies the following state transitions for a tab:
// - Initial state: ACTIVE
// - Freeze(): ACTIVE->PENDING_FREEZE
// - Discard(kUrgent): PENDING_FREEZE->DISCARDED
IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs,
                       TabFreezeAndUrgentDiscardBeforeFreezeCompletes) {
  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  // Freeze the background tab.
  EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(1)->GetState());
  EXPECT_TRUE(GetLifecycleUnitAt(1)->Freeze());
  EXPECT_EQ(LifecycleUnitState::PENDING_FREEZE,
            GetLifecycleUnitAt(1)->GetState());

  // Urgently discard the background tab.
  EXPECT_TRUE(
      GetLifecycleUnitAt(1)->Discard(LifecycleUnitDiscardReason::URGENT));
  EXPECT_EQ(LifecycleUnitState::DISCARDED, GetLifecycleUnitAt(1)->GetState());
}

// Verifies the following state transitions for a tab:
// - Initial state: ACTIVE
// - Freeze(): ACTIVE->PENDING_FREEZE
// - Freeze happens in renderer: PENDING_FREEZE->FROZEN
// - Discard(kUrgent): FROZEN->DISCARDED
IN_PROC_BROWSER_TEST_F(TabManagerTest, TabFreezeAndUrgentDiscard) {
  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  TestTransitionFromActiveToFrozen();

  // Urgently discard the background tab.
  EXPECT_TRUE(
      GetLifecycleUnitAt(1)->Discard(LifecycleUnitDiscardReason::URGENT));
  EXPECT_EQ(LifecycleUnitState::DISCARDED, GetLifecycleUnitAt(1)->GetState());
}

// Verifies the following state transitions for a tab:
// - Initial state: ACTIVE
// - Discard(kProactive): ACTIVE->PENDING_DISCARD
// - Focus: PENDING_DISCARD->PENDING_FREEZE
// - (optional) Freeze happens in renderer: PENDING_FREEZE->FROZEN
// - Renderer is notified of new visibility: PENDING_FREEZE->ACTIVE or
//   FROZEN->ACTIVE.
IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs,
                       TabProactiveDiscardAndFocusBeforeFreezeCompletes) {
  // Proactively discard the background tab.
  EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(1)->GetState());
  EXPECT_TRUE(
      GetLifecycleUnitAt(1)->Discard(LifecycleUnitDiscardReason::PROACTIVE));
  EXPECT_EQ(LifecycleUnitState::PENDING_DISCARD,
            GetLifecycleUnitAt(1)->GetState());

  // Focus and make visible the background tab. It should transition to
  // PENDING_FREEZE, to indicate that there is a freeze on its way to the
  // renderer but that no discard should happen if the renderer freezes the page
  // before being notified that it became visible.
  tsm()->ActivateTabAt(1, true);
  GetWebContentsAt(1)->WasShown();
  EXPECT_EQ(LifecycleUnitState::PENDING_FREEZE,
            GetLifecycleUnitAt(1)->GetState());

  // The tab should eventually transition to ACTIVE. If the renderer freezes the
  // page before being notified that the tab became visible, there could be an
  // intermediate transition to FROZEN.
  ExpectStateTransitionObserver expect_state_transition(
      GetLifecycleUnitAt(1), LifecycleUnitState::ACTIVE);
  expect_state_transition.AllowState(LifecycleUnitState::FROZEN);
  expect_state_transition.Wait();
}

// Verifies the following state transitions for a tab:
// - Initial state: ACTIVE
// - Discard(kProactive): ACTIVE->PENDING_DISCARD
// - Freeze happens in renderer: PENDING_DISCARD->DISCARDED
// - Focus: DISCARDED->ACTIVE
IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs,
                       TabProactiveDiscardAndFocusToReload) {
  // Proactively discard the background tab.
  EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(1)->GetState());
  EXPECT_TRUE(
      GetLifecycleUnitAt(1)->Discard(LifecycleUnitDiscardReason::PROACTIVE));
  EXPECT_EQ(LifecycleUnitState::PENDING_DISCARD,
            GetLifecycleUnitAt(1)->GetState());

  // After the freeze happens in the renderer, the tab is discarded.
  {
    ExpectStateTransitionObserver expect_state_transition(
        GetLifecycleUnitAt(1), LifecycleUnitState::DISCARDED);
    expect_state_transition.Wait();
  }

  // When the tab is focused and made visible, it transitions to ACTIVE.
  tsm()->ActivateTabAt(1, true);
  GetWebContentsAt(1)->WasShown();
  EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(1)->GetState());
}

// Verifies the following state transitions for a tab:
// - Initial state: ACTIVE
// - Discard(kProactive): ACTIVE->PENDING_DISCARD
// - Freeze(): Disallowed
// - Freeze happens in renderer: PENDING_DISCARD->DISCARDED
IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs,
                       TabFreezeDisallowedWhenProactivelyDiscarding) {
  // Proactively discard the background tab.
  EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(1)->GetState());
  EXPECT_TRUE(
      GetLifecycleUnitAt(1)->Discard(LifecycleUnitDiscardReason::PROACTIVE));
  EXPECT_EQ(LifecycleUnitState::PENDING_DISCARD,
            GetLifecycleUnitAt(1)->GetState());

  // Freezing the tab should be disallowed.
  DecisionDetails decision_details;
  EXPECT_FALSE(GetLifecycleUnitAt(1)->CanFreeze(&decision_details));
  EXPECT_FALSE(GetLifecycleUnitAt(1)->Freeze());
  EXPECT_EQ(LifecycleUnitState::PENDING_DISCARD,
            GetLifecycleUnitAt(1)->GetState());

  // The tab should eventually transition to DISCARDED.
  ExpectStateTransitionObserver expect_state_transition(
      GetLifecycleUnitAt(1), LifecycleUnitState::DISCARDED);
  expect_state_transition.Wait();
}

// Verifies the following state transitions for a tab:
// - Initial state: ACTIVE
// - Discard(kUrgent): ACTIVE->DISCARDED
// - Navigate: DISCARDED->ACTIVE
//             window.document.wasDiscarded is true
IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs, TabUrgentDiscardAndNavigate) {
  const char kDiscardedStateJS[] =
      "window.domAutomationController.send("
      "window.document.wasDiscarded);";

  GURL test_page(ui_test_utils::GetTestUrl(
      base::FilePath(), base::FilePath(FILE_PATH_LITERAL("simple.html"))));
  ui_test_utils::NavigateToURL(browser(), test_page);

  // document.wasDiscarded is false initially.
  bool not_discarded_result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      GetWebContentsAt(0), kDiscardedStateJS, &not_discarded_result));
  EXPECT_FALSE(not_discarded_result);

  // Discard the tab.
  EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(0)->GetState());
  EXPECT_TRUE(
      GetLifecycleUnitAt(0)->Discard(LifecycleUnitDiscardReason::EXTERNAL));
  EXPECT_EQ(LifecycleUnitState::DISCARDED, GetLifecycleUnitAt(0)->GetState());

  // Here we simulate re-focussing the tab causing reload with navigation,
  // the navigation will reload the tab.
  // TODO(fdoray): Figure out why the test fails if a reload is done instead of
  // a navigation.
  ui_test_utils::NavigateToURL(browser(), test_page);
  EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(0)->GetState());

  // document.wasDiscarded is true on navigate after discard.
  bool discarded_result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      GetWebContentsAt(0), kDiscardedStateJS, &discarded_result));
  EXPECT_TRUE(discarded_result);
}

IN_PROC_BROWSER_TEST_F(TabManagerTest, DiscardedTabHasNoProcess) {
  GURL test_page(ui_test_utils::GetTestUrl(
      base::FilePath(), base::FilePath(FILE_PATH_LITERAL("simple.html"))));
  ui_test_utils::NavigateToURL(browser(), test_page);
  content::WebContents* web_contents = tsm()->GetActiveWebContents();

  // The renderer process should be alive at this point.
  content::RenderProcessHost* process =
      web_contents->GetMainFrame()->GetProcess();
  ASSERT_TRUE(process);
  EXPECT_TRUE(process->IsInitializedAndNotDead());
  EXPECT_NE(base::kNullProcessHandle, process->GetProcess().Handle());
  int renderer_id = process->GetID();

  // Discard the tab. This simulates a tab discard.
  TabLifecycleUnitExternal::FromWebContents(web_contents)->DiscardTab();
  content::WebContents* new_web_contents = tsm()->GetActiveWebContents();
  EXPECT_NE(new_web_contents, web_contents);
  web_contents = new_web_contents;
  content::RenderProcessHost* new_process =
      web_contents->GetMainFrame()->GetProcess();
  EXPECT_NE(new_process, process);
  EXPECT_NE(new_process->GetID(), renderer_id);
  process = new_process;

  // The renderer process should be dead after a discard.
  EXPECT_EQ(process, web_contents->GetMainFrame()->GetProcess());
  EXPECT_FALSE(process->IsInitializedAndNotDead());
  EXPECT_EQ(base::kNullProcessHandle, process->GetProcess().Handle());

  // Here we simulate re-focussing the tab causing reload with navigation,
  // the navigation will reload the tab.
  ui_test_utils::NavigateToURL(browser(), test_page);

  // Reload should mean that the renderer process is alive now.
  EXPECT_EQ(process, web_contents->GetMainFrame()->GetProcess());
  EXPECT_TRUE(process->IsInitializedAndNotDead());
  EXPECT_NE(base::kNullProcessHandle, process->GetProcess().Handle());
}

IN_PROC_BROWSER_TEST_F(TabManagerTest,
                       TabManagerWasDiscardedCrossSiteSubFrame) {
  const char kDiscardedStateJS[] =
      "window.domAutomationController.send("
      "window.document.wasDiscarded);";
  // Navigate to a page with a cross-site frame.
  content::SetupCrossSiteRedirector(embedded_test_server());
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/iframe_cross_site.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Grab the original frames.
  content::WebContents* contents = tsm()->GetActiveWebContents();
  content::RenderFrameHost* main_frame = contents->GetMainFrame();
  ASSERT_EQ(3u, contents->GetAllFrames().size());
  content::RenderFrameHost* child_frame = contents->GetAllFrames()[1];

  // Sanity check that in this test page the main frame and the
  // subframe are cross-site.
  EXPECT_NE(main_frame->GetLastCommittedURL().GetOrigin(),
            child_frame->GetLastCommittedURL().GetOrigin());
  if (content::AreAllSitesIsolatedForTesting()) {
    EXPECT_NE(main_frame->GetSiteInstance(), child_frame->GetSiteInstance());
    EXPECT_NE(main_frame->GetProcess()->GetID(),
              child_frame->GetProcess()->GetID());
  }

  // document.wasDiscarded is false before discard, on main frame and child
  // frame.
  bool before_discard_mainframe_result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      main_frame, kDiscardedStateJS, &before_discard_mainframe_result));
  EXPECT_FALSE(before_discard_mainframe_result);

  bool before_discard_childframe_result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      child_frame, kDiscardedStateJS, &before_discard_childframe_result));
  EXPECT_FALSE(before_discard_childframe_result);

  // Discard the tab. This simulates a tab discard.
  TabLifecycleUnitExternal::FromWebContents(contents)->DiscardTab();

  // Here we simulate re-focussing the tab causing reload with navigation,
  // the navigation will reload the tab.
  // TODO(panicker): Consider adding a test hook on LifecycleUnit when ready.
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Re-assign pointers after discarding, as they've changed.
  contents = tsm()->GetActiveWebContents();
  main_frame = contents->GetMainFrame();
  ASSERT_LE(2u, contents->GetAllFrames().size());
  child_frame = contents->GetAllFrames()[1];

  // document.wasDiscarded is true after discard, on mainframe and childframe.
  bool discarded_mainframe_result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      main_frame, kDiscardedStateJS, &discarded_mainframe_result));
  EXPECT_TRUE(discarded_mainframe_result);

  bool discarded_childframe_result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      child_frame, kDiscardedStateJS, &discarded_childframe_result));
  EXPECT_TRUE(discarded_childframe_result);

  // Navigate the child frame, wasDiscarded is not set anymore.
  GURL childframe_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(contents, "frame1", childframe_url));
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      contents->GetAllFrames()[1], kDiscardedStateJS,
      &discarded_childframe_result));
  EXPECT_FALSE(discarded_childframe_result);

  // Navigate second child frame cross site.
  GURL second_childframe_url(
      embedded_test_server()->GetURL("d.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(contents, "frame2", second_childframe_url));
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      contents->GetAllFrames()[2], kDiscardedStateJS,
      &discarded_childframe_result));
  EXPECT_FALSE(discarded_childframe_result);

  // Navigate the main frame (same site) again, wasDiscarded is not set anymore.
  ui_test_utils::NavigateToURL(browser(), main_url);
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      main_frame, kDiscardedStateJS, &discarded_mainframe_result));
  EXPECT_FALSE(discarded_mainframe_result);

  // Go back in history and ensure wasDiscarded is still false.
  content::TestNavigationObserver observer(contents);
  contents->GetController().GoBack();
  observer.Wait();
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      main_frame, kDiscardedStateJS, &discarded_mainframe_result));
  EXPECT_FALSE(discarded_mainframe_result);
}

namespace {

// Ensures that |browser| has |num_tabs| open tabs.
void EnsureTabsInBrowser(Browser* browser, int num_tabs) {
  for (int i = 0; i < num_tabs; ++i) {
    ui_test_utils::NavigateToURLWithDisposition(
        browser, GURL(chrome::kChromeUICreditsURL),
        i == 0 ? WindowOpenDisposition::CURRENT_TAB
               : WindowOpenDisposition::NEW_BACKGROUND_TAB,
        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
  }

  EXPECT_EQ(num_tabs, browser->tab_strip_model()->count());
}

// Creates a browser with |num_tabs| tabs.
Browser* CreateBrowserWithTabs(int num_tabs) {
  Browser* current_browser = BrowserList::GetInstance()->GetLastActive();
  ui_test_utils::BrowserAddedObserver browser_added_observer;
  chrome::NewWindow(current_browser);
  Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
  EXPECT_EQ(new_browser, BrowserList::GetInstance()->GetLastActive());
  EnsureTabsInBrowser(new_browser, num_tabs);
  return new_browser;
}

}  // namespace

// Flaky on Linux.  Times out on Windows debug builds. http://crbug.com/772839.
#if defined(OS_LINUX) || (defined(OS_WIN) && !defined(NDEBUG))
#define MAYBE_DiscardTabsWithMinimizedAndOccludedWindows \
  DISABLED_DiscardTabsWithMinimizedAndOccludedWindows
#else
#define MAYBE_DiscardTabsWithMinimizedAndOccludedWindows \
  DiscardTabsWithMinimizedAndOccludedWindows
#endif
IN_PROC_BROWSER_TEST_F(TabManagerTest,
                       MAYBE_DiscardTabsWithMinimizedAndOccludedWindows) {
  // Covered by |browser2|.
  Browser* browser1 = browser();
  EnsureTabsInBrowser(browser1, 2);
  browser1->window()->SetBounds(gfx::Rect(10, 10, 10, 10));
  // Covers |browser1|.
  Browser* browser2 = CreateBrowserWithTabs(2);
  EXPECT_NE(browser1, browser2);
  browser2->window()->SetBounds(gfx::Rect(0, 0, 100, 100));
  // Active browser.
  Browser* browser3 = CreateBrowserWithTabs(2);
  EXPECT_NE(browser1, browser3);
  EXPECT_NE(browser2, browser3);
  browser3->window()->SetBounds(gfx::Rect(110, 0, 100, 100));
  // Minimized browser.
  Browser* browser4 = CreateBrowserWithTabs(2);
  browser4->window()->Minimize();
  EXPECT_NE(browser1, browser4);
  EXPECT_NE(browser2, browser4);
  EXPECT_NE(browser3, browser4);

  // Advance time so everything is urgent discardable.
  test_clock_.Advance(kBackgroundUrgentProtectionTime);

  for (int i = 0; i < 8; ++i)
    tab_manager()->DiscardTab(LifecycleUnitDiscardReason::PROACTIVE);

  base::RunLoop().RunUntilIdle();

// On ChromeOS, active tabs are discarded if their window is non-visible. On
// other platforms, they are never discarded.
#if defined(OS_CHROMEOS)
  EXPECT_TRUE(IsTabDiscarded(browser1->tab_strip_model()->GetWebContentsAt(0)));
  EXPECT_FALSE(
      IsTabDiscarded(browser2->tab_strip_model()->GetWebContentsAt(0)));
  EXPECT_FALSE(
      IsTabDiscarded(browser3->tab_strip_model()->GetWebContentsAt(0)));
  EXPECT_TRUE(IsTabDiscarded(browser4->tab_strip_model()->GetWebContentsAt(0)));
#else
  EXPECT_FALSE(
      IsTabDiscarded(browser1->tab_strip_model()->GetWebContentsAt(0)));
  EXPECT_FALSE(
      IsTabDiscarded(browser2->tab_strip_model()->GetWebContentsAt(0)));
  EXPECT_FALSE(
      IsTabDiscarded(browser3->tab_strip_model()->GetWebContentsAt(0)));
  EXPECT_FALSE(
      IsTabDiscarded(browser4->tab_strip_model()->GetWebContentsAt(0)));
#endif

  // Non-active tabs can be discarded on all platforms.
  EXPECT_TRUE(IsTabDiscarded(browser1->tab_strip_model()->GetWebContentsAt(1)));
  EXPECT_TRUE(IsTabDiscarded(browser2->tab_strip_model()->GetWebContentsAt(1)));
  EXPECT_TRUE(IsTabDiscarded(browser3->tab_strip_model()->GetWebContentsAt(1)));
  EXPECT_TRUE(IsTabDiscarded(browser4->tab_strip_model()->GetWebContentsAt(1)));
}

IN_PROC_BROWSER_TEST_F(TabManagerTest, UnfreezeTabOnNavigationEvent) {
  TestTransitionFromActiveToPendingFreeze();

  browser()->tab_strip_model()->GetWebContentsAt(1)->GetController().Reload(
      content::ReloadType::NORMAL, false);

  ExpectStateTransitionObserver expect_state_transition(
      GetLifecycleUnitAt(1), LifecycleUnitState::ACTIVE);
  expect_state_transition.AllowState(LifecycleUnitState::PENDING_UNFREEZE);
  expect_state_transition.AllowState(LifecycleUnitState::FROZEN);
  expect_state_transition.Wait();
}

}  // namespace resource_coordinator

#endif  // OS_WIN || OS_MAXOSX || OS_LINUX || defined(OS_CHROMEOS)
