Commit 17135cd8 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

Media Engagement: Clear data from MEI when urls are expired

History is expired automatically after 90 days. This clears data from
MEI if history is expired and there is no more history remaining on that
origin.

BUG=818153

Change-Id: I7dd309d5abddb398ff0ec452147d25a86ce827b6
Reviewed-on: https://chromium-review.googlesource.com/960142
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#546237}
parent fc88e337
...@@ -44,6 +44,7 @@ enum class MediaEngagementClearReason { ...@@ -44,6 +44,7 @@ enum class MediaEngagementClearReason {
kDataRange = 1, kDataRange = 1,
kHistoryAll = 2, kHistoryAll = 2,
kHistoryRange = 3, kHistoryRange = 3,
kHistoryExpired = 4,
kCount kCount
}; };
...@@ -207,10 +208,24 @@ void MediaEngagementService::OnURLsDeleted( ...@@ -207,10 +208,24 @@ void MediaEngagementService::OnURLsDeleted(
return; return;
} }
// TODO(818153): history expiration currently has no effect on MEI but entries // If origins are expired by the history service delete them if they have no
// that no longer appear in history should be removed from the database. // more visits.
if (expired) if (expired) {
DCHECK(history_service);
// Build a set of all origins in |deleted_rows|.
std::set<GURL> origins;
for (const history::URLRow& row : deleted_rows) {
origins.insert(row.url().GetOrigin());
}
// Check if any origins no longer have any visits.
history_service->GetCountsAndLastVisitForOrigins(
origins,
base::BindRepeating(&MediaEngagementService::RemoveOriginsWithNoVisits,
base::Unretained(this), origins));
return; return;
}
std::map<GURL, int> origins; std::map<GURL, int> origins;
for (const history::URLRow& row : deleted_rows) { for (const history::URLRow& row : deleted_rows) {
...@@ -248,6 +263,25 @@ void MediaEngagementService::OnURLsDeleted( ...@@ -248,6 +263,25 @@ void MediaEngagementService::OnURLsDeleted(
} }
} }
void MediaEngagementService::RemoveOriginsWithNoVisits(
const std::set<GURL>& deleted_origins,
const history::OriginCountAndLastVisitMap& origin_data) {
// Find all origins that are in |deleted_origins| and not in
// |remaining_origins| and clear MEI data on them.
bool has_deleted_origins = false;
for (const GURL& origin : deleted_origins) {
const auto& origin_count = origin_data.find(origin);
if (origin_count == origin_data.end() || origin_count->second.first > 0)
continue;
Clear(origin);
has_deleted_origins = true;
}
if (has_deleted_origins)
RecordClear(MediaEngagementClearReason::kHistoryExpired);
}
void MediaEngagementService::Clear(const GURL& url) { void MediaEngagementService::Clear(const GURL& url) {
HostContentSettingsMapFactory::GetForProfile(profile_) HostContentSettingsMapFactory::GetForProfile(profile_)
->ClearSettingsForOneTypeWithPredicate( ->ClearSettingsForOneTypeWithPredicate(
......
...@@ -138,6 +138,13 @@ class MediaEngagementService : public KeyedService, ...@@ -138,6 +138,13 @@ class MediaEngagementService : public KeyedService,
int GetSchemaVersion() const; int GetSchemaVersion() const;
void SetSchemaVersion(int); void SetSchemaVersion(int);
// Remove origins from `deleted_origins` that have no more visits in the
// history service, represented as `origin_data`. This is meant to be used
// when the service receives a notification of history expiration.
void RemoveOriginsWithNoVisits(
const std::set<GURL>& deleted_origins,
const history::OriginCountAndLastVisitMap& origin_data);
// Allows us to cancel the RecordScoresToHistogram task if we are destroyed. // Allows us to cancel the RecordScoresToHistogram task if we are destroyed.
base::CancelableTaskTracker task_tracker_; base::CancelableTaskTracker task_tracker_;
......
...@@ -40,6 +40,9 @@ namespace { ...@@ -40,6 +40,9 @@ namespace {
base::FilePath g_temp_history_dir; base::FilePath g_temp_history_dir;
// History is automatically expired after 90 days.
base::TimeDelta kHistoryExpirationThreshold = base::TimeDelta::FromDays(90);
// Waits until a change is observed in media engagement content settings. // Waits until a change is observed in media engagement content settings.
class MediaEngagementChangeWaiter : public content_settings::Observer { class MediaEngagementChangeWaiter : public content_settings::Observer {
public: public:
...@@ -108,8 +111,7 @@ class MediaEngagementServiceTest : public ChromeRenderViewHostTestHarness { ...@@ -108,8 +111,7 @@ class MediaEngagementServiceTest : public ChromeRenderViewHostTestHarness {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
g_temp_history_dir = temp_dir_.GetPath(); g_temp_history_dir = temp_dir_.GetPath();
HistoryServiceFactory::GetInstance()->SetTestingFactory( ConfigureHistoryService();
profile(), &BuildTestHistoryService);
test_clock_.SetNow(GetReferenceTime()); test_clock_.SetNow(GetReferenceTime());
service_ = base::WrapUnique(StartNewMediaEngagementService()); service_ = base::WrapUnique(StartNewMediaEngagementService());
...@@ -124,6 +126,23 @@ class MediaEngagementServiceTest : public ChromeRenderViewHostTestHarness { ...@@ -124,6 +126,23 @@ class MediaEngagementServiceTest : public ChromeRenderViewHostTestHarness {
return service; return service;
} }
void ConfigureHistoryService() {
HistoryServiceFactory::GetInstance()->SetTestingFactory(
profile(), &BuildTestHistoryService);
}
void RestartHistoryService() {
history::HistoryService* history_old = HistoryServiceFactory::GetForProfile(
profile(), ServiceAccessType::IMPLICIT_ACCESS);
history_old->Shutdown();
HistoryServiceFactory::ShutdownForProfile(profile());
ConfigureHistoryService();
history::HistoryService* history = HistoryServiceFactory::GetForProfile(
profile(), ServiceAccessType::IMPLICIT_ACCESS);
history->AddObserver(service());
}
void RecordVisitAndPlaybackAndAdvanceClock(GURL url) { void RecordVisitAndPlaybackAndAdvanceClock(GURL url) {
RecordVisit(url); RecordVisit(url);
AdvanceClock(); AdvanceClock();
...@@ -540,6 +559,52 @@ TEST_F(MediaEngagementServiceTest, CleanupOriginsOnHistoryDeletion) { ...@@ -540,6 +559,52 @@ TEST_F(MediaEngagementServiceTest, CleanupOriginsOnHistoryDeletion) {
} }
} }
TEST_F(MediaEngagementServiceTest, CleanUpDatabaseWhenHistoryIsExpired) {
base::HistogramTester histogram_tester;
// |origin1| will have history that is before the expiry threshold and should
// not be deleted. |origin2| will have history either side of the threshold
// and should also not be deleted. |origin3| will have history before the
// threshold and should be deleted.
GURL origin1("http://www.google.com/");
GURL origin2("https://drive.google.com/");
GURL origin3("http://deleted.com/");
// Populate test MEI data.
SetScores(origin1, 20, 20);
SetScores(origin2, 30, 30);
SetScores(origin3, 40, 40);
base::Time today = base::Time::Now();
base::Time before_threshold = today - kHistoryExpirationThreshold;
SetNow(today);
// Populate test history records.
history::HistoryService* history = HistoryServiceFactory::GetForProfile(
profile(), ServiceAccessType::IMPLICIT_ACCESS);
history->AddPage(origin1, today, history::SOURCE_BROWSED);
history->AddPage(origin2, today, history::SOURCE_BROWSED);
history->AddPage(origin2, before_threshold, history::SOURCE_BROWSED);
history->AddPage(origin3, before_threshold, history::SOURCE_BROWSED);
// Expire history older than |threshold|.
MediaEngagementChangeWaiter waiter(profile());
RestartHistoryService();
waiter.Wait();
// Check the scores for the test origins.
ExpectScores(origin1, 1.0, 20, 20, TimeNotSet());
ExpectScores(origin2, 1.0, 30, 30, TimeNotSet());
ExpectScores(origin3, 0, 0, 0, TimeNotSet());
// Check that we recorded the expiry event to a histogram.
histogram_tester.ExpectTotalCount(MediaEngagementService::kHistogramClearName,
1);
histogram_tester.ExpectBucketCount(
MediaEngagementService::kHistogramClearName, 4, 1);
}
TEST_F(MediaEngagementServiceTest, CleanUpDatabaseWhenHistoryIsDeleted) { TEST_F(MediaEngagementServiceTest, CleanUpDatabaseWhenHistoryIsDeleted) {
GURL origin1("http://www.google.com/"); GURL origin1("http://www.google.com/");
GURL origin1a("http://www.google.com/search?q=asdf"); GURL origin1a("http://www.google.com/search?q=asdf");
...@@ -647,7 +712,9 @@ TEST_F(MediaEngagementServiceTest, HistoryExpirationIsNoOp) { ...@@ -647,7 +712,9 @@ TEST_F(MediaEngagementServiceTest, HistoryExpirationIsNoOp) {
{ {
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
service()->OnURLsDeleted(nullptr, false, true, history::URLRows(), history::HistoryService* history = HistoryServiceFactory::GetForProfile(
profile(), ServiceAccessType::IMPLICIT_ACCESS);
service()->OnURLsDeleted(history, false, true, history::URLRows(),
std::set<GURL>()); std::set<GURL>());
// Same as above, nothing should have changed. // Same as above, nothing should have changed.
......
...@@ -28682,6 +28682,7 @@ Called by update_use_counter_css.py.--> ...@@ -28682,6 +28682,7 @@ Called by update_use_counter_css.py.-->
<int value="1" label="Data (range)"/> <int value="1" label="Data (range)"/>
<int value="2" label="History (all)"/> <int value="2" label="History (all)"/>
<int value="3" label="History (range)"/> <int value="3" label="History (range)"/>
<int value="4" label="History (expired)"/>
</enum> </enum>
<enum name="MediaEngagementSessionEvent"> <enum name="MediaEngagementSessionEvent">
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