| Index: media/base/android/media_drm_bridge.cc
|
| diff --git a/media/base/android/media_drm_bridge.cc b/media/base/android/media_drm_bridge.cc
|
| index 91c08d2033fdb32e6d2a78a90a8edaacfedab030..a89522df7115e8426a6df794cf6d0323f6fd485f 100644
|
| --- a/media/base/android/media_drm_bridge.cc
|
| +++ b/media/base/android/media_drm_bridge.cc
|
| @@ -19,6 +19,7 @@
|
| #include "base/sys_byteorder.h"
|
| #include "base/sys_info.h"
|
| #include "jni/MediaDrmBridge_jni.h"
|
| +#include "media/base/cdm_key_information.h"
|
|
|
| #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
|
|
|
| @@ -30,20 +31,34 @@ using base::android::ScopedJavaLocalRef;
|
|
|
| namespace media {
|
|
|
| -static uint32 ReadUint32(const uint8_t* data) {
|
| +namespace {
|
| +
|
| +// DrmBridge supports session expiration event but doesn't provide detailed
|
| +// status for each key ID, which is required by the EME spec. Use a dummy key ID
|
| +// here to report session expiration info.
|
| +const char kDummyKeyId[] = "Dummy Key Id";
|
| +
|
| +uint32 ReadUint32(const uint8_t* data) {
|
| uint32 value = 0;
|
| for (int i = 0; i < 4; ++i)
|
| value = (value << 8) | data[i];
|
| return value;
|
| }
|
|
|
| -static uint64 ReadUint64(const uint8_t* data) {
|
| +uint64 ReadUint64(const uint8_t* data) {
|
| uint64 value = 0;
|
| for (int i = 0; i < 8; ++i)
|
| value = (value << 8) | data[i];
|
| return value;
|
| }
|
|
|
| +// Returns string session ID from jbyteArray (byte[] in Java).
|
| +std::string GetSessionId(JNIEnv* env, jbyteArray j_session_id) {
|
| + std::vector<uint8> session_id_vector;
|
| + JavaByteArrayToByteVector(env, j_session_id, &session_id_vector);
|
| + return std::string(session_id_vector.begin(), session_id_vector.end());
|
| +}
|
| +
|
| // The structure of an ISO CENC Protection System Specific Header (PSSH) box is
|
| // as follows. (See ISO/IEC FDIS 23001-7:2011(E).)
|
| // Note: ISO boxes use big-endian values.
|
| @@ -70,58 +85,6 @@ const uint8 kWidevineUuid[16] = {
|
|
|
| typedef std::vector<uint8> UUID;
|
|
|
| -class KeySystemUuidManager {
|
| - public:
|
| - KeySystemUuidManager();
|
| - UUID GetUUID(const std::string& key_system);
|
| - void AddMapping(const std::string& key_system, const UUID& uuid);
|
| - std::vector<std::string> GetPlatformKeySystemNames();
|
| -
|
| - private:
|
| - typedef base::hash_map<std::string, UUID> KeySystemUuidMap;
|
| -
|
| - KeySystemUuidMap key_system_uuid_map_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(KeySystemUuidManager);
|
| -};
|
| -
|
| -KeySystemUuidManager::KeySystemUuidManager() {
|
| - // Widevine is always supported in Android.
|
| - key_system_uuid_map_[kWidevineKeySystem] =
|
| - UUID(kWidevineUuid, kWidevineUuid + arraysize(kWidevineUuid));
|
| -}
|
| -
|
| -UUID KeySystemUuidManager::GetUUID(const std::string& key_system) {
|
| - KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system);
|
| - if (it == key_system_uuid_map_.end())
|
| - return UUID();
|
| - return it->second;
|
| -}
|
| -
|
| -void KeySystemUuidManager::AddMapping(const std::string& key_system,
|
| - const UUID& uuid) {
|
| - KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system);
|
| - DCHECK(it == key_system_uuid_map_.end())
|
| - << "Shouldn't overwrite an existing key system.";
|
| - if (it != key_system_uuid_map_.end())
|
| - return;
|
| - key_system_uuid_map_[key_system] = uuid;
|
| -}
|
| -
|
| -std::vector<std::string> KeySystemUuidManager::GetPlatformKeySystemNames() {
|
| - std::vector<std::string> key_systems;
|
| - for (KeySystemUuidMap::iterator it = key_system_uuid_map_.begin();
|
| - it != key_system_uuid_map_.end(); ++it) {
|
| - // Rule out the key system handled by Chrome explicitly.
|
| - if (it->first != kWidevineKeySystem)
|
| - key_systems.push_back(it->first);
|
| - }
|
| - return key_systems;
|
| -}
|
| -
|
| -base::LazyInstance<KeySystemUuidManager>::Leaky g_key_system_uuid_manager =
|
| - LAZY_INSTANCE_INITIALIZER;
|
| -
|
| // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the
|
| // "Data" of the box and put it in |pssh_data|. Returns true if such a box is
|
| // found and successfully parsed. Returns false otherwise.
|
| @@ -129,9 +92,10 @@ base::LazyInstance<KeySystemUuidManager>::Leaky g_key_system_uuid_manager =
|
| // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box
|
| // will be set in |pssh_data|.
|
| // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped.
|
| -static bool GetPsshData(const uint8* data, int data_size,
|
| - const UUID& uuid,
|
| - std::vector<uint8>* pssh_data) {
|
| +bool GetPsshData(const uint8* data,
|
| + int data_size,
|
| + const UUID& uuid,
|
| + std::vector<uint8>* pssh_data) {
|
| const uint8* cur = data;
|
| const uint8* data_end = data + data_size;
|
| int bytes_left = data_size;
|
| @@ -206,37 +170,65 @@ static bool GetPsshData(const uint8* data, int data_size,
|
| return false;
|
| }
|
|
|
| -static MediaDrmBridge::SecurityLevel GetSecurityLevelFromString(
|
| - const std::string& security_level_str) {
|
| - if (0 == security_level_str.compare("L1"))
|
| - return MediaDrmBridge::SECURITY_LEVEL_1;
|
| - if (0 == security_level_str.compare("L3"))
|
| - return MediaDrmBridge::SECURITY_LEVEL_3;
|
| - DCHECK(security_level_str.empty());
|
| - return MediaDrmBridge::SECURITY_LEVEL_NONE;
|
| +class KeySystemUuidManager {
|
| + public:
|
| + KeySystemUuidManager();
|
| + UUID GetUUID(const std::string& key_system);
|
| + void AddMapping(const std::string& key_system, const UUID& uuid);
|
| + std::vector<std::string> GetPlatformKeySystemNames();
|
| +
|
| + private:
|
| + typedef base::hash_map<std::string, UUID> KeySystemUuidMap;
|
| +
|
| + KeySystemUuidMap key_system_uuid_map_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(KeySystemUuidManager);
|
| +};
|
| +
|
| +KeySystemUuidManager::KeySystemUuidManager() {
|
| + // Widevine is always supported in Android.
|
| + key_system_uuid_map_[kWidevineKeySystem] =
|
| + UUID(kWidevineUuid, kWidevineUuid + arraysize(kWidevineUuid));
|
| }
|
|
|
| -static std::string GetSecurityLevelString(
|
| - MediaDrmBridge::SecurityLevel security_level) {
|
| - switch (security_level) {
|
| - case MediaDrmBridge::SECURITY_LEVEL_NONE:
|
| - return "";
|
| - case MediaDrmBridge::SECURITY_LEVEL_1:
|
| - return "L1";
|
| - case MediaDrmBridge::SECURITY_LEVEL_3:
|
| - return "L3";
|
| +UUID KeySystemUuidManager::GetUUID(const std::string& key_system) {
|
| + KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system);
|
| + if (it == key_system_uuid_map_.end())
|
| + return UUID();
|
| + return it->second;
|
| +}
|
| +
|
| +void KeySystemUuidManager::AddMapping(const std::string& key_system,
|
| + const UUID& uuid) {
|
| + KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system);
|
| + DCHECK(it == key_system_uuid_map_.end())
|
| + << "Shouldn't overwrite an existing key system.";
|
| + if (it != key_system_uuid_map_.end())
|
| + return;
|
| + key_system_uuid_map_[key_system] = uuid;
|
| +}
|
| +
|
| +std::vector<std::string> KeySystemUuidManager::GetPlatformKeySystemNames() {
|
| + std::vector<std::string> key_systems;
|
| + for (KeySystemUuidMap::iterator it = key_system_uuid_map_.begin();
|
| + it != key_system_uuid_map_.end(); ++it) {
|
| + // Rule out the key system handled by Chrome explicitly.
|
| + if (it->first != kWidevineKeySystem)
|
| + key_systems.push_back(it->first);
|
| }
|
| - return "";
|
| + return key_systems;
|
| }
|
|
|
| +base::LazyInstance<KeySystemUuidManager>::Leaky g_key_system_uuid_manager =
|
| + LAZY_INSTANCE_INITIALIZER;
|
| +
|
| // Checks whether |key_system| is supported with |container_mime_type|. Only
|
| // checks |key_system| support if |container_mime_type| is empty.
|
| // TODO(xhwang): The |container_mime_type| is not the same as contentType in
|
| // the EME spec. Revisit this once the spec issue with initData type is
|
| // resolved.
|
| -static bool IsKeySystemSupportedWithTypeImpl(
|
| - const std::string& key_system,
|
| - const std::string& container_mime_type) {
|
| +bool IsKeySystemSupportedWithTypeImpl(const std::string& key_system,
|
| + const std::string& container_mime_type) {
|
| if (!MediaDrmBridge::IsAvailable())
|
| return false;
|
|
|
| @@ -253,6 +245,42 @@ static bool IsKeySystemSupportedWithTypeImpl(
|
| env, j_scheme_uuid.obj(), j_container_mime_type.obj());
|
| }
|
|
|
| +MediaDrmBridge::SecurityLevel GetSecurityLevelFromString(
|
| + const std::string& security_level_str) {
|
| + if (0 == security_level_str.compare("L1"))
|
| + return MediaDrmBridge::SECURITY_LEVEL_1;
|
| + if (0 == security_level_str.compare("L3"))
|
| + return MediaDrmBridge::SECURITY_LEVEL_3;
|
| + DCHECK(security_level_str.empty());
|
| + return MediaDrmBridge::SECURITY_LEVEL_NONE;
|
| +}
|
| +
|
| +std::string GetSecurityLevelString(
|
| + MediaDrmBridge::SecurityLevel security_level) {
|
| + switch (security_level) {
|
| + case MediaDrmBridge::SECURITY_LEVEL_NONE:
|
| + return "";
|
| + case MediaDrmBridge::SECURITY_LEVEL_1:
|
| + return "L1";
|
| + case MediaDrmBridge::SECURITY_LEVEL_3:
|
| + return "L3";
|
| + }
|
| + return "";
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// Called by Java.
|
| +static void AddKeySystemUuidMapping(JNIEnv* env,
|
| + jclass clazz,
|
| + jstring j_key_system,
|
| + jobject j_buffer) {
|
| + std::string key_system = ConvertJavaStringToUTF8(env, j_key_system);
|
| + uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer));
|
| + UUID uuid(buffer, buffer + 16);
|
| + g_key_system_uuid_manager.Get().AddMapping(key_system, uuid);
|
| +}
|
| +
|
| // static
|
| bool MediaDrmBridge::IsAvailable() {
|
| if (base::android::BuildInfo::GetInstance()->sdk_int() < 19)
|
| @@ -283,22 +311,13 @@ bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system,
|
| return false;
|
|
|
| scoped_ptr<MediaDrmBridge> media_drm_bridge =
|
| - MediaDrmBridge::CreateSessionless(key_system);
|
| + MediaDrmBridge::CreateWithoutSessionSupport(key_system);
|
| if (!media_drm_bridge)
|
| return false;
|
|
|
| return media_drm_bridge->SetSecurityLevel(security_level);
|
| }
|
|
|
| -static void AddKeySystemUuidMapping(JNIEnv* env, jclass clazz,
|
| - jstring j_key_system,
|
| - jobject j_buffer) {
|
| - std::string key_system = ConvertJavaStringToUTF8(env, j_key_system);
|
| - uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer));
|
| - UUID uuid(buffer, buffer + 16);
|
| - g_key_system_uuid_manager.Get().AddMapping(key_system, uuid);
|
| -}
|
| -
|
| // static
|
| std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() {
|
| return g_key_system_uuid_manager.Get().GetPlatformKeySystemNames();
|
| @@ -322,18 +341,17 @@ bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) {
|
| return RegisterNativesImpl(env);
|
| }
|
|
|
| -MediaDrmBridge::MediaDrmBridge(const std::vector<uint8>& scheme_uuid,
|
| - const SessionCreatedCB& session_created_cb,
|
| - const SessionMessageCB& session_message_cb,
|
| - const SessionReadyCB& session_ready_cb,
|
| - const SessionClosedCB& session_closed_cb,
|
| - const SessionErrorCB& session_error_cb)
|
| +MediaDrmBridge::MediaDrmBridge(
|
| + const std::vector<uint8>& scheme_uuid,
|
| + const SessionMessageCB& session_message_cb,
|
| + const SessionClosedCB& session_closed_cb,
|
| + const SessionErrorCB& session_error_cb,
|
| + const SessionKeysChangeCB& session_keys_change_cb)
|
| : scheme_uuid_(scheme_uuid),
|
| - session_created_cb_(session_created_cb),
|
| session_message_cb_(session_message_cb),
|
| - session_ready_cb_(session_ready_cb),
|
| session_closed_cb_(session_closed_cb),
|
| - session_error_cb_(session_error_cb) {
|
| + session_error_cb_(session_error_cb),
|
| + session_keys_change_cb_(session_keys_change_cb) {
|
| JNIEnv* env = AttachCurrentThread();
|
| CHECK(env);
|
|
|
| @@ -351,13 +369,14 @@ MediaDrmBridge::~MediaDrmBridge() {
|
| }
|
|
|
| // static
|
| +// TODO(xhwang): Enable SessionExpirationUpdateCB when it is supported.
|
| scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(
|
| const std::string& key_system,
|
| - const SessionCreatedCB& session_created_cb,
|
| const SessionMessageCB& session_message_cb,
|
| - const SessionReadyCB& session_ready_cb,
|
| const SessionClosedCB& session_closed_cb,
|
| - const SessionErrorCB& session_error_cb) {
|
| + const SessionErrorCB& session_error_cb,
|
| + const SessionKeysChangeCB& session_keys_change_cb,
|
| + const SessionExpirationUpdateCB& /* session_expiration_update_cb */) {
|
| scoped_ptr<MediaDrmBridge> media_drm_bridge;
|
| if (!IsAvailable())
|
| return media_drm_bridge.Pass();
|
| @@ -366,12 +385,9 @@ scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(
|
| if (scheme_uuid.empty())
|
| return media_drm_bridge.Pass();
|
|
|
| - media_drm_bridge.reset(new MediaDrmBridge(scheme_uuid,
|
| - session_created_cb,
|
| - session_message_cb,
|
| - session_ready_cb,
|
| - session_closed_cb,
|
| - session_error_cb));
|
| + media_drm_bridge.reset(new MediaDrmBridge(scheme_uuid, session_message_cb,
|
| + session_closed_cb, session_error_cb,
|
| + session_keys_change_cb));
|
|
|
| if (media_drm_bridge->j_media_drm_.is_null())
|
| media_drm_bridge.reset();
|
| @@ -380,14 +396,11 @@ scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(
|
| }
|
|
|
| // static
|
| -scoped_ptr<MediaDrmBridge> MediaDrmBridge::CreateSessionless(
|
| +scoped_ptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport(
|
| const std::string& key_system) {
|
| - return MediaDrmBridge::Create(key_system,
|
| - SessionCreatedCB(),
|
| - SessionMessageCB(),
|
| - SessionReadyCB(),
|
| - SessionClosedCB(),
|
| - SessionErrorCB());
|
| + return MediaDrmBridge::Create(
|
| + key_system, SessionMessageCB(), SessionClosedCB(), SessionErrorCB(),
|
| + SessionKeysChangeCB(), SessionExpirationUpdateCB());
|
| }
|
|
|
| bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) {
|
| @@ -403,27 +416,42 @@ bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) {
|
| env, j_media_drm_.obj(), j_security_level.obj());
|
| }
|
|
|
| -bool MediaDrmBridge::CreateSession(uint32 session_id,
|
| - const std::string& content_type,
|
| - const uint8* init_data,
|
| - int init_data_length) {
|
| +void MediaDrmBridge::SetServerCertificate(
|
| + const uint8* certificate_data,
|
| + int certificate_data_length,
|
| + scoped_ptr<media::SimpleCdmPromise> promise) {
|
| + promise->reject(NOT_SUPPORTED_ERROR, 0,
|
| + "SetServerCertificate() is not supported.");
|
| +}
|
| +
|
| +void MediaDrmBridge::CreateSessionAndGenerateRequest(
|
| + SessionType session_type,
|
| + const std::string& init_data_type,
|
| + const uint8* init_data,
|
| + int init_data_length,
|
| + scoped_ptr<media::NewSessionCdmPromise> promise) {
|
| DVLOG(1) << __FUNCTION__;
|
|
|
| - DCHECK(!session_created_cb_.is_null())
|
| - << "CreateSession called on a sessionless MediaDrmBridge object.";
|
| + if (session_type != media::MediaKeys::TEMPORARY_SESSION) {
|
| + promise->reject(NOT_SUPPORTED_ERROR, 0,
|
| + "Only the temporary session type is supported.");
|
| + return;
|
| + }
|
|
|
| JNIEnv* env = AttachCurrentThread();
|
| ScopedJavaLocalRef<jbyteArray> j_init_data;
|
| // Caller should always use "video/*" content types.
|
| - DCHECK_EQ(0u, content_type.find("video/"));
|
| + DCHECK_EQ(0u, init_data_type.find("video/"));
|
|
|
| // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as
|
| // the init data when using MP4 container.
|
| if (std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid) &&
|
| - content_type == "video/mp4") {
|
| + init_data_type == "video/mp4") {
|
| std::vector<uint8> pssh_data;
|
| - if (!GetPsshData(init_data, init_data_length, scheme_uuid_, &pssh_data))
|
| - return false;
|
| + if (!GetPsshData(init_data, init_data_length, scheme_uuid_, &pssh_data)) {
|
| + promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid PSSH data.");
|
| + return;
|
| + }
|
| j_init_data =
|
| base::android::ToJavaByteArray(env, &pssh_data[0], pssh_data.size());
|
| } else {
|
| @@ -432,41 +460,58 @@ bool MediaDrmBridge::CreateSession(uint32 session_id,
|
| }
|
|
|
| ScopedJavaLocalRef<jstring> j_mime =
|
| - ConvertUTF8ToJavaString(env, content_type);
|
| - Java_MediaDrmBridge_createSession(
|
| - env, j_media_drm_.obj(), session_id, j_init_data.obj(), j_mime.obj());
|
| - return true;
|
| + ConvertUTF8ToJavaString(env, init_data_type);
|
| + uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
|
| + Java_MediaDrmBridge_createSession(env, j_media_drm_.obj(), j_init_data.obj(),
|
| + j_mime.obj(), promise_id);
|
| }
|
|
|
| -void MediaDrmBridge::LoadSession(uint32 session_id,
|
| - const std::string& web_session_id) {
|
| - // MediaDrmBridge doesn't support loading sessions.
|
| - NOTREACHED();
|
| +void MediaDrmBridge::LoadSession(
|
| + SessionType session_type,
|
| + const std::string& session_id,
|
| + scoped_ptr<media::NewSessionCdmPromise> promise) {
|
| + promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported.");
|
| }
|
|
|
| -void MediaDrmBridge::UpdateSession(uint32 session_id,
|
| - const uint8* response,
|
| - int response_length) {
|
| +void MediaDrmBridge::UpdateSession(
|
| + const std::string& session_id,
|
| + const uint8* response,
|
| + int response_length,
|
| + scoped_ptr<media::SimpleCdmPromise> promise) {
|
| DVLOG(1) << __FUNCTION__;
|
|
|
| - DCHECK(!session_ready_cb_.is_null())
|
| - << __FUNCTION__ << " called on a sessionless MediaDrmBridge object.";
|
| -
|
| JNIEnv* env = AttachCurrentThread();
|
| ScopedJavaLocalRef<jbyteArray> j_response =
|
| base::android::ToJavaByteArray(env, response, response_length);
|
| - Java_MediaDrmBridge_updateSession(
|
| - env, j_media_drm_.obj(), session_id, j_response.obj());
|
| + ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray(
|
| + env, reinterpret_cast<const uint8_t*>(session_id.data()),
|
| + session_id.size());
|
| + uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
|
| + Java_MediaDrmBridge_updateSession(env, j_media_drm_.obj(), j_session_id.obj(),
|
| + j_response.obj(), promise_id);
|
| }
|
|
|
| -void MediaDrmBridge::ReleaseSession(uint32 session_id) {
|
| +void MediaDrmBridge::CloseSession(const std::string& session_id,
|
| + scoped_ptr<media::SimpleCdmPromise> promise) {
|
| DVLOG(1) << __FUNCTION__;
|
| + JNIEnv* env = AttachCurrentThread();
|
| + ScopedJavaLocalRef<jbyteArray> j_session_id = base::android::ToJavaByteArray(
|
| + env, reinterpret_cast<const uint8_t*>(session_id.data()),
|
| + session_id.size());
|
| + uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
|
| + Java_MediaDrmBridge_closeSession(env, j_media_drm_.obj(), j_session_id.obj(),
|
| + promise_id);
|
| +}
|
|
|
| - DCHECK(!session_closed_cb_.is_null())
|
| - << __FUNCTION__ << " called on a sessionless MediaDrmBridge object.";
|
| +void MediaDrmBridge::RemoveSession(
|
| + const std::string& session_id,
|
| + scoped_ptr<media::SimpleCdmPromise> promise) {
|
| + promise->reject(NOT_SUPPORTED_ERROR, 0, "RemoveSession() is not supported.");
|
| +}
|
|
|
| - JNIEnv* env = AttachCurrentThread();
|
| - Java_MediaDrmBridge_releaseSession(env, j_media_drm_.obj(), session_id);
|
| +CdmContext* MediaDrmBridge::GetCdmContext() {
|
| + NOTREACHED();
|
| + return nullptr;
|
| }
|
|
|
| int MediaDrmBridge::RegisterPlayer(const base::Closure& new_key_cb,
|
| @@ -500,54 +545,80 @@ void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject) {
|
| base::ResetAndReturn(&media_crypto_ready_cb_).Run();
|
| }
|
|
|
| -void MediaDrmBridge::OnSessionCreated(JNIEnv* env,
|
| - jobject j_media_drm,
|
| - jint j_session_id,
|
| - jstring j_web_session_id) {
|
| - uint32 session_id = j_session_id;
|
| - std::string web_session_id = ConvertJavaStringToUTF8(env, j_web_session_id);
|
| - session_created_cb_.Run(session_id, web_session_id);
|
| +void MediaDrmBridge::OnPromiseResolved(JNIEnv* env,
|
| + jobject j_media_drm,
|
| + jint j_promise_id) {
|
| + cdm_promise_adapter_.ResolvePromise(j_promise_id);
|
| +}
|
| +
|
| +void MediaDrmBridge::OnPromiseResolvedWithSession(JNIEnv* env,
|
| + jobject j_media_drm,
|
| + jint j_promise_id,
|
| + jbyteArray j_session_id) {
|
| + cdm_promise_adapter_.ResolvePromise(j_promise_id,
|
| + GetSessionId(env, j_session_id));
|
| +}
|
| +
|
| +void MediaDrmBridge::OnPromiseRejected(JNIEnv* env,
|
| + jobject j_media_drm,
|
| + jint j_promise_id,
|
| + jstring j_error_message) {
|
| + std::string error_message = ConvertJavaStringToUTF8(env, j_error_message);
|
| + cdm_promise_adapter_.RejectPromise(j_promise_id, MediaKeys::UNKNOWN_ERROR, 0,
|
| + error_message);
|
| }
|
|
|
| void MediaDrmBridge::OnSessionMessage(JNIEnv* env,
|
| jobject j_media_drm,
|
| - jint j_session_id,
|
| + jbyteArray j_session_id,
|
| jbyteArray j_message,
|
| - jstring j_destination_url) {
|
| - uint32 session_id = j_session_id;
|
| + jstring j_legacy_destination_url) {
|
| std::vector<uint8> message;
|
| JavaByteArrayToByteVector(env, j_message, &message);
|
| - GURL destination_gurl = GURL(ConvertJavaStringToUTF8(env, j_destination_url));
|
| - if (!destination_gurl.is_valid() && !destination_gurl.is_empty()) {
|
| - DLOG(WARNING) << "SessionMessage destination_url is invalid : "
|
| - << destination_gurl.possibly_invalid_spec();
|
| - destination_gurl = GURL::EmptyGURL(); // Replace invalid destination_url.
|
| - }
|
| - session_message_cb_.Run(session_id, message, destination_gurl);
|
| -}
|
| + GURL legacy_destination_url =
|
| + GURL(ConvertJavaStringToUTF8(env, j_legacy_destination_url));
|
| + // Note: Message type is not supported in MediaDrm. Do our best guess here.
|
| + media::MediaKeys::MessageType message_type =
|
| + legacy_destination_url.is_empty() ? media::MediaKeys::LICENSE_REQUEST
|
| + : media::MediaKeys::LICENSE_RENEWAL;
|
|
|
| -void MediaDrmBridge::OnSessionReady(JNIEnv* env,
|
| - jobject j_media_drm,
|
| - jint j_session_id) {
|
| - uint32 session_id = j_session_id;
|
| - session_ready_cb_.Run(session_id);
|
| - // TODO(xhwang/jrummell): Move this when usableKeyIds/keyschange are
|
| - // implemented.
|
| - player_tracker_.NotifyNewKey();
|
| + session_message_cb_.Run(GetSessionId(env, j_session_id), message_type,
|
| + message, legacy_destination_url);
|
| }
|
|
|
| void MediaDrmBridge::OnSessionClosed(JNIEnv* env,
|
| jobject j_media_drm,
|
| - jint j_session_id) {
|
| - uint32 session_id = j_session_id;
|
| - session_closed_cb_.Run(session_id);
|
| -}
|
| -
|
| -void MediaDrmBridge::OnSessionError(JNIEnv* env,
|
| - jobject j_media_drm,
|
| - jint j_session_id) {
|
| - uint32 session_id = j_session_id;
|
| - session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0);
|
| + jbyteArray j_session_id) {
|
| + session_closed_cb_.Run(GetSessionId(env, j_session_id));
|
| +}
|
| +
|
| +void MediaDrmBridge::OnSessionKeysChange(JNIEnv* env,
|
| + jobject j_media_drm,
|
| + jbyteArray j_session_id,
|
| + bool has_additional_usable_key,
|
| + jint j_key_status) {
|
| + if (has_additional_usable_key)
|
| + player_tracker_.NotifyNewKey();
|
| +
|
| + scoped_ptr<CdmKeyInformation> cdm_key_information(new CdmKeyInformation());
|
| + cdm_key_information->key_id.assign(kDummyKeyId,
|
| + kDummyKeyId + sizeof(kDummyKeyId));
|
| + cdm_key_information->status =
|
| + static_cast<CdmKeyInformation::KeyStatus>(j_key_status);
|
| + CdmKeysInfo cdm_keys_info;
|
| + cdm_keys_info.push_back(cdm_key_information.release());
|
| +
|
| + session_keys_change_cb_.Run(GetSessionId(env, j_session_id),
|
| + has_additional_usable_key, cdm_keys_info.Pass());
|
| +}
|
| +
|
| +void MediaDrmBridge::OnLegacySessionError(JNIEnv* env,
|
| + jobject j_media_drm,
|
| + jbyteArray j_session_id,
|
| + jstring j_error_message) {
|
| + std::string error_message = ConvertJavaStringToUTF8(env, j_error_message);
|
| + session_error_cb_.Run(GetSessionId(env, j_session_id),
|
| + MediaKeys::UNKNOWN_ERROR, 0, error_message);
|
| }
|
|
|
| ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() {
|
|
|