Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "media/base/android/media_drm_bridge.h" | 5 #include "media/base/android/media_drm_bridge.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/android/build_info.h" | 9 #include "base/android/build_info.h" |
| 10 #include "base/android/jni_array.h" | 10 #include "base/android/jni_array.h" |
| 11 #include "base/android/jni_string.h" | 11 #include "base/android/jni_string.h" |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
| 14 #include "base/containers/hash_tables.h" | 14 #include "base/containers/hash_tables.h" |
| 15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
| 16 #include "base/location.h" | 16 #include "base/location.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
| 20 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
| 21 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| 22 #include "base/sys_byteorder.h" | 22 #include "base/sys_byteorder.h" |
| 23 #include "base/sys_info.h" | 23 #include "base/sys_info.h" |
| 24 #include "base/thread_task_runner_handle.h" | 24 #include "base/thread_task_runner_handle.h" |
| 25 #include "jni/MediaDrmBridge_jni.h" | 25 #include "jni/MediaDrmBridge_jni.h" |
| 26 #include "media/base/android/media_client_android.h" | 26 #include "media/base/android/media_client_android.h" |
| 27 #include "media/base/android/media_drm_bridge_delegate.h" | 27 #include "media/base/android/media_drm_bridge_delegate.h" |
| 28 #include "media/base/android/media_task_runner.h" | |
| 29 #include "media/base/cdm_key_information.h" | 28 #include "media/base/cdm_key_information.h" |
| 30 | 29 |
| 31 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. | 30 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. |
| 32 | 31 |
| 33 using base::android::AttachCurrentThread; | 32 using base::android::AttachCurrentThread; |
| 34 using base::android::ConvertUTF8ToJavaString; | 33 using base::android::ConvertUTF8ToJavaString; |
| 35 using base::android::ConvertJavaStringToUTF8; | 34 using base::android::ConvertJavaStringToUTF8; |
| 36 using base::android::JavaByteArrayToByteVector; | 35 using base::android::JavaByteArrayToByteVector; |
| 37 using base::android::ScopedJavaGlobalRef; | 36 using base::android::ScopedJavaGlobalRef; |
| 38 using base::android::ScopedJavaLocalRef; | 37 using base::android::ScopedJavaLocalRef; |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 case MediaDrmBridge::SECURITY_LEVEL_1: | 206 case MediaDrmBridge::SECURITY_LEVEL_1: |
| 208 return "L1"; | 207 return "L1"; |
| 209 case MediaDrmBridge::SECURITY_LEVEL_3: | 208 case MediaDrmBridge::SECURITY_LEVEL_3: |
| 210 return "L3"; | 209 return "L3"; |
| 211 } | 210 } |
| 212 return ""; | 211 return ""; |
| 213 } | 212 } |
| 214 | 213 |
| 215 } // namespace | 214 } // namespace |
| 216 | 215 |
| 217 MediaDrmBridge::~MediaDrmBridge() { | |
| 218 DVLOG(1) << __FUNCTION__; | |
| 219 | |
| 220 DCHECK(!use_media_thread_ || GetMediaTaskRunner()->BelongsToCurrentThread()); | |
| 221 | |
| 222 player_tracker_.NotifyCdmUnset(); | |
| 223 } | |
| 224 | |
| 225 void MediaDrmBridge::DeleteOnCorrectThread() { | |
| 226 DCHECK(task_runner_->BelongsToCurrentThread()); | |
| 227 DVLOG(1) << __FUNCTION__; | |
| 228 | |
| 229 JNIEnv* env = AttachCurrentThread(); | |
| 230 if (!j_media_drm_.is_null()) | |
| 231 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj()); | |
| 232 | |
| 233 // After the call to Java_MediaDrmBridge_destroy() Java won't call native | |
| 234 // methods anymore, this is ensured by MediaDrmBridge.java. | |
| 235 | |
| 236 // CdmPromiseAdapter must be destroyed on the UI thread. | |
| 237 cdm_promise_adapter_.reset(); | |
| 238 | |
| 239 // Post deletion onto Media thread if we use it. | |
| 240 if (use_media_thread_) { | |
| 241 weak_factory_.InvalidateWeakPtrs(); | |
| 242 GetMediaTaskRunner()->DeleteSoon(FROM_HERE, this); | |
| 243 } else { | |
| 244 delete this; | |
| 245 } | |
| 246 } | |
| 247 | |
| 248 // static | 216 // static |
| 249 bool MediaDrmBridge::IsAvailable() { | 217 bool MediaDrmBridge::IsAvailable() { |
| 250 if (base::android::BuildInfo::GetInstance()->sdk_int() < 19) | 218 if (base::android::BuildInfo::GetInstance()->sdk_int() < 19) |
| 251 return false; | 219 return false; |
| 252 | 220 |
| 253 int32 os_major_version = 0; | 221 int32 os_major_version = 0; |
| 254 int32 os_minor_version = 0; | 222 int32 os_minor_version = 0; |
| 255 int32 os_bugfix_version = 0; | 223 int32 os_bugfix_version = 0; |
| 256 base::SysInfo::OperatingSystemVersionNumbers( | 224 base::SysInfo::OperatingSystemVersionNumbers( |
| 257 &os_major_version, &os_minor_version, &os_bugfix_version); | 225 &os_major_version, &os_minor_version, &os_bugfix_version); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 279 DCHECK(!key_system.empty() && !container_mime_type.empty()); | 247 DCHECK(!key_system.empty() && !container_mime_type.empty()); |
| 280 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); | 248 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); |
| 281 } | 249 } |
| 282 | 250 |
| 283 // static | 251 // static |
| 284 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { | 252 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { |
| 285 return g_key_system_manager.Get().GetPlatformKeySystemNames(); | 253 return g_key_system_manager.Get().GetPlatformKeySystemNames(); |
| 286 } | 254 } |
| 287 | 255 |
| 288 // static | 256 // static |
| 289 ScopedMediaDrmBridgePtr MediaDrmBridge::Create( | 257 scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create( |
| 290 const std::string& key_system, | 258 const std::string& key_system, |
| 291 const SessionMessageCB& session_message_cb, | 259 const SessionMessageCB& session_message_cb, |
| 292 const SessionClosedCB& session_closed_cb, | 260 const SessionClosedCB& session_closed_cb, |
| 293 const LegacySessionErrorCB& legacy_session_error_cb, | 261 const LegacySessionErrorCB& legacy_session_error_cb, |
| 294 const SessionKeysChangeCB& session_keys_change_cb, | 262 const SessionKeysChangeCB& session_keys_change_cb, |
| 295 const SessionExpirationUpdateCB& session_expiration_update_cb) { | 263 const SessionExpirationUpdateCB& session_expiration_update_cb) { |
| 296 DVLOG(1) << __FUNCTION__; | 264 DVLOG(1) << __FUNCTION__; |
| 297 | 265 |
| 298 scoped_ptr<MediaDrmBridge, BrowserCdmDeleter> media_drm_bridge; | |
| 299 if (!IsAvailable()) | 266 if (!IsAvailable()) |
| 300 return media_drm_bridge.Pass(); | 267 return nullptr; |
| 301 | 268 |
| 302 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); | 269 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); |
| 303 if (scheme_uuid.empty()) | 270 if (scheme_uuid.empty()) |
| 304 return media_drm_bridge.Pass(); | 271 return nullptr; |
| 305 | 272 |
| 306 media_drm_bridge.reset( | 273 scoped_refptr<MediaDrmBridge> media_drm_bridge( |
| 307 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, | 274 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, |
| 308 legacy_session_error_cb, session_keys_change_cb, | 275 legacy_session_error_cb, session_keys_change_cb, |
| 309 session_expiration_update_cb)); | 276 session_expiration_update_cb)); |
| 310 | 277 |
| 311 if (media_drm_bridge->j_media_drm_.is_null()) | 278 if (media_drm_bridge->j_media_drm_.is_null()) |
| 312 media_drm_bridge.reset(); | 279 media_drm_bridge = nullptr; |
| 313 | 280 |
| 314 return media_drm_bridge.Pass(); | 281 return media_drm_bridge; |
| 315 } | 282 } |
| 316 | 283 |
| 317 // static | 284 // static |
| 318 ScopedMediaDrmBridgePtr MediaDrmBridge::CreateWithoutSessionSupport( | 285 scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport( |
| 319 const std::string& key_system) { | 286 const std::string& key_system) { |
| 320 return MediaDrmBridge::Create( | 287 return MediaDrmBridge::Create( |
| 321 key_system, SessionMessageCB(), SessionClosedCB(), LegacySessionErrorCB(), | 288 key_system, SessionMessageCB(), SessionClosedCB(), LegacySessionErrorCB(), |
| 322 SessionKeysChangeCB(), SessionExpirationUpdateCB()); | 289 SessionKeysChangeCB(), SessionExpirationUpdateCB()); |
| 323 } | 290 } |
| 324 | 291 |
| 325 base::WeakPtr<MediaDrmBridge> MediaDrmBridge::WeakPtr() { | |
| 326 return weak_factory_.GetWeakPtr(); | |
| 327 } | |
| 328 | |
| 329 void MediaDrmBridge::SetServerCertificate( | 292 void MediaDrmBridge::SetServerCertificate( |
| 330 const std::vector<uint8_t>& certificate, | 293 const std::vector<uint8_t>& certificate, |
| 331 scoped_ptr<media::SimpleCdmPromise> promise) { | 294 scoped_ptr<media::SimpleCdmPromise> promise) { |
| 332 DVLOG(2) << __FUNCTION__; | 295 DVLOG(2) << __FUNCTION__; |
| 333 | 296 |
| 334 DCHECK(!certificate.empty()); | 297 DCHECK(!certificate.empty()); |
| 335 | 298 |
| 336 JNIEnv* env = AttachCurrentThread(); | 299 JNIEnv* env = AttachCurrentThread(); |
| 337 ScopedJavaLocalRef<jbyteArray> j_certificate; | 300 ScopedJavaLocalRef<jbyteArray> j_certificate; |
| 338 if (Java_MediaDrmBridge_setServerCertificate(env, j_media_drm_.obj(), | 301 if (Java_MediaDrmBridge_setServerCertificate(env, j_media_drm_.obj(), |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 | 408 |
| 446 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; | 409 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; |
| 447 promise->reject(NOT_SUPPORTED_ERROR, 0, "RemoveSession() is not supported."); | 410 promise->reject(NOT_SUPPORTED_ERROR, 0, "RemoveSession() is not supported."); |
| 448 } | 411 } |
| 449 | 412 |
| 450 CdmContext* MediaDrmBridge::GetCdmContext() { | 413 CdmContext* MediaDrmBridge::GetCdmContext() { |
| 451 NOTREACHED(); | 414 NOTREACHED(); |
| 452 return nullptr; | 415 return nullptr; |
| 453 } | 416 } |
| 454 | 417 |
| 418 void MediaDrmBridge::DeleteOnCorrectThread() const { | |
| 419 DVLOG(1) << __FUNCTION__; | |
| 420 | |
| 421 if (!task_runner_->BelongsToCurrentThread()) { | |
| 422 // When DeleteSoon returns false, |this| will be leaked, which is okay. | |
| 423 task_runner_->DeleteSoon(FROM_HERE, this); | |
| 424 } else { | |
| 425 delete this; | |
| 426 } | |
| 427 } | |
| 428 | |
| 455 int MediaDrmBridge::RegisterPlayer(const base::Closure& new_key_cb, | 429 int MediaDrmBridge::RegisterPlayer(const base::Closure& new_key_cb, |
| 456 const base::Closure& cdm_unset_cb) { | 430 const base::Closure& cdm_unset_cb) { |
| 457 DCHECK(!use_media_thread_ || GetMediaTaskRunner()->BelongsToCurrentThread()); | 431 // |player_tracker_| can be accessed from any thread. |
| 458 return player_tracker_.RegisterPlayer(new_key_cb, cdm_unset_cb); | 432 return player_tracker_.RegisterPlayer(new_key_cb, cdm_unset_cb); |
| 459 } | 433 } |
| 460 | 434 |
| 461 void MediaDrmBridge::UnregisterPlayer(int registration_id) { | 435 void MediaDrmBridge::UnregisterPlayer(int registration_id) { |
| 462 DCHECK(!use_media_thread_ || GetMediaTaskRunner()->BelongsToCurrentThread()); | 436 // |player_tracker_| can be accessed from any thread. |
| 463 player_tracker_.UnregisterPlayer(registration_id); | 437 player_tracker_.UnregisterPlayer(registration_id); |
| 464 } | 438 } |
| 465 | 439 |
| 466 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { | 440 bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { |
| 467 if (security_level != SECURITY_LEVEL_NONE && | 441 if (security_level != SECURITY_LEVEL_NONE && |
| 468 !std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid)) { | 442 !std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid)) { |
| 469 NOTREACHED() << "Widevine security level " << security_level | 443 NOTREACHED() << "Widevine security level " << security_level |
| 470 << "used with another key system"; | 444 << "used with another key system"; |
| 471 return false; | 445 return false; |
| 472 } | 446 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 | 494 |
| 521 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { | 495 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { |
| 522 DCHECK(task_runner_->BelongsToCurrentThread()); | 496 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 523 | 497 |
| 524 JNIEnv* env = AttachCurrentThread(); | 498 JNIEnv* env = AttachCurrentThread(); |
| 525 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); | 499 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); |
| 526 } | 500 } |
| 527 | 501 |
| 528 void MediaDrmBridge::SetMediaCryptoReadyCB( | 502 void MediaDrmBridge::SetMediaCryptoReadyCB( |
| 529 const MediaCryptoReadyCB& media_crypto_ready_cb) { | 503 const MediaCryptoReadyCB& media_crypto_ready_cb) { |
| 530 DCHECK(task_runner_->BelongsToCurrentThread()); | 504 if (!task_runner_->BelongsToCurrentThread()) { |
| 505 task_runner_->PostTask( | |
| 506 FROM_HERE, | |
| 507 base::Bind(&MediaDrmBridge::SetMediaCryptoReadyCB, | |
| 508 weak_factory_.GetWeakPtr(), media_crypto_ready_cb)); | |
| 509 return; | |
| 510 } | |
| 511 | |
| 531 DVLOG(1) << __FUNCTION__; | 512 DVLOG(1) << __FUNCTION__; |
| 532 | 513 |
| 533 if (media_crypto_ready_cb.is_null()) { | 514 if (media_crypto_ready_cb.is_null()) { |
| 534 media_crypto_ready_cb_.Reset(); | 515 media_crypto_ready_cb_.Reset(); |
| 535 return; | 516 return; |
| 536 } | 517 } |
| 537 | 518 |
| 538 DCHECK(media_crypto_ready_cb_.is_null()); | 519 DCHECK(media_crypto_ready_cb_.is_null()); |
| 539 | 520 |
| 540 // |media_crypto_ready_cb| is already bound to the correct thread | 521 // |media_crypto_ready_cb| is already bound to the correct thread |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 551 // only do minimal work and then post tasks to avoid reentrancy issues. | 532 // only do minimal work and then post tasks to avoid reentrancy issues. |
| 552 | 533 |
| 553 void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject j_media_drm) { | 534 void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject j_media_drm) { |
| 554 DCHECK(task_runner_->BelongsToCurrentThread()); | 535 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 555 DVLOG(1) << __FUNCTION__; | 536 DVLOG(1) << __FUNCTION__; |
| 556 | 537 |
| 557 if (media_crypto_ready_cb_.is_null()) | 538 if (media_crypto_ready_cb_.is_null()) |
| 558 return; | 539 return; |
| 559 | 540 |
| 560 task_runner_->PostTask( | 541 task_runner_->PostTask( |
| 561 FROM_HERE, base::Bind(&MediaDrmBridge::NotifyMediaCryptoReady, WeakPtr(), | 542 FROM_HERE, base::Bind(&MediaDrmBridge::NotifyMediaCryptoReady, |
| 543 weak_factory_.GetWeakPtr(), | |
| 562 base::ResetAndReturn(&media_crypto_ready_cb_))); | 544 base::ResetAndReturn(&media_crypto_ready_cb_))); |
| 563 } | 545 } |
| 564 | 546 |
| 565 void MediaDrmBridge::OnPromiseResolved(JNIEnv* env, | 547 void MediaDrmBridge::OnPromiseResolved(JNIEnv* env, |
| 566 jobject j_media_drm, | 548 jobject j_media_drm, |
| 567 jint j_promise_id) { | 549 jint j_promise_id) { |
| 568 task_runner_->PostTask(FROM_HERE, base::Bind(&MediaDrmBridge::ResolvePromise, | 550 task_runner_->PostTask(FROM_HERE, |
| 569 WeakPtr(), j_promise_id)); | 551 base::Bind(&MediaDrmBridge::ResolvePromise, |
| 552 weak_factory_.GetWeakPtr(), j_promise_id)); | |
| 570 } | 553 } |
| 571 | 554 |
| 572 void MediaDrmBridge::OnPromiseResolvedWithSession(JNIEnv* env, | 555 void MediaDrmBridge::OnPromiseResolvedWithSession(JNIEnv* env, |
| 573 jobject j_media_drm, | 556 jobject j_media_drm, |
| 574 jint j_promise_id, | 557 jint j_promise_id, |
| 575 jbyteArray j_session_id) { | 558 jbyteArray j_session_id) { |
| 576 task_runner_->PostTask( | 559 task_runner_->PostTask(FROM_HERE, |
| 577 FROM_HERE, | 560 base::Bind(&MediaDrmBridge::ResolvePromiseWithSession, |
| 578 base::Bind(&MediaDrmBridge::ResolvePromiseWithSession, WeakPtr(), | 561 weak_factory_.GetWeakPtr(), j_promise_id, |
| 579 j_promise_id, GetSessionId(env, j_session_id))); | 562 GetSessionId(env, j_session_id))); |
| 580 } | 563 } |
| 581 | 564 |
| 582 void MediaDrmBridge::OnPromiseRejected(JNIEnv* env, | 565 void MediaDrmBridge::OnPromiseRejected(JNIEnv* env, |
| 583 jobject j_media_drm, | 566 jobject j_media_drm, |
| 584 jint j_promise_id, | 567 jint j_promise_id, |
| 585 jstring j_error_message) { | 568 jstring j_error_message) { |
| 586 task_runner_->PostTask( | 569 task_runner_->PostTask( |
| 587 FROM_HERE, | 570 FROM_HERE, |
| 588 base::Bind(&MediaDrmBridge::RejectPromise, WeakPtr(), j_promise_id, | 571 base::Bind(&MediaDrmBridge::RejectPromise, weak_factory_.GetWeakPtr(), |
| 589 ConvertJavaStringToUTF8(env, j_error_message))); | 572 j_promise_id, ConvertJavaStringToUTF8(env, j_error_message))); |
| 590 } | 573 } |
| 591 | 574 |
| 592 void MediaDrmBridge::OnSessionMessage(JNIEnv* env, | 575 void MediaDrmBridge::OnSessionMessage(JNIEnv* env, |
| 593 jobject j_media_drm, | 576 jobject j_media_drm, |
| 594 jbyteArray j_session_id, | 577 jbyteArray j_session_id, |
| 595 jint j_message_type, | 578 jint j_message_type, |
| 596 jbyteArray j_message, | 579 jbyteArray j_message, |
| 597 jstring j_legacy_destination_url) { | 580 jstring j_legacy_destination_url) { |
| 598 DVLOG(2) << __FUNCTION__; | 581 DVLOG(2) << __FUNCTION__; |
| 599 | 582 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 619 } | 602 } |
| 620 | 603 |
| 621 void MediaDrmBridge::OnSessionKeysChange(JNIEnv* env, | 604 void MediaDrmBridge::OnSessionKeysChange(JNIEnv* env, |
| 622 jobject j_media_drm, | 605 jobject j_media_drm, |
| 623 jbyteArray j_session_id, | 606 jbyteArray j_session_id, |
| 624 jobjectArray j_keys_info, | 607 jobjectArray j_keys_info, |
| 625 bool has_additional_usable_key) { | 608 bool has_additional_usable_key) { |
| 626 DVLOG(2) << __FUNCTION__; | 609 DVLOG(2) << __FUNCTION__; |
| 627 | 610 |
| 628 if (has_additional_usable_key) | 611 if (has_additional_usable_key) |
| 629 NotifyNewKeyOnCorrectThread(); | 612 player_tracker_.NotifyNewKey(); |
| 630 | 613 |
| 631 CdmKeysInfo cdm_keys_info; | 614 CdmKeysInfo cdm_keys_info; |
| 632 | 615 |
| 633 size_t size = env->GetArrayLength(j_keys_info); | 616 size_t size = env->GetArrayLength(j_keys_info); |
| 634 DCHECK_GT(size, 0u); | 617 DCHECK_GT(size, 0u); |
| 635 | 618 |
| 636 for (size_t i = 0; i < size; ++i) { | 619 for (size_t i = 0; i < size; ++i) { |
| 637 ScopedJavaLocalRef<jobject> j_key_status( | 620 ScopedJavaLocalRef<jobject> j_key_status( |
| 638 env, env->GetObjectArrayElement(j_keys_info, i)); | 621 env, env->GetObjectArrayElement(j_keys_info, i)); |
| 639 | 622 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 720 const SessionKeysChangeCB& session_keys_change_cb, | 703 const SessionKeysChangeCB& session_keys_change_cb, |
| 721 const SessionExpirationUpdateCB& session_expiration_update_cb) | 704 const SessionExpirationUpdateCB& session_expiration_update_cb) |
| 722 : scheme_uuid_(scheme_uuid), | 705 : scheme_uuid_(scheme_uuid), |
| 723 session_message_cb_(session_message_cb), | 706 session_message_cb_(session_message_cb), |
| 724 session_closed_cb_(session_closed_cb), | 707 session_closed_cb_(session_closed_cb), |
| 725 legacy_session_error_cb_(legacy_session_error_cb), | 708 legacy_session_error_cb_(legacy_session_error_cb), |
| 726 session_keys_change_cb_(session_keys_change_cb), | 709 session_keys_change_cb_(session_keys_change_cb), |
| 727 session_expiration_update_cb_(session_expiration_update_cb), | 710 session_expiration_update_cb_(session_expiration_update_cb), |
| 728 cdm_promise_adapter_(new CdmPromiseAdapter()), | 711 cdm_promise_adapter_(new CdmPromiseAdapter()), |
| 729 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 712 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 730 use_media_thread_(UseMediaThreadForMediaPlayback()), | |
| 731 media_weak_factory_(this), | |
| 732 weak_factory_(this) { | 713 weak_factory_(this) { |
| 733 DVLOG(1) << __FUNCTION__; | 714 DVLOG(1) << __FUNCTION__; |
| 734 | 715 |
| 735 JNIEnv* env = AttachCurrentThread(); | 716 JNIEnv* env = AttachCurrentThread(); |
| 736 CHECK(env); | 717 CHECK(env); |
| 737 | 718 |
| 738 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 719 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
| 739 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 720 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
| 740 j_media_drm_.Reset(Java_MediaDrmBridge_create( | 721 j_media_drm_.Reset(Java_MediaDrmBridge_create( |
| 741 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); | 722 env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); |
| 742 } | 723 } |
| 743 | 724 |
| 725 MediaDrmBridge::~MediaDrmBridge() { | |
| 726 DCHECK(task_runner_->BelongsToCurrentThread()); | |
| 727 DVLOG(1) << __FUNCTION__; | |
| 728 | |
| 729 JNIEnv* env = AttachCurrentThread(); | |
| 730 | |
| 731 // After the call to Java_MediaDrmBridge_destroy() Java won't call native | |
| 732 // methods anymore, this is ensured by MediaDrmBridge.java. | |
| 733 if (!j_media_drm_.is_null()) | |
| 734 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj()); | |
| 735 | |
| 736 player_tracker_.NotifyCdmUnset(); | |
|
Tima Vaisburd
2015/10/29 01:17:53
There seem to be no players to notify, right? If y
xhwang
2015/10/29 03:12:31
The fact that the callback won't fire is an implem
| |
| 737 } | |
| 738 | |
| 744 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 | 739 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 |
| 745 // static | 740 // static |
| 746 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { | 741 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { |
| 747 DCHECK(IsAvailable()); | 742 DCHECK(IsAvailable()); |
| 748 return SECURITY_LEVEL_1 == security_level; | 743 return SECURITY_LEVEL_1 == security_level; |
| 749 } | 744 } |
| 750 | 745 |
| 751 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { | 746 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { |
| 752 JNIEnv* env = AttachCurrentThread(); | 747 JNIEnv* env = AttachCurrentThread(); |
| 753 ScopedJavaLocalRef<jstring> j_security_level = | 748 ScopedJavaLocalRef<jstring> j_security_level = |
| 754 Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_.obj()); | 749 Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_.obj()); |
| 755 std::string security_level_str = | 750 std::string security_level_str = |
| 756 ConvertJavaStringToUTF8(env, j_security_level.obj()); | 751 ConvertJavaStringToUTF8(env, j_security_level.obj()); |
| 757 return GetSecurityLevelFromString(security_level_str); | 752 return GetSecurityLevelFromString(security_level_str); |
| 758 } | 753 } |
| 759 | 754 |
| 760 void MediaDrmBridge::NotifyNewKeyOnCorrectThread() { | |
| 761 // Repost this method onto the Media thread if |use_media_thread_| is true. | |
| 762 if (use_media_thread_ && !GetMediaTaskRunner()->BelongsToCurrentThread()) { | |
| 763 GetMediaTaskRunner()->PostTask( | |
| 764 FROM_HERE, base::Bind(&MediaDrmBridge::NotifyNewKeyOnCorrectThread, | |
| 765 media_weak_factory_.GetWeakPtr())); | |
| 766 return; | |
| 767 } | |
| 768 | |
| 769 DCHECK(!use_media_thread_ || GetMediaTaskRunner()->BelongsToCurrentThread()); | |
| 770 DVLOG(1) << __FUNCTION__; | |
| 771 | |
| 772 player_tracker_.NotifyNewKey(); | |
| 773 } | |
| 774 | |
| 775 void MediaDrmBridge::NotifyMediaCryptoReady(const MediaCryptoReadyCB& cb) { | 755 void MediaDrmBridge::NotifyMediaCryptoReady(const MediaCryptoReadyCB& cb) { |
| 776 DCHECK(task_runner_->BelongsToCurrentThread()); | 756 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 777 | 757 |
| 778 DCHECK(!cb.is_null()); | 758 DCHECK(!cb.is_null()); |
| 779 DCHECK(!GetMediaCrypto().is_null()); | 759 DCHECK(!GetMediaCrypto().is_null()); |
| 780 | 760 |
| 781 // We can use scoped_ptr to pass ScopedJavaGlobalRef with a callback. | 761 // We can use scoped_ptr to pass ScopedJavaGlobalRef with a callback. |
| 782 scoped_ptr<ScopedJavaGlobalRef<jobject>> j_object_ptr( | 762 scoped_ptr<ScopedJavaGlobalRef<jobject>> j_object_ptr( |
| 783 new ScopedJavaGlobalRef<jobject>()); | 763 new ScopedJavaGlobalRef<jobject>()); |
| 784 j_object_ptr->Reset(AttachCurrentThread(), GetMediaCrypto().obj()); | 764 j_object_ptr->Reset(AttachCurrentThread(), GetMediaCrypto().obj()); |
| 785 | 765 |
| 786 cb.Run(j_object_ptr.Pass(), IsProtectedSurfaceRequired()); | 766 cb.Run(j_object_ptr.Pass(), IsProtectedSurfaceRequired()); |
| 787 } | 767 } |
| 788 | 768 |
| 789 } // namespace media | 769 } // namespace media |
| OLD | NEW |