1 // Copyright 2013 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/renderer/media/android/renderer_media_player_manager.h"
8 #include "base/message_loop/message_loop.h"
9 #include "content/common/media/cdm_messages.h"
10 #include "content/common/media/media_player_messages_android.h"
11 #include "content/public/common/renderer_preferences.h"
12 #include "content/renderer/media/android/proxy_media_keys.h"
13 #include "content/renderer/media/android/renderer_media_player_manager.h"
14 #include "content/renderer/media/android/webmediaplayer_android.h"
15 #include "content/renderer/render_view_impl.h"
16 #include "ui/gfx/rect_f.h"
20 // Maximum sizes for various EME API parameters. These are checks to prevent
21 // unnecessarily large messages from being passed around, and the sizes
22 // are somewhat arbitrary as the EME spec doesn't specify any limits.
23 const size_t kMaxWebSessionIdLength = 512;
24 const size_t kMaxSessionMessageLength = 10240; // 10 KB
26 RendererMediaPlayerManager::RendererMediaPlayerManager(RenderView* render_view)
27 : RenderViewObserver(render_view),
28 next_media_player_id_(0),
29 fullscreen_frame_(NULL),
30 pending_fullscreen_frame_(NULL) {}
32 RendererMediaPlayerManager::~RendererMediaPlayerManager() {
33 std::map<int, WebMediaPlayerAndroid*>::iterator player_it;
34 for (player_it = media_players_.begin();
35 player_it != media_players_.end(); ++player_it) {
36 WebMediaPlayerAndroid* player = player_it->second;
40 Send(new MediaPlayerHostMsg_DestroyAllMediaPlayers(routing_id()));
43 bool RendererMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) {
45 IPC_BEGIN_MESSAGE_MAP(RendererMediaPlayerManager, msg)
46 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaMetadataChanged,
47 OnMediaMetadataChanged)
48 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaPlaybackCompleted,
49 OnMediaPlaybackCompleted)
50 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaBufferingUpdate,
51 OnMediaBufferingUpdate)
52 IPC_MESSAGE_HANDLER(MediaPlayerMsg_SeekRequest, OnSeekRequest)
53 IPC_MESSAGE_HANDLER(MediaPlayerMsg_SeekCompleted, OnSeekCompleted)
54 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaError, OnMediaError)
55 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaVideoSizeChanged,
57 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaTimeUpdate, OnTimeUpdate)
58 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaPlayerReleased,
59 OnMediaPlayerReleased)
60 IPC_MESSAGE_HANDLER(MediaPlayerMsg_ConnectedToRemoteDevice,
61 OnConnectedToRemoteDevice)
62 IPC_MESSAGE_HANDLER(MediaPlayerMsg_DisconnectedFromRemoteDevice,
63 OnDisconnectedFromRemoteDevice)
64 IPC_MESSAGE_HANDLER(MediaPlayerMsg_RequestFullscreen,
66 IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidEnterFullscreen, OnDidEnterFullscreen)
67 IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidExitFullscreen, OnDidExitFullscreen)
68 IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPlay, OnPlayerPlay)
69 IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPause, OnPlayerPause)
70 IPC_MESSAGE_HANDLER(CdmMsg_SessionCreated, OnSessionCreated)
71 IPC_MESSAGE_HANDLER(CdmMsg_SessionMessage, OnSessionMessage)
72 IPC_MESSAGE_HANDLER(CdmMsg_SessionReady, OnSessionReady)
73 IPC_MESSAGE_HANDLER(CdmMsg_SessionClosed, OnSessionClosed)
74 IPC_MESSAGE_HANDLER(CdmMsg_SessionError, OnSessionError)
75 IPC_MESSAGE_UNHANDLED(handled = false)
80 void RendererMediaPlayerManager::Initialize(
81 MediaPlayerHostMsg_Initialize_Type type,
84 const GURL& first_party_for_cookies,
85 int demuxer_client_id) {
86 Send(new MediaPlayerHostMsg_Initialize(
87 routing_id(), type, player_id, url, first_party_for_cookies,
91 void RendererMediaPlayerManager::Start(int player_id) {
92 Send(new MediaPlayerHostMsg_Start(routing_id(), player_id));
95 void RendererMediaPlayerManager::Pause(
97 bool is_media_related_action) {
98 Send(new MediaPlayerHostMsg_Pause(
99 routing_id(), player_id, is_media_related_action));
102 void RendererMediaPlayerManager::Seek(
104 const base::TimeDelta& time) {
105 Send(new MediaPlayerHostMsg_Seek(routing_id(), player_id, time));
108 void RendererMediaPlayerManager::SetVolume(int player_id, double volume) {
109 Send(new MediaPlayerHostMsg_SetVolume(routing_id(), player_id, volume));
112 void RendererMediaPlayerManager::SetPoster(int player_id, const GURL& poster) {
113 Send(new MediaPlayerHostMsg_SetPoster(routing_id(), player_id, poster));
116 void RendererMediaPlayerManager::ReleaseResources(int player_id) {
117 Send(new MediaPlayerHostMsg_Release(routing_id(), player_id));
120 void RendererMediaPlayerManager::DestroyPlayer(int player_id) {
121 Send(new MediaPlayerHostMsg_DestroyMediaPlayer(routing_id(), player_id));
124 void RendererMediaPlayerManager::OnMediaMetadataChanged(
126 base::TimeDelta duration,
130 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
132 player->OnMediaMetadataChanged(duration, width, height, success);
135 void RendererMediaPlayerManager::OnMediaPlaybackCompleted(int player_id) {
136 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
138 player->OnPlaybackComplete();
141 void RendererMediaPlayerManager::OnMediaBufferingUpdate(int player_id,
143 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
145 player->OnBufferingUpdate(percent);
148 void RendererMediaPlayerManager::OnSeekRequest(
150 const base::TimeDelta& time_to_seek) {
151 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
153 player->OnSeekRequest(time_to_seek);
156 void RendererMediaPlayerManager::OnSeekCompleted(
158 const base::TimeDelta& current_time) {
159 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
161 player->OnSeekComplete(current_time);
164 void RendererMediaPlayerManager::OnMediaError(int player_id, int error) {
165 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
167 player->OnMediaError(error);
170 void RendererMediaPlayerManager::OnVideoSizeChanged(int player_id,
173 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
175 player->OnVideoSizeChanged(width, height);
178 void RendererMediaPlayerManager::OnTimeUpdate(int player_id,
179 base::TimeDelta current_time) {
180 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
182 player->OnTimeUpdate(current_time);
185 void RendererMediaPlayerManager::OnMediaPlayerReleased(int player_id) {
186 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
188 player->OnPlayerReleased();
191 void RendererMediaPlayerManager::OnConnectedToRemoteDevice(int player_id,
192 const std::string& remote_playback_message) {
193 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
195 player->OnConnectedToRemoteDevice(remote_playback_message);
198 void RendererMediaPlayerManager::OnDisconnectedFromRemoteDevice(int player_id) {
199 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
201 player->OnDisconnectedFromRemoteDevice();
204 void RendererMediaPlayerManager::OnDidEnterFullscreen(int player_id) {
205 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
207 player->OnDidEnterFullscreen();
210 void RendererMediaPlayerManager::OnDidExitFullscreen(int player_id) {
211 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
213 player->OnDidExitFullscreen();
216 void RendererMediaPlayerManager::OnPlayerPlay(int player_id) {
217 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
219 player->OnMediaPlayerPlay();
222 void RendererMediaPlayerManager::OnPlayerPause(int player_id) {
223 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
225 player->OnMediaPlayerPause();
228 void RendererMediaPlayerManager::OnRequestFullscreen(int player_id) {
229 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
231 player->OnRequestFullscreen();
234 void RendererMediaPlayerManager::EnterFullscreen(int player_id,
235 blink::WebFrame* frame) {
236 pending_fullscreen_frame_ = frame;
237 Send(new MediaPlayerHostMsg_EnterFullscreen(routing_id(), player_id));
240 void RendererMediaPlayerManager::ExitFullscreen(int player_id) {
241 pending_fullscreen_frame_ = NULL;
242 Send(new MediaPlayerHostMsg_ExitFullscreen(routing_id(), player_id));
245 void RendererMediaPlayerManager::SetCdm(int player_id, int cdm_id) {
246 if (cdm_id == kInvalidCdmId)
248 Send(new MediaPlayerHostMsg_SetCdm(routing_id(), player_id, cdm_id));
251 void RendererMediaPlayerManager::InitializeCdm(int cdm_id,
252 ProxyMediaKeys* media_keys,
253 const std::string& key_system,
254 const GURL& security_origin) {
255 DCHECK_NE(cdm_id, kInvalidCdmId);
256 RegisterMediaKeys(cdm_id, media_keys);
257 Send(new CdmHostMsg_InitializeCdm(
258 routing_id(), cdm_id, key_system, security_origin));
261 void RendererMediaPlayerManager::CreateSession(
264 CdmHostMsg_CreateSession_ContentType content_type,
265 const std::vector<uint8>& init_data) {
266 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered.";
267 Send(new CdmHostMsg_CreateSession(
268 routing_id(), cdm_id, session_id, content_type, init_data));
271 void RendererMediaPlayerManager::UpdateSession(
274 const std::vector<uint8>& response) {
275 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered.";
277 new CdmHostMsg_UpdateSession(routing_id(), cdm_id, session_id, response));
280 void RendererMediaPlayerManager::ReleaseSession(int cdm_id, uint32 session_id) {
281 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered.";
282 Send(new CdmHostMsg_ReleaseSession(routing_id(), cdm_id, session_id));
285 void RendererMediaPlayerManager::DestroyCdm(int cdm_id) {
286 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered.";
287 Send(new CdmHostMsg_DestroyCdm(routing_id(), cdm_id));
288 media_keys_.erase(cdm_id);
291 void RendererMediaPlayerManager::OnSessionCreated(
294 const std::string& web_session_id) {
295 if (web_session_id.length() > kMaxWebSessionIdLength) {
296 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0);
300 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
302 media_keys->OnSessionCreated(session_id, web_session_id);
305 void RendererMediaPlayerManager::OnSessionMessage(
308 const std::vector<uint8>& message,
309 const GURL& destination_url) {
310 if (message.size() > kMaxSessionMessageLength) {
311 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0);
315 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
317 media_keys->OnSessionMessage(session_id, message, destination_url.spec());
320 void RendererMediaPlayerManager::OnSessionReady(int cdm_id, uint32 session_id) {
321 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
323 media_keys->OnSessionReady(session_id);
326 void RendererMediaPlayerManager::OnSessionClosed(int cdm_id,
328 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
330 media_keys->OnSessionClosed(session_id);
333 void RendererMediaPlayerManager::OnSessionError(
336 media::MediaKeys::KeyError error_code,
337 uint32 system_code) {
338 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
340 media_keys->OnSessionError(session_id, error_code, system_code);
343 int RendererMediaPlayerManager::RegisterMediaPlayer(
344 WebMediaPlayerAndroid* player) {
345 media_players_[next_media_player_id_] = player;
346 return next_media_player_id_++;
349 void RendererMediaPlayerManager::UnregisterMediaPlayer(int player_id) {
350 media_players_.erase(player_id);
353 void RendererMediaPlayerManager::RegisterMediaKeys(int cdm_id,
354 ProxyMediaKeys* media_keys) {
355 // Only allowed to register once.
356 DCHECK(media_keys_.find(cdm_id) == media_keys_.end());
358 media_keys_[cdm_id] = media_keys;
361 void RendererMediaPlayerManager::ReleaseVideoResources() {
362 std::map<int, WebMediaPlayerAndroid*>::iterator player_it;
363 for (player_it = media_players_.begin();
364 player_it != media_players_.end(); ++player_it) {
365 WebMediaPlayerAndroid* player = player_it->second;
367 // Do not release if an audio track is still playing
368 if (player && (player->paused() || player->hasVideo()))
369 player->ReleaseMediaResources();
373 WebMediaPlayerAndroid* RendererMediaPlayerManager::GetMediaPlayer(
375 std::map<int, WebMediaPlayerAndroid*>::iterator iter =
376 media_players_.find(player_id);
377 if (iter != media_players_.end())
382 ProxyMediaKeys* RendererMediaPlayerManager::GetMediaKeys(int cdm_id) {
383 std::map<int, ProxyMediaKeys*>::iterator iter = media_keys_.find(cdm_id);
384 return (iter != media_keys_.end()) ? iter->second : NULL;
387 bool RendererMediaPlayerManager::CanEnterFullscreen(blink::WebFrame* frame) {
388 return (!fullscreen_frame_ && !pending_fullscreen_frame_)
389 || ShouldEnterFullscreen(frame);
392 void RendererMediaPlayerManager::DidEnterFullscreen(blink::WebFrame* frame) {
393 pending_fullscreen_frame_ = NULL;
394 fullscreen_frame_ = frame;
397 void RendererMediaPlayerManager::DidExitFullscreen() {
398 fullscreen_frame_ = NULL;
401 bool RendererMediaPlayerManager::IsInFullscreen(blink::WebFrame* frame) {
402 return fullscreen_frame_ == frame;
405 bool RendererMediaPlayerManager::ShouldEnterFullscreen(blink::WebFrame* frame) {
406 return fullscreen_frame_ == frame || pending_fullscreen_frame_ == frame;
409 #if defined(VIDEO_HOLE)
410 void RendererMediaPlayerManager::RequestExternalSurface(
412 const gfx::RectF& geometry) {
413 Send(new MediaPlayerHostMsg_NotifyExternalSurface(
414 routing_id(), player_id, true, geometry));
417 void RendererMediaPlayerManager::DidCommitCompositorFrame() {
418 std::map<int, gfx::RectF> geometry_change;
419 RetrieveGeometryChanges(&geometry_change);
420 for (std::map<int, gfx::RectF>::iterator it = geometry_change.begin();
421 it != geometry_change.end();
423 Send(new MediaPlayerHostMsg_NotifyExternalSurface(
424 routing_id(), it->first, false, it->second));
428 void RendererMediaPlayerManager::RetrieveGeometryChanges(
429 std::map<int, gfx::RectF>* changes) {
430 DCHECK(changes->empty());
431 for (std::map<int, WebMediaPlayerAndroid*>::iterator player_it =
432 media_players_.begin();
433 player_it != media_players_.end();
435 WebMediaPlayerAndroid* player = player_it->second;
437 if (player && player->hasVideo()) {
438 if (player->UpdateBoundaryRectangle())
439 (*changes)[player_it->first] = player->GetBoundaryRectangle();
445 RendererMediaPlayerManager::ShouldUseVideoOverlayForEmbeddedEncryptedVideo() {
446 const RendererPreferences& prefs = static_cast<RenderViewImpl*>(
447 render_view())->renderer_preferences();
448 return prefs.use_video_overlay_for_embedded_encrypted_video;
450 #endif // defined(VIDEO_HOLE)
452 } // namespace content