Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chromecast / media / cdm / browser_cdm_cast.cc
blobfa4195ad3c9cafb55bda1672a0c2a1af860e0b08
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"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "media/base/cdm_key_information.h"
12 #include "media/base/cdm_promise.h"
13 #include "media/cdm/player_tracker_impl.h"
15 namespace chromecast {
16 namespace media {
18 namespace {
20 // media::CdmPromiseTemplate implementation that wraps a promise so as to
21 // allow passing to other threads.
22 template <typename... T>
23 class CdmPromiseInternal : public ::media::CdmPromiseTemplate<T...> {
24 public:
25 CdmPromiseInternal(scoped_ptr<::media::CdmPromiseTemplate<T...>> promise)
26 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
27 promise_(promise.Pass()) {
30 ~CdmPromiseInternal() final {
31 // Promise must be resolved or rejected before destruction.
32 DCHECK(!promise_);
35 // CdmPromiseTemplate<> implementation.
36 void resolve(const T&... result) final;
38 void reject(::media::MediaKeys::Exception exception,
39 uint32_t system_code,
40 const std::string& error_message) final {
41 MarkPromiseSettled();
42 task_runner_->PostTask(
43 FROM_HERE,
44 base::Bind(&::media::CdmPromiseTemplate<T...>::reject,
45 base::Owned(promise_.release()),
46 exception, system_code, error_message));
49 private:
50 using ::media::CdmPromiseTemplate<T...>::MarkPromiseSettled;
52 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
53 scoped_ptr<::media::CdmPromiseTemplate<T...>> promise_;
56 template <typename... T>
57 void CdmPromiseInternal<T...>::resolve(const T&... result) {
58 MarkPromiseSettled();
59 task_runner_->PostTask(
60 FROM_HERE,
61 base::Bind(&::media::CdmPromiseTemplate<T...>::resolve,
62 base::Owned(promise_.release()),
63 result...));
66 template <typename... T>
67 scoped_ptr<CdmPromiseInternal<T...>> BindPromiseToCurrentLoop(
68 scoped_ptr<::media::CdmPromiseTemplate<T...>> promise) {
69 return make_scoped_ptr(new CdmPromiseInternal<T...>(promise.Pass()));
72 } // namespace
74 BrowserCdmCast::BrowserCdmCast() {
75 thread_checker_.DetachFromThread();
78 BrowserCdmCast::~BrowserCdmCast() {
79 DCHECK(thread_checker_.CalledOnValidThread());
80 DCHECK(player_tracker_impl_.get());
81 player_tracker_impl_->NotifyCdmUnset();
84 void BrowserCdmCast::Initialize(
85 const ::media::SessionMessageCB& session_message_cb,
86 const ::media::SessionClosedCB& session_closed_cb,
87 const ::media::LegacySessionErrorCB& legacy_session_error_cb,
88 const ::media::SessionKeysChangeCB& session_keys_change_cb,
89 const ::media::SessionExpirationUpdateCB& session_expiration_update_cb) {
90 DCHECK(thread_checker_.CalledOnValidThread());
92 player_tracker_impl_.reset(new ::media::PlayerTrackerImpl);
94 session_message_cb_ = session_message_cb;
95 session_closed_cb_ = session_closed_cb;
96 legacy_session_error_cb_ = legacy_session_error_cb;
97 session_keys_change_cb_ = session_keys_change_cb;
98 session_expiration_update_cb_ = session_expiration_update_cb;
100 InitializeInternal();
103 int BrowserCdmCast::RegisterPlayer(const base::Closure& new_key_cb,
104 const base::Closure& cdm_unset_cb) {
105 DCHECK(thread_checker_.CalledOnValidThread());
106 return player_tracker_impl_->RegisterPlayer(new_key_cb, cdm_unset_cb);
109 void BrowserCdmCast::UnregisterPlayer(int registration_id) {
110 DCHECK(thread_checker_.CalledOnValidThread());
111 player_tracker_impl_->UnregisterPlayer(registration_id);
114 ::media::CdmContext* BrowserCdmCast::GetCdmContext() {
115 NOTREACHED();
116 return nullptr;
119 void BrowserCdmCast::OnSessionMessage(
120 const std::string& session_id,
121 const std::vector<uint8_t>& message,
122 const GURL& destination_url,
123 ::media::MediaKeys::MessageType message_type) {
124 session_message_cb_.Run(session_id,
125 message_type,
126 message,
127 destination_url);
130 void BrowserCdmCast::OnSessionClosed(const std::string& session_id) {
131 session_closed_cb_.Run(session_id);
134 void BrowserCdmCast::OnSessionKeysChange(
135 const std::string& session_id,
136 const ::media::KeyIdAndKeyPairs& keys) {
137 ::media::CdmKeysInfo cdm_keys_info;
138 for (const std::pair<std::string, std::string>& key : keys) {
139 scoped_ptr< ::media::CdmKeyInformation> cdm_key_information(
140 new ::media::CdmKeyInformation());
141 cdm_key_information->key_id.assign(key.first.begin(), key.first.end());
142 cdm_keys_info.push_back(cdm_key_information.release());
144 session_keys_change_cb_.Run(session_id, true, cdm_keys_info.Pass());
146 player_tracker_impl_->NotifyNewKey();
149 // A macro runs current member function on |task_runner_| thread.
150 #define FORWARD_ON_CDM_THREAD(param_fn, ...) \
151 task_runner_->PostTask( \
152 FROM_HERE, \
153 base::Bind(&BrowserCdmCast::param_fn, \
154 base::Unretained(browser_cdm_cast_.get()), ##__VA_ARGS__))
156 BrowserCdmCastUi::BrowserCdmCastUi(
157 scoped_ptr<BrowserCdmCast> browser_cdm_cast,
158 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
159 : browser_cdm_cast_(browser_cdm_cast.Pass()), task_runner_(task_runner) {
162 BrowserCdmCastUi::~BrowserCdmCastUi() {
163 DCHECK(thread_checker_.CalledOnValidThread());
164 task_runner_->DeleteSoon(FROM_HERE, browser_cdm_cast_.release());
167 int BrowserCdmCastUi::RegisterPlayer(const base::Closure& new_key_cb,
168 const base::Closure& cdm_unset_cb) {
169 NOTREACHED() << "RegisterPlayer should be called on BrowserCdmCast";
170 return -1;
173 void BrowserCdmCastUi::UnregisterPlayer(int registration_id) {
174 NOTREACHED() << "UnregisterPlayer should be called on BrowserCdmCast";
177 BrowserCdmCast* BrowserCdmCastUi::browser_cdm_cast() const {
178 DCHECK(thread_checker_.CalledOnValidThread());
179 return browser_cdm_cast_.get();
182 void BrowserCdmCastUi::SetServerCertificate(
183 const std::vector<uint8_t>& certificate,
184 scoped_ptr<::media::SimpleCdmPromise> promise) {
185 DCHECK(thread_checker_.CalledOnValidThread());
186 FORWARD_ON_CDM_THREAD(
187 SetServerCertificate,
188 certificate,
189 base::Passed(BindPromiseToCurrentLoop(promise.Pass())));
192 void BrowserCdmCastUi::CreateSessionAndGenerateRequest(
193 ::media::MediaKeys::SessionType session_type,
194 ::media::EmeInitDataType init_data_type,
195 const std::vector<uint8_t>& init_data,
196 scoped_ptr<::media::NewSessionCdmPromise> promise) {
197 DCHECK(thread_checker_.CalledOnValidThread());
198 FORWARD_ON_CDM_THREAD(
199 CreateSessionAndGenerateRequest,
200 session_type,
201 init_data_type,
202 init_data,
203 base::Passed(BindPromiseToCurrentLoop(promise.Pass())));
206 void BrowserCdmCastUi::LoadSession(
207 ::media::MediaKeys::SessionType session_type,
208 const std::string& session_id,
209 scoped_ptr<::media::NewSessionCdmPromise> promise) {
210 DCHECK(thread_checker_.CalledOnValidThread());
211 FORWARD_ON_CDM_THREAD(
212 LoadSession, session_type, session_id,
213 base::Passed(BindPromiseToCurrentLoop(promise.Pass())));
216 void BrowserCdmCastUi::UpdateSession(
217 const std::string& session_id,
218 const std::vector<uint8_t>& response,
219 scoped_ptr<::media::SimpleCdmPromise> promise) {
220 DCHECK(thread_checker_.CalledOnValidThread());
221 FORWARD_ON_CDM_THREAD(
222 UpdateSession,
223 session_id,
224 response,
225 base::Passed(BindPromiseToCurrentLoop(promise.Pass())));
228 void BrowserCdmCastUi::CloseSession(
229 const std::string& session_id,
230 scoped_ptr<::media::SimpleCdmPromise> promise) {
231 DCHECK(thread_checker_.CalledOnValidThread());
232 FORWARD_ON_CDM_THREAD(CloseSession, session_id,
233 base::Passed(BindPromiseToCurrentLoop(promise.Pass())));
236 void BrowserCdmCastUi::RemoveSession(
237 const std::string& session_id,
238 scoped_ptr<::media::SimpleCdmPromise> promise) {
239 DCHECK(thread_checker_.CalledOnValidThread());
240 FORWARD_ON_CDM_THREAD(RemoveSession, session_id,
241 base::Passed(BindPromiseToCurrentLoop(promise.Pass())));
244 ::media::CdmContext* BrowserCdmCastUi::GetCdmContext() {
245 NOTREACHED();
246 return nullptr;
249 // A default empty implementation for subclasses that don't need to provide
250 // any key system specific initialization.
251 void BrowserCdmCast::InitializeInternal() {
254 } // namespace media
255 } // namespace chromecast