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 ecac70483763e99f3c0a60f7794615a6d57a9a2f..c429e10f59fd5ca8d96dad367cd9fd4540c8ca04 100644 |
--- a/media/base/android/media_drm_bridge.cc |
+++ b/media/base/android/media_drm_bridge.cc |
@@ -15,6 +15,7 @@ |
#include "base/location.h" |
#include "base/logging.h" |
#include "base/message_loop/message_loop_proxy.h" |
+#include "base/stl_util.h" |
#include "base/strings/string_util.h" |
#include "base/sys_byteorder.h" |
#include "base/sys_info.h" |
@@ -38,6 +39,7 @@ namespace { |
// 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) |
@@ -51,6 +53,7 @@ uint64 ReadUint64(const uint8_t* data) { |
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) { |
@@ -59,6 +62,7 @@ std::string GetSessionId(JNIEnv* env, jbyteArray j_session_id) { |
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. |
@@ -79,12 +83,14 @@ const int kPsshSystemIdSize = 16; |
const int kPsshDataSizeSize = 4; |
const uint32 kTencType = 0x74656e63; |
const uint32 kPsshType = 0x70737368; |
+*/ |
const uint8 kWidevineUuid[16] = { |
0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, |
0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; |
typedef std::vector<uint8> UUID; |
+/* |
// 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. |
@@ -169,6 +175,7 @@ bool GetPsshData(const uint8* data, |
return false; |
} |
+*/ |
class KeySystemUuidManager { |
public: |
@@ -268,6 +275,38 @@ std::string GetSecurityLevelString( |
return ""; |
} |
+class DelegateList { |
+ public: |
+ DelegateList(); |
+ |
+ void RegisterDelegate(const std::string& key_system, |
+ MediaDrmBridge::Delegate* delegate); |
+ MediaDrmBridge::Delegate* GetDelegate(const std::string& key_system); |
+ |
+ private: |
+ std::hash_map<std::string, MediaDrmBridge::Delegate*> delegates_; |
+ DISALLOW_COPY_AND_ASSIGN(DelegateList); |
+}; |
+ |
+base::LazyInstance<DelegateList>::Leaky g_delegates = |
+ LAZY_INSTANCE_INITIALIZER; |
+ |
+DelegateList::DelegateList() { |
+} |
+ |
+void DelegateList::RegisterDelegate( |
+ const std::string& key_system, MediaDrmBridge::Delegate* delegate) { |
+ DCHECK(!ContainsKey(delegates_, key_system)); |
+ delegates_[key_system] = delegate; |
+} |
+ |
+MediaDrmBridge::Delegate* DelegateList::GetDelegate( |
+ const std::string& key_system) { |
+ if (!ContainsKey(delegates_, key_system)) |
+ return nullptr; |
+ return delegates_[key_system]; |
+} |
+ |
} // namespace |
// Called by Java. |
@@ -324,6 +363,12 @@ bool MediaDrmBridge::IsKeySystemSupportedWithType( |
return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); |
} |
+// static |
+void MediaDrmBridge::RegisterDelegate(const std::string& key_system, |
+ Delegate* delegate) { |
+ g_delegates.Get().RegisterDelegate(key_system, delegate); |
+} |
+ |
bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { |
return RegisterNativesImpl(env); |
} |
@@ -333,8 +378,10 @@ MediaDrmBridge::MediaDrmBridge( |
const SessionMessageCB& session_message_cb, |
const SessionClosedCB& session_closed_cb, |
const SessionErrorCB& session_error_cb, |
- const SessionKeysChangeCB& session_keys_change_cb) |
+ const SessionKeysChangeCB& session_keys_change_cb, |
+ Delegate* delegate) |
: scheme_uuid_(scheme_uuid), |
+ delegate_(delegate), |
session_message_cb_(session_message_cb), |
session_closed_cb_(session_closed_cb), |
session_error_cb_(session_error_cb), |
@@ -372,9 +419,10 @@ scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create( |
if (scheme_uuid.empty()) |
return media_drm_bridge.Pass(); |
+ Delegate* delegate = g_delegates.Get().GetDelegate(key_system); |
media_drm_bridge.reset(new MediaDrmBridge(scheme_uuid, session_message_cb, |
session_closed_cb, session_error_cb, |
- session_keys_change_cb)); |
+ session_keys_change_cb, delegate)); |
if (media_drm_bridge->j_media_drm_.is_null()) |
media_drm_bridge.reset(); |
@@ -434,9 +482,12 @@ void MediaDrmBridge::CreateSessionAndGenerateRequest( |
JNIEnv* env = AttachCurrentThread(); |
ScopedJavaLocalRef<jbyteArray> j_init_data; |
+ ScopedJavaLocalRef<jobjectArray> j_additional_data; |
// Caller should always use "video/*" content types. |
DCHECK_EQ(0u, init_data_type.find("video/")); |
+/* |
+ TODO: find an appropriate place for this to live. |
// 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) && |
@@ -448,7 +499,26 @@ void MediaDrmBridge::CreateSessionAndGenerateRequest( |
} |
j_init_data = |
base::android::ToJavaByteArray(env, &pssh_data[0], pssh_data.size()); |
- } else { |
+ } |
+*/ |
+ |
+ if (delegate_) { |
+ std::vector<uint8> init_data_from_delegate; |
+ std::vector<std::string> additional_data_from_delegate; |
+ delegate_->OnCreateSession(init_data_type, init_data, init_data_length, |
+ init_data_from_delegate, |
+ additional_data_from_delegate); |
+ if (!init_data_from_delegate.empty()) { |
+ j_init_data = base::android::ToJavaByteArray( |
+ env, &init_data_from_delegate[0], init_data_from_delegate.size()); |
+ } |
+ if (!additional_data_from_delegate.empty()) { |
+ j_additional_data = base::android::ToJavaArrayOfStrings( |
+ env, additional_data_from_delegate); |
+ } |
+ } |
+ |
+ if (j_init_data.is_null()) { |
j_init_data = |
base::android::ToJavaByteArray(env, init_data, init_data_length); |
} |
@@ -457,7 +527,8 @@ void MediaDrmBridge::CreateSessionAndGenerateRequest( |
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); |
+ j_mime.obj(), j_additional_data.obj(), |
+ promise_id); |
} |
void MediaDrmBridge::LoadSession( |