Commit bdb95bb9 authored by Sebastien Marchand's avatar Sebastien Marchand Committed by Commit Bot

Reland "RC: Connect the Local DB to TabHelper and add browsertests."

This is a reland of 8f4ffc9a with a fix
for a flakiness in LocalSiteCharacteristicsDatabaseTest.PRE_ClearHistory,
the HistoryService::Delete task didn't always had time to run before we
assumed that the entry had been removed from the history, this fix this
by running RunUntilIdle() several time (until the deletion has
complete)



Original change's description:
> RC: Connect the Local DB to TabHelper and add browsertests.
>
> Bug: 773382
> Change-Id: Ie7cbbf2c74bfbf1f1522b2a1f775a392545ad0a9
> Reviewed-on: https://chromium-review.googlesource.com/1088196
> Commit-Queue: Sébastien Marchand <sebmarchand@chromium.org>
> Reviewed-by: François Doray <fdoray@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#568519}

Bug: 773382
Change-Id: I05072f974d70c200fff87e0239c8537c8d0bcfc8
Reviewed-on: https://chromium-review.googlesource.com/1106940
Commit-Queue: François Doray <fdoray@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569311}
parent cb9aed04
......@@ -101,6 +101,8 @@ class LocalSiteCharacteristicsDataImpl
return site_characteristics_;
}
size_t loaded_tabs_count_for_testing() const { return loaded_tabs_count_; }
size_t loaded_tabs_in_background_count_for_testing() const {
return loaded_tabs_in_background_count_;
}
......
......@@ -66,6 +66,8 @@ void LocalSiteCharacteristicsDataWriter::NotifyUpdatesTitleInBackground() {
void LocalSiteCharacteristicsDataWriter::NotifyUsesAudioInBackground() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(TabVisibility::kBackground, tab_visibility_);
// TODO(sebmarchand): Do not advance the background audio observation time
// when the WebContents has never played audio.
impl_->NotifyUsesAudioInBackground();
}
......
// 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/desktop_notification_profile_util.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_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/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});
}
} // 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);
internal::LocalSiteCharacteristicsDataImpl* impl =
static_cast<LocalSiteCharacteristicsDataReader*>(reader.get())
->impl_for_testing()
.get();
while (!impl->site_characteristics_for_testing().IsInitialized())
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();
}
// Ensure that the current tab is allowed to display non-persistent
// notifications.
void AllowBackgroundNotificationInActiveTab() {
HostContentSettingsMapFactory::GetForProfile(browser()->profile())
->ClearSettingsForOneType(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
HostContentSettingsMapFactory::GetForProfile(browser()->profile())
->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
CONTENT_SETTING_ALLOW);
content::WebContents* web_contents = GetActiveWebContents();
DesktopNotificationProfileUtil::GrantPermission(
browser()->profile(), web_contents->GetLastCommittedURL());
PermissionRequestManager::FromWebContents(web_contents)
->set_auto_response_for_test(PermissionRequestManager::ACCEPT_ALL);
ExecuteScriptInMainFrame("RequestNotificationsPermission();");
}
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();
// 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);
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)));
}
// 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)));
}
// 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);
EXPECT_EQ(TabLoadTracker::LoadingState::LOADED,
TabLoadTracker::Get()->GetLoadingState(
browser()->tab_strip_model()->GetWebContentsAt(i)));
browser()->tab_strip_model()->GetWebContentsAt(i)->WasHidden();
}
internal::LocalSiteCharacteristicsDataImpl* impl =
static_cast<LocalSiteCharacteristicsDataReader*>(test_reader.get())
->impl_for_testing()
.get();
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);
GetActiveWebContents()->WasHidden();
// 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);
GetActiveWebContents()->WasHidden();
// 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());
}
} // namespace resource_coordinator
......@@ -27,6 +27,10 @@
#include "services/resource_coordinator/public/mojom/service_constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#if !defined(OS_ANDROID)
#include "chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.h"
#endif
DEFINE_WEB_CONTENTS_USER_DATA_KEY(
resource_coordinator::ResourceCoordinatorTabHelper);
......@@ -62,6 +66,14 @@ ResourceCoordinatorTabHelper::ResourceCoordinatorTabHelper(
TabMemoryMetricsReporter::Get()->StartReporting(TabLoadTracker::Get());
}
#if !defined(OS_ANDROID)
if (base::FeatureList::IsEnabled(features::kSiteCharacteristicsDatabase)) {
local_site_characteristics_wc_observer_ =
std::make_unique<LocalSiteCharacteristicsWebContentsObserver>(
web_contents);
}
#endif
}
ResourceCoordinatorTabHelper::~ResourceCoordinatorTabHelper() = default;
......
......@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
......@@ -17,6 +18,7 @@
namespace resource_coordinator {
class PageResourceCoordinator;
class LocalSiteCharacteristicsWebContentsObserver;
class ResourceCoordinatorTabHelper
: public content::WebContentsObserver,
......@@ -63,6 +65,11 @@ class ResourceCoordinatorTabHelper
page_resource_coordinator_;
ukm::SourceId ukm_source_id_ = ukm::kInvalidSourceId;
#if !defined(OS_ANDROID)
std::unique_ptr<LocalSiteCharacteristicsWebContentsObserver>
local_site_characteristics_wc_observer_;
#endif
// Favicon and title are set when a page is loaded, we only want to send
// signals to GRC about title and favicon update from the previous title and
// favicon, thus we want to ignore the very first update since it is always
......
......@@ -697,6 +697,7 @@ test("browser_tests") {
"../browser/renderer_host/render_process_host_chrome_browsertest.cc",
"../browser/repost_form_warning_browsertest.cc",
"../browser/resource_coordinator/local_site_characteristics_data_store_factory_browsertest.cc",
"../browser/resource_coordinator/local_site_characteristics_database_browsertest.cc",
"../browser/resource_coordinator/render_process_probe_browsertest.cc",
"../browser/resource_coordinator/tab_activity_watcher_browsertest.cc",
"../browser/resource_coordinator/tab_manager_browsertest.cc",
......
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Site Characteristics Database Test Page</title>
</head>
<body>
<script>
// Requests permission to display Web Notifications.
function RequestNotificationsPermission() {
Notification.requestPermission(function (level) {
domAutomationController.send(level);
});
}
// Instantiates a new non-persistent notification with the given |title|
// and |options| and then closes it.
function DisplayAndCloseNonPersistentNotification(title, options) {
const notification = new Notification(title, options || {});
notification.addEventListener('show', e => {
notification.close();
});
notification.addEventListener('close', e => {
domAutomationController.send('ok');
});
}
// Play |test_audio.ogg|.
function PlayAudio() {
var audio = new Audio('test_audio.ogg');
audio.addEventListener('loadeddata', function () {
audio.play();
})
}
// Change the page title to |new_title|
function ChangeTitle(new_title) {
document.title = new_title;
}
// Change the favicon to |default_favicon.png|.
function ChangeFavicon() {
favicon = document.createElement('link');
favicon.setAttribute('rel', 'shortcut icon');
var head = document.querySelector('head');
head.appendChild(favicon);
favicon.setAttribute('type', 'image/png');
favicon.setAttribute('href', 'default_favicon.png');
}
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment