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 1b48959e9bad9ae15030a60b37bcce87c4d49bd8..c9107906f7d8ad43cb8e9d811e6c6ed7cd044817 100644 |
--- a/content/browser/media/android/media_web_contents_observer_android.cc |
+++ b/content/browser/media/android/media_web_contents_observer_android.cc |
@@ -6,9 +6,12 @@ |
#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" |
+#include "content/browser/media/android/media_session_controller.h" |
#include "content/browser/media/android/media_session_observer.h" |
#include "content/browser/media/cdm/browser_cdm_manager.h" |
#include "content/browser/web_contents/web_contents_impl.h" |
+#include "content/common/media/media_player_delegate_messages.h" |
#include "content/common/media/media_player_messages_android.h" |
#include "content/common/media/media_session_messages_android.h" |
#include "content/public/browser/render_frame_host.h" |
@@ -58,6 +61,19 @@ MediaWebContentsObserverAndroid::GetMediaSessionManager( |
return manager; |
} |
+bool MediaWebContentsObserverAndroid::RequestPlay( |
+ RenderFrameHost* render_frame_host, |
+ int delegate_id, |
+ bool has_audio, |
+ bool is_remote, |
+ base::TimeDelta duration) { |
+ // |has_video| forced to true since the value doesn't matter at present. |
+ OnMediaPlaying(render_frame_host, delegate_id, true, has_audio, is_remote, |
+ duration); |
+ return media_session_map_.find(MediaPlayerId( |
+ render_frame_host, delegate_id)) != media_session_map_.end(); |
+} |
+ |
#if defined(VIDEO_HOLE) |
void MediaWebContentsObserverAndroid::OnFrameInfoUpdated() { |
for (auto it = media_player_managers_.begin(); |
@@ -71,6 +87,13 @@ void MediaWebContentsObserverAndroid::RenderFrameDeleted( |
RenderFrameHost* render_frame_host) { |
MediaWebContentsObserver::RenderFrameDeleted(render_frame_host); |
+ 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); |
+ else |
+ ++it; |
+ } |
+ |
// Always destroy the media players before CDMs because we do not support |
// detaching CDMs from media players yet. See http://crbug.com/330324 |
media_player_managers_.erase(render_frame_host); |
@@ -90,6 +113,10 @@ void MediaWebContentsObserverAndroid::RenderFrameDeleted( |
bool MediaWebContentsObserverAndroid::OnMessageReceived( |
const IPC::Message& msg, |
RenderFrameHost* render_frame_host) { |
+ // Receive play/pause/destroyed messages, but don't mark as processed so they |
+ // are also handled by MediaWebContentsObserver. |
+ OnMediaPlayerDelegateMessageReceived(msg, render_frame_host); |
+ |
if (MediaWebContentsObserver::OnMessageReceived(msg, render_frame_host)) |
return true; |
@@ -99,6 +126,19 @@ bool MediaWebContentsObserverAndroid::OnMessageReceived( |
return OnMediaPlayerSetCdmMessageReceived(msg, render_frame_host); |
} |
+void MediaWebContentsObserverAndroid::OnMediaPlayerDelegateMessageReceived( |
+ const IPC::Message& msg, |
+ RenderFrameHost* render_frame_host) { |
+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MediaWebContentsObserverAndroid, msg, |
+ render_frame_host) |
+ IPC_MESSAGE_HANDLER(MediaPlayerDelegateHostMsg_OnMediaDestroyed, |
+ OnMediaDestroyed) |
+ IPC_MESSAGE_HANDLER(MediaPlayerDelegateHostMsg_OnMediaPlaying, |
+ OnMediaPlaying) |
+ IPC_MESSAGE_HANDLER(MediaPlayerDelegateHostMsg_OnMediaPaused, OnMediaPaused) |
+ IPC_END_MESSAGE_MAP() |
+} |
+ |
bool MediaWebContentsObserverAndroid::OnMediaPlayerMessageReceived( |
const IPC::Message& msg, |
RenderFrameHost* render_frame_host) { |
@@ -197,4 +237,59 @@ void MediaWebContentsObserverAndroid::OnSetCdm( |
media_player->SetCdm(cdm); |
} |
+void MediaWebContentsObserverAndroid::OnMediaDestroyed( |
+ RenderFrameHost* render_frame_host, |
+ int delegate_id) { |
+ media_session_map_.erase(MediaPlayerId(render_frame_host, delegate_id)); |
+} |
+ |
+void MediaWebContentsObserverAndroid::OnMediaPlaying( |
+ RenderFrameHost* render_frame_host, |
+ int delegate_id, |
+ bool has_video, |
+ bool has_audio, |
+ bool is_remote, |
+ base::TimeDelta duration) { |
+ const MediaPlayerId id(render_frame_host, delegate_id); |
+ |
+ // Since we don't remove session instances on pause, there may be an existing |
+ // instance for this playback attempt. |
+ // |
+ // 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; |
+ } |
+ |
+ scoped_ptr<MediaSessionController> controller( |
+ new MediaSessionController(id, this)); |
+ |
+ if (!controller->Initialize(has_audio, is_remote, duration)) |
+ return; |
+ |
+ media_session_map_[id] = std::move(controller); |
+} |
+ |
+void MediaWebContentsObserverAndroid::OnMediaPaused( |
+ RenderFrameHost* render_frame_host, |
+ int delegate_id, |
+ bool reached_end_of_stream) { |
+ // Drop the session if playback completes normally. |
+ if (reached_end_of_stream) { |
+ OnMediaDestroyed(render_frame_host, delegate_id); |
+ return; |
+ } |
+ |
+ auto it = |
+ media_session_map_.find(MediaPlayerId(render_frame_host, delegate_id)); |
+ if (it == media_session_map_.end()) |
+ return; |
+ |
+ it->second->OnPlaybackPaused(); |
+} |
+ |
} // namespace content |