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

[Media Engagement] Track AudioContext playbacks

Adds AudioContext player tracking to MediaEngagementContentsObserver
with it's own page level timer. On MediaEngagementSession this CL
seperates significant playback into media element playback and
audio context playback. Since we may record a playback we need to
disable committing on significant playback and just record on
destroy or navigate instead.

BUG=878460

Change-Id: Ic66152f8cb5b3a6338804c04de7dd0bf5c1cb154
Reviewed-on: https://chromium-review.googlesource.com/1194992
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587899}
parent b3b25596
......@@ -337,7 +337,7 @@ class MediaEngagementPreloadBrowserTest : public InProcessBrowserTest {
IN_PROC_BROWSER_TEST_F(MediaEngagementBrowserTest, RecordEngagement) {
LoadTestPageAndWaitForPlayAndAudible("engagement_test.html", false);
AdvanceMeaningfulPlaybackTime();
ExpectScores(1, 1, 0, 0);
ExpectScores(0, 0, 0, 0);
CloseTab();
ExpectScores(1, 1, 1, 1);
}
......
......@@ -122,6 +122,8 @@ void MediaEngagementContentsObserver::ClearPlayerStates() {
playback_timer_.Stop();
player_states_.clear();
significant_players_.clear();
audio_context_players_.clear();
audio_context_timer_.Stop();
}
void MediaEngagementContentsObserver::RegisterAudiblePlayersWithSession() {
......@@ -270,8 +272,21 @@ void MediaEngagementContentsObserver::MediaStoppedPlaying(
UpdatePlayerTimer(media_player_id);
}
void MediaEngagementContentsObserver::AudioContextPlaybackStarted(
const AudioContextId& audio_context_id) {
audio_context_players_.insert(audio_context_id);
UpdateAudioContextTimer();
}
void MediaEngagementContentsObserver::AudioContextPlaybackStopped(
const AudioContextId& audio_context_id) {
audio_context_players_.erase(audio_context_id);
UpdateAudioContextTimer();
}
void MediaEngagementContentsObserver::DidUpdateAudioMutingState(bool muted) {
UpdatePageTimer();
UpdateAudioContextTimer();
}
std::vector<MediaEngagementContentsObserver::InsignificantPlaybackReason>
......@@ -330,7 +345,23 @@ void MediaEngagementContentsObserver::OnSignificantMediaPlaybackTimeForPlayer(
void MediaEngagementContentsObserver::OnSignificantMediaPlaybackTimeForPage() {
DCHECK(session_);
if (session_->significant_playback_recorded())
if (session_->significant_media_element_playback_recorded())
return;
// Do not record significant playback if the tab did not make
// a sound recently.
auto* audible_helper = RecentlyAudibleHelper::FromWebContents(web_contents());
if (!audible_helper->WasRecentlyAudible())
return;
session_->RecordSignificantMediaElementPlayback();
}
void MediaEngagementContentsObserver::
OnSignificantAudioContextPlaybackTimeForPage() {
DCHECK(session_);
if (session_->significant_audio_context_playback_recorded())
return;
// Do not record significant playback if the tab did not make
......@@ -339,7 +370,7 @@ void MediaEngagementContentsObserver::OnSignificantMediaPlaybackTimeForPage() {
if (!audible_helper->WasRecentlyAudible())
return;
session_->RecordSignificantPlayback();
session_->RecordSignificantAudioContextPlayback();
}
void MediaEngagementContentsObserver::RecordInsignificantReasons(
......@@ -474,7 +505,7 @@ bool MediaEngagementContentsObserver::AreConditionsMet() const {
}
void MediaEngagementContentsObserver::UpdatePageTimer() {
if (!session_ || session_->significant_playback_recorded())
if (!session_ || session_->significant_media_element_playback_recorded())
return;
if (AreConditionsMet()) {
......@@ -497,6 +528,35 @@ void MediaEngagementContentsObserver::UpdatePageTimer() {
}
}
bool MediaEngagementContentsObserver::AreAudioContextConditionsMet() const {
if (audio_context_players_.empty())
return false;
return !web_contents()->IsAudioMuted();
}
void MediaEngagementContentsObserver::UpdateAudioContextTimer() {
if (!session_ || session_->significant_audio_context_playback_recorded())
return;
if (AreAudioContextConditionsMet()) {
if (audio_context_timer_.IsRunning())
return;
if (task_runner_)
audio_context_timer_.SetTaskRunner(task_runner_);
audio_context_timer_.Start(
FROM_HERE,
MediaEngagementContentsObserver::kSignificantMediaPlaybackTime,
base::Bind(&MediaEngagementContentsObserver::
OnSignificantAudioContextPlaybackTimeForPage,
base::Unretained(this)));
} else if (audio_context_timer_.IsRunning()) {
audio_context_timer_.Stop();
}
}
void MediaEngagementContentsObserver::SetTaskRunnerForTest(
scoped_refptr<base::SequencedTaskRunner> task_runner) {
task_runner_ = std::move(task_runner);
......
......@@ -39,6 +39,10 @@ class MediaEngagementContentsObserver : public content::WebContentsObserver {
void DidUpdateAudioMutingState(bool muted) override;
void MediaMutedStatusChanged(const MediaPlayerId& id, bool muted) override;
void MediaResized(const gfx::Size& size, const MediaPlayerId& id) override;
void AudioContextPlaybackStarted(
const AudioContextId& audio_context_id) override;
void AudioContextPlaybackStopped(
const AudioContextId& audio_context_id) override;
static const gfx::Size kSignificantSize;
static const char* const kHistogramScoreAtPlaybackName;
......@@ -96,9 +100,14 @@ class MediaEngagementContentsObserver : public content::WebContentsObserver {
void OnSignificantMediaPlaybackTimeForPlayer(const MediaPlayerId& id);
void OnSignificantMediaPlaybackTimeForPage();
void OnSignificantAudioContextPlaybackTimeForPage();
void UpdatePlayerTimer(const MediaPlayerId&);
void UpdatePageTimer();
void UpdateAudioContextTimer();
bool AreConditionsMet() const;
bool AreAudioContextConditionsMet() const;
void SetTaskRunnerForTest(scoped_refptr<base::SequencedTaskRunner>);
......@@ -114,6 +123,13 @@ class MediaEngagementContentsObserver : public content::WebContentsObserver {
// significant playback.
std::set<MediaPlayerId> significant_players_;
// Timer that will fire when the playback time of any audio context reaches
// the minimum for significant media playback.
base::OneShotTimer audio_context_timer_;
// Set of active audio contexts that can produce a significant playback.
std::set<AudioContextId> audio_context_players_;
// Measures playback time for a player.
class PlaybackTimer {
public:
......
......@@ -61,6 +61,9 @@ class MediaEngagementContentsObserverTest
contents_observer_->SetTaskRunnerForTest(task_runner_);
SimulateInaudible();
// Advance the test clock to a non-null value.
Advance15Minutes();
}
void TearDown() override {
......@@ -89,10 +92,19 @@ class MediaEngagementContentsObserverTest
audible_row->second.second;
}
bool IsAudioContextTimerRunning() const {
return contents_observer_->audio_context_timer_.IsRunning();
}
bool HasSession() const { return !!contents_observer_->session_; }
bool WasSignificantPlaybackRecorded() const {
return contents_observer_->session_->significant_playback_recorded();
return contents_observer_->session_->WasSignificantPlaybackRecorded();
}
bool WasSignificantAudioContextPlaybackRecorded() const {
return contents_observer_->session_
->significant_audio_context_playback_recorded();
}
size_t GetSignificantActivePlayersCount() const {
......@@ -103,6 +115,10 @@ class MediaEngagementContentsObserverTest
return contents_observer_->player_states_.size();
}
size_t GetAudioContextPlayersCount() const {
return contents_observer_->audio_context_players_.size();
}
void SimulatePlaybackStarted(int id, bool has_audio, bool has_video) {
content::WebContentsObserver::MediaPlayerInfo player_info(has_video,
has_audio);
......@@ -167,18 +183,38 @@ class MediaEngagementContentsObserverTest
contents_observer_->OnVisibilityChanged(content::Visibility::HIDDEN);
}
void SimulateAudioContextStarted(int id) {
content::WebContentsObserver::AudioContextId player_id(
nullptr /* RenderFrameHost */, id);
contents_observer_->AudioContextPlaybackStarted(player_id);
}
void SimulateAudioContextStopped(int id) {
content::WebContentsObserver::AudioContextId player_id(
nullptr /* RenderFrameHost */, id);
contents_observer_->AudioContextPlaybackStopped(player_id);
}
bool AreConditionsMet() const {
return contents_observer_->AreConditionsMet();
}
void SimulateSignificantPlaybackRecorded() {
contents_observer_->session_->RecordSignificantPlayback();
bool AreAudioContextConditionsMet() const {
return contents_observer_->AreAudioContextConditionsMet();
}
void SimulateSignificantPlaybackTimeForPage() {
void SimulateSignificantMediaElementPlaybackRecorded() {
contents_observer_->session_->RecordSignificantMediaElementPlayback();
}
void SimulateSignificantMediaElementPlaybackTimeForPage() {
contents_observer_->OnSignificantMediaPlaybackTimeForPage();
}
void SimulateSignificantAudioContextPlaybackRecorded() {
contents_observer_->OnSignificantAudioContextPlaybackTimeForPage();
}
void SimulateSignificantPlaybackTimeForPlayer(int id) {
SimulateLongMediaPlayback(id);
content::WebContentsObserver::MediaPlayerId player_id(
......@@ -190,12 +226,18 @@ class MediaEngagementContentsObserverTest
task_runner_->FastForwardBy(kMaxWaitingTime);
}
void SimulateAudioContextPlaybackTimerFired() {
task_runner_->FastForwardBy(kMaxWaitingTime);
}
void ExpectScores(GURL url,
double expected_score,
int expected_visits,
int expected_media_playbacks,
int expected_audible_playbacks,
int expected_significant_playbacks) {
int expected_significant_playbacks,
int expected_media_element_playbacks,
int expected_audio_context_playbacks) {
EXPECT_EQ(service_->GetEngagementScore(url), expected_score);
EXPECT_EQ(service_->GetScoreMapForTesting()[url], expected_score);
......@@ -204,6 +246,10 @@ class MediaEngagementContentsObserverTest
EXPECT_EQ(expected_media_playbacks, score.media_playbacks());
EXPECT_EQ(expected_audible_playbacks, score.audible_playbacks());
EXPECT_EQ(expected_significant_playbacks, score.significant_playbacks());
EXPECT_EQ(expected_media_element_playbacks,
score.media_element_playbacks());
EXPECT_EQ(expected_audio_context_playbacks,
score.audio_context_playbacks());
}
void SetScores(GURL url,
......@@ -429,77 +475,124 @@ class MediaEngagementContentsObserverTest
TEST_F(MediaEngagementContentsObserverTest, SignificantActivePlayerCount) {
EXPECT_EQ(0u, GetSignificantActivePlayersCount());
EXPECT_EQ(0u, GetAudioContextPlayersCount());
SimulateAudioVideoPlaybackStarted(0);
SimulateResizeEventSignificantSize(0);
EXPECT_EQ(1u, GetSignificantActivePlayersCount());
EXPECT_EQ(0u, GetAudioContextPlayersCount());
SimulateAudioVideoPlaybackStarted(1);
SimulateResizeEventSignificantSize(1);
EXPECT_EQ(2u, GetSignificantActivePlayersCount());
EXPECT_EQ(0u, GetAudioContextPlayersCount());
SimulateAudioVideoPlaybackStarted(2);
SimulateResizeEventSignificantSize(2);
EXPECT_EQ(3u, GetSignificantActivePlayersCount());
EXPECT_EQ(0u, GetAudioContextPlayersCount());
SimulatePlaybackStopped(1);
EXPECT_EQ(2u, GetSignificantActivePlayersCount());
EXPECT_EQ(0u, GetAudioContextPlayersCount());
SimulatePlaybackStopped(0);
EXPECT_EQ(1u, GetSignificantActivePlayersCount());
EXPECT_EQ(0u, GetAudioContextPlayersCount());
SimulateResizeEvent(2, gfx::Size(1, 1));
EXPECT_EQ(0u, GetSignificantActivePlayersCount());
EXPECT_EQ(0u, GetAudioContextPlayersCount());
SimulateSignificantAudioPlayer(3);
EXPECT_EQ(1u, GetSignificantActivePlayersCount());
EXPECT_EQ(0u, GetAudioContextPlayersCount());
SimulateAudioContextStarted(0);
EXPECT_EQ(1u, GetSignificantActivePlayersCount());
EXPECT_EQ(1u, GetAudioContextPlayersCount());
SimulateAudioContextStarted(1);
EXPECT_EQ(1u, GetSignificantActivePlayersCount());
EXPECT_EQ(2u, GetAudioContextPlayersCount());
SimulateAudioContextStopped(0);
EXPECT_EQ(1u, GetSignificantActivePlayersCount());
EXPECT_EQ(1u, GetAudioContextPlayersCount());
}
TEST_F(MediaEngagementContentsObserverTest, AreConditionsMet) {
EXPECT_FALSE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateSignificantVideoPlayer(0);
EXPECT_TRUE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateResizeEvent(0, gfx::Size(1, 1));
EXPECT_FALSE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateResizeEventSignificantSize(0);
EXPECT_TRUE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateResizeEvent(
0,
gfx::Size(MediaEngagementContentsObserver::kSignificantSize.width(), 1));
EXPECT_FALSE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateResizeEvent(
0,
gfx::Size(1, MediaEngagementContentsObserver::kSignificantSize.height()));
EXPECT_FALSE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateResizeEventSignificantSize(0);
web_contents()->SetAudioMuted(true);
EXPECT_FALSE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
web_contents()->SetAudioMuted(false);
SimulatePlaybackStopped(0);
EXPECT_FALSE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateAudioVideoPlaybackStarted(0);
EXPECT_TRUE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateMutedStateChange(0, true);
EXPECT_FALSE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateSignificantVideoPlayer(1);
EXPECT_TRUE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateAudioContextStarted(0);
EXPECT_TRUE(AreConditionsMet());
EXPECT_TRUE(AreAudioContextConditionsMet());
web_contents()->SetAudioMuted(true);
EXPECT_FALSE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
web_contents()->SetAudioMuted(false);
SimulateAudioContextStopped(0);
EXPECT_TRUE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
}
TEST_F(MediaEngagementContentsObserverTest, AreConditionsMet_AudioOnly) {
EXPECT_FALSE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
SimulateSignificantAudioPlayer(0);
EXPECT_TRUE(AreConditionsMet());
EXPECT_FALSE(AreAudioContextConditionsMet());
}
TEST_F(MediaEngagementContentsObserverTest, RecordInsignificantReason) {
......@@ -615,7 +708,19 @@ TEST_F(MediaEngagementContentsObserverTest,
MediaEngagementContentsObserver::InsignificantPlaybackReason::kCount, 1);
}
TEST_F(MediaEngagementContentsObserverTest, EnsureCleanupAfterNavigation) {
TEST_F(MediaEngagementContentsObserverTest,
EnsureCleanupAfterNavigation_AudioContext) {
EXPECT_FALSE(GetAudioContextPlayersCount());
SimulateAudioContextStarted(0);
EXPECT_TRUE(GetAudioContextPlayersCount());
Navigate(GURL("https://example.com"));
EXPECT_FALSE(GetAudioContextPlayersCount());
}
TEST_F(MediaEngagementContentsObserverTest,
EnsureCleanupAfterNavigation_Media) {
EXPECT_FALSE(GetStoredPlayerStatesCount());
SimulateMutedStateChange(0, true);
......@@ -664,6 +769,23 @@ TEST_F(MediaEngagementContentsObserverTest, TimerRunsDependingOnConditions) {
EXPECT_TRUE(IsTimerRunning());
}
TEST_F(MediaEngagementContentsObserverTest,
TimerRunsDependingOnConditions_AudioContext) {
EXPECT_FALSE(IsAudioContextTimerRunning());
SimulateAudioContextStarted(0);
EXPECT_TRUE(IsAudioContextTimerRunning());
web_contents()->SetAudioMuted(true);
EXPECT_FALSE(IsAudioContextTimerRunning());
web_contents()->SetAudioMuted(false);
EXPECT_TRUE(IsAudioContextTimerRunning());
SimulateAudioContextStopped(0);
EXPECT_FALSE(IsAudioContextTimerRunning());
}
TEST_F(MediaEngagementContentsObserverTest,
TimerRunsDependingOnConditions_AudioOnly) {
EXPECT_FALSE(IsTimerRunning());
......@@ -672,14 +794,39 @@ TEST_F(MediaEngagementContentsObserverTest,
EXPECT_TRUE(IsTimerRunning());
}
TEST_F(MediaEngagementContentsObserverTest, TimerDoesNotRunIfEntryRecorded) {
SimulateSignificantPlaybackRecorded();
TEST_F(MediaEngagementContentsObserverTest,
TimerDoesNotRunIfEntryRecorded_AudioContext) {
SimulateAudible();
SimulateSignificantAudioContextPlaybackRecorded();
EXPECT_TRUE(WasSignificantAudioContextPlaybackRecorded());
SimulateAudioContextStarted(0);
EXPECT_FALSE(IsAudioContextTimerRunning());
}
TEST_F(MediaEngagementContentsObserverTest,
TimerDoesNotRunIfEntryRecorded_Media) {
SimulateSignificantMediaElementPlaybackRecorded();
EXPECT_TRUE(WasSignificantPlaybackRecorded());
SimulateSignificantVideoPlayer(0);
EXPECT_FALSE(IsTimerRunning());
}
TEST_F(MediaEngagementContentsObserverTest,
SignificantPlaybackRecordedWhenTimerFires) {
SignificantPlaybackRecordedWhenTimerFires_AudioContext) {
Navigate(GURL("https://www.example.com"));
SimulateAudioContextStarted(0);
SimulateAudible();
EXPECT_TRUE(IsAudioContextTimerRunning());
EXPECT_FALSE(WasSignificantAudioContextPlaybackRecorded());
SimulateAudioContextPlaybackTimerFired();
EXPECT_TRUE(WasSignificantAudioContextPlaybackRecorded());
}
TEST_F(MediaEngagementContentsObserverTest,
SignificantPlaybackRecordedWhenTimerFires_Media) {
Navigate(GURL("https://www.example.com"));
SimulateSignificantVideoPlayer(0);
EXPECT_TRUE(IsTimerRunning());
......@@ -692,16 +839,31 @@ TEST_F(MediaEngagementContentsObserverTest,
TEST_F(MediaEngagementContentsObserverTest, InteractionsRecorded) {
GURL url("https://www.example.com");
GURL url2("https://www.example.org");
ExpectScores(url, 0.0, 0, 0, 0, 0);
ExpectScores(url, 0.0, 0, 0, 0, 0, 0, 0);
Navigate(url);
Navigate(url2);
ExpectScores(url, 0.0, 1, 0, 0, 0);
ExpectScores(url, 0.0, 1, 0, 0, 0, 0, 0);
Navigate(url);
SimulateAudible();
SimulateSignificantPlaybackTimeForPage();
ExpectScores(url, 0.05, 2, 1, 0, 0);
SimulateSignificantMediaElementPlaybackTimeForPage();
// We need to navigate to another page to commit the scores.
ExpectScores(url, 0.0, 1, 0, 0, 0, 0, 0);
Navigate(url2);
ExpectScores(url, 0.05, 2, 1, 0, 0, 1, 0);
// Simulate both audio context and media element on the same page.
Navigate(url);
SimulateAudible();
SimulateAudioContextStarted(0);
SimulateAudioContextPlaybackTimerFired();
SimulateSignificantMediaElementPlaybackTimeForPage();
// We need to navigate to another page to commit the scores.
Navigate(url2);
ExpectScores(url, 0.1, 3, 2, 0, 0, 2, 1);
}
TEST_F(MediaEngagementContentsObserverTest,
......@@ -722,7 +884,18 @@ TEST_F(MediaEngagementContentsObserverTest, DoNotRecordAudiolessTrack) {
}
TEST_F(MediaEngagementContentsObserverTest,
ResetStateOnNavigationWithPlayingPlayers) {
ResetStateOnNavigationWithPlayingPlayers_AudioContext) {
Navigate(GURL("https://www.google.com"));
SimulateAudioContextStarted(0);
EXPECT_TRUE(IsAudioContextTimerRunning());
Navigate(GURL("https://www.example.com"));
EXPECT_FALSE(GetAudioContextPlayersCount());
EXPECT_FALSE(IsAudioContextTimerRunning());
}
TEST_F(MediaEngagementContentsObserverTest,
ResetStateOnNavigationWithPlayingPlayers_Media) {
Navigate(GURL("https://www.google.com"));
SimulateSignificantVideoPlayer(0);
ForceUpdateTimer(0);
......@@ -803,7 +976,21 @@ TEST_F(MediaEngagementContentsObserverTest,
MediaEngagementContentsObserver::kHistogramScoreAtPlaybackName, 0);
}
TEST_F(MediaEngagementContentsObserverTest, VisibilityNotRequired) {
TEST_F(MediaEngagementContentsObserverTest,
VisibilityNotRequired_AudioContext) {
EXPECT_FALSE(IsAudioContextTimerRunning());
SimulateAudioContextStarted(0);
EXPECT_TRUE(IsAudioContextTimerRunning());
SimulateIsVisible();
EXPECT_TRUE(IsAudioContextTimerRunning());
SimulateIsHidden();
EXPECT_TRUE(IsAudioContextTimerRunning());
}
TEST_F(MediaEngagementContentsObserverTest, VisibilityNotRequired_Media) {
EXPECT_FALSE(IsTimerRunning());
SimulateSignificantVideoPlayer(0);
......@@ -823,16 +1010,34 @@ TEST_F(MediaEngagementContentsObserverTest, RecordUkmMetricsOnDestroy) {
EXPECT_FALSE(WasSignificantPlaybackRecorded());
SimulateSignificantVideoPlayer(0);
SimulateSignificantPlaybackTimeForPage();
SimulateSignificantMediaElementPlaybackTimeForPage();
SimulateSignificantPlaybackTimeForPlayer(0);
SimulateSignificantVideoPlayer(1);
EXPECT_TRUE(WasSignificantPlaybackRecorded());
SimulateDestroy();
ExpectScores(url, 21.0 / 25.0, 25, 21, 5, 2);
ExpectScores(url, 21.0 / 25.0, 25, 21, 5, 2, 1, 0);
ExpectUkmEntry(url, 21, 25, 84, 1, true, 2, 5, 1, 2, 0);
}
TEST_F(MediaEngagementContentsObserverTest,
RecordUkmMetricsOnDestroy_AudioContextOnly) {
GURL url("https://www.google.com");
SetScores(url, 24, 20, 2, 1);
Navigate(url);
EXPECT_FALSE(WasSignificantAudioContextPlaybackRecorded());
SimulateAudioContextStarted(0);
SimulateAudible();
SimulateAudioContextPlaybackTimerFired();
EXPECT_TRUE(WasSignificantAudioContextPlaybackRecorded());
SimulateDestroy();
// AudioContext playbacks should count as a significant playback.
ExpectScores(url, 21.0 / 25.0, 25, 21, 2, 1, 0, 1);
ExpectUkmEntry(url, 21, 25, 84, 0, true, 0, 2, 0, 1, 0);
}
TEST_F(MediaEngagementContentsObserverTest,
RecordUkmMetricsOnDestroy_NoPlaybacks) {
GURL url("https://www.google.com");
......@@ -842,7 +1047,7 @@ TEST_F(MediaEngagementContentsObserverTest,
EXPECT_FALSE(WasSignificantPlaybackRecorded());
SimulateDestroy();
ExpectScores(url, 20.0 / 25.0, 25, 20, 2, 1);
ExpectScores(url, 20.0 / 25.0, 25, 20, 2, 1, 0, 0);
ExpectUkmEntry(url, 20, 25, 80, 0, true, 0, 2, 0, 1, 0);
}
......@@ -853,16 +1058,35 @@ TEST_F(MediaEngagementContentsObserverTest, RecordUkmMetricsOnNavigate) {
EXPECT_FALSE(WasSignificantPlaybackRecorded());
SimulateSignificantVideoPlayer(0);
SimulateSignificantPlaybackTimeForPage();
SimulateSignificantMediaElementPlaybackTimeForPage();
SimulateSignificantPlaybackTimeForPlayer(0);
SimulateSignificantVideoPlayer(1);
EXPECT_TRUE(WasSignificantPlaybackRecorded());
Navigate(GURL("https://www.example.org"));
ExpectScores(url, 21.0 / 25.0, 25, 21, 5, 2);
ExpectScores(url, 21.0 / 25.0, 25, 21, 5, 2, 1, 0);
ExpectUkmEntry(url, 21, 25, 84, 1, true, 2, 5, 1, 2, 0);
}
TEST_F(MediaEngagementContentsObserverTest,
RecordUkmMetricsOnNavigate_AudioContextOnly) {
GURL url("https://www.google.com");
SetScores(url, 24, 20, 2, 1);
Navigate(url);
EXPECT_FALSE(WasSignificantAudioContextPlaybackRecorded());
SimulateAudioContextStarted(0);
SimulateAudible();
SimulateAudioContextPlaybackTimerFired();
EXPECT_TRUE(WasSignificantAudioContextPlaybackRecorded());
Navigate(GURL("https://www.example.org"));
// AudioContext playbacks should count as a media playback.
ExpectScores(url, 21.0 / 25.0, 25, 21, 2, 1, 0, 1);
ExpectUkmEntry(url, 21, 25, 84, 0, true, 0, 2, 0, 1, 0);
}
TEST_F(MediaEngagementContentsObserverTest,
RecordUkmMetricsOnNavigate_NoPlaybacks) {
GURL url("https://www.google.com");
......@@ -872,7 +1096,7 @@ TEST_F(MediaEngagementContentsObserverTest,
EXPECT_FALSE(WasSignificantPlaybackRecorded());
Navigate(GURL("https://www.example.org"));
ExpectScores(url, 6 / 28.0, 28, 6, 2, 1);
ExpectScores(url, 6 / 28.0, 28, 6, 2, 1, 0, 0);
ExpectUkmEntry(url, 6, 28, 21, 0, false, 0, 2, 0, 1, 0);
}
......@@ -887,7 +1111,7 @@ TEST_F(MediaEngagementContentsObserverTest,
Advance15Minutes();
const base::Time first = Now();
SimulateSignificantVideoPlayer(0);
SimulateSignificantPlaybackTimeForPage();
SimulateSignificantMediaElementPlaybackTimeForPage();
SimulateSignificantPlaybackTimeForPlayer(0);
Advance15Minutes();
......@@ -895,7 +1119,7 @@ TEST_F(MediaEngagementContentsObserverTest,
SimulateSignificantPlaybackTimeForPlayer(1);
SimulateDestroy();
ExpectScores(url, 21.0 / 25.0, 25, 21, 5, 3);
ExpectScores(url, 21.0 / 25.0, 25, 21, 5, 3, 1, 0);
ExpectLastPlaybackTime(url, first);
ExpectUkmEntry(url, 21, 25, 84, 1, true, 2, 5, 2, 3, 900);
}
......@@ -937,16 +1161,15 @@ TEST_F(MediaEngagementContentsObserverTest, RecordAudiblePlayers_OnDestroy) {
// This one is stopped.
SimulatePlaybackStopped(5);
// Test that the scores were recorded, but not the audible scores.
SimulateSignificantPlaybackTimeForPage();
// Simulate significant playback time for all the players.
SimulateSignificantMediaElementPlaybackTimeForPage();
SimulateSignificantPlaybackTimeForPlayer(0);
SimulateSignificantPlaybackTimeForPlayer(1);
SimulateSignificantPlaybackTimeForPlayer(2);
ExpectScores(url, 0.05, 1, 1, 0, 0);
// Test that when we destroy the audible players the scores are recorded.
SimulateDestroy();
ExpectScores(url, 0.05, 1, 1, 3, 3);
ExpectScores(url, 0.05, 1, 1, 3, 3, 1, 0);
}
TEST_F(MediaEngagementContentsObserverTest, RecordAudiblePlayers_OnNavigate) {
......@@ -969,23 +1192,22 @@ TEST_F(MediaEngagementContentsObserverTest, RecordAudiblePlayers_OnNavigate) {
// This one is stopped.
SimulatePlaybackStopped(5);
// Test that the scores were recorded, but not the audible scores.
SimulateSignificantPlaybackTimeForPage();
// Simulate significant playback time for all the players.
SimulateSignificantMediaElementPlaybackTimeForPage();
SimulateSignificantPlaybackTimeForPlayer(0);
SimulateSignificantPlaybackTimeForPlayer(1);
SimulateSignificantPlaybackTimeForPlayer(2);
ExpectScores(url, 0.05, 1, 1, 0, 0);
// Navigate to a sub page and continue watching.
Navigate(GURL("https://www.google.com/test"));
SimulateSignificantAudioPlayer(1);
SimulateLongMediaPlayback(1);
ExpectScores(url, 0.05, 1, 1, 0, 0);
ExpectScores(url, 0.0, 0, 0, 0, 0, 0, 0);
// Test that when we navigate to a new origin the audible players the scores
// are recorded.
Navigate(GURL("https://www.google.co.uk"));
ExpectScores(url, 0.05, 1, 1, 4, 3);
ExpectScores(url, 0.05, 1, 1, 4, 3, 1, 0);
}
TEST_F(MediaEngagementContentsObserverTest, TimerSpecificToPlayer) {
......@@ -997,7 +1219,7 @@ TEST_F(MediaEngagementContentsObserverTest, TimerSpecificToPlayer) {
ForceUpdateTimer(1);
SimulateDestroy();
ExpectScores(url, 0, 1, 0, 1, 0);
ExpectScores(url, 0, 1, 0, 1, 0, 0, 0);
}
TEST_F(MediaEngagementContentsObserverTest, PagePlayerTimersDifferent) {
......@@ -1007,12 +1229,14 @@ TEST_F(MediaEngagementContentsObserverTest, PagePlayerTimersDifferent) {
EXPECT_TRUE(IsTimerRunning());
EXPECT_TRUE(IsTimerRunningForPlayer(0));
EXPECT_TRUE(IsTimerRunningForPlayer(1));
EXPECT_FALSE(IsAudioContextTimerRunning());
SimulateMutedStateChange(0, true);
EXPECT_TRUE(IsTimerRunning());
EXPECT_FALSE(IsTimerRunningForPlayer(0));
EXPECT_TRUE(IsTimerRunningForPlayer(1));
EXPECT_FALSE(IsAudioContextTimerRunning());
}
TEST_F(MediaEngagementContentsObserverTest, SignificantAudibleTabMuted_On) {
......@@ -1024,7 +1248,7 @@ TEST_F(MediaEngagementContentsObserverTest, SignificantAudibleTabMuted_On) {
SimulateSignificantPlaybackTimeForPlayer(0);
SimulateDestroy();
ExpectScores(url, 0, 1, 0, 1, 0);
ExpectScores(url, 0, 1, 0, 1, 0, 0, 0);
}
TEST_F(MediaEngagementContentsObserverTest, SignificantAudibleTabMuted_Off) {
......@@ -1035,7 +1259,7 @@ TEST_F(MediaEngagementContentsObserverTest, SignificantAudibleTabMuted_Off) {
SimulateSignificantPlaybackTimeForPlayer(0);
SimulateDestroy();
ExpectScores(url, 0, 1, 0, 1, 1);
ExpectScores(url, 0, 1, 0, 1, 1, 0, 0);
}
TEST_F(MediaEngagementContentsObserverTest, RecordPlaybackTime) {
......@@ -1076,7 +1300,7 @@ TEST_F(MediaEngagementContentsObserverTest, ShortMediaIgnored) {
// Test that when we navigate to a new origin the audible players the scores
// are recorded and we log extra UKM events with the times.
Navigate(GURL("https://www.google.co.uk"));
ExpectScores(url, 0, 1, 0, 2, 2);
ExpectScores(url, 0, 1, 0, 2, 2, 0, 0);
ExpectUkmIgnoredEntries(url, std::vector<int64_t>{1000, 2000});
}
......@@ -1093,7 +1317,7 @@ TEST_F(MediaEngagementContentsObserverTest, TotalTimeUsedInShortCalculation) {
ExpectPlaybackTime(0, base::TimeDelta::FromSeconds(10));
SimulateDestroy();
ExpectScores(url, 0, 1, 0, 1, 1);
ExpectScores(url, 0, 1, 0, 1, 1, 0, 0);
ExpectNoUkmIgnoreEntry(url);
}
......@@ -1105,7 +1329,7 @@ TEST_F(MediaEngagementContentsObserverTest, OnlyIgnoreFinishedMedia) {
SimulatePlaybackStoppedWithTime(0, false, base::TimeDelta::FromSeconds(2));
SimulateDestroy();
ExpectScores(url, 0, 1, 0, 1, 0);
ExpectScores(url, 0, 1, 0, 1, 0, 0, 0);
ExpectNoUkmIgnoreEntry(url);
}
......
......@@ -86,10 +86,13 @@ class MediaEngagementScore final {
int media_playbacks() const { return media_playbacks_; }
void IncrementMediaPlaybacks();
// Get the last time media was played on this origin.
// Gets/sets the last time media was played on this origin.
base::Time last_media_playback_time() const {
return last_media_playback_time_;
}
void set_last_media_playback_time(base::Time new_time) {
last_media_playback_time_ = new_time;
}
// Get/increment the number of audible media playbacks this origin had.
int audible_playbacks() const { return audible_playbacks_; }
......@@ -152,9 +155,6 @@ class MediaEngagementScore final {
void set_visits_with_media_tag(int visits) {
visits_with_media_tag_ = visits;
}
void set_last_media_playback_time(base::Time new_time) {
last_media_playback_time_ = new_time;
}
void set_media_element_playbacks(int playbacks) {
media_element_playbacks_ = playbacks;
}
......
......@@ -321,15 +321,6 @@ MediaEngagementService::GetAllScoreDetails() const {
return details;
}
void MediaEngagementService::RecordPlayback(const GURL& url) {
if (!ShouldRecordEngagement(url))
return;
MediaEngagementScore score = CreateEngagementScore(url);
score.IncrementMediaPlaybacks();
score.Commit();
}
MediaEngagementScore MediaEngagementService::CreateEngagementScore(
const GURL& url) const {
// If we are in incognito, |settings| will automatically have the data from
......
......@@ -65,9 +65,6 @@ class MediaEngagementService : public KeyedService,
// Record a visit of a |url|.
void RecordVisit(const GURL& url);
// Record a media playback on a |url|.
void RecordPlayback(const GURL& url);
// Returns an array of engagement score details for all origins which
// have a score.
std::vector<media::mojom::MediaEngagementScoreDetailsPtr> GetAllScoreDetails()
......@@ -103,6 +100,8 @@ class MediaEngagementService : public KeyedService,
// cleared, either partially or fully.
static const char kHistogramClearName[];
const base::Clock* clock() const { return clock_; }
private:
friend class MediaEngagementBrowserTest;
friend class MediaEngagementContentsObserverTest;
......
......@@ -162,7 +162,16 @@ class MediaEngagementServiceTest : public ChromeRenderViewHostTestHarness {
void RecordVisit(GURL url) { service_->RecordVisit(url); }
void RecordPlayback(GURL url) { service_->RecordPlayback(url); }
void RecordPlayback(GURL url) {
RecordPlaybackForService(service_.get(), url);
}
void RecordPlaybackForService(MediaEngagementService* service, GURL url) {
MediaEngagementScore score = service->CreateEngagementScore(url);
score.IncrementMediaPlaybacks();
score.set_last_media_playback_time(service->clock()->Now());
score.Commit();
}
void ExpectScores(MediaEngagementService* service,
GURL url,
......@@ -370,7 +379,7 @@ TEST_F(MediaEngagementServiceTest, IncognitoOverrideRegularProfile) {
}
incognito_service->RecordVisit(kUrl1);
incognito_service->RecordPlayback(kUrl2);
RecordPlaybackForService(incognito_service, kUrl2);
// Score shouldn't have changed in regular profile.
{
......
......@@ -49,21 +49,22 @@ bool MediaEngagementSession::IsSameOriginWith(const url::Origin& origin) const {
return origin_.IsSameOriginWith(origin);
}
void MediaEngagementSession::RecordSignificantPlayback() {
DCHECK(!significant_playback_recorded_);
void MediaEngagementSession::RecordSignificantMediaElementPlayback() {
DCHECK(!significant_media_element_playback_recorded_);
significant_playback_recorded_ = true;
pending_data_to_commit_.playback = true;
significant_media_element_playback_recorded_ = true;
pending_data_to_commit_.media_element_playback = true;
// When a session was restored, visits are only recorded when there was a
// playback. Add back the visit now as this code can only be executed once
// per session.
if (restore_status_ == RestoreType::kRestored)
pending_data_to_commit_.visit = true;
RecordSignificantPlayback();
}
// When playback has happened, the visit can be recorded as there will be no
// further changes.
CommitPendingData();
void MediaEngagementSession::RecordSignificantAudioContextPlayback() {
DCHECK(!significant_audio_context_playback_recorded_);
significant_audio_context_playback_recorded_ = true;
pending_data_to_commit_.audio_context_playback = true;
RecordSignificantPlayback();
}
void MediaEngagementSession::RecordShortPlaybackIgnored(int length_msec) {
......@@ -89,8 +90,19 @@ void MediaEngagementSession::RegisterAudiblePlayers(
significant_players_delta_ += significant_players;
}
bool MediaEngagementSession::significant_playback_recorded() const {
return significant_playback_recorded_;
bool MediaEngagementSession::WasSignificantPlaybackRecorded() const {
return significant_media_element_playback_recorded_ ||
significant_audio_context_playback_recorded_;
}
bool MediaEngagementSession::significant_media_element_playback_recorded()
const {
return significant_media_element_playback_recorded_;
}
bool MediaEngagementSession::significant_audio_context_playback_recorded()
const {
return significant_audio_context_playback_recorded_;
}
const url::Origin& MediaEngagementSession::origin() const {
......@@ -104,7 +116,7 @@ MediaEngagementSession::~MediaEngagementSession() {
if (HasPendingDataToCommit()) {
CommitPendingData();
} else if ((restore_status_ == RestoreType::kRestored) &&
!significant_playback_recorded_) {
!WasSignificantPlaybackRecorded()) {
RecordStatusHistograms();
}
......@@ -124,6 +136,21 @@ ukm::UkmRecorder* MediaEngagementSession::GetUkmRecorder() {
return ukm_recorder;
}
void MediaEngagementSession::RecordSignificantPlayback() {
DCHECK(WasSignificantPlaybackRecorded());
// If this was the first time we recorded significant playback then we should
// record the playback time.
if (first_significant_playback_time_.is_null())
first_significant_playback_time_ = service_->clock()->Now();
// When a session was restored, visits are only recorded when there was a
// playback. Add back the visit now as this code can only be executed once
// per session.
if (restore_status_ == RestoreType::kRestored)
pending_data_to_commit_.visit = true;
}
void MediaEngagementSession::RecordUkmMetrics() {
ukm::UkmRecorder* ukm_recorder = GetUkmRecorder();
if (!ukm_recorder)
......@@ -142,7 +169,7 @@ void MediaEngagementSession::RecordUkmMetrics() {
.SetPlaybacks_Total(score.media_playbacks())
.SetVisits_Total(score.visits())
.SetEngagement_Score(round(score.actual_score() * 100))
.SetPlaybacks_Delta(significant_playback_recorded_)
.SetPlaybacks_Delta(significant_media_element_playback_recorded_)
.SetEngagement_IsHigh(score.high_score())
.SetEngagement_IsHigh_Changed(high_score_changed_)
.SetEngagement_IsHigh_Changes(score.high_score_changes())
......@@ -155,9 +182,14 @@ void MediaEngagementSession::RecordUkmMetrics() {
.Record(ukm_recorder);
}
bool MediaEngagementSession::HasPendingPlaybackToCommit() const {
return pending_data_to_commit_.audio_context_playback ||
pending_data_to_commit_.media_element_playback;
}
bool MediaEngagementSession::HasPendingDataToCommit() const {
return pending_data_to_commit_.visit || pending_data_to_commit_.playback ||
pending_data_to_commit_.players;
return pending_data_to_commit_.visit || pending_data_to_commit_.players ||
HasPendingPlaybackToCommit();
}
void MediaEngagementSession::RecordStatusHistograms() const {
......@@ -165,12 +197,12 @@ void MediaEngagementSession::RecordStatusHistograms() const {
(restore_status_ == RestoreType::kRestored));
RecordSessionStatus(SessionStatus::kCreated);
if (pending_data_to_commit_.playback)
if (HasPendingPlaybackToCommit())
RecordSessionStatus(SessionStatus::kSignificantPlayback);
if (restore_status_ == RestoreType::kRestored) {
RecordRestoredSessionStatus(SessionStatus::kCreated);
if (pending_data_to_commit_.playback)
if (HasPendingPlaybackToCommit())
RecordRestoredSessionStatus(SessionStatus::kSignificantPlayback);
}
}
......@@ -187,11 +219,20 @@ void MediaEngagementSession::CommitPendingData() {
if (pending_data_to_commit_.visit)
score.IncrementVisits();
if (significant_playback_recorded_ && pending_data_to_commit_.playback) {
if (WasSignificantPlaybackRecorded() && HasPendingPlaybackToCommit()) {
const base::Time old_time = score.last_media_playback_time();
score.IncrementMediaPlaybacks();
if (pending_data_to_commit_.audio_context_playback)
score.IncrementAudioContextPlaybacks();
if (pending_data_to_commit_.media_element_playback)
score.IncrementMediaElementPlaybacks();
// Use the stored significant playback time.
score.set_last_media_playback_time(first_significant_playback_time_);
// This code should be reached once and |time_since_playback_for_ukm_| can't
// be set.
DCHECK(time_since_playback_for_ukm_.is_zero());
......@@ -221,6 +262,7 @@ void MediaEngagementSession::CommitPendingData() {
// If the high state has changed store that in a bool.
high_score_changed_ = previous_high_value != score.high_score();
pending_data_to_commit_.visit = pending_data_to_commit_.playback =
pending_data_to_commit_.players = false;
pending_data_to_commit_.visit = pending_data_to_commit_.players =
pending_data_to_commit_.audio_context_playback =
pending_data_to_commit_.media_element_playback = false;
}
......@@ -37,8 +37,13 @@ class MediaEngagementSession : public base::RefCounted<MediaEngagementSession> {
// Returns whether the session's origin is same origin with |origin|.
bool IsSameOriginWith(const url::Origin& origin) const;
// Record that the session received a significant playback.
void RecordSignificantPlayback();
// Record that the session received a significant playback from a media
// element.
void RecordSignificantMediaElementPlayback();
// Record that the session received a significant playback from an audio
// context.
void RecordSignificantAudioContextPlayback();
// Record the length of an ignored media playback.
void RecordShortPlaybackIgnored(int length_msec);
......@@ -48,7 +53,11 @@ class MediaEngagementSession : public base::RefCounted<MediaEngagementSession> {
void RegisterAudiblePlayers(int32_t audible_players,
int32_t significant_players);
bool significant_playback_recorded() const;
// Whether any significant playback was recorded.
bool WasSignificantPlaybackRecorded() const;
bool significant_media_element_playback_recorded() const;
bool significant_audio_context_playback_recorded() const;
const url::Origin& origin() const;
private:
......@@ -61,9 +70,17 @@ class MediaEngagementSession : public base::RefCounted<MediaEngagementSession> {
// Returns the UkmRecorder with the right source id set.
ukm::UkmRecorder* GetUkmRecorder();
// Records a significant playback that is either a media element or an audio
// context playback.
void RecordSignificantPlayback();
// Record the score and change in score to UKM.
void RecordUkmMetrics();
// Returns whether the session has a pending playback that needs to be
// committed into the database.
bool HasPendingPlaybackToCommit() const;
// Returns whether the session has data that needs to be committed into the
// database.
bool HasPendingDataToCommit() const;
......@@ -93,14 +110,19 @@ class MediaEngagementSession : public base::RefCounted<MediaEngagementSession> {
int32_t audible_players_total_ = 0;
int32_t significant_players_total_ = 0;
bool significant_playback_recorded_ = false;
bool significant_media_element_playback_recorded_ = false;
bool significant_audio_context_playback_recorded_ = false;
struct PendingDataToCommit {
bool visit = true;
bool playback = false;
bool audio_context_playback = false;
bool media_element_playback = false;
bool players = false;
};
PendingDataToCommit pending_data_to_commit_;
// The time the first significant playback occurred.
base::Time first_significant_playback_time_;
// The time between significant playbacks to be recorded to UKM.
base::TimeDelta time_since_playback_for_ukm_;
......
......@@ -33,9 +33,14 @@ class MediaEngagementSessionTest : public testing::Test {
return session->pending_data_to_commit_.visit;
}
static bool HasPendingPlaybackToCommitForSession(
static bool HasPendingAudioContextPlaybackToCommitForSession(
MediaEngagementSession* session) {
return session->pending_data_to_commit_.playback;
return session->pending_data_to_commit_.audio_context_playback;
}
static bool HasPendingMediaElementPlaybackToCommitForSession(
MediaEngagementSession* session) {
return session->pending_data_to_commit_.media_element_playback;
}
static bool HasPendingPlayersToCommitForSession(
......@@ -70,15 +75,23 @@ class MediaEngagementSessionTest : public testing::Test {
static void SetPendingDataToCommitForSession(MediaEngagementSession* session,
bool visit,
bool playback,
bool audio_context_playback,
bool media_element_playback,
bool players) {
session->pending_data_to_commit_ = {visit, playback, players};
session->pending_data_to_commit_ = {visit, audio_context_playback,
media_element_playback, players};
}
static void SetSignificantAudioContextPlaybackRecordedForSession(
MediaEngagementSession* session,
bool value) {
session->significant_audio_context_playback_recorded_ = value;
}
static void SetSignificantPlaybackRecordedForSession(
static void SetSignificantMediaElementPlaybackRecordedForSession(
MediaEngagementSession* session,
bool value) {
session->significant_playback_recorded_ = value;
session->significant_media_element_playback_recorded_ = value;
}
static void CommitPendingDataForSession(MediaEngagementSession* session) {
......@@ -102,6 +115,9 @@ class MediaEngagementSessionTest : public testing::Test {
void SetUp() override {
service_ =
base::WrapUnique(new MediaEngagementService(&profile_, &test_clock_));
// Advance the test clock to a non null value.
test_clock_.Advance(base::TimeDelta::FromMinutes(15));
}
MediaEngagementService* service() const { return service_.get(); }
......@@ -126,6 +142,13 @@ class MediaEngagementSessionTest : public testing::Test {
return service()->HasHighEngagement(origin().GetURL());
}
void RecordPlayback(GURL url) {
MediaEngagementScore score = service_->CreateEngagementScore(url);
score.IncrementMediaPlaybacks();
score.set_last_media_playback_time(service_->clock()->Now());
score.Commit();
}
private:
const url::Origin origin_;
base::SimpleTestClock test_clock_;
......@@ -272,19 +295,110 @@ TEST_F(MediaEngagementSessionTest, GetUkmRecorder_NotNull) {
EXPECT_NE(nullptr, GetUkmRecorderForSession(session.get()));
}
// Test that RecordSignificantPlayback() sets the significant_playback_recorded_
// boolean to true.
TEST_F(MediaEngagementSessionTest, RecordSignificantPlayback_SetsBoolean) {
// Test that RecordSignificantAudioContextPlayback() sets the
// significant_audio_context_playback_recorded_ boolean to true.
TEST_F(MediaEngagementSessionTest,
RecordSignificantAudioContextPlayback_SetsBoolean) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kNotRestored);
EXPECT_FALSE(session->significant_playback_recorded());
EXPECT_FALSE(session->significant_audio_context_playback_recorded());
EXPECT_FALSE(session->WasSignificantPlaybackRecorded());
session->RecordSignificantAudioContextPlayback();
EXPECT_TRUE(session->significant_audio_context_playback_recorded());
EXPECT_TRUE(session->WasSignificantPlaybackRecorded());
}
// Test that RecordSignificantMediaElementPlayback() sets the
// significant_media_element_playback_recorded_ boolean to true.
TEST_F(MediaEngagementSessionTest,
RecordSignificantMediaElementPlayback_SetsBoolean) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kNotRestored);
EXPECT_FALSE(session->significant_media_element_playback_recorded());
EXPECT_FALSE(session->WasSignificantPlaybackRecorded());
session->RecordSignificantMediaElementPlayback();
EXPECT_TRUE(session->significant_media_element_playback_recorded());
EXPECT_TRUE(session->WasSignificantPlaybackRecorded());
}
// Test that RecordSignificantAudioContextPlayback() records playback.
TEST_F(MediaEngagementSessionTest,
RecordSignificantAudioContextPlayback_SetsPendingPlayback) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kNotRestored);
int expected_visits = 0;
int expected_playbacks = 0;
{
MediaEngagementScore score =
service()->CreateEngagementScore(origin().GetURL());
expected_visits = score.visits() + 1;
expected_playbacks = score.media_playbacks() + 1;
}
EXPECT_FALSE(HasPendingAudioContextPlaybackToCommitForSession(session.get()));
EXPECT_TRUE(HasPendingVisitToCommitForSession(session.get()));
session->RecordSignificantAudioContextPlayback();
EXPECT_TRUE(HasPendingDataToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
EXPECT_FALSE(HasPendingDataToCommitForSession(session.get()));
{
MediaEngagementScore score =
service()->CreateEngagementScore(origin().GetURL());
EXPECT_EQ(expected_visits, score.visits());
EXPECT_EQ(expected_playbacks, score.media_playbacks());
EXPECT_EQ(expected_playbacks, score.audio_context_playbacks());
}
}
// Test that RecordSignificantMediaElementPlayback() records playback.
TEST_F(MediaEngagementSessionTest,
RecordSignificantMediaElementPlayback_SetsPendingPlayback) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kNotRestored);
int expected_visits = 0;
int expected_playbacks = 0;
{
MediaEngagementScore score =
service()->CreateEngagementScore(origin().GetURL());
expected_visits = score.visits() + 1;
expected_playbacks = score.media_playbacks() + 1;
}
EXPECT_FALSE(HasPendingMediaElementPlaybackToCommitForSession(session.get()));
EXPECT_TRUE(HasPendingVisitToCommitForSession(session.get()));
session->RecordSignificantMediaElementPlayback();
EXPECT_TRUE(HasPendingDataToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
EXPECT_FALSE(HasPendingDataToCommitForSession(session.get()));
{
MediaEngagementScore score =
service()->CreateEngagementScore(origin().GetURL());
session->RecordSignificantPlayback();
EXPECT_TRUE(session->significant_playback_recorded());
EXPECT_EQ(expected_visits, score.visits());
EXPECT_EQ(expected_playbacks, score.media_playbacks());
EXPECT_EQ(expected_playbacks, score.media_element_playbacks());
}
}
// Test that RecordSignificantPlayback() records playback.
// Test that RecordSignificantAudioContextPlayback and
// RecordSignificantMediaElementPlayback() records a single playback
TEST_F(MediaEngagementSessionTest,
RecordSignificantPlayback_SetsPendingPlayback) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
......@@ -300,10 +414,15 @@ TEST_F(MediaEngagementSessionTest,
expected_playbacks = score.media_playbacks() + 1;
}
EXPECT_FALSE(HasPendingPlaybackToCommitForSession(session.get()));
EXPECT_FALSE(HasPendingAudioContextPlaybackToCommitForSession(session.get()));
EXPECT_FALSE(HasPendingMediaElementPlaybackToCommitForSession(session.get()));
EXPECT_TRUE(HasPendingVisitToCommitForSession(session.get()));
session->RecordSignificantPlayback();
session->RecordSignificantAudioContextPlayback();
session->RecordSignificantMediaElementPlayback();
EXPECT_TRUE(HasPendingDataToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
EXPECT_FALSE(HasPendingDataToCommitForSession(session.get()));
{
......@@ -312,6 +431,8 @@ TEST_F(MediaEngagementSessionTest,
EXPECT_EQ(expected_visits, score.visits());
EXPECT_EQ(expected_playbacks, score.media_playbacks());
EXPECT_EQ(expected_playbacks, score.audio_context_playbacks());
EXPECT_EQ(expected_playbacks, score.media_element_playbacks());
}
}
......@@ -325,8 +446,8 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_Reset) {
CommitPendingDataForSession(session.get());
EXPECT_FALSE(HasPendingDataToCommitForSession(session.get()));
SetSignificantPlaybackRecordedForSession(session.get(), true);
SetPendingDataToCommitForSession(session.get(), true, true, true);
SetSignificantMediaElementPlaybackRecordedForSession(session.get(), true);
SetPendingDataToCommitForSession(session.get(), true, true, true, true);
EXPECT_TRUE(HasPendingDataToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
......@@ -356,7 +477,7 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdateVisitsAsNeeded) {
EXPECT_EQ(expected_visits, score.visits());
}
SetPendingDataToCommitForSession(session.get(), true, false, false);
SetPendingDataToCommitForSession(session.get(), true, false, false, false);
EXPECT_TRUE(HasPendingVisitToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
......@@ -367,8 +488,8 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdateVisitsAsNeeded) {
EXPECT_EQ(expected_visits, score.visits());
}
SetSignificantPlaybackRecordedForSession(session.get(), true);
SetPendingDataToCommitForSession(session.get(), false, true, true);
SetSignificantMediaElementPlaybackRecordedForSession(session.get(), true);
SetPendingDataToCommitForSession(session.get(), false, true, true, true);
EXPECT_FALSE(HasPendingVisitToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
......@@ -391,7 +512,7 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdatePlaybackWhenNeeded) {
expected_playbacks = score.media_playbacks();
}
EXPECT_FALSE(HasPendingPlaybackToCommitForSession(session.get()));
EXPECT_FALSE(HasPendingMediaElementPlaybackToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
{
......@@ -400,9 +521,9 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdatePlaybackWhenNeeded) {
EXPECT_EQ(expected_playbacks, score.media_playbacks());
}
SetSignificantPlaybackRecordedForSession(session.get(), true);
SetPendingDataToCommitForSession(session.get(), false, true, false);
EXPECT_TRUE(HasPendingPlaybackToCommitForSession(session.get()));
SetSignificantAudioContextPlaybackRecordedForSession(session.get(), true);
SetPendingDataToCommitForSession(session.get(), false, true, false, false);
EXPECT_TRUE(HasPendingAudioContextPlaybackToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
++expected_playbacks;
......@@ -412,21 +533,25 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdatePlaybackWhenNeeded) {
EXPECT_EQ(expected_playbacks, score.media_playbacks());
}
// Both significant_playback_recorded_ and pending data need to be true.
SetSignificantPlaybackRecordedForSession(session.get(), false);
SetPendingDataToCommitForSession(session.get(), false, true, false);
EXPECT_TRUE(HasPendingPlaybackToCommitForSession(session.get()));
SetSignificantAudioContextPlaybackRecordedForSession(session.get(), false);
SetSignificantMediaElementPlaybackRecordedForSession(session.get(), true);
SetPendingDataToCommitForSession(session.get(), false, false, true, false);
EXPECT_TRUE(HasPendingMediaElementPlaybackToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
++expected_playbacks;
{
MediaEngagementScore score =
service()->CreateEngagementScore(origin().GetURL());
EXPECT_EQ(expected_playbacks, score.media_playbacks());
}
SetSignificantPlaybackRecordedForSession(session.get(), true);
SetPendingDataToCommitForSession(session.get(), true, false, true);
EXPECT_FALSE(HasPendingPlaybackToCommitForSession(session.get()));
// Both significant_media_element_playback_recorded_ and pending data need to
// be true.
SetSignificantMediaElementPlaybackRecordedForSession(session.get(), false);
SetPendingDataToCommitForSession(session.get(), false, false, true, false);
EXPECT_TRUE(HasPendingMediaElementPlaybackToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
{
......@@ -435,9 +560,33 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdatePlaybackWhenNeeded) {
EXPECT_EQ(expected_playbacks, score.media_playbacks());
}
SetSignificantPlaybackRecordedForSession(session.get(), false);
SetPendingDataToCommitForSession(session.get(), true, false, true);
EXPECT_FALSE(HasPendingPlaybackToCommitForSession(session.get()));
// Both significant_audio_context_playback_recorded_ and pending data need to
// be true.
SetSignificantAudioContextPlaybackRecordedForSession(session.get(), false);
SetPendingDataToCommitForSession(session.get(), false, true, false, false);
EXPECT_TRUE(HasPendingAudioContextPlaybackToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
{
MediaEngagementScore score =
service()->CreateEngagementScore(origin().GetURL());
EXPECT_EQ(expected_playbacks, score.media_playbacks());
}
SetSignificantMediaElementPlaybackRecordedForSession(session.get(), true);
SetPendingDataToCommitForSession(session.get(), true, false, false, true);
EXPECT_FALSE(HasPendingMediaElementPlaybackToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
{
MediaEngagementScore score =
service()->CreateEngagementScore(origin().GetURL());
EXPECT_EQ(expected_playbacks, score.media_playbacks());
}
SetSignificantMediaElementPlaybackRecordedForSession(session.get(), false);
SetPendingDataToCommitForSession(session.get(), true, false, false, true);
EXPECT_FALSE(HasPendingMediaElementPlaybackToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
{
......@@ -472,7 +621,7 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdatePlayersWhenNeeded) {
}
session->RegisterAudiblePlayers(0, 0);
SetPendingDataToCommitForSession(session.get(), true, true, false);
SetPendingDataToCommitForSession(session.get(), true, true, true, false);
EXPECT_FALSE(HasPendingPlayersToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
......@@ -484,7 +633,7 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdatePlayersWhenNeeded) {
}
session->RegisterAudiblePlayers(0, 0);
SetPendingDataToCommitForSession(session.get(), false, false, true);
SetPendingDataToCommitForSession(session.get(), false, false, false, true);
EXPECT_TRUE(HasPendingPlayersToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
......@@ -496,7 +645,7 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdatePlayersWhenNeeded) {
}
session->RegisterAudiblePlayers(1, 1);
SetPendingDataToCommitForSession(session.get(), true, true, false);
SetPendingDataToCommitForSession(session.get(), true, true, true, false);
EXPECT_FALSE(HasPendingPlayersToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
......@@ -508,7 +657,7 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdatePlayersWhenNeeded) {
}
session->RegisterAudiblePlayers(0, 0);
SetPendingDataToCommitForSession(session.get(), false, false, true);
SetPendingDataToCommitForSession(session.get(), false, false, false, true);
EXPECT_TRUE(HasPendingPlayersToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
......@@ -522,7 +671,7 @@ TEST_F(MediaEngagementSessionTest, CommitPendingData_UpdatePlayersWhenNeeded) {
}
session->RegisterAudiblePlayers(1, 1);
SetPendingDataToCommitForSession(session.get(), false, false, true);
SetPendingDataToCommitForSession(session.get(), false, false, false, true);
EXPECT_TRUE(HasPendingPlayersToCommitForSession(session.get()));
CommitPendingDataForSession(session.get());
......@@ -545,7 +694,8 @@ TEST_F(MediaEngagementSessionTest, RecordUkmMetrics) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kNotRestored);
session->RecordSignificantPlayback();
session->RecordSignificantMediaElementPlayback();
CommitPendingDataForSession(session.get());
EXPECT_EQ(0u, test_ukm_recorder().GetEntriesByName(Entry::kEntryName).size());
......@@ -583,8 +733,9 @@ TEST_F(MediaEngagementSessionTest, RecordUkmMetrics) {
ukm_entry, Entry::kEngagement_IsHigh_ChangedName));
}
SetSignificantPlaybackRecordedForSession(session.get(), false);
session->RecordSignificantPlayback();
SetSignificantMediaElementPlaybackRecordedForSession(session.get(), false);
session->RecordSignificantMediaElementPlayback();
CommitPendingDataForSession(session.get());
RecordUkmMetricsForSession(session.get());
......@@ -633,7 +784,8 @@ TEST_F(MediaEngagementSessionTest, RecordUkmMetrics_Changed_NowHigh) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kNotRestored);
session->RecordSignificantPlayback();
session->RecordSignificantMediaElementPlayback();
CommitPendingDataForSession(session.get());
EXPECT_EQ(0u, test_ukm_recorder().GetEntriesByName(Entry::kEntryName).size());
......@@ -760,7 +912,7 @@ TEST_F(MediaEngagementSessionTest, DestructorCommitDataIfNeeded) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kNotRestored);
session->RecordSignificantPlayback();
session->RecordSignificantMediaElementPlayback();
// |session| was destructed.
}
......@@ -804,7 +956,7 @@ TEST_F(MediaEngagementSessionTest, DestructorCommitDataIfNeeded) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kNotRestored);
SetPendingDataToCommitForSession(session.get(), false, false, false);
SetPendingDataToCommitForSession(session.get(), false, false, false, false);
// |session| was destructed.
}
......@@ -829,7 +981,7 @@ TEST_F(MediaEngagementSessionTest, TimeSinceLastPlayback_NoPreviousRecord) {
// Advance in time and play.
test_clock()->Advance(base::TimeDelta::FromSeconds(42));
session->RecordSignificantPlayback();
session->RecordSignificantMediaElementPlayback();
EXPECT_TRUE(GetTimeSincePlaybackForSession(session.get()).is_zero());
}
......@@ -844,10 +996,11 @@ TEST_F(MediaEngagementSessionTest, TimeSinceLastPlayback_PreviousRecord) {
// Advance in time and play.
test_clock()->Advance(base::TimeDelta::FromSeconds(42));
service()->RecordPlayback(origin().GetURL());
RecordPlayback(origin().GetURL());
test_clock()->Advance(base::TimeDelta::FromSeconds(42));
session->RecordSignificantPlayback();
session->RecordSignificantMediaElementPlayback();
CommitPendingDataForSession(session.get());
EXPECT_EQ(42, GetTimeSincePlaybackForSession(session.get()).InSeconds());
}
......@@ -874,7 +1027,8 @@ TEST_F(MediaEngagementSessionTest, RestoredSession_PlaybackRecordsVisits) {
expected_playbacks = score.media_playbacks() + 1;
}
session->RecordSignificantPlayback();
session->RecordSignificantMediaElementPlayback();
CommitPendingDataForSession(session.get());
{
MediaEngagementScore score =
......@@ -901,7 +1055,7 @@ TEST_F(MediaEngagementSessionTest, StatusHistogram_NoPlayback) {
histogram_tester.ExpectBucketCount("Media.Engagement.Session", 0, 1);
}
TEST_F(MediaEngagementSessionTest, StatusHistogram_Playback) {
TEST_F(MediaEngagementSessionTest, StatusHistogram_AudioContext_Playback) {
base::HistogramTester histogram_tester;
histogram_tester.ExpectTotalCount("Media.Engagement.Session", 0);
......@@ -911,7 +1065,27 @@ TEST_F(MediaEngagementSessionTest, StatusHistogram_Playback) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kNotRestored);
session->RecordSignificantPlayback();
session->RecordSignificantAudioContextPlayback();
}
histogram_tester.ExpectTotalCount("Media.Engagement.Session", 2);
histogram_tester.ExpectTotalCount("Media.Engagement.Session.Restored", 0);
histogram_tester.ExpectBucketCount("Media.Engagement.Session", 0, 1);
histogram_tester.ExpectBucketCount("Media.Engagement.Session", 1, 1);
}
TEST_F(MediaEngagementSessionTest, StatusHistogram_Media_Playback) {
base::HistogramTester histogram_tester;
histogram_tester.ExpectTotalCount("Media.Engagement.Session", 0);
histogram_tester.ExpectTotalCount("Media.Engagement.Session.Restored", 0);
{
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kNotRestored);
session->RecordSignificantMediaElementPlayback();
}
histogram_tester.ExpectTotalCount("Media.Engagement.Session", 2);
......@@ -939,7 +1113,30 @@ TEST_F(MediaEngagementSessionTest, StatusHistogram_Restored_NoPlayback) {
histogram_tester.ExpectBucketCount("Media.Engagement.Session.Restored", 0, 1);
}
TEST_F(MediaEngagementSessionTest, StatusHistogram_Restored_Playback) {
TEST_F(MediaEngagementSessionTest,
StatusHistogram_Restored_AudioContext_Playback) {
base::HistogramTester histogram_tester;
histogram_tester.ExpectTotalCount("Media.Engagement.Session", 0);
histogram_tester.ExpectTotalCount("Media.Engagement.Session.Restored", 0);
{
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kRestored);
session->RecordSignificantAudioContextPlayback();
}
histogram_tester.ExpectTotalCount("Media.Engagement.Session", 2);
histogram_tester.ExpectTotalCount("Media.Engagement.Session.Restored", 2);
histogram_tester.ExpectBucketCount("Media.Engagement.Session", 0, 1);
histogram_tester.ExpectBucketCount("Media.Engagement.Session", 1, 1);
histogram_tester.ExpectBucketCount("Media.Engagement.Session.Restored", 0, 1);
histogram_tester.ExpectBucketCount("Media.Engagement.Session.Restored", 1, 1);
}
TEST_F(MediaEngagementSessionTest, StatusHistogram_Restored_Media_Playback) {
base::HistogramTester histogram_tester;
histogram_tester.ExpectTotalCount("Media.Engagement.Session", 0);
......@@ -949,7 +1146,7 @@ TEST_F(MediaEngagementSessionTest, StatusHistogram_Restored_Playback) {
scoped_refptr<MediaEngagementSession> session = new MediaEngagementSession(
service(), origin(), MediaEngagementSession::RestoreType::kRestored);
session->RecordSignificantPlayback();
session->RecordSignificantMediaElementPlayback();
}
histogram_tester.ExpectTotalCount("Media.Engagement.Session", 2);
......
......@@ -31,10 +31,16 @@ MediaEngagementWebUIBrowserTest.prototype = {
GEN('MediaEngagementService* service =');
GEN(' MediaEngagementServiceFactory::GetForProfile(');
GEN(' browser()->profile());');
GEN('service->RecordVisit(GURL("' + EXAMPLE_URL_1 + '"));');
GEN('service->RecordVisit(GURL("' + EXAMPLE_URL_2 + '"));');
GEN('service->RecordPlayback(GURL("' + EXAMPLE_URL_1 + '"));');
GEN('service->RecordPlayback(GURL("' + EXAMPLE_URL_2 + '"));');
GEN('MediaEngagementScore score1 =');
GEN(' service->CreateEngagementScore(GURL("' + EXAMPLE_URL_1 + '"));');
GEN('score1.IncrementVisits();');
GEN('score1.IncrementMediaPlaybacks();');
GEN('score1.Commit();');
GEN('MediaEngagementScore score2 =');
GEN(' service->CreateEngagementScore(GURL("' + EXAMPLE_URL_2 + '"));');
GEN('score2.IncrementVisits();');
GEN('score2.IncrementMediaPlaybacks();');
GEN('score2.Commit();');
},
extraLibraries: [
......
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