Index: content/browser/media/android/media_web_contents_observer_android.cc |
diff --git a/content/browser/media/android/media_web_contents_observer_android.cc b/content/browser/media/android/media_web_contents_observer_android.cc |
index f5f53b36459d8f185b7164d162338c8414864424..5bb943137df8ddca5ed01ecb25c41510b0d9499f 100644 |
--- a/content/browser/media/android/media_web_contents_observer_android.cc |
+++ b/content/browser/media/android/media_web_contents_observer_android.cc |
@@ -4,6 +4,7 @@ |
#include "content/browser/media/android/media_web_contents_observer_android.h" |
+#include "base/callback.h" |
#include "content/browser/media/android/browser_media_player_manager.h" |
#include "content/browser/media/android/browser_media_session_manager.h" |
#include "content/browser/media/android/media_session.h" |
@@ -87,6 +88,14 @@ void MediaWebContentsObserverAndroid::RenderFrameDeleted( |
RenderFrameHost* render_frame_host) { |
MediaWebContentsObserver::RenderFrameDeleted(render_frame_host); |
+ const int routing_id = render_frame_host->GetRoutingID(); |
+ for (auto it = focus_waiters_.begin(); it != focus_waiters_.end();) { |
+ if (it->first == routing_id) |
+ it = focus_waiters_.erase(it); |
+ else |
+ ++it; |
+ } |
+ |
for (auto it = media_session_map_.begin(); it != media_session_map_.end();) { |
if (it->first.first == render_frame_host) |
it = media_session_map_.erase(it); |
@@ -132,6 +141,23 @@ bool MediaWebContentsObserverAndroid::OnMessageReceived( |
return false; |
} |
+void MediaWebContentsObserverAndroid::WaitForAudioFocusAsyncInternal( |
+ int render_frame_id, |
+ const base::Closure& focus_cb) { |
+ // See if audio focus has already been approved for the given render frame; we |
+ // don't care which delegate it corresponds to, just that one has approval and |
+ // is actively playing audio. |
+ for (const auto& kv : media_session_map_) { |
+ if (kv.first.first->GetRoutingID() == render_frame_id && |
+ kv.second->is_playing()) { |
mlamouri (slow - plz ping)
2016/02/03 15:20:51
Couldn't a controller be playing even though it do
|
+ focus_cb.Run(); |
+ return; |
+ } |
+ } |
+ |
+ focus_waiters_.push_back(FocusWaiter(render_frame_id, focus_cb)); |
+} |
+ |
void MediaWebContentsObserverAndroid::OnMediaPlayerDelegateMessageReceived( |
const IPC::Message& msg, |
RenderFrameHost* render_frame_host) { |
@@ -297,20 +323,34 @@ void MediaWebContentsObserverAndroid::OnMediaPlaying( |
// In this case, try to reinitialize it with the new settings. If they are |
// the same, this is a no-op. If the reinitialize fails, destroy the |
// controller. A later playback attempt will create a new controller. |
- auto it = media_session_map_.find(id); |
- if (it != media_session_map_.end()) { |
- if (!it->second->Initialize(has_audio, is_remote, duration)) |
- media_session_map_.erase(it); |
- return; |
+ auto session_it = media_session_map_.find(id); |
+ if (session_it != media_session_map_.end()) { |
+ if (!session_it->second->Initialize(has_audio, is_remote, duration)) { |
+ media_session_map_.erase(session_it); |
+ return; |
+ } |
+ } else { |
+ scoped_ptr<MediaSessionController> controller( |
+ new MediaSessionController(id, this)); |
+ |
+ if (!controller->Initialize(has_audio, is_remote, duration)) |
+ return; |
+ |
+ media_session_map_[id] = std::move(controller); |
} |
- scoped_ptr<MediaSessionController> controller( |
- new MediaSessionController(id, this)); |
- |
- if (!controller->Initialize(has_audio, is_remote, duration)) |
- return; |
- |
- media_session_map_[id] = std::move(controller); |
+ // Notify all focus waiters for the render frame that audio output is allowed, |
+ // delegates will still pause audio as necessary in response to focus changes |
+ // from the media session. |
+ const int routing_id = render_frame_host->GetRoutingID(); |
+ for (auto it = focus_waiters_.begin(); it != focus_waiters_.end();) { |
+ if (it->first == routing_id) { |
+ it->second.Run(); |
+ it = focus_waiters_.erase(it); |
+ } else { |
+ ++it; |
+ } |
+ } |
} |
} // namespace content |