| Index: content/renderer/media/android/webmediaplayer_android.cc
|
| diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
|
| index 765a87f41d2688506e16a837307870d5bf70d057..26d50ebf8542464d15c23acb4409f97565ab9272 100644
|
| --- a/content/renderer/media/android/webmediaplayer_android.cc
|
| +++ b/content/renderer/media/android/webmediaplayer_android.cc
|
| @@ -184,11 +184,11 @@ WebMediaPlayerAndroid::WebMediaPlayerAndroid(
|
| int frame_id,
|
| bool enable_texture_copy,
|
| const media::WebMediaPlayerParams& params)
|
| - : RenderFrameObserver(RenderFrame::FromWebFrame(frame)),
|
| - frame_(frame),
|
| + : frame_(frame),
|
| client_(client),
|
| encrypted_client_(encrypted_client),
|
| delegate_(delegate),
|
| + delegate_id_(0),
|
| defer_load_cb_(params.defer_load_cb()),
|
| buffered_(static_cast<size_t>(1)),
|
| media_task_runner_(params.media_task_runner()),
|
| @@ -226,6 +226,9 @@ WebMediaPlayerAndroid::WebMediaPlayerAndroid(
|
| frame_id_(frame_id),
|
| enable_texture_copy_(enable_texture_copy),
|
| suppress_deleting_texture_(false),
|
| + playback_completed_(false),
|
| + volume_(1.0),
|
| + volume_multiplier_(1.0),
|
| weak_factory_(this) {
|
| DCHECK(player_manager_);
|
| DCHECK(cdm_factory_);
|
| @@ -233,13 +236,15 @@ WebMediaPlayerAndroid::WebMediaPlayerAndroid(
|
| DCHECK(main_thread_checker_.CalledOnValidThread());
|
| stream_texture_factory_->AddObserver(this);
|
|
|
| + if (delegate_)
|
| + delegate_id_ = delegate_->AddObserver(this);
|
| +
|
| player_id_ = player_manager_->RegisterMediaPlayer(this);
|
|
|
| #if defined(VIDEO_HOLE)
|
| - const RendererPreferences& prefs =
|
| - static_cast<RenderFrameImpl*>(render_frame())
|
| - ->render_view()
|
| - ->renderer_preferences();
|
| + const RendererPreferences& prefs = RenderFrameImpl::FromRoutingID(frame_id)
|
| + ->render_view()
|
| + ->renderer_preferences();
|
| force_use_overlay_embedded_video_ = prefs.use_view_overlay_for_all_video;
|
| if (force_use_overlay_embedded_video_ ||
|
| player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo()) {
|
| @@ -282,8 +287,10 @@ WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
|
| current_frame_ = NULL;
|
| }
|
|
|
| - if (delegate_)
|
| - delegate_->PlayerGone(this);
|
| + if (delegate_) {
|
| + delegate_->PlayerGone(delegate_id_);
|
| + delegate_->RemoveObserver(delegate_id_);
|
| + }
|
|
|
| stream_texture_factory_->RemoveObserver(this);
|
|
|
| @@ -429,9 +436,13 @@ void WebMediaPlayerAndroid::play() {
|
| EstablishSurfaceTexturePeer();
|
| }
|
|
|
| - if (paused())
|
| - player_manager_->Start(player_id_);
|
| + // UpdatePlayingState() must be run before calling Start() to ensure that the
|
| + // browser side MediaPlayerAndroid values for hasAudio() and hasVideo() take
|
| + // precedent over the guesses that we make based on mime type.
|
| + const bool is_paused = paused();
|
| UpdatePlayingState(true);
|
| + if (is_paused)
|
| + player_manager_->Start(player_id_);
|
| UpdateNetworkState(WebMediaPlayer::NetworkStateLoading);
|
| }
|
|
|
| @@ -452,6 +463,7 @@ void WebMediaPlayerAndroid::seek(double seconds) {
|
| DCHECK(main_thread_checker_.CalledOnValidThread());
|
| DVLOG(1) << __FUNCTION__ << "(" << seconds << ")";
|
|
|
| + playback_completed_ = false;
|
| base::TimeDelta new_seek_time = base::TimeDelta::FromSecondsD(seconds);
|
|
|
| if (seeking_) {
|
| @@ -495,13 +507,12 @@ bool WebMediaPlayerAndroid::supportsSave() const {
|
| return false;
|
| }
|
|
|
| -void WebMediaPlayerAndroid::setRate(double rate) {
|
| - NOTIMPLEMENTED();
|
| -}
|
| +void WebMediaPlayerAndroid::setRate(double rate) {}
|
|
|
| void WebMediaPlayerAndroid::setVolume(double volume) {
|
| DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - player_manager_->SetVolume(player_id_, volume);
|
| + volume_ = volume;
|
| + player_manager_->SetVolume(player_id_, volume_ * volume_multiplier_);
|
| }
|
|
|
| void WebMediaPlayerAndroid::setSinkId(
|
| @@ -852,6 +863,8 @@ void WebMediaPlayerAndroid::OnPlaybackComplete() {
|
| // playing after seek completes.
|
| if (seeking_ && seek_time_ == base::TimeDelta())
|
| player_manager_->Start(player_id_);
|
| + else
|
| + playback_completed_ = true;
|
| }
|
|
|
| void WebMediaPlayerAndroid::OnBufferingUpdate(int percentage) {
|
| @@ -1088,6 +1101,9 @@ void WebMediaPlayerAndroid::OnPlayerReleased() {
|
| if (is_playing_)
|
| OnMediaPlayerPause();
|
|
|
| + if (delegate_)
|
| + delegate_->PlayerGone(delegate_id_);
|
| +
|
| #if defined(VIDEO_HOLE)
|
| last_computed_rect_ = gfx::RectF();
|
| #endif // defined(VIDEO_HOLE)
|
| @@ -1102,6 +1118,8 @@ void WebMediaPlayerAndroid::SuspendAndReleaseResources() {
|
| case WebMediaPlayer::NetworkStateLoaded:
|
| Pause(false);
|
| client_->playbackStateChanged();
|
| + if (delegate_)
|
| + delegate_->PlayerGone(delegate_id_);
|
| break;
|
| // If a WebMediaPlayer instance has entered into one of these states,
|
| // the internal network state in HTMLMediaElement could be set to empty.
|
| @@ -1117,12 +1135,6 @@ void WebMediaPlayerAndroid::SuspendAndReleaseResources() {
|
| SetNeedsEstablishPeer(true);
|
| }
|
|
|
| -void WebMediaPlayerAndroid::OnDestruct() {
|
| - NOTREACHED() << "WebMediaPlayer should be destroyed before any "
|
| - "RenderFrameObserver::OnDestruct() gets called when "
|
| - "the RenderFrame goes away.";
|
| -}
|
| -
|
| void WebMediaPlayerAndroid::InitializePlayer(
|
| const GURL& url,
|
| const GURL& first_party_for_cookies,
|
| @@ -1133,7 +1145,7 @@ void WebMediaPlayerAndroid::InitializePlayer(
|
| allow_stored_credentials_ = allow_stored_credentials;
|
| player_manager_->Initialize(
|
| player_type_, player_id_, url, first_party_for_cookies, demuxer_client_id,
|
| - frame_->document().url(), allow_stored_credentials);
|
| + frame_->document().url(), allow_stored_credentials, delegate_id_);
|
| is_player_initialized_ = true;
|
|
|
| if (is_fullscreen_)
|
| @@ -1373,10 +1385,20 @@ void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) {
|
| interpolator_.StopInterpolating();
|
|
|
| if (delegate_) {
|
| - if (is_playing)
|
| - delegate_->DidPlay(this);
|
| - else
|
| - delegate_->DidPause(this);
|
| + if (is_playing) {
|
| + // We must specify either video or audio to the delegate, but neither may
|
| + // be known at this point -- there are no video only containers, so only
|
| + // send audio if we know for sure its audio. The browser side player will
|
| + // fill in the correct value later for media sessions.
|
| + delegate_->DidPlay(delegate_id_, hasVideo(), !hasVideo(), isRemote(),
|
| + duration_);
|
| + } else {
|
| + // Even if OnPlaybackComplete() has not been called yet, Blink may have
|
| + // already fired the ended event based on current time relative to
|
| + // duration -- so we need to check both possibilities here.
|
| + delegate_->DidPause(delegate_id_,
|
| + playback_completed_ || currentTime() >= duration());
|
| + }
|
| }
|
| }
|
|
|
| @@ -1759,6 +1781,31 @@ void WebMediaPlayerAndroid::OnWaitingForDecryptionKey() {
|
| encrypted_client_->didResumePlaybackBlockedForKey();
|
| }
|
|
|
| +void WebMediaPlayerAndroid::OnHidden() {
|
| + // RendererMediaPlayerManager will not call SuspendAndReleaseResources() if we
|
| + // were already in the paused state; thus notify the MediaWebContentsObserver
|
| + // that we've been hidden so any lingering MediaSessions are released.
|
| + if (delegate_)
|
| + delegate_->PlayerGone(delegate_id_);
|
| +}
|
| +
|
| +void WebMediaPlayerAndroid::OnShown() {}
|
| +
|
| +void WebMediaPlayerAndroid::OnPlay() {
|
| + play();
|
| + client_->playbackStateChanged();
|
| +}
|
| +
|
| +void WebMediaPlayerAndroid::OnPause() {
|
| + pause();
|
| + client_->playbackStateChanged();
|
| +}
|
| +
|
| +void WebMediaPlayerAndroid::OnVolumeMultiplierUpdate(double multiplier) {
|
| + volume_multiplier_ = multiplier;
|
| + setVolume(volume_);
|
| +}
|
| +
|
| void WebMediaPlayerAndroid::OnCdmContextReady(media::CdmContext* cdm_context) {
|
| DCHECK(!cdm_context_);
|
|
|
|
|