| 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" |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 cdm_promise_adapter_.ResolvePromise(promise_id, session_id); | 485 cdm_promise_adapter_.ResolvePromise(promise_id, session_id); |
| 486 } | 486 } |
| 487 | 487 |
| 488 void MediaDrmBridge::RejectPromise(uint32_t promise_id, | 488 void MediaDrmBridge::RejectPromise(uint32_t promise_id, |
| 489 const std::string& error_message) { | 489 const std::string& error_message) { |
| 490 DVLOG(2) << __FUNCTION__; | 490 DVLOG(2) << __FUNCTION__; |
| 491 cdm_promise_adapter_.RejectPromise(promise_id, MediaKeys::UNKNOWN_ERROR, 0, | 491 cdm_promise_adapter_.RejectPromise(promise_id, MediaKeys::UNKNOWN_ERROR, 0, |
| 492 error_message); | 492 error_message); |
| 493 } | 493 } |
| 494 | 494 |
| 495 ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { | 495 jobject MediaDrmBridge::GetMediaCrypto() { |
| 496 DCHECK(task_runner_->BelongsToCurrentThread()); | 496 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 497 | 497 return j_media_crypto_->obj(); |
| 498 JNIEnv* env = AttachCurrentThread(); | |
| 499 return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); | |
| 500 } | 498 } |
| 501 | 499 |
| 502 void MediaDrmBridge::SetMediaCryptoReadyCB( | 500 void MediaDrmBridge::SetMediaCryptoReadyCB( |
| 503 const MediaCryptoReadyCB& media_crypto_ready_cb) { | 501 const MediaCryptoReadyCB& media_crypto_ready_cb) { |
| 504 if (!task_runner_->BelongsToCurrentThread()) { | 502 if (!task_runner_->BelongsToCurrentThread()) { |
| 505 task_runner_->PostTask( | 503 task_runner_->PostTask( |
| 506 FROM_HERE, | 504 FROM_HERE, |
| 507 base::Bind(&MediaDrmBridge::SetMediaCryptoReadyCB, | 505 base::Bind(&MediaDrmBridge::SetMediaCryptoReadyCB, |
| 508 weak_factory_.GetWeakPtr(), media_crypto_ready_cb)); | 506 weak_factory_.GetWeakPtr(), media_crypto_ready_cb)); |
| 509 return; | 507 return; |
| 510 } | 508 } |
| 511 | 509 |
| 512 DVLOG(1) << __FUNCTION__; | 510 DVLOG(1) << __FUNCTION__; |
| 513 | 511 |
| 514 if (media_crypto_ready_cb.is_null()) { | 512 if (media_crypto_ready_cb.is_null()) { |
| 515 media_crypto_ready_cb_.Reset(); | 513 media_crypto_ready_cb_.Reset(); |
| 516 return; | 514 return; |
| 517 } | 515 } |
| 518 | 516 |
| 519 DCHECK(media_crypto_ready_cb_.is_null()); | 517 DCHECK(media_crypto_ready_cb_.is_null()); |
| 518 media_crypto_ready_cb_ = media_crypto_ready_cb; |
| 520 | 519 |
| 521 // |media_crypto_ready_cb| is already bound to the correct thread | 520 if (!j_media_crypto_) |
| 522 // (either UI or Media). | |
| 523 if (!GetMediaCrypto().is_null()) { | |
| 524 NotifyMediaCryptoReady(media_crypto_ready_cb); | |
| 525 return; | 521 return; |
| 526 } | |
| 527 | 522 |
| 528 media_crypto_ready_cb_ = media_crypto_ready_cb; | 523 base::ResetAndReturn(&media_crypto_ready_cb_) |
| 524 .Run(CreateJavaObjectPtr(j_media_crypto_->obj()), |
| 525 IsProtectedSurfaceRequired()); |
| 529 } | 526 } |
| 530 | 527 |
| 531 //------------------------------------------------------------------------------ | 528 //------------------------------------------------------------------------------ |
| 532 // The following OnXxx functions are called from Java. The implementation must | 529 // The following OnXxx functions are called from Java. The implementation must |
| 533 // only do minimal work and then post tasks to avoid reentrancy issues. | 530 // only do minimal work and then post tasks to avoid reentrancy issues. |
| 534 | 531 |
| 535 void MediaDrmBridge::OnMediaCryptoReady( | 532 void MediaDrmBridge::OnMediaCryptoReady( |
| 536 JNIEnv* env, | 533 JNIEnv* env, |
| 537 const JavaParamRef<jobject>& j_media_drm) { | 534 const JavaParamRef<jobject>& j_media_drm, |
| 535 const JavaParamRef<jobject>& j_media_crypto) { |
| 538 DCHECK(task_runner_->BelongsToCurrentThread()); | 536 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 539 DVLOG(1) << __FUNCTION__; | 537 DVLOG(1) << __FUNCTION__; |
| 540 | 538 |
| 541 if (media_crypto_ready_cb_.is_null()) | |
| 542 return; | |
| 543 | |
| 544 task_runner_->PostTask( | 539 task_runner_->PostTask( |
| 545 FROM_HERE, base::Bind(&MediaDrmBridge::NotifyMediaCryptoReady, | 540 FROM_HERE, |
| 546 weak_factory_.GetWeakPtr(), | 541 base::Bind(&MediaDrmBridge::NotifyMediaCryptoReady, |
| 547 base::ResetAndReturn(&media_crypto_ready_cb_))); | 542 weak_factory_.GetWeakPtr(), |
| 543 base::Passed(CreateJavaObjectPtr(j_media_crypto.obj())))); |
| 548 } | 544 } |
| 549 | 545 |
| 550 void MediaDrmBridge::OnStartProvisioning( | 546 void MediaDrmBridge::OnStartProvisioning( |
| 551 JNIEnv* env, | 547 JNIEnv* env, |
| 552 const JavaParamRef<jobject>& j_media_drm, | 548 const JavaParamRef<jobject>& j_media_drm, |
| 553 const JavaParamRef<jstring>& j_default_url, | 549 const JavaParamRef<jstring>& j_default_url, |
| 554 const JavaParamRef<jbyteArray>& j_request_data) { | 550 const JavaParamRef<jbyteArray>& j_request_data) { |
| 555 DVLOG(1) << __FUNCTION__; | 551 DVLOG(1) << __FUNCTION__; |
| 556 | 552 |
| 557 task_runner_->PostTask(FROM_HERE, | 553 task_runner_->PostTask(FROM_HERE, |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 | 748 |
| 753 JNIEnv* env = AttachCurrentThread(); | 749 JNIEnv* env = AttachCurrentThread(); |
| 754 | 750 |
| 755 // After the call to Java_MediaDrmBridge_destroy() Java won't call native | 751 // After the call to Java_MediaDrmBridge_destroy() Java won't call native |
| 756 // methods anymore, this is ensured by MediaDrmBridge.java. | 752 // methods anymore, this is ensured by MediaDrmBridge.java. |
| 757 if (!j_media_drm_.is_null()) | 753 if (!j_media_drm_.is_null()) |
| 758 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj()); | 754 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj()); |
| 759 | 755 |
| 760 player_tracker_.NotifyCdmUnset(); | 756 player_tracker_.NotifyCdmUnset(); |
| 761 | 757 |
| 758 if (!media_crypto_ready_cb_.is_null()) { |
| 759 base::ResetAndReturn(&media_crypto_ready_cb_) |
| 760 .Run(CreateJavaObjectPtr(nullptr), IsProtectedSurfaceRequired()); |
| 761 } |
| 762 |
| 762 // Rejects all pending promises. | 763 // Rejects all pending promises. |
| 763 cdm_promise_adapter_.Clear(); | 764 cdm_promise_adapter_.Clear(); |
| 764 } | 765 } |
| 765 | 766 |
| 766 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 | 767 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 |
| 767 // static | 768 // static |
| 768 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { | 769 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { |
| 769 DCHECK(IsAvailable()); | 770 DCHECK(IsAvailable()); |
| 770 return SECURITY_LEVEL_1 == security_level; | 771 return SECURITY_LEVEL_1 == security_level; |
| 771 } | 772 } |
| 772 | 773 |
| 773 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { | 774 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { |
| 774 JNIEnv* env = AttachCurrentThread(); | 775 JNIEnv* env = AttachCurrentThread(); |
| 775 ScopedJavaLocalRef<jstring> j_security_level = | 776 ScopedJavaLocalRef<jstring> j_security_level = |
| 776 Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_.obj()); | 777 Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_.obj()); |
| 777 std::string security_level_str = | 778 std::string security_level_str = |
| 778 ConvertJavaStringToUTF8(env, j_security_level.obj()); | 779 ConvertJavaStringToUTF8(env, j_security_level.obj()); |
| 779 return GetSecurityLevelFromString(security_level_str); | 780 return GetSecurityLevelFromString(security_level_str); |
| 780 } | 781 } |
| 781 | 782 |
| 782 void MediaDrmBridge::NotifyMediaCryptoReady(const MediaCryptoReadyCB& cb) { | 783 // We have to use scoped_ptr to pass ScopedJavaGlobalRef with a callback. |
| 784 // TODO(timav): Check whether we can simply pass j_media_crypto_->obj() in the |
| 785 // callback. |
| 786 MediaDrmBridge::JavaObjectPtr MediaDrmBridge::CreateJavaObjectPtr( |
| 787 jobject object) { |
| 788 JavaObjectPtr j_object_ptr(new ScopedJavaGlobalRef<jobject>()); |
| 789 j_object_ptr->Reset(AttachCurrentThread(), object); |
| 790 return j_object_ptr; |
| 791 } |
| 792 |
| 793 void MediaDrmBridge::NotifyMediaCryptoReady(JavaObjectPtr j_media_crypto) { |
| 783 DCHECK(task_runner_->BelongsToCurrentThread()); | 794 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 795 DCHECK(j_media_crypto); |
| 796 DCHECK(!j_media_crypto_); |
| 784 | 797 |
| 785 DCHECK(!cb.is_null()); | 798 j_media_crypto_ = std::move(j_media_crypto); |
| 786 DCHECK(!GetMediaCrypto().is_null()); | |
| 787 | 799 |
| 788 // We can use scoped_ptr to pass ScopedJavaGlobalRef with a callback. | 800 if (media_crypto_ready_cb_.is_null()) |
| 789 scoped_ptr<ScopedJavaGlobalRef<jobject>> j_object_ptr( | 801 return; |
| 790 new ScopedJavaGlobalRef<jobject>()); | |
| 791 j_object_ptr->Reset(AttachCurrentThread(), GetMediaCrypto().obj()); | |
| 792 | 802 |
| 793 cb.Run(j_object_ptr.Pass(), IsProtectedSurfaceRequired()); | 803 base::ResetAndReturn(&media_crypto_ready_cb_) |
| 804 .Run(CreateJavaObjectPtr(j_media_crypto_->obj()), |
| 805 IsProtectedSurfaceRequired()); |
| 794 } | 806 } |
| 795 | 807 |
| 796 void MediaDrmBridge::SendProvisioningRequest(const std::string& default_url, | 808 void MediaDrmBridge::SendProvisioningRequest(const std::string& default_url, |
| 797 const std::string& request_data) { | 809 const std::string& request_data) { |
| 798 DCHECK(task_runner_->BelongsToCurrentThread()); | 810 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 799 DVLOG(1) << __FUNCTION__; | 811 DVLOG(1) << __FUNCTION__; |
| 800 | 812 |
| 801 DCHECK(!provision_fetcher_) << "At most one provision request at any time."; | 813 DCHECK(!provision_fetcher_) << "At most one provision request at any time."; |
| 802 provision_fetcher_ = create_fetcher_cb_.Run(); | 814 provision_fetcher_ = create_fetcher_cb_.Run(); |
| 803 | 815 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 821 JNIEnv* env = AttachCurrentThread(); | 833 JNIEnv* env = AttachCurrentThread(); |
| 822 | 834 |
| 823 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray( | 835 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray( |
| 824 env, reinterpret_cast<const uint8_t*>(response.data()), response.size()); | 836 env, reinterpret_cast<const uint8_t*>(response.data()), response.size()); |
| 825 | 837 |
| 826 Java_MediaDrmBridge_processProvisionResponse(env, j_media_drm_.obj(), success, | 838 Java_MediaDrmBridge_processProvisionResponse(env, j_media_drm_.obj(), success, |
| 827 j_response.obj()); | 839 j_response.obj()); |
| 828 } | 840 } |
| 829 | 841 |
| 830 } // namespace media | 842 } // namespace media |
| OLD | NEW |