| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |