Index: content/browser/renderer_host/media/audio_renderer_host.cc |
diff --git a/content/browser/renderer_host/media/audio_renderer_host.cc b/content/browser/renderer_host/media/audio_renderer_host.cc |
index ad9ca1d450ca82be4fe7db0f33a072d7d444d7c3..f09ca270ce59482be07c60b20a7e9dda6b429c7b 100644 |
--- a/content/browser/renderer_host/media/audio_renderer_host.cc |
+++ b/content/browser/renderer_host/media/audio_renderer_host.cc |
@@ -20,6 +20,7 @@ |
#include "content/browser/media/audio_stream_monitor.h" |
#include "content/browser/media/capture/audio_mirroring_manager.h" |
#include "content/browser/media/media_internals.h" |
+#include "content/browser/media/media_web_contents_observer.h" |
#include "content/browser/renderer_host/media/audio_input_device_manager.h" |
#include "content/browser/renderer_host/media/audio_sync_reader.h" |
#include "content/browser/renderer_host/media/media_stream_manager.h" |
@@ -159,6 +160,8 @@ class AudioRendererHost::AudioEntry |
bool playing() const { return playing_; } |
void set_playing(bool playing) { playing_ = playing; } |
+ void update_last_pause_time() { last_pause_time_ = base::TimeTicks::Now(); } |
+ base::TimeTicks last_pause_time() { return last_pause_time_; } |
private: |
// media::AudioOutputController::EventHandler implementation. |
@@ -183,6 +186,8 @@ class AudioRendererHost::AudioEntry |
const scoped_refptr<media::AudioOutputController> controller_; |
bool playing_; |
+ |
+ base::TimeTicks last_pause_time_; |
}; |
AudioRendererHost::AudioEntry::AudioEntry( |
@@ -614,6 +619,30 @@ void AudioRendererHost::OnPlayStream(int stream_id) { |
return; |
} |
+ if (entry->controller()->GetAudioParameters().effects() & |
+ media::AudioParameters::FOCUSABLE) { |
+ MediaWebContentsObserver::WaitForAudioFocusAsync( |
+ render_process_id_, entry->render_frame_id(), |
+ base::Bind(&AudioRendererHost::OnFocusAvailable, this, stream_id, |
+ base::TimeTicks::Now())); |
+ } else { |
+ entry->controller()->Play(); |
+ audio_log_->OnStarted(stream_id); |
+ } |
+} |
+ |
+void AudioRendererHost::OnFocusAvailable(int stream_id, |
+ base::TimeTicks play_time) { |
+ // Abort the playback if: |
+ // - The entry has been destroyed while focus was requested. |
+ // - A subsequent pause has come through. |
+ // |
+ // A focus request never fails via this path. If it's denied a pause request |
+ // will be issues directly to the player. |
+ AudioEntry* entry = LookupById(stream_id); |
+ if (!entry || play_time < entry->last_pause_time()) |
+ return; |
+ |
entry->controller()->Play(); |
audio_log_->OnStarted(stream_id); |
} |
@@ -627,6 +656,7 @@ void AudioRendererHost::OnPauseStream(int stream_id) { |
return; |
} |
+ entry->update_last_pause_time(); |
entry->controller()->Pause(); |
audio_log_->OnStopped(stream_id); |
} |