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.
18static const size_t kEmeWebSessionIdMaximum = 512;
19static const size_t kEmeMessageMaximum = 10240;  // 10 KB
20static const size_t kEmeDestinationUrlMaximum = 2048;  // 2 KB
21
22namespace content {
23
24RendererMediaPlayerManager::RendererMediaPlayerManager(RenderView* render_view)
25    : RenderViewObserver(render_view),
26      next_media_player_id_(0),
27      fullscreen_frame_(NULL),
28      pending_fullscreen_frame_(NULL) {}
29
30RendererMediaPlayerManager::~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
41bool 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
78void 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
89void RendererMediaPlayerManager::Start(int player_id) {
90  Send(new MediaPlayerHostMsg_Start(routing_id(), player_id));
91}
92
93void 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
100void RendererMediaPlayerManager::Seek(
101    int player_id,
102    const base::TimeDelta& time) {
103  Send(new MediaPlayerHostMsg_Seek(routing_id(), player_id, time));
104}
105
106void RendererMediaPlayerManager::SetVolume(int player_id, double volume) {
107  Send(new MediaPlayerHostMsg_SetVolume(routing_id(), player_id, volume));
108}
109
110void RendererMediaPlayerManager::ReleaseResources(int player_id) {
111  Send(new MediaPlayerHostMsg_Release(routing_id(), player_id));
112}
113
114void RendererMediaPlayerManager::DestroyPlayer(int player_id) {
115  Send(new MediaPlayerHostMsg_DestroyMediaPlayer(routing_id(), player_id));
116}
117
118void 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
129void RendererMediaPlayerManager::OnMediaPlaybackCompleted(int player_id) {
130  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
131  if (player)
132    player->OnPlaybackComplete();
133}
134
135void RendererMediaPlayerManager::OnMediaBufferingUpdate(int player_id,
136                                                        int percent) {
137  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
138  if (player)
139    player->OnBufferingUpdate(percent);
140}
141
142void 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
150void 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
158void RendererMediaPlayerManager::OnMediaError(int player_id, int error) {
159  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
160  if (player)
161    player->OnMediaError(error);
162}
163
164void 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
172void 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
179void RendererMediaPlayerManager::OnMediaPlayerReleased(int player_id) {
180  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
181  if (player)
182    player->OnPlayerReleased();
183}
184
185void RendererMediaPlayerManager::OnConnectedToRemoteDevice(int player_id) {
186  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
187  if (player)
188    player->OnConnectedToRemoteDevice();
189}
190
191void RendererMediaPlayerManager::OnDisconnectedFromRemoteDevice(int player_id) {
192  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
193  if (player)
194    player->OnDisconnectedFromRemoteDevice();
195}
196
197void RendererMediaPlayerManager::OnDidEnterFullscreen(int player_id) {
198  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
199  if (player)
200    player->OnDidEnterFullscreen();
201}
202
203void RendererMediaPlayerManager::OnDidExitFullscreen(int player_id) {
204  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
205  if (player)
206    player->OnDidExitFullscreen();
207}
208
209void RendererMediaPlayerManager::OnPlayerPlay(int player_id) {
210  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
211  if (player)
212    player->OnMediaPlayerPlay();
213}
214
215void RendererMediaPlayerManager::OnPlayerPause(int player_id) {
216  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
217  if (player)
218    player->OnMediaPlayerPause();
219}
220
221void RendererMediaPlayerManager::OnRequestFullscreen(int player_id) {
222  WebMediaPlayerAndroid* player = GetMediaPlayer(player_id);
223  if (player)
224    player->OnRequestFullscreen();
225}
226
227void 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
233void RendererMediaPlayerManager::ExitFullscreen(int player_id) {
234  pending_fullscreen_frame_ = NULL;
235  Send(new MediaPlayerHostMsg_ExitFullscreen(routing_id(), player_id));
236}
237
238void 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
247void 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
256void 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
264void 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
270void 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
285void 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
306void 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
313void 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
320void 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
330int RendererMediaPlayerManager::RegisterMediaPlayer(
331    WebMediaPlayerAndroid* player) {
332  media_players_[next_media_player_id_] = player;
333  return next_media_player_id_++;
334}
335
336void RendererMediaPlayerManager::UnregisterMediaPlayer(int player_id) {
337  media_players_.erase(player_id);
338  media_keys_.erase(player_id);
339}
340
341void 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
354void 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
366WebMediaPlayerAndroid* 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
375ProxyMediaKeys* 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
381bool RendererMediaPlayerManager::CanEnterFullscreen(blink::WebFrame* frame) {
382  return (!fullscreen_frame_ && !pending_fullscreen_frame_)
383      || ShouldEnterFullscreen(frame);
384}
385
386void RendererMediaPlayerManager::DidEnterFullscreen(blink::WebFrame* frame) {
387  pending_fullscreen_frame_ = NULL;
388  fullscreen_frame_ = frame;
389}
390
391void RendererMediaPlayerManager::DidExitFullscreen() {
392  fullscreen_frame_ = NULL;
393}
394
395bool RendererMediaPlayerManager::IsInFullscreen(blink::WebFrame* frame) {
396  return fullscreen_frame_ == frame;
397}
398
399bool RendererMediaPlayerManager::ShouldEnterFullscreen(blink::WebFrame* frame) {
400  return fullscreen_frame_ == frame || pending_fullscreen_frame_ == frame;
401}
402
403#if defined(VIDEO_HOLE)
404void 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
411void 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
422void 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