Chromium Code Reviews| 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 |