04cde982cd114f242c619d739d6aad97dde11b4b
[platform/framework/web/crosswalk.git] / src / content / browser / media / android / browser_media_player_manager.cc
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/browser/media/android/browser_media_player_manager.h"
6
7 #include "base/command_line.h"
8 #include "content/browser/android/content_view_core_impl.h"
9 #include "content/browser/media/android/browser_demuxer_android.h"
10 #include "content/browser/media/android/media_resource_getter_impl.h"
11 #include "content/browser/renderer_host/render_view_host_impl.h"
12 #include "content/browser/web_contents/web_contents_view_android.h"
13 #include "content/common/media/media_player_messages_android.h"
14 #include "content/public/browser/android/content_view_core.h"
15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/storage_partition.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/browser/web_contents_delegate.h"
21 #include "content/public/common/content_client.h"
22 #include "content/public/common/content_switches.h"
23 #include "media/base/android/media_drm_bridge.h"
24 #include "media/base/android/media_player_bridge.h"
25 #include "media/base/android/media_source_player.h"
26 #include "media/base/media_switches.h"
27
28 using media::MediaDrmBridge;
29 using media::MediaPlayerAndroid;
30 using media::MediaPlayerBridge;
31 using media::MediaPlayerManager;
32 using media::MediaSourcePlayer;
33
34 // Threshold on the number of media players per renderer before we start
35 // attempting to release inactive media players.
36 static const int kMediaPlayerThreshold = 1;
37
38 // Maximum sizes for various EME message parameters. These are checks to
39 // prevent unnecessarily large messages from being passed around, and the sizes
40 // are somewhat arbitrary as the EME specification doesn't specify any limits.
41 static const size_t kEmeUuidSize = 16;
42 static const size_t kEmeTypeMaximum = 50;  // Type is a MIME type.
43 static const size_t kEmeInitDataMaximum = 10240;  // 10 KB
44 static const size_t kEmeResponseMaximum = 10240;  // 10 KB
45
46 namespace content {
47
48 static BrowserMediaPlayerManager::Factory g_factory = NULL;
49
50 // static
51 void BrowserMediaPlayerManager::RegisterFactory(Factory factory) {
52   g_factory = factory;
53 }
54
55 // static
56 BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create(
57     RenderViewHost* rvh) {
58   if (g_factory)
59     return g_factory(rvh);
60   return new BrowserMediaPlayerManager(rvh);
61 }
62
63 ContentViewCoreImpl* BrowserMediaPlayerManager::GetContentViewCore() const {
64   return ContentViewCoreImpl::FromWebContents(web_contents());
65 }
66
67 // static
68 MediaPlayerAndroid* BrowserMediaPlayerManager::CreateMediaPlayer(
69     MediaPlayerHostMsg_Initialize_Type type,
70     int player_id,
71     const GURL& url,
72     const GURL& first_party_for_cookies,
73     int demuxer_client_id,
74     bool hide_url_log,
75     MediaPlayerManager* manager,
76     BrowserDemuxerAndroid* demuxer) {
77   switch (type) {
78     case MEDIA_PLAYER_TYPE_URL: {
79       const std::string user_agent = GetUserAgent(url);
80       MediaPlayerBridge* media_player_bridge = new MediaPlayerBridge(
81           player_id,
82           url,
83           first_party_for_cookies,
84           user_agent,
85           hide_url_log,
86           manager);
87       BrowserMediaPlayerManager* browser_media_player_manager =
88           static_cast<BrowserMediaPlayerManager*>(manager);
89       ContentViewCoreImpl* content_view_core_impl =
90           static_cast<ContentViewCoreImpl*>(ContentViewCore::FromWebContents(
91               browser_media_player_manager->web_contents_));
92       if (!content_view_core_impl) {
93         // May reach here due to prerendering. Don't extract the metadata
94         // since it is expensive.
95         // TODO(qinmin): extract the metadata once the user decided to load
96         // the page.
97         browser_media_player_manager->OnMediaMetadataChanged(
98             player_id, base::TimeDelta(), 0, 0, false);
99       } else if (!content_view_core_impl->ShouldBlockMediaRequest(url)) {
100         media_player_bridge->Initialize();
101       }
102       return media_player_bridge;
103     }
104
105     case MEDIA_PLAYER_TYPE_MEDIA_SOURCE: {
106       return new MediaSourcePlayer(
107           player_id, manager, demuxer->CreateDemuxer(demuxer_client_id));
108     }
109   }
110
111   NOTREACHED();
112   return NULL;
113 }
114
115 BrowserMediaPlayerManager::BrowserMediaPlayerManager(
116     RenderViewHost* render_view_host)
117     : WebContentsObserver(WebContents::FromRenderViewHost(render_view_host)),
118       fullscreen_player_id_(-1),
119       pending_fullscreen_player_id_(-1),
120       web_contents_(WebContents::FromRenderViewHost(render_view_host)),
121       weak_ptr_factory_(this) {
122 }
123
124 BrowserMediaPlayerManager::~BrowserMediaPlayerManager() {}
125
126 bool BrowserMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) {
127   bool handled = true;
128   IPC_BEGIN_MESSAGE_MAP(BrowserMediaPlayerManager, msg)
129     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_EnterFullscreen, OnEnterFullscreen)
130     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_ExitFullscreen, OnExitFullscreen)
131     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Initialize, OnInitialize)
132     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Start, OnStart)
133     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Seek, OnSeek)
134     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Pause, OnPause)
135     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetVolume, OnSetVolume)
136     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Release, OnReleaseResources)
137     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyMediaPlayer, OnDestroyPlayer)
138     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers,
139                         DestroyAllMediaPlayers)
140     IPC_MESSAGE_HANDLER(MediaKeysHostMsg_InitializeCDM,
141                         OnInitializeCDM)
142     IPC_MESSAGE_HANDLER(MediaKeysHostMsg_CreateSession, OnCreateSession)
143     IPC_MESSAGE_HANDLER(MediaKeysHostMsg_UpdateSession, OnUpdateSession)
144     IPC_MESSAGE_HANDLER(MediaKeysHostMsg_ReleaseSession, OnReleaseSession)
145     IPC_MESSAGE_HANDLER(MediaKeysHostMsg_CancelAllPendingSessionCreations,
146                         OnCancelAllPendingSessionCreations)
147 #if defined(VIDEO_HOLE)
148     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyExternalSurface,
149                         OnNotifyExternalSurface)
150 #endif  // defined(VIDEO_HOLE)
151     IPC_MESSAGE_UNHANDLED(handled = false)
152   IPC_END_MESSAGE_MAP()
153   return handled;
154 }
155
156 void BrowserMediaPlayerManager::FullscreenPlayerPlay() {
157   MediaPlayerAndroid* player = GetFullscreenPlayer();
158   if (player) {
159     player->Start();
160     Send(new MediaPlayerMsg_DidMediaPlayerPlay(
161         routing_id(), fullscreen_player_id_));
162   }
163 }
164
165 void BrowserMediaPlayerManager::FullscreenPlayerPause() {
166   MediaPlayerAndroid* player = GetFullscreenPlayer();
167   if (player) {
168     player->Pause(true);
169     Send(new MediaPlayerMsg_DidMediaPlayerPause(
170         routing_id(), fullscreen_player_id_));
171   }
172 }
173
174 void BrowserMediaPlayerManager::FullscreenPlayerSeek(int msec) {
175   MediaPlayerAndroid* player = GetFullscreenPlayer();
176   if (player) {
177     // TODO(kbalazs): if |fullscreen_player_is_released_| is true
178     // at this point, player->GetCurrentTime() will be wrong until
179     // FullscreenPlayerPlay (http://crbug.com/322798).
180     OnSeekRequest(fullscreen_player_id_,
181                   base::TimeDelta::FromMilliseconds(msec));
182   }
183 }
184
185 void BrowserMediaPlayerManager::ExitFullscreen(bool release_media_player) {
186   if (CommandLine::ForCurrentProcess()->HasSwitch(
187       switches::kEnableOverlayFullscreenVideoSubtitle)) {
188     if (WebContentsDelegate* delegate = web_contents_->GetDelegate())
189       delegate->ToggleFullscreenModeForTab(web_contents_, false);
190     if (RenderWidgetHostViewAndroid* view_android =
191         static_cast<RenderWidgetHostViewAndroid*>(
192             web_contents_->GetRenderWidgetHostView())) {
193       view_android->SetOverlayVideoMode(false);
194     }
195   }
196
197   Send(new MediaPlayerMsg_DidExitFullscreen(
198       routing_id(), fullscreen_player_id_));
199   video_view_.reset();
200   MediaPlayerAndroid* player = GetFullscreenPlayer();
201   fullscreen_player_id_ = -1;
202   if (!player)
203     return;
204   if (release_media_player)
205     player->Release();
206   else
207     player->SetVideoSurface(gfx::ScopedJavaSurface());
208 }
209
210 void BrowserMediaPlayerManager::SuspendFullscreen() {
211   MediaPlayerAndroid* player = GetFullscreenPlayer();
212   if (player)
213     player->SetVideoSurface(gfx::ScopedJavaSurface());
214 }
215
216 void BrowserMediaPlayerManager::ResumeFullscreen(
217     gfx::ScopedJavaSurface surface) {
218   MediaPlayerAndroid* player = GetFullscreenPlayer();
219   if (player)
220     player->SetVideoSurface(surface.Pass());
221 }
222
223 void BrowserMediaPlayerManager::OnTimeUpdate(int player_id,
224                                              base::TimeDelta current_time) {
225   Send(new MediaPlayerMsg_MediaTimeUpdate(
226       routing_id(), player_id, current_time));
227 }
228
229 void BrowserMediaPlayerManager::SetVideoSurface(
230     gfx::ScopedJavaSurface surface) {
231   MediaPlayerAndroid* player = GetFullscreenPlayer();
232   if (!player)
233     return;
234   if (!surface.IsEmpty()) {
235     Send(new MediaPlayerMsg_DidEnterFullscreen(routing_id(),
236                                                player->player_id()));
237   }
238   player->SetVideoSurface(surface.Pass());
239
240   if (!CommandLine::ForCurrentProcess()->HasSwitch(
241       switches::kEnableOverlayFullscreenVideoSubtitle)) {
242     return;
243   }
244   if (RenderWidgetHostViewAndroid* view_android =
245       static_cast<RenderWidgetHostViewAndroid*>(
246           web_contents_->GetRenderWidgetHostView())) {
247     view_android->SetOverlayVideoMode(true);
248   }
249   if (WebContentsDelegate* delegate = web_contents_->GetDelegate())
250     delegate->ToggleFullscreenModeForTab(web_contents_, true);
251 }
252
253 void BrowserMediaPlayerManager::OnMediaMetadataChanged(
254     int player_id, base::TimeDelta duration, int width, int height,
255     bool success) {
256   Send(new MediaPlayerMsg_MediaMetadataChanged(
257       routing_id(), player_id, duration, width, height, success));
258   if (fullscreen_player_id_ == player_id)
259     video_view_->UpdateMediaMetadata();
260 }
261
262 void BrowserMediaPlayerManager::OnPlaybackComplete(int player_id) {
263   Send(new MediaPlayerMsg_MediaPlaybackCompleted(routing_id(), player_id));
264   if (fullscreen_player_id_ == player_id)
265     video_view_->OnPlaybackComplete();
266 }
267
268 void BrowserMediaPlayerManager::OnMediaInterrupted(int player_id) {
269   // Tell WebKit that the audio should be paused, then release all resources
270   Send(new MediaPlayerMsg_MediaPlayerReleased(routing_id(), player_id));
271   OnReleaseResources(player_id);
272 }
273
274 void BrowserMediaPlayerManager::OnBufferingUpdate(
275     int player_id, int percentage) {
276   Send(new MediaPlayerMsg_MediaBufferingUpdate(
277       routing_id(), player_id, percentage));
278   if (fullscreen_player_id_ == player_id)
279     video_view_->OnBufferingUpdate(percentage);
280 }
281
282 void BrowserMediaPlayerManager::OnSeekRequest(
283     int player_id,
284     const base::TimeDelta& time_to_seek) {
285   Send(new MediaPlayerMsg_SeekRequest(routing_id(), player_id, time_to_seek));
286 }
287
288 void BrowserMediaPlayerManager::OnSeekComplete(
289     int player_id,
290     const base::TimeDelta& current_time) {
291   Send(new MediaPlayerMsg_SeekCompleted(routing_id(), player_id, current_time));
292 }
293
294 void BrowserMediaPlayerManager::OnError(int player_id, int error) {
295   Send(new MediaPlayerMsg_MediaError(routing_id(), player_id, error));
296   if (fullscreen_player_id_ == player_id)
297     video_view_->OnMediaPlayerError(error);
298 }
299
300 void BrowserMediaPlayerManager::OnVideoSizeChanged(
301     int player_id, int width, int height) {
302   Send(new MediaPlayerMsg_MediaVideoSizeChanged(routing_id(), player_id,
303       width, height));
304   if (fullscreen_player_id_ == player_id)
305     video_view_->OnVideoSizeChanged(width, height);
306 }
307
308 void BrowserMediaPlayerManager::RequestMediaResources(int player_id) {
309   int num_active_player = 0;
310   ScopedVector<MediaPlayerAndroid>::iterator it;
311   for (it = players_.begin(); it != players_.end(); ++it) {
312     if (!(*it)->IsPlayerReady())
313       continue;
314
315     // The player is already active, ignore it.
316     if ((*it)->player_id() == player_id)
317       return;
318     else
319       num_active_player++;
320   }
321
322   // Number of active players are less than the threshold, do nothing.
323   if (num_active_player < kMediaPlayerThreshold)
324     return;
325
326   for (it = players_.begin(); it != players_.end(); ++it) {
327     if ((*it)->IsPlayerReady() && !(*it)->IsPlaying() &&
328         fullscreen_player_id_ != (*it)->player_id()) {
329       (*it)->Release();
330       Send(new MediaPlayerMsg_MediaPlayerReleased(
331           routing_id(), (*it)->player_id()));
332     }
333   }
334 }
335
336 void BrowserMediaPlayerManager::ReleaseMediaResources(int player_id) {
337   // Nothing needs to be done.
338 }
339
340 media::MediaResourceGetter*
341 BrowserMediaPlayerManager::GetMediaResourceGetter() {
342   if (!media_resource_getter_.get()) {
343     RenderProcessHost* host = web_contents()->GetRenderProcessHost();
344     BrowserContext* context = host->GetBrowserContext();
345     StoragePartition* partition = host->GetStoragePartition();
346     fileapi::FileSystemContext* file_system_context =
347         partition ? partition->GetFileSystemContext() : NULL;
348     media_resource_getter_.reset(new MediaResourceGetterImpl(
349         context, file_system_context, host->GetID(), routing_id()));
350   }
351   return media_resource_getter_.get();
352 }
353
354 MediaPlayerAndroid* BrowserMediaPlayerManager::GetFullscreenPlayer() {
355   return GetPlayer(fullscreen_player_id_);
356 }
357
358 MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) {
359   for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin();
360       it != players_.end(); ++it) {
361     if ((*it)->player_id() == player_id)
362       return *it;
363   }
364   return NULL;
365 }
366
367 MediaDrmBridge* BrowserMediaPlayerManager::GetDrmBridge(int media_keys_id) {
368   for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin();
369       it != drm_bridges_.end(); ++it) {
370     if ((*it)->media_keys_id() == media_keys_id)
371       return *it;
372   }
373   return NULL;
374 }
375
376 void BrowserMediaPlayerManager::DestroyAllMediaPlayers() {
377   players_.clear();
378   drm_bridges_.clear();
379   if (fullscreen_player_id_ != -1) {
380     video_view_.reset();
381     fullscreen_player_id_ = -1;
382   }
383 }
384
385 void BrowserMediaPlayerManager::OnProtectedSurfaceRequested(int player_id) {
386   if (fullscreen_player_id_ == player_id)
387     return;
388
389   if (fullscreen_player_id_ != -1) {
390     // TODO(qinmin): Determine the correct error code we should report to WMPA.
391     OnError(player_id, MediaPlayerAndroid::MEDIA_ERROR_DECODE);
392     return;
393   }
394
395   // If the player is pending approval, wait for the approval to happen.
396   if (media_keys_ids_pending_approval_.end() !=
397       media_keys_ids_pending_approval_.find(player_id)) {
398     pending_fullscreen_player_id_ = player_id;
399     return;
400   }
401
402   // Send an IPC to the render process to request the video element to enter
403   // fullscreen. OnEnterFullscreen() will be called later on success.
404   // This guarantees the fullscreen video will be rendered correctly.
405   // During the process, DisableFullscreenEncryptedMediaPlayback() may get
406   // called before or after OnEnterFullscreen(). If it is called before
407   // OnEnterFullscreen(), the player will not enter fullscreen. And it will
408   // retry the process once CreateSession() is allowed to proceed.
409   // TODO(qinmin): make this flag default on android.
410   if (CommandLine::ForCurrentProcess()->HasSwitch(
411       switches::kDisableGestureRequirementForMediaFullscreen)) {
412     Send(new MediaPlayerMsg_RequestFullscreen(routing_id(), player_id));
413   }
414 }
415
416 // The following 5 functions are EME MediaKeySession events.
417
418 void BrowserMediaPlayerManager::OnSessionCreated(
419     int media_keys_id,
420     uint32 session_id,
421     const std::string& web_session_id) {
422   Send(new MediaKeysMsg_SessionCreated(
423       routing_id(), media_keys_id, session_id, web_session_id));
424 }
425
426 void BrowserMediaPlayerManager::OnSessionMessage(
427     int media_keys_id,
428     uint32 session_id,
429     const std::vector<uint8>& message,
430     const std::string& destination_url) {
431   Send(new MediaKeysMsg_SessionMessage(
432       routing_id(), media_keys_id, session_id, message, destination_url));
433 }
434
435 void BrowserMediaPlayerManager::OnSessionReady(int media_keys_id,
436                                                uint32 session_id) {
437   Send(new MediaKeysMsg_SessionReady(routing_id(), media_keys_id, session_id));
438 }
439
440 void BrowserMediaPlayerManager::OnSessionClosed(int media_keys_id,
441                                                 uint32 session_id) {
442   Send(new MediaKeysMsg_SessionClosed(routing_id(), media_keys_id, session_id));
443 }
444
445 void BrowserMediaPlayerManager::OnSessionError(
446     int media_keys_id,
447     uint32 session_id,
448     media::MediaKeys::KeyError error_code,
449     int system_code) {
450   Send(new MediaKeysMsg_SessionError(
451       routing_id(), media_keys_id, session_id, error_code, system_code));
452 }
453
454 #if defined(VIDEO_HOLE)
455 void BrowserMediaPlayerManager::AttachExternalVideoSurface(int player_id,
456                                                            jobject surface) {
457   MediaPlayerAndroid* player = GetPlayer(player_id);
458   if (player) {
459     player->SetVideoSurface(
460         gfx::ScopedJavaSurface::AcquireExternalSurface(surface));
461   }
462 }
463
464 void BrowserMediaPlayerManager::DetachExternalVideoSurface(int player_id) {
465   MediaPlayerAndroid* player = GetPlayer(player_id);
466   if (player)
467     player->SetVideoSurface(gfx::ScopedJavaSurface());
468 }
469
470 void BrowserMediaPlayerManager::OnNotifyExternalSurface(
471     int player_id, bool is_request, const gfx::RectF& rect) {
472   if (!web_contents_)
473     return;
474
475   WebContentsViewAndroid* view =
476       static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
477   if (view)
478     view->NotifyExternalSurface(player_id, is_request, rect);
479 }
480 #endif  // defined(VIDEO_HOLE)
481
482 void BrowserMediaPlayerManager::DisableFullscreenEncryptedMediaPlayback() {
483   if (fullscreen_player_id_ == -1)
484     return;
485
486   // If the fullscreen player is not playing back encrypted video, do nothing.
487   MediaDrmBridge* drm_bridge = GetDrmBridge(fullscreen_player_id_);
488   if (!drm_bridge)
489     return;
490
491   // Exit fullscreen.
492   pending_fullscreen_player_id_ = fullscreen_player_id_;
493   OnExitFullscreen(fullscreen_player_id_);
494 }
495
496 void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) {
497   DCHECK_EQ(fullscreen_player_id_, -1);
498   if (media_keys_ids_pending_approval_.find(player_id) !=
499       media_keys_ids_pending_approval_.end()) {
500     return;
501   }
502
503   if (video_view_.get()) {
504     fullscreen_player_id_ = player_id;
505     video_view_->OpenVideo();
506   } else if (!ContentVideoView::GetInstance()) {
507     // In Android WebView, two ContentViewCores could both try to enter
508     // fullscreen video, we just ignore the second one.
509     fullscreen_player_id_ = player_id;
510     video_view_.reset(new ContentVideoView(this));
511   }
512 }
513
514 void BrowserMediaPlayerManager::OnExitFullscreen(int player_id) {
515   if (fullscreen_player_id_ == player_id) {
516     MediaPlayerAndroid* player = GetPlayer(player_id);
517     if (player)
518       player->SetVideoSurface(gfx::ScopedJavaSurface());
519     video_view_->OnExitFullscreen();
520   }
521 }
522
523 void BrowserMediaPlayerManager::OnInitialize(
524     MediaPlayerHostMsg_Initialize_Type type,
525     int player_id,
526     const GURL& url,
527     const GURL& first_party_for_cookies,
528     int demuxer_client_id) {
529   DCHECK(type != MEDIA_PLAYER_TYPE_MEDIA_SOURCE || demuxer_client_id > 0)
530       << "Media source players must have positive demuxer client IDs: "
531       << demuxer_client_id;
532
533   RemovePlayer(player_id);
534
535   RenderProcessHostImpl* host = static_cast<RenderProcessHostImpl*>(
536       web_contents()->GetRenderProcessHost());
537   AddPlayer(CreateMediaPlayer(
538       type, player_id, url, first_party_for_cookies, demuxer_client_id,
539       host->GetBrowserContext()->IsOffTheRecord(), this,
540       host->browser_demuxer_android()));
541 }
542
543 void BrowserMediaPlayerManager::OnStart(int player_id) {
544   MediaPlayerAndroid* player = GetPlayer(player_id);
545   if (player)
546     player->Start();
547 }
548
549 void BrowserMediaPlayerManager::OnSeek(
550     int player_id,
551     const base::TimeDelta& time) {
552   MediaPlayerAndroid* player = GetPlayer(player_id);
553   if (player)
554     player->SeekTo(time);
555 }
556
557 void BrowserMediaPlayerManager::OnPause(
558     int player_id,
559     bool is_media_related_action) {
560   MediaPlayerAndroid* player = GetPlayer(player_id);
561   if (player)
562     player->Pause(is_media_related_action);
563 }
564
565 void BrowserMediaPlayerManager::OnSetVolume(int player_id, double volume) {
566   MediaPlayerAndroid* player = GetPlayer(player_id);
567   if (player)
568     player->SetVolume(volume);
569 }
570
571 void BrowserMediaPlayerManager::OnReleaseResources(int player_id) {
572   MediaPlayerAndroid* player = GetPlayer(player_id);
573   if (player)
574     player->Release();
575
576 #if defined(VIDEO_HOLE)
577   WebContentsViewAndroid* view =
578       static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
579   if (view)
580     view->NotifyExternalSurface(player_id, false, gfx::RectF());
581 #endif  // defined(VIDEO_HOLE)
582 }
583
584 void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) {
585   RemovePlayer(player_id);
586   if (fullscreen_player_id_ == player_id)
587     fullscreen_player_id_ = -1;
588 }
589
590 void BrowserMediaPlayerManager::OnInitializeCDM(
591     int media_keys_id,
592     const std::vector<uint8>& uuid,
593     const GURL& frame_url) {
594   if (uuid.size() != kEmeUuidSize) {
595     // This failure will be discovered and reported by OnCreateSession()
596     // as GetDrmBridge() will return null.
597     NOTREACHED() << "Invalid UUID for ID: " << media_keys_id;
598     return;
599   }
600
601   AddDrmBridge(media_keys_id, uuid, frame_url);
602   // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id|
603   // is the same as the |player_id|.
604   OnSetMediaKeys(media_keys_id, media_keys_id);
605 }
606
607 void BrowserMediaPlayerManager::OnCreateSession(
608     int media_keys_id,
609     uint32 session_id,
610     const std::string& type,
611     const std::vector<uint8>& init_data) {
612   if (type.length() > kEmeTypeMaximum) {
613     OnSessionError(
614         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
615     return;
616   }
617   if (init_data.size() > kEmeInitDataMaximum) {
618     OnSessionError(
619         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
620     return;
621   }
622
623   if (CommandLine::ForCurrentProcess()
624       ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) {
625     CreateSessionIfPermitted(media_keys_id, session_id, type, init_data, true);
626     return;
627   }
628
629   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
630   if (!drm_bridge) {
631     DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
632     OnSessionError(
633         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
634     return;
635   }
636
637   if (media_keys_ids_approved_.find(media_keys_id) ==
638       media_keys_ids_approved_.end()) {
639     media_keys_ids_pending_approval_.insert(media_keys_id);
640   }
641
642   BrowserContext* context =
643       web_contents()->GetRenderProcessHost()->GetBrowserContext();
644
645   context->RequestProtectedMediaIdentifierPermission(
646       web_contents()->GetRenderProcessHost()->GetID(),
647       web_contents()->GetRenderViewHost()->GetRoutingID(),
648       static_cast<int>(session_id),
649       media_keys_id,
650       drm_bridge->frame_url(),
651       base::Bind(&BrowserMediaPlayerManager::CreateSessionIfPermitted,
652                  weak_ptr_factory_.GetWeakPtr(),
653                  media_keys_id,
654                  session_id,
655                  type,
656                  init_data));
657 }
658
659 void BrowserMediaPlayerManager::OnUpdateSession(
660     int media_keys_id,
661     uint32 session_id,
662     const std::vector<uint8>& response) {
663   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
664   if (!drm_bridge) {
665     DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
666     OnSessionError(
667         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
668     return;
669   }
670
671   if (response.size() > kEmeResponseMaximum) {
672     DLOG(WARNING) << "Response for ID: " << media_keys_id
673                   << " too long: " << response.size();
674     OnSessionError(
675         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
676     return;
677   }
678
679   drm_bridge->UpdateSession(session_id, &response[0], response.size());
680   // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id|
681   // is the same as the |player_id|.
682   // TODO(xhwang): Separate |media_keys_id| and |player_id|.
683   MediaPlayerAndroid* player = GetPlayer(media_keys_id);
684   if (player)
685     player->OnKeyAdded();
686 }
687
688 void BrowserMediaPlayerManager::OnReleaseSession(int media_keys_id,
689                                                  uint32 session_id) {
690   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
691   if (!drm_bridge) {
692     DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
693     OnSessionError(
694         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
695     return;
696   }
697
698   drm_bridge->ReleaseSession(session_id);
699 }
700
701 void BrowserMediaPlayerManager::OnCancelAllPendingSessionCreations(
702     int media_keys_id) {
703   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
704   if (!drm_bridge) return;
705
706   BrowserContext* context =
707       web_contents()->GetRenderProcessHost()->GetBrowserContext();
708   context->CancelProtectedMediaIdentifierPermissionRequests(media_keys_id);
709 }
710
711 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) {
712   DCHECK(!GetPlayer(player->player_id()));
713   players_.push_back(player);
714   if (player->IsRemote()) {
715     Send(new MediaPlayerMsg_ConnectedToRemoteDevice(routing_id(),
716                                                     player->player_id()));
717   }
718 }
719
720 void BrowserMediaPlayerManager::RemovePlayer(int player_id) {
721   for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin();
722       it != players_.end(); ++it) {
723     MediaPlayerAndroid* player = *it;
724     if (player->player_id() == player_id) {
725       if (player->IsRemote()) {
726         Send(new MediaPlayerMsg_DisconnectedFromRemoteDevice(
727             routing_id(), player->player_id()));
728       }
729       players_.erase(it);
730       break;
731     }
732   }
733 }
734
735 scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer(
736       int player_id, media::MediaPlayerAndroid* player) {
737   media::MediaPlayerAndroid* previous_player = NULL;
738   for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin();
739       it != players_.end(); ++it) {
740     if ((*it)->player_id() == player_id) {
741       previous_player = *it;
742       players_.weak_erase(it);
743       players_.push_back(player);
744       if (!previous_player->IsRemote() && player->IsRemote()) {
745         Send(new MediaPlayerMsg_ConnectedToRemoteDevice(
746             routing_id(), player->player_id()));
747       } else if (previous_player->IsRemote() && !player->IsRemote()) {
748         Send(new MediaPlayerMsg_DisconnectedFromRemoteDevice(
749             routing_id(), player->player_id()));
750       }
751       break;
752     }
753   }
754   return scoped_ptr<media::MediaPlayerAndroid>(previous_player);
755 }
756
757 void BrowserMediaPlayerManager::AddDrmBridge(int media_keys_id,
758                                              const std::vector<uint8>& uuid,
759                                              const GURL& frame_url) {
760   DCHECK(!GetDrmBridge(media_keys_id));
761
762   scoped_ptr<MediaDrmBridge> drm_bridge(MediaDrmBridge::Create(
763       media_keys_id, uuid, frame_url, this));
764   if (!drm_bridge) {
765     // This failure will be discovered and reported by OnCreateSession()
766     // as GetDrmBridge() will return null.
767     DVLOG(1) << "failed to create drm bridge.";
768     return;
769   }
770
771   // TODO(xhwang/ddorwin): Pass the security level from key system.
772   MediaDrmBridge::SecurityLevel security_level =
773       MediaDrmBridge::SECURITY_LEVEL_3;
774   if (CommandLine::ForCurrentProcess()
775           ->HasSwitch(switches::kMediaDrmEnableNonCompositing)) {
776     security_level = MediaDrmBridge::SECURITY_LEVEL_1;
777   }
778   if (!drm_bridge->SetSecurityLevel(security_level)) {
779     DVLOG(1) << "failed to set security level " << security_level;
780     return;
781   }
782
783   drm_bridges_.push_back(drm_bridge.release());
784 }
785
786 void BrowserMediaPlayerManager::RemoveDrmBridge(int media_keys_id) {
787   for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin();
788       it != drm_bridges_.end(); ++it) {
789     if ((*it)->media_keys_id() == media_keys_id) {
790       drm_bridges_.erase(it);
791       break;
792     }
793   }
794 }
795
796 void BrowserMediaPlayerManager::OnSetMediaKeys(int player_id,
797                                                int media_keys_id) {
798   MediaPlayerAndroid* player = GetPlayer(player_id);
799   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
800   if (!player || !drm_bridge) {
801     DVLOG(1) << "OnSetMediaKeys(): Player and MediaKeys must be present.";
802     return;
803   }
804   // TODO(qinmin): add the logic to decide whether we should create the
805   // fullscreen surface for EME lv1.
806   player->SetDrmBridge(drm_bridge);
807 }
808
809 void BrowserMediaPlayerManager::CreateSessionIfPermitted(
810     int media_keys_id,
811     uint32 session_id,
812     const std::string& type,
813     const std::vector<uint8>& init_data,
814     bool permitted) {
815   if (!permitted) {
816     OnSessionError(
817         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
818     return;
819   }
820
821   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
822   if (!drm_bridge) {
823     DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
824     OnSessionError(
825         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
826     return;
827   }
828   media_keys_ids_pending_approval_.erase(media_keys_id);
829   media_keys_ids_approved_.insert(media_keys_id);
830   drm_bridge->CreateSession(session_id, type, &init_data[0], init_data.size());
831
832   // TODO(qinmin): currently |media_keys_id| and player ID are identical.
833   // This might not be true in the future.
834   if (pending_fullscreen_player_id_ != media_keys_id)
835     return;
836
837   pending_fullscreen_player_id_ = -1;
838   MediaPlayerAndroid* player = GetPlayer(media_keys_id);
839   if (player->IsPlaying())
840     OnProtectedSurfaceRequested(media_keys_id);
841 }
842
843 }  // namespace content