| Index: media/blink/webmediaplayer_impl.cc
 | 
| diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
 | 
| index bea9a92a34c679b3dc60456d9d76b9d03d7d1536..3f5ead5a4357ced4799371f487e5d9d481a3a796 100644
 | 
| --- a/media/blink/webmediaplayer_impl.cc
 | 
| +++ b/media/blink/webmediaplayer_impl.cc
 | 
| @@ -121,10 +121,6 @@ bool IsBackgroundedSuspendEnabled() {
 | 
|  #endif
 | 
|  }
 | 
|  
 | 
| -bool IsResumeBackgroundVideosEnabled() {
 | 
| -  return base::FeatureList::IsEnabled(kResumeBackgroundVideo);
 | 
| -}
 | 
| -
 | 
|  bool IsBackgroundVideoTrackOptimizationEnabled() {
 | 
|    return base::FeatureList::IsEnabled(kBackgroundVideoTrackOptimization);
 | 
|  }
 | 
| @@ -1439,15 +1435,10 @@ void WebMediaPlayerImpl::OnFrameHidden() {
 | 
|  
 | 
|    // OnFrameHidden() can be called when frame is closed, then IsHidden() will
 | 
|    // return false, so check explicitly.
 | 
| -  if (IsHidden()) {
 | 
| -    if (ShouldPauseVideoWhenHidden()) {
 | 
| -      PauseVideoIfNeeded();
 | 
| -      return;
 | 
| -    } else {
 | 
| -      DisableVideoTrackIfNeeded();
 | 
| -    }
 | 
| -  }
 | 
| +  if (IsHidden())
 | 
| +    client_->wasBackgrounded();
 | 
|  
 | 
| +  UpdateBackgroundVideoOptimizationState();
 | 
|    UpdatePlayState();
 | 
|  
 | 
|    // Schedule suspended playing media to be paused if the user doesn't come back
 | 
| @@ -1482,14 +1473,14 @@ void WebMediaPlayerImpl::OnFrameShown() {
 | 
|                     base::Unretained(compositor_), new_processed_frame_cb));
 | 
|    }
 | 
|  
 | 
| +  EnableVideoTrackIfNeeded();
 | 
| +
 | 
|    if (paused_when_hidden_) {
 | 
|      paused_when_hidden_ = false;
 | 
|      OnPlay();  // Calls UpdatePlayState() so return afterwards.
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| -  EnableVideoTrackIfNeeded();
 | 
| -
 | 
|    UpdatePlayState();
 | 
|  }
 | 
|  
 | 
