| 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(static_cast<MediaKeys::Exception>(result->exception), | 31 promise->reject(static_cast<MediaKeys::Exception>(result->exception), |
| 32 result->system_code, result->error_message); | 32 result->system_code, 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(NOT_SUPPORTED_ERROR, 0, "Mojo CDM creation failed."); | 109 promise->reject(NOT_SUPPORTED_ERROR, 0, "Mojo CDM creation failed."); |
| 110 return; | 110 return; |
| 111 } | 111 } |
| 112 | 112 |
| 113 // Otherwise, set an error handler to catch the connection error. | 113 // Otherwise, set an error handler to catch the connection error. |
| 114 remote_cdm_.set_connection_error_handler( | 114 remote_cdm_.set_connection_error_handler( |
| 115 base::Bind(&MojoCdm::OnConnectionError, base::Unretained(this))); | 115 base::Bind(&MojoCdm::OnConnectionError, base::Unretained(this))); |
| 116 | 116 |
| 117 pending_init_promise_ = std::move(promise); | 117 pending_init_promise_ = std::move(promise); |
| 118 | 118 |
| 119 remote_cdm_->Initialize( | 119 remote_cdm_->Initialize( |
| 120 key_system, security_origin.spec(), mojom::CdmConfig::From(cdm_config), | 120 key_system, security_origin.spec(), mojom::CdmConfig::From(cdm_config), |
| 121 base::Bind(&MojoCdm::OnCdmInitialized, base::Unretained(this))); | 121 base::Bind(&MojoCdm::OnCdmInitialized, base::Unretained(this))); |
| 122 } | 122 } |
| 123 | 123 |
| 124 void MojoCdm::OnConnectionError() { | 124 void MojoCdm::OnConnectionError() { |
| 125 LOG(ERROR) << "Remote CDM connection error."; | 125 LOG(ERROR) << "Remote CDM connection error."; |
| 126 DCHECK(thread_checker_.CalledOnValidThread()); | 126 DCHECK(thread_checker_.CalledOnValidThread()); |
| 127 | 127 |
| 128 // We only handle initial connection error. | 128 // Handle initial connection error. |
| 129 if (!pending_init_promise_) | 129 if (pending_init_promise_) { |
| 130 return; | 130 pending_init_promise_->reject(NOT_SUPPORTED_ERROR, 0, |
| 131 "Mojo CDM creation failed."); |
| 132 pending_init_promise_.reset(); |
| 133 } |
| 131 | 134 |
| 132 pending_init_promise_->reject(NOT_SUPPORTED_ERROR, 0, | 135 cdm_session_tracker_.CloseRemainingSessions(session_closed_cb_); |
| 133 "Mojo CDM creation failed."); | |
| 134 pending_init_promise_.reset(); | |
| 135 } | 136 } |
| 136 | 137 |
| 137 void MojoCdm::SetServerCertificate(const std::vector<uint8_t>& certificate, | 138 void MojoCdm::SetServerCertificate(const std::vector<uint8_t>& certificate, |
| 138 std::unique_ptr<SimpleCdmPromise> promise) { | 139 std::unique_ptr<SimpleCdmPromise> promise) { |
| 139 DVLOG(2) << __FUNCTION__; | 140 DVLOG(2) << __FUNCTION__; |
| 140 DCHECK(thread_checker_.CalledOnValidThread()); | 141 DCHECK(thread_checker_.CalledOnValidThread()); |
| 141 | 142 |
| 142 remote_cdm_->SetServerCertificate( | 143 remote_cdm_->SetServerCertificate( |
| 143 certificate, base::Bind(&MojoCdm::OnSimpleCdmPromiseResult, | 144 certificate, base::Bind(&MojoCdm::OnSimpleCdmPromiseResult, |
| 144 base::Unretained(this), base::Passed(&promise))); | 145 base::Unretained(this), base::Passed(&promise))); |
| (...skipping 56 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 19 matching lines...) Expand all Loading... |
| 241 DCHECK(thread_checker_.CalledOnValidThread()); | 242 DCHECK(thread_checker_.CalledOnValidThread()); |
| 242 | 243 |
| 243 session_message_cb_.Run( | 244 session_message_cb_.Run( |
| 244 session_id, static_cast<MediaKeys::MessageType>(message_type), message); | 245 session_id, static_cast<MediaKeys::MessageType>(message_type), message); |
| 245 } | 246 } |
| 246 | 247 |
| 247 void MojoCdm::OnSessionClosed(const std::string& session_id) { | 248 void MojoCdm::OnSessionClosed(const std::string& session_id) { |
| 248 DVLOG(2) << __FUNCTION__; | 249 DVLOG(2) << __FUNCTION__; |
| 249 DCHECK(thread_checker_.CalledOnValidThread()); | 250 DCHECK(thread_checker_.CalledOnValidThread()); |
| 250 | 251 |
| 252 cdm_session_tracker_.RemoveSession(session_id); |
| 251 session_closed_cb_.Run(session_id); | 253 session_closed_cb_.Run(session_id); |
| 252 } | 254 } |
| 253 | 255 |
| 254 void MojoCdm::OnSessionKeysChange( | 256 void MojoCdm::OnSessionKeysChange( |
| 255 const std::string& session_id, | 257 const std::string& session_id, |
| 256 bool has_additional_usable_key, | 258 bool has_additional_usable_key, |
| 257 std::vector<mojom::CdmKeyInformationPtr> keys_info) { | 259 std::vector<mojom::CdmKeyInformationPtr> keys_info) { |
| 258 DVLOG(2) << __FUNCTION__; | 260 DVLOG(2) << __FUNCTION__; |
| 259 DCHECK(thread_checker_.CalledOnValidThread()); | 261 DCHECK(thread_checker_.CalledOnValidThread()); |
| 260 | 262 |
| 261 // TODO(jrummell): Handling resume playback should be done in the media | 263 // TODO(jrummell): Handling resume playback should be done in the media |
| 262 // player, not in the Decryptors. http://crbug.com/413413. | 264 // player, not in the Decryptors. http://crbug.com/413413. |
| 263 if (has_additional_usable_key) { | 265 if (has_additional_usable_key) { |
| 264 base::AutoLock auto_lock(lock_); | 266 base::AutoLock auto_lock(lock_); |
| 265 if (decryptor_) { | 267 if (decryptor_) { |
| 266 DCHECK(decryptor_task_runner_); | 268 DCHECK(decryptor_task_runner_); |
| 267 decryptor_task_runner_->PostTask( | 269 decryptor_task_runner_->PostTask( |
| 268 FROM_HERE, | 270 FROM_HERE, |
| 269 base::Bind(&MojoCdm::OnKeyAdded, weak_factory_.GetWeakPtr())); | 271 base::Bind(&MojoCdm::OnKeyAdded, weak_factory_.GetWeakPtr())); |
| 270 } | 272 } |
| 271 } | 273 } |
| 272 | 274 |
| 273 media::CdmKeysInfo key_data; | 275 CdmKeysInfo key_data; |
| 274 key_data.reserve(keys_info.size()); | 276 key_data.reserve(keys_info.size()); |
| 275 for (size_t i = 0; i < keys_info.size(); ++i) { | 277 for (size_t i = 0; i < keys_info.size(); ++i) { |
| 276 key_data.push_back( | 278 key_data.push_back( |
| 277 keys_info[i].To<std::unique_ptr<media::CdmKeyInformation>>().release()); | 279 keys_info[i].To<std::unique_ptr<CdmKeyInformation>>().release()); |
| 278 } | 280 } |
| 279 session_keys_change_cb_.Run(session_id, has_additional_usable_key, | 281 session_keys_change_cb_.Run(session_id, has_additional_usable_key, |
| 280 std::move(key_data)); | 282 std::move(key_data)); |
| 281 } | 283 } |
| 282 | 284 |
| 283 void MojoCdm::OnSessionExpirationUpdate(const std::string& session_id, | 285 void MojoCdm::OnSessionExpirationUpdate(const std::string& session_id, |
| 284 double new_expiry_time_sec) { | 286 double new_expiry_time_sec) { |
| 285 DVLOG(2) << __FUNCTION__; | 287 DVLOG(2) << __FUNCTION__; |
| 286 DCHECK(thread_checker_.CalledOnValidThread()); | 288 DCHECK(thread_checker_.CalledOnValidThread()); |
| 287 | 289 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 if (result->success) | 330 if (result->success) |
| 329 promise->resolve(); | 331 promise->resolve(); |
| 330 else | 332 else |
| 331 RejectPromise(std::move(promise), std::move(result)); | 333 RejectPromise(std::move(promise), std::move(result)); |
| 332 } | 334 } |
| 333 | 335 |
| 334 void MojoCdm::OnNewSessionCdmPromiseResult( | 336 void MojoCdm::OnNewSessionCdmPromiseResult( |
| 335 std::unique_ptr<NewSessionCdmPromise> promise, | 337 std::unique_ptr<NewSessionCdmPromise> promise, |
| 336 mojom::CdmPromiseResultPtr result, | 338 mojom::CdmPromiseResultPtr result, |
| 337 const std::string& session_id) { | 339 const std::string& session_id) { |
| 338 if (result->success) | 340 if (result->success) { |
| 341 cdm_session_tracker_.AddSession(session_id); |
| 339 promise->resolve(session_id); | 342 promise->resolve(session_id); |
| 340 else | 343 } else |
| 341 RejectPromise(std::move(promise), std::move(result)); | 344 RejectPromise(std::move(promise), std::move(result)); |
| 342 } | 345 } |
| 343 | 346 |
| 344 } // namespace media | 347 } // namespace media |
| OLD | NEW |