| 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/services/mojo_cdm.h" | 5 #include "media/mojo/services/mojo_cdm.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
| 15 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
| 16 #include "media/base/cdm_context.h" | 16 #include "media/base/cdm_context.h" |
| 17 #include "media/base/cdm_key_information.h" | 17 #include "media/base/cdm_key_information.h" |
| 18 #include "media/base/cdm_promise.h" | 18 #include "media/base/cdm_promise.h" |
| 19 #include "media/mojo/common/media_type_converters.h" | 19 #include "media/mojo/common/media_type_converters.h" |
| 20 #include "media/mojo/interfaces/decryptor.mojom.h" | 20 #include "media/mojo/interfaces/decryptor.mojom.h" |
| 21 #include "media/mojo/services/mojo_decryptor.h" | 21 #include "media/mojo/services/mojo_decryptor.h" |
| 22 #include "services/shell/public/cpp/connect.h" | 22 #include "services/shell/public/cpp/connect.h" |
| 23 #include "services/shell/public/interfaces/interface_provider.mojom.h" | 23 #include "services/shell/public/interfaces/interface_provider.mojom.h" |
| 24 #include "url/gurl.h" | 24 #include "url/gurl.h" |
| 25 | 25 |
| 26 namespace media { | 26 namespace media { |
| 27 | 27 |
| 28 template <typename PromiseType> | 28 template <typename PromiseType> |
| 29 static void RejectPromise(std::unique_ptr<PromiseType> promise, | 29 static void RejectPromise(std::unique_ptr<PromiseType> promise, |
| 30 interfaces::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 media::CdmConfig& cdm_config, |
| 40 interfaces::ContentDecryptionModulePtr remote_cdm, | 40 mojom::ContentDecryptionModulePtr remote_cdm, |
| 41 const media::SessionMessageCB& session_message_cb, | 41 const media::SessionMessageCB& session_message_cb, |
| 42 const media::SessionClosedCB& session_closed_cb, | 42 const media::SessionClosedCB& session_closed_cb, |
| 43 const media::LegacySessionErrorCB& legacy_session_error_cb, | 43 const media::LegacySessionErrorCB& legacy_session_error_cb, |
| 44 const media::SessionKeysChangeCB& session_keys_change_cb, | 44 const media::SessionKeysChangeCB& session_keys_change_cb, |
| 45 const media::SessionExpirationUpdateCB& session_expiration_update_cb, | 45 const media::SessionExpirationUpdateCB& session_expiration_update_cb, |
| 46 const media::CdmCreatedCB& cdm_created_cb) { | 46 const media::CdmCreatedCB& cdm_created_cb) { |
| 47 scoped_refptr<MojoCdm> mojo_cdm( | 47 scoped_refptr<MojoCdm> mojo_cdm( |
| 48 new MojoCdm(std::move(remote_cdm), session_message_cb, session_closed_cb, | 48 new MojoCdm(std::move(remote_cdm), session_message_cb, session_closed_cb, |
| 49 legacy_session_error_cb, session_keys_change_cb, | 49 legacy_session_error_cb, session_keys_change_cb, |
| 50 session_expiration_update_cb)); | 50 session_expiration_update_cb)); |
| 51 | 51 |
| 52 // |mojo_cdm| ownership is passed to the promise. | 52 // |mojo_cdm| ownership is passed to the promise. |
| 53 std::unique_ptr<CdmInitializedPromise> promise( | 53 std::unique_ptr<CdmInitializedPromise> promise( |
| 54 new CdmInitializedPromise(cdm_created_cb, mojo_cdm)); | 54 new CdmInitializedPromise(cdm_created_cb, mojo_cdm)); |
| 55 | 55 |
| 56 mojo_cdm->InitializeCdm(key_system, security_origin, cdm_config, | 56 mojo_cdm->InitializeCdm(key_system, security_origin, cdm_config, |
| 57 std::move(promise)); | 57 std::move(promise)); |
| 58 } | 58 } |
| 59 | 59 |
| 60 MojoCdm::MojoCdm(interfaces::ContentDecryptionModulePtr remote_cdm, | 60 MojoCdm::MojoCdm(mojom::ContentDecryptionModulePtr remote_cdm, |
| 61 const SessionMessageCB& session_message_cb, | 61 const SessionMessageCB& session_message_cb, |
| 62 const SessionClosedCB& session_closed_cb, | 62 const SessionClosedCB& session_closed_cb, |
| 63 const LegacySessionErrorCB& legacy_session_error_cb, | 63 const LegacySessionErrorCB& legacy_session_error_cb, |
| 64 const SessionKeysChangeCB& session_keys_change_cb, | 64 const SessionKeysChangeCB& session_keys_change_cb, |
| 65 const SessionExpirationUpdateCB& session_expiration_update_cb) | 65 const SessionExpirationUpdateCB& session_expiration_update_cb) |
| 66 : remote_cdm_(std::move(remote_cdm)), | 66 : remote_cdm_(std::move(remote_cdm)), |
| 67 binding_(this), | 67 binding_(this), |
| 68 cdm_id_(CdmContext::kInvalidCdmId), | 68 cdm_id_(CdmContext::kInvalidCdmId), |
| 69 session_message_cb_(session_message_cb), | 69 session_message_cb_(session_message_cb), |
| 70 session_closed_cb_(session_closed_cb), | 70 session_closed_cb_(session_closed_cb), |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 return; | 115 return; |
| 116 } | 116 } |
| 117 | 117 |
| 118 // Otherwise, set an error handler to catch the connection error. | 118 // Otherwise, set an error handler to catch the connection error. |
| 119 remote_cdm_.set_connection_error_handler( | 119 remote_cdm_.set_connection_error_handler( |
| 120 base::Bind(&MojoCdm::OnConnectionError, base::Unretained(this))); | 120 base::Bind(&MojoCdm::OnConnectionError, base::Unretained(this))); |
| 121 | 121 |
| 122 pending_init_promise_ = std::move(promise); | 122 pending_init_promise_ = std::move(promise); |
| 123 | 123 |
| 124 remote_cdm_->Initialize( | 124 remote_cdm_->Initialize( |
| 125 key_system, security_origin.spec(), | 125 key_system, security_origin.spec(), mojom::CdmConfig::From(cdm_config), |
| 126 interfaces::CdmConfig::From(cdm_config), | |
| 127 base::Bind(&MojoCdm::OnCdmInitialized, base::Unretained(this))); | 126 base::Bind(&MojoCdm::OnCdmInitialized, base::Unretained(this))); |
| 128 } | 127 } |
| 129 | 128 |
| 130 void MojoCdm::OnConnectionError() { | 129 void MojoCdm::OnConnectionError() { |
| 131 LOG(ERROR) << "Remote CDM connection error."; | 130 LOG(ERROR) << "Remote CDM connection error."; |
| 132 DCHECK(thread_checker_.CalledOnValidThread()); | 131 DCHECK(thread_checker_.CalledOnValidThread()); |
| 133 | 132 |
| 134 // We only handle initial connection error. | 133 // We only handle initial connection error. |
| 135 if (!pending_init_promise_) | 134 if (!pending_init_promise_) |
| 136 return; | 135 return; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 153 | 152 |
| 154 void MojoCdm::CreateSessionAndGenerateRequest( | 153 void MojoCdm::CreateSessionAndGenerateRequest( |
| 155 SessionType session_type, | 154 SessionType session_type, |
| 156 EmeInitDataType init_data_type, | 155 EmeInitDataType init_data_type, |
| 157 const std::vector<uint8_t>& init_data, | 156 const std::vector<uint8_t>& init_data, |
| 158 std::unique_ptr<NewSessionCdmPromise> promise) { | 157 std::unique_ptr<NewSessionCdmPromise> promise) { |
| 159 DVLOG(2) << __FUNCTION__; | 158 DVLOG(2) << __FUNCTION__; |
| 160 DCHECK(thread_checker_.CalledOnValidThread()); | 159 DCHECK(thread_checker_.CalledOnValidThread()); |
| 161 | 160 |
| 162 remote_cdm_->CreateSessionAndGenerateRequest( | 161 remote_cdm_->CreateSessionAndGenerateRequest( |
| 163 static_cast<interfaces::ContentDecryptionModule::SessionType>( | 162 static_cast<mojom::ContentDecryptionModule::SessionType>(session_type), |
| 164 session_type), | 163 static_cast<mojom::ContentDecryptionModule::InitDataType>(init_data_type), |
| 165 static_cast<interfaces::ContentDecryptionModule::InitDataType>( | |
| 166 init_data_type), | |
| 167 mojo::Array<uint8_t>::From(init_data), | 164 mojo::Array<uint8_t>::From(init_data), |
| 168 base::Bind(&MojoCdm::OnPromiseResult<std::string>, base::Unretained(this), | 165 base::Bind(&MojoCdm::OnPromiseResult<std::string>, base::Unretained(this), |
| 169 base::Passed(&promise))); | 166 base::Passed(&promise))); |
| 170 } | 167 } |
| 171 | 168 |
| 172 void MojoCdm::LoadSession(SessionType session_type, | 169 void MojoCdm::LoadSession(SessionType session_type, |
| 173 const std::string& session_id, | 170 const std::string& session_id, |
| 174 std::unique_ptr<NewSessionCdmPromise> promise) { | 171 std::unique_ptr<NewSessionCdmPromise> promise) { |
| 175 DVLOG(2) << __FUNCTION__; | 172 DVLOG(2) << __FUNCTION__; |
| 176 DCHECK(thread_checker_.CalledOnValidThread()); | 173 DCHECK(thread_checker_.CalledOnValidThread()); |
| 177 | 174 |
| 178 remote_cdm_->LoadSession( | 175 remote_cdm_->LoadSession( |
| 179 static_cast<interfaces::ContentDecryptionModule::SessionType>( | 176 static_cast<mojom::ContentDecryptionModule::SessionType>(session_type), |
| 180 session_type), | |
| 181 session_id, base::Bind(&MojoCdm::OnPromiseResult<std::string>, | 177 session_id, base::Bind(&MojoCdm::OnPromiseResult<std::string>, |
| 182 base::Unretained(this), base::Passed(&promise))); | 178 base::Unretained(this), base::Passed(&promise))); |
| 183 } | 179 } |
| 184 | 180 |
| 185 void MojoCdm::UpdateSession(const std::string& session_id, | 181 void MojoCdm::UpdateSession(const std::string& session_id, |
| 186 const std::vector<uint8_t>& response, | 182 const std::vector<uint8_t>& response, |
| 187 std::unique_ptr<SimpleCdmPromise> promise) { | 183 std::unique_ptr<SimpleCdmPromise> promise) { |
| 188 DVLOG(2) << __FUNCTION__; | 184 DVLOG(2) << __FUNCTION__; |
| 189 DCHECK(thread_checker_.CalledOnValidThread()); | 185 DCHECK(thread_checker_.CalledOnValidThread()); |
| 190 | 186 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 } | 233 } |
| 238 | 234 |
| 239 int MojoCdm::GetCdmId() const { | 235 int MojoCdm::GetCdmId() const { |
| 240 base::AutoLock auto_lock(lock_); | 236 base::AutoLock auto_lock(lock_); |
| 241 // Can be called on a different thread. | 237 // Can be called on a different thread. |
| 242 DCHECK_NE(CdmContext::kInvalidCdmId, cdm_id_); | 238 DCHECK_NE(CdmContext::kInvalidCdmId, cdm_id_); |
| 243 return cdm_id_; | 239 return cdm_id_; |
| 244 } | 240 } |
| 245 | 241 |
| 246 void MojoCdm::OnSessionMessage(const mojo::String& session_id, | 242 void MojoCdm::OnSessionMessage(const mojo::String& session_id, |
| 247 interfaces::CdmMessageType message_type, | 243 mojom::CdmMessageType message_type, |
| 248 mojo::Array<uint8_t> message, | 244 mojo::Array<uint8_t> message, |
| 249 const mojo::String& legacy_destination_url) { | 245 const mojo::String& legacy_destination_url) { |
| 250 DVLOG(2) << __FUNCTION__; | 246 DVLOG(2) << __FUNCTION__; |
| 251 DCHECK(thread_checker_.CalledOnValidThread()); | 247 DCHECK(thread_checker_.CalledOnValidThread()); |
| 252 | 248 |
| 253 GURL verified_gurl = GURL(legacy_destination_url.get()); | 249 GURL verified_gurl = GURL(legacy_destination_url.get()); |
| 254 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) { | 250 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) { |
| 255 DLOG(WARNING) << "SessionMessage destination_url is invalid : " | 251 DLOG(WARNING) << "SessionMessage destination_url is invalid : " |
| 256 << verified_gurl.possibly_invalid_spec(); | 252 << verified_gurl.possibly_invalid_spec(); |
| 257 verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. | 253 verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. |
| 258 } | 254 } |
| 259 | 255 |
| 260 session_message_cb_.Run(session_id, | 256 session_message_cb_.Run(session_id, |
| 261 static_cast<MediaKeys::MessageType>(message_type), | 257 static_cast<MediaKeys::MessageType>(message_type), |
| 262 message.storage(), verified_gurl); | 258 message.storage(), verified_gurl); |
| 263 } | 259 } |
| 264 | 260 |
| 265 void MojoCdm::OnSessionClosed(const mojo::String& session_id) { | 261 void MojoCdm::OnSessionClosed(const mojo::String& session_id) { |
| 266 DVLOG(2) << __FUNCTION__; | 262 DVLOG(2) << __FUNCTION__; |
| 267 DCHECK(thread_checker_.CalledOnValidThread()); | 263 DCHECK(thread_checker_.CalledOnValidThread()); |
| 268 | 264 |
| 269 session_closed_cb_.Run(session_id); | 265 session_closed_cb_.Run(session_id); |
| 270 } | 266 } |
| 271 | 267 |
| 272 void MojoCdm::OnLegacySessionError(const mojo::String& session_id, | 268 void MojoCdm::OnLegacySessionError(const mojo::String& session_id, |
| 273 interfaces::CdmException exception, | 269 mojom::CdmException exception, |
| 274 uint32_t system_code, | 270 uint32_t system_code, |
| 275 const mojo::String& error_message) { | 271 const mojo::String& error_message) { |
| 276 DVLOG(2) << __FUNCTION__; | 272 DVLOG(2) << __FUNCTION__; |
| 277 DCHECK(thread_checker_.CalledOnValidThread()); | 273 DCHECK(thread_checker_.CalledOnValidThread()); |
| 278 | 274 |
| 279 legacy_session_error_cb_.Run(session_id, | 275 legacy_session_error_cb_.Run(session_id, |
| 280 static_cast<MediaKeys::Exception>(exception), | 276 static_cast<MediaKeys::Exception>(exception), |
| 281 system_code, error_message); | 277 system_code, error_message); |
| 282 } | 278 } |
| 283 | 279 |
| 284 void MojoCdm::OnSessionKeysChange( | 280 void MojoCdm::OnSessionKeysChange( |
| 285 const mojo::String& session_id, | 281 const mojo::String& session_id, |
| 286 bool has_additional_usable_key, | 282 bool has_additional_usable_key, |
| 287 mojo::Array<interfaces::CdmKeyInformationPtr> keys_info) { | 283 mojo::Array<mojom::CdmKeyInformationPtr> keys_info) { |
| 288 DVLOG(2) << __FUNCTION__; | 284 DVLOG(2) << __FUNCTION__; |
| 289 DCHECK(thread_checker_.CalledOnValidThread()); | 285 DCHECK(thread_checker_.CalledOnValidThread()); |
| 290 | 286 |
| 291 // TODO(jrummell): Handling resume playback should be done in the media | 287 // TODO(jrummell): Handling resume playback should be done in the media |
| 292 // player, not in the Decryptors. http://crbug.com/413413. | 288 // player, not in the Decryptors. http://crbug.com/413413. |
| 293 if (has_additional_usable_key) { | 289 if (has_additional_usable_key) { |
| 294 base::AutoLock auto_lock(lock_); | 290 base::AutoLock auto_lock(lock_); |
| 295 if (decryptor_) { | 291 if (decryptor_) { |
| 296 DCHECK(decryptor_task_runner_); | 292 DCHECK(decryptor_task_runner_); |
| 297 decryptor_task_runner_->PostTask( | 293 decryptor_task_runner_->PostTask( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 312 | 308 |
| 313 void MojoCdm::OnSessionExpirationUpdate(const mojo::String& session_id, | 309 void MojoCdm::OnSessionExpirationUpdate(const mojo::String& session_id, |
| 314 double new_expiry_time_sec) { | 310 double new_expiry_time_sec) { |
| 315 DVLOG(2) << __FUNCTION__; | 311 DVLOG(2) << __FUNCTION__; |
| 316 DCHECK(thread_checker_.CalledOnValidThread()); | 312 DCHECK(thread_checker_.CalledOnValidThread()); |
| 317 | 313 |
| 318 session_expiration_update_cb_.Run( | 314 session_expiration_update_cb_.Run( |
| 319 session_id, base::Time::FromDoubleT(new_expiry_time_sec)); | 315 session_id, base::Time::FromDoubleT(new_expiry_time_sec)); |
| 320 } | 316 } |
| 321 | 317 |
| 322 void MojoCdm::OnCdmInitialized(interfaces::CdmPromiseResultPtr result, | 318 void MojoCdm::OnCdmInitialized(mojom::CdmPromiseResultPtr result, |
| 323 int cdm_id, | 319 int cdm_id, |
| 324 interfaces::DecryptorPtr decryptor) { | 320 mojom::DecryptorPtr decryptor) { |
| 325 DVLOG(2) << __FUNCTION__ << " cdm_id: " << cdm_id; | 321 DVLOG(2) << __FUNCTION__ << " cdm_id: " << cdm_id; |
| 326 DCHECK(thread_checker_.CalledOnValidThread()); | 322 DCHECK(thread_checker_.CalledOnValidThread()); |
| 327 DCHECK(pending_init_promise_); | 323 DCHECK(pending_init_promise_); |
| 328 | 324 |
| 329 if (!result->success) { | 325 if (!result->success) { |
| 330 RejectPromise(std::move(pending_init_promise_), std::move(result)); | 326 RejectPromise(std::move(pending_init_promise_), std::move(result)); |
| 331 return; | 327 return; |
| 332 } | 328 } |
| 333 | 329 |
| 334 { | 330 { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 346 base::AutoLock auto_lock(lock_); | 342 base::AutoLock auto_lock(lock_); |
| 347 | 343 |
| 348 DCHECK(decryptor_task_runner_); | 344 DCHECK(decryptor_task_runner_); |
| 349 DCHECK(decryptor_task_runner_->BelongsToCurrentThread()); | 345 DCHECK(decryptor_task_runner_->BelongsToCurrentThread()); |
| 350 DCHECK(decryptor_); | 346 DCHECK(decryptor_); |
| 351 | 347 |
| 352 decryptor_->OnKeyAdded(); | 348 decryptor_->OnKeyAdded(); |
| 353 } | 349 } |
| 354 | 350 |
| 355 } // namespace media | 351 } // namespace media |
| OLD | NEW |