// Copyright 2018 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 <algorithm>

#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/path_service.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/notifications/notification_permission_context.h"
#include "chrome/browser/permissions/permission_request_manager.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h"
#include "chrome/browser/resource_coordinator/local_site_characteristics_data_reader.h"
#include "chrome/browser/resource_coordinator/local_site_characteristics_data_store_factory.h"
#include "chrome/browser/resource_coordinator/site_characteristics_data_reader.h"
#include "chrome/browser/resource_coordinator/tab_load_tracker.h"
#include "chrome/browser/resource_coordinator/tab_load_tracker_test_support.h"
#include "chrome/browser/resource_coordinator/tab_manager_features.h"
#include "chrome/browser/resource_coordinator/time.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/public/browser/notification_service.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/web_contents_tester.h"
#include "media/base/media_switches.h"
#include "net/dns/mock_host_resolver.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/origin.h"

#if defined(OS_CHROMEOS)
#include "chromeos/constants/chromeos_switches.h"
#endif

namespace resource_coordinator {

namespace {

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

constexpr char kTestPage[] =
    "/resource_coordinator/site_characteristics_test_page.html";

// Returns the longest feature observation window.
base::TimeDelta GetLongestObservationWindow() {
  const SiteCharacteristicsDatabaseParams& params =
      GetStaticSiteCharacteristicsDatabaseParams();
  return std::max({params.favicon_update_observation_window,
                   params.title_update_observation_window,
                   params.audio_usage_observation_window,
                   params.notifications_usage_observation_window});
}

// Returns the longest grace period.
base::TimeDelta GetLongestGracePeriod() {
  const SiteCharacteristicsDatabaseParams& params =
      GetStaticSiteCharacteristicsDatabaseParams();
  return std::max({params.title_or_favicon_change_grace_period,
                   params.audio_usage_grace_period});
}

// Returns the SiteCharacteristicsProto that backs |reader|.
const SiteCharacteristicsProto* GetSiteCharacteristicsProtoFromReader(
    SiteCharacteristicsDataReader* reader) {
  const internal::LocalSiteCharacteristicsDataImpl* impl =
      static_cast<LocalSiteCharacteristicsDataReader*>(reader)
          ->impl_for_testing();
  return &impl->site_characteristics_for_testing();
}

}  // namespace

class LocalSiteCharacteristicsDatabaseTest : public InProcessBrowserTest {
 public:
  LocalSiteCharacteristicsDatabaseTest()
      : scoped_set_tick_clock_for_testing_(&test_clock_),
        test_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {}
  ~LocalSiteCharacteristicsDatabaseTest() override = default;

  void SetUp() override {
    test_clock_.Advance(base::TimeDelta::FromSeconds(1));
    scoped_feature_list_.InitAndEnableFeature(
        features::kSiteCharacteristicsDatabase);
    InProcessBrowserTest::SetUp();
  }

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

    // Setup the test server.
    base::FilePath test_data_dir;
    ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir));
    test_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
    test_server_.ServeFilesFromDirectory(
        test_data_dir.AppendASCII("chrome/test/data/"));
    ASSERT_TRUE(test_server_.InitializeAndListen());
    test_server_.StartAcceptingConnections();
    const std::string real_host = test_server_.host_port_pair().host();
    host_resolver()->AddRule("*", real_host);
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitchASCII(
        switches::kAutoplayPolicy,
        switches::autoplay::kNoUserGestureRequiredPolicy);

    // HTTPS server only serves a valid cert for localhost, so this is needed
    // to load pages from other origins without an interstitial.
    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);

#if defined(OS_CHROMEOS)
    command_line->AppendSwitch(
        chromeos::switches::kIgnoreUserProfileMappingForTests);
#endif
    InProcessBrowserTest::SetUpCommandLine(command_line);
  }

  WebContents* GetActiveWebContents() {
    return browser()->tab_strip_model()->GetActiveWebContents();
  }

  std::unique_ptr<SiteCharacteristicsDataReader> GetReaderForOrigin(
      Profile* profile,
      const url::Origin& origin) {
    SiteCharacteristicsDataStore* data_store =
        LocalSiteCharacteristicsDataStoreFactory::GetForProfile(profile);
    EXPECT_TRUE(data_store);
    std::unique_ptr<SiteCharacteristicsDataReader> reader =
        data_store->GetReaderForOrigin(origin);

    const internal::LocalSiteCharacteristicsDataImpl* impl =
        static_cast<LocalSiteCharacteristicsDataReader*>(reader.get())
            ->impl_for_testing();
    while (!impl->fully_initialized_for_testing())
      base::RunLoop().RunUntilIdle();
    return reader;
  }

  // Test that feature usage is tracked correctly:
  //   - kSiteFeatureUsageUnknown if never observed and observation window
  //     hasn't expired.
  //   - kSiteFeatureNotInUse if never observed and observation window has
  //     expired.
  //   - kSiteFeatureInUse if observed.
  // |feature_detection_method| is the SiteCharacteristicsDataReader method that
  // will be called to query the status of this feature. |triggering_closure| is
  // the closure to run to cause this feature to be used (this will get called
  // while the tab is in background) and |allowing_closure| is an optional
  // closure that should run before testing the feature usage (to allow it to
  // be used).
  void TestFeatureUsageDetection(
      SiteFeatureUsage (
          SiteCharacteristicsDataReader::*feature_detection_method)() const,
      base::RepeatingClosure triggering_closure,
      base::RepeatingClosure allowing_closure = base::DoNothing::Repeatedly()) {
    // Test that feature usage is tracked correctly before the expiration of its
    // observation window.
    TestFeatureUsageDetectionImpl(feature_detection_method, allowing_closure,
                                  triggering_closure, false);
    // Test that feature usage is tracked correctly after the expiration of its
    // observation window.
    TestFeatureUsageDetectionImpl(feature_detection_method,
                                  std::move(allowing_closure),
                                  std::move(triggering_closure), true);
  }

  void ExecuteScriptInMainFrame(const char* script) {
    content::RenderFrameHost* main_frame =
        GetActiveWebContents()->GetMainFrame();
    EXPECT_TRUE(content::ExecuteScript(main_frame, script));
  }

  void PlayAudioInActiveWebContents() {
    ExecuteScriptInMainFrame("PlayAudio();");
  }

  void ChangeTitleOfActiveWebContents() {
    ExecuteScriptInMainFrame("ChangeTitle('new_title')");
  }

  void ChangeFaviconOfActiveWebContents() {
    ExecuteScriptInMainFrame("ChangeFavicon()");
  }

  void TriggerNonPersistentNotificationInActiveWebContents() {
    ExecuteScriptInMainFrame(
        "DisplayAndCloseNonPersistentNotification('foo');");
  }

  // By default a tab has to play audio while being visible if it wants to be
  // able to play audio in background (see
  // ChromeContentRendererClient::DeferMediaLoad). This makes the current active
  // WebContents visible, play some audio and background it. After calling
  // this the background tab is allowed play audio.
  void AllowBackgroundAudioInActiveTab() {
    content::WebContents* active_webcontents = GetActiveWebContents();
    active_webcontents->WasShown();
    PlayAudioInActiveWebContents();

    // Wait for the audio to start playing.
    while (!active_webcontents->WasEverAudible())
      base::RunLoop().RunUntilIdle();

    active_webcontents->GetController().Reload(content::ReloadType::NORMAL,
                                               false);
    content::WaitForLoadStop(GetActiveWebContents());
    // Background the tab and reload it so the audio will stop playing if it's
    // still playing.
    GetActiveWebContents()->WasHidden();
    test_clock_.Advance(
        GetStaticSiteCharacteristicsDatabaseParams().audio_usage_grace_period);
  }

  // Ensure that the current tab is allowed to display non-persistent
  // notifications.
  void AllowBackgroundNotificationInActiveTab() {
    content::WebContents* web_contents = GetActiveWebContents();
    NotificationPermissionContext::UpdatePermission(
        browser()->profile(), web_contents->GetLastCommittedURL(),
        CONTENT_SETTING_ALLOW);

    ExecuteScriptInMainFrame("RequestNotificationsPermission();");
  }

  void ExpireTitleOrFaviconGracePeriod() {
    test_clock_.Advance(GetStaticSiteCharacteristicsDatabaseParams()
                            .title_or_favicon_change_grace_period);
  }

  base::SimpleTestTickClock& test_clock() { return test_clock_; }
  net::test_server::EmbeddedTestServer& test_server() { return test_server_; }

 private:
  void TestFeatureUsageDetectionImpl(
      SiteFeatureUsage (
          SiteCharacteristicsDataReader::*feature_detection_method)() const,
      base::OnceClosure allowing_closure,
      base::RepeatingClosure triggering_closure,
      bool wait_for_observation_window_to_expire);

  base::SimpleTestTickClock test_clock_;
  ScopedSetTickClockForTesting scoped_set_tick_clock_for_testing_;
  base::test::ScopedFeatureList scoped_feature_list_;
  net::test_server::EmbeddedTestServer test_server_;

  DISALLOW_COPY_AND_ASSIGN(LocalSiteCharacteristicsDatabaseTest);
};

void LocalSiteCharacteristicsDatabaseTest::TestFeatureUsageDetectionImpl(
    SiteFeatureUsage (
        SiteCharacteristicsDataReader::*feature_detection_method)() const,
    base::OnceClosure allowing_closure,
    base::RepeatingClosure triggering_closure,
    bool wait_for_observation_window_to_expire) {
  // Use a different origin depending on the type of test to make sure that
  // previous observations don't get re-used.
  const char* kOrigin =
      wait_for_observation_window_to_expire ? "foo.com" : "bar.com";
  GURL test_url(test_server_.GetURL(kOrigin, kTestPage));

  // Get the reader for this origin.
  auto reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            (reader.get()->*feature_detection_method)());

  // Navigate to the test url and background it.
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), test_url, WindowOpenDisposition::CURRENT_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
  GetActiveWebContents()->WasHidden();
  WaitForTransitionToLoaded(GetActiveWebContents());

  // If needed, wait for all feature observation windows to expire.
  if (wait_for_observation_window_to_expire) {
    test_clock_.Advance(GetLongestObservationWindow());
    EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
              (reader.get()->*feature_detection_method)());
  }

  // Call the allowing closure.
  std::move(allowing_closure).Run();

  // Ensure that the closure hasn't caused the feature usage status to
  // change.
  if (wait_for_observation_window_to_expire) {
    EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
              (reader.get()->*feature_detection_method)());
  } else {
    EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
              (reader.get()->*feature_detection_method)());
  }

  // Cause the feature to be used.
  triggering_closure.Run();

  while ((reader.get()->*feature_detection_method)() !=
         SiteFeatureUsage::kSiteFeatureInUse) {
    base::RunLoop().RunUntilIdle();
  }

  // Advance the clock, make sure that the feature usage status doesn't
  // change.
  test_clock_.Advance(GetLongestObservationWindow());

  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
            (reader.get()->*feature_detection_method)());
}

// Test that doesn't use any feature.
IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest, NoFeatureUsed) {
  GURL test_url(test_server().GetURL("foo.com", kTestPage));

  ui_test_utils::NavigateToURLWithDisposition(
      browser(), test_url, WindowOpenDisposition::NEW_BACKGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(1);
  EXPECT_EQ(test_url, contents->GetLastCommittedURL());
  WaitForTransitionToLoaded(contents);

  auto reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UpdatesFaviconInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UpdatesTitleInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UsesAudioInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UsesNotificationsInBackground());

  test_clock().Advance(GetLongestObservationWindow());

  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
            reader->UpdatesFaviconInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
            reader->UpdatesTitleInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
            reader->UsesAudioInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
            reader->UsesNotificationsInBackground());
}

// Test that use features while in foreground, this shouldn't be recorded.
IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
                       FeatureUsedInForegroundOnly) {
  GURL test_url(test_server().GetURL("foo.com", kTestPage));

  ui_test_utils::NavigateToURLWithDisposition(
      browser(), test_url, WindowOpenDisposition::CURRENT_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  GetActiveWebContents()->WasShown();

  ChangeTitleOfActiveWebContents();
  ChangeFaviconOfActiveWebContents();
  PlayAudioInActiveWebContents();
  // TODO(sebmarchand): Also trigger a background notification once.

  auto reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UpdatesFaviconInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UpdatesTitleInBackground());

  // Advance the clock while the tab is still in foreground and make sure that
  // the state hasn't changed.
  test_clock().Advance(GetLongestObservationWindow());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UpdatesFaviconInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UpdatesTitleInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UsesAudioInBackground());
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UsesNotificationsInBackground());
}

// Test that the audio feature usage in background gets detected properly.
IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
                       AudioFeatureUsage) {
  TestFeatureUsageDetection(
      &SiteCharacteristicsDataReader::UsesAudioInBackground,
      base::BindRepeating(
          &LocalSiteCharacteristicsDatabaseTest::PlayAudioInActiveWebContents,
          base::Unretained(this)),
      base::BindRepeating(&LocalSiteCharacteristicsDatabaseTest::
                              AllowBackgroundAudioInActiveTab,
                          base::Unretained(this)));
}

// Test that the notification feature usage in background gets detected
// properly.
// TODO(sebmarchand): Figure out how to trigger a non-persistent notification in
// this test.
IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
                       DISABLED_NotificationFeatureUsage) {
  TestFeatureUsageDetection(
      &SiteCharacteristicsDataReader::UsesNotificationsInBackground,
      base::BindRepeating(
          &LocalSiteCharacteristicsDatabaseTest::
              TriggerNonPersistentNotificationInActiveWebContents,
          base::Unretained(this)),
      base::BindRepeating(&LocalSiteCharacteristicsDatabaseTest::
                              AllowBackgroundNotificationInActiveTab,
                          base::Unretained(this)));
}

IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
                       TitleUpdateFeatureUsage) {
  TestFeatureUsageDetection(
      &SiteCharacteristicsDataReader::UpdatesTitleInBackground,
      base::BindRepeating(
          &LocalSiteCharacteristicsDatabaseTest::ChangeTitleOfActiveWebContents,
          base::Unretained(this)),
      base::BindRepeating(&LocalSiteCharacteristicsDatabaseTest::
                              ExpireTitleOrFaviconGracePeriod,
                          base::Unretained(this)));
}

// Test that the favicon update feature usage in background gets detected
// properly.
IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
                       FaviconUpdateFeatureUsage) {
  TestFeatureUsageDetection(
      &SiteCharacteristicsDataReader::UpdatesFaviconInBackground,
      base::BindRepeating(&LocalSiteCharacteristicsDatabaseTest::
                              ChangeFaviconOfActiveWebContents,
                          base::Unretained(this)),
      base::BindRepeating(&LocalSiteCharacteristicsDatabaseTest::
                              ExpireTitleOrFaviconGracePeriod,
                          base::Unretained(this)));
}

// Test that loads the same origin into multiple tabs and ensure that they get
// tracked properly.
IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
                       LoadedStateGetsTrackedProperly) {
  GURL test_url(test_server().GetURL("foo.com", kTestPage));
  auto test_reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));

  const size_t kTabCount = 3;

  // Load all the tabs and background them.
  for (size_t i = 0; i < kTabCount; ++i) {
    ui_test_utils::NavigateToURLWithDisposition(
        browser(), test_url,
        i == 0 ? WindowOpenDisposition::CURRENT_TAB
               : WindowOpenDisposition::NEW_FOREGROUND_TAB,
        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    content::WebContents* contents =
        browser()->tab_strip_model()->GetWebContentsAt(i);
    WaitForTransitionToLoaded(contents);
    EXPECT_EQ(TabLoadTracker::LoadingState::LOADED,
              TabLoadTracker::Get()->GetLoadingState(contents));
    contents->WasHidden();
  }

  const internal::LocalSiteCharacteristicsDataImpl* impl =
      static_cast<LocalSiteCharacteristicsDataReader*>(test_reader.get())
          ->impl_for_testing();
  EXPECT_TRUE(impl);
  EXPECT_EQ(3U, impl->loaded_tabs_count_for_testing());
  EXPECT_EQ(3U, impl->loaded_tabs_in_background_count_for_testing());

  // Change the visibility of the tabs.
  for (size_t i = 0; i < kTabCount; ++i) {
    browser()->tab_strip_model()->GetWebContentsAt(i)->WasShown();

    EXPECT_EQ(kTabCount, impl->loaded_tabs_count_for_testing());
    EXPECT_EQ(kTabCount - (i + 1),
              impl->loaded_tabs_in_background_count_for_testing());
  }

  for (size_t i = 0; i < kTabCount; ++i)
    browser()->tab_strip_model()->GetWebContentsAt(i)->WasHidden();

  EXPECT_EQ(3U, impl->loaded_tabs_in_background_count_for_testing());

  // Close the tabs.
  for (size_t i = 0; i < kTabCount; ++i) {
    EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt(0, 0));
    EXPECT_EQ(kTabCount - (i + 1), impl->loaded_tabs_count_for_testing());
    EXPECT_EQ(kTabCount - (i + 1),
              impl->loaded_tabs_in_background_count_for_testing());
  }
}

// Ensure that the observations gets persisted on disk.
IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
                       PRE_DatabaseGetsPersisted) {
  GURL test_url(test_server().GetURL("foo.com", kTestPage));

  // Get the reader for this origin.
  auto reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UpdatesTitleInBackground());

  // Navigate to the test url and background it.
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), test_url, WindowOpenDisposition::CURRENT_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
  WaitForTransitionToLoaded(GetActiveWebContents());
  GetActiveWebContents()->WasHidden();

  test_clock().Advance(GetLongestGracePeriod());

  // Cause the "title update in background" feature to be used.
  ChangeTitleOfActiveWebContents();

  while (reader->UpdatesTitleInBackground() !=
         SiteFeatureUsage::kSiteFeatureInUse) {
    base::RunLoop().RunUntilIdle();
  }
}

IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
                       DatabaseGetsPersisted) {
  GURL test_url(test_server().GetURL("foo.com", kTestPage));

  // Get the reader for this origin.
  auto reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));

  // We should remember the observation made previously.
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
            reader->UpdatesTitleInBackground());
}

// Ensure that clearing the history removes the observations from disk.
IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest, PRE_ClearHistory) {
  GURL test_url(test_server().GetURL("foo.com", kTestPage));

  // Get the reader for this origin.
  auto reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UpdatesTitleInBackground());

  // Navigate to the test url and background it.
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), test_url, WindowOpenDisposition::CURRENT_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
  WaitForTransitionToLoaded(GetActiveWebContents());
  GetActiveWebContents()->WasHidden();

  test_clock().Advance(GetLongestGracePeriod());

  // Cause the "title update in background" feature to be used.
  ChangeTitleOfActiveWebContents();

  while (reader->UpdatesTitleInBackground() !=
         SiteFeatureUsage::kSiteFeatureInUse) {
    base::RunLoop().RunUntilIdle();
  }

  HistoryServiceFactory::GetForProfile(browser()->profile(),
                                       ServiceAccessType::IMPLICIT_ACCESS)
      ->DeleteURL(test_url);
  // The history gets cleared asynchronously.
  while (reader->UpdatesTitleInBackground() !=
         SiteFeatureUsage::kSiteFeatureUsageUnknown) {
    base::RunLoop().RunUntilIdle();
  }
}

IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest, ClearHistory) {
  GURL test_url(test_server().GetURL("foo.com", kTestPage));

  // Get the reader for this origin.
  auto reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));

  // The history has been cleared, we shouldn't know if this feature is used.
  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
            reader->UpdatesTitleInBackground());
}

// Ensure that the observation time gets tracked across sessions.
IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
                       PRE_DatabaseObservationTimeTrackedAcrossSessions) {
  GURL test_url(test_server().GetURL("foo.com", kTestPage));

  auto reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
  const SiteCharacteristicsProto* site_characteristics =
      GetSiteCharacteristicsProtoFromReader(reader.get());

  EXPECT_EQ(0, site_characteristics->updates_title_in_background()
                   .observation_duration());

  // Navigate to the test url and background it.
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), test_url, WindowOpenDisposition::CURRENT_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
  WaitForTransitionToLoaded(GetActiveWebContents());
  GetActiveWebContents()->WasHidden();

  test_clock().Advance(base::TimeDelta::FromSeconds(10));
  EXPECT_GE(10, site_characteristics->updates_title_in_background()
                    .observation_duration());
}

IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
                       DatabaseObservationTimeTrackedAcrossSessions) {
  GURL test_url(test_server().GetURL("foo.com", kTestPage));

  auto reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
  const SiteCharacteristicsProto* site_characteristics =
      GetSiteCharacteristicsProtoFromReader(reader.get());

  auto observation_duration =
      site_characteristics->updates_title_in_background()
          .observation_duration();
  // The observation duration shouldn't be null as this has been augmented in
  // the 'PRE' part of this test.
  EXPECT_NE(0, observation_duration);

  // Advance the clock and reset this reader. This should increase the
  // observation duration that we have for this origin in the database.
  test_clock().Advance(base::TimeDelta::FromSeconds(10));
  reader.reset();

  reader =
      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
  site_characteristics = GetSiteCharacteristicsProtoFromReader(reader.get());

  EXPECT_GE(observation_duration,
            site_characteristics->updates_title_in_background()
                .observation_duration());
}

}  // namespace resource_coordinator
