// 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 "chrome/browser/memory/tab_manager.h"

#include <algorithm>
#include <map>
#include <vector>

#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string16.h"
#include "base/test/mock_entropy_provider.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/memory/tab_manager_web_contents_data.h"
#include "chrome/browser/memory/tab_stats.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/variations/variations_associated_data.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using content::WebContents;
using content::WebContentsTester;

namespace memory {
namespace {

class TabStripDummyDelegate : public TestTabStripModelDelegate {
 public:
  TabStripDummyDelegate() {}

  bool RunUnloadListenerBeforeClosing(WebContents* contents) override {
    return false;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TabStripDummyDelegate);
};

class MockTabStripModelObserver : public TabStripModelObserver {
 public:
  MockTabStripModelObserver()
      : nb_events_(0), old_contents_(nullptr), new_contents_(nullptr) {}

  int NbEvents() const { return nb_events_; }
  WebContents* OldContents() const { return old_contents_; }
  WebContents* NewContents() const { return new_contents_; }

  void Reset() {
    nb_events_ = 0;
    old_contents_ = nullptr;
    new_contents_ = nullptr;
  }

  // TabStripModelObserver implementation:
  void TabReplacedAt(TabStripModel* tab_strip_model,
                     WebContents* old_contents,
                     WebContents* new_contents,
                     int index) override {
    nb_events_++;
    old_contents_ = old_contents;
    new_contents_ = new_contents;
  }

 private:
  int nb_events_;
  WebContents* old_contents_;
  WebContents* new_contents_;

  DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver);
};

// A mock task runner. This isn't directly a TaskRunner as the reference
// counting confuses gmock.
class LenientMockTaskRunner {
 public:
  LenientMockTaskRunner() {}
  MOCK_METHOD3(PostDelayedTask,
               bool(const tracked_objects::Location&,
                    const base::Closure&,
                    base::TimeDelta));
 private:
  DISALLOW_COPY_AND_ASSIGN(LenientMockTaskRunner);
};
using MockTaskRunner = testing::StrictMock<LenientMockTaskRunner>;

// Represents a pending task.
using Task = std::pair<base::TimeTicks, base::Closure>;

// Comparator used for sorting Task objects. Can't use std::pair's default
// comparison operators because Closure's are comparable.
struct TaskComparator {
  bool operator()(const Task& t1, const Task& t2) const {
    // Reverse the sort order so this can be used with a min-heap.
    return t1.first > t2.first;
  }
};

// A TaskRunner implementation that delegates to a MockTaskRunner for asserting
// on task insertion order, and which stores tasks for actual later execution.
class TaskRunnerProxy : public base::TaskRunner {
 public:
  TaskRunnerProxy(MockTaskRunner* mock,
                  base::SimpleTestTickClock* clock)
      : mock_(mock), clock_(clock) {}
  bool RunsTasksOnCurrentThread() const override { return true; }
  bool PostDelayedTask(const tracked_objects::Location& location,
                       const base::Closure& closure,
                       base::TimeDelta delta) override {
    mock_->PostDelayedTask(location, closure, delta);
    base::TimeTicks when = clock_->NowTicks() + delta;
    tasks_.push_back(Task(when, closure));
    // Use 'greater' comparator to make this a min heap.
    std::push_heap(tasks_.begin(), tasks_.end(), TaskComparator());
    return true;
  }

  // Runs tasks up to the current time. Returns the number of tasks executed.
  size_t RunTasks() {
    base::TimeTicks now = clock_->NowTicks();
    size_t count = 0;
    while (!tasks_.empty() && tasks_.front().first <= now) {
      tasks_.front().second.Run();
      std::pop_heap(tasks_.begin(), tasks_.end(), TaskComparator());
      tasks_.pop_back();
      ++count;
    }
    return count;
  }

  // Advances the clock and runs the next task in the queue. Can run more than
  // one task if multiple tasks have the same scheduled time.
  size_t RunNextTask() {
    // Get the time of the next task that can possibly run.
    base::TimeTicks when = tasks_.front().first;

    // Advance the clock to exactly that time.
    base::TimeTicks now = clock_->NowTicks();
    if (now < when) {
      base::TimeDelta delta = when - now;
      clock_->Advance(delta);
    }

    // Run whatever tasks are now eligible to run.
    return RunTasks();
  }

  size_t size() const { return tasks_.size(); }

 private:
  ~TaskRunnerProxy() override {}

  MockTaskRunner* mock_;
  base::SimpleTestTickClock* clock_;

  // A min-heap of outstanding tasks.
  using Task = std::pair<base::TimeTicks, base::Closure>;
  std::vector<Task> tasks_;

  DISALLOW_COPY_AND_ASSIGN(TaskRunnerProxy);
};

enum TestIndicies {
  kSelected,
  kAutoDiscardable,
  kPinned,
  kApp,
  kPlayingAudio,
  kFormEntry,
  kRecent,
  kOld,
  kReallyOld,
  kOldButPinned,
  kInternalPage,
};
}  // namespace

class LenientTabManagerTest : public ChromeRenderViewHostTestHarness {
 public:
  WebContents* CreateWebContents() {
    return WebContents::Create(WebContents::CreateParams(profile()));
  }

  MOCK_METHOD2(NotifyRendererProcess,
               void(const content::RenderProcessHost*,
                    base::MemoryPressureListener::MemoryPressureLevel));
};
using TabManagerTest = testing::StrictMock<LenientTabManagerTest>;

// TODO(georgesak): Add tests for protection to tabs with form input and
// playing audio;

// Tests the sorting comparator to make sure it's producing the desired order.
TEST_F(TabManagerTest, Comparator) {
  TabStatsList test_list;
  const base::TimeTicks now = base::TimeTicks::Now();

  // Add kSelected last to verify that the array is being sorted.

  {
    TabStats stats;
    stats.last_active = now;
    stats.is_pinned = true;
    stats.child_process_host_id = kPinned;
    test_list.push_back(stats);
  }

  {
    TabStats stats;
    stats.last_active = now;
    stats.is_app = true;
    stats.child_process_host_id = kApp;
    test_list.push_back(stats);
  }

  {
    TabStats stats;
    stats.last_active = now;
    stats.is_media = true;
    stats.child_process_host_id = kPlayingAudio;
    test_list.push_back(stats);
  }

  {
    TabStats stats;
    stats.last_active = now;
    stats.has_form_entry = true;
    stats.child_process_host_id = kFormEntry;
    test_list.push_back(stats);
  }

  {
    TabStats stats;
    stats.last_active = now - base::TimeDelta::FromSeconds(10);
    stats.child_process_host_id = kRecent;
    test_list.push_back(stats);
  }

  {
    TabStats stats;
    stats.last_active = now - base::TimeDelta::FromMinutes(15);
    stats.child_process_host_id = kOld;
    test_list.push_back(stats);
  }

  {
    TabStats stats;
    stats.last_active = now - base::TimeDelta::FromDays(365);
    stats.child_process_host_id = kReallyOld;
    test_list.push_back(stats);
  }

  {
    TabStats stats;
    stats.is_pinned = true;
    stats.last_active = now - base::TimeDelta::FromDays(365);
    stats.child_process_host_id = kOldButPinned;
    test_list.push_back(stats);
  }

  {
    TabStats stats;
    stats.last_active = now;
    stats.is_internal_page = true;
    stats.child_process_host_id = kInternalPage;
    test_list.push_back(stats);
  }

  {
    TabStats stats;
    stats.last_active = now;
    stats.is_auto_discardable = false;
    stats.child_process_host_id = kAutoDiscardable;
    test_list.push_back(stats);
  }

  // This entry sorts to the front, so by adding it last, it verifies that the
  // array is being sorted.
  {
    TabStats stats;
    stats.last_active = now;
    stats.is_selected = true;
    stats.child_process_host_id = kSelected;
    test_list.push_back(stats);
  }

  std::sort(test_list.begin(), test_list.end(), TabManager::CompareTabStats);

  int index = 0;
  EXPECT_EQ(kSelected, test_list[index++].child_process_host_id);
  EXPECT_EQ(kAutoDiscardable, test_list[index++].child_process_host_id);
  EXPECT_EQ(kFormEntry, test_list[index++].child_process_host_id);
  EXPECT_EQ(kPlayingAudio, test_list[index++].child_process_host_id);
  EXPECT_EQ(kPinned, test_list[index++].child_process_host_id);
  EXPECT_EQ(kOldButPinned, test_list[index++].child_process_host_id);
  EXPECT_EQ(kApp, test_list[index++].child_process_host_id);
  EXPECT_EQ(kRecent, test_list[index++].child_process_host_id);
  EXPECT_EQ(kOld, test_list[index++].child_process_host_id);
  EXPECT_EQ(kReallyOld, test_list[index++].child_process_host_id);
  EXPECT_EQ(kInternalPage, test_list[index++].child_process_host_id);
}

