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