Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: media/mojo/clients/mojo_cdm.cc

Issue 2426813002: EME: Close existing sessions on CDM failure (Closed)
Patch Set: rename result (+rebase) Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/mojo/clients/mojo_cdm.h ('k') | media/test/data/eme_player_js/clearkey_player.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 "media/mojo/clients/mojo_cdm.h" 5 #include "media/mojo/clients/mojo_cdm.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 18 matching lines...) Expand all
29 static void RejectPromise(std::unique_ptr<PromiseType> promise, 29 static void RejectPromise(std::unique_ptr<PromiseType> promise,
30 mojom::CdmPromiseResultPtr result) { 30 mojom::CdmPromiseResultPtr result) {
31 promise->reject(result->exception, result->system_code, 31 promise->reject(result->exception, result->system_code,
32 result->error_message); 32 result->error_message);
33 } 33 }
34 34
35 // static 35 // static
36 void MojoCdm::Create( 36 void MojoCdm::Create(
37 const std::string& key_system, 37 const std::string& key_system,
38 const GURL& security_origin, 38 const GURL& security_origin,
39 const media::CdmConfig& cdm_config, 39 const CdmConfig& cdm_config,
40 mojom::ContentDecryptionModulePtr remote_cdm, 40 mojom::ContentDecryptionModulePtr remote_cdm,
41 const media::SessionMessageCB& session_message_cb, 41 const SessionMessageCB& session_message_cb,
42 const media::SessionClosedCB& session_closed_cb, 42 const SessionClosedCB& session_closed_cb,
43 const media::SessionKeysChangeCB& session_keys_change_cb, 43 const SessionKeysChangeCB& session_keys_change_cb,
44 const media::SessionExpirationUpdateCB& session_expiration_update_cb, 44 const SessionExpirationUpdateCB& session_expiration_update_cb,
45 const media::CdmCreatedCB& cdm_created_cb) { 45 const CdmCreatedCB& cdm_created_cb) {
46 scoped_refptr<MojoCdm> mojo_cdm( 46 scoped_refptr<MojoCdm> mojo_cdm(
47 new MojoCdm(std::move(remote_cdm), session_message_cb, session_closed_cb, 47 new MojoCdm(std::move(remote_cdm), session_message_cb, session_closed_cb,
48 session_keys_change_cb, session_expiration_update_cb)); 48 session_keys_change_cb, session_expiration_update_cb));
49 49
50 // |mojo_cdm| ownership is passed to the promise. 50 // |mojo_cdm| ownership is passed to the promise.
51 std::unique_ptr<CdmInitializedPromise> promise( 51 std::unique_ptr<CdmInitializedPromise> promise(
52 new CdmInitializedPromise(cdm_created_cb, mojo_cdm)); 52 new CdmInitializedPromise(cdm_created_cb, mojo_cdm));
53 53
54 mojo_cdm->InitializeCdm(key_system, security_origin, cdm_config, 54 mojo_cdm->InitializeCdm(key_system, security_origin, cdm_config,
55 std::move(promise)); 55 std::move(promise));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 decryptor_task_runner_->DeleteSoon(FROM_HERE, decryptor_.release()); 91 decryptor_task_runner_->DeleteSoon(FROM_HERE, decryptor_.release());
92 } 92 }
93 } 93 }
94 94
95 // Using base::Unretained(this) below is safe because |this| owns |remote_cdm_|, 95 // Using base::Unretained(this) below is safe because |this| owns |remote_cdm_|,
96 // and if |this| is destroyed, |remote_cdm_| will be destroyed as well. Then the 96 // and if |this| is destroyed, |remote_cdm_| will be destroyed as well. Then the
97 // error handler can't be invoked and callbacks won't be dispatched. 97 // error handler can't be invoked and callbacks won't be dispatched.
98 98
99 void MojoCdm::InitializeCdm(const std::string& key_system, 99 void MojoCdm::InitializeCdm(const std::string& key_system,
100 const GURL& security_origin, 100 const GURL& security_origin,
101 const media::CdmConfig& cdm_config, 101 const CdmConfig& cdm_config,
102 std::unique_ptr<CdmInitializedPromise> promise) { 102 std::unique_ptr<CdmInitializedPromise> promise) {
103 DVLOG(1) << __FUNCTION__ << ": " << key_system; 103 DVLOG(1) << __FUNCTION__ << ": " << key_system;
104 DCHECK(thread_checker_.CalledOnValidThread()); 104 DCHECK(thread_checker_.CalledOnValidThread());
105 105
106 // If connection error has happened, fail immediately. 106 // If connection error has happened, fail immediately.
107 if (remote_cdm_.encountered_error()) { 107 if (remote_cdm_.encountered_error()) {
108 LOG(ERROR) << "Remote CDM encountered error."; 108 LOG(ERROR) << "Remote CDM encountered error.";
109 promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, 109 promise->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0,
110 "Mojo CDM creation failed."); 110 "Mojo CDM creation failed.");
111 return; 111 return;
112 } 112 }
113 113
114 // Otherwise, set an error handler to catch the connection error. 114 // Otherwise, set an error handler to catch the connection error.
115 remote_cdm_.set_connection_error_handler( 115 remote_cdm_.set_connection_error_handler(
116 base::Bind(&MojoCdm::OnConnectionError, base::Unretained(this))); 116 base::Bind(&MojoCdm::OnConnectionError, base::Unretained(this)));
117 117
118 pending_init_promise_ = std::move(promise); 118 pending_init_promise_ = std::move(promise);
119 119
120 remote_cdm_->Initialize( 120 remote_cdm_->Initialize(
121 key_system, security_origin.spec(), mojom::CdmConfig::From(cdm_config), 121 key_system, security_origin.spec(), mojom::CdmConfig::From(cdm_config),
122 base::Bind(&MojoCdm::OnCdmInitialized, base::Unretained(this))); 122 base::Bind(&MojoCdm::OnCdmInitialized, base::Unretained(this)));
123 } 123 }
124 124
125 void MojoCdm::OnConnectionError() { 125 void MojoCdm::OnConnectionError() {
126 LOG(ERROR) << "Remote CDM connection error."; 126 LOG(ERROR) << "Remote CDM connection error.";
127 DCHECK(thread_checker_.CalledOnValidThread()); 127 DCHECK(thread_checker_.CalledOnValidThread());
128 128
129 // We only handle initial connection error. 129 // Handle initial connection error.
130 if (!pending_init_promise_) 130 if (pending_init_promise_) {
131 return; 131 pending_init_promise_->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0,
132 "Mojo CDM creation failed.");
133 pending_init_promise_.reset();
134 }
132 135
133 pending_init_promise_->reject(CdmPromise::NOT_SUPPORTED_ERROR, 0, 136 cdm_session_tracker_.CloseRemainingSessions(session_closed_cb_);
134 "Mojo CDM creation failed.");
135 pending_init_promise_.reset();
136 } 137 }
137 138
138 void MojoCdm::SetServerCertificate(const std::vector<uint8_t>& certificate, 139 void MojoCdm::SetServerCertificate(const std::vector<uint8_t>& certificate,
139 std::unique_ptr<SimpleCdmPromise> promise) { 140 std::unique_ptr<SimpleCdmPromise> promise) {
140 DVLOG(2) << __FUNCTION__; 141 DVLOG(2) << __FUNCTION__;
141 DCHECK(thread_checker_.CalledOnValidThread()); 142 DCHECK(thread_checker_.CalledOnValidThread());
142 143
143 remote_cdm_->SetServerCertificate( 144 remote_cdm_->SetServerCertificate(
144 certificate, base::Bind(&MojoCdm::OnSimpleCdmPromiseResult, 145 certificate, base::Bind(&MojoCdm::OnSimpleCdmPromiseResult,
145 base::Unretained(this), base::Passed(&promise))); 146 base::Unretained(this), base::Passed(&promise)));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 remote_cdm_->RemoveSession( 202 remote_cdm_->RemoveSession(
202 session_id, base::Bind(&MojoCdm::OnSimpleCdmPromiseResult, 203 session_id, base::Bind(&MojoCdm::OnSimpleCdmPromiseResult,
203 base::Unretained(this), base::Passed(&promise))); 204 base::Unretained(this), base::Passed(&promise)));
204 } 205 }
205 206
206 CdmContext* MojoCdm::GetCdmContext() { 207 CdmContext* MojoCdm::GetCdmContext() {
207 DVLOG(2) << __FUNCTION__; 208 DVLOG(2) << __FUNCTION__;
208 return this; 209 return this;
209 } 210 }
210 211
211 media::Decryptor* MojoCdm::GetDecryptor() { 212 Decryptor* MojoCdm::GetDecryptor() {
212 base::AutoLock auto_lock(lock_); 213 base::AutoLock auto_lock(lock_);
213 214
214 if (!decryptor_task_runner_) 215 if (!decryptor_task_runner_)
215 decryptor_task_runner_ = base::ThreadTaskRunnerHandle::Get(); 216 decryptor_task_runner_ = base::ThreadTaskRunnerHandle::Get();
216 217
217 DCHECK(decryptor_task_runner_->BelongsToCurrentThread()); 218 DCHECK(decryptor_task_runner_->BelongsToCurrentThread());
218 219
219 // Can be called on a different thread. 220 // Can be called on a different thread.
220 if (decryptor_ptr_info_.is_valid()) { 221 if (decryptor_ptr_info_.is_valid()) {
221 DCHECK(!decryptor_); 222 DCHECK(!decryptor_);
(...skipping 18 matching lines...) Expand all
240 DVLOG(2) << __FUNCTION__; 241 DVLOG(2) << __FUNCTION__;
241 DCHECK(thread_checker_.CalledOnValidThread()); 242 DCHECK(thread_checker_.CalledOnValidThread());
242 243
243 session_message_cb_.Run(session_id, message_type, message); 244 session_message_cb_.Run(session_id, message_type, message);
244 } 245 }
245 246
246 void MojoCdm::OnSessionClosed(const std::string& session_id) { 247 void MojoCdm::OnSessionClosed(const std::string& session_id) {
247 DVLOG(2) << __FUNCTION__; 248 DVLOG(2) << __FUNCTION__;
248 DCHECK(thread_checker_.CalledOnValidThread()); 249 DCHECK(thread_checker_.CalledOnValidThread());
249 250
251 cdm_session_tracker_.RemoveSession(session_id);
250 session_closed_cb_.Run(session_id); 252 session_closed_cb_.Run(session_id);
251 } 253 }
252 254
253 void MojoCdm::OnSessionKeysChange( 255 void MojoCdm::OnSessionKeysChange(
254 const std::string& session_id, 256 const std::string& session_id,
255 bool has_additional_usable_key, 257 bool has_additional_usable_key,
256 std::vector<mojom::CdmKeyInformationPtr> keys_info) { 258 std::vector<mojom::CdmKeyInformationPtr> keys_info) {
257 DVLOG(2) << __FUNCTION__; 259 DVLOG(2) << __FUNCTION__;
258 DCHECK(thread_checker_.CalledOnValidThread()); 260 DCHECK(thread_checker_.CalledOnValidThread());
259 261
260 // TODO(jrummell): Handling resume playback should be done in the media 262 // TODO(jrummell): Handling resume playback should be done in the media
261 // player, not in the Decryptors. http://crbug.com/413413. 263 // player, not in the Decryptors. http://crbug.com/413413.
262 if (has_additional_usable_key) { 264 if (has_additional_usable_key) {
263 base::AutoLock auto_lock(lock_); 265 base::AutoLock auto_lock(lock_);
264 if (decryptor_) { 266 if (decryptor_) {
265 DCHECK(decryptor_task_runner_); 267 DCHECK(decryptor_task_runner_);
266 decryptor_task_runner_->PostTask( 268 decryptor_task_runner_->PostTask(
267 FROM_HERE, 269 FROM_HERE,
268 base::Bind(&MojoCdm::OnKeyAdded, weak_factory_.GetWeakPtr())); 270 base::Bind(&MojoCdm::OnKeyAdded, weak_factory_.GetWeakPtr()));
269 } 271 }
270 } 272 }
271 273
272 media::CdmKeysInfo key_data; 274 CdmKeysInfo key_data;
273 key_data.reserve(keys_info.size()); 275 key_data.reserve(keys_info.size());
274 for (size_t i = 0; i < keys_info.size(); ++i) { 276 for (size_t i = 0; i < keys_info.size(); ++i) {
275 key_data.push_back( 277 key_data.push_back(
276 keys_info[i].To<std::unique_ptr<media::CdmKeyInformation>>().release()); 278 keys_info[i].To<std::unique_ptr<CdmKeyInformation>>().release());
277 } 279 }
278 session_keys_change_cb_.Run(session_id, has_additional_usable_key, 280 session_keys_change_cb_.Run(session_id, has_additional_usable_key,
279 std::move(key_data)); 281 std::move(key_data));
280 } 282 }
281 283
282 void MojoCdm::OnSessionExpirationUpdate(const std::string& session_id, 284 void MojoCdm::OnSessionExpirationUpdate(const std::string& session_id,
283 double new_expiry_time_sec) { 285 double new_expiry_time_sec) {
284 DVLOG(2) << __FUNCTION__; 286 DVLOG(2) << __FUNCTION__;
285 DCHECK(thread_checker_.CalledOnValidThread()); 287 DCHECK(thread_checker_.CalledOnValidThread());
286 288
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 if (result->success) 329 if (result->success)
328 promise->resolve(); 330 promise->resolve();
329 else 331 else
330 RejectPromise(std::move(promise), std::move(result)); 332 RejectPromise(std::move(promise), std::move(result));
331 } 333 }
332 334
333 void MojoCdm::OnNewSessionCdmPromiseResult( 335 void MojoCdm::OnNewSessionCdmPromiseResult(
334 std::unique_ptr<NewSessionCdmPromise> promise, 336 std::unique_ptr<NewSessionCdmPromise> promise,
335 mojom::CdmPromiseResultPtr result, 337 mojom::CdmPromiseResultPtr result,
336 const std::string& session_id) { 338 const std::string& session_id) {
337 if (result->success) 339 if (result->success) {
340 cdm_session_tracker_.AddSession(session_id);
338 promise->resolve(session_id); 341 promise->resolve(session_id);
339 else 342 } else
340 RejectPromise(std::move(promise), std::move(result)); 343 RejectPromise(std::move(promise), std::move(result));
341 } 344 }
342 345
343 } // namespace media 346 } // namespace media
OLDNEW
« no previous file with comments | « media/mojo/clients/mojo_cdm.h ('k') | media/test/data/eme_player_js/clearkey_player.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698