TEST_F(TabManagerTest, IsInternalPage) {
  EXPECT_TRUE(TabManager::IsInternalPage(GURL(chrome::kChromeUIDownloadsURL)));
  EXPECT_TRUE(TabManager::IsInternalPage(GURL(chrome::kChromeUIHistoryURL)));
  EXPECT_TRUE(TabManager::IsInternalPage(GURL(chrome::kChromeUINewTabURL)));
  EXPECT_TRUE(TabManager::IsInternalPage(GURL(chrome::kChromeUISettingsURL)));

// Debugging URLs are not included.
#if defined(OS_CHROMEOS)
  EXPECT_FALSE(TabManager::IsInternalPage(GURL(chrome::kChromeUIDiscardsURL)));
#endif
  EXPECT_FALSE(
      TabManager::IsInternalPage(GURL(chrome::kChromeUINetInternalsURL)));

  // Prefix matches are included.
  EXPECT_TRUE(
      TabManager::IsInternalPage(GURL("chrome://settings/fakeSetting")));
}

// Ensures discarding tabs leaves TabStripModel in a good state.
TEST_F(TabManagerTest, DiscardWebContentsAt) {
  TabManager tab_manager;

  TabStripDummyDelegate delegate;
  TabStripModel tabstrip(&delegate, profile());
  tabstrip.AddObserver(&tab_manager);

  // Fill it with some tabs.
  WebContents* contents1 = CreateWebContents();
  tabstrip.AppendWebContents(contents1, true);
  WebContents* contents2 = CreateWebContents();
  tabstrip.AppendWebContents(contents2, true);

  // Start watching for events after the appends to avoid observing state
  // transitions that aren't relevant to this test.
  MockTabStripModelObserver tabstrip_observer;
  tabstrip.AddObserver(&tabstrip_observer);

  // Discard one of the tabs.
  WebContents* null_contents1 = tab_manager.DiscardWebContentsAt(0, &tabstrip);
  ASSERT_EQ(2, tabstrip.count());
  EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
  ASSERT_EQ(null_contents1, tabstrip.GetWebContentsAt(0));
  ASSERT_EQ(contents2, tabstrip.GetWebContentsAt(1));
  ASSERT_EQ(1, tabstrip_observer.NbEvents());
  EXPECT_EQ(contents1, tabstrip_observer.OldContents());
  EXPECT_EQ(null_contents1, tabstrip_observer.NewContents());
  tabstrip_observer.Reset();

  // Discard the same tab again, after resetting its discard state.
  tab_manager.GetWebContentsData(tabstrip.GetWebContentsAt(0))
      ->SetDiscardState(false);
  WebContents* null_contents2 = tab_manager.DiscardWebContentsAt(0, &tabstrip);
  ASSERT_EQ(2, tabstrip.count());
  EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
  ASSERT_EQ(null_contents2, tabstrip.GetWebContentsAt(0));
  ASSERT_EQ(contents2, tabstrip.GetWebContentsAt(1));
  ASSERT_EQ(1, tabstrip_observer.NbEvents());
  EXPECT_EQ(null_contents1, tabstrip_observer.OldContents());
  EXPECT_EQ(null_contents2, tabstrip_observer.NewContents());

  // Activating the tab should clear its discard state.
  tabstrip.ActivateTabAt(0, true /* user_gesture */);
  ASSERT_EQ(2, tabstrip.count());
  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));

  // Don't discard active tab.
  tab_manager.DiscardWebContentsAt(0, &tabstrip);
  ASSERT_EQ(2, tabstrip.count());
  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));

  tabstrip.CloseAllTabs();
  EXPECT_TRUE(tabstrip.empty());
}

