diff options
author | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-27 21:17:17 +0000 |
---|---|---|
committer | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-27 21:17:17 +0000 |
commit | a017938bc9a573c30a26df17252ed95ad4b151c1 (patch) | |
tree | f64b3f00ad96a6145c003f2d74243dc6abb71594 | |
parent | 3d990b7aab7a23019bd4f03f91a33f9fb0ff741f (diff) | |
download | chromium_src-a017938bc9a573c30a26df17252ed95ad4b151c1.zip chromium_src-a017938bc9a573c30a26df17252ed95ad4b151c1.tar.gz chromium_src-a017938bc9a573c30a26df17252ed95ad4b151c1.tar.bz2 |
Make RendererMediaPlayerManager a RenderFrameObserver.
Major change:
- Make BrowserMediaPlayerManager (BMPM) a per RenderFrame object.
- Introduce MediaWebContentsObserver (MWCO) which managers all BMPMs.
- MWCO forwards all IPCs to BMPM.
Other changes necessary to switch from RenderView to RenderFrame:
- Use MediaWebContentsObserver to send PauseVideo message to render.
- Use render frame routing ID to set surface peer.
VIDEO_HOLE related changes:
- Add DidCommitCompositorFrame() to RenderFrameObserver.
- Add OnFrameInfoUpdated() to MediaWebContentsObserver.
BUG=338910
TEST=Tested with test pages and Youtube purchased movies.
Review URL: https://codereview.chromium.org/278353003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273033 0039d316-1c4b-4281-b951-d872f2087c98
30 files changed, 476 insertions, 199 deletions
diff --git a/content/browser/android/child_process_launcher_android.cc b/content/browser/android/child_process_launcher_android.cc index 8c940da..06fa0cb 100644 --- a/content/browser/android/child_process_launcher_android.cc +++ b/content/browser/android/child_process_launcher_android.cc @@ -8,7 +8,9 @@ #include "base/android/jni_array.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/media/android/browser_media_player_manager.h" +#include "content/browser/media/android/media_web_contents_observer.h" #include "content/browser/renderer_host/compositor_impl_android.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/public/browser/browser_thread.h" @@ -29,34 +31,52 @@ namespace content { namespace { // Pass a java surface object to the MediaPlayerAndroid object -// identified by render process handle, render view ID and player ID. +// identified by render process handle, render frame ID and player ID. static void SetSurfacePeer( const base::android::JavaRef<jobject>& surface, base::ProcessHandle render_process_handle, - int render_view_id, + int render_frame_id, int player_id) { - int renderer_id = 0; + int render_process_id = 0; RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator(); while (!it.IsAtEnd()) { if (it.GetCurrentValue()->GetHandle() == render_process_handle) { - renderer_id = it.GetCurrentValue()->GetID(); + render_process_id = it.GetCurrentValue()->GetID(); break; } it.Advance(); } + if (!render_process_id) { + DVLOG(1) << "Cannot find render process for render_process_handle " + << render_process_handle; + return; + } - if (renderer_id) { - RenderViewHostImpl* host = RenderViewHostImpl::FromID( - renderer_id, render_view_id); - if (host) { - media::MediaPlayerAndroid* player = - host->media_player_manager()->GetPlayer(player_id); - if (player && - player != host->media_player_manager()->GetFullscreenPlayer()) { - gfx::ScopedJavaSurface scoped_surface(surface); - player->SetVideoSurface(scoped_surface.Pass()); - } - } + RenderFrameHostImpl* frame = + RenderFrameHostImpl::FromID(render_process_id, render_frame_id); + if (!frame) { + DVLOG(1) << "Cannot find frame for render_frame_id " << render_frame_id; + return; + } + + RenderViewHostImpl* view = + static_cast<RenderViewHostImpl*>(frame->GetRenderViewHost()); + BrowserMediaPlayerManager* player_manager = + view->media_web_contents_observer()->GetMediaPlayerManager(frame); + if (!player_manager) { + DVLOG(1) << "Cannot find the media player manager for frame " << frame; + return; + } + + media::MediaPlayerAndroid* player = player_manager->GetPlayer(player_id); + if (!player) { + DVLOG(1) << "Cannot find media player for player_id " << player_id; + return; + } + + if (player != player_manager->GetFullscreenPlayer()) { + gfx::ScopedJavaSurface scoped_surface(surface); + player->SetVideoSurface(scoped_surface.Pass()); } } diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index 2ef62be..66d83b2 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc @@ -24,7 +24,7 @@ #include "content/browser/frame_host/navigation_controller_impl.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/geolocation/geolocation_dispatcher_host.h" -#include "content/browser/media/android/browser_media_player_manager.h" +#include "content/browser/media/android/media_web_contents_observer.h" #include "content/browser/renderer_host/compositor_impl_android.h" #include "content/browser/renderer_host/input/motion_event_android.h" #include "content/browser/renderer_host/input/web_input_event_builders_android.h" @@ -365,9 +365,10 @@ void ContentViewCoreImpl::Hide() { } void ContentViewCoreImpl::PauseVideo() { - RenderViewHost* host = web_contents_->GetRenderViewHost(); - if (host) - host->Send(new ViewMsg_PauseVideo(host->GetRoutingID())); + RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>( + web_contents_->GetRenderViewHost()); + if (rvhi) + rvhi->media_web_contents_observer()->PauseVideo(); } void ContentViewCoreImpl::PauseOrResumeGeolocation(bool should_pause) { diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc index 6792951..c4fdb62 100644 --- a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc +++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc @@ -194,13 +194,13 @@ gpu::GLInProcessContext* SynchronousCompositorFactoryImpl::GetShareContext() { } scoped_refptr<StreamTextureFactory> -SynchronousCompositorFactoryImpl::CreateStreamTextureFactory(int view_id) { +SynchronousCompositorFactoryImpl::CreateStreamTextureFactory(int frame_id) { scoped_refptr<StreamTextureFactorySynchronousImpl> factory( StreamTextureFactorySynchronousImpl::Create( base::Bind( &SynchronousCompositorFactoryImpl::TryCreateStreamTextureFactory, base::Unretained(this)), - view_id)); + frame_id)); return factory; } diff --git a/content/browser/android/surface_texture_peer_browser_impl.cc b/content/browser/android/surface_texture_peer_browser_impl.cc index 7935c9a..99e2c08 100644 --- a/content/browser/android/surface_texture_peer_browser_impl.cc +++ b/content/browser/android/surface_texture_peer_browser_impl.cc @@ -4,7 +4,9 @@ #include "content/browser/android/surface_texture_peer_browser_impl.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/media/android/browser_media_player_manager.h" +#include "content/browser/media/android/media_web_contents_observer.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" @@ -16,34 +18,52 @@ namespace content { namespace { // Pass a java surface object to the MediaPlayerAndroid object -// identified by render process handle, render view ID and player ID. +// identified by render process handle, render frame ID and player ID. static void SetSurfacePeer( scoped_refptr<gfx::SurfaceTexture> surface_texture, base::ProcessHandle render_process_handle, - int render_view_id, + int render_frame_id, int player_id) { - int renderer_id = 0; + int render_process_id = 0; RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator(); while (!it.IsAtEnd()) { if (it.GetCurrentValue()->GetHandle() == render_process_handle) { - renderer_id = it.GetCurrentValue()->GetID(); + render_process_id = it.GetCurrentValue()->GetID(); break; } it.Advance(); } + if (!render_process_id) { + DVLOG(1) << "Cannot find render process for render_process_handle " + << render_process_handle; + return; + } - if (renderer_id) { - RenderViewHostImpl* host = RenderViewHostImpl::FromID( - renderer_id, render_view_id); - if (host) { - media::MediaPlayerAndroid* player = - host->media_player_manager()->GetPlayer(player_id); - if (player && - player != host->media_player_manager()->GetFullscreenPlayer()) { - gfx::ScopedJavaSurface surface(surface_texture.get()); - player->SetVideoSurface(surface.Pass()); - } - } + RenderFrameHostImpl* frame = + RenderFrameHostImpl::FromID(render_process_id, render_frame_id); + if (!frame) { + DVLOG(1) << "Cannot find frame for render_frame_id " << render_frame_id; + return; + } + + RenderViewHostImpl* view = + static_cast<RenderViewHostImpl*>(frame->GetRenderViewHost()); + BrowserMediaPlayerManager* player_manager = + view->media_web_contents_observer()->GetMediaPlayerManager(frame); + if (!player_manager) { + DVLOG(1) << "Cannot find the media player manager for frame " << frame; + return; + } + + media::MediaPlayerAndroid* player = player_manager->GetPlayer(player_id); + if (!player) { + DVLOG(1) << "Cannot find media player for player_id " << player_id; + return; + } + + if (player != player_manager->GetFullscreenPlayer()) { + gfx::ScopedJavaSurface scoped_surface(surface_texture); + player->SetVideoSurface(scoped_surface.Pass()); } } @@ -58,14 +78,14 @@ SurfaceTexturePeerBrowserImpl::~SurfaceTexturePeerBrowserImpl() { void SurfaceTexturePeerBrowserImpl::EstablishSurfaceTexturePeer( base::ProcessHandle render_process_handle, scoped_refptr<gfx::SurfaceTexture> surface_texture, - int render_view_id, + int render_frame_id, int player_id) { if (!surface_texture.get()) return; BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( &SetSurfacePeer, surface_texture, render_process_handle, - render_view_id, player_id)); + render_frame_id, player_id)); } } // namespace content diff --git a/content/browser/android/surface_texture_peer_browser_impl.h b/content/browser/android/surface_texture_peer_browser_impl.h index 4aa8563..ea3fd04 100644 --- a/content/browser/android/surface_texture_peer_browser_impl.h +++ b/content/browser/android/surface_texture_peer_browser_impl.h @@ -25,7 +25,7 @@ class SurfaceTexturePeerBrowserImpl : public SurfaceTexturePeer { virtual void EstablishSurfaceTexturePeer( base::ProcessHandle render_process_handle, scoped_refptr<gfx::SurfaceTexture> surface_texture, - int render_view_id, + int render_frame_id, int player_id) OVERRIDE; private: diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc index ac37e42..914bb9f 100644 --- a/content/browser/media/android/browser_media_player_manager.cc +++ b/content/browser/media/android/browser_media_player_manager.cc @@ -18,6 +18,7 @@ #include "content/public/browser/android/external_video_surface_container.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/storage_partition.h" @@ -58,10 +59,10 @@ void BrowserMediaPlayerManager::RegisterFactory(Factory factory) { // static BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create( - RenderViewHost* rvh) { + RenderFrameHost* rfh) { if (g_factory) - return g_factory(rvh); - return new BrowserMediaPlayerManager(rvh); + return g_factory(rfh); + return new BrowserMediaPlayerManager(rfh); } ContentViewCoreImpl* BrowserMediaPlayerManager::GetContentViewCore() const { @@ -126,46 +127,16 @@ MediaPlayerAndroid* BrowserMediaPlayerManager::CreateMediaPlayer( } BrowserMediaPlayerManager::BrowserMediaPlayerManager( - RenderViewHost* render_view_host) - : WebContentsObserver(WebContents::FromRenderViewHost(render_view_host)), + RenderFrameHost* render_frame_host) + : render_frame_host_(render_frame_host), fullscreen_player_id_(-1), fullscreen_player_is_released_(false), - web_contents_(WebContents::FromRenderViewHost(render_view_host)), + web_contents_(WebContents::FromRenderFrameHost(render_frame_host)), weak_ptr_factory_(this) { } BrowserMediaPlayerManager::~BrowserMediaPlayerManager() {} -bool BrowserMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(BrowserMediaPlayerManager, msg) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_EnterFullscreen, OnEnterFullscreen) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_ExitFullscreen, OnExitFullscreen) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Initialize, OnInitialize) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Start, OnStart) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Seek, OnSeek) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Pause, OnPause) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetVolume, OnSetVolume) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetPoster, OnSetPoster) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Release, OnReleaseResources) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyMediaPlayer, OnDestroyPlayer) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers, - DestroyAllMediaPlayers) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetCdm, OnSetCdm) - IPC_MESSAGE_HANDLER(CdmHostMsg_InitializeCdm, OnInitializeCdm) - IPC_MESSAGE_HANDLER(CdmHostMsg_CreateSession, OnCreateSession) - IPC_MESSAGE_HANDLER(CdmHostMsg_UpdateSession, OnUpdateSession) - IPC_MESSAGE_HANDLER(CdmHostMsg_ReleaseSession, OnReleaseSession) - IPC_MESSAGE_HANDLER(CdmHostMsg_DestroyCdm, OnDestroyCdm) -#if defined(VIDEO_HOLE) - IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyExternalSurface, - OnNotifyExternalSurface) -#endif // defined(VIDEO_HOLE) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - void BrowserMediaPlayerManager::FullscreenPlayerPlay() { MediaPlayerAndroid* player = GetFullscreenPlayer(); if (player) { @@ -174,8 +145,8 @@ void BrowserMediaPlayerManager::FullscreenPlayerPlay() { fullscreen_player_is_released_ = false; } player->Start(); - Send(new MediaPlayerMsg_DidMediaPlayerPlay( - routing_id(), fullscreen_player_id_)); + Send(new MediaPlayerMsg_DidMediaPlayerPlay(RoutingID(), + fullscreen_player_id_)); } } @@ -183,8 +154,8 @@ void BrowserMediaPlayerManager::FullscreenPlayerPause() { MediaPlayerAndroid* player = GetFullscreenPlayer(); if (player) { player->Pause(true); - Send(new MediaPlayerMsg_DidMediaPlayerPause( - routing_id(), fullscreen_player_id_)); + Send(new MediaPlayerMsg_DidMediaPlayerPause(RoutingID(), + fullscreen_player_id_)); } } @@ -211,8 +182,8 @@ void BrowserMediaPlayerManager::ExitFullscreen(bool release_media_player) { } } - Send(new MediaPlayerMsg_DidExitFullscreen( - routing_id(), fullscreen_player_id_)); + Send( + new MediaPlayerMsg_DidExitFullscreen(RoutingID(), fullscreen_player_id_)); video_view_.reset(); MediaPlayerAndroid* player = GetFullscreenPlayer(); fullscreen_player_id_ = -1; @@ -226,8 +197,8 @@ void BrowserMediaPlayerManager::ExitFullscreen(bool release_media_player) { void BrowserMediaPlayerManager::OnTimeUpdate(int player_id, base::TimeDelta current_time) { - Send(new MediaPlayerMsg_MediaTimeUpdate( - routing_id(), player_id, current_time)); + Send( + new MediaPlayerMsg_MediaTimeUpdate(RoutingID(), player_id, current_time)); } void BrowserMediaPlayerManager::SetVideoSurface( @@ -241,8 +212,7 @@ void BrowserMediaPlayerManager::SetVideoSurface( if (empty_surface) return; - Send(new MediaPlayerMsg_DidEnterFullscreen(routing_id(), - player->player_id())); + Send(new MediaPlayerMsg_DidEnterFullscreen(RoutingID(), player->player_id())); if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableOverlayFullscreenVideoSubtitle)) { return; @@ -260,27 +230,27 @@ void BrowserMediaPlayerManager::OnMediaMetadataChanged( int player_id, base::TimeDelta duration, int width, int height, bool success) { Send(new MediaPlayerMsg_MediaMetadataChanged( - routing_id(), player_id, duration, width, height, success)); + RoutingID(), player_id, duration, width, height, success)); if (fullscreen_player_id_ == player_id) video_view_->UpdateMediaMetadata(); } void BrowserMediaPlayerManager::OnPlaybackComplete(int player_id) { - Send(new MediaPlayerMsg_MediaPlaybackCompleted(routing_id(), player_id)); + Send(new MediaPlayerMsg_MediaPlaybackCompleted(RoutingID(), player_id)); if (fullscreen_player_id_ == player_id) video_view_->OnPlaybackComplete(); } void BrowserMediaPlayerManager::OnMediaInterrupted(int player_id) { // Tell WebKit that the audio should be paused, then release all resources - Send(new MediaPlayerMsg_MediaPlayerReleased(routing_id(), player_id)); + Send(new MediaPlayerMsg_MediaPlayerReleased(RoutingID(), player_id)); OnReleaseResources(player_id); } void BrowserMediaPlayerManager::OnBufferingUpdate( int player_id, int percentage) { Send(new MediaPlayerMsg_MediaBufferingUpdate( - routing_id(), player_id, percentage)); + RoutingID(), player_id, percentage)); if (fullscreen_player_id_ == player_id) video_view_->OnBufferingUpdate(percentage); } @@ -288,24 +258,28 @@ void BrowserMediaPlayerManager::OnBufferingUpdate( void BrowserMediaPlayerManager::OnSeekRequest( int player_id, const base::TimeDelta& time_to_seek) { - Send(new MediaPlayerMsg_SeekRequest(routing_id(), player_id, time_to_seek)); + Send(new MediaPlayerMsg_SeekRequest(RoutingID(), player_id, time_to_seek)); +} + +void BrowserMediaPlayerManager::PauseVideo() { + Send(new MediaPlayerMsg_PauseVideo(RoutingID())); } void BrowserMediaPlayerManager::OnSeekComplete( int player_id, const base::TimeDelta& current_time) { - Send(new MediaPlayerMsg_SeekCompleted(routing_id(), player_id, current_time)); + Send(new MediaPlayerMsg_SeekCompleted(RoutingID(), player_id, current_time)); } void BrowserMediaPlayerManager::OnError(int player_id, int error) { - Send(new MediaPlayerMsg_MediaError(routing_id(), player_id, error)); + Send(new MediaPlayerMsg_MediaError(RoutingID(), player_id, error)); if (fullscreen_player_id_ == player_id) video_view_->OnMediaPlayerError(error); } void BrowserMediaPlayerManager::OnVideoSizeChanged( int player_id, int width, int height) { - Send(new MediaPlayerMsg_MediaVideoSizeChanged(routing_id(), player_id, + Send(new MediaPlayerMsg_MediaVideoSizeChanged(RoutingID(), player_id, width, height)); if (fullscreen_player_id_ == player_id) video_view_->OnVideoSizeChanged(width, height); @@ -373,7 +347,7 @@ void BrowserMediaPlayerManager::RequestFullScreen(int player_id) { // TODO(qinmin): make this flag default on android. if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableGestureRequirementForMediaFullscreen)) { - Send(new MediaPlayerMsg_RequestFullscreen(routing_id(), player_id)); + Send(new MediaPlayerMsg_RequestFullscreen(RoutingID(), player_id)); } } @@ -384,7 +358,7 @@ void BrowserMediaPlayerManager::OnSessionCreated( uint32 session_id, const std::string& web_session_id) { Send(new CdmMsg_SessionCreated( - routing_id(), cdm_id, session_id, web_session_id)); + RoutingID(), cdm_id, session_id, web_session_id)); } void BrowserMediaPlayerManager::OnSessionMessage( @@ -400,15 +374,15 @@ void BrowserMediaPlayerManager::OnSessionMessage( } Send(new CdmMsg_SessionMessage( - routing_id(), cdm_id, session_id, message, destination_gurl)); + RoutingID(), cdm_id, session_id, message, destination_gurl)); } void BrowserMediaPlayerManager::OnSessionReady(int cdm_id, uint32 session_id) { - Send(new CdmMsg_SessionReady(routing_id(), cdm_id, session_id)); + Send(new CdmMsg_SessionReady(RoutingID(), cdm_id, session_id)); } void BrowserMediaPlayerManager::OnSessionClosed(int cdm_id, uint32 session_id) { - Send(new CdmMsg_SessionClosed(routing_id(), cdm_id, session_id)); + Send(new CdmMsg_SessionClosed(RoutingID(), cdm_id, session_id)); } void BrowserMediaPlayerManager::OnSessionError( @@ -417,7 +391,7 @@ void BrowserMediaPlayerManager::OnSessionError( media::MediaKeys::KeyError error_code, uint32 system_code) { Send(new CdmMsg_SessionError( - routing_id(), cdm_id, session_id, error_code, system_code)); + RoutingID(), cdm_id, session_id, error_code, system_code)); } #if defined(VIDEO_HOLE) @@ -501,8 +475,8 @@ void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) { // TODO(qinmin): There is no need to send DidEnterFullscreen message. // However, if we don't send the message, page layers will not be // correctly restored. http:crbug.com/367346. - Send(new MediaPlayerMsg_DidEnterFullscreen(routing_id(), player_id)); - Send(new MediaPlayerMsg_DidExitFullscreen(routing_id(), player_id)); + Send(new MediaPlayerMsg_DidEnterFullscreen(RoutingID(), player_id)); + Send(new MediaPlayerMsg_DidExitFullscreen(RoutingID(), player_id)); video_view_.reset(); } @@ -833,6 +807,14 @@ void BrowserMediaPlayerManager::OnSetCdm(int player_id, int cdm_id) { cdm_to_player_map_[cdm_id] = player_id; } +int BrowserMediaPlayerManager::RoutingID() { + return render_frame_host_->GetRoutingID(); +} + +bool BrowserMediaPlayerManager::Send(IPC::Message* msg) { + return render_frame_host_->Send(msg); +} + void BrowserMediaPlayerManager::CreateSessionIfPermitted( int cdm_id, uint32 session_id, @@ -882,8 +864,8 @@ void BrowserMediaPlayerManager::OnMediaResourcesRequested(int player_id) { if ((*it)->IsPlayerReady() && !(*it)->IsPlaying() && fullscreen_player_id_ != (*it)->player_id()) { (*it)->Release(); - Send(new MediaPlayerMsg_MediaPlayerReleased( - routing_id(), (*it)->player_id())); + Send(new MediaPlayerMsg_MediaPlayerReleased(RoutingID(), + (*it)->player_id())); } } } diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h index b6648f0..fbc2487 100644 --- a/content/browser/media/android/browser_media_player_manager.h +++ b/content/browser/media/android/browser_media_player_manager.h @@ -16,9 +16,10 @@ #include "base/memory/scoped_vector.h" #include "base/time/time.h" #include "content/browser/android/content_video_view.h" +#include "content/common/content_export.h" #include "content/common/media/cdm_messages_enums.h" #include "content/common/media/media_player_messages_enums_android.h" -#include "content/public/browser/web_contents_observer.h" +#include "ipc/ipc_message.h" #include "media/base/android/media_player_android.h" #include "media/base/android/media_player_manager.h" #include "ui/gfx/rect_f.h" @@ -33,6 +34,7 @@ namespace content { class BrowserDemuxerAndroid; class ContentViewCoreImpl; class ExternalVideoSurfaceContainer; +class RenderFrameHost; class WebContents; // This class manages all the MediaPlayerAndroid and CDM objects. @@ -41,23 +43,19 @@ class WebContents; // MediaPlayerAndroid and CDM objects are converted to IPCs and then sent to // the render process. class CONTENT_EXPORT BrowserMediaPlayerManager - : public WebContentsObserver, - public media::MediaPlayerManager { + : public media::MediaPlayerManager { public: // Permits embedders to provide an extended version of the class. - typedef BrowserMediaPlayerManager* (*Factory)(RenderViewHost*); + typedef BrowserMediaPlayerManager* (*Factory)(RenderFrameHost*); static void RegisterFactory(Factory factory); // Returns a new instance using the registered factory if available. - static BrowserMediaPlayerManager* Create(RenderViewHost* rvh); + static BrowserMediaPlayerManager* Create(RenderFrameHost* rfh); ContentViewCoreImpl* GetContentViewCore() const; virtual ~BrowserMediaPlayerManager(); - // WebContentsObserver overrides. - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - // Fullscreen video playback controls. virtual void FullscreenPlayerPlay(); virtual void FullscreenPlayerPause(); @@ -69,6 +67,9 @@ class CONTENT_EXPORT BrowserMediaPlayerManager // Any actual seek started by renderer will be handled by browser in OnSeek(). void OnSeekRequest(int player_id, const base::TimeDelta& time_to_seek); + // Pauses all video players manages by this class. + void PauseVideo(); + // media::MediaPlayerManager overrides. virtual void OnTimeUpdate( int player_id, base::TimeDelta current_time) OVERRIDE; @@ -113,10 +114,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager void OnFrameInfoUpdated(); #endif // defined(VIDEO_HOLE) - protected: - // Clients must use Create() or subclass constructor. - explicit BrowserMediaPlayerManager(RenderViewHost* render_view_host); - // Message handlers. virtual void OnEnterFullscreen(int player_id); virtual void OnExitFullscreen(int player_id); @@ -147,6 +144,16 @@ class CONTENT_EXPORT BrowserMediaPlayerManager void OnReleaseSession(int cdm_id, uint32 session_id); void OnSetCdm(int player_id, int cdm_id); void OnDestroyCdm(int cdm_id); +#if defined(VIDEO_HOLE) + void OnNotifyExternalSurface( + int player_id, bool is_request, const gfx::RectF& rect); +#endif // defined(VIDEO_HOLE) + + protected: + // Clients must use Create() or subclass constructor. + explicit BrowserMediaPlayerManager(RenderFrameHost* render_frame_host); + + WebContents* web_contents() const { return web_contents_; } // Cancels all pending session creations associated with |cdm_id|. void CancelAllPendingSessionCreations(int cdm_id); @@ -173,6 +180,11 @@ class CONTENT_EXPORT BrowserMediaPlayerManager // Removes the CDM with the specified id. void RemoveCdm(int cdm_id); + int RoutingID(); + + // Helper function to send messages to RenderFrameObserver. + bool Send(IPC::Message* msg); + private: // If |permitted| is false, it does nothing but send // |CdmMsg_SessionError| IPC message. @@ -208,11 +220,11 @@ class CONTENT_EXPORT BrowserMediaPlayerManager virtual void OnMediaResourcesReleased(int player_id); #if defined(VIDEO_HOLE) - void OnNotifyExternalSurface( - int player_id, bool is_request, const gfx::RectF& rect); void OnRequestExternalSurface(int player_id, const gfx::RectF& rect); #endif // defined(VIDEO_HOLE) + RenderFrameHost* const render_frame_host_; + // An array of managed players. ScopedVector<media::MediaPlayerAndroid> players_; @@ -244,7 +256,7 @@ class CONTENT_EXPORT BrowserMediaPlayerManager // Whether the fullscreen player has been Release()-d. bool fullscreen_player_is_released_; - WebContents* web_contents_; + WebContents* const web_contents_; // Object for retrieving resources media players. scoped_ptr<media::MediaResourceGetter> media_resource_getter_; diff --git a/content/browser/media/android/media_web_contents_observer.cc b/content/browser/media/android/media_web_contents_observer.cc new file mode 100644 index 0000000..711375c --- /dev/null +++ b/content/browser/media/android/media_web_contents_observer.cc @@ -0,0 +1,131 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/media/android/media_web_contents_observer.h" + +#include "base/stl_util.h" +#include "content/browser/media/android/browser_media_player_manager.h" +#include "content/common/media/cdm_messages.h" +#include "content/common/media/media_player_messages_android.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" +#include "ipc/ipc_message_macros.h" + +namespace content { + +MediaWebContentsObserver::MediaWebContentsObserver( + RenderViewHost* render_view_host) + : WebContentsObserver(WebContents::FromRenderViewHost(render_view_host)) { +} + +MediaWebContentsObserver::~MediaWebContentsObserver() { +} + +void MediaWebContentsObserver::RenderFrameDeleted( + RenderFrameHost* render_frame_host) { + uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host); + media_player_managers_.erase(key); +} + +bool MediaWebContentsObserver::OnMessageReceived( + const IPC::Message& msg, + RenderFrameHost* render_frame_host) { + BrowserMediaPlayerManager* player_manager = + GetMediaPlayerManager(render_frame_host); + DCHECK(player_manager); + + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserver, msg) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_EnterFullscreen, + player_manager, + BrowserMediaPlayerManager::OnEnterFullscreen) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_ExitFullscreen, + player_manager, + BrowserMediaPlayerManager::OnExitFullscreen) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize, + player_manager, + BrowserMediaPlayerManager::OnInitialize) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start, + player_manager, + BrowserMediaPlayerManager::OnStart) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Seek, + player_manager, + BrowserMediaPlayerManager::OnSeek) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Pause, + player_manager, + BrowserMediaPlayerManager::OnPause) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetVolume, + player_manager, + BrowserMediaPlayerManager::OnSetVolume) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetPoster, + player_manager, + BrowserMediaPlayerManager::OnSetPoster) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Release, + player_manager, + BrowserMediaPlayerManager::OnReleaseResources) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyMediaPlayer, + player_manager, + BrowserMediaPlayerManager::OnDestroyPlayer) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyAllMediaPlayers, + player_manager, + BrowserMediaPlayerManager::DestroyAllMediaPlayers) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetCdm, + player_manager, + BrowserMediaPlayerManager::OnSetCdm) + IPC_MESSAGE_FORWARD(CdmHostMsg_InitializeCdm, + player_manager, + BrowserMediaPlayerManager::OnInitializeCdm) + IPC_MESSAGE_FORWARD(CdmHostMsg_CreateSession, + player_manager, + BrowserMediaPlayerManager::OnCreateSession) + IPC_MESSAGE_FORWARD(CdmHostMsg_UpdateSession, + player_manager, + BrowserMediaPlayerManager::OnUpdateSession) + IPC_MESSAGE_FORWARD(CdmHostMsg_ReleaseSession, + player_manager, + BrowserMediaPlayerManager::OnReleaseSession) + IPC_MESSAGE_FORWARD(CdmHostMsg_DestroyCdm, + player_manager, + BrowserMediaPlayerManager::OnDestroyCdm) +#if defined(VIDEO_HOLE) + IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_NotifyExternalSurface, + player_manager, + BrowserMediaPlayerManager::OnNotifyExternalSurface) +#endif // defined(VIDEO_HOLE) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +BrowserMediaPlayerManager* MediaWebContentsObserver::GetMediaPlayerManager( + RenderFrameHost* render_frame_host) { + uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host); + if (!media_player_managers_.contains(key)) { + media_player_managers_.set( + key, + scoped_ptr<BrowserMediaPlayerManager>( + BrowserMediaPlayerManager::Create(render_frame_host))); + } + return media_player_managers_.get(key); +} + +void MediaWebContentsObserver::PauseVideo() { + for (MediaPlayerManagerMap::iterator iter = media_player_managers_.begin(); + iter != media_player_managers_.end(); ++iter) { + BrowserMediaPlayerManager* manager = iter->second; + manager->PauseVideo(); + } +} + +#if defined(VIDEO_HOLE) +void MediaWebContentsObserver::OnFrameInfoUpdated() { + for (MediaPlayerManagerMap::iterator iter = media_player_managers_.begin(); + iter != media_player_managers_.end(); ++iter) { + BrowserMediaPlayerManager* manager = iter->second; + manager->OnFrameInfoUpdated(); + } +} +#endif // defined(VIDEO_HOLE) + +} // namespace content diff --git a/content/browser/media/android/media_web_contents_observer.h b/content/browser/media/android/media_web_contents_observer.h new file mode 100644 index 0000000..126bbfb --- /dev/null +++ b/content/browser/media/android/media_web_contents_observer.h @@ -0,0 +1,55 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_WEB_CONTENTS_OBSERVER_H_ +#define CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_WEB_CONTENTS_OBSERVER_H_ + +#include "base/compiler_specific.h" +#include "base/containers/scoped_ptr_hash_map.h" +#include "content/common/content_export.h" +#include "content/public/browser/web_contents_observer.h" + +namespace content { + +class BrowserMediaPlayerManager; +class RenderViewHost; + +// This class manages all RenderFrame based media related managers at the +// browser side. It receives IPC messages from media RenderFrameObservers and +// forwards them to the corresponding managers. The managers are responsible +// for sending IPCs back to the RenderFrameObservers at the render side. +class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver { + public: + explicit MediaWebContentsObserver(RenderViewHost* render_view_host); + virtual ~MediaWebContentsObserver(); + + // WebContentsObserver implementations. + virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) OVERRIDE; + virtual bool OnMessageReceived(const IPC::Message& message, + RenderFrameHost* render_frame_host) OVERRIDE; + + // Gets the media player manager associated with |render_frame_host|. Creates + // a new one if it doesn't exist. The caller doesn't own the returned pointer. + BrowserMediaPlayerManager* GetMediaPlayerManager( + RenderFrameHost* render_frame_host); + + // Pauses all media player. + void PauseVideo(); + +#if defined(VIDEO_HOLE) + void OnFrameInfoUpdated(); +#endif // defined(VIDEO_HOLE) + + private: + // Map from RenderFrameHost* to BrowserMediaPlayerManager. + typedef base::ScopedPtrHashMap<uintptr_t, BrowserMediaPlayerManager> + MediaPlayerManagerMap; + MediaPlayerManagerMap media_player_managers_; + + DISALLOW_COPY_AND_ASSIGN(MediaWebContentsObserver); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_WEB_CONTENTS_OBSERVER_H_ diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 0a95825..334181b 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc @@ -92,7 +92,7 @@ #if defined(OS_MACOSX) #include "content/browser/renderer_host/popup_menu_helper_mac.h" #elif defined(OS_ANDROID) -#include "content/browser/media/android/browser_media_player_manager.h" +#include "content/browser/media/android/media_web_contents_observer.h" #elif defined(OS_WIN) #include "base/win/win_util.h" #endif @@ -224,7 +224,7 @@ RenderViewHostImpl::RenderViewHostImpl( } #if defined(OS_ANDROID) - media_player_manager_.reset(BrowserMediaPlayerManager::Create(this)); + media_web_contents_observer_.reset(new MediaWebContentsObserver(this)); #endif unload_event_monitor_timeout_.reset(new TimeoutMonitor(base::Bind( diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index 0fc5b28..3da659b 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h @@ -53,7 +53,7 @@ struct SelectedFileInfo; namespace content { -class BrowserMediaPlayerManager; +class MediaWebContentsObserver; class ChildProcessSecurityPolicyImpl; class PageState; class RenderWidgetHostDelegate; @@ -392,8 +392,8 @@ class CONTENT_EXPORT RenderViewHostImpl #endif #if defined(OS_ANDROID) - BrowserMediaPlayerManager* media_player_manager() { - return media_player_manager_.get(); + MediaWebContentsObserver* media_web_contents_observer() { + return media_web_contents_observer_.get(); } void DidSelectPopupMenuItems(const std::vector<int>& selected_indices); @@ -625,8 +625,9 @@ class CONTENT_EXPORT RenderViewHostImpl bool virtual_keyboard_requested_; #if defined(OS_ANDROID) - // Manages all the android mediaplayer objects and handling IPCs for video. - scoped_ptr<BrowserMediaPlayerManager> media_player_manager_; + // Manages all the android mediaplayer managers and forwards IPCs to the + // managers. + scoped_ptr<MediaWebContentsObserver> media_web_contents_observer_; #endif // Used to swap out or shutdown this RVH when the unload event is taking too diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 47309d4..0457b32 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc @@ -35,7 +35,7 @@ #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/gpu/gpu_process_host_ui_shim.h" #include "content/browser/gpu/gpu_surface_tracker.h" -#include "content/browser/media/android/browser_media_player_manager.h" +#include "content/browser/media/android/media_web_contents_observer.h" #include "content/browser/renderer_host/compositor_impl_android.h" #include "content/browser/renderer_host/dip_util.h" #include "content/browser/renderer_host/image_transport_factory_android.h" @@ -993,7 +993,7 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated( if (host_ && host_->IsRenderView()) { RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>( RenderViewHost::From(host_)); - rvhi->media_player_manager()->OnFrameInfoUpdated(); + rvhi->media_web_contents_observer()->OnFrameInfoUpdated(); } #endif // defined(VIDEO_HOLE) } diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index a2bdcb1..1256f58 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -3398,11 +3398,6 @@ void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh, ResetLoadProgressState(); loading_frames_in_progress_ = 0; -#if defined(OS_ANDROID) - if (GetRenderViewHostImpl()->media_player_manager()) - GetRenderViewHostImpl()->media_player_manager()->DestroyAllMediaPlayers(); -#endif - FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderProcessGone(GetCrashedStatus())); diff --git a/content/common/media/media_player_messages_android.h b/content/common/media/media_player_messages_android.h index 12fdcf1..b1b4af4 100644 --- a/content/common/media/media_player_messages_android.h +++ b/content/common/media/media_player_messages_android.h @@ -189,6 +189,9 @@ IPC_MESSAGE_ROUTED1(MediaPlayerMsg_DisconnectedFromRemoteDevice, IPC_MESSAGE_ROUTED1(MediaPlayerMsg_RequestFullscreen, int /*player_id */) +// Pauses all video playback. +IPC_MESSAGE_ROUTED0(MediaPlayerMsg_PauseVideo) + // Messages for controlling the media playback in browser process ---------- // Destroy the media player object. diff --git a/content/common/view_messages.h b/content/common/view_messages.h index ae8ea61..fbf7347 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -942,9 +942,6 @@ IPC_MESSAGE_ROUTED1(ViewMsg_BeginFrame, // processed on the browser side. IPC_MESSAGE_ROUTED0(ViewMsg_ImeEventAck) -// Sent by the browser when we should pause video playback. -IPC_MESSAGE_ROUTED0(ViewMsg_PauseVideo); - // Extracts the data at the given rect, returning it through the // ViewHostMsg_SmartClipDataExtracted IPC. IPC_MESSAGE_ROUTED1(ViewMsg_ExtractSmartClipData, diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 45ada0a..b799ad9 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -782,6 +782,8 @@ 'browser/media/android/media_drm_credential_manager.h', 'browser/media/android/media_resource_getter_impl.cc', 'browser/media/android/media_resource_getter_impl.h', + 'browser/media/android/media_web_contents_observer.cc', + 'browser/media/android/media_web_contents_observer.h', 'browser/media/capture/audio_mirroring_manager.cc', 'browser/media/capture/audio_mirroring_manager.h', 'browser/media/capture/content_video_capture_device_core.cc', diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h index 9dd2de6e..63c73a5 100644 --- a/content/public/renderer/render_frame_observer.h +++ b/content/public/renderer/render_frame_observer.h @@ -62,6 +62,9 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener, int32 line_number, int32 severity_level) {} + // Called when a compositor frame has committed. + virtual void DidCommitCompositorFrame() {} + // IPC::Listener implementation. virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; diff --git a/content/renderer/android/synchronous_compositor_factory.h b/content/renderer/android/synchronous_compositor_factory.h index d79988d..58785bb 100644 --- a/content/renderer/android/synchronous_compositor_factory.h +++ b/content/renderer/android/synchronous_compositor_factory.h @@ -51,7 +51,7 @@ class SynchronousCompositorFactory { virtual scoped_refptr<webkit::gpu::ContextProviderWebContext> GetSharedOffscreenContextProviderForMainThread() = 0; virtual scoped_refptr<StreamTextureFactory> CreateStreamTextureFactory( - int view_id) = 0; + int frame_id) = 0; virtual blink::WebGraphicsContext3D* CreateOffscreenGraphicsContext3D( const blink::WebGraphicsContext3D::Attributes& attributes) = 0; diff --git a/content/renderer/media/android/renderer_media_player_manager.cc b/content/renderer/media/android/renderer_media_player_manager.cc index f50f9b5..ea9fea4 100644 --- a/content/renderer/media/android/renderer_media_player_manager.cc +++ b/content/renderer/media/android/renderer_media_player_manager.cc @@ -23,11 +23,13 @@ namespace content { const size_t kMaxWebSessionIdLength = 512; const size_t kMaxSessionMessageLength = 10240; // 10 KB -RendererMediaPlayerManager::RendererMediaPlayerManager(RenderView* render_view) - : RenderViewObserver(render_view), +RendererMediaPlayerManager::RendererMediaPlayerManager( + RenderFrame* render_frame) + : RenderFrameObserver(render_frame), next_media_player_id_(0), fullscreen_frame_(NULL), - pending_fullscreen_frame_(NULL) {} + pending_fullscreen_frame_(NULL) { +} RendererMediaPlayerManager::~RendererMediaPlayerManager() { std::map<int, WebMediaPlayerAndroid*>::iterator player_it; @@ -67,6 +69,7 @@ bool RendererMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidExitFullscreen, OnDidExitFullscreen) IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPlay, OnPlayerPlay) IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPause, OnPlayerPause) + IPC_MESSAGE_HANDLER(MediaPlayerMsg_PauseVideo, OnPauseVideo) IPC_MESSAGE_HANDLER(CdmMsg_SessionCreated, OnSessionCreated) IPC_MESSAGE_HANDLER(CdmMsg_SessionMessage, OnSessionMessage) IPC_MESSAGE_HANDLER(CdmMsg_SessionReady, OnSessionReady) @@ -231,6 +234,10 @@ void RendererMediaPlayerManager::OnRequestFullscreen(int player_id) { player->OnRequestFullscreen(); } +void RendererMediaPlayerManager::OnPauseVideo() { + ReleaseVideoResources(); +} + void RendererMediaPlayerManager::EnterFullscreen(int player_id, blink::WebFrame* frame) { pending_fullscreen_frame_ = frame; @@ -361,8 +368,8 @@ void RendererMediaPlayerManager::RegisterMediaKeys(int cdm_id, void RendererMediaPlayerManager::ReleaseVideoResources() { std::map<int, WebMediaPlayerAndroid*>::iterator player_it; - for (player_it = media_players_.begin(); - player_it != media_players_.end(); ++player_it) { + for (player_it = media_players_.begin(); player_it != media_players_.end(); + ++player_it) { WebMediaPlayerAndroid* player = player_it->second; // Do not release if an audio track is still playing @@ -444,8 +451,8 @@ void RendererMediaPlayerManager::RetrieveGeometryChanges( bool RendererMediaPlayerManager::ShouldUseVideoOverlayForEmbeddedEncryptedVideo() { - const RendererPreferences& prefs = static_cast<RenderViewImpl*>( - render_view())->renderer_preferences(); + const RendererPreferences& prefs = static_cast<RenderFrameImpl*>( + render_frame())->render_view()->renderer_preferences(); return prefs.use_video_overlay_for_embedded_encrypted_video; } #endif // defined(VIDEO_HOLE) diff --git a/content/renderer/media/android/renderer_media_player_manager.h b/content/renderer/media/android/renderer_media_player_manager.h index 9fb5e44..73044c4 100644 --- a/content/renderer/media/android/renderer_media_player_manager.h +++ b/content/renderer/media/android/renderer_media_player_manager.h @@ -13,7 +13,7 @@ #include "base/time/time.h" #include "content/common/media/cdm_messages_enums.h" #include "content/common/media/media_player_messages_enums_android.h" -#include "content/public/renderer/render_view_observer.h" +#include "content/public/renderer/render_frame_observer.h" #include "media/base/android/media_player_android.h" #include "media/base/media_keys.h" #include "url/gurl.h" @@ -32,16 +32,16 @@ class ProxyMediaKeys; class WebMediaPlayerAndroid; // Class for managing all the WebMediaPlayerAndroid objects in the same -// RenderView. -class RendererMediaPlayerManager : public RenderViewObserver { +// RenderFrame. +class RendererMediaPlayerManager : public RenderFrameObserver { public: static const int kInvalidCdmId = 0; - // Constructs a RendererMediaPlayerManager object for the |render_view|. - RendererMediaPlayerManager(RenderView* render_view); + // Constructs a RendererMediaPlayerManager object for the |render_frame|. + RendererMediaPlayerManager(RenderFrame* render_frame); virtual ~RendererMediaPlayerManager(); - // RenderViewObserver overrides. + // RenderFrameObserver overrides. virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; // Initializes a MediaPlayerAndroid object in browser process. @@ -91,7 +91,7 @@ class RendererMediaPlayerManager : public RenderViewObserver { // Requests an external surface for out-of-band compositing. void RequestExternalSurface(int player_id, const gfx::RectF& geometry); - // RenderViewObserver overrides. + // RenderFrameObserver overrides. virtual void DidCommitCompositorFrame() OVERRIDE; // Returns true if a media player should use video-overlay for the embedded @@ -124,10 +124,6 @@ class RendererMediaPlayerManager : public RenderViewObserver { // used in other methods. void RegisterMediaKeys(int cdm_id, ProxyMediaKeys* media_keys); - // Releases the media resources managed by this object when a video - // is playing. - void ReleaseVideoResources(); - // Checks whether a player can enter fullscreen. bool CanEnterFullscreen(blink::WebFrame* frame); @@ -175,6 +171,7 @@ class RendererMediaPlayerManager : public RenderViewObserver { void OnPlayerPlay(int player_id); void OnPlayerPause(int player_id); void OnRequestFullscreen(int player_id); + void OnPauseVideo(); void OnSessionCreated(int cdm_id, uint32 session_id, const std::string& web_session_id); @@ -189,6 +186,12 @@ class RendererMediaPlayerManager : public RenderViewObserver { media::MediaKeys::KeyError error_code, uint32 system_code); + // Release all video player resources. + // If something is in progress the resource will not be freed. It will + // only be freed once the tab is destroyed or if the user navigates away + // via WebMediaPlayerAndroid::Destroy. + void ReleaseVideoResources(); + // Info for all available WebMediaPlayerAndroid on a page; kept so that // we can enumerate them to send updates about tab focus and visibility. std::map<int, WebMediaPlayerAndroid*> media_players_; diff --git a/content/renderer/media/android/stream_texture_factory_impl.cc b/content/renderer/media/android/stream_texture_factory_impl.cc index ef1c21b..58d165b 100644 --- a/content/renderer/media/android/stream_texture_factory_impl.cc +++ b/content/renderer/media/android/stream_texture_factory_impl.cc @@ -81,17 +81,17 @@ void StreamTextureProxyImpl::OnMatrixChanged(const float matrix[16]) { scoped_refptr<StreamTextureFactoryImpl> StreamTextureFactoryImpl::Create( const scoped_refptr<cc::ContextProvider>& context_provider, GpuChannelHost* channel, - int view_id) { - return new StreamTextureFactoryImpl(context_provider, channel, view_id); + int frame_id) { + return new StreamTextureFactoryImpl(context_provider, channel, frame_id); } StreamTextureFactoryImpl::StreamTextureFactoryImpl( const scoped_refptr<cc::ContextProvider>& context_provider, GpuChannelHost* channel, - int view_id) + int frame_id) : context_provider_(context_provider), channel_(channel), - view_id_(view_id) { + frame_id_(frame_id) { DCHECK(channel); } @@ -106,7 +106,7 @@ StreamTextureProxy* StreamTextureFactoryImpl::CreateProxy() { void StreamTextureFactoryImpl::EstablishPeer(int32 stream_id, int player_id) { DCHECK(channel_.get()); channel_->Send( - new GpuStreamTextureMsg_EstablishPeer(stream_id, view_id_, player_id)); + new GpuStreamTextureMsg_EstablishPeer(stream_id, frame_id_, player_id)); } unsigned StreamTextureFactoryImpl::CreateStreamTexture( diff --git a/content/renderer/media/android/stream_texture_factory_impl.h b/content/renderer/media/android/stream_texture_factory_impl.h index bebec8c..7721c48 100644 --- a/content/renderer/media/android/stream_texture_factory_impl.h +++ b/content/renderer/media/android/stream_texture_factory_impl.h @@ -26,7 +26,7 @@ class StreamTextureFactoryImpl : public StreamTextureFactory { static scoped_refptr<StreamTextureFactoryImpl> Create( const scoped_refptr<cc::ContextProvider>& context_provider, GpuChannelHost* channel, - int view_id); + int frame_id); // StreamTextureFactory implementation. virtual StreamTextureProxy* CreateProxy() OVERRIDE; @@ -43,12 +43,12 @@ class StreamTextureFactoryImpl : public StreamTextureFactory { StreamTextureFactoryImpl( const scoped_refptr<cc::ContextProvider>& context_provider, GpuChannelHost* channel, - int view_id); + int frame_id); virtual ~StreamTextureFactoryImpl(); scoped_refptr<cc::ContextProvider> context_provider_; scoped_refptr<GpuChannelHost> channel_; - int view_id_; + int frame_id_; DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureFactoryImpl); }; diff --git a/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc b/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc index b5512a4..75536cb 100644 --- a/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc +++ b/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc @@ -136,16 +136,16 @@ void StreamTextureProxyImpl::OnFrameAvailable() { scoped_refptr<StreamTextureFactorySynchronousImpl> StreamTextureFactorySynchronousImpl::Create( const CreateContextProviderCallback& try_create_callback, - int view_id) { - return new StreamTextureFactorySynchronousImpl(try_create_callback, view_id); + int frame_id) { + return new StreamTextureFactorySynchronousImpl(try_create_callback, frame_id); } StreamTextureFactorySynchronousImpl::StreamTextureFactorySynchronousImpl( const CreateContextProviderCallback& try_create_callback, - int view_id) + int frame_id) : create_context_provider_callback_(try_create_callback), context_provider_(create_context_provider_callback_.Run()), - view_id_(view_id) {} + frame_id_(frame_id) {} StreamTextureFactorySynchronousImpl::~StreamTextureFactorySynchronousImpl() {} @@ -167,7 +167,7 @@ void StreamTextureFactorySynchronousImpl::EstablishPeer(int32 stream_id, SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer( base::Process::Current().handle(), surface_texture, - view_id_, + frame_id_, player_id); } } diff --git a/content/renderer/media/android/stream_texture_factory_synchronous_impl.h b/content/renderer/media/android/stream_texture_factory_synchronous_impl.h index cc4026a9..3466c56 100644 --- a/content/renderer/media/android/stream_texture_factory_synchronous_impl.h +++ b/content/renderer/media/android/stream_texture_factory_synchronous_impl.h @@ -41,7 +41,7 @@ class StreamTextureFactorySynchronousImpl : public StreamTextureFactory { static scoped_refptr<StreamTextureFactorySynchronousImpl> Create( const CreateContextProviderCallback& try_create_callback, - int view_id); + int frame_id); virtual StreamTextureProxy* CreateProxy() OVERRIDE; virtual void EstablishPeer(int32 stream_id, int player_id) OVERRIDE; @@ -56,12 +56,12 @@ class StreamTextureFactorySynchronousImpl : public StreamTextureFactory { friend class base::RefCounted<StreamTextureFactorySynchronousImpl>; StreamTextureFactorySynchronousImpl( const CreateContextProviderCallback& try_create_callback, - int view_id); + int frame_id); virtual ~StreamTextureFactorySynchronousImpl(); CreateContextProviderCallback create_context_provider_callback_; scoped_refptr<ContextProvider> context_provider_; - int view_id_; + int frame_id_; DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureFactorySynchronousImpl); }; diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index a7a3245..cb58d67 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -120,6 +120,7 @@ #include "content/common/gpu/client/context_provider_command_buffer.h" #include "content/renderer/android/synchronous_compositor_factory.h" +#include "content/renderer/media/android/renderer_media_player_manager.h" #include "content/renderer/media/android/stream_texture_factory_impl.h" #include "content/renderer/media/android/webmediaplayer_android.h" #endif @@ -404,6 +405,9 @@ RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id) notification_provider_(NULL), media_stream_client_(NULL), web_user_media_client_(NULL), +#if defined(OS_ANDROID) + media_player_manager_(NULL), +#endif weak_factory_(this) { RenderThread::Get()->AddRoute(routing_id_, this); @@ -423,6 +427,10 @@ RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id) RenderFrameImpl::~RenderFrameImpl() { FOR_EACH_OBSERVER(RenderFrameObserver, observers_, RenderFrameGone()); FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnDestruct()); +#if defined(VIDEO_HOLE) + if (media_player_manager_) + render_view_->UnregisterVideoHoleFrame(this); +#endif // defined(VIDEO_HOLE) g_routing_id_frame_map.Get().erase(routing_id_); RenderThread::Get()->RemoveRoute(routing_id_); } @@ -1251,6 +1259,8 @@ void RenderFrameImpl::LoadNavigationErrorPage( void RenderFrameImpl::DidCommitCompositorFrame() { if (compositing_helper_) compositing_helper_->DidCommitCompositorFrame(); + FOR_EACH_OBSERVER( + RenderFrameObserver, observers_, DidCommitCompositorFrame()); } RenderView* RenderFrameImpl::GetRenderView() { @@ -3477,19 +3487,29 @@ WebMediaPlayer* RenderFrameImpl::CreateAndroidWebMediaPlayer( } stream_texture_factory = StreamTextureFactoryImpl::Create( - context_provider, gpu_channel_host, render_view_->routing_id_); + context_provider, gpu_channel_host, routing_id_); } return new WebMediaPlayerAndroid( frame_, client, weak_factory_.GetWeakPtr(), - render_view_->media_player_manager_, + GetMediaPlayerManager(), stream_texture_factory, RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy(), new RenderMediaLog()); } -#endif +RendererMediaPlayerManager* RenderFrameImpl::GetMediaPlayerManager() { + if (!media_player_manager_) { + media_player_manager_ = new RendererMediaPlayerManager(this); +#if defined(VIDEO_HOLE) + render_view_->RegisterVideoHoleFrame(this); +#endif // defined(VIDEO_HOLE) + } + return media_player_manager_; +} + +#endif // defined(OS_ANDROID) } // namespace content diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 7d9171c..9cebe76 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h @@ -26,6 +26,10 @@ #include "third_party/WebKit/public/web/WebHistoryCommitType.h" #include "ui/gfx/range/range.h" +#if defined(OS_ANDROID) +#include "content/renderer/media/android/renderer_media_player_manager.h" +#endif + class TransportDIB; struct FrameMsg_BuffersSwapped_Params; struct FrameMsg_CompositorFrameSwapped_Params; @@ -64,6 +68,10 @@ class RenderWidget; class RenderWidgetFullscreenPepper; struct CustomContextMenuContext; +#if defined(OS_ANDROID) +class RendererMediaPlayerManager; +#endif + class CONTENT_EXPORT RenderFrameImpl : public RenderFrame, NON_EXPORTED_BASE(public blink::WebFrameClient), @@ -524,6 +532,8 @@ class CONTENT_EXPORT RenderFrameImpl blink::WebMediaPlayer* CreateAndroidWebMediaPlayer( const blink::WebURL& url, blink::WebMediaPlayerClient* client); + + RendererMediaPlayerManager* GetMediaPlayerManager(); #endif // Stores the WebLocalFrame we are associated with. @@ -593,6 +603,13 @@ class CONTENT_EXPORT RenderFrameImpl MediaStreamClient* media_stream_client_; blink::WebUserMediaClient* web_user_media_client_; +#if defined(OS_ANDROID) + // Manages all media players in this render frame for communicating with the + // real media player and CDM objects in the browser process. It's okay to use + // raw pointers since it's a RenderFrameObserver. + RendererMediaPlayerManager* media_player_manager_; +#endif + base::WeakPtrFactory<RenderFrameImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(RenderFrameImpl); diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index ec984c0..e42b602 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -199,7 +199,6 @@ #include "content/renderer/android/content_detector.h" #include "content/renderer/android/email_detector.h" #include "content/renderer/android/phone_number_detector.h" -#include "content/renderer/media/android/renderer_media_player_manager.h" #include "net/android/network_library.h" #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/public/platform/WebFloatPoint.h" @@ -661,7 +660,6 @@ RenderViewImpl::RenderViewImpl(RenderViewImplParams* params) mouse_lock_dispatcher_(NULL), #if defined(OS_ANDROID) expected_content_intent_id_(0), - media_player_manager_(NULL), #endif #if defined(OS_WIN) focused_plugin_id_(-1), @@ -788,10 +786,6 @@ void RenderViewImpl::Initialize(RenderViewImplParams* params) { new TextInputClientObserver(this); #endif // defined(OS_MACOSX) -#if defined(OS_ANDROID) - media_player_manager_ = new RendererMediaPlayerManager(this); -#endif - // The next group of objects all implement RenderViewObserver, so are deleted // along with the RenderView automatically. devtools_agent_ = new DevToolsAgent(this); @@ -1140,7 +1134,6 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItems, OnSelectPopupMenuItems) IPC_MESSAGE_HANDLER(ViewMsg_UpdateTopControlsState, OnUpdateTopControlsState) - IPC_MESSAGE_HANDLER(ViewMsg_PauseVideo, OnPauseVideo) IPC_MESSAGE_HANDLER(ViewMsg_ExtractSmartClipData, OnExtractSmartClipData) #elif defined(OS_MACOSX) IPC_MESSAGE_HANDLER(ViewMsg_PluginImeCompositionCompleted, @@ -1312,16 +1305,6 @@ void RenderViewImpl::OnSetInLiveResize(bool in_live_resize) { } #endif -#if defined(OS_ANDROID) -void RenderViewImpl::OnPauseVideo() { - // Inform RendererMediaPlayerManager to release all video player resources. - // If something is in progress the resource will not be freed, it will - // only be freed once the tab is destroyed or if the user navigates away - // via WebMediaPlayerAndroid::Destroy. - media_player_manager_->ReleaseVideoResources(); -} -#endif - /////////////////////////////////////////////////////////////////////////////// // Sends the current history state to the browser so it will be saved before we diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 2e4fb14..4094b94 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h @@ -155,7 +155,6 @@ struct FileChooserParams; struct RenderViewImplParams; #if defined(OS_ANDROID) -class RendererMediaPlayerManager; class WebMediaPlayerProxyAndroid; #endif @@ -775,7 +774,6 @@ class CONTENT_EXPORT RenderViewImpl void OnUpdateTopControlsState(bool enable_hiding, bool enable_showing, bool animate); - void OnPauseVideo(); void OnExtractSmartClipData(const gfx::Rect& rect); void GetSelectionRootBounds(gfx::Rect* bounds) const; #elif defined(OS_MACOSX) @@ -1112,10 +1110,6 @@ class CONTENT_EXPORT RenderViewImpl typedef std::vector< linked_ptr<ContentDetector> > ContentDetectorList; ContentDetectorList content_detectors_; - // The media player manager for managing all the media players on this view - // for communicating with the real media player objects in browser process. - RendererMediaPlayerManager* media_player_manager_; - // A date/time picker object for date and time related input elements. scoped_ptr<RendererDateTimePicker> date_time_picker_client_; #endif diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 4eaa8ea..5428b54 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -1212,6 +1212,19 @@ void RenderWidget::didBecomeReadyForAdditionalInput() { void RenderWidget::DidCommitCompositorFrame() { FOR_EACH_OBSERVER(RenderFrameImpl, swapped_out_frames_, DidCommitCompositorFrame()); +#if defined(VIDEO_HOLE) + // Not using FOR_EACH_OBSERVER because |swapped_out_frames_| and + // |video_hole_frames_| may have common frames. + if (!video_hole_frames_.might_have_observers()) + return; + ObserverListBase<RenderFrameImpl>::Iterator iter(video_hole_frames_); + RenderFrameImpl* frame; + while ((frame = iter.GetNext()) != NULL) { + // Prevent duplicate notification of DidCommitCompositorFrame(). + if (!swapped_out_frames_.HasObserver(frame)) + frame->DidCommitCompositorFrame(); + } +#endif // defined(VIDEO_HOLE) } void RenderWidget::didCommitAndDrawCompositorFrame() { @@ -2111,4 +2124,14 @@ void RenderWidget::UnregisterSwappedOutChildFrame(RenderFrameImpl* frame) { swapped_out_frames_.RemoveObserver(frame); } +#if defined(VIDEO_HOLE) +void RenderWidget::RegisterVideoHoleFrame(RenderFrameImpl* frame) { + video_hole_frames_.AddObserver(frame); +} + +void RenderWidget::UnregisterVideoHoleFrame(RenderFrameImpl* frame) { + video_hole_frames_.RemoveObserver(frame); +} +#endif // defined(VIDEO_HOLE) + } // namespace content diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index acdc7d4..43811c3 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h @@ -113,6 +113,11 @@ class CONTENT_EXPORT RenderWidget void RegisterSwappedOutChildFrame(RenderFrameImpl* frame); void UnregisterSwappedOutChildFrame(RenderFrameImpl* frame); +#if defined(VIDEO_HOLE) + void RegisterVideoHoleFrame(RenderFrameImpl* frame); + void UnregisterVideoHoleFrame(RenderFrameImpl* frame); +#endif // defined(VIDEO_HOLE) + // IPC::Listener virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; @@ -708,9 +713,12 @@ class CONTENT_EXPORT RenderWidget scoped_ptr<ResizingModeSelector> resizing_mode_selector_; - // A list of swapped out RenderFrames that need to be notified + // Lists of swapped out RenderFrames that need to be notified // of compositing-related events (e.g. DidCommitCompositorFrame). ObserverList<RenderFrameImpl> swapped_out_frames_; +#if defined(VIDEO_HOLE) + ObserverList<RenderFrameImpl> video_hole_frames_; +#endif // defined(VIDEO_HOLE) ui::MenuSourceType context_menu_source_type_; gfx::Point touch_editing_context_menu_location_; |