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.
4
5 #include "content/renderer/media/android/renderer_media_player_manager.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "content/common/media/media_player_messages_android.h"
10 #include "content/renderer/media/android/proxy_media_keys.h"
11 #include "content/renderer/media/android/renderer_media_player_manager.h"
12 #include "content/renderer/media/android/webmediaplayer_android.h"
13 #include "ui/gfx/rect_f.h"
14
15 // Maximum sizes for various EME message parameters. These are checks to
16 // prevent unnecessarily large messages from being passed around, and the sizes
17 // are somewhat arbitrary as the EME specification doesn't specify any limits.
18 static const size_t kEmeWebSessionIdMaximum = 512;
19 static const size_t kEmeMessageMaximum = 10240; // 10 KB
20 static const size_t kEmeDestinationUrlMaximum = 2048; // 2 KB
21
22 namespace content {
23
RendererMediaPlayerManager(RenderView * render_view)24 RendererMediaPlayerManager::RendererMediaPlayerManager(RenderView* render_view)
25 : RenderViewObserver(render_view),
26 next_media_player_id_(0),
27 fullscreen_frame_(NULL),
28 pending_fullscreen_frame_(NULL) {}
29
~RendererMediaPlayerManager()30 RendererMediaPlayerManager::~RendererMediaPlayerManager() {
31 std::map<int, WebMediaPlayerAndroid*>::iterator player_it;
32 for (player_it = media_players_.begin();
33 player_it != media_players_.end(); ++player_it) {
34 WebMediaPlayerAndroid* player = player_it->second;
35 player->Detach();
36 }
37
38 Send(new MediaPlayerHostMsg_DestroyAllMediaPlayers(routing_id()));
39 }
40
OnMessageReceived(const IPC::Message & msg)41 bool RendererMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) {
42 bool handled = true;
43 IPC_BEGIN_MESSAGE_MAP(RendererMediaPlayerManager, msg)
44 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaMetadataChanged,
45 OnMediaMetadataChanged)
46 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaPlaybackCompleted,
47 OnMediaPlaybackCompleted)
48 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaBufferingUpdate,
49 OnMediaBufferingUpdate)
50 IPC_MESSAGE_HANDLER(MediaPlayerMsg_SeekRequest, OnSeekRequest)
51 IPC_MESSAGE_HANDLER(MediaPlayerMsg_SeekCompleted, OnSeekCompleted)
52 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaError, OnMediaError)
53 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaVideoSizeChanged,
54 OnVideoSizeChanged)
55 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaTimeUpdate, OnTimeUpdate)
56 IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaPlayerReleased,
57 OnMediaPlayerReleased)
58 IPC_MESSAGE_HANDLER(MediaPlayerMsg_ConnectedToRemoteDevice,
59 OnConnectedToRemoteDevice)
60 IPC_MESSAGE_HANDLER(MediaPlayerMsg_DisconnectedFromRemoteDevice,
61 OnDisconnectedFromRemoteDevice)
62 IPC_MESSAGE_HANDLER(MediaPlayerMsg_RequestFullscreen,
63 OnRequestFullscreen)
64 IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidEnterFullscreen, OnDidEnterFullscreen)
65 IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidExitFullscreen, OnDidExitFullscreen)
66 IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPlay, OnPlayerPlay)
67 IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPause, OnPlayerPause)
68 IPC_MESSAGE_HANDLER(MediaKeysMsg_SessionCreated, OnSessionCreated)
69 IPC_MESSAGE_HANDLER(MediaKeysMsg_SessionMessage, OnSessionMessage)
70 IPC_MESSAGE_HANDLER(MediaKeysMsg_SessionReady, OnSessionReady)
71 IPC_MESSAGE_HANDLER(MediaKeysMsg_SessionClosed, OnSessionClosed)
72 IPC_MESSAGE_HANDLER(MediaKeysMsg_SessionError, OnSessionError)
73 IPC_MESSAGE_UNHANDLED(handled = false)
74 IPC_END_MESSAGE_MAP()
75 return handled;
76 }
77
Initialize(MediaPlayerHostMsg_Initialize_Type type,int player_id,const GURL & url,const GURL & first_party_for_cookies,int demuxer_client_id)78 void RendererMediaPlayerManager::Initialize(
79 MediaPlayerHostMsg_Initialize_Type type,
80 int player_id,
81 const GURL& url,
82 const GURL& first_party_for_cookies,
83 int demuxer_client_id) {
84 Send(new MediaPlayerHostMsg_Initialize(
85 routing_id(), type, player_id, url, first_party_for_cookies,
86 demuxer_client_id));
87 }
88
Start(int player_id)89 void RendererMediaPlayerManager::Start(int player_id) {
90 Send(new MediaPlayerHostMsg_Start(routing_id(), player_id));
91 }
92
Pause(int player_id,bool is_media_related_action)93 void RendererMediaPlayerManager::Pause(
94 int player_id,
95 bool is_media_related_action) {
96 Send(new MediaPlayerHostMsg_Pause(
97 routing_id(), player_id, is_media_related_action));
98 }
99
Seek(int player_id,const base::TimeDelta & time)100 void RendererMediaPlayerManager::Seek(
101 int player_id,
102 const base::TimeDelta& time) {
103 Send(new MediaPlayerHostMsg_Seek(routing_id(), player_id, time));
104 }
105
SetVolume(int player_id,double volume)106 void RendererMediaPlayerManager::SetVolume(int player_id, double volume) {
107 Send(new MediaPlayerHostMsg_SetVolume(routing_id(), player_id, volume));
108 }
109
ReleaseResources(int player_id)110 void RendererMediaPlayerManager::ReleaseResources(int player_id) {
111 Send(new MediaPlayerHostMsg_Release(routing_id(), player_id));
112 }
113
DestroyPlayer(int player_id)114 void RendererMediaPlayerManager::DestroyPlayer(int player_id) {
115 Send(new MediaPlayerHostMsg_DestroyMediaPlayer(routing_id(), player_id));
116 }
117
OnMediaMetadataChanged(int player_id,base::TimeDelta duration,int width,int height,bool success)118 void RendererMediaPlayerManager::OnMediaMetadataChanged(
119 int player_id,
120 base::TimeDelta duration,
121 int width,
122 int height,
123 bool success) {
124 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
125 if (player)
126 player->OnMediaMetadataChanged(duration, width, height, success);
127 }
128
OnMediaPlaybackCompleted(int player_id)129 void RendererMediaPlayerManager::OnMediaPlaybackCompleted(int player_id) {
130 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
131 if (player)
132 player->OnPlaybackComplete();
133 }
134
OnMediaBufferingUpdate(int player_id,int percent)135 void RendererMediaPlayerManager::OnMediaBufferingUpdate(int player_id,
136 int percent) {
137 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
138 if (player)
139 player->OnBufferingUpdate(percent);
140 }
141
OnSeekRequest(int player_id,const base::TimeDelta & time_to_seek)142 void RendererMediaPlayerManager::OnSeekRequest(
143 int player_id,
144 const base::TimeDelta& time_to_seek) {
145 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
146 if (player)
147 player->OnSeekRequest(time_to_seek);
148 }
149
OnSeekCompleted(int player_id,const base::TimeDelta & current_time)150 void RendererMediaPlayerManager::OnSeekCompleted(
151 int player_id,
152 const base::TimeDelta& current_time) {
153 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
154 if (player)
155 player->OnSeekComplete(current_time);
156 }
157
OnMediaError(int player_id,int error)158 void RendererMediaPlayerManager::OnMediaError(int player_id, int error) {
159 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
160 if (player)
161 player->OnMediaError(error);
162 }
163
OnVideoSizeChanged(int player_id,int width,int height)164 void RendererMediaPlayerManager::OnVideoSizeChanged(int player_id,
165 int width,
166 int height) {
167 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
168 if (player)
169 player->OnVideoSizeChanged(width, height);
170 }
171
OnTimeUpdate(int player_id,base::TimeDelta current_time)172 void RendererMediaPlayerManager::OnTimeUpdate(int player_id,
173 base::TimeDelta current_time) {
174 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
175 if (player)
176 player->OnTimeUpdate(current_time);
177 }
178
OnMediaPlayerReleased(int player_id)179 void RendererMediaPlayerManager::OnMediaPlayerReleased(int player_id) {
180 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
181 if (player)
182 player->OnPlayerReleased();
183 }
184
OnConnectedToRemoteDevice(int player_id)185 void RendererMediaPlayerManager::OnConnectedToRemoteDevice(int player_id) {
186 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
187 if (player)
188 player->OnConnectedToRemoteDevice();
189 }
190
OnDisconnectedFromRemoteDevice(int player_id)191 void RendererMediaPlayerManager::OnDisconnectedFromRemoteDevice(int player_id) {
192 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
193 if (player)
194 player->OnDisconnectedFromRemoteDevice();
195 }
196
OnDidEnterFullscreen(int player_id)197 void RendererMediaPlayerManager::OnDidEnterFullscreen(int player_id) {
198 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
199 if (player)
200 player->OnDidEnterFullscreen();
201 }
202
OnDidExitFullscreen(int player_id)203 void RendererMediaPlayerManager::OnDidExitFullscreen(int player_id) {
204 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
205 if (player)
206 player->OnDidExitFullscreen();
207 }
208
OnPlayerPlay(int player_id)209 void RendererMediaPlayerManager::OnPlayerPlay(int player_id) {
210 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
211 if (player)
212 player->OnMediaPlayerPlay();
213 }
214
OnPlayerPause(int player_id)215 void RendererMediaPlayerManager::OnPlayerPause(int player_id) {
216 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
217 if (player)
218 player->OnMediaPlayerPause();
219 }
220
OnRequestFullscreen(int player_id)221 void RendererMediaPlayerManager::OnRequestFullscreen(int player_id) {
222 WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
223 if (player)
224 player->OnRequestFullscreen();
225 }
226
EnterFullscreen(int player_id,blink::WebFrame * frame)227 void RendererMediaPlayerManager::EnterFullscreen(int player_id,
228 blink::WebFrame* frame) {
229 pending_fullscreen_frame_ = frame;
230 Send(new MediaPlayerHostMsg_EnterFullscreen(routing_id(), player_id));
231 }
232
ExitFullscreen(int player_id)233 void RendererMediaPlayerManager::ExitFullscreen(int player_id) {
234 pending_fullscreen_frame_ = NULL;
235 Send(new MediaPlayerHostMsg_ExitFullscreen(routing_id(), player_id));
236 }
237
InitializeCDM(int media_keys_id,ProxyMediaKeys * media_keys,const std::vector<uint8> & uuid,const GURL & frame_url)238 void RendererMediaPlayerManager::InitializeCDM(int media_keys_id,
239 ProxyMediaKeys* media_keys,
240 const std::vector<uint8>& uuid,
241 const GURL& frame_url) {
242 RegisterMediaKeys(media_keys_id, media_keys);
243 Send(new MediaKeysHostMsg_InitializeCDM(
244 routing_id(), media_keys_id, uuid, frame_url));
245 }
246
CreateSession(int media_keys_id,uint32 session_id,const std::string & type,const std::vector<uint8> & init_data)247 void RendererMediaPlayerManager::CreateSession(
248 int media_keys_id,
249 uint32 session_id,
250 const std::string& type,
251 const std::vector<uint8>& init_data) {
252 Send(new MediaKeysHostMsg_CreateSession(
253 routing_id(), media_keys_id, session_id, type, init_data));
254 }
255
UpdateSession(int media_keys_id,uint32 session_id,const std::vector<uint8> & response)256 void RendererMediaPlayerManager::UpdateSession(
257 int media_keys_id,
258 uint32 session_id,
259 const std::vector<uint8>& response) {
260 Send(new MediaKeysHostMsg_UpdateSession(
261 routing_id(), media_keys_id, session_id, response));
262 }
263
ReleaseSession(int media_keys_id,uint32 session_id)264 void RendererMediaPlayerManager::ReleaseSession(int media_keys_id,
265 uint32 session_id) {
266 Send(new MediaKeysHostMsg_ReleaseSession(
267 routing_id(), media_keys_id, session_id));
268 }
269
OnSessionCreated(int media_keys_id,uint32 session_id,const std::string & web_session_id)270 void RendererMediaPlayerManager::OnSessionCreated(
271 int media_keys_id,
272 uint32 session_id,
273 const std::string& web_session_id) {
274 if (web_session_id.length() > kEmeWebSessionIdMaximum) {
275 OnSessionError(
276 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
277 return;
278 }
279
280 ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id);
281 if (media_keys)
282 media_keys->OnSessionCreated(session_id, web_session_id);
283 }
284
OnSessionMessage(int media_keys_id,uint32 session_id,const std::vector<uint8> & message,const std::string & destination_url)285 void RendererMediaPlayerManager::OnSessionMessage(
286 int media_keys_id,
287 uint32 session_id,
288 const std::vector<uint8>& message,
289 const std::string& destination_url) {
290 if (message.size() > kEmeMessageMaximum) {
291 OnSessionError(
292 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
293 return;
294 }
295 if (destination_url.length() > kEmeDestinationUrlMaximum) {
296 OnSessionError(
297 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
298 return;
299 }
300
301 ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id);
302 if (media_keys)
303 media_keys->OnSessionMessage(session_id, message, destination_url);
304 }
305
OnSessionReady(int media_keys_id,uint32 session_id)306 void RendererMediaPlayerManager::OnSessionReady(int media_keys_id,
307 uint32 session_id) {
308 ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id);
309 if (media_keys)
310 media_keys->OnSessionReady(session_id);
311 }
312
OnSessionClosed(int media_keys_id,uint32 session_id)313 void RendererMediaPlayerManager::OnSessionClosed(int media_keys_id,
314 uint32 session_id) {
315 ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id);
316 if (media_keys)
317 media_keys->OnSessionClosed(session_id);
318 }
319
OnSessionError(int media_keys_id,uint32 session_id,media::MediaKeys::KeyError error_code,int system_code)320 void RendererMediaPlayerManager::OnSessionError(
321 int media_keys_id,
322 uint32 session_id,
323 media::MediaKeys::KeyError error_code,
324 int system_code) {
325 ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id);
326 if (media_keys)
327 media_keys->OnSessionError(session_id, error_code, system_code);
328 }
329
RegisterMediaPlayer(WebMediaPlayerAndroid * player)330 int RendererMediaPlayerManager::RegisterMediaPlayer(
331 WebMediaPlayerAndroid* player) {
332 media_players_[next_media_player_id_] = player;
333 return next_media_player_id_++;
334 }
335
UnregisterMediaPlayer(int player_id)336 void RendererMediaPlayerManager::UnregisterMediaPlayer(int player_id) {
337 media_players_.erase(player_id);
338 media_keys_.erase(player_id);
339 }
340
RegisterMediaKeys(int media_keys_id,ProxyMediaKeys * media_keys)341 void RendererMediaPlayerManager::RegisterMediaKeys(int media_keys_id,
342 ProxyMediaKeys* media_keys) {
343 // WebMediaPlayerAndroid must have already been registered for
344 // |media_keys_id|. For now |media_keys_id| is the same as player_id
345 // used in other methods.
346 DCHECK(media_players_.find(media_keys_id) != media_players_.end());
347
348 // Only allowed to register once.
349 DCHECK(media_keys_.find(media_keys_id) == media_keys_.end());
350
351 media_keys_[media_keys_id] = media_keys;
352 }
353
ReleaseVideoResources()354 void RendererMediaPlayerManager::ReleaseVideoResources() {
355 std::map<int, WebMediaPlayerAndroid*>::iterator player_it;
356 for (player_it = media_players_.begin();
357 player_it != media_players_.end(); ++player_it) {
358 WebMediaPlayerAndroid* player = player_it->second;
359
360 // Do not release if an audio track is still playing
361 if (player && (player->paused() || player->hasVideo()))
362 player->ReleaseMediaResources();
363 }
364 }
365
GetMediaPlayer(int player_id)366 WebMediaPlayerAndroid* RendererMediaPlayerManager::GetMediaPlayer(
367 int player_id) {
368 std::map<int, WebMediaPlayerAndroid*>::iterator iter =
369 media_players_.find(player_id);
370 if (iter != media_players_.end())
371 return iter->second;
372 return NULL;
373 }
374
GetMediaKeys(int media_keys_id)375 ProxyMediaKeys* RendererMediaPlayerManager::GetMediaKeys(int media_keys_id) {
376 std::map<int, ProxyMediaKeys*>::iterator iter =
377 media_keys_.find(media_keys_id);
378 return (iter != media_keys_.end()) ? iter->second : NULL;
379 }
380
CanEnterFullscreen(blink::WebFrame * frame)381 bool RendererMediaPlayerManager::CanEnterFullscreen(blink::WebFrame* frame) {
382 return (!fullscreen_frame_ && !pending_fullscreen_frame_)
383 || ShouldEnterFullscreen(frame);
384 }
385
DidEnterFullscreen(blink::WebFrame * frame)386 void RendererMediaPlayerManager::DidEnterFullscreen(blink::WebFrame* frame) {
387 pending_fullscreen_frame_ = NULL;
388 fullscreen_frame_ = frame;
389 }
390
DidExitFullscreen()391 void RendererMediaPlayerManager::DidExitFullscreen() {
392 fullscreen_frame_ = NULL;
393 }
394
IsInFullscreen(blink::WebFrame * frame)395 bool RendererMediaPlayerManager::IsInFullscreen(blink::WebFrame* frame) {
396 return fullscreen_frame_ == frame;
397 }
398
ShouldEnterFullscreen(blink::WebFrame * frame)399 bool RendererMediaPlayerManager::ShouldEnterFullscreen(blink::WebFrame* frame) {
400 return fullscreen_frame_ == frame || pending_fullscreen_frame_ == frame;
401 }
402
403 #if defined(VIDEO_HOLE)
RequestExternalSurface(int player_id,const gfx::RectF & geometry)404 void RendererMediaPlayerManager::RequestExternalSurface(
405 int player_id,
406 const gfx::RectF& geometry) {
407 Send(new MediaPlayerHostMsg_NotifyExternalSurface(
408 routing_id(), player_id, true, geometry));
409 }
410
DidCommitCompositorFrame()411 void RendererMediaPlayerManager::DidCommitCompositorFrame() {
412 std::map<int, gfx::RectF> geometry_change;
413 RetrieveGeometryChanges(&geometry_change);
414 for (std::map<int, gfx::RectF>::iterator it = geometry_change.begin();
415 it != geometry_change.end();
416 ++it) {
417 Send(new MediaPlayerHostMsg_NotifyExternalSurface(
418 routing_id(), it->first, false, it->second));
419 }
420 }
421
RetrieveGeometryChanges(std::map<int,gfx::RectF> * changes)422 void RendererMediaPlayerManager::RetrieveGeometryChanges(
423 std::map<int, gfx::RectF>* changes) {
424 DCHECK(changes->empty());
425 for (std::map<int, WebMediaPlayerAndroid*>::iterator player_it =
426 media_players_.begin();
427 player_it != media_players_.end();
428 ++player_it) {
429 WebMediaPlayerAndroid* player = player_it->second;
430
431 if (player && player->hasVideo()) {
432 gfx::RectF rect;
433 if (player->RetrieveGeometryChange(&rect)) {
434 (*changes)[player_it->first] = rect;
435 }
436 }
437 }
438 }
439 #endif // defined(VIDEO_HOLE)
440
441 } // namespace content
442