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 <stddef.h> | 7 #include <stddef.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 | 185 |
186 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); | 186 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); |
187 if (scheme_uuid.empty()) | 187 if (scheme_uuid.empty()) |
188 return false; | 188 return false; |
189 | 189 |
190 JNIEnv* env = AttachCurrentThread(); | 190 JNIEnv* env = AttachCurrentThread(); |
191 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 191 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
192 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 192 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
193 ScopedJavaLocalRef<jstring> j_container_mime_type = | 193 ScopedJavaLocalRef<jstring> j_container_mime_type = |
194 ConvertUTF8ToJavaString(env, container_mime_type); | 194 ConvertUTF8ToJavaString(env, container_mime_type); |
195 return Java_MediaDrmBridge_isCryptoSchemeSupported( | 195 return Java_MediaDrmBridge_isCryptoSchemeSupported(env, j_scheme_uuid, |
196 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); | 196 j_container_mime_type); |
197 } | 197 } |
198 | 198 |
199 MediaDrmBridge::SecurityLevel GetSecurityLevelFromString( | 199 MediaDrmBridge::SecurityLevel GetSecurityLevelFromString( |
200 const std::string& security_level_str) { | 200 const std::string& security_level_str) { |
201 if (0 == security_level_str.compare("L1")) | 201 if (0 == security_level_str.compare("L1")) |
202 return MediaDrmBridge::SECURITY_LEVEL_1; | 202 return MediaDrmBridge::SECURITY_LEVEL_1; |
203 if (0 == security_level_str.compare("L3")) | 203 if (0 == security_level_str.compare("L3")) |
204 return MediaDrmBridge::SECURITY_LEVEL_3; | 204 return MediaDrmBridge::SECURITY_LEVEL_3; |
205 DCHECK(security_level_str.empty()); | 205 DCHECK(security_level_str.empty()); |
206 return MediaDrmBridge::SECURITY_LEVEL_DEFAULT; | 206 return MediaDrmBridge::SECURITY_LEVEL_DEFAULT; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 const std::vector<uint8_t>& certificate, | 348 const std::vector<uint8_t>& certificate, |
349 std::unique_ptr<media::SimpleCdmPromise> promise) { | 349 std::unique_ptr<media::SimpleCdmPromise> promise) { |
350 DCHECK(task_runner_->BelongsToCurrentThread()); | 350 DCHECK(task_runner_->BelongsToCurrentThread()); |
351 DVLOG(2) << __FUNCTION__ << "(" << certificate.size() << " bytes)"; | 351 DVLOG(2) << __FUNCTION__ << "(" << certificate.size() << " bytes)"; |
352 | 352 |
353 DCHECK(!certificate.empty()); | 353 DCHECK(!certificate.empty()); |
354 | 354 |
355 JNIEnv* env = AttachCurrentThread(); | 355 JNIEnv* env = AttachCurrentThread(); |
356 ScopedJavaLocalRef<jbyteArray> j_certificate = base::android::ToJavaByteArray( | 356 ScopedJavaLocalRef<jbyteArray> j_certificate = base::android::ToJavaByteArray( |
357 env, certificate.data(), certificate.size()); | 357 env, certificate.data(), certificate.size()); |
358 if (Java_MediaDrmBridge_setServerCertificate(env, j_media_drm_.obj(), | 358 if (Java_MediaDrmBridge_setServerCertificate(env, j_media_drm_, |
359 j_certificate.obj())) { | 359 j_certificate)) { |
360 promise->resolve(); | 360 promise->resolve(); |
361 } else { | 361 } else { |
362 promise->reject(INVALID_ACCESS_ERROR, 0, "Set server certificate failed."); | 362 promise->reject(INVALID_ACCESS_ERROR, 0, "Set server certificate failed."); |
363 } | 363 } |
364 } | 364 } |
365 | 365 |
366 void MediaDrmBridge::CreateSessionAndGenerateRequest( | 366 void MediaDrmBridge::CreateSessionAndGenerateRequest( |
367 SessionType session_type, | 367 SessionType session_type, |
368 media::EmeInitDataType init_data_type, | 368 media::EmeInitDataType init_data_type, |
369 const std::vector<uint8_t>& init_data, | 369 const std::vector<uint8_t>& init_data, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 } | 408 } |
409 | 409 |
410 if (j_init_data.is_null()) { | 410 if (j_init_data.is_null()) { |
411 j_init_data = | 411 j_init_data = |
412 base::android::ToJavaByteArray(env, init_data.data(), init_data.size()); | 412 base::android::ToJavaByteArray(env, init_data.data(), init_data.size()); |
413 } | 413 } |
414 | 414 |
415 ScopedJavaLocalRef<jstring> j_mime = | 415 ScopedJavaLocalRef<jstring> j_mime = |
416 ConvertUTF8ToJavaString(env, ConvertInitDataType(init_data_type)); | 416 ConvertUTF8ToJavaString(env, ConvertInitDataType(init_data_type)); |
417 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 417 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
418 Java_MediaDrmBridge_createSessionFromNative( | 418 Java_MediaDrmBridge_createSessionFromNative(env, j_media_drm_, j_init_data, |
419 env, j_media_drm_.obj(), j_init_data.obj(), j_mime.obj(), | 419 j_mime, j_optional_parameters, |
420 j_optional_parameters.obj(), promise_id); | 420 promise_id); |
421 } | 421 } |
422 | 422 |
423 void MediaDrmBridge::LoadSession( | 423 void MediaDrmBridge::LoadSession( |
424 SessionType session_type, | 424 SessionType session_type, |
425 const std::string& session_id, | 425 const std::string& session_id, |
426 std::unique_ptr<media::NewSessionCdmPromise> promise) { | 426 std::unique_ptr<media::NewSessionCdmPromise> promise) { |
427 DCHECK(task_runner_->BelongsToCurrentThread()); | 427 DCHECK(task_runner_->BelongsToCurrentThread()); |
428 DVLOG(2) << __FUNCTION__; | 428 DVLOG(2) << __FUNCTION__; |
429 | 429 |
430 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; | 430 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; |
431 promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); | 431 promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); |
432 } | 432 } |
433 | 433 |
434 void MediaDrmBridge::UpdateSession( | 434 void MediaDrmBridge::UpdateSession( |
435 const std::string& session_id, | 435 const std::string& session_id, |
436 const std::vector<uint8_t>& response, | 436 const std::vector<uint8_t>& response, |
437 std::unique_ptr<media::SimpleCdmPromise> promise) { | 437 std::unique_ptr<media::SimpleCdmPromise> promise) { |
438 DCHECK(task_runner_->BelongsToCurrentThread()); | 438 DCHECK(task_runner_->BelongsToCurrentThread()); |
439 DVLOG(2) << __FUNCTION__; | 439 DVLOG(2) << __FUNCTION__; |
440 | 440 |
441 JNIEnv* env = AttachCurrentThread(); | 441 JNIEnv* env = AttachCurrentThread(); |
442 ScopedJavaLocalRef<jbyteArray> j_response = | 442 ScopedJavaLocalRef<jbyteArray> j_response = |
443 base::android::ToJavaByteArray(env, response.data(), response.size()); | 443 base::android::ToJavaByteArray(env, response.data(), response.size()); |
444 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray( | 444 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray( |
445 env, reinterpret_cast<const uint8_t*>(session_id.data()), | 445 env, reinterpret_cast<const uint8_t*>(session_id.data()), |
446 session_id.size()); | 446 session_id.size()); |
447 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 447 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
448 Java_MediaDrmBridge_updateSession(env, j_media_drm_.obj(), j_session_id.obj(), | 448 Java_MediaDrmBridge_updateSession(env, j_media_drm_, j_session_id, j_response, |
449 j_response.obj(), promise_id); | 449 promise_id); |
450 } | 450 } |
451 | 451 |
452 void MediaDrmBridge::CloseSession( | 452 void MediaDrmBridge::CloseSession( |
453 const std::string& session_id, | 453 const std::string& session_id, |
454 std::unique_ptr<media::SimpleCdmPromise> promise) { | 454 std::unique_ptr<media::SimpleCdmPromise> promise) { |
455 DCHECK(task_runner_->BelongsToCurrentThread()); | 455 DCHECK(task_runner_->BelongsToCurrentThread()); |
456 DVLOG(2) << __FUNCTION__; | 456 DVLOG(2) << __FUNCTION__; |
457 | 457 |
458 JNIEnv* env = AttachCurrentThread(); | 458 JNIEnv* env = AttachCurrentThread(); |
459 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray( | 459 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray( |
460 env, reinterpret_cast<const uint8_t*>(session_id.data()), | 460 env, reinterpret_cast<const uint8_t*>(session_id.data()), |
461 session_id.size()); | 461 session_id.size()); |
462 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 462 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
463 Java_MediaDrmBridge_closeSession(env, j_media_drm_.obj(), j_session_id.obj(), | 463 Java_MediaDrmBridge_closeSession(env, j_media_drm_, j_session_id, promise_id); |
464 promise_id); | |
465 } | 464 } |
466 | 465 |
467 void MediaDrmBridge::RemoveSession( | 466 void MediaDrmBridge::RemoveSession( |
468 const std::string& session_id, | 467 const std::string& session_id, |
469 std::unique_ptr<media::SimpleCdmPromise> promise) { | 468 std::unique_ptr<media::SimpleCdmPromise> promise) { |
470 DCHECK(task_runner_->BelongsToCurrentThread()); | 469 DCHECK(task_runner_->BelongsToCurrentThread()); |
471 DVLOG(2) << __FUNCTION__; | 470 DVLOG(2) << __FUNCTION__; |
472 | 471 |
473 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; | 472 NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android."; |
474 promise->reject(NOT_SUPPORTED_ERROR, 0, "RemoveSession() is not supported."); | 473 promise->reject(NOT_SUPPORTED_ERROR, 0, "RemoveSession() is not supported."); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 return true; | 510 return true; |
512 } | 511 } |
513 | 512 |
514 void MediaDrmBridge::ResetDeviceCredentials( | 513 void MediaDrmBridge::ResetDeviceCredentials( |
515 const ResetCredentialsCB& callback) { | 514 const ResetCredentialsCB& callback) { |
516 DVLOG(1) << __FUNCTION__; | 515 DVLOG(1) << __FUNCTION__; |
517 | 516 |
518 DCHECK(reset_credentials_cb_.is_null()); | 517 DCHECK(reset_credentials_cb_.is_null()); |
519 reset_credentials_cb_ = callback; | 518 reset_credentials_cb_ = callback; |
520 JNIEnv* env = AttachCurrentThread(); | 519 JNIEnv* env = AttachCurrentThread(); |
521 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); | 520 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_); |
522 } | 521 } |
523 | 522 |
524 void MediaDrmBridge::ResolvePromise(uint32_t promise_id) { | 523 void MediaDrmBridge::ResolvePromise(uint32_t promise_id) { |
525 DVLOG(2) << __FUNCTION__; | 524 DVLOG(2) << __FUNCTION__; |
526 cdm_promise_adapter_.ResolvePromise(promise_id); | 525 cdm_promise_adapter_.ResolvePromise(promise_id); |
527 } | 526 } |
528 | 527 |
529 void MediaDrmBridge::ResolvePromiseWithSession(uint32_t promise_id, | 528 void MediaDrmBridge::ResolvePromiseWithSession(uint32_t promise_id, |
530 const std::string& session_id) { | 529 const std::string& session_id) { |
531 DVLOG(2) << __FUNCTION__; | 530 DVLOG(2) << __FUNCTION__; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 CdmKeysInfo cdm_keys_info; | 674 CdmKeysInfo cdm_keys_info; |
676 | 675 |
677 size_t size = env->GetArrayLength(j_keys_info); | 676 size_t size = env->GetArrayLength(j_keys_info); |
678 DCHECK_GT(size, 0u); | 677 DCHECK_GT(size, 0u); |
679 | 678 |
680 for (size_t i = 0; i < size; ++i) { | 679 for (size_t i = 0; i < size; ++i) { |
681 ScopedJavaLocalRef<jobject> j_key_status( | 680 ScopedJavaLocalRef<jobject> j_key_status( |
682 env, env->GetObjectArrayElement(j_keys_info, i)); | 681 env, env->GetObjectArrayElement(j_keys_info, i)); |
683 | 682 |
684 ScopedJavaLocalRef<jbyteArray> j_key_id = | 683 ScopedJavaLocalRef<jbyteArray> j_key_id = |
685 Java_KeyStatus_getKeyId(env, j_key_status.obj()); | 684 Java_KeyStatus_getKeyId(env, j_key_status); |
686 std::vector<uint8_t> key_id; | 685 std::vector<uint8_t> key_id; |
687 JavaByteArrayToByteVector(env, j_key_id.obj(), &key_id); | 686 JavaByteArrayToByteVector(env, j_key_id.obj(), &key_id); |
688 DCHECK(!key_id.empty()); | 687 DCHECK(!key_id.empty()); |
689 | 688 |
690 jint j_status_code = Java_KeyStatus_getStatusCode(env, j_key_status.obj()); | 689 jint j_status_code = Java_KeyStatus_getStatusCode(env, j_key_status); |
691 CdmKeyInformation::KeyStatus key_status = | 690 CdmKeyInformation::KeyStatus key_status = |
692 ConvertKeyStatus(static_cast<KeyStatus>(j_status_code)); | 691 ConvertKeyStatus(static_cast<KeyStatus>(j_status_code)); |
693 | 692 |
694 DVLOG(2) << __FUNCTION__ << "Key status change: " | 693 DVLOG(2) << __FUNCTION__ << "Key status change: " |
695 << base::HexEncode(&key_id[0], key_id.size()) << ", " | 694 << base::HexEncode(&key_id[0], key_id.size()) << ", " |
696 << key_status; | 695 << key_status; |
697 | 696 |
698 cdm_keys_info.push_back(new CdmKeyInformation(key_id, key_status, 0)); | 697 cdm_keys_info.push_back(new CdmKeyInformation(key_id, key_status, 0)); |
699 } | 698 } |
700 | 699 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 | 789 |
791 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 790 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
792 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 791 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
793 | 792 |
794 std::string security_level_str = GetSecurityLevelString(security_level); | 793 std::string security_level_str = GetSecurityLevelString(security_level); |
795 ScopedJavaLocalRef<jstring> j_security_level = | 794 ScopedJavaLocalRef<jstring> j_security_level = |
796 ConvertUTF8ToJavaString(env, security_level_str); | 795 ConvertUTF8ToJavaString(env, security_level_str); |
797 | 796 |
798 // Note: OnMediaCryptoReady() could be called in this call. | 797 // Note: OnMediaCryptoReady() could be called in this call. |
799 j_media_drm_.Reset(Java_MediaDrmBridge_create( | 798 j_media_drm_.Reset(Java_MediaDrmBridge_create( |
800 env, j_scheme_uuid.obj(), j_security_level.obj(), | 799 env, j_scheme_uuid, j_security_level, reinterpret_cast<intptr_t>(this))); |
801 reinterpret_cast<intptr_t>(this))); | |
802 } | 800 } |
803 | 801 |
804 MediaDrmBridge::~MediaDrmBridge() { | 802 MediaDrmBridge::~MediaDrmBridge() { |
805 DCHECK(task_runner_->BelongsToCurrentThread()); | 803 DCHECK(task_runner_->BelongsToCurrentThread()); |
806 DVLOG(1) << __FUNCTION__; | 804 DVLOG(1) << __FUNCTION__; |
807 | 805 |
808 JNIEnv* env = AttachCurrentThread(); | 806 JNIEnv* env = AttachCurrentThread(); |
809 | 807 |
810 // After the call to Java_MediaDrmBridge_destroy() Java won't call native | 808 // After the call to Java_MediaDrmBridge_destroy() Java won't call native |
811 // methods anymore, this is ensured by MediaDrmBridge.java. | 809 // methods anymore, this is ensured by MediaDrmBridge.java. |
812 if (!j_media_drm_.is_null()) | 810 if (!j_media_drm_.is_null()) |
813 Java_MediaDrmBridge_destroy(env, j_media_drm_.obj()); | 811 Java_MediaDrmBridge_destroy(env, j_media_drm_); |
814 | 812 |
815 player_tracker_.NotifyCdmUnset(); | 813 player_tracker_.NotifyCdmUnset(); |
816 | 814 |
817 if (!media_crypto_ready_cb_.is_null()) { | 815 if (!media_crypto_ready_cb_.is_null()) { |
818 base::ResetAndReturn(&media_crypto_ready_cb_) | 816 base::ResetAndReturn(&media_crypto_ready_cb_) |
819 .Run(CreateJavaObjectPtr(nullptr), IsProtectedSurfaceRequired()); | 817 .Run(CreateJavaObjectPtr(nullptr), IsProtectedSurfaceRequired()); |
820 } | 818 } |
821 | 819 |
822 // Rejects all pending promises. | 820 // Rejects all pending promises. |
823 cdm_promise_adapter_.Clear(); | 821 cdm_promise_adapter_.Clear(); |
824 } | 822 } |
825 | 823 |
826 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 | 824 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 |
827 // static | 825 // static |
828 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { | 826 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { |
829 DCHECK(IsAvailable()); | 827 DCHECK(IsAvailable()); |
830 return SECURITY_LEVEL_1 == security_level; | 828 return SECURITY_LEVEL_1 == security_level; |
831 } | 829 } |
832 | 830 |
833 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { | 831 MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { |
834 JNIEnv* env = AttachCurrentThread(); | 832 JNIEnv* env = AttachCurrentThread(); |
835 ScopedJavaLocalRef<jstring> j_security_level = | 833 ScopedJavaLocalRef<jstring> j_security_level = |
836 Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_.obj()); | 834 Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_); |
837 std::string security_level_str = | 835 std::string security_level_str = |
838 ConvertJavaStringToUTF8(env, j_security_level.obj()); | 836 ConvertJavaStringToUTF8(env, j_security_level.obj()); |
839 return GetSecurityLevelFromString(security_level_str); | 837 return GetSecurityLevelFromString(security_level_str); |
840 } | 838 } |
841 | 839 |
842 // We have to use scoped_ptr to pass ScopedJavaGlobalRef with a callback. | 840 // We have to use scoped_ptr to pass ScopedJavaGlobalRef with a callback. |
843 // TODO(timav): Check whether we can simply pass j_media_crypto_->obj() in the | 841 // TODO(timav): Check whether we can simply pass j_media_crypto_->obj() in the |
844 // callback. | 842 // callback. |
845 MediaDrmBridge::JavaObjectPtr MediaDrmBridge::CreateJavaObjectPtr( | 843 MediaDrmBridge::JavaObjectPtr MediaDrmBridge::CreateJavaObjectPtr( |
846 jobject object) { | 844 jobject object) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 provision_fetcher_.reset(); | 885 provision_fetcher_.reset(); |
888 | 886 |
889 if (!success) | 887 if (!success) |
890 VLOG(1) << "Device provision failure: can't get server response"; | 888 VLOG(1) << "Device provision failure: can't get server response"; |
891 | 889 |
892 JNIEnv* env = AttachCurrentThread(); | 890 JNIEnv* env = AttachCurrentThread(); |
893 | 891 |
894 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray( | 892 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray( |
895 env, reinterpret_cast<const uint8_t*>(response.data()), response.size()); | 893 env, reinterpret_cast<const uint8_t*>(response.data()), response.size()); |
896 | 894 |
897 Java_MediaDrmBridge_processProvisionResponse(env, j_media_drm_.obj(), success, | 895 Java_MediaDrmBridge_processProvisionResponse(env, j_media_drm_, success, |
898 j_response.obj()); | 896 j_response); |
899 } | 897 } |
900 | 898 |
901 void MediaDrmBridge::OnHasAdditionalUsableKey() { | 899 void MediaDrmBridge::OnHasAdditionalUsableKey() { |
902 DCHECK(task_runner_->BelongsToCurrentThread()); | 900 DCHECK(task_runner_->BelongsToCurrentThread()); |
903 DVLOG(1) << __FUNCTION__; | 901 DVLOG(1) << __FUNCTION__; |
904 | 902 |
905 player_tracker_.NotifyNewKey(); | 903 player_tracker_.NotifyNewKey(); |
906 } | 904 } |
907 | 905 |
908 } // namespace media | 906 } // namespace media |
OLD | NEW |