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/android/scoped_java_ref.h" | 7 #include "base/android/scoped_java_ref.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/stl_util.h" | |
| 9 #include "content/browser/android/content_view_core_impl.h" | 10 #include "content/browser/android/content_view_core_impl.h" |
| 10 #include "content/browser/media/android/browser_demuxer_android.h" | 11 #include "content/browser/media/android/browser_demuxer_android.h" |
| 11 #include "content/browser/media/android/media_resource_getter_impl.h" | 12 #include "content/browser/media/android/media_resource_getter_impl.h" |
| 12 #include "content/browser/renderer_host/render_view_host_impl.h" | 13 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 13 #include "content/browser/web_contents/web_contents_view_android.h" | 14 #include "content/browser/web_contents/web_contents_view_android.h" |
| 14 #include "content/common/media/cdm_messages.h" | 15 #include "content/common/media/cdm_messages.h" |
| 15 #include "content/common/media/media_player_messages_android.h" | 16 #include "content/common/media/media_player_messages_android.h" |
| 16 #include "content/public/browser/android/content_view_core.h" | 17 #include "content/public/browser/android/content_view_core.h" |
| 17 #include "content/public/browser/android/external_video_surface_container.h" | 18 #include "content/public/browser/android/external_video_surface_container.h" |
| 18 #include "content/public/browser/browser_context.h" | 19 #include "content/public/browser/browser_context.h" |
| 19 #include "content/public/browser/content_browser_client.h" | 20 #include "content/public/browser/content_browser_client.h" |
| 20 #include "content/public/browser/render_process_host.h" | 21 #include "content/public/browser/render_process_host.h" |
| 21 #include "content/public/browser/render_view_host.h" | 22 #include "content/public/browser/render_view_host.h" |
| 22 #include "content/public/browser/storage_partition.h" | 23 #include "content/public/browser/storage_partition.h" |
| 23 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
| 24 #include "content/public/browser/web_contents_delegate.h" | 25 #include "content/public/browser/web_contents_delegate.h" |
| 25 #include "content/public/common/content_client.h" | 26 #include "content/public/common/content_client.h" |
| 26 #include "content/public/common/content_switches.h" | 27 #include "content/public/common/content_switches.h" |
| 27 #include "media/base/android/media_drm_bridge.h" | |
| 28 #include "media/base/android/media_player_bridge.h" | 28 #include "media/base/android/media_player_bridge.h" |
| 29 #include "media/base/android/media_source_player.h" | 29 #include "media/base/android/media_source_player.h" |
| 30 #include "media/base/cdm_factory.h" | |
| 30 #include "media/base/media_switches.h" | 31 #include "media/base/media_switches.h" |
| 31 | 32 |
| 32 using media::MediaDrmBridge; | 33 using media::MediaKeys; |
| 33 using media::MediaPlayerAndroid; | 34 using media::MediaPlayerAndroid; |
| 34 using media::MediaPlayerBridge; | 35 using media::MediaPlayerBridge; |
| 35 using media::MediaPlayerManager; | 36 using media::MediaPlayerManager; |
| 36 using media::MediaSourcePlayer; | 37 using media::MediaSourcePlayer; |
| 37 | 38 |
| 38 namespace content { | 39 namespace content { |
| 39 | 40 |
| 40 // Threshold on the number of media players per renderer before we start | 41 // Threshold on the number of media players per renderer before we start |
| 41 // attempting to release inactive media players. | 42 // attempting to release inactive media players. |
| 42 const int kMediaPlayerThreshold = 1; | 43 const int kMediaPlayerThreshold = 1; |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 | 336 |
| 336 MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) { | 337 MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) { |
| 337 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); | 338 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); |
| 338 it != players_.end(); ++it) { | 339 it != players_.end(); ++it) { |
| 339 if ((*it)->player_id() == player_id) | 340 if ((*it)->player_id() == player_id) |
| 340 return *it; | 341 return *it; |
| 341 } | 342 } |
| 342 return NULL; | 343 return NULL; |
| 343 } | 344 } |
| 344 | 345 |
| 345 MediaDrmBridge* BrowserMediaPlayerManager::GetDrmBridge(int cdm_id) { | 346 MediaKeys* BrowserMediaPlayerManager::GetCdm(int cdm_id) { |
| 346 for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin(); | 347 CdmMap::const_iterator iter = cdm_map_.find(cdm_id); |
| 347 it != drm_bridges_.end(); ++it) { | 348 return (iter == cdm_map_.end()) ? NULL : iter->second; |
| 348 if ((*it)->cdm_id() == cdm_id) | |
| 349 return *it; | |
| 350 } | |
| 351 return NULL; | |
| 352 } | 349 } |
| 353 | 350 |
| 354 void BrowserMediaPlayerManager::DestroyAllMediaPlayers() { | 351 void BrowserMediaPlayerManager::DestroyAllMediaPlayers() { |
| 355 players_.clear(); | 352 players_.clear(); |
| 356 drm_bridges_.clear(); | 353 STLDeleteValues(&cdm_map_); |
| 357 if (fullscreen_player_id_ != -1) { | 354 if (fullscreen_player_id_ != -1) { |
| 358 video_view_.reset(); | 355 video_view_.reset(); |
| 359 fullscreen_player_id_ = -1; | 356 fullscreen_player_id_ = -1; |
| 360 } | 357 } |
| 361 } | 358 } |
| 362 | 359 |
| 363 void BrowserMediaPlayerManager::RequestFullScreen(int player_id) { | 360 void BrowserMediaPlayerManager::RequestFullScreen(int player_id) { |
| 364 if (fullscreen_player_id_ == player_id) | 361 if (fullscreen_player_id_ == player_id) |
| 365 return; | 362 return; |
| 366 | 363 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 387 uint32 session_id, | 384 uint32 session_id, |
| 388 const std::string& web_session_id) { | 385 const std::string& web_session_id) { |
| 389 Send(new CdmMsg_SessionCreated( | 386 Send(new CdmMsg_SessionCreated( |
| 390 routing_id(), cdm_id, session_id, web_session_id)); | 387 routing_id(), cdm_id, session_id, web_session_id)); |
| 391 } | 388 } |
| 392 | 389 |
| 393 void BrowserMediaPlayerManager::OnSessionMessage( | 390 void BrowserMediaPlayerManager::OnSessionMessage( |
| 394 int cdm_id, | 391 int cdm_id, |
| 395 uint32 session_id, | 392 uint32 session_id, |
| 396 const std::vector<uint8>& message, | 393 const std::vector<uint8>& message, |
| 397 const GURL& destination_url) { | 394 const std::string& destination_url) { |
| 395 GURL destination_gurl(destination_url); | |
| 396 if (!destination_gurl.is_valid() && !destination_gurl.is_empty()) { | |
| 397 DLOG(WARNING) << "SessionMessage destination_url is invalid : " | |
| 398 << destination_gurl.possibly_invalid_spec(); | |
| 399 destination_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. | |
| 400 } | |
| 401 | |
| 398 Send(new CdmMsg_SessionMessage( | 402 Send(new CdmMsg_SessionMessage( |
| 399 routing_id(), cdm_id, session_id, message, destination_url)); | 403 routing_id(), cdm_id, session_id, message, destination_gurl)); |
| 400 } | 404 } |
| 401 | 405 |
| 402 void BrowserMediaPlayerManager::OnSessionReady(int cdm_id, uint32 session_id) { | 406 void BrowserMediaPlayerManager::OnSessionReady(int cdm_id, uint32 session_id) { |
| 403 Send(new CdmMsg_SessionReady(routing_id(), cdm_id, session_id)); | 407 Send(new CdmMsg_SessionReady(routing_id(), cdm_id, session_id)); |
| 404 } | 408 } |
| 405 | 409 |
| 406 void BrowserMediaPlayerManager::OnSessionClosed(int cdm_id, uint32 session_id) { | 410 void BrowserMediaPlayerManager::OnSessionClosed(int cdm_id, uint32 session_id) { |
| 407 Send(new CdmMsg_SessionClosed(routing_id(), cdm_id, session_id)); | 411 Send(new CdmMsg_SessionClosed(routing_id(), cdm_id, session_id)); |
| 408 } | 412 } |
| 409 | 413 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 584 RemovePlayer(player_id); | 588 RemovePlayer(player_id); |
| 585 if (fullscreen_player_id_ == player_id) | 589 if (fullscreen_player_id_ == player_id) |
| 586 fullscreen_player_id_ = -1; | 590 fullscreen_player_id_ = -1; |
| 587 } | 591 } |
| 588 | 592 |
| 589 void BrowserMediaPlayerManager::OnInitializeCdm(int cdm_id, | 593 void BrowserMediaPlayerManager::OnInitializeCdm(int cdm_id, |
| 590 const std::string& key_system, | 594 const std::string& key_system, |
| 591 const GURL& security_origin) { | 595 const GURL& security_origin) { |
| 592 if (key_system.size() > kMaxKeySystemLength) { | 596 if (key_system.size() > kMaxKeySystemLength) { |
| 593 // This failure will be discovered and reported by OnCreateSession() | 597 // This failure will be discovered and reported by OnCreateSession() |
| 594 // as GetDrmBridge() will return null. | 598 // as GetCdm() will return null. |
| 595 NOTREACHED() << "Invalid key system: " << key_system; | 599 NOTREACHED() << "Invalid key system: " << key_system; |
| 596 return; | 600 return; |
| 597 } | 601 } |
| 598 | 602 |
| 599 if (!MediaDrmBridge::IsKeySystemSupported(key_system)) { | 603 AddCdm(cdm_id, key_system, security_origin); |
| 600 NOTREACHED() << "Unsupported key system: " << key_system; | |
| 601 return; | |
| 602 } | |
| 603 | |
| 604 AddDrmBridge(cdm_id, key_system, security_origin); | |
| 605 } | 604 } |
| 606 | 605 |
| 607 void BrowserMediaPlayerManager::OnCreateSession( | 606 void BrowserMediaPlayerManager::OnCreateSession( |
| 608 int cdm_id, | 607 int cdm_id, |
| 609 uint32 session_id, | 608 uint32 session_id, |
| 610 CdmHostMsg_CreateSession_ContentType content_type, | 609 CdmHostMsg_CreateSession_ContentType content_type, |
| 611 const std::vector<uint8>& init_data) { | 610 const std::vector<uint8>& init_data) { |
| 612 if (init_data.size() > kMaxInitDataLength) { | 611 if (init_data.size() > kMaxInitDataLength) { |
| 613 LOG(WARNING) << "InitData for ID: " << cdm_id | 612 LOG(WARNING) << "InitData for ID: " << cdm_id |
| 614 << " too long: " << init_data.size(); | 613 << " too long: " << init_data.size(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 632 NOTREACHED(); | 631 NOTREACHED(); |
| 633 return; | 632 return; |
| 634 } | 633 } |
| 635 | 634 |
| 636 if (CommandLine::ForCurrentProcess() | 635 if (CommandLine::ForCurrentProcess() |
| 637 ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) { | 636 ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) { |
| 638 CreateSessionIfPermitted(cdm_id, session_id, mime_type, init_data, true); | 637 CreateSessionIfPermitted(cdm_id, session_id, mime_type, init_data, true); |
| 639 return; | 638 return; |
| 640 } | 639 } |
| 641 | 640 |
| 642 MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id); | 641 MediaKeys* cdm = GetCdm(cdm_id); |
| 643 if (!drm_bridge) { | 642 if (!cdm) { |
| 644 DLOG(WARNING) << "No MediaDrmBridge for ID: " << cdm_id << " found"; | 643 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found"; |
| 645 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 644 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 646 return; | 645 return; |
| 647 } | 646 } |
| 648 | 647 |
| 649 BrowserContext* context = | 648 BrowserContext* context = |
| 650 web_contents()->GetRenderProcessHost()->GetBrowserContext(); | 649 web_contents()->GetRenderProcessHost()->GetBrowserContext(); |
| 651 | 650 |
| 651 if (!ContainsKey(cdm_security_origin_map_, cdm_id)) { | |
|
damienv1
2014/05/15 16:43:57
Not a big performance degradation but the map quer
xhwang
2014/05/15 20:59:29
Done.
| |
| 652 NOTREACHED(); | |
| 653 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | |
| 654 return; | |
| 655 } | |
| 656 | |
| 652 context->RequestProtectedMediaIdentifierPermission( | 657 context->RequestProtectedMediaIdentifierPermission( |
| 653 web_contents()->GetRenderProcessHost()->GetID(), | 658 web_contents()->GetRenderProcessHost()->GetID(), |
| 654 web_contents()->GetRenderViewHost()->GetRoutingID(), | 659 web_contents()->GetRenderViewHost()->GetRoutingID(), |
| 655 static_cast<int>(session_id), | 660 static_cast<int>(session_id), |
| 656 cdm_id, | 661 cdm_id, |
| 657 drm_bridge->security_origin(), | 662 cdm_security_origin_map_[cdm_id], |
| 658 base::Bind(&BrowserMediaPlayerManager::CreateSessionIfPermitted, | 663 base::Bind(&BrowserMediaPlayerManager::CreateSessionIfPermitted, |
| 659 weak_ptr_factory_.GetWeakPtr(), | 664 weak_ptr_factory_.GetWeakPtr(), |
| 660 cdm_id, | 665 cdm_id, |
| 661 session_id, | 666 session_id, |
| 662 mime_type, | 667 mime_type, |
| 663 init_data)); | 668 init_data)); |
| 664 } | 669 } |
| 665 | 670 |
| 666 void BrowserMediaPlayerManager::OnUpdateSession( | 671 void BrowserMediaPlayerManager::OnUpdateSession( |
| 667 int cdm_id, | 672 int cdm_id, |
| 668 uint32 session_id, | 673 uint32 session_id, |
| 669 const std::vector<uint8>& response) { | 674 const std::vector<uint8>& response) { |
| 670 MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id); | 675 MediaKeys* cdm = GetCdm(cdm_id); |
| 671 if (!drm_bridge) { | 676 if (!cdm) { |
| 672 DLOG(WARNING) << "No MediaDrmBridge for ID: " << cdm_id << " found"; | 677 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found"; |
| 673 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 678 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 674 return; | 679 return; |
| 675 } | 680 } |
| 676 | 681 |
| 677 if (response.size() > kMaxSessionResponseLength) { | 682 if (response.size() > kMaxSessionResponseLength) { |
| 678 LOG(WARNING) << "Response for ID: " << cdm_id | 683 LOG(WARNING) << "Response for ID " << cdm_id |
| 679 << " too long: " << response.size(); | 684 << " is too long: " << response.size(); |
| 680 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 685 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 681 return; | 686 return; |
| 682 } | 687 } |
| 683 | 688 |
| 684 drm_bridge->UpdateSession(session_id, &response[0], response.size()); | 689 cdm->UpdateSession(session_id, &response[0], response.size()); |
| 685 | 690 |
| 686 DrmBridgePlayerMap::const_iterator iter = drm_bridge_player_map_.find(cdm_id); | 691 CdmToPlayerMap::const_iterator iter = cdm_to_player_map_.find(cdm_id); |
| 687 if (iter == drm_bridge_player_map_.end()) | 692 if (iter == cdm_to_player_map_.end()) |
| 688 return; | 693 return; |
| 689 | 694 |
| 690 int player_id = iter->second; | 695 int player_id = iter->second; |
| 691 MediaPlayerAndroid* player = GetPlayer(player_id); | 696 MediaPlayerAndroid* player = GetPlayer(player_id); |
| 692 if (player) | 697 if (player) |
| 693 player->OnKeyAdded(); | 698 player->OnKeyAdded(); |
| 694 } | 699 } |
| 695 | 700 |
| 696 void BrowserMediaPlayerManager::OnReleaseSession(int cdm_id, | 701 void BrowserMediaPlayerManager::OnReleaseSession(int cdm_id, |
| 697 uint32 session_id) { | 702 uint32 session_id) { |
| 698 MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id); | 703 MediaKeys* cdm = GetCdm(cdm_id); |
| 699 if (!drm_bridge) { | 704 if (!cdm) { |
| 700 DLOG(WARNING) << "No MediaDrmBridge for ID: " << cdm_id << " found"; | 705 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found"; |
| 701 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 706 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 702 return; | 707 return; |
| 703 } | 708 } |
| 704 | 709 |
| 705 drm_bridge->ReleaseSession(session_id); | 710 cdm->ReleaseSession(session_id); |
| 706 } | 711 } |
| 707 | 712 |
| 708 void BrowserMediaPlayerManager::OnDestroyCdm(int cdm_id) { | 713 void BrowserMediaPlayerManager::OnDestroyCdm(int cdm_id) { |
| 709 MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id); | 714 MediaKeys* cdm = GetCdm(cdm_id); |
| 710 if (!drm_bridge) return; | 715 if (!cdm) |
| 716 return; | |
| 711 | 717 |
| 712 CancelAllPendingSessionCreations(cdm_id); | 718 CancelAllPendingSessionCreations(cdm_id); |
| 713 RemoveDrmBridge(cdm_id); | 719 RemoveCdm(cdm_id); |
| 714 } | 720 } |
| 715 | 721 |
| 716 void BrowserMediaPlayerManager::CancelAllPendingSessionCreations(int cdm_id) { | 722 void BrowserMediaPlayerManager::CancelAllPendingSessionCreations(int cdm_id) { |
| 717 BrowserContext* context = | 723 BrowserContext* context = |
| 718 web_contents()->GetRenderProcessHost()->GetBrowserContext(); | 724 web_contents()->GetRenderProcessHost()->GetBrowserContext(); |
| 719 context->CancelProtectedMediaIdentifierPermissionRequests(cdm_id); | 725 context->CancelProtectedMediaIdentifierPermissionRequests(cdm_id); |
| 720 } | 726 } |
| 721 | 727 |
| 722 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { | 728 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { |
| 723 DCHECK(!GetPlayer(player->player_id())); | 729 DCHECK(!GetPlayer(player->player_id())); |
| 724 players_.push_back(player); | 730 players_.push_back(player); |
| 725 } | 731 } |
| 726 | 732 |
| 727 void BrowserMediaPlayerManager::RemovePlayer(int player_id) { | 733 void BrowserMediaPlayerManager::RemovePlayer(int player_id) { |
| 728 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); | 734 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); |
| 729 it != players_.end(); ++it) { | 735 it != players_.end(); ++it) { |
| 730 MediaPlayerAndroid* player = *it; | 736 MediaPlayerAndroid* player = *it; |
| 731 if (player->player_id() == player_id) { | 737 if (player->player_id() == player_id) { |
| 732 players_.erase(it); | 738 players_.erase(it); |
| 733 break; | 739 break; |
| 734 } | 740 } |
| 735 } | 741 } |
| 736 | 742 |
| 737 for (DrmBridgePlayerMap::iterator it = drm_bridge_player_map_.begin(); | 743 for (CdmToPlayerMap::iterator it = cdm_to_player_map_.begin(); |
| 738 it != drm_bridge_player_map_.end(); ++it) { | 744 it != cdm_to_player_map_.end(); |
| 745 ++it) { | |
| 739 if (it->second == player_id) { | 746 if (it->second == player_id) { |
| 740 drm_bridge_player_map_.erase(it); | 747 cdm_to_player_map_.erase(it); |
| 741 break; | 748 break; |
| 742 } | 749 } |
| 743 } | 750 } |
| 744 } | 751 } |
| 745 | 752 |
| 746 scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer( | 753 scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer( |
| 747 int player_id, media::MediaPlayerAndroid* player) { | 754 int player_id, media::MediaPlayerAndroid* player) { |
| 748 media::MediaPlayerAndroid* previous_player = NULL; | 755 media::MediaPlayerAndroid* previous_player = NULL; |
| 749 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); | 756 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); |
| 750 it != players_.end(); ++it) { | 757 it != players_.end(); ++it) { |
| 751 if ((*it)->player_id() == player_id) { | 758 if ((*it)->player_id() == player_id) { |
| 752 previous_player = *it; | 759 previous_player = *it; |
| 753 players_.weak_erase(it); | 760 players_.weak_erase(it); |
| 754 players_.push_back(player); | 761 players_.push_back(player); |
| 755 break; | 762 break; |
| 756 } | 763 } |
| 757 } | 764 } |
| 758 return scoped_ptr<media::MediaPlayerAndroid>(previous_player); | 765 return scoped_ptr<media::MediaPlayerAndroid>(previous_player); |
| 759 } | 766 } |
| 760 | 767 |
| 761 void BrowserMediaPlayerManager::AddDrmBridge(int cdm_id, | 768 void BrowserMediaPlayerManager::AddCdm(int cdm_id, |
| 762 const std::string& key_system, | 769 const std::string& key_system, |
| 763 const GURL& security_origin) { | 770 const GURL& security_origin) { |
| 764 DCHECK(!GetDrmBridge(cdm_id)); | 771 DCHECK(!GetCdm(cdm_id)); |
| 772 base::WeakPtr<BrowserMediaPlayerManager> weak_this = | |
| 773 weak_ptr_factory_.GetWeakPtr(); | |
| 765 | 774 |
| 766 scoped_ptr<MediaDrmBridge> drm_bridge( | 775 scoped_ptr<MediaKeys> cdm(media::CreateBrowserCdm( |
| 767 MediaDrmBridge::Create(cdm_id, key_system, security_origin, this)); | 776 key_system, |
| 768 if (!drm_bridge) { | 777 base::Bind( |
| 778 &BrowserMediaPlayerManager::OnSessionCreated, weak_this, cdm_id), | |
|
damienv1
2014/05/15 16:43:57
Just want to confirm the threading model:
- Browse
xhwang
2014/05/15 20:59:29
All browser side stuff lives on the UI thread. Thi
| |
| 779 base::Bind( | |
| 780 &BrowserMediaPlayerManager::OnSessionMessage, weak_this, cdm_id), | |
| 781 base::Bind(&BrowserMediaPlayerManager::OnSessionReady, weak_this, cdm_id), | |
|
damienv1
2014/05/15 16:43:57
nit: just to make it look better, I would go to a
xhwang
2014/05/15 20:59:29
Done.
| |
| 782 base::Bind( | |
| 783 &BrowserMediaPlayerManager::OnSessionClosed, weak_this, cdm_id), | |
| 784 base::Bind( | |
| 785 &BrowserMediaPlayerManager::OnSessionError, weak_this, cdm_id))); | |
| 786 | |
| 787 if (!cdm) { | |
| 769 // This failure will be discovered and reported by OnCreateSession() | 788 // This failure will be discovered and reported by OnCreateSession() |
| 770 // as GetDrmBridge() will return null. | 789 // as GetCdm() will return null. |
| 771 DVLOG(1) << "failed to create drm bridge."; | 790 DVLOG(1) << "failed to create CDM."; |
| 772 return; | 791 return; |
| 773 } | 792 } |
| 774 | 793 |
| 775 // TODO(xhwang/ddorwin): Pass the security level from key system. | 794 cdm_map_[cdm_id] = cdm.release(); |
| 776 MediaDrmBridge::SecurityLevel security_level = | 795 cdm_security_origin_map_[cdm_id] = security_origin; |
| 777 MediaDrmBridge::SECURITY_LEVEL_3; | |
| 778 if (CommandLine::ForCurrentProcess() | |
| 779 ->HasSwitch(switches::kMediaDrmEnableNonCompositing)) { | |
| 780 security_level = MediaDrmBridge::SECURITY_LEVEL_1; | |
| 781 } | |
| 782 if (!drm_bridge->SetSecurityLevel(security_level)) { | |
| 783 DVLOG(1) << "failed to set security level " << security_level; | |
| 784 return; | |
| 785 } | |
| 786 | |
| 787 drm_bridges_.push_back(drm_bridge.release()); | |
| 788 } | 796 } |
| 789 | 797 |
| 790 void BrowserMediaPlayerManager::RemoveDrmBridge(int cdm_id) { | 798 void BrowserMediaPlayerManager::RemoveCdm(int cdm_id) { |
| 791 // TODO(xhwang): Detach DrmBridge from the player it's set to. In prefixed | 799 // TODO(xhwang): Detach CDM from the player it's set to. In prefixed |
| 792 // EME implementation the current code is fine because we always destroy the | 800 // EME implementation the current code is fine because we always destroy the |
| 793 // player before we destroy the DrmBridge. This will not always be the case | 801 // player before we destroy the DrmBridge. This will not always be the case |
| 794 // in unprefixed EME implementation. | 802 // in unprefixed EME implementation. |
| 795 for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin(); | 803 CdmMap::iterator iter = cdm_map_.find(cdm_id); |
| 796 it != drm_bridges_.end(); ++it) { | 804 if (iter != cdm_map_.end()) { |
| 797 if ((*it)->cdm_id() == cdm_id) { | 805 delete iter->second; |
| 798 drm_bridges_.erase(it); | 806 cdm_map_.erase(iter); |
| 799 drm_bridge_player_map_.erase(cdm_id); | |
| 800 break; | |
| 801 } | |
| 802 } | 807 } |
| 808 cdm_to_player_map_.erase(cdm_id); | |
| 809 cdm_security_origin_map_.erase(cdm_id); | |
| 803 } | 810 } |
| 804 | 811 |
| 805 void BrowserMediaPlayerManager::OnSetCdm(int player_id, int cdm_id) { | 812 void BrowserMediaPlayerManager::OnSetCdm(int player_id, int cdm_id) { |
| 806 MediaPlayerAndroid* player = GetPlayer(player_id); | 813 MediaPlayerAndroid* player = GetPlayer(player_id); |
| 807 MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id); | 814 MediaKeys* cdm = GetCdm(cdm_id); |
| 808 if (!drm_bridge || !player) { | 815 if (!cdm || !player) { |
| 809 DVLOG(1) << "Cannot set CDM on the specified player."; | 816 DVLOG(1) << "Cannot set CDM on the specified player."; |
| 810 return; | 817 return; |
| 811 } | 818 } |
| 812 | 819 |
| 813 // TODO(qinmin): add the logic to decide whether we should create the | 820 // TODO(qinmin): add the logic to decide whether we should create the |
| 814 // fullscreen surface for EME lv1. | 821 // fullscreen surface for EME lv1. |
| 815 player->SetDrmBridge(drm_bridge); | 822 player->SetCdm(cdm); |
| 816 // Do now support setting one CDM on multiple players. | 823 // Do now support setting one CDM on multiple players. |
| 817 DCHECK(drm_bridge_player_map_.find(cdm_id) == drm_bridge_player_map_.end()); | 824 DCHECK(!ContainsKey(cdm_to_player_map_, cdm_id)); |
|
damienv1
2014/05/15 16:43:57
Do we have possibly the same security issue here ?
ddorwin
2014/05/15 20:06:05
I originally thought not, but is it possible that
xhwang
2014/05/15 20:59:29
Done.
| |
| 818 drm_bridge_player_map_[cdm_id] = player_id; | 825 cdm_to_player_map_[cdm_id] = player_id; |
| 819 } | 826 } |
| 820 | 827 |
| 821 void BrowserMediaPlayerManager::CreateSessionIfPermitted( | 828 void BrowserMediaPlayerManager::CreateSessionIfPermitted( |
| 822 int cdm_id, | 829 int cdm_id, |
| 823 uint32 session_id, | 830 uint32 session_id, |
| 824 const std::string& content_type, | 831 const std::string& content_type, |
| 825 const std::vector<uint8>& init_data, | 832 const std::vector<uint8>& init_data, |
| 826 bool permitted) { | 833 bool permitted) { |
| 827 if (!permitted) { | 834 if (!permitted) { |
| 828 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 835 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 829 return; | 836 return; |
| 830 } | 837 } |
| 831 | 838 |
| 832 MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id); | 839 MediaKeys* cdm = GetCdm(cdm_id); |
| 833 if (!drm_bridge) { | 840 if (!cdm) { |
| 834 DLOG(WARNING) << "No MediaDrmBridge for ID: " << cdm_id << " found"; | 841 DLOG(WARNING) << "No CDM for ID: " << cdm_id << " found"; |
| 835 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 842 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); |
| 836 return; | 843 return; |
| 837 } | 844 } |
| 838 | 845 |
| 839 // This could fail, in which case a SessionError will be fired. | 846 // This could fail, in which case a SessionError will be fired. |
| 840 drm_bridge->CreateSession( | 847 cdm->CreateSession(session_id, content_type, &init_data[0], init_data.size()); |
| 841 session_id, content_type, &init_data[0], init_data.size()); | |
| 842 } | 848 } |
| 843 | 849 |
| 844 void BrowserMediaPlayerManager::ReleaseFullscreenPlayer( | 850 void BrowserMediaPlayerManager::ReleaseFullscreenPlayer( |
| 845 MediaPlayerAndroid* player) { | 851 MediaPlayerAndroid* player) { |
| 846 player->Release(); | 852 player->Release(); |
| 847 } | 853 } |
| 848 | 854 |
| 849 void BrowserMediaPlayerManager::OnMediaResourcesRequested(int player_id) { | 855 void BrowserMediaPlayerManager::OnMediaResourcesRequested(int player_id) { |
| 850 int num_active_player = 0; | 856 int num_active_player = 0; |
| 851 ScopedVector<MediaPlayerAndroid>::iterator it; | 857 ScopedVector<MediaPlayerAndroid>::iterator it; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 878 #if defined(VIDEO_HOLE) | 884 #if defined(VIDEO_HOLE) |
| 879 MediaPlayerAndroid* player = GetPlayer(player_id); | 885 MediaPlayerAndroid* player = GetPlayer(player_id); |
| 880 if (player && player->IsSurfaceInUse()) | 886 if (player && player->IsSurfaceInUse()) |
| 881 return; | 887 return; |
| 882 if (external_video_surface_container_) | 888 if (external_video_surface_container_) |
| 883 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); | 889 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); |
| 884 #endif // defined(VIDEO_HOLE) | 890 #endif // defined(VIDEO_HOLE) |
| 885 } | 891 } |
| 886 | 892 |
| 887 } // namespace content | 893 } // namespace content |
| OLD | NEW |