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/browser/media/android/browser_media_player_manager.h"
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"
28 using media::MediaDrmBridge;
29 using media::MediaPlayerAndroid;
30 using media::MediaPlayerBridge;
31 using media::MediaPlayerManager;
32 using media::MediaSourcePlayer;
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;
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
48 static BrowserMediaPlayerManager::Factory g_factory = NULL;
51 void BrowserMediaPlayerManager::RegisterFactory(Factory factory) {
56 BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create(
57 RenderViewHost* rvh) {
59 return g_factory(rvh);
60 return new BrowserMediaPlayerManager(rvh);
63 ContentViewCoreImpl* BrowserMediaPlayerManager::GetContentViewCore() const {
64 return ContentViewCoreImpl::FromWebContents(web_contents());
68 MediaPlayerAndroid* BrowserMediaPlayerManager::CreateMediaPlayer(
69 MediaPlayerHostMsg_Initialize_Type type,
72 const GURL& first_party_for_cookies,
73 int demuxer_client_id,
75 MediaPlayerManager* manager,
76 BrowserDemuxerAndroid* demuxer) {
78 case MEDIA_PLAYER_TYPE_URL: {
79 const std::string user_agent = GetUserAgent(url);
80 MediaPlayerBridge* media_player_bridge = new MediaPlayerBridge(
83 first_party_for_cookies,
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
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();
102 return media_player_bridge;
105 case MEDIA_PLAYER_TYPE_MEDIA_SOURCE: {
106 return new MediaSourcePlayer(
107 player_id, manager, demuxer->CreateDemuxer(demuxer_client_id));
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) {
124 BrowserMediaPlayerManager::~BrowserMediaPlayerManager() {}
126 bool BrowserMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) {
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,
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()
156 void BrowserMediaPlayerManager::FullscreenPlayerPlay() {
157 MediaPlayerAndroid* player = GetFullscreenPlayer();
160 Send(new MediaPlayerMsg_DidMediaPlayerPlay(
161 routing_id(), fullscreen_player_id_));
165 void BrowserMediaPlayerManager::FullscreenPlayerPause() {
166 MediaPlayerAndroid* player = GetFullscreenPlayer();
169 Send(new MediaPlayerMsg_DidMediaPlayerPause(
170 routing_id(), fullscreen_player_id_));
174 void BrowserMediaPlayerManager::FullscreenPlayerSeek(int msec) {
175 MediaPlayerAndroid* player = GetFullscreenPlayer();
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));
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);
197 Send(new MediaPlayerMsg_DidExitFullscreen(
198 routing_id(), fullscreen_player_id_));
200 MediaPlayerAndroid* player = GetFullscreenPlayer();
201 fullscreen_player_id_ = -1;
204 if (release_media_player)
207 player->SetVideoSurface(gfx::ScopedJavaSurface());
210 void BrowserMediaPlayerManager::SuspendFullscreen() {
211 MediaPlayerAndroid* player = GetFullscreenPlayer();
213 player->SetVideoSurface(gfx::ScopedJavaSurface());
216 void BrowserMediaPlayerManager::ResumeFullscreen(
217 gfx::ScopedJavaSurface surface) {
218 MediaPlayerAndroid* player = GetFullscreenPlayer();
220 player->SetVideoSurface(surface.Pass());
223 void BrowserMediaPlayerManager::OnTimeUpdate(int player_id,
224 base::TimeDelta current_time) {
225 Send(new MediaPlayerMsg_MediaTimeUpdate(
226 routing_id(), player_id, current_time));
229 void BrowserMediaPlayerManager::SetVideoSurface(
230 gfx::ScopedJavaSurface surface) {
231 MediaPlayerAndroid* player = GetFullscreenPlayer();
234 if (!surface.IsEmpty()) {
235 Send(new MediaPlayerMsg_DidEnterFullscreen(routing_id(),
236 player->player_id()));
238 player->SetVideoSurface(surface.Pass());
240 if (!CommandLine::ForCurrentProcess()->HasSwitch(
241 switches::kEnableOverlayFullscreenVideoSubtitle)) {
244 if (RenderWidgetHostViewAndroid* view_android =
245 static_cast<RenderWidgetHostViewAndroid*>(
246 web_contents_->GetRenderWidgetHostView())) {
247 view_android->SetOverlayVideoMode(true);
249 if (WebContentsDelegate* delegate = web_contents_->GetDelegate())
250 delegate->ToggleFullscreenModeForTab(web_contents_, true);
253 void BrowserMediaPlayerManager::OnMediaMetadataChanged(
254 int player_id, base::TimeDelta duration, int width, int height,
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();
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();
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);
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);
282 void BrowserMediaPlayerManager::OnSeekRequest(
284 const base::TimeDelta& time_to_seek) {
285 Send(new MediaPlayerMsg_SeekRequest(routing_id(), player_id, time_to_seek));
288 void BrowserMediaPlayerManager::OnSeekComplete(
290 const base::TimeDelta& current_time) {
291 Send(new MediaPlayerMsg_SeekCompleted(routing_id(), player_id, current_time));
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);
300 void BrowserMediaPlayerManager::OnVideoSizeChanged(
301 int player_id, int width, int height) {
302 Send(new MediaPlayerMsg_MediaVideoSizeChanged(routing_id(), player_id,
304 if (fullscreen_player_id_ == player_id)
305 video_view_->OnVideoSizeChanged(width, height);
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())
315 // The player is already active, ignore it.
316 if ((*it)->player_id() == player_id)
322 // Number of active players are less than the threshold, do nothing.
323 if (num_active_player < kMediaPlayerThreshold)
326 for (it = players_.begin(); it != players_.end(); ++it) {
327 if ((*it)->IsPlayerReady() && !(*it)->IsPlaying() &&
328 fullscreen_player_id_ != (*it)->player_id()) {
330 Send(new MediaPlayerMsg_MediaPlayerReleased(
331 routing_id(), (*it)->player_id()));
336 void BrowserMediaPlayerManager::ReleaseMediaResources(int player_id) {
337 // Nothing needs to be done.
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()));
351 return media_resource_getter_.get();
354 MediaPlayerAndroid* BrowserMediaPlayerManager::GetFullscreenPlayer() {
355 return GetPlayer(fullscreen_player_id_);
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)
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)
376 void BrowserMediaPlayerManager::DestroyAllMediaPlayers() {
378 drm_bridges_.clear();
379 if (fullscreen_player_id_ != -1) {
381 fullscreen_player_id_ = -1;
385 void BrowserMediaPlayerManager::OnProtectedSurfaceRequested(int player_id) {
386 if (fullscreen_player_id_ == player_id)
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);
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;
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));
416 // The following 5 functions are EME MediaKeySession events.
418 void BrowserMediaPlayerManager::OnSessionCreated(
421 const std::string& web_session_id) {
422 Send(new MediaKeysMsg_SessionCreated(
423 routing_id(), media_keys_id, session_id, web_session_id));
426 void BrowserMediaPlayerManager::OnSessionMessage(
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));
435 void BrowserMediaPlayerManager::OnSessionReady(int media_keys_id,
437 Send(new MediaKeysMsg_SessionReady(routing_id(), media_keys_id, session_id));
440 void BrowserMediaPlayerManager::OnSessionClosed(int media_keys_id,
442 Send(new MediaKeysMsg_SessionClosed(routing_id(), media_keys_id, session_id));
445 void BrowserMediaPlayerManager::OnSessionError(
448 media::MediaKeys::KeyError error_code,
450 Send(new MediaKeysMsg_SessionError(
451 routing_id(), media_keys_id, session_id, error_code, system_code));
454 #if defined(VIDEO_HOLE)
455 void BrowserMediaPlayerManager::AttachExternalVideoSurface(int player_id,
457 MediaPlayerAndroid* player = GetPlayer(player_id);
459 player->SetVideoSurface(
460 gfx::ScopedJavaSurface::AcquireExternalSurface(surface));
464 void BrowserMediaPlayerManager::DetachExternalVideoSurface(int player_id) {
465 MediaPlayerAndroid* player = GetPlayer(player_id);
467 player->SetVideoSurface(gfx::ScopedJavaSurface());
470 void BrowserMediaPlayerManager::OnNotifyExternalSurface(
471 int player_id, bool is_request, const gfx::RectF& rect) {
475 WebContentsViewAndroid* view =
476 static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
478 view->NotifyExternalSurface(player_id, is_request, rect);
480 #endif // defined(VIDEO_HOLE)
482 void BrowserMediaPlayerManager::DisableFullscreenEncryptedMediaPlayback() {
483 if (fullscreen_player_id_ == -1)
486 // If the fullscreen player is not playing back encrypted video, do nothing.
487 MediaDrmBridge* drm_bridge = GetDrmBridge(fullscreen_player_id_);
492 pending_fullscreen_player_id_ = fullscreen_player_id_;
493 OnExitFullscreen(fullscreen_player_id_);
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()) {
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));
514 void BrowserMediaPlayerManager::OnExitFullscreen(int player_id) {
515 if (fullscreen_player_id_ == player_id) {
516 MediaPlayerAndroid* player = GetPlayer(player_id);
518 player->SetVideoSurface(gfx::ScopedJavaSurface());
519 video_view_->OnExitFullscreen();
523 void BrowserMediaPlayerManager::OnInitialize(
524 MediaPlayerHostMsg_Initialize_Type type,
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;
533 RemovePlayer(player_id);
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()));
543 void BrowserMediaPlayerManager::OnStart(int player_id) {
544 MediaPlayerAndroid* player = GetPlayer(player_id);
549 void BrowserMediaPlayerManager::OnSeek(
551 const base::TimeDelta& time) {
552 MediaPlayerAndroid* player = GetPlayer(player_id);
554 player->SeekTo(time);
557 void BrowserMediaPlayerManager::OnPause(
559 bool is_media_related_action) {
560 MediaPlayerAndroid* player = GetPlayer(player_id);
562 player->Pause(is_media_related_action);
565 void BrowserMediaPlayerManager::OnSetVolume(int player_id, double volume) {
566 MediaPlayerAndroid* player = GetPlayer(player_id);
568 player->SetVolume(volume);
571 void BrowserMediaPlayerManager::OnReleaseResources(int player_id) {
572 MediaPlayerAndroid* player = GetPlayer(player_id);
576 #if defined(VIDEO_HOLE)
577 WebContentsViewAndroid* view =
578 static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
580 view->NotifyExternalSurface(player_id, false, gfx::RectF());
581 #endif // defined(VIDEO_HOLE)
584 void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) {
585 RemovePlayer(player_id);
586 if (fullscreen_player_id_ == player_id)
587 fullscreen_player_id_ = -1;
590 void BrowserMediaPlayerManager::OnInitializeCDM(
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;
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);
607 void BrowserMediaPlayerManager::OnCreateSession(
610 const std::string& type,
611 const std::vector<uint8>& init_data) {
612 if (type.length() > kEmeTypeMaximum) {
614 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
617 if (init_data.size() > kEmeInitDataMaximum) {
619 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
623 if (CommandLine::ForCurrentProcess()
624 ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) {
625 CreateSessionIfPermitted(media_keys_id, session_id, type, init_data, true);
629 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
631 DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
633 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
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);
642 BrowserContext* context =
643 web_contents()->GetRenderProcessHost()->GetBrowserContext();
645 context->RequestProtectedMediaIdentifierPermission(
646 web_contents()->GetRenderProcessHost()->GetID(),
647 web_contents()->GetRenderViewHost()->GetRoutingID(),
648 static_cast<int>(session_id),
650 drm_bridge->frame_url(),
651 base::Bind(&BrowserMediaPlayerManager::CreateSessionIfPermitted,
652 weak_ptr_factory_.GetWeakPtr(),
659 void BrowserMediaPlayerManager::OnUpdateSession(
662 const std::vector<uint8>& response) {
663 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
665 DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
667 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
671 if (response.size() > kEmeResponseMaximum) {
672 DLOG(WARNING) << "Response for ID: " << media_keys_id
673 << " too long: " << response.size();
675 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
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);
685 player->OnKeyAdded();
688 void BrowserMediaPlayerManager::OnReleaseSession(int media_keys_id,
690 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
692 DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
694 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
698 drm_bridge->ReleaseSession(session_id);
701 void BrowserMediaPlayerManager::OnCancelAllPendingSessionCreations(
703 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
704 if (!drm_bridge) return;
706 BrowserContext* context =
707 web_contents()->GetRenderProcessHost()->GetBrowserContext();
708 context->CancelProtectedMediaIdentifierPermissionRequests(media_keys_id);
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()));
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()));
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()));
754 return scoped_ptr<media::MediaPlayerAndroid>(previous_player);
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));
762 scoped_ptr<MediaDrmBridge> drm_bridge(MediaDrmBridge::Create(
763 media_keys_id, uuid, frame_url, this));
765 // This failure will be discovered and reported by OnCreateSession()
766 // as GetDrmBridge() will return null.
767 DVLOG(1) << "failed to create drm bridge.";
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;
778 if (!drm_bridge->SetSecurityLevel(security_level)) {
779 DVLOG(1) << "failed to set security level " << security_level;
783 drm_bridges_.push_back(drm_bridge.release());
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);
796 void BrowserMediaPlayerManager::OnSetMediaKeys(int player_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.";
804 // TODO(qinmin): add the logic to decide whether we should create the
805 // fullscreen surface for EME lv1.
806 player->SetDrmBridge(drm_bridge);
809 void BrowserMediaPlayerManager::CreateSessionIfPermitted(
812 const std::string& type,
813 const std::vector<uint8>& init_data,
817 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
821 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
823 DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
825 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
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());
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)
837 pending_fullscreen_player_id_ = -1;
838 MediaPlayerAndroid* player = GetPlayer(media_keys_id);
839 if (player->IsPlaying())
840 OnProtectedSurfaceRequested(media_keys_id);
843 } // namespace content