| @@ -1954,25 +1945,14 @@ WebMediaPlayerImpl::UpdatePlayState_ComputePlayState(bool is_remote,
 | 
|    // errors.
 | 
|    bool has_error = IsNetworkStateError(network_state_);
 | 
|  
 | 
| -  // After HaveMetadata, we know which tracks are present and the duration.
 | 
| -  bool have_metadata = ready_state_ >= WebMediaPlayer::ReadyStateHaveMetadata;
 | 
| -
 | 
|    // After HaveFutureData, Blink will call play() if the state is not paused;
 | 
|    // prior to this point |paused_| is not accurate.
 | 
|    bool have_future_data =
 | 
|        highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData;
 | 
|  
 | 
| -  // Background suspend is not enabled for audio-only players unless paused,
 | 
| -  // though in the case of audio-only the session should be kept.
 | 
| -  // Videos are not suspended if the user resumed the playback via the remote
 | 
| -  // controls earlier and it's still playing.
 | 
| -  bool is_backgrounded_video = is_backgrounded && have_metadata && hasVideo();
 | 
| -  bool can_play_backgrounded = is_backgrounded_video && !is_remote &&
 | 
| -                               hasAudio() && IsResumeBackgroundVideosEnabled();
 | 
| -  bool is_background_playing = delegate_->IsBackgroundVideoPlaybackUnlocked();
 | 
| -  bool background_suspended = can_auto_suspend && is_backgrounded_video &&
 | 
| -                              !(can_play_backgrounded && is_background_playing);
 | 
| -  bool background_pause_suspended =
 | 
| +  // Background suspend is only enabled for paused players.
 | 
| +  // In the case of players with audio the session should be kept.
 | 
| +  bool background_suspended =
 | 
|        can_auto_suspend && is_backgrounded && paused_ && have_future_data;
 | 
|  
 | 
|    // Idle suspension is allowed prior to have future data since there exist
 | 
| @@ -1992,8 +1972,7 @@ WebMediaPlayerImpl::UpdatePlayState_ComputePlayState(bool is_remote,
 | 
|  
 | 
|    // Combined suspend state.
 | 
|    result.is_suspended = is_remote || must_suspend || idle_suspended ||
 | 
| -                        background_suspended || background_pause_suspended ||
 | 
| -                        can_stay_suspended;
 | 
| +                        background_suspended || can_stay_suspended;
 | 
|  
 | 
|    // We do not treat |playback_rate_| == 0 as paused. For the media session,
 | 
|    // being paused implies displaying a play button, which is incorrect in this
 | 
| @@ -2015,20 +1994,15 @@ WebMediaPlayerImpl::UpdatePlayState_ComputePlayState(bool is_remote,
 | 
|    // TODO(sandersd): If Blink told us the paused state sooner, we could create
 | 
|    // the media session sooner.
 | 
|    bool can_play = !has_error && !is_remote && have_future_data;
 | 
| -  bool has_session_playing = can_play && !must_suspend && !background_suspended;
 | 
| -
 | 
| -  // |has_session_suspended| means the player is suspended from the media
 | 
| -  // element point of view but paused and can be resumed from the delegate point
 | 
| -  // of view. Therefore it behaves like |paused_| for the delegate.
 | 
| -  bool has_session_suspended = can_play && !must_suspend &&
 | 
| -                               background_suspended && can_play_backgrounded;
 | 
| -
 | 
| -  bool has_session = has_session_playing || has_session_suspended;
 | 
| +  bool has_session =
 | 
| +      can_play && !must_suspend && hasAudio() &&
 | 
| +      (!hasVideo() || !is_backgrounded || !IsBackgroundedSuspendEnabled() ||
 | 
| +       base::FeatureList::IsEnabled(kResumeBackgroundVideo));
 | 
|  
 | 
|    if (!has_session) {
 | 
|      result.delegate_state = DelegateState::GONE;
 | 
|      result.is_idle = delegate_->IsIdle(delegate_id_);
 | 
| -  } else if (paused_ || has_session_suspended) {
 | 
| +  } else if (paused_) {
 | 
|      // TODO(sandersd): Is it possible to have a suspended session, be ended,
 | 
|      // and not be paused? If so we should be in a PLAYING state.
 | 
|      result.delegate_state =
 | 
| @@ -2106,8 +2080,9 @@ void WebMediaPlayerImpl::FinishMemoryUsageReport(int64_t demuxer_memory_usage) {
 | 
|  }
 | 
|  
 | 
|  void WebMediaPlayerImpl::ScheduleIdlePauseTimer() {
 | 
| -  // Only schedule the pause timer if we're playing and are suspended.
 | 
| -  if (paused_ || !pipeline_controller_.IsSuspended())
 | 
| +  // Only schedule the pause timer if we're not paused or paused but going to
 | 
| +  // resume when foregrounded, and are suspended.
 | 
| +  if ((paused_ && !paused_when_hidden_) || !pipeline_controller_.IsSuspended())
 | 
|      return;
 | 
|  
 | 
|  #if defined(OS_ANDROID)
 | 
| @@ -2155,14 +2130,24 @@ void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) {
 | 
|  }
 | 
|  
 | 
|  bool WebMediaPlayerImpl::ShouldPauseVideoWhenHidden() const {
 | 
| -#if !defined(OS_ANDROID)
 | 
| -  // On desktop, this behavior is behind the feature flag.
 | 
| -  if (!IsBackgroundVideoTrackOptimizationEnabled())
 | 
| -    return false;
 | 
| +  // If suspending background video, pause any video that's not remoted or
 | 
| +  // not unlocked to play in the background.
 | 
| +  if (IsBackgroundedSuspendEnabled()) {
 | 
| +    if (!hasVideo())
 | 
| +      return false;
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +    if (isRemote())
 | 
| +      return false;
 | 
|  #endif
 | 
|  
 | 
| -  // Pause video-only players that match the criteria for being optimized.
 | 
| -  return !hasAudio() && IsBackgroundOptimizationCandidate();
 | 
| +    return !hasAudio() || !client_->isBackgroundVideoPlaybackUnlocked();
 | 
| +  }
 | 
| +
 | 
| +  // Otherwise only pause if the optimization is on and it's a video-only
 | 
| +  // optimization candidate.
 | 
| +  return IsBackgroundVideoTrackOptimizationEnabled() && !hasAudio() &&
 | 
| +         IsBackgroundOptimizationCandidate();
 | 
|  }
 | 
|  
 | 
|  bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const {
 | 
| @@ -2293,7 +2278,6 @@ void WebMediaPlayerImpl::ReportTimeFromForegroundToFirstFrame(
 | 
|                          time_to_first_frame);
 | 
|    }
 | 
|  }
 | 
| -
 | 
|  void WebMediaPlayerImpl::SwitchRenderer(bool disable_pipeline_auto_suspend) {
 | 
|    DCHECK(main_task_runner_->BelongsToCurrentThread());
 | 
|    disable_pipeline_auto_suspend_ = disable_pipeline_auto_suspend;
 | 
| 
 |