summaryrefslogtreecommitdiff
path: root/chromium/media/base/android/media_drm_bridge.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/base/android/media_drm_bridge.cc')
-rw-r--r--chromium/media/base/android/media_drm_bridge.cc211
1 files changed, 181 insertions, 30 deletions
diff --git a/chromium/media/base/android/media_drm_bridge.cc b/chromium/media/base/android/media_drm_bridge.cc
index ee4fbbdf115..95f38eddef9 100644
--- a/chromium/media/base/android/media_drm_bridge.cc
+++ b/chromium/media/base/android/media_drm_bridge.cc
@@ -4,11 +4,18 @@
#include "media/base/android/media_drm_bridge.h"
+#include "base/android/build_info.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
+#include "base/callback_helpers.h"
+#include "base/location.h"
#include "base/logging.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "jni/MediaDrmBridge_jni.h"
#include "media/base/android/media_player_manager.h"
+using base::android::AttachCurrentThread;
+using base::android::ConvertUTF8ToJavaString;
using base::android::ConvertJavaStringToUTF8;
using base::android::JavaByteArrayToByteVector;
using base::android::ScopedJavaLocalRef;
@@ -134,54 +141,160 @@ static bool GetPsshData(const uint8* data, int data_size,
return false;
}
+bool MediaDrmBridge::can_use_media_drm_ = 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;
+}
+
+// static
+scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(
+ int media_keys_id,
+ const std::vector<uint8>& scheme_uuid,
+ const GURL& frame_url,
+ const std::string& security_level,
+ MediaPlayerManager* manager) {
+ scoped_ptr<MediaDrmBridge> media_drm_bridge;
+
+ if (IsAvailable() && !scheme_uuid.empty()) {
+ // TODO(qinmin): check whether the uuid is valid.
+ media_drm_bridge.reset(new MediaDrmBridge(
+ media_keys_id, scheme_uuid, frame_url, security_level, manager));
+ if (media_drm_bridge->j_media_drm_.is_null())
+ media_drm_bridge.reset();
+ }
+
+ return media_drm_bridge.Pass();
+}
+
// static
bool MediaDrmBridge::IsAvailable() {
- return false;
+ return can_use_media_drm_ &&
+ base::android::BuildInfo::GetInstance()->sdk_int() >= 18;
+}
+
+// static
+bool MediaDrmBridge::IsSecureDecoderRequired(
+ const std::string& security_level_str) {
+ return IsSecureDecoderRequired(
+ GetSecurityLevelFromString(security_level_str));
}
-MediaDrmBridge* MediaDrmBridge::Create(int media_keys_id,
- const std::vector<uint8>& uuid,
- MediaPlayerManager* manager) {
- if (!IsAvailable())
- return NULL;
+bool MediaDrmBridge::IsSecurityLevelSupported(
+ const std::vector<uint8>& scheme_uuid,
+ const std::string& security_level) {
+ // Pass 0 as |media_keys_id| and NULL as |manager| as they are not used in
+ // creation time of MediaDrmBridge.
+ return MediaDrmBridge::Create(0, scheme_uuid, GURL(), security_level, NULL) !=
+ NULL;
+}
- // TODO(qinmin): check whether the uuid is valid.
- return new MediaDrmBridge(media_keys_id, uuid, manager);
+bool MediaDrmBridge::IsCryptoSchemeSupported(
+ const std::vector<uint8>& scheme_uuid,
+ const std::string& container_mime_type) {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jbyteArray> j_scheme_uuid =
+ base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size());
+ ScopedJavaLocalRef<jstring> j_container_mime_type =
+ ConvertUTF8ToJavaString(env, container_mime_type);
+ return Java_MediaDrmBridge_isCryptoSchemeSupported(
+ env, j_scheme_uuid.obj(), j_container_mime_type.obj());
+}
+
+bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) {
+ return RegisterNativesImpl(env);
}
MediaDrmBridge::MediaDrmBridge(int media_keys_id,
- const std::vector<uint8>& uuid,
+ const std::vector<uint8>& scheme_uuid,
+ const GURL& frame_url,
+ const std::string& security_level,
MediaPlayerManager* manager)
- : media_keys_id_(media_keys_id), uuid_(uuid), manager_(manager) {
- // TODO(qinmin): pass the uuid to DRM engine.
+ : media_keys_id_(media_keys_id),
+ scheme_uuid_(scheme_uuid),
+ frame_url_(frame_url),
+ manager_(manager) {
+ JNIEnv* env = AttachCurrentThread();
+ CHECK(env);
+
+ ScopedJavaLocalRef<jbyteArray> j_scheme_uuid =
+ base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size());
+ ScopedJavaLocalRef<jstring> j_security_level =
+ ConvertUTF8ToJavaString(env, security_level);
+ j_media_drm_.Reset(Java_MediaDrmBridge_create(
+ env, j_scheme_uuid.obj(), j_security_level.obj(),
+ reinterpret_cast<intptr_t>(this)));
}
-MediaDrmBridge::~MediaDrmBridge() {}
+MediaDrmBridge::~MediaDrmBridge() {
+ JNIEnv* env = AttachCurrentThread();
+ if (!j_media_drm_.is_null())
+ Java_MediaDrmBridge_release(env, j_media_drm_.obj());
+}
bool MediaDrmBridge::GenerateKeyRequest(const std::string& type,
const uint8* init_data,
int init_data_length) {
std::vector<uint8> pssh_data;
- if (!GetPsshData(init_data, init_data_length, uuid_, &pssh_data))
+ if (!GetPsshData(init_data, init_data_length, scheme_uuid_, &pssh_data))
return false;
- NOTIMPLEMENTED();
- return false;
-}
-
-void MediaDrmBridge::CancelKeyRequest(const std::string& session_id) {
- NOTIMPLEMENTED();
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jbyteArray> j_pssh_data =
+ base::android::ToJavaByteArray(env, &pssh_data[0], pssh_data.size());
+ ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, type);
+ Java_MediaDrmBridge_generateKeyRequest(
+ env, j_media_drm_.obj(), j_pssh_data.obj(), j_mime.obj());
+ return true;
}
void MediaDrmBridge::AddKey(const uint8* key, int key_length,
const uint8* init_data, int init_data_length,
const std::string& session_id) {
- NOTIMPLEMENTED();
+ DVLOG(1) << __FUNCTION__;
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jbyteArray> j_key_data =
+ base::android::ToJavaByteArray(env, key, key_length);
+ ScopedJavaLocalRef<jstring> j_session_id =
+ ConvertUTF8ToJavaString(env, session_id);
+ Java_MediaDrmBridge_addKey(
+ env, j_media_drm_.obj(), j_session_id.obj(), j_key_data.obj());
}
-ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() {
- NOTIMPLEMENTED();
- return ScopedJavaLocalRef<jobject>();
+void MediaDrmBridge::CancelKeyRequest(const std::string& session_id) {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> j_session_id =
+ ConvertUTF8ToJavaString(env, session_id);
+ Java_MediaDrmBridge_cancelKeyRequest(
+ env, j_media_drm_.obj(), j_session_id.obj());
+}
+
+void MediaDrmBridge::SetMediaCryptoReadyCB(const base::Closure& closure) {
+ if (closure.is_null()) {
+ media_crypto_ready_cb_.Reset();
+ return;
+ }
+
+ DCHECK(media_crypto_ready_cb_.is_null());
+
+ if (!GetMediaCrypto().is_null()) {
+ base::MessageLoopProxy::current()->PostTask(FROM_HERE, closure);
+ return;
+ }
+
+ media_crypto_ready_cb_ = closure;
+}
+
+void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject) {
+ DCHECK(!GetMediaCrypto().is_null());
+ if (!media_crypto_ready_cb_.is_null())
+ base::ResetAndReturn(&media_crypto_ready_cb_).Run();
}
void MediaDrmBridge::OnKeyMessage(JNIEnv* env,
@@ -197,13 +310,51 @@ void MediaDrmBridge::OnKeyMessage(JNIEnv* env,
manager_->OnKeyMessage(media_keys_id_, session_id, message, destination_url);
}
-void MediaDrmBridge::OnDrmEvent(JNIEnv* env,
- jobject j_media_drm,
- jstring session_id,
- jint event,
- jint extra,
- jstring data) {
- NOTIMPLEMENTED();
+void MediaDrmBridge::OnKeyAdded(JNIEnv* env, jobject, jstring j_session_id) {
+ std::string session_id = ConvertJavaStringToUTF8(env, j_session_id);
+ manager_->OnKeyAdded(media_keys_id_, session_id);
+}
+
+void MediaDrmBridge::OnKeyError(JNIEnv* env, jobject, jstring j_session_id) {
+ // |j_session_id| can be NULL, in which case we'll return an empty string.
+ std::string session_id = ConvertJavaStringToUTF8(env, j_session_id);
+ manager_->OnKeyError(media_keys_id_, session_id, MediaKeys::kUnknownError, 0);
+}
+
+ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() {
+ JNIEnv* env = AttachCurrentThread();
+ return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj());
+}
+
+// static
+bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) {
+ return MediaDrmBridge::SECURITY_LEVEL_1 == security_level;
+}
+
+MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> j_security_level =
+ Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_.obj());
+ std::string security_level_str =
+ ConvertJavaStringToUTF8(env, j_security_level.obj());
+ return GetSecurityLevelFromString(security_level_str);
+}
+
+bool MediaDrmBridge::IsProtectedSurfaceRequired() {
+ return IsSecureDecoderRequired(GetSecurityLevel());
+}
+
+void MediaDrmBridge::ResetDeviceCredentials(
+ const ResetCredentialsCB& callback) {
+ DCHECK(reset_credentials_cb_.is_null());
+ reset_credentials_cb_ = callback;
+ JNIEnv* env = AttachCurrentThread();
+ Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj());
+}
+
+void MediaDrmBridge::OnResetDeviceCredentialsCompleted(
+ JNIEnv* env, jobject, bool success) {
+ base::ResetAndReturn(&reset_credentials_cb_).Run(success);
}
} // namespace media