Skip to content

Commit

Permalink
[Media Engagement] Track AudioContext playbacks
Browse files Browse the repository at this point in the history
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: Mounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587899}
  • Loading branch information
beccahughes authored and Commit Bot committed Aug 31, 2018
1 parent b3b2559 commit e4555db
Show file tree
Hide file tree
Showing 12 changed files with 711 additions and 145 deletions.
2 changes: 1 addition & 1 deletion chrome/browser/media/media_engagement_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
66 changes: 63 additions & 3 deletions chrome/browser/media/media_engagement_contents_observer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand All @@ -339,7 +370,7 @@ void MediaEngagementContentsObserver::OnSignificantMediaPlaybackTimeForPage() {
if (!audible_helper->WasRecentlyAudible())
return;

session_->RecordSignificantPlayback();
session_->RecordSignificantAudioContextPlayback();
}

void MediaEngagementContentsObserver::RecordInsignificantReasons(
Expand Down Expand Up @@ -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()) {
Expand All @@ -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);
Expand Down
16 changes: 16 additions & 0 deletions chrome/browser/media/media_engagement_contents_observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>);

Expand All @@ -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:
Expand Down

0 comments on commit e4555db

Please sign in to comment.