Commit fb380be6 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Media Engagement] Add storage for AudioContext

Add a media element playbacks and an audio
context playbacks field to the
MediaEngagmentScore. The media element playbacks
field should be pre-populated with the current
media playbacks value (as all previous playbacks
would be from media elements).

BUG=878460

Change-Id: If34b468bddf1cefaf753e0acd220afa1f100331b
Reviewed-on: https://chromium-review.googlesource.com/1194690
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587888}
parent 85110147
...@@ -24,6 +24,10 @@ const char MediaEngagementScore::kSignificantPlaybacksKey[] = ...@@ -24,6 +24,10 @@ const char MediaEngagementScore::kSignificantPlaybacksKey[] =
const char MediaEngagementScore::kVisitsWithMediaTagKey[] = const char MediaEngagementScore::kVisitsWithMediaTagKey[] =
"visitsWithMediaTag"; "visitsWithMediaTag";
const char MediaEngagementScore::kHighScoreChanges[] = "highScoreChanges"; const char MediaEngagementScore::kHighScoreChanges[] = "highScoreChanges";
const char MediaEngagementScore::kSignificantMediaPlaybacksKey[] =
"mediaElementPlaybacks";
const char MediaEngagementScore::kSignificantAudioContextPlaybacksKey[] =
"audioContextPlaybacks";
const char MediaEngagementScore::kScoreMinVisitsParamName[] = "min_visits"; const char MediaEngagementScore::kScoreMinVisitsParamName[] = "min_visits";
const char MediaEngagementScore::kHighScoreLowerThresholdParamName[] = const char MediaEngagementScore::kHighScoreLowerThresholdParamName[] =
...@@ -82,24 +86,18 @@ MediaEngagementScore::MediaEngagementScore(base::Clock* clock, ...@@ -82,24 +86,18 @@ MediaEngagementScore::MediaEngagementScore(base::Clock* clock,
: MediaEngagementScore( : MediaEngagementScore(
clock, clock,
origin, origin,
GetMediaEngagementScoreDictForSettings(settings, origin)) { GetMediaEngagementScoreDictForSettings(settings, origin),
settings_map_ = settings; settings) {}
}
MediaEngagementScore::MediaEngagementScore( MediaEngagementScore::MediaEngagementScore(
base::Clock* clock, base::Clock* clock,
const GURL& origin, const GURL& origin,
std::unique_ptr<base::DictionaryValue> score_dict, std::unique_ptr<base::DictionaryValue> score_dict,
HostContentSettingsMap* settings) HostContentSettingsMap* settings)
: MediaEngagementScore(clock, origin, std::move(score_dict)) { : origin_(origin),
settings_map_ = settings; clock_(clock),
} score_dict_(score_dict.release()),
settings_map_(settings) {
MediaEngagementScore::MediaEngagementScore(
base::Clock* clock,
const GURL& origin,
std::unique_ptr<base::DictionaryValue> score_dict)
: origin_(origin), clock_(clock), score_dict_(score_dict.release()) {
if (!score_dict_) if (!score_dict_)
return; return;
...@@ -110,6 +108,10 @@ MediaEngagementScore::MediaEngagementScore( ...@@ -110,6 +108,10 @@ MediaEngagementScore::MediaEngagementScore(
score_dict_->GetInteger(kSignificantPlaybacksKey, &significant_playbacks_); score_dict_->GetInteger(kSignificantPlaybacksKey, &significant_playbacks_);
score_dict_->GetInteger(kVisitsWithMediaTagKey, &visits_with_media_tag_); score_dict_->GetInteger(kVisitsWithMediaTagKey, &visits_with_media_tag_);
score_dict_->GetInteger(kHighScoreChanges, &high_score_changes_); score_dict_->GetInteger(kHighScoreChanges, &high_score_changes_);
score_dict_->GetInteger(kSignificantMediaPlaybacksKey,
&media_element_playbacks_);
score_dict_->GetInteger(kSignificantAudioContextPlaybacksKey,
&audio_context_playbacks_);
double internal_time; double internal_time;
if (score_dict_->GetDouble(kLastMediaPlaybackTimeKey, &internal_time)) if (score_dict_->GetDouble(kLastMediaPlaybackTimeKey, &internal_time))
...@@ -120,14 +122,23 @@ MediaEngagementScore::MediaEngagementScore( ...@@ -120,14 +122,23 @@ MediaEngagementScore::MediaEngagementScore(
// or if we have data from before the bit was introduced. // or if we have data from before the bit was introduced.
bool was_high = is_high_; bool was_high = is_high_;
Recalculate(); Recalculate();
if (is_high_ != was_high) { bool needs_commit = is_high_ != was_high;
if (settings_map_) {
Commit(); // If we have a score for media playbacks and we do not have a value for
} else { // both media element playbacks and audio context playbacks then we should
// Update the internal dictionary for testing. // copy media playbacks into media element playbacks.
score_dict_->SetBoolean(kHasHighScoreKey, is_high_); bool has_new_playbacks_key_ =
} score_dict_->FindKey(kSignificantMediaPlaybacksKey) ||
score_dict_->FindKey(kSignificantAudioContextPlaybacksKey);
if (!has_new_playbacks_key_) {
media_element_playbacks_ = media_playbacks_;
needs_commit = true;
} }
// If we need to commit because of a migration and we have the settings map
// then we should commit.
if (needs_commit && settings_map_)
Commit();
} }
// TODO(beccahughes): Add typemap. // TODO(beccahughes): Add typemap.
...@@ -169,6 +180,8 @@ bool MediaEngagementScore::UpdateScoreDict() { ...@@ -169,6 +180,8 @@ bool MediaEngagementScore::UpdateScoreDict() {
int stored_significant_playbacks = 0; int stored_significant_playbacks = 0;
int stored_visits_with_media_tag = 0; int stored_visits_with_media_tag = 0;
int high_score_changes = 0; int high_score_changes = 0;
int stored_media_element_playbacks = 0;
int stored_audio_context_playbacks = 0;
score_dict_->GetInteger(kVisitsKey, &stored_visits); score_dict_->GetInteger(kVisitsKey, &stored_visits);
score_dict_->GetInteger(kMediaPlaybacksKey, &stored_media_playbacks); score_dict_->GetInteger(kMediaPlaybacksKey, &stored_media_playbacks);
...@@ -181,6 +194,10 @@ bool MediaEngagementScore::UpdateScoreDict() { ...@@ -181,6 +194,10 @@ bool MediaEngagementScore::UpdateScoreDict() {
score_dict_->GetInteger(kVisitsWithMediaTagKey, score_dict_->GetInteger(kVisitsWithMediaTagKey,
&stored_visits_with_media_tag); &stored_visits_with_media_tag);
score_dict_->GetInteger(kHighScoreChanges, &high_score_changes); score_dict_->GetInteger(kHighScoreChanges, &high_score_changes);
score_dict_->GetInteger(kSignificantMediaPlaybacksKey,
&stored_media_element_playbacks);
score_dict_->GetInteger(kSignificantAudioContextPlaybacksKey,
&stored_audio_context_playbacks);
bool changed = stored_visits != visits() || bool changed = stored_visits != visits() ||
stored_media_playbacks != media_playbacks() || stored_media_playbacks != media_playbacks() ||
...@@ -188,6 +205,8 @@ bool MediaEngagementScore::UpdateScoreDict() { ...@@ -188,6 +205,8 @@ bool MediaEngagementScore::UpdateScoreDict() {
stored_audible_playbacks != audible_playbacks() || stored_audible_playbacks != audible_playbacks() ||
stored_significant_playbacks != significant_playbacks() || stored_significant_playbacks != significant_playbacks() ||
stored_visits_with_media_tag != visits_with_media_tag() || stored_visits_with_media_tag != visits_with_media_tag() ||
stored_media_element_playbacks != media_element_playbacks() ||
stored_audio_context_playbacks != audio_context_playbacks() ||
stored_last_media_playback_internal != stored_last_media_playback_internal !=
last_media_playback_time_.ToInternalValue(); last_media_playback_time_.ToInternalValue();
...@@ -210,6 +229,10 @@ bool MediaEngagementScore::UpdateScoreDict() { ...@@ -210,6 +229,10 @@ bool MediaEngagementScore::UpdateScoreDict() {
score_dict_->SetInteger(kSignificantPlaybacksKey, significant_playbacks_); score_dict_->SetInteger(kSignificantPlaybacksKey, significant_playbacks_);
score_dict_->SetInteger(kVisitsWithMediaTagKey, visits_with_media_tag_); score_dict_->SetInteger(kVisitsWithMediaTagKey, visits_with_media_tag_);
score_dict_->SetInteger(kHighScoreChanges, high_score_changes_); score_dict_->SetInteger(kHighScoreChanges, high_score_changes_);
score_dict_->SetInteger(kSignificantMediaPlaybacksKey,
media_element_playbacks_);
score_dict_->SetInteger(kSignificantAudioContextPlaybacksKey,
audio_context_playbacks_);
return true; return true;
} }
......
...@@ -28,6 +28,11 @@ class MediaEngagementScore final { ...@@ -28,6 +28,11 @@ class MediaEngagementScore final {
// kSignificantPlaybacksKey will store the number of significant playbacks // kSignificantPlaybacksKey will store the number of significant playbacks
// on an origin. kVisitsWithMediaTagKey will store the number of visits to // on an origin. kVisitsWithMediaTagKey will store the number of visits to
// an origin where at least one page had a media tag. // an origin where at least one page had a media tag.
// kSignificantMediaPlaybacksKey will store significant playbacks that
// originated from media elements and kSignificantAudioContextPlaybacksKey
// will store significant playbacks originated from audio contexts. The
// sum of the two may be higher than kMediaPlaybacksKey as a visit may have
// both an audio context playback and a media element playback.
static const char kVisitsKey[]; static const char kVisitsKey[];
static const char kMediaPlaybacksKey[]; static const char kMediaPlaybacksKey[];
static const char kLastMediaPlaybackTimeKey[]; static const char kLastMediaPlaybackTimeKey[];
...@@ -36,6 +41,8 @@ class MediaEngagementScore final { ...@@ -36,6 +41,8 @@ class MediaEngagementScore final {
static const char kSignificantPlaybacksKey[]; static const char kSignificantPlaybacksKey[];
static const char kVisitsWithMediaTagKey[]; static const char kVisitsWithMediaTagKey[];
static const char kHighScoreChanges[]; static const char kHighScoreChanges[];
static const char kSignificantMediaPlaybacksKey[];
static const char kSignificantAudioContextPlaybacksKey[];
// Origins with a number of visits less than this number will recieve // Origins with a number of visits less than this number will recieve
// a score of zero. // a score of zero.
...@@ -102,6 +109,20 @@ class MediaEngagementScore final { ...@@ -102,6 +109,20 @@ class MediaEngagementScore final {
set_visits_with_media_tag(visits_with_media_tag_ + 1); set_visits_with_media_tag(visits_with_media_tag_ + 1);
} }
// Get/increment the number of significant playbacks from media elements this
// origin had.
int media_element_playbacks() const { return media_element_playbacks_; }
void IncrementMediaElementPlaybacks() {
set_media_element_playbacks(media_element_playbacks_ + 1);
}
// Get/increment the number of significant playbacks from audio contexts this
// origin had.
int audio_context_playbacks() const { return audio_context_playbacks_; }
void IncrementAudioContextPlaybacks() {
set_audio_context_playbacks(audio_context_playbacks_ + 1);
}
// Get a breakdown of the score that can be serialized by Mojo. // Get a breakdown of the score that can be serialized by Mojo.
media::mojom::MediaEngagementScoreDetailsPtr GetScoreDetails() const; media::mojom::MediaEngagementScoreDetailsPtr GetScoreDetails() const;
...@@ -134,16 +155,17 @@ class MediaEngagementScore final { ...@@ -134,16 +155,17 @@ class MediaEngagementScore final {
void set_last_media_playback_time(base::Time new_time) { void set_last_media_playback_time(base::Time new_time) {
last_media_playback_time_ = new_time; last_media_playback_time_ = new_time;
} }
void set_media_element_playbacks(int playbacks) {
media_element_playbacks_ = playbacks;
}
void set_audio_context_playbacks(int playbacks) {
audio_context_playbacks_ = playbacks;
}
private: private:
friend class MediaEngagementServiceTest; friend class MediaEngagementServiceTest;
friend class MediaEngagementScoreTest; friend class MediaEngagementScoreTest;
// Used for tests.
MediaEngagementScore(base::Clock* clock,
const GURL& origin,
std::unique_ptr<base::DictionaryValue> score_dict);
// Update the dictionary continaing the latest score values and return whether // Update the dictionary continaing the latest score values and return whether
// they have changed or not (since what was last retrieved from content // they have changed or not (since what was last retrieved from content
// settings). // settings).
...@@ -180,6 +202,12 @@ class MediaEngagementScore final { ...@@ -180,6 +202,12 @@ class MediaEngagementScore final {
// The last time media was played back on this origin. // The last time media was played back on this origin.
base::Time last_media_playback_time_; base::Time last_media_playback_time_;
// The number of significant playbacks from a media element this origin had.
int media_element_playbacks_ = 0;
// The number of significant playbacks from an audio context this origin had.
int audio_context_playbacks_ = 0;
// The origin this score represents. // The origin this score represents.
GURL origin_; GURL origin_;
......
...@@ -69,7 +69,9 @@ class MediaEngagementScoreTest : public ChromeRenderViewHostTestHarness { ...@@ -69,7 +69,9 @@ class MediaEngagementScoreTest : public ChromeRenderViewHostTestHarness {
int audible_playbacks, int audible_playbacks,
int significant_playbacks, int significant_playbacks,
int visits_with_media_tag, int visits_with_media_tag,
int high_score_changes) { int high_score_changes,
int media_element_playbacks,
int audio_context_playbacks) {
EXPECT_EQ(expected_visits, score->visits()); EXPECT_EQ(expected_visits, score->visits());
EXPECT_EQ(expected_media_playbacks, score->media_playbacks()); EXPECT_EQ(expected_media_playbacks, score->media_playbacks());
EXPECT_EQ(expected_last_media_playback_time, EXPECT_EQ(expected_last_media_playback_time,
...@@ -79,6 +81,8 @@ class MediaEngagementScoreTest : public ChromeRenderViewHostTestHarness { ...@@ -79,6 +81,8 @@ class MediaEngagementScoreTest : public ChromeRenderViewHostTestHarness {
EXPECT_EQ(significant_playbacks, score->significant_playbacks()); EXPECT_EQ(significant_playbacks, score->significant_playbacks());
EXPECT_EQ(visits_with_media_tag, score->visits_with_media_tag()); EXPECT_EQ(visits_with_media_tag, score->visits_with_media_tag());
EXPECT_EQ(high_score_changes, score->high_score_changes()); EXPECT_EQ(high_score_changes, score->high_score_changes());
EXPECT_EQ(media_element_playbacks, score->media_element_playbacks());
EXPECT_EQ(audio_context_playbacks, score->audio_context_playbacks());
} }
void UpdateScore(MediaEngagementScore* score) { void UpdateScore(MediaEngagementScore* score) {
...@@ -89,6 +93,8 @@ class MediaEngagementScoreTest : public ChromeRenderViewHostTestHarness { ...@@ -89,6 +93,8 @@ class MediaEngagementScoreTest : public ChromeRenderViewHostTestHarness {
score->IncrementAudiblePlaybacks(1); score->IncrementAudiblePlaybacks(1);
score->IncrementSignificantPlaybacks(1); score->IncrementSignificantPlaybacks(1);
score->IncrementVisitsWithMediaTag(); score->IncrementVisitsWithMediaTag();
score->IncrementMediaElementPlaybacks();
score->IncrementAudioContextPlaybacks();
} }
void TestScoreInitializesAndUpdates( void TestScoreInitializesAndUpdates(
...@@ -100,13 +106,16 @@ class MediaEngagementScoreTest : public ChromeRenderViewHostTestHarness { ...@@ -100,13 +106,16 @@ class MediaEngagementScoreTest : public ChromeRenderViewHostTestHarness {
int audible_playbacks, int audible_playbacks,
int significant_playbacks, int significant_playbacks,
int visits_with_media_tag, int visits_with_media_tag,
int high_score_changes) { int high_score_changes,
MediaEngagementScore* initial_score = int media_element_playbacks,
new MediaEngagementScore(&test_clock, GURL(), std::move(score_dict)); int audio_context_playbacks) {
MediaEngagementScore* initial_score = new MediaEngagementScore(
&test_clock, GURL(), std::move(score_dict), nullptr /* settings */);
VerifyScore(initial_score, expected_visits, expected_media_playbacks, VerifyScore(initial_score, expected_visits, expected_media_playbacks,
expected_last_media_playback_time, has_high_score, expected_last_media_playback_time, has_high_score,
audible_playbacks, significant_playbacks, visits_with_media_tag, audible_playbacks, significant_playbacks, visits_with_media_tag,
high_score_changes); high_score_changes, media_element_playbacks,
audio_context_playbacks);
// Updating the score dict should return false, as the score shouldn't // Updating the score dict should return false, as the score shouldn't
// have changed at this point. // have changed at this point.
...@@ -197,7 +206,7 @@ TEST_F(MediaEngagementScoreTest, MojoSerialization) { ...@@ -197,7 +206,7 @@ TEST_F(MediaEngagementScoreTest, MojoSerialization) {
TEST_F(MediaEngagementScoreTest, EmptyDictionary) { TEST_F(MediaEngagementScoreTest, EmptyDictionary) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
TestScoreInitializesAndUpdates(std::move(dict), 0, 0, base::Time(), false, 0, TestScoreInitializesAndUpdates(std::move(dict), 0, 0, base::Time(), false, 0,
0, 0, 0); 0, 0, 0, 0, 0);
} }
// Test that scores are read / written correctly from / to partially empty // Test that scores are read / written correctly from / to partially empty
...@@ -207,7 +216,7 @@ TEST_F(MediaEngagementScoreTest, PartiallyEmptyDictionary) { ...@@ -207,7 +216,7 @@ TEST_F(MediaEngagementScoreTest, PartiallyEmptyDictionary) {
dict->SetInteger(MediaEngagementScore::kVisitsKey, 2); dict->SetInteger(MediaEngagementScore::kVisitsKey, 2);
TestScoreInitializesAndUpdates(std::move(dict), 2, 0, base::Time(), false, 0, TestScoreInitializesAndUpdates(std::move(dict), 2, 0, base::Time(), false, 0,
0, 0, 0); 0, 0, 0, 0, 0);
} }
// Test that scores are read / written correctly from / to populated score // Test that scores are read / written correctly from / to populated score
...@@ -223,9 +232,12 @@ TEST_F(MediaEngagementScoreTest, PopulatedDictionary) { ...@@ -223,9 +232,12 @@ TEST_F(MediaEngagementScoreTest, PopulatedDictionary) {
dict->SetInteger(MediaEngagementScore::kSignificantPlaybacksKey, 4); dict->SetInteger(MediaEngagementScore::kSignificantPlaybacksKey, 4);
dict->SetInteger(MediaEngagementScore::kVisitsWithMediaTagKey, 6); dict->SetInteger(MediaEngagementScore::kVisitsWithMediaTagKey, 6);
dict->SetInteger(MediaEngagementScore::kHighScoreChanges, 3); dict->SetInteger(MediaEngagementScore::kHighScoreChanges, 3);
dict->SetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey, 1);
dict->SetInteger(MediaEngagementScore::kSignificantAudioContextPlaybacksKey,
2);
TestScoreInitializesAndUpdates(std::move(dict), 20, 12, test_clock.Now(), TestScoreInitializesAndUpdates(std::move(dict), 20, 12, test_clock.Now(),
true, 2, 4, 6, 3); true, 2, 4, 6, 3, 1, 2);
} }
// Test getting and commiting the score works correctly with different // Test getting and commiting the score works correctly with different
...@@ -241,7 +253,7 @@ TEST_F(MediaEngagementScoreTest, ContentSettingsMultiOrigin) { ...@@ -241,7 +253,7 @@ TEST_F(MediaEngagementScoreTest, ContentSettingsMultiOrigin) {
// Verify the score is originally zero, try incrementing and storing // Verify the score is originally zero, try incrementing and storing
// the score. // the score.
VerifyScore(score, 0, 0, base::Time(), false, 0, 0, 0, 0); VerifyScore(score, 0, 0, base::Time(), false, 0, 0, 0, 0, 0, 0);
score->IncrementVisits(); score->IncrementVisits();
UpdateScore(score); UpdateScore(score);
score->Commit(); score->Commit();
...@@ -256,9 +268,11 @@ TEST_F(MediaEngagementScoreTest, ContentSettingsMultiOrigin) { ...@@ -256,9 +268,11 @@ TEST_F(MediaEngagementScoreTest, ContentSettingsMultiOrigin) {
new MediaEngagementScore(&test_clock, same_origin, settings_map); new MediaEngagementScore(&test_clock, same_origin, settings_map);
MediaEngagementScore* different_origin_score = MediaEngagementScore* different_origin_score =
new MediaEngagementScore(&test_clock, different_origin, settings_map); new MediaEngagementScore(&test_clock, different_origin, settings_map);
VerifyScore(new_score, 2, 1, test_clock.Now(), false, 1, 1, 1, 0); VerifyScore(new_score, 2, 1, test_clock.Now(), false, 1, 1, 1, 0, 1, 1);
VerifyScore(same_origin_score, 2, 1, test_clock.Now(), false, 1, 1, 1, 0); VerifyScore(same_origin_score, 2, 1, test_clock.Now(), false, 1, 1, 1, 0, 1,
VerifyScore(different_origin_score, 0, 0, base::Time(), false, 0, 0, 0, 0); 1);
VerifyScore(different_origin_score, 0, 0, base::Time(), false, 0, 0, 0, 0, 0,
0);
delete score; delete score;
delete new_score; delete new_score;
...@@ -276,6 +290,8 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) { ...@@ -276,6 +290,8 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) {
int example_significant_playbacks = 5; int example_significant_playbacks = 5;
int example_visits_with_media_tags = 20; int example_visits_with_media_tags = 20;
int example_high_score_changes = 1; int example_high_score_changes = 1;
int example_media_element_playbacks = 1;
int example_audio_context_playbacks = 3;
// Store some example data in content settings. // Store some example data in content settings.
GURL origin("https://www.google.com"); GURL origin("https://www.google.com");
...@@ -295,6 +311,11 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) { ...@@ -295,6 +311,11 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) {
example_visits_with_media_tags); example_visits_with_media_tags);
score_dict->SetInteger(MediaEngagementScore::kHighScoreChanges, score_dict->SetInteger(MediaEngagementScore::kHighScoreChanges,
example_high_score_changes); example_high_score_changes);
score_dict->SetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey,
example_media_element_playbacks);
score_dict->SetInteger(
MediaEngagementScore::kSignificantAudioContextPlaybacksKey,
example_audio_context_playbacks);
settings_map->SetWebsiteSettingDefaultScope( settings_map->SetWebsiteSettingDefaultScope(
origin, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT, origin, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
content_settings::ResourceIdentifier(), std::move(score_dict)); content_settings::ResourceIdentifier(), std::move(score_dict));
...@@ -311,6 +332,8 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) { ...@@ -311,6 +332,8 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) {
EXPECT_EQ(score->visits_with_media_tag(), example_visits_with_media_tags); EXPECT_EQ(score->visits_with_media_tag(), example_visits_with_media_tags);
EXPECT_EQ(score->visits_with_media_tag(), example_visits_with_media_tags); EXPECT_EQ(score->visits_with_media_tag(), example_visits_with_media_tags);
EXPECT_EQ(score->high_score_changes(), example_high_score_changes); EXPECT_EQ(score->high_score_changes(), example_high_score_changes);
EXPECT_EQ(score->media_element_playbacks(), example_media_element_playbacks);
EXPECT_EQ(score->audio_context_playbacks(), example_audio_context_playbacks);
UpdateScore(score); UpdateScore(score);
score->IncrementMediaPlaybacks(); score->IncrementMediaPlaybacks();
...@@ -326,6 +349,8 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) { ...@@ -326,6 +349,8 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) {
int stored_significant_playbacks; int stored_significant_playbacks;
int stored_visits_with_media_tag; int stored_visits_with_media_tag;
int stored_high_score_changes; int stored_high_score_changes;
int stored_media_element_playbacks;
int stored_audio_context_playbacks;
std::unique_ptr<base::DictionaryValue> values = std::unique_ptr<base::DictionaryValue> values =
base::DictionaryValue::From(settings_map->GetWebsiteSetting( base::DictionaryValue::From(settings_map->GetWebsiteSetting(
origin, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT, origin, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
...@@ -345,6 +370,10 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) { ...@@ -345,6 +370,10 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) {
&stored_visits_with_media_tag); &stored_visits_with_media_tag);
values->GetInteger(MediaEngagementScore::kHighScoreChanges, values->GetInteger(MediaEngagementScore::kHighScoreChanges,
&stored_high_score_changes); &stored_high_score_changes);
values->GetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey,
&stored_media_element_playbacks);
values->GetInteger(MediaEngagementScore::kSignificantAudioContextPlaybacksKey,
&stored_audio_context_playbacks);
EXPECT_EQ(stored_visits, example_num_visits + 1); EXPECT_EQ(stored_visits, example_num_visits + 1);
EXPECT_EQ(stored_media_playbacks, example_media_playbacks + 2); EXPECT_EQ(stored_media_playbacks, example_media_playbacks + 2);
EXPECT_EQ(stored_last_media_playback_time, EXPECT_EQ(stored_last_media_playback_time,
...@@ -354,6 +383,10 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) { ...@@ -354,6 +383,10 @@ TEST_F(MediaEngagementScoreTest, ContentSettings) {
EXPECT_EQ(stored_visits_with_media_tag, example_visits_with_media_tags + 1); EXPECT_EQ(stored_visits_with_media_tag, example_visits_with_media_tags + 1);
EXPECT_TRUE(stored_has_high_score); EXPECT_TRUE(stored_has_high_score);
EXPECT_EQ(stored_high_score_changes, example_high_score_changes + 1); EXPECT_EQ(stored_high_score_changes, example_high_score_changes + 1);
EXPECT_EQ(stored_media_element_playbacks,
example_media_element_playbacks + 1);
EXPECT_EQ(stored_audio_context_playbacks,
example_audio_context_playbacks + 1);
delete score; delete score;
} }
...@@ -374,32 +407,87 @@ TEST_F(MediaEngagementScoreTest, EngagementScoreCalculation) { ...@@ -374,32 +407,87 @@ TEST_F(MediaEngagementScoreTest, EngagementScoreCalculation) {
} }
// Test that a score without the high_score bit uses the correct bounds. // Test that a score without the high_score bit uses the correct bounds.
TEST_F(MediaEngagementScoreTest, HighScoreLegacy) { TEST_F(MediaEngagementScoreTest, HighScoreLegacy_High) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); const GURL url("https://www.example.com");
dict->SetInteger(MediaEngagementScore::kVisitsKey, 20); HostContentSettingsMap* settings_map =
dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, 6); HostContentSettingsMapFactory::GetForProfile(profile());
TestScoreInitializesAndUpdates(std::move(dict), 20, 6, base::Time(), true, 0,
0, 0, 0); {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
std::unique_ptr<base::DictionaryValue> dict2(new base::DictionaryValue()); dict->SetInteger(MediaEngagementScore::kVisitsKey, 20);
dict2->SetInteger(MediaEngagementScore::kVisitsKey, 20); dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, 6);
dict2->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, 4); settings_map->SetWebsiteSettingDefaultScope(
TestScoreInitializesAndUpdates(std::move(dict2), 20, 4, base::Time(), false, url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
0, 0, 0, 0); content_settings::ResourceIdentifier(), std::move(dict));
}
{
std::unique_ptr<MediaEngagementScore> score(
new MediaEngagementScore(&test_clock, url, settings_map));
VerifyScore(score.get(), 20, 6, base::Time(), true, 0, 0, 0, 1, 6, 0);
}
}
// Test that a score without the high_score bit uses the correct bounds.
TEST_F(MediaEngagementScoreTest, HighScoreLegacy_Low) {
const GURL url("https://www.example.com");
HostContentSettingsMap* settings_map =
HostContentSettingsMapFactory::GetForProfile(profile());
{
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger(MediaEngagementScore::kVisitsKey, 20);
dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, 4);
settings_map->SetWebsiteSettingDefaultScope(
url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
content_settings::ResourceIdentifier(), std::move(dict));
}
{
std::unique_ptr<MediaEngagementScore> score(
new MediaEngagementScore(&test_clock, url, settings_map));
VerifyScore(score.get(), 20, 4, base::Time(), false, 0, 0, 0, 0, 4, 0);
}
} }
// Test that if we changed the boundaries the high_score bit is updated // Test that if we changed the boundaries the high_score bit is updated
// when the score is loaded. // when the score is loaded.
TEST_F(MediaEngagementScoreTest, HighScoreUpdated) { TEST_F(MediaEngagementScoreTest, HighScoreUpdated) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); const GURL url("https://www.example.com");
dict->SetInteger(MediaEngagementScore::kVisitsKey, 10); HostContentSettingsMap* settings_map =
dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, 1); HostContentSettingsMapFactory::GetForProfile(profile());
dict->SetDouble(MediaEngagementScore::kLastMediaPlaybackTimeKey,
test_clock.Now().ToInternalValue());
dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, true);
TestScoreInitializesAndUpdates(std::move(dict), 10, 1, test_clock.Now(), {
false, 0, 0, 0, 0); std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger(MediaEngagementScore::kVisitsKey, 10);
dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, 1);
dict->SetDouble(MediaEngagementScore::kLastMediaPlaybackTimeKey,
test_clock.Now().ToInternalValue());
dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, true);
settings_map->SetWebsiteSettingDefaultScope(
url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
content_settings::ResourceIdentifier(), std::move(dict));
}
{
std::unique_ptr<MediaEngagementScore> score(
new MediaEngagementScore(&test_clock, url, settings_map));
EXPECT_FALSE(score->high_score());
base::RunLoop().RunUntilIdle();
}
{
std::unique_ptr<base::DictionaryValue> dict =
base::DictionaryValue::From(settings_map->GetWebsiteSetting(
url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
content_settings::ResourceIdentifier(), nullptr));
bool stored_high_score = false;
dict->GetBoolean(MediaEngagementScore::kHasHighScoreKey,
&stored_high_score);
EXPECT_FALSE(stored_high_score);
}
} }
// Test that the has high score upper and lower thresholds work. // Test that the has high score upper and lower thresholds work.
...@@ -491,3 +579,143 @@ TEST_F(MediaEngagementScoreTest, HighScoreChanges) { ...@@ -491,3 +579,143 @@ TEST_F(MediaEngagementScoreTest, HighScoreChanges) {
EXPECT_EQ(2, score->high_score_changes()); EXPECT_EQ(2, score->high_score_changes());
} }
} }
// Test that we migrate the media playbacks value to media element playbacks.
TEST_F(MediaEngagementScoreTest, MigrateMediaElementPlaybacks) {
const GURL url("https://www.example.com");
HostContentSettingsMap* settings_map =
HostContentSettingsMapFactory::GetForProfile(profile());
int media_playbacks = 6;
{
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, true);
dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, media_playbacks);
settings_map->SetWebsiteSettingDefaultScope(
url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
content_settings::ResourceIdentifier(), std::move(dict));
}
{
std::unique_ptr<MediaEngagementScore> score(
new MediaEngagementScore(&test_clock, url, settings_map));
EXPECT_EQ(media_playbacks, score->media_playbacks());
EXPECT_EQ(media_playbacks, score->media_element_playbacks());
base::RunLoop().RunUntilIdle();
}
{
std::unique_ptr<base::DictionaryValue> dict =
base::DictionaryValue::From(settings_map->GetWebsiteSetting(
url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
content_settings::ResourceIdentifier(), nullptr));
int stored_media_playbacks = 0;
int stored_media_element_playbacks = 0;
dict->GetInteger(MediaEngagementScore::kMediaPlaybacksKey,
&stored_media_playbacks);
dict->GetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey,
&stored_media_element_playbacks);
EXPECT_EQ(media_playbacks, stored_media_playbacks);
EXPECT_EQ(media_playbacks, stored_media_element_playbacks);
}
}
// Test that we do not migrate media element playbacks if we have an audio
// context playback.
TEST_F(MediaEngagementScoreTest,
NoMigrateMediaElementPlaybacks_AudioContextPresent) {
const GURL url("https://www.example.com");
HostContentSettingsMap* settings_map =
HostContentSettingsMapFactory::GetForProfile(profile());
int media_playbacks = 6;
int audio_context_playbacks = 3;
{
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, true);
dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, media_playbacks);
dict->SetInteger(MediaEngagementScore::kSignificantAudioContextPlaybacksKey,
audio_context_playbacks);
settings_map->SetWebsiteSettingDefaultScope(
url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
content_settings::ResourceIdentifier(), std::move(dict));
}
{
std::unique_ptr<MediaEngagementScore> score(
new MediaEngagementScore(&test_clock, url, settings_map));
EXPECT_EQ(media_playbacks, score->media_playbacks());
EXPECT_EQ(0, score->media_element_playbacks());
EXPECT_EQ(audio_context_playbacks, score->audio_context_playbacks());
base::RunLoop().RunUntilIdle();
}
{
std::unique_ptr<base::DictionaryValue> dict =
base::DictionaryValue::From(settings_map->GetWebsiteSetting(
url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
content_settings::ResourceIdentifier(), nullptr));
EXPECT_NE(nullptr, dict->FindKey(MediaEngagementScore::kMediaPlaybacksKey));
EXPECT_EQ(
nullptr,
dict->FindKey(MediaEngagementScore::kSignificantMediaPlaybacksKey));
}
}
// Test that we do not migrate media element playbacks if we have a media
// element playback.
TEST_F(MediaEngagementScoreTest,
NoMigrateMediaElementPlaybacks_MediaElementPresent) {
const GURL url("https://www.example.com");
HostContentSettingsMap* settings_map =
HostContentSettingsMapFactory::GetForProfile(profile());
int media_playbacks = 6;
int media_element_playbacks = 3;
{
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, true);
dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, media_playbacks);
dict->SetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey,
media_element_playbacks);
settings_map->SetWebsiteSettingDefaultScope(
url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
content_settings::ResourceIdentifier(), std::move(dict));
}
{
std::unique_ptr<MediaEngagementScore> score(
new MediaEngagementScore(&test_clock, url, settings_map));
EXPECT_EQ(media_playbacks, score->media_playbacks());
EXPECT_EQ(media_element_playbacks, score->media_element_playbacks());
base::RunLoop().RunUntilIdle();
}
{
std::unique_ptr<base::DictionaryValue> dict =
base::DictionaryValue::From(settings_map->GetWebsiteSetting(
url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
content_settings::ResourceIdentifier(), nullptr));
int stored_media_playbacks = 0;
int stored_media_element_playbacks = 0;
dict->GetInteger(MediaEngagementScore::kMediaPlaybacksKey,
&stored_media_playbacks);
dict->GetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey,
&stored_media_element_playbacks);
EXPECT_EQ(media_playbacks, stored_media_playbacks);
EXPECT_EQ(media_element_playbacks, stored_media_element_playbacks);
}
}
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