blob: 925f528a050acaa08ba32892e06571080ed941e0 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_MEDIA_MEDIA_ENGAGEMENT_CONTENTS_OBSERVER_H_
#define CHROME_BROWSER_MEDIA_MEDIA_ENGAGEMENT_CONTENTS_OBSERVER_H_
#include "content/public/browser/web_contents_observer.h"
namespace gfx {
class Size;
} // namespace gfx
class MediaEngagementContentsObserverTest;
class MediaEngagementService;
class MediaEngagementContentsObserver : public content::WebContentsObserver {
public:
~MediaEngagementContentsObserver() override;
// WebContentsObserver implementation.
void WebContentsDestroyed() override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
void ReadyToCommitNavigation(
content::NavigationHandle* navigation_handle) override;
void WasShown() override;
void WasHidden() override;
void MediaStartedPlaying(const MediaPlayerInfo& media_player_info,
const MediaPlayerId& media_player_id) override;
void MediaStoppedPlaying(const MediaPlayerInfo& media_player_info,
const MediaPlayerId& media_player_id) override;
void DidUpdateAudioMutingState(bool muted) override;
void MediaMutedStatusChanged(const MediaPlayerId& id, bool muted) override;
void MediaResized(const gfx::Size& size, const MediaPlayerId& id) override;
static const gfx::Size kSignificantSize;
static const char* const kHistogramScoreAtPlaybackName;
private:
FRIEND_TEST_ALL_PREFIXES(MediaEngagementContentsObserverTest,
RecordInsignificantReason);
FRIEND_TEST_ALL_PREFIXES(MediaEngagementContentsObserverTest,
RecordInsignificantReason_NotAdded_AfterFirstTime);
// Only MediaEngagementService can create a MediaEngagementContentsObserver.
friend MediaEngagementService;
friend MediaEngagementContentsObserverTest;
friend class MediaEngagementBrowserTest;
MediaEngagementContentsObserver(content::WebContents* web_contents,
MediaEngagementService* service);
// This enum is used to record a histogram and should not be renumbered.
enum class InsignificantPlaybackReason {
// The frame size of the video is too small.
kFrameSizeTooSmall = 0,
// The player was muted.
kAudioMuted,
// The media is paused.
kMediaPaused,
// No audio track was present on the media.
kNoAudioTrack,
// This is always recorded to the histogram so we can see the number
// of events that occured.
kCount,
// Add new items before this one, always keep this one at the end.
kReasonMax,
};
enum class InsignificantHistogram {
// The player isn't currently significant and can't be because it
// doesn't meet all the criteria (first time only).
kPlayerNotAddedFirstTime = 0,
// The player isn't currently significant and can't be because it
// doesn't meet all the critera (after the first time).
kPlayerNotAddedAfterFirstTime,
// The player was significant but no longer meets the criteria.
kPlayerRemoved,
};
void OnSignificantMediaPlaybackTime();
bool AreConditionsMet() const;
void UpdateTimer();
void SetTimerForTest(std::unique_ptr<base::Timer> timer);
// |this| is owned by |service_|.
MediaEngagementService* service_;
// Timer that will fire when the playback time reaches the minimum for
// significant media playback.
std::unique_ptr<base::Timer> playback_timer_;
// Set of active players that can produce a significant playback. In other
// words, whether this set is empty can be used to know if there is a
// significant playback.
std::set<MediaPlayerId> significant_players_;
// A structure containing all the information we have about a player's state.
struct PlayerState {
base::Optional<bool> muted;
base::Optional<bool> playing; // Currently playing.
base::Optional<bool> significant_size; // The video track has at least
// a certain frame size.
base::Optional<bool> has_audio; // The media has an audio track.
// The engagement score of the origin at playback has been recorded
// to a histogram.
bool score_recorded = false;
// The reasons why the player was not significant have been recorded
// to a histogram.
bool reasons_recorded = false;
PlayerState();
PlayerState& operator=(const PlayerState&);
};
std::map<MediaPlayerId, PlayerState> player_states_;
PlayerState& GetPlayerState(const MediaPlayerId& id);
void ClearPlayerStates();
// Inserts/removes players from significant_players_ based on whether
// they are considered significant by GetInsignificantPlayerReason.
void MaybeInsertRemoveSignificantPlayer(const MediaPlayerId& id);
// Returns a vector containing InsignificantPlaybackReason's why a player
// would not be considered significant.
std::vector<MediaEngagementContentsObserver::InsignificantPlaybackReason>
GetInsignificantPlayerReasons(const PlayerState& state);
// Records why a player is not significant to a historgram.
void RecordInsignificantReasons(
std::vector<InsignificantPlaybackReason> reasons,
const PlayerState& state,
InsignificantHistogram histogram);
// Returns whether we have recieved all the state information about a
// player in order to be able to make a decision about it.
bool IsPlayerStateComplete(const PlayerState& state);
// Returns whether the player is considered to be significant and record
// any reasons why not to a histogram.
bool IsSignificantPlayerAndRecord(
const MediaPlayerId& id,
MediaEngagementContentsObserver::InsignificantHistogram histogram);
static const char* const kHistogramSignificantNotAddedAfterFirstTimeName;
static const char* const kHistogramSignificantNotAddedFirstTimeName;
static const char* const kHistogramSignificantRemovedName;
static const int kMaxInsignificantPlaybackReason;
// Record the score and change in score to UKM.
void RecordUkmMetrics();
bool is_visible_ = false;
bool significant_playback_recorded_ = false;
// Records the engagement score for the current origin to a histogram so we
// can identify whether the playback would have been blocked.
void RecordEngagementScoreToHistogramAtPlayback(const MediaPlayerId& id);
url::Origin committed_origin_;
static const base::TimeDelta kSignificantMediaPlaybackTime;
DISALLOW_COPY_AND_ASSIGN(MediaEngagementContentsObserver);
};
#endif // CHROME_BROWSER_MEDIA_MEDIA_ENGAGEMENT_CONTENTS_OBSERVER_H_