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 "chromecast/media/cdm/browser_cdm_cast.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "media/base/cdm_key_information.h"
11 #include "media/base/cdm_promise.h"
12 #include "media/cdm/player_tracker_impl.h"
14 namespace chromecast
{
17 BrowserCdmCast::BrowserCdmCast() {
18 thread_checker_
.DetachFromThread();
21 BrowserCdmCast::~BrowserCdmCast() {
22 DCHECK(thread_checker_
.CalledOnValidThread());
23 DCHECK(player_tracker_impl_
.get());
24 player_tracker_impl_
->NotifyCdmUnset();
27 void BrowserCdmCast::Initialize(
28 const ::media::SessionMessageCB
& session_message_cb
,
29 const ::media::SessionClosedCB
& session_closed_cb
,
30 const ::media::LegacySessionErrorCB
& legacy_session_error_cb
,
31 const ::media::SessionKeysChangeCB
& session_keys_change_cb
,
32 const ::media::SessionExpirationUpdateCB
& session_expiration_update_cb
) {
33 DCHECK(thread_checker_
.CalledOnValidThread());
35 player_tracker_impl_
.reset(new ::media::PlayerTrackerImpl
);
37 session_message_cb_
= session_message_cb
;
38 session_closed_cb_
= session_closed_cb
;
39 legacy_session_error_cb_
= legacy_session_error_cb
;
40 session_keys_change_cb_
= session_keys_change_cb
;
41 session_expiration_update_cb_
= session_expiration_update_cb
;
44 int BrowserCdmCast::RegisterPlayer(const base::Closure
& new_key_cb
,
45 const base::Closure
& cdm_unset_cb
) {
46 DCHECK(thread_checker_
.CalledOnValidThread());
47 return player_tracker_impl_
->RegisterPlayer(new_key_cb
, cdm_unset_cb
);
50 void BrowserCdmCast::UnregisterPlayer(int registration_id
) {
51 DCHECK(thread_checker_
.CalledOnValidThread());
52 player_tracker_impl_
->UnregisterPlayer(registration_id
);
55 void BrowserCdmCast::LoadSession(
56 ::media::MediaKeys::SessionType session_type
,
57 const std::string
& session_id
,
58 scoped_ptr
<::media::NewSessionCdmPromise
> promise
) {
59 NOTREACHED() << "LoadSession not supported";
60 legacy_session_error_cb_
.Run(
61 session_id
, ::media::MediaKeys::Exception::NOT_SUPPORTED_ERROR
, 0,
65 ::media::CdmContext
* BrowserCdmCast::GetCdmContext() {
70 void BrowserCdmCast::OnSessionMessage(const std::string
& session_id
,
71 const std::vector
<uint8
>& message
,
72 const GURL
& destination_url
) {
73 // Note: Message type is not supported in Chromecast. Do our best guess here.
74 ::media::MediaKeys::MessageType message_type
=
75 destination_url
.is_empty() ? ::media::MediaKeys::LICENSE_REQUEST
76 : ::media::MediaKeys::LICENSE_RENEWAL
;
77 session_message_cb_
.Run(session_id
,
83 void BrowserCdmCast::OnSessionClosed(const std::string
& session_id
) {
84 session_closed_cb_
.Run(session_id
);
87 void BrowserCdmCast::OnSessionKeysChange(
88 const std::string
& session_id
,
89 const ::media::KeyIdAndKeyPairs
& keys
) {
90 ::media::CdmKeysInfo cdm_keys_info
;
91 for (const std::pair
<std::string
, std::string
>& key
: keys
) {
92 scoped_ptr
< ::media::CdmKeyInformation
> cdm_key_information(
93 new ::media::CdmKeyInformation());
94 cdm_key_information
->key_id
.assign(key
.first
.begin(), key
.first
.end());
95 cdm_keys_info
.push_back(cdm_key_information
.release());
97 session_keys_change_cb_
.Run(session_id
, true, cdm_keys_info
.Pass());
99 player_tracker_impl_
->NotifyNewKey();
102 void BrowserCdmCast::SetServerCertificateHelper(
103 const std::vector
<uint8
>& certificate_data
,
104 scoped_ptr
<::media::SimpleCdmPromise
> promise
) {
105 SetServerCertificate(certificate_data
.data(),
106 certificate_data
.size(),
110 void BrowserCdmCast::CreateSessionAndGenerateRequestHelper(
111 ::media::MediaKeys::SessionType session_type
,
112 ::media::EmeInitDataType init_data_type
,
113 const std::vector
<uint8
>& init_data
,
114 scoped_ptr
<::media::NewSessionCdmPromise
> promise
) {
115 CreateSessionAndGenerateRequest(
116 session_type
, init_data_type
, init_data
.data(), init_data
.size(),
120 void BrowserCdmCast::UpdateSessionHelper(
121 const std::string
& session_id
,
122 const std::vector
<uint8
>& response
,
123 scoped_ptr
<::media::SimpleCdmPromise
> promise
) {
124 UpdateSession(session_id
, response
.data(), response
.size(), promise
.Pass());
127 // A macro runs current member function on |cdm_loop_| thread.
128 #define FORWARD_ON_CDM_THREAD(param_fn, ...) \
129 cdm_loop_->PostTask( \
131 base::Bind(&BrowserCdmCast::param_fn, \
132 base::Unretained(browser_cdm_cast_.get()), ##__VA_ARGS__))
135 BrowserCdmCastUi::BrowserCdmCastUi(
136 scoped_ptr
<BrowserCdmCast
> browser_cdm_cast
,
137 const scoped_refptr
<base::MessageLoopProxy
>& cdm_loop
)
138 : browser_cdm_cast_(browser_cdm_cast
.Pass()),
139 cdm_loop_(cdm_loop
) {
142 BrowserCdmCastUi::~BrowserCdmCastUi() {
143 DCHECK(thread_checker_
.CalledOnValidThread());
144 cdm_loop_
->DeleteSoon(FROM_HERE
, browser_cdm_cast_
.release());
147 int BrowserCdmCastUi::RegisterPlayer(const base::Closure
& new_key_cb
,
148 const base::Closure
& cdm_unset_cb
) {
149 NOTREACHED() << "RegisterPlayer should be called on BrowserCdmCast";
153 void BrowserCdmCastUi::UnregisterPlayer(int registration_id
) {
154 NOTREACHED() << "UnregisterPlayer should be called on BrowserCdmCast";
157 BrowserCdmCast
* BrowserCdmCastUi::browser_cdm_cast() const {
158 DCHECK(thread_checker_
.CalledOnValidThread());
159 return browser_cdm_cast_
.get();
162 void BrowserCdmCastUi::SetServerCertificate(
163 const uint8
* certificate_data
,
164 int certificate_data_length
,
165 scoped_ptr
<::media::SimpleCdmPromise
> promise
) {
166 DCHECK(thread_checker_
.CalledOnValidThread());
167 FORWARD_ON_CDM_THREAD(
168 SetServerCertificateHelper
,
169 std::vector
<uint8
>(certificate_data
,
170 certificate_data
+ certificate_data_length
),
171 base::Passed(&promise
));
174 void BrowserCdmCastUi::CreateSessionAndGenerateRequest(
175 ::media::MediaKeys::SessionType session_type
,
176 ::media::EmeInitDataType init_data_type
,
177 const uint8
* init_data
,
178 int init_data_length
,
179 scoped_ptr
<::media::NewSessionCdmPromise
> promise
) {
180 DCHECK(thread_checker_
.CalledOnValidThread());
181 FORWARD_ON_CDM_THREAD(
182 CreateSessionAndGenerateRequestHelper
,
185 std::vector
<uint8
>(init_data
, init_data
+ init_data_length
),
186 base::Passed(&promise
));
189 void BrowserCdmCastUi::LoadSession(
190 ::media::MediaKeys::SessionType session_type
,
191 const std::string
& session_id
,
192 scoped_ptr
<::media::NewSessionCdmPromise
> promise
) {
193 DCHECK(thread_checker_
.CalledOnValidThread());
194 FORWARD_ON_CDM_THREAD(
195 LoadSession
, session_type
, session_id
, base::Passed(&promise
));
198 void BrowserCdmCastUi::UpdateSession(
199 const std::string
& session_id
,
200 const uint8
* response
,
202 scoped_ptr
<::media::SimpleCdmPromise
> promise
) {
203 DCHECK(thread_checker_
.CalledOnValidThread());
204 FORWARD_ON_CDM_THREAD(
207 std::vector
<uint8
>(response
, response
+ response_length
),
208 base::Passed(&promise
));
211 void BrowserCdmCastUi::CloseSession(
212 const std::string
& session_id
,
213 scoped_ptr
<::media::SimpleCdmPromise
> promise
) {
214 DCHECK(thread_checker_
.CalledOnValidThread());
215 FORWARD_ON_CDM_THREAD(CloseSession
, session_id
, base::Passed(&promise
));
218 void BrowserCdmCastUi::RemoveSession(
219 const std::string
& session_id
,
220 scoped_ptr
<::media::SimpleCdmPromise
> promise
) {
221 DCHECK(thread_checker_
.CalledOnValidThread());
222 FORWARD_ON_CDM_THREAD(RemoveSession
, session_id
, base::Passed(&promise
));
225 ::media::CdmContext
* BrowserCdmCastUi::GetCdmContext() {
231 } // namespace chromecast