// Makes sure that reloading a discarded tab without activating it unmarks the
// tab as discarded so it won't reload on activation.
TEST_F(TabManagerTest, ReloadDiscardedTabContextMenu) {
  // Note that we do not add |tab_manager| as an observer to |tabstrip| here as
  // the event we are trying to test for is not related to the tab strip, but
  // the web content instead and therefore should be handled by WebContentsData
  // (which observes the web content).
  TabManager tab_manager;
  TabStripDummyDelegate delegate;
  TabStripModel tabstrip(&delegate, profile());

  // Create 2 tabs because the active tab cannot be discarded.
  tabstrip.AppendWebContents(CreateWebContents(), true);
  content::WebContents* test_contents =
      WebContentsTester::CreateTestWebContents(browser_context(), nullptr);
  tabstrip.AppendWebContents(test_contents, false);  // Opened in background.

  // Navigate to a web page. This is necessary to set a current entry in memory
  // so the reload can happen.
  WebContentsTester::For(test_contents)
      ->NavigateAndCommit(GURL("chrome://newtab"));
  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));

  tab_manager.DiscardWebContentsAt(1, &tabstrip);
  EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));

  tabstrip.GetWebContentsAt(1)->GetController().Reload(false);
  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
  tabstrip.CloseAllTabs();
  EXPECT_TRUE(tabstrip.empty());
}

// Makes sure that the last active time property is saved even though the tab is
// discarded.
TEST_F(TabManagerTest, DiscardedTabKeepsLastActiveTime) {
  TabManager tab_manager;
  TabStripDummyDelegate delegate;
  TabStripModel tabstrip(&delegate, profile());
  tabstrip.AddObserver(&tab_manager);

  tabstrip.AppendWebContents(CreateWebContents(), true);
  WebContents* test_contents = CreateWebContents();
  tabstrip.AppendWebContents(test_contents, false);

  // Simulate an old inactive tab about to get discarded.
  base::TimeTicks new_last_active_time =
      base::TimeTicks::Now() - base::TimeDelta::FromMinutes(35);
  test_contents->SetLastActiveTime(new_last_active_time);
  EXPECT_EQ(new_last_active_time, test_contents->GetLastActiveTime());

  WebContents* null_contents = tab_manager.DiscardWebContentsAt(1, &tabstrip);
  EXPECT_EQ(new_last_active_time, null_contents->GetLastActiveTime());

  tabstrip.CloseAllTabs();
  EXPECT_TRUE(tabstrip.empty());
}

// Test to see if a tab can only be discarded once. On Windows and Mac, this
// defaults to true unless overridden through a variation parameter. On other
// platforms, it's always false.
#if defined(OS_WIN) || defined(OS_MACOSX)
TEST_F(TabManagerTest, CanOnlyDiscardOnce) {
  TabManager tab_manager;
  const std::string kTrialName = features::kAutomaticTabDiscarding.name;

  // Not setting the variation parameter.
  {
    bool discard_once_value = tab_manager.CanOnlyDiscardOnce();
    EXPECT_TRUE(discard_once_value);
  }

  // Setting the variation parameter to true.
  {
    std::unique_ptr<base::FieldTrialList> field_trial_list_;
    field_trial_list_.reset(
        new base::FieldTrialList(
            base::MakeUnique<base::MockEntropyProvider>()));
    variations::testing::ClearAllVariationParams();

    std::map<std::string, std::string> params;
    params["AllowMultipleDiscards"] = "true";
    ASSERT_TRUE(variations::AssociateVariationParams(kTrialName, "A", params));
    base::FieldTrialList::CreateFieldTrial(kTrialName, "A");

    bool discard_once_value = tab_manager.CanOnlyDiscardOnce();
    EXPECT_FALSE(discard_once_value);
  }

  // Setting the variation parameter to something else.
  {
    std::unique_ptr<base::FieldTrialList> field_trial_list_;
    field_trial_list_.reset(
        new base::FieldTrialList(
            base::MakeUnique<base::MockEntropyProvider>()));
    variations::testing::ClearAllVariationParams();

    std::map<std::string, std::string> params;
    params["AllowMultipleDiscards"] = "somethingElse";
    ASSERT_TRUE(variations::AssociateVariationParams(kTrialName, "B", params));
    base::FieldTrialList::CreateFieldTrial(kTrialName, "B");

    bool discard_once_value = tab_manager.CanOnlyDiscardOnce();
    EXPECT_TRUE(discard_once_value);
  }
}
#else
TEST_F(TabManagerTest, CanOnlyDiscardOnce) {
  TabManager tab_manager;

  bool discard_once_value = tab_manager.CanOnlyDiscardOnce();
  EXPECT_FALSE(discard_once_value);
}
#endif  // defined(OS_WIN) || defined(OS_MACOSX)

namespace {

using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel;

// Function that always indicates the absence of memory pressure.
MemoryPressureLevel ReturnNoPressure() {
  return base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
}

// Function that simply parrots back an externally specified memory pressure
// level.
MemoryPressureLevel ReturnSpecifiedPressure(
    const MemoryPressureLevel* level) {
  return *level;
}

}  // namespace

// ChildProcessNotification is disabled on Chrome OS. crbug.com/588172.
#if defined(OS_CHROMEOS)
#define MAYBE_ChildProcessNotifications DISABLED_ChildProcessNotifications
#else
#define MAYBE_ChildProcessNotifications ChildProcessNotifications
#endif

// Ensure that memory pressure notifications are forwarded to child processes.
TEST_F(TabManagerTest, MAYBE_ChildProcessNotifications) {
  TabManager tm;

  // Set up the tab strip.
  TabStripDummyDelegate delegate;
  TabStripModel tabstrip(&delegate, profile());

  // Create test clock, task runner.
  base::SimpleTestTickClock test_clock;
  MockTaskRunner mock_task_runner;
  scoped_refptr<TaskRunnerProxy> task_runner(
      new TaskRunnerProxy(&mock_task_runner, &test_clock));

  // Configure the TabManager for testing.
  tabstrip.AddObserver(&tm);
  tm.test_tab_strip_models_.push_back(
      TabManager::TestTabStripModel(&tabstrip, false /* !is_app */));
  tm.test_tick_clock_ = &test_clock;
  tm.task_runner_ = task_runner;
  tm.notify_renderer_process_ = base::Bind(
      &TabManagerTest::NotifyRendererProcess, base::Unretained(this));

  // Create two dummy tabs.
  auto* tab0 = CreateWebContents();
  auto* tab1 = CreateWebContents();
  auto* tab2 = CreateWebContents();
  tabstrip.AppendWebContents(tab0, true);   // Foreground tab.
  tabstrip.AppendWebContents(tab1, false);  // Background tab.
  tabstrip.AppendWebContents(tab2, false);  // Background tab.
  const content::RenderProcessHost* renderer1 = tab1->GetRenderProcessHost();
  const content::RenderProcessHost* renderer2 = tab2->GetRenderProcessHost();

  // Make sure that tab2 has a lower priority than tab1 by its access time.
  test_clock.Advance(base::TimeDelta::FromMilliseconds(1));
  tab2->SetLastActiveTime(test_clock.NowTicks());
  test_clock.Advance(base::TimeDelta::FromMilliseconds(1));
  tab1->SetLastActiveTime(test_clock.NowTicks());

  // Expect that the tab manager has not yet encountered memory pressure.
  EXPECT_FALSE(tm.under_memory_pressure_);
  EXPECT_EQ(0u, tm.notified_renderers_.size());

  // Simulate a memory pressure situation that will immediately end. This should
  // cause no notifications or scheduled tasks.
  auto level = base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
  tm.get_current_pressure_level_ = base::Bind(&ReturnNoPressure);
  tm.OnMemoryPressure(level);
  testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
  EXPECT_FALSE(tm.under_memory_pressure_);
  EXPECT_EQ(0u, task_runner->size());
  EXPECT_EQ(0u, tm.notified_renderers_.size());

  // START OF MEMORY PRESSURE

  // Simulate a memory pressure situation that persists. This should cause a
  // task to be scheduled, and a background renderer to be notified.
  tm.get_current_pressure_level_ = base::Bind(
      &ReturnSpecifiedPressure, base::Unretained(&level));
  EXPECT_CALL(mock_task_runner, PostDelayedTask(
      testing::_,
      testing::_,
      base::TimeDelta::FromSeconds(tm.kRendererNotificationDelayInSeconds)));
  EXPECT_CALL(*this, NotifyRendererProcess(renderer2, level));
  tm.OnMemoryPressure(level);
  testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
  testing::Mock::VerifyAndClearExpectations(this);
  EXPECT_TRUE(tm.under_memory_pressure_);
  EXPECT_EQ(1u, task_runner->size());
  EXPECT_EQ(1u, tm.notified_renderers_.size());
  EXPECT_EQ(1u, tm.notified_renderers_.count(renderer2));

  // REPEATED MEMORY PRESSURE SIGNAL

  // Simulate another memory pressure event. This should not cause any
  // additional tasks to be scheduled, nor any further renderer notifications.
  tm.OnMemoryPressure(level);
  testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
  testing::Mock::VerifyAndClearExpectations(this);
  EXPECT_TRUE(tm.under_memory_pressure_);
  EXPECT_EQ(1u, task_runner->size());
  EXPECT_EQ(1u, tm.notified_renderers_.size());

  // FIRST SCHEDULED NOTIFICATION

  // Run the scheduled task. This should cause another notification, but this
  // time to the foreground tab. It should also cause another scheduled event.
  EXPECT_CALL(mock_task_runner, PostDelayedTask(
      testing::_,
      testing::_,
      base::TimeDelta::FromSeconds(tm.kRendererNotificationDelayInSeconds)));
  EXPECT_CALL(*this, NotifyRendererProcess(renderer1, level));
  EXPECT_EQ(1u, task_runner->RunNextTask());
  testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
  testing::Mock::VerifyAndClearExpectations(this);
  EXPECT_TRUE(tm.under_memory_pressure_);
  EXPECT_EQ(1u, task_runner->size());
  EXPECT_EQ(2u, tm.notified_renderers_.size());
  EXPECT_EQ(1u, tm.notified_renderers_.count(renderer1));

  // SECOND SCHEDULED NOTIFICATION

  // Run the scheduled task. This should cause another notification, to the
  // background tab. It should also cause another scheduled event.
  EXPECT_CALL(mock_task_runner, PostDelayedTask(
      testing::_,
      testing::_,
      base::TimeDelta::FromSeconds(tm.kRendererNotificationDelayInSeconds)));
  EXPECT_CALL(*this, NotifyRendererProcess(renderer2, level));
  EXPECT_EQ(1u, task_runner->RunNextTask());
  testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
  testing::Mock::VerifyAndClearExpectations(this);
  EXPECT_TRUE(tm.under_memory_pressure_);
  EXPECT_EQ(1u, task_runner->size());
  EXPECT_EQ(1u, tm.notified_renderers_.size());

  // Expect that the background tab has been notified. The list of notified
  // renderers maintained by the TabManager should also have been reset because
  // the notification logic restarts after all renderers are notified.
  EXPECT_EQ(1u, tm.notified_renderers_.count(renderer2));

  // END OF MEMORY PRESSURE

  // End the memory pressure condition and run the scheduled event. This should
  // clean up the various state data. It should not schedule another event nor
  // fire any notifications.
  level = base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
  EXPECT_EQ(1u, task_runner->RunNextTask());
  testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
  testing::Mock::VerifyAndClearExpectations(this);
  EXPECT_FALSE(tm.under_memory_pressure_);
  EXPECT_EQ(0u, task_runner->size());
  EXPECT_EQ(0u, tm.notified_renderers_.size());


  // Clean up the tabstrip.
  tabstrip.CloseAllTabs();
  ASSERT_TRUE(tabstrip.empty());
}

TEST_F(TabManagerTest, NextPurgeAndSuspendState) {
  TabManager tab_manager;
  TabStripDummyDelegate delegate;
  TabStripModel tabstrip(&delegate, profile());
  tabstrip.AddObserver(&tab_manager);

  WebContents* test_contents = CreateWebContents();
  tabstrip.AppendWebContents(test_contents, false);

  base::TimeDelta threshold = base::TimeDelta::FromSeconds(180);
  base::SimpleTestTickClock test_clock;

  tab_manager.GetWebContentsData(test_contents)
      ->SetPurgeAndSuspendState(TabManager::RUNNING);
  tab_manager.GetWebContentsData(test_contents)
      ->SetLastPurgeAndSuspendModifiedTimeForTesting(test_clock.NowTicks());

  test_clock.Advance(base::TimeDelta::FromSeconds(180));
  EXPECT_EQ(TabManager::RUNNING,
            tab_manager.GetNextPurgeAndSuspendState(
                test_contents, test_clock.NowTicks(), threshold));

  test_clock.Advance(base::TimeDelta::FromSeconds(1));
  EXPECT_EQ(TabManager::SUSPENDED,
            tab_manager.GetNextPurgeAndSuspendState(
                test_contents, test_clock.NowTicks(), threshold));

  tab_manager.GetWebContentsData(test_contents)
      ->SetPurgeAndSuspendState(TabManager::SUSPENDED);
  tab_manager.GetWebContentsData(test_contents)
      ->SetLastPurgeAndSuspendModifiedTimeForTesting(test_clock.NowTicks());

  test_clock.Advance(base::TimeDelta::FromSeconds(120));
  EXPECT_EQ(TabManager::SUSPENDED,
            tab_manager.GetNextPurgeAndSuspendState(
                test_contents, test_clock.NowTicks(), threshold));

  test_clock.Advance(base::TimeDelta::FromSeconds(1));
  EXPECT_EQ(TabManager::RESUMED,
            tab_manager.GetNextPurgeAndSuspendState(
                test_contents, test_clock.NowTicks(), threshold));

  tab_manager.GetWebContentsData(test_contents)
      ->SetPurgeAndSuspendState(TabManager::RESUMED);
  tab_manager.GetWebContentsData(test_contents)
      ->SetLastPurgeAndSuspendModifiedTimeForTesting(test_clock.NowTicks());

  test_clock.Advance(base::TimeDelta::FromSeconds(10));
  EXPECT_EQ(TabManager::RESUMED,
            tab_manager.GetNextPurgeAndSuspendState(
                test_contents, test_clock.NowTicks(), threshold));

  test_clock.Advance(base::TimeDelta::FromSeconds(1));
  EXPECT_EQ(TabManager::SUSPENDED,
            tab_manager.GetNextPurgeAndSuspendState(
                test_contents, test_clock.NowTicks(), threshold));

  // Clean up the tabstrip.
  tabstrip.CloseAllTabs();
  EXPECT_TRUE(tabstrip.empty());
}

TEST_F(TabManagerTest, ActivateTabResetPurgeAndSuspendState) {
  TabManager tab_manager;
  TabStripDummyDelegate delegate;
  TabStripModel tabstrip(&delegate, profile());
  tabstrip.AddObserver(&tab_manager);

  WebContents* tab1 = CreateWebContents();
  WebContents* tab2 = CreateWebContents();
  tabstrip.AppendWebContents(tab1, true);
  tabstrip.AppendWebContents(tab2, false);

  base::SimpleTestTickClock test_clock;

  // Initially PurgeAndSuspend state should be RUNNING.
  EXPECT_EQ(TabManager::RUNNING,
            tab_manager.GetWebContentsData(tab2)->GetPurgeAndSuspendState());

  tab_manager.GetWebContentsData(tab2)->SetPurgeAndSuspendState(
      TabManager::SUSPENDED);
  tab_manager.GetWebContentsData(tab2)
      ->SetLastPurgeAndSuspendModifiedTimeForTesting(test_clock.NowTicks());

  // Activate tab2. Tab2's PurgeAndSuspend state should be RUNNING.
  tabstrip.ActivateTabAt(1, true /* user_gesture */);
  EXPECT_EQ(TabManager::RUNNING,
            tab_manager.GetWebContentsData(tab2)->GetPurgeAndSuspendState());

  tab_manager.GetWebContentsData(tab1)->SetPurgeAndSuspendState(
      TabManager::RESUMED);
  tab_manager.GetWebContentsData(tab1)
      ->SetLastPurgeAndSuspendModifiedTimeForTesting(test_clock.NowTicks());

  // Activate tab1. Tab1's PurgeAndSuspend state should be RUNNING.
  tabstrip.ActivateTabAt(0, true /* user_gesture */);
  EXPECT_EQ(TabManager::RUNNING,
            tab_manager.GetWebContentsData(tab1)->GetPurgeAndSuspendState());

  // Clean up the tabstrip.
  tabstrip.CloseAllTabs();
  EXPECT_TRUE(tabstrip.empty());
}

}  // namespace memory
