1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/media/media_web_contents_observer.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/stl_util.h"
9 #include "content/browser/media/cdm/browser_cdm_manager.h"
10 #include "content/common/media/cdm_messages.h"
11 #include "content/public/browser/render_frame_host.h"
12 #include "content/public/browser/web_contents.h"
13 #include "ipc/ipc_message_macros.h"
15 #if defined(OS_ANDROID)
16 #include "content/browser/media/android/browser_media_player_manager.h"
17 #include "content/common/media/media_player_messages_android.h"
18 #include "media/base/android/media_player_android.h"
19 #endif // defined(OS_ANDROID)
23 MediaWebContentsObserver::MediaWebContentsObserver(
24 RenderViewHost
* render_view_host
)
25 : WebContentsObserver(WebContents::FromRenderViewHost(render_view_host
)) {
28 MediaWebContentsObserver::~MediaWebContentsObserver() {
31 void MediaWebContentsObserver::RenderFrameDeleted(
32 RenderFrameHost
* render_frame_host
) {
33 uintptr_t key
= reinterpret_cast<uintptr_t>(render_frame_host
);
34 // Always destroy the media players before CDMs because we do not support
35 // detaching CDMs from media players yet. See http://crbug.com/330324
36 #if defined(OS_ANDROID)
37 media_player_managers_
.erase(key
);
39 cdm_managers_
.erase(key
);
42 bool MediaWebContentsObserver::OnMessageReceived(
43 const IPC::Message
& msg
,
44 RenderFrameHost
* render_frame_host
) {
45 #if defined(OS_ANDROID)
46 // Handles MediaPlayer messages first because MediaPlayers messages are much
47 // more frequent than CDM messages.
48 if (OnMediaPlayerMessageReceived(msg
, render_frame_host
))
51 if (OnMediaPlayerSetCdmMessageReceived(msg
, render_frame_host
))
53 #endif // defined(OS_ANDROID)
55 if (OnCdmMessageReceived(msg
, render_frame_host
))
61 bool MediaWebContentsObserver::OnCdmMessageReceived(
62 const IPC::Message
& msg
,
63 RenderFrameHost
* render_frame_host
) {
65 IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserver
, msg
)
66 IPC_MESSAGE_FORWARD(CdmHostMsg_InitializeCdm
,
67 GetCdmManager(render_frame_host
),
68 BrowserCdmManager::OnInitializeCdm
)
69 IPC_MESSAGE_FORWARD(CdmHostMsg_CreateSession
,
70 GetCdmManager(render_frame_host
),
71 BrowserCdmManager::OnCreateSession
)
72 IPC_MESSAGE_FORWARD(CdmHostMsg_UpdateSession
,
73 GetCdmManager(render_frame_host
),
74 BrowserCdmManager::OnUpdateSession
)
75 IPC_MESSAGE_FORWARD(CdmHostMsg_ReleaseSession
,
76 GetCdmManager(render_frame_host
),
77 BrowserCdmManager::OnReleaseSession
)
78 IPC_MESSAGE_FORWARD(CdmHostMsg_DestroyCdm
,
79 GetCdmManager(render_frame_host
),
80 BrowserCdmManager::OnDestroyCdm
)
81 IPC_MESSAGE_UNHANDLED(handled
= false)
86 BrowserCdmManager
* MediaWebContentsObserver::GetCdmManager(
87 RenderFrameHost
* render_frame_host
) {
88 uintptr_t key
= reinterpret_cast<uintptr_t>(render_frame_host
);
89 if (!cdm_managers_
.contains(key
)) {
91 key
, make_scoped_ptr(BrowserCdmManager::Create(render_frame_host
)));
93 return cdm_managers_
.get(key
);
96 #if defined(OS_ANDROID)
97 bool MediaWebContentsObserver::OnMediaPlayerMessageReceived(
98 const IPC::Message
& msg
,
99 RenderFrameHost
* render_frame_host
) {
101 IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserver
, msg
)
102 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_EnterFullscreen
,
103 GetMediaPlayerManager(render_frame_host
),
104 BrowserMediaPlayerManager::OnEnterFullscreen
)
105 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_ExitFullscreen
,
106 GetMediaPlayerManager(render_frame_host
),
107 BrowserMediaPlayerManager::OnExitFullscreen
)
108 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize
,
109 GetMediaPlayerManager(render_frame_host
),
110 BrowserMediaPlayerManager::OnInitialize
)
111 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start
,
112 GetMediaPlayerManager(render_frame_host
),
113 BrowserMediaPlayerManager::OnStart
)
114 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Seek
,
115 GetMediaPlayerManager(render_frame_host
),
116 BrowserMediaPlayerManager::OnSeek
)
117 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Pause
,
118 GetMediaPlayerManager(render_frame_host
),
119 BrowserMediaPlayerManager::OnPause
)
120 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetVolume
,
121 GetMediaPlayerManager(render_frame_host
),
122 BrowserMediaPlayerManager::OnSetVolume
)
123 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetPoster
,
124 GetMediaPlayerManager(render_frame_host
),
125 BrowserMediaPlayerManager::OnSetPoster
)
126 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Release
,
127 GetMediaPlayerManager(render_frame_host
),
128 BrowserMediaPlayerManager::OnReleaseResources
)
129 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyMediaPlayer
,
130 GetMediaPlayerManager(render_frame_host
),
131 BrowserMediaPlayerManager::OnDestroyPlayer
)
132 #if defined(VIDEO_HOLE)
133 IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_NotifyExternalSurface
,
134 GetMediaPlayerManager(render_frame_host
),
135 BrowserMediaPlayerManager::OnNotifyExternalSurface
)
136 #endif // defined(VIDEO_HOLE)
137 IPC_MESSAGE_UNHANDLED(handled
= false)
138 IPC_END_MESSAGE_MAP()
142 bool MediaWebContentsObserver::OnMediaPlayerSetCdmMessageReceived(
143 const IPC::Message
& msg
,
144 RenderFrameHost
* render_frame_host
) {
146 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(
147 MediaWebContentsObserver
, msg
, render_frame_host
)
148 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetCdm
, OnSetCdm
)
149 IPC_MESSAGE_UNHANDLED(handled
= false)
150 IPC_END_MESSAGE_MAP()
154 void MediaWebContentsObserver::OnSetCdm(RenderFrameHost
* render_frame_host
,
157 media::MediaPlayerAndroid
* media_player
=
158 GetMediaPlayerManager(render_frame_host
)->GetPlayer(player_id
);
160 NOTREACHED() << "OnSetCdm: MediaPlayer not found for " << player_id
;
164 media::BrowserCdm
* cdm
= GetCdmManager(render_frame_host
)->GetCdm(cdm_id
);
166 NOTREACHED() << "OnSetCdm: CDM not found for " << cdm_id
;
170 // TODO(xhwang): This could possibly fail. In that case we should reject the
172 media_player
->SetCdm(cdm
);
175 BrowserMediaPlayerManager
* MediaWebContentsObserver::GetMediaPlayerManager(
176 RenderFrameHost
* render_frame_host
) {
177 uintptr_t key
= reinterpret_cast<uintptr_t>(render_frame_host
);
178 if (!media_player_managers_
.contains(key
)) {
179 media_player_managers_
.set(
181 make_scoped_ptr(BrowserMediaPlayerManager::Create(render_frame_host
)));
183 return media_player_managers_
.get(key
);
186 void MediaWebContentsObserver::PauseVideo() {
187 for (MediaPlayerManagerMap::iterator iter
= media_player_managers_
.begin();
188 iter
!= media_player_managers_
.end(); ++iter
) {
189 BrowserMediaPlayerManager
* manager
= iter
->second
;
190 manager
->PauseVideo();
194 #if defined(VIDEO_HOLE)
195 void MediaWebContentsObserver::OnFrameInfoUpdated() {
196 for (MediaPlayerManagerMap::iterator iter
= media_player_managers_
.begin();
197 iter
!= media_player_managers_
.end(); ++iter
) {
198 BrowserMediaPlayerManager
* manager
= iter
->second
;
199 manager
->OnFrameInfoUpdated();
202 #endif // defined(VIDEO_HOLE)
204 #endif // defined(OS_ANDROID)
206 } // namespace content