diff options
Diffstat (limited to 'chromium/media/base/android/media_drm_bridge.cc')
-rw-r--r-- | chromium/media/base/android/media_drm_bridge.cc | 211 |
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 |