• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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