| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 | 85 |
| 86 typedef std::vector<uint8> UUID; | 86 typedef std::vector<uint8> UUID; |
| 87 | 87 |
| 88 // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the | 88 // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the |
| 89 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is | 89 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is |
| 90 // found and successfully parsed. Returns false otherwise. | 90 // found and successfully parsed. Returns false otherwise. |
| 91 // Notes: | 91 // Notes: |
| 92 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box | 92 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box |
| 93 // will be set in |pssh_data|. | 93 // will be set in |pssh_data|. |
| 94 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. | 94 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. |
| 95 bool GetPsshData(const uint8* data, | 95 bool GetPsshData(const std::vector<uint8_t>& data, |
| 96 int data_size, | |
| 97 const UUID& uuid, | 96 const UUID& uuid, |
| 98 std::vector<uint8>* pssh_data) { | 97 std::vector<uint8>* pssh_data) { |
| 99 const uint8* cur = data; | 98 int bytes_left = data.size(); |
| 100 const uint8* data_end = data + data_size; | 99 const uint8_t* cur = &data[0]; |
| 101 int bytes_left = data_size; | 100 const uint8_t* data_end = cur + bytes_left; |
| 102 | 101 |
| 103 while (bytes_left > 0) { | 102 while (bytes_left > 0) { |
| 104 const uint8* box_head = cur; | 103 const uint8* box_head = cur; |
| 105 | 104 |
| 106 if (bytes_left < kBoxHeaderSize) | 105 if (bytes_left < kBoxHeaderSize) |
| 107 return false; | 106 return false; |
| 108 | 107 |
| 109 uint64_t box_size = ReadUint32(cur); | 108 uint64_t box_size = ReadUint32(cur); |
| 110 uint32 type = ReadUint32(cur + 4); | 109 uint32 type = ReadUint32(cur + 4); |
| 111 cur += kBoxHeaderSize; | 110 cur += kBoxHeaderSize; |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 if (security_level_str.empty()) | 419 if (security_level_str.empty()) |
| 421 return false; | 420 return false; |
| 422 | 421 |
| 423 ScopedJavaLocalRef<jstring> j_security_level = | 422 ScopedJavaLocalRef<jstring> j_security_level = |
| 424 ConvertUTF8ToJavaString(env, security_level_str); | 423 ConvertUTF8ToJavaString(env, security_level_str); |
| 425 return Java_MediaDrmBridge_setSecurityLevel( | 424 return Java_MediaDrmBridge_setSecurityLevel( |
| 426 env, j_media_drm_.obj(), j_security_level.obj()); | 425 env, j_media_drm_.obj(), j_security_level.obj()); |
| 427 } | 426 } |
| 428 | 427 |
| 429 void MediaDrmBridge::SetServerCertificate( | 428 void MediaDrmBridge::SetServerCertificate( |
| 430 const uint8* certificate_data, | 429 const std::vector<uint8_t>& certificate, |
| 431 int certificate_data_length, | |
| 432 scoped_ptr<media::SimpleCdmPromise> promise) { | 430 scoped_ptr<media::SimpleCdmPromise> promise) { |
| 433 promise->reject(NOT_SUPPORTED_ERROR, 0, | 431 promise->reject(NOT_SUPPORTED_ERROR, 0, |
| 434 "SetServerCertificate() is not supported."); | 432 "SetServerCertificate() is not supported."); |
| 435 } | 433 } |
| 436 | 434 |
| 437 void MediaDrmBridge::CreateSessionAndGenerateRequest( | 435 void MediaDrmBridge::CreateSessionAndGenerateRequest( |
| 438 SessionType session_type, | 436 SessionType session_type, |
| 439 media::EmeInitDataType init_data_type, | 437 media::EmeInitDataType init_data_type, |
| 440 const uint8* init_data, | 438 const std::vector<uint8_t>& init_data, |
| 441 int init_data_length, | |
| 442 scoped_ptr<media::NewSessionCdmPromise> promise) { | 439 scoped_ptr<media::NewSessionCdmPromise> promise) { |
| 443 DVLOG(1) << __FUNCTION__; | 440 DVLOG(1) << __FUNCTION__; |
| 444 | 441 |
| 445 if (session_type != media::MediaKeys::TEMPORARY_SESSION) { | 442 if (session_type != media::MediaKeys::TEMPORARY_SESSION) { |
| 446 promise->reject(NOT_SUPPORTED_ERROR, 0, | 443 promise->reject(NOT_SUPPORTED_ERROR, 0, |
| 447 "Only the temporary session type is supported."); | 444 "Only the temporary session type is supported."); |
| 448 return; | 445 return; |
| 449 } | 446 } |
| 450 | 447 |
| 451 JNIEnv* env = AttachCurrentThread(); | 448 JNIEnv* env = AttachCurrentThread(); |
| 452 ScopedJavaLocalRef<jbyteArray> j_init_data; | 449 ScopedJavaLocalRef<jbyteArray> j_init_data; |
| 453 | 450 |
| 454 // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as | 451 // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as |
| 455 // the init data when using MP4 container. | 452 // the init data when using MP4 container. |
| 456 if (std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid) && | 453 if (std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid) && |
| 457 init_data_type == media::EmeInitDataType::CENC) { | 454 init_data_type == media::EmeInitDataType::CENC) { |
| 458 std::vector<uint8> pssh_data; | 455 std::vector<uint8> pssh_data; |
| 459 if (!GetPsshData(init_data, init_data_length, scheme_uuid_, &pssh_data)) { | 456 if (!GetPsshData(init_data, scheme_uuid_, &pssh_data)) { |
| 460 promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid PSSH data."); | 457 promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid PSSH data."); |
| 461 return; | 458 return; |
| 462 } | 459 } |
| 463 j_init_data = | 460 j_init_data = base::android::ToJavaByteArray( |
| 464 base::android::ToJavaByteArray(env, &pssh_data[0], pssh_data.size()); | 461 env, vector_as_array(&pssh_data), pssh_data.size()); |
| 465 } else { | 462 } else { |
| 466 j_init_data = | 463 j_init_data = base::android::ToJavaByteArray( |
| 467 base::android::ToJavaByteArray(env, init_data, init_data_length); | 464 env, vector_as_array(&init_data), init_data.size()); |
| 468 } | 465 } |
| 469 | 466 |
| 470 ScopedJavaLocalRef<jstring> j_mime = | 467 ScopedJavaLocalRef<jstring> j_mime = |
| 471 ConvertUTF8ToJavaString(env, ConvertInitDataType(init_data_type)); | 468 ConvertUTF8ToJavaString(env, ConvertInitDataType(init_data_type)); |
| 472 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); | 469 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
| 473 Java_MediaDrmBridge_createSession(env, j_media_drm_.obj(), j_init_data.obj(), | 470 Java_MediaDrmBridge_createSession(env, j_media_drm_.obj(), j_init_data.obj(), |
| 474 j_mime.obj(), promise_id); | 471 j_mime.obj(), promise_id); |
| 475 } | 472 } |
| 476 | 473 |
| 477 void MediaDrmBridge::LoadSession( | 474 void MediaDrmBridge::LoadSession( |
| 478 SessionType session_type, | 475 SessionType session_type, |
| 479 const std::string& session_id, | 476 const std::string& session_id, |
| 480 scoped_ptr<media::NewSessionCdmPromise> promise) { | 477 scoped_ptr<media::NewSessionCdmPromise> promise) { |
| 481 promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); | 478 promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); |
| 482 } | 479 } |
| 483 | 480 |
| 484 void MediaDrmBridge::UpdateSession( | 481 void MediaDrmBridge::UpdateSession( |
| 485 const std::string& session_id, | 482 const std::string& session_id, |
| 486 const uint8* response, | 483 const std::vector<uint8_t>& response, |
| 487 int response_length, | |
| 488 scoped_ptr<media::SimpleCdmPromise> promise) { | 484 scoped_ptr<media::SimpleCdmPromise> promise) { |
| 489 DVLOG(1) << __FUNCTION__; | 485 DVLOG(1) << __FUNCTION__; |
| 490 | 486 |
| 491 JNIEnv* env = AttachCurrentThread(); | 487 JNIEnv* env = AttachCurrentThread(); |
| 492 ScopedJavaLocalRef<jbyteArray> j_response = | 488 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray( |
| 493 base::android::ToJavaByteArray(env, response, response_length); | 489 env, vector_as_array(&response), response.size()); |
| 494 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray( | 490 ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray( |
| 495 env, reinterpret_cast<const uint8_t*>(session_id.data()), | 491 env, reinterpret_cast<const uint8_t*>(session_id.data()), |
| 496 session_id.size()); | 492 session_id.size()); |
| 497 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); | 493 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
| 498 Java_MediaDrmBridge_updateSession(env, j_media_drm_.obj(), j_session_id.obj(), | 494 Java_MediaDrmBridge_updateSession(env, j_media_drm_.obj(), j_session_id.obj(), |
| 499 j_response.obj(), promise_id); | 495 j_response.obj(), promise_id); |
| 500 } | 496 } |
| 501 | 497 |
| 502 void MediaDrmBridge::CloseSession(const std::string& session_id, | 498 void MediaDrmBridge::CloseSession(const std::string& session_id, |
| 503 scoped_ptr<media::SimpleCdmPromise> promise) { | 499 scoped_ptr<media::SimpleCdmPromise> promise) { |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 JNIEnv* env = AttachCurrentThread(); | 655 JNIEnv* env = AttachCurrentThread(); |
| 660 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); | 656 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); |
| 661 } | 657 } |
| 662 | 658 |
| 663 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( | 659 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( |
| 664 JNIEnv* env, jobject, bool success) { | 660 JNIEnv* env, jobject, bool success) { |
| 665 base::ResetAndReturn(&reset_credentials_cb_).Run(success); | 661 base::ResetAndReturn(&reset_credentials_cb_).Run(success); |
| 666 } | 662 } |
| 667 | 663 |
| 668 } // namespace media | 664 } // namespace media |
| OLD | NEW |