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/renderer/media/crypto/ppapi_decryptor.h" | 5 #include "content/renderer/media/crypto/ppapi_decryptor.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 base::Closure additional_resolve_cb_; | 86 base::Closure additional_resolve_cb_; |
87 }; | 87 }; |
88 | 88 |
89 scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create( | 89 scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create( |
90 const std::string& key_system, | 90 const std::string& key_system, |
91 const GURL& security_origin, | 91 const GURL& security_origin, |
92 const CreatePepperCdmCB& create_pepper_cdm_cb, | 92 const CreatePepperCdmCB& create_pepper_cdm_cb, |
93 const media::SessionMessageCB& session_message_cb, | 93 const media::SessionMessageCB& session_message_cb, |
94 const media::SessionReadyCB& session_ready_cb, | 94 const media::SessionReadyCB& session_ready_cb, |
95 const media::SessionClosedCB& session_closed_cb, | 95 const media::SessionClosedCB& session_closed_cb, |
96 const media::SessionErrorCB& session_error_cb) { | 96 const media::SessionErrorCB& session_error_cb, |
97 const media::SessionKeysChangeCB& session_keys_change_cb, | |
98 const media::SessionExpirationChangeCB& session_expiration_change_cb) { | |
97 std::string plugin_type = GetPepperType(key_system); | 99 std::string plugin_type = GetPepperType(key_system); |
98 DCHECK(!plugin_type.empty()); | 100 DCHECK(!plugin_type.empty()); |
99 scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper = | 101 scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper = |
100 create_pepper_cdm_cb.Run(plugin_type, security_origin); | 102 create_pepper_cdm_cb.Run(plugin_type, security_origin); |
101 if (!pepper_cdm_wrapper) { | 103 if (!pepper_cdm_wrapper) { |
102 DLOG(ERROR) << "Plugin instance creation failed."; | 104 DLOG(ERROR) << "Plugin instance creation failed."; |
103 return scoped_ptr<PpapiDecryptor>(); | 105 return scoped_ptr<PpapiDecryptor>(); |
104 } | 106 } |
105 | 107 |
106 return scoped_ptr<PpapiDecryptor>( | 108 return scoped_ptr<PpapiDecryptor>( |
107 new PpapiDecryptor(key_system, | 109 new PpapiDecryptor(key_system, |
108 pepper_cdm_wrapper.Pass(), | 110 pepper_cdm_wrapper.Pass(), |
109 session_message_cb, | 111 session_message_cb, |
110 session_ready_cb, | 112 session_ready_cb, |
111 session_closed_cb, | 113 session_closed_cb, |
112 session_error_cb)); | 114 session_error_cb, |
115 session_keys_change_cb, | |
116 session_expiration_change_cb)); | |
113 } | 117 } |
114 | 118 |
115 PpapiDecryptor::PpapiDecryptor( | 119 PpapiDecryptor::PpapiDecryptor( |
116 const std::string& key_system, | 120 const std::string& key_system, |
117 scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper, | 121 scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper, |
118 const media::SessionMessageCB& session_message_cb, | 122 const media::SessionMessageCB& session_message_cb, |
119 const media::SessionReadyCB& session_ready_cb, | 123 const media::SessionReadyCB& session_ready_cb, |
120 const media::SessionClosedCB& session_closed_cb, | 124 const media::SessionClosedCB& session_closed_cb, |
121 const media::SessionErrorCB& session_error_cb) | 125 const media::SessionErrorCB& session_error_cb, |
126 const media::SessionKeysChangeCB& session_keys_change_cb, | |
127 const media::SessionExpirationChangeCB& session_expiration_change_cb) | |
122 : pepper_cdm_wrapper_(pepper_cdm_wrapper.Pass()), | 128 : pepper_cdm_wrapper_(pepper_cdm_wrapper.Pass()), |
123 session_message_cb_(session_message_cb), | 129 session_message_cb_(session_message_cb), |
124 session_ready_cb_(session_ready_cb), | 130 session_ready_cb_(session_ready_cb), |
125 session_closed_cb_(session_closed_cb), | 131 session_closed_cb_(session_closed_cb), |
126 session_error_cb_(session_error_cb), | 132 session_error_cb_(session_error_cb), |
133 session_keys_change_cb_(session_keys_change_cb), | |
134 session_expiration_change_cb_(session_expiration_change_cb), | |
127 render_loop_proxy_(base::MessageLoopProxy::current()), | 135 render_loop_proxy_(base::MessageLoopProxy::current()), |
128 weak_ptr_factory_(this) { | 136 weak_ptr_factory_(this) { |
129 DCHECK(pepper_cdm_wrapper_.get()); | 137 DCHECK(pepper_cdm_wrapper_.get()); |
130 DCHECK(!session_message_cb_.is_null()); | 138 DCHECK(!session_message_cb_.is_null()); |
131 DCHECK(!session_ready_cb_.is_null()); | 139 DCHECK(!session_ready_cb_.is_null()); |
132 DCHECK(!session_closed_cb_.is_null()); | 140 DCHECK(!session_closed_cb_.is_null()); |
133 DCHECK(!session_error_cb_.is_null()); | 141 DCHECK(!session_error_cb_.is_null()); |
142 DCHECK(!session_keys_change_cb.is_null()); | |
143 DCHECK(!session_expiration_change_cb.is_null()); | |
134 | 144 |
135 base::WeakPtr<PpapiDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr(); | 145 base::WeakPtr<PpapiDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr(); |
136 CdmDelegate()->Initialize( | 146 CdmDelegate()->Initialize( |
137 key_system, | 147 key_system, |
138 base::Bind(&PpapiDecryptor::OnSessionMessage, weak_this), | 148 base::Bind(&PpapiDecryptor::OnSessionMessage, weak_this), |
139 base::Bind(&PpapiDecryptor::OnSessionReady, weak_this), | 149 base::Bind(&PpapiDecryptor::OnSessionReady, weak_this), |
140 base::Bind(&PpapiDecryptor::OnSessionClosed, weak_this), | 150 base::Bind(&PpapiDecryptor::OnSessionClosed, weak_this), |
141 base::Bind(&PpapiDecryptor::OnSessionError, weak_this), | 151 base::Bind(&PpapiDecryptor::OnSessionError, weak_this), |
152 base::Bind(&PpapiDecryptor::OnSessionKeysChange, weak_this), | |
153 base::Bind(&PpapiDecryptor::OnSessionExpirationChange, weak_this), | |
142 base::Bind(&PpapiDecryptor::OnFatalPluginError, weak_this)); | 154 base::Bind(&PpapiDecryptor::OnFatalPluginError, weak_this)); |
143 } | 155 } |
144 | 156 |
145 PpapiDecryptor::~PpapiDecryptor() { | 157 PpapiDecryptor::~PpapiDecryptor() { |
146 pepper_cdm_wrapper_.reset(); | 158 pepper_cdm_wrapper_.reset(); |
147 } | 159 } |
148 | 160 |
161 void PpapiDecryptor::SetServerCertificate( | |
162 const uint8* certificate_data, | |
163 int certificate_data_length, | |
164 scoped_ptr<media::SimpleCdmPromise> promise) { | |
165 DVLOG(2) << __FUNCTION__; | |
166 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | |
167 | |
168 if (!CdmDelegate()) { | |
169 promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); | |
170 return; | |
171 } | |
172 | |
173 CdmDelegate()->SetServerCertificate( | |
174 certificate_data, certificate_data_length, promise.Pass()); | |
175 } | |
176 | |
149 void PpapiDecryptor::CreateSession( | 177 void PpapiDecryptor::CreateSession( |
150 const std::string& init_data_type, | 178 const std::string& init_data_type, |
151 const uint8* init_data, | 179 const uint8* init_data, |
152 int init_data_length, | 180 int init_data_length, |
153 SessionType session_type, | 181 SessionType session_type, |
154 scoped_ptr<media::NewSessionCdmPromise> promise) { | 182 scoped_ptr<media::NewSessionCdmPromise> promise) { |
155 DVLOG(2) << __FUNCTION__; | 183 DVLOG(2) << __FUNCTION__; |
156 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | 184 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
157 | 185 |
158 if (!CdmDelegate()) { | 186 if (!CdmDelegate()) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 scoped_ptr<media::SimpleCdmPromise> promise) { | 223 scoped_ptr<media::SimpleCdmPromise> promise) { |
196 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | 224 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
197 | 225 |
198 if (!CdmDelegate()) { | 226 if (!CdmDelegate()) { |
199 promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); | 227 promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); |
200 return; | 228 return; |
201 } | 229 } |
202 | 230 |
203 scoped_ptr<SessionUpdatedPromise> session_updated_promise( | 231 scoped_ptr<SessionUpdatedPromise> session_updated_promise( |
204 new SessionUpdatedPromise(promise.Pass(), | 232 new SessionUpdatedPromise(promise.Pass(), |
205 base::Bind(&PpapiDecryptor::ResumePlayback, | 233 base::Bind(&PpapiDecryptor::ResumePlayback, |
ddorwin
2014/09/11 23:31:11
This should not be necessary once OnSessionKeysCha
jrummell
2014/09/15 18:22:39
Done.
| |
206 weak_ptr_factory_.GetWeakPtr()))); | 234 weak_ptr_factory_.GetWeakPtr()))); |
207 CdmDelegate()->UpdateSession( | 235 CdmDelegate()->UpdateSession( |
208 web_session_id, | 236 web_session_id, |
209 response, | 237 response, |
210 response_length, | 238 response_length, |
211 session_updated_promise.PassAs<media::SimpleCdmPromise>()); | 239 session_updated_promise.PassAs<media::SimpleCdmPromise>()); |
212 } | 240 } |
213 | 241 |
214 void PpapiDecryptor::ReleaseSession( | 242 void PpapiDecryptor::CloseSession(const std::string& web_session_id, |
243 scoped_ptr<media::SimpleCdmPromise> promise) { | |
244 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | |
245 | |
246 if (!CdmDelegate()) { | |
247 promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); | |
248 return; | |
249 } | |
250 | |
251 CdmDelegate()->CloseSession(web_session_id, promise.Pass()); | |
252 } | |
253 | |
254 void PpapiDecryptor::RemoveSession( | |
215 const std::string& web_session_id, | 255 const std::string& web_session_id, |
216 scoped_ptr<media::SimpleCdmPromise> promise) { | 256 scoped_ptr<media::SimpleCdmPromise> promise) { |
217 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | 257 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
218 | 258 |
219 if (!CdmDelegate()) { | 259 if (!CdmDelegate()) { |
220 promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); | 260 promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); |
221 return; | 261 return; |
222 } | 262 } |
223 | 263 |
224 CdmDelegate()->CloseSession(web_session_id, promise.Pass()); | 264 CdmDelegate()->RemoveSession(web_session_id, promise.Pass()); |
265 } | |
266 | |
267 void PpapiDecryptor::GetUsableKeyIds(const std::string& web_session_id, | |
268 scoped_ptr<media::KeyIdsPromise> promise) { | |
269 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | |
270 | |
271 if (!CdmDelegate()) { | |
272 promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); | |
273 return; | |
274 } | |
275 | |
276 CdmDelegate()->GetUsableKeyIds(web_session_id, promise.Pass()); | |
225 } | 277 } |
226 | 278 |
227 media::Decryptor* PpapiDecryptor::GetDecryptor() { | 279 media::Decryptor* PpapiDecryptor::GetDecryptor() { |
228 return this; | 280 return this; |
229 } | 281 } |
230 | 282 |
231 void PpapiDecryptor::RegisterNewKeyCB(StreamType stream_type, | 283 void PpapiDecryptor::RegisterNewKeyCB(StreamType stream_type, |
232 const NewKeyCB& new_key_cb) { | 284 const NewKeyCB& new_key_cb) { |
233 if (!render_loop_proxy_->BelongsToCurrentThread()) { | 285 if (!render_loop_proxy_->BelongsToCurrentThread()) { |
234 render_loop_proxy_->PostTask(FROM_HERE, | 286 render_loop_proxy_->PostTask(FROM_HERE, |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 } | 481 } |
430 } | 482 } |
431 | 483 |
432 void PpapiDecryptor::OnSessionMessage(const std::string& web_session_id, | 484 void PpapiDecryptor::OnSessionMessage(const std::string& web_session_id, |
433 const std::vector<uint8>& message, | 485 const std::vector<uint8>& message, |
434 const GURL& destination_url) { | 486 const GURL& destination_url) { |
435 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | 487 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
436 session_message_cb_.Run(web_session_id, message, destination_url); | 488 session_message_cb_.Run(web_session_id, message, destination_url); |
437 } | 489 } |
438 | 490 |
491 void PpapiDecryptor::OnSessionKeysChange(const std::string& web_session_id, | |
492 bool has_additional_usable_key) { | |
493 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | |
494 | |
495 if (has_additional_usable_key) | |
496 ResumePlayback(); | |
497 | |
498 session_keys_change_cb_.Run(web_session_id, has_additional_usable_key); | |
499 } | |
500 | |
501 void PpapiDecryptor::OnSessionExpirationChange( | |
502 const std::string& web_session_id, | |
503 double new_expiry_time) { | |
504 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | |
505 session_expiration_change_cb_.Run(web_session_id, new_expiry_time); | |
506 } | |
507 | |
439 void PpapiDecryptor::OnSessionReady(const std::string& web_session_id) { | 508 void PpapiDecryptor::OnSessionReady(const std::string& web_session_id) { |
440 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | 509 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
441 | 510 |
442 ResumePlayback(); | 511 ResumePlayback(); |
ddorwin
2014/09/11 23:31:11
I think we should be able to remove this once OnSe
jrummell
2014/09/15 18:22:39
Done.
| |
443 session_ready_cb_.Run(web_session_id); | 512 session_ready_cb_.Run(web_session_id); |
444 } | 513 } |
445 | 514 |
446 void PpapiDecryptor::OnSessionClosed(const std::string& web_session_id) { | 515 void PpapiDecryptor::OnSessionClosed(const std::string& web_session_id) { |
447 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | 516 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
448 session_closed_cb_.Run(web_session_id); | 517 session_closed_cb_.Run(web_session_id); |
449 } | 518 } |
450 | 519 |
451 void PpapiDecryptor::OnSessionError(const std::string& web_session_id, | 520 void PpapiDecryptor::OnSessionError(const std::string& web_session_id, |
452 MediaKeys::Exception exception_code, | 521 MediaKeys::Exception exception_code, |
(...skipping 19 matching lines...) Expand all Loading... | |
472 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | 541 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
473 pepper_cdm_wrapper_.reset(); | 542 pepper_cdm_wrapper_.reset(); |
474 } | 543 } |
475 | 544 |
476 ContentDecryptorDelegate* PpapiDecryptor::CdmDelegate() { | 545 ContentDecryptorDelegate* PpapiDecryptor::CdmDelegate() { |
477 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | 546 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
478 return (pepper_cdm_wrapper_) ? pepper_cdm_wrapper_->GetCdmDelegate() : NULL; | 547 return (pepper_cdm_wrapper_) ? pepper_cdm_wrapper_->GetCdmDelegate() : NULL; |
479 } | 548 } |
480 | 549 |
481 } // namespace content | 550 } // namespace content |
OLD | NEW |