Home | History | Annotate | Download | only in media
      1 // Copyright 2014 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/renderer/media/cdm_session_adapter.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "base/memory/weak_ptr.h"
     10 #include "base/stl_util.h"
     11 #include "content/renderer/media/crypto/content_decryption_module_factory.h"
     12 #include "content/renderer/media/webcontentdecryptionmodulesession_impl.h"
     13 #include "media/base/cdm_promise.h"
     14 #include "media/base/media_keys.h"
     15 #include "url/gurl.h"
     16 
     17 namespace content {
     18 
     19 CdmSessionAdapter::CdmSessionAdapter() :
     20 #if defined(ENABLE_BROWSER_CDMS)
     21     cdm_id_(0),
     22 #endif
     23     weak_ptr_factory_(this) {}
     24 
     25 CdmSessionAdapter::~CdmSessionAdapter() {}
     26 
     27 bool CdmSessionAdapter::Initialize(
     28 #if defined(ENABLE_PEPPER_CDMS)
     29     const CreatePepperCdmCB& create_pepper_cdm_cb,
     30 #elif defined(ENABLE_BROWSER_CDMS)
     31     RendererCdmManager* manager,
     32 #endif  // defined(ENABLE_PEPPER_CDMS)
     33     const std::string& key_system,
     34     const GURL& security_origin) {
     35   base::WeakPtr<CdmSessionAdapter> weak_this = weak_ptr_factory_.GetWeakPtr();
     36   media_keys_ = ContentDecryptionModuleFactory::Create(
     37       key_system,
     38       security_origin,
     39 #if defined(ENABLE_PEPPER_CDMS)
     40       create_pepper_cdm_cb,
     41 #elif defined(ENABLE_BROWSER_CDMS)
     42       manager,
     43       &cdm_id_,
     44 #endif  // defined(ENABLE_PEPPER_CDMS)
     45       base::Bind(&CdmSessionAdapter::OnSessionMessage, weak_this),
     46       base::Bind(&CdmSessionAdapter::OnSessionReady, weak_this),
     47       base::Bind(&CdmSessionAdapter::OnSessionClosed, weak_this),
     48       base::Bind(&CdmSessionAdapter::OnSessionError, weak_this));
     49 
     50   // Success if |media_keys_| created.
     51   return media_keys_;
     52 }
     53 
     54 WebContentDecryptionModuleSessionImpl* CdmSessionAdapter::CreateSession(
     55     blink::WebContentDecryptionModuleSession::Client* client) {
     56   return new WebContentDecryptionModuleSessionImpl(client, this);
     57 }
     58 
     59 void CdmSessionAdapter::RegisterSession(
     60     const std::string& web_session_id,
     61     base::WeakPtr<WebContentDecryptionModuleSessionImpl> session) {
     62   DCHECK(!ContainsKey(sessions_, web_session_id));
     63   sessions_[web_session_id] = session;
     64 }
     65 
     66 void CdmSessionAdapter::RemoveSession(const std::string& web_session_id) {
     67   DCHECK(ContainsKey(sessions_, web_session_id));
     68   sessions_.erase(web_session_id);
     69 }
     70 
     71 void CdmSessionAdapter::InitializeNewSession(
     72     const std::string& init_data_type,
     73     const uint8* init_data,
     74     int init_data_length,
     75     media::MediaKeys::SessionType session_type,
     76     scoped_ptr<media::NewSessionCdmPromise> promise) {
     77   media_keys_->CreateSession(init_data_type,
     78                              init_data,
     79                              init_data_length,
     80                              session_type,
     81                              promise.Pass());
     82 }
     83 
     84 void CdmSessionAdapter::UpdateSession(
     85     const std::string& web_session_id,
     86     const uint8* response,
     87     int response_length,
     88     scoped_ptr<media::SimpleCdmPromise> promise) {
     89   media_keys_->UpdateSession(
     90       web_session_id, response, response_length, promise.Pass());
     91 }
     92 
     93 void CdmSessionAdapter::ReleaseSession(
     94     const std::string& web_session_id,
     95     scoped_ptr<media::SimpleCdmPromise> promise) {
     96   media_keys_->ReleaseSession(web_session_id, promise.Pass());
     97 }
     98 
     99 media::Decryptor* CdmSessionAdapter::GetDecryptor() {
    100   return media_keys_->GetDecryptor();
    101 }
    102 
    103 #if defined(ENABLE_BROWSER_CDMS)
    104 int CdmSessionAdapter::GetCdmId() const {
    105   return cdm_id_;
    106 }
    107 #endif  // defined(ENABLE_BROWSER_CDMS)
    108 
    109 void CdmSessionAdapter::OnSessionMessage(const std::string& web_session_id,
    110                                          const std::vector<uint8>& message,
    111                                          const GURL& destination_url) {
    112   WebContentDecryptionModuleSessionImpl* session = GetSession(web_session_id);
    113   DLOG_IF(WARNING, !session) << __FUNCTION__ << " for unknown session "
    114                              << web_session_id;
    115   if (session)
    116     session->OnSessionMessage(message, destination_url);
    117 }
    118 
    119 void CdmSessionAdapter::OnSessionReady(const std::string& web_session_id) {
    120   WebContentDecryptionModuleSessionImpl* session = GetSession(web_session_id);
    121   DLOG_IF(WARNING, !session) << __FUNCTION__ << " for unknown session "
    122                              << web_session_id;
    123   if (session)
    124     session->OnSessionReady();
    125 }
    126 
    127 void CdmSessionAdapter::OnSessionClosed(const std::string& web_session_id) {
    128   WebContentDecryptionModuleSessionImpl* session = GetSession(web_session_id);
    129   DLOG_IF(WARNING, !session) << __FUNCTION__ << " for unknown session "
    130                              << web_session_id;
    131   if (session)
    132     session->OnSessionClosed();
    133 }
    134 
    135 void CdmSessionAdapter::OnSessionError(
    136     const std::string& web_session_id,
    137     media::MediaKeys::Exception exception_code,
    138     uint32 system_code,
    139     const std::string& error_message) {
    140   WebContentDecryptionModuleSessionImpl* session = GetSession(web_session_id);
    141   DLOG_IF(WARNING, !session) << __FUNCTION__ << " for unknown session "
    142                              << web_session_id;
    143   if (session)
    144     session->OnSessionError(exception_code, system_code, error_message);
    145 }
    146 
    147 WebContentDecryptionModuleSessionImpl* CdmSessionAdapter::GetSession(
    148     const std::string& web_session_id) {
    149   // Since session objects may get garbage collected, it is possible that there
    150   // are events coming back from the CDM and the session has been unregistered.
    151   // We can not tell if the CDM is firing events at sessions that never existed.
    152   SessionMap::iterator session = sessions_.find(web_session_id);
    153   return (session != sessions_.end()) ? session->second.get() : NULL;
    154 }
    155 
    156 }  // namespace content
    157