Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/media/android/browser_media_player_manager.h" | 5 #include "content/browser/media/android/browser_media_player_manager.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "content/browser/android/content_view_core_impl.h" | 8 #include "content/browser/android/content_view_core_impl.h" |
| 9 #include "content/browser/media/android/browser_demuxer_android.h" | 9 #include "content/browser/media/android/browser_demuxer_android.h" |
| 10 #include "content/browser/media/android/media_resource_getter_impl.h" | 10 #include "content/browser/media/android/media_resource_getter_impl.h" |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Start, OnStart) | 116 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Start, OnStart) |
| 117 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Seek, OnSeek) | 117 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Seek, OnSeek) |
| 118 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Pause, OnPause) | 118 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Pause, OnPause) |
| 119 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetVolume, OnSetVolume) | 119 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetVolume, OnSetVolume) |
| 120 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Release, OnReleaseResources) | 120 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Release, OnReleaseResources) |
| 121 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyMediaPlayer, OnDestroyPlayer) | 121 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyMediaPlayer, OnDestroyPlayer) |
| 122 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers, | 122 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers, |
| 123 DestroyAllMediaPlayers) | 123 DestroyAllMediaPlayers) |
| 124 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_InitializeCDM, | 124 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_InitializeCDM, |
| 125 OnInitializeCDM) | 125 OnInitializeCDM) |
| 126 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_GenerateKeyRequest, | 126 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_CreateSession, OnCreateSession) |
| 127 OnGenerateKeyRequest) | 127 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_UpdateSession, OnUpdateSession) |
| 128 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_AddKey, OnAddKey) | 128 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_ReleaseSession, OnReleaseSession) |
| 129 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_CancelKeyRequest, | |
| 130 OnCancelKeyRequest) | |
| 131 #if defined(GOOGLE_TV) | 129 #if defined(GOOGLE_TV) |
| 132 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyExternalSurface, | 130 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyExternalSurface, |
| 133 OnNotifyExternalSurface) | 131 OnNotifyExternalSurface) |
| 134 #endif | 132 #endif |
| 135 IPC_MESSAGE_UNHANDLED(handled = false) | 133 IPC_MESSAGE_UNHANDLED(handled = false) |
| 136 IPC_END_MESSAGE_MAP() | 134 IPC_END_MESSAGE_MAP() |
| 137 return handled; | 135 return handled; |
| 138 } | 136 } |
| 139 | 137 |
| 140 void BrowserMediaPlayerManager::FullscreenPlayerPlay() { | 138 void BrowserMediaPlayerManager::FullscreenPlayerPlay() { |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 pending_fullscreen_player_id_ = player_id; | 346 pending_fullscreen_player_id_ = player_id; |
| 349 return; | 347 return; |
| 350 } | 348 } |
| 351 | 349 |
| 352 // Send an IPC to the render process to request the video element to enter | 350 // Send an IPC to the render process to request the video element to enter |
| 353 // fullscreen. OnEnterFullscreen() will be called later on success. | 351 // fullscreen. OnEnterFullscreen() will be called later on success. |
| 354 // This guarantees the fullscreen video will be rendered correctly. | 352 // This guarantees the fullscreen video will be rendered correctly. |
| 355 // During the process, DisableFullscreenEncryptedMediaPlayback() may get | 353 // During the process, DisableFullscreenEncryptedMediaPlayback() may get |
| 356 // called before or after OnEnterFullscreen(). If it is called before | 354 // called before or after OnEnterFullscreen(). If it is called before |
| 357 // OnEnterFullscreen(), the player will not enter fullscreen. And it will | 355 // OnEnterFullscreen(), the player will not enter fullscreen. And it will |
| 358 // retry the process once the GenerateKeyRequest is allowed to proceed | 356 // retry the process once CreateSession() is allowed to proceed. |
| 359 // TODO(qinmin): make this flag default on android. | 357 // TODO(qinmin): make this flag default on android. |
| 360 if (CommandLine::ForCurrentProcess()->HasSwitch( | 358 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 361 switches::kDisableGestureRequirementForMediaFullscreen)) { | 359 switches::kDisableGestureRequirementForMediaFullscreen)) { |
| 362 Send(new MediaPlayerMsg_RequestFullscreen(routing_id(), player_id)); | 360 Send(new MediaPlayerMsg_RequestFullscreen(routing_id(), player_id)); |
| 363 } | 361 } |
| 364 } | 362 } |
| 365 | 363 |
| 366 // The following 5 functions are EME MediaKeySession events. | 364 // The following 5 functions are EME MediaKeySession events. |
| 367 | 365 |
| 368 void BrowserMediaPlayerManager::OnSessionCreated( | 366 void BrowserMediaPlayerManager::OnSessionCreated( |
| 369 int media_keys_id, | 367 int media_keys_id, |
| 370 uint32 session_id, | 368 uint32 session_id, |
| 371 const std::string& web_session_id) { | 369 const std::string& web_session_id) { |
| 372 Send(new MediaKeysMsg_SetSessionId( | 370 Send(new MediaKeysMsg_SessionCreated( |
| 373 routing_id(), media_keys_id, session_id, web_session_id)); | 371 routing_id(), media_keys_id, session_id, web_session_id)); |
| 374 } | 372 } |
| 375 | 373 |
| 376 void BrowserMediaPlayerManager::OnSessionMessage( | 374 void BrowserMediaPlayerManager::OnSessionMessage( |
| 377 int media_keys_id, | 375 int media_keys_id, |
| 378 uint32 session_id, | 376 uint32 session_id, |
| 379 const std::vector<uint8>& message, | 377 const std::vector<uint8>& message, |
| 380 const std::string& destination_url) { | 378 const std::string& destination_url) { |
| 381 Send(new MediaKeysMsg_KeyMessage( | 379 Send(new MediaKeysMsg_SessionMessage( |
| 382 routing_id(), media_keys_id, session_id, message, destination_url)); | 380 routing_id(), media_keys_id, session_id, message, destination_url)); |
| 383 } | 381 } |
| 384 | 382 |
| 385 void BrowserMediaPlayerManager::OnSessionReady(int media_keys_id, | 383 void BrowserMediaPlayerManager::OnSessionReady(int media_keys_id, |
| 386 uint32 session_id) { | 384 uint32 session_id) { |
| 387 Send(new MediaKeysMsg_KeyAdded(routing_id(), media_keys_id, session_id)); | 385 Send(new MediaKeysMsg_SessionReady(routing_id(), media_keys_id, session_id)); |
| 388 } | 386 } |
| 389 | 387 |
| 390 void BrowserMediaPlayerManager::OnSessionClosed(int media_keys_id, | 388 void BrowserMediaPlayerManager::OnSessionClosed(int media_keys_id, |
| 391 uint32 session_id) { | 389 uint32 session_id) { |
| 392 // TODO(jrummell): Update Android calls and IPC names. | 390 Send(new MediaKeysMsg_SessionClosed(routing_id(), media_keys_id, session_id)); |
| 393 } | 391 } |
| 394 | 392 |
| 395 void BrowserMediaPlayerManager::OnSessionError( | 393 void BrowserMediaPlayerManager::OnSessionError( |
| 396 int media_keys_id, | 394 int media_keys_id, |
| 397 uint32 session_id, | 395 uint32 session_id, |
| 398 media::MediaKeys::KeyError error_code, | 396 media::MediaKeys::KeyError error_code, |
| 399 int system_code) { | 397 int system_code) { |
| 400 Send(new MediaKeysMsg_KeyError( | 398 Send(new MediaKeysMsg_SessionError( |
| 401 routing_id(), media_keys_id, session_id, error_code, system_code)); | 399 routing_id(), media_keys_id, session_id, error_code, system_code)); |
| 402 } | 400 } |
| 403 | 401 |
| 404 #if defined(GOOGLE_TV) | 402 #if defined(GOOGLE_TV) |
| 405 void BrowserMediaPlayerManager::AttachExternalVideoSurface(int player_id, | 403 void BrowserMediaPlayerManager::AttachExternalVideoSurface(int player_id, |
| 406 jobject surface) { | 404 jobject surface) { |
| 407 MediaPlayerAndroid* player = GetPlayer(player_id); | 405 MediaPlayerAndroid* player = GetPlayer(player_id); |
| 408 if (player) { | 406 if (player) { |
| 409 player->SetVideoSurface( | 407 player->SetVideoSurface( |
| 410 gfx::ScopedJavaSurface::AcquireExternalSurface(surface)); | 408 gfx::ScopedJavaSurface::AcquireExternalSurface(surface)); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 539 void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) { | 537 void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) { |
| 540 RemovePlayer(player_id); | 538 RemovePlayer(player_id); |
| 541 if (fullscreen_player_id_ == player_id) | 539 if (fullscreen_player_id_ == player_id) |
| 542 fullscreen_player_id_ = -1; | 540 fullscreen_player_id_ = -1; |
| 543 } | 541 } |
| 544 | 542 |
| 545 void BrowserMediaPlayerManager::OnInitializeCDM( | 543 void BrowserMediaPlayerManager::OnInitializeCDM( |
| 546 int media_keys_id, | 544 int media_keys_id, |
| 547 const std::vector<uint8>& uuid, | 545 const std::vector<uint8>& uuid, |
| 548 const GURL& frame_url) { | 546 const GURL& frame_url) { |
| 547 if (uuid.size() != 16) { | |
| 548 // This failure will be discovered and reported by OnCreateSession() | |
|
palmer
2013/12/11 00:18:18
That's not immediately obvious to me. I think it i
jrummell
2013/12/11 02:21:52
Errors can only be thrown at sessions, so this ini
| |
| 549 // as GetDrmBridge() will return null. | |
| 550 DLOG(WARNING) << "Invalid UUID for ID: " << media_keys_id; | |
|
ddorwin
2013/12/10 23:48:08
NOTREACHED()?
This is a programming bug, so I thin
palmer
2013/12/11 00:18:18
No, because you never know what kind of weirdness
ddorwin
2013/12/11 00:30:04
Right, keep the runtime check at 547, but NOTREACH
jrummell
2013/12/11 02:21:52
Done.
| |
| 551 return; | |
| 552 } | |
| 553 | |
| 549 AddDrmBridge(media_keys_id, uuid, frame_url); | 554 AddDrmBridge(media_keys_id, uuid, frame_url); |
| 550 // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id| | 555 // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id| |
| 551 // is the same as the |player_id|. | 556 // is the same as the |player_id|. |
| 552 OnSetMediaKeys(media_keys_id, media_keys_id); | 557 OnSetMediaKeys(media_keys_id, media_keys_id); |
| 553 } | 558 } |
| 554 | 559 |
| 555 void BrowserMediaPlayerManager::OnGenerateKeyRequest( | 560 void BrowserMediaPlayerManager::OnCreateSession( |
| 556 int media_keys_id, | 561 int media_keys_id, |
| 557 uint32 session_id, | 562 uint32 session_id, |
| 558 const std::string& type, | 563 const std::string& type, |
| 559 const std::vector<uint8>& init_data) { | 564 const std::vector<uint8>& init_data) { |
| 565 if (type.length() > 512) { | |
|
ddorwin
2013/12/10 23:48:08
50 is more than enough for type.
jrummell
2013/12/11 02:21:52
Done.
| |
| 566 DLOG(WARNING) << "'type' for ID: " << media_keys_id | |
|
ddorwin
2013/12/10 23:48:08
We probably don't need to log since this should ne
jrummell
2013/12/11 02:21:52
Done.
| |
| 567 << " too long: " << type.length(); | |
| 568 OnSessionError( | |
| 569 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); | |
| 570 return; | |
| 571 } | |
| 572 if (init_data.size() > 10240) { | |
|
ddorwin
2013/12/10 23:48:08
Should we note that these are checks for security
palmer
2013/12/11 00:18:18
Yes to both. I'd use some kind of named constant i
ddorwin
2013/12/11 00:30:04
initData is container-specific and the messages an
jrummell
2013/12/11 02:21:52
Done.
| |
| 573 DLOG(WARNING) << "'init_data' for ID: " << media_keys_id | |
| 574 << " too long:" << init_data.size(); | |
| 575 OnSessionError( | |
| 576 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); | |
| 577 return; | |
| 578 } | |
| 579 | |
| 560 if (CommandLine::ForCurrentProcess() | 580 if (CommandLine::ForCurrentProcess() |
| 561 ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) { | 581 ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) { |
| 562 GenerateKeyIfAllowed(media_keys_id, session_id, type, init_data, true); | 582 GenerateKeyIfAllowed(media_keys_id, session_id, type, init_data, true); |
| 563 return; | 583 return; |
| 564 } | 584 } |
| 565 | 585 |
| 566 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); | 586 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); |
| 567 if (!drm_bridge) { | 587 if (!drm_bridge) { |
| 568 DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; | 588 DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; |
| 569 OnSessionError( | 589 OnSessionError( |
| 570 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); | 590 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 571 return; | 591 return; |
| 572 } | 592 } |
| 573 | 593 |
| 574 if (media_keys_ids_approved_.find(media_keys_id) == | 594 if (media_keys_ids_approved_.find(media_keys_id) == |
| 575 media_keys_ids_approved_.end()) { | 595 media_keys_ids_approved_.end()) { |
| 576 media_keys_ids_pending_approval_.insert(media_keys_id); | 596 media_keys_ids_pending_approval_.insert(media_keys_id); |
| 577 } | 597 } |
| 578 web_contents()->GetDelegate()->RequestProtectedMediaIdentifierPermission( | 598 web_contents()->GetDelegate()->RequestProtectedMediaIdentifierPermission( |
| 579 web_contents(), | 599 web_contents(), |
| 580 drm_bridge->frame_url(), | 600 drm_bridge->frame_url(), |
| 581 base::Bind(&BrowserMediaPlayerManager::GenerateKeyIfAllowed, | 601 base::Bind(&BrowserMediaPlayerManager::GenerateKeyIfAllowed, |
| 582 weak_ptr_factory_.GetWeakPtr(), | 602 weak_ptr_factory_.GetWeakPtr(), |
| 583 media_keys_id, | 603 media_keys_id, |
| 584 session_id, | 604 session_id, |
| 585 type, | 605 type, |
| 586 init_data)); | 606 init_data)); |
| 587 } | 607 } |
| 588 | 608 |
| 589 void BrowserMediaPlayerManager::OnAddKey(int media_keys_id, | 609 void BrowserMediaPlayerManager::OnUpdateSession( |
| 590 uint32 session_id, | 610 int media_keys_id, |
| 591 const std::vector<uint8>& key, | 611 uint32 session_id, |
| 592 const std::vector<uint8>& init_data) { | 612 const std::vector<uint8>& response) { |
| 593 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); | 613 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); |
| 594 if (!drm_bridge) { | 614 if (!drm_bridge) { |
| 595 DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; | 615 DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; |
| 596 OnSessionError( | 616 OnSessionError( |
| 597 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); | 617 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 598 return; | 618 return; |
| 599 } | 619 } |
| 600 | 620 |
| 601 DCHECK(init_data.empty()); | 621 if (response.size() > 10240) { |
|
palmer
2013/12/11 00:18:18
Same thing here, and it's another argument in favo
jrummell
2013/12/11 02:21:52
Done.
| |
| 602 drm_bridge->UpdateSession(session_id, &key[0], key.size()); | 622 DLOG(WARNING) << "Response for ID: " << media_keys_id |
| 623 << " too long: " << response.size(); | |
| 624 OnSessionError( | |
| 625 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); | |
| 626 return; | |
| 627 } | |
| 628 | |
| 629 drm_bridge->UpdateSession(session_id, &response[0], response.size()); | |
| 603 // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id| | 630 // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id| |
| 604 // is the same as the |player_id|. | 631 // is the same as the |player_id|. |
| 605 // TODO(xhwang): Separate |media_keys_id| and |player_id|. | 632 // TODO(xhwang): Separate |media_keys_id| and |player_id|. |
| 606 MediaPlayerAndroid* player = GetPlayer(media_keys_id); | 633 MediaPlayerAndroid* player = GetPlayer(media_keys_id); |
| 607 if (player) | 634 if (player) |
| 608 player->OnKeyAdded(); | 635 player->OnKeyAdded(); |
| 609 } | 636 } |
| 610 | 637 |
| 611 void BrowserMediaPlayerManager::OnCancelKeyRequest(int media_keys_id, | 638 void BrowserMediaPlayerManager::OnReleaseSession(int media_keys_id, |
| 612 uint32 session_id) { | 639 uint32 session_id) { |
| 613 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); | 640 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); |
| 614 if (!drm_bridge) { | 641 if (!drm_bridge) { |
| 615 DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; | 642 DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; |
| 616 OnSessionError( | 643 OnSessionError( |
| 617 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); | 644 media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 618 return; | 645 return; |
| 619 } | 646 } |
| 620 | 647 |
| 621 drm_bridge->ReleaseSession(session_id); | 648 drm_bridge->ReleaseSession(session_id); |
| 622 } | 649 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 674 // TODO(xhwang/ddorwin): Pass the security level from key system. | 701 // TODO(xhwang/ddorwin): Pass the security level from key system. |
| 675 std::string security_level = "L3"; | 702 std::string security_level = "L3"; |
| 676 if (CommandLine::ForCurrentProcess() | 703 if (CommandLine::ForCurrentProcess() |
| 677 ->HasSwitch(switches::kMediaDrmEnableNonCompositing)) { | 704 ->HasSwitch(switches::kMediaDrmEnableNonCompositing)) { |
| 678 security_level = "L1"; | 705 security_level = "L1"; |
| 679 } | 706 } |
| 680 | 707 |
| 681 scoped_ptr<MediaDrmBridge> drm_bridge(MediaDrmBridge::Create( | 708 scoped_ptr<MediaDrmBridge> drm_bridge(MediaDrmBridge::Create( |
| 682 media_keys_id, uuid, frame_url, security_level, this)); | 709 media_keys_id, uuid, frame_url, security_level, this)); |
| 683 if (!drm_bridge) { | 710 if (!drm_bridge) { |
| 684 // This failure will be discovered and reported by OnGenerateKeyRequest() | 711 // This failure will be discovered and reported by OnCreateSession() |
| 685 // as GetDrmBridge() will return null. | 712 // as GetDrmBridge() will return null. |
| 686 DVLOG(1) << "failed to create drm bridge."; | 713 DVLOG(1) << "failed to create drm bridge."; |
| 687 return; | 714 return; |
| 688 } | 715 } |
| 689 | 716 |
| 690 drm_bridges_.push_back(drm_bridge.release()); | 717 drm_bridges_.push_back(drm_bridge.release()); |
| 691 } | 718 } |
| 692 | 719 |
| 693 void BrowserMediaPlayerManager::RemoveDrmBridge(int media_keys_id) { | 720 void BrowserMediaPlayerManager::RemoveDrmBridge(int media_keys_id) { |
| 694 for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin(); | 721 for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 738 if (pending_fullscreen_player_id_ != media_keys_id) | 765 if (pending_fullscreen_player_id_ != media_keys_id) |
| 739 return; | 766 return; |
| 740 | 767 |
| 741 pending_fullscreen_player_id_ = -1; | 768 pending_fullscreen_player_id_ = -1; |
| 742 MediaPlayerAndroid* player = GetPlayer(media_keys_id); | 769 MediaPlayerAndroid* player = GetPlayer(media_keys_id); |
| 743 if (player->IsPlaying()) | 770 if (player->IsPlaying()) |
| 744 OnProtectedSurfaceRequested(media_keys_id); | 771 OnProtectedSurfaceRequested(media_keys_id); |
| 745 } | 772 } |
| 746 | 773 |
| 747 } // namespace content | 774 } // namespace content |
| OLD | NEW |