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.
5 #include "content/renderer/media/cdm_session_adapter.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/crypto/key_systems.h"
13 #include "content/renderer/media/webcontentdecryptionmodulesession_impl.h"
14 #include "media/base/cdm_promise.h"
15 #include "media/base/media_keys.h"
20 const char kMediaEME
[] = "Media.EME.";
21 const char kDot
[] = ".";
23 CdmSessionAdapter::CdmSessionAdapter() :
24 #if defined(ENABLE_BROWSER_CDMS)
27 weak_ptr_factory_(this) {}
29 CdmSessionAdapter::~CdmSessionAdapter() {}
31 bool CdmSessionAdapter::Initialize(
32 #if defined(ENABLE_PEPPER_CDMS)
33 const CreatePepperCdmCB
& create_pepper_cdm_cb
,
34 #elif defined(ENABLE_BROWSER_CDMS)
35 RendererCdmManager
* manager
,
36 #endif // defined(ENABLE_PEPPER_CDMS)
37 const std::string
& key_system
,
38 const GURL
& security_origin
) {
39 key_system_uma_prefix_
= kMediaEME
+ KeySystemNameForUMA(key_system
) + kDot
;
40 base::WeakPtr
<CdmSessionAdapter
> weak_this
= weak_ptr_factory_
.GetWeakPtr();
41 media_keys_
= ContentDecryptionModuleFactory::Create(
44 #if defined(ENABLE_PEPPER_CDMS)
46 #elif defined(ENABLE_BROWSER_CDMS)
49 #endif // defined(ENABLE_PEPPER_CDMS)
50 base::Bind(&CdmSessionAdapter::OnSessionMessage
, weak_this
),
51 base::Bind(&CdmSessionAdapter::OnSessionReady
, weak_this
),
52 base::Bind(&CdmSessionAdapter::OnSessionClosed
, weak_this
),
53 base::Bind(&CdmSessionAdapter::OnSessionError
, weak_this
));
55 // Success if |media_keys_| created.
59 WebContentDecryptionModuleSessionImpl
* CdmSessionAdapter::CreateSession() {
60 return new WebContentDecryptionModuleSessionImpl(this);
63 bool CdmSessionAdapter::RegisterSession(
64 const std::string
& web_session_id
,
65 base::WeakPtr
<WebContentDecryptionModuleSessionImpl
> session
) {
66 // If this session ID is already registered, don't register it again.
67 if (ContainsKey(sessions_
, web_session_id
))
70 sessions_
[web_session_id
] = session
;
74 void CdmSessionAdapter::RemoveSession(const std::string
& web_session_id
) {
75 DCHECK(ContainsKey(sessions_
, web_session_id
));
76 sessions_
.erase(web_session_id
);
79 void CdmSessionAdapter::InitializeNewSession(
80 const std::string
& init_data_type
,
81 const uint8
* init_data
,
83 media::MediaKeys::SessionType session_type
,
84 scoped_ptr
<media::NewSessionCdmPromise
> promise
) {
85 media_keys_
->CreateSession(init_data_type
,
92 void CdmSessionAdapter::UpdateSession(
93 const std::string
& web_session_id
,
94 const uint8
* response
,
96 scoped_ptr
<media::SimpleCdmPromise
> promise
) {
97 media_keys_
->UpdateSession(
98 web_session_id
, response
, response_length
, promise
.Pass());
101 void CdmSessionAdapter::ReleaseSession(
102 const std::string
& web_session_id
,
103 scoped_ptr
<media::SimpleCdmPromise
> promise
) {
104 media_keys_
->ReleaseSession(web_session_id
, promise
.Pass());
107 media::Decryptor
* CdmSessionAdapter::GetDecryptor() {
108 return media_keys_
->GetDecryptor();
111 const std::string
& CdmSessionAdapter::GetKeySystemUMAPrefix() const {
112 return key_system_uma_prefix_
;
115 #if defined(ENABLE_BROWSER_CDMS)
116 int CdmSessionAdapter::GetCdmId() const {
119 #endif // defined(ENABLE_BROWSER_CDMS)
121 void CdmSessionAdapter::OnSessionMessage(const std::string
& web_session_id
,
122 const std::vector
<uint8
>& message
,
123 const GURL
& destination_url
) {
124 WebContentDecryptionModuleSessionImpl
* session
= GetSession(web_session_id
);
125 DLOG_IF(WARNING
, !session
) << __FUNCTION__
<< " for unknown session "
128 session
->OnSessionMessage(message
, destination_url
);
131 void CdmSessionAdapter::OnSessionReady(const std::string
& web_session_id
) {
132 WebContentDecryptionModuleSessionImpl
* session
= GetSession(web_session_id
);
133 DLOG_IF(WARNING
, !session
) << __FUNCTION__
<< " for unknown session "
136 session
->OnSessionReady();
139 void CdmSessionAdapter::OnSessionClosed(const std::string
& web_session_id
) {
140 WebContentDecryptionModuleSessionImpl
* session
= GetSession(web_session_id
);
141 DLOG_IF(WARNING
, !session
) << __FUNCTION__
<< " for unknown session "
144 session
->OnSessionClosed();
147 void CdmSessionAdapter::OnSessionError(
148 const std::string
& web_session_id
,
149 media::MediaKeys::Exception exception_code
,
151 const std::string
& error_message
) {
152 WebContentDecryptionModuleSessionImpl
* session
= GetSession(web_session_id
);
153 DLOG_IF(WARNING
, !session
) << __FUNCTION__
<< " for unknown session "
156 session
->OnSessionError(exception_code
, system_code
, error_message
);
159 WebContentDecryptionModuleSessionImpl
* CdmSessionAdapter::GetSession(
160 const std::string
& web_session_id
) {
161 // Since session objects may get garbage collected, it is possible that there
162 // are events coming back from the CDM and the session has been unregistered.
163 // We can not tell if the CDM is firing events at sessions that never existed.
164 SessionMap::iterator session
= sessions_
.find(web_session_id
);
165 return (session
!= sessions_
.end()) ? session
->second
.get() : NULL
;
168 } // namespace content