| 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 96821aec43c07a7fd3e78e847c77d1d3ad7c9377..65decbe2e69b3c8b566d74592a0a74b93e038298 100644
|
| --- a/media/base/android/media_drm_bridge.cc
|
| +++ b/media/base/android/media_drm_bridge.cc
|
| @@ -29,6 +29,7 @@
|
| #include "media/base/android/media_codec_util.h"
|
| #include "media/base/android/media_drm_bridge_delegate.h"
|
| #include "media/base/android/provision_fetcher.h"
|
| +#include "media/base/media_permission.h"
|
| #include "media/base/cdm_key_information.h"
|
| #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
|
|
|
| @@ -74,16 +75,16 @@ const uint8_t kWidevineUuid[16] = {
|
|
|
| // Convert |init_data_type| to a string supported by MediaDRM.
|
| // "audio"/"video" does not matter, so use "video".
|
| -std::string ConvertInitDataType(media::EmeInitDataType init_data_type) {
|
| +std::string ConvertInitDataType(EmeInitDataType init_data_type) {
|
| // TODO(jrummell/xhwang): EME init data types like "webm" and "cenc" are
|
| // supported in API level >=21 for Widevine key system. Switch to use those
|
| // strings when they are officially supported in Android for all key systems.
|
| switch (init_data_type) {
|
| - case media::EmeInitDataType::WEBM:
|
| + case EmeInitDataType::WEBM:
|
| return "video/webm";
|
| - case media::EmeInitDataType::CENC:
|
| + case EmeInitDataType::CENC:
|
| return "video/mp4";
|
| - case media::EmeInitDataType::KEYIDS:
|
| + case EmeInitDataType::KEYIDS:
|
| return "keyids";
|
| default:
|
| NOTREACHED();
|
| @@ -280,7 +281,9 @@ std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() {
|
| // static
|
| scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateInternal(
|
| const std::string& key_system,
|
| + const GURL& security_origin,
|
| SecurityLevel security_level,
|
| + MediaPermission* media_permission,
|
| const CreateFetcherCB& create_fetcher_cb,
|
| const SessionMessageCB& session_message_cb,
|
| const SessionClosedCB& session_closed_cb,
|
| @@ -295,8 +298,9 @@ scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateInternal(
|
| return nullptr;
|
|
|
| scoped_refptr<MediaDrmBridge> media_drm_bridge(new MediaDrmBridge(
|
| - scheme_uuid, security_level, create_fetcher_cb, session_message_cb,
|
| - session_closed_cb, legacy_session_error_cb, session_keys_change_cb,
|
| + scheme_uuid, security_origin, security_level, media_permission,
|
| + create_fetcher_cb, session_message_cb, session_closed_cb,
|
| + legacy_session_error_cb, session_keys_change_cb,
|
| session_expiration_update_cb));
|
|
|
| if (media_drm_bridge->j_media_drm_.is_null())
|
| @@ -308,7 +312,9 @@ scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateInternal(
|
| // static
|
| scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create(
|
| const std::string& key_system,
|
| + const GURL& security_origin,
|
| SecurityLevel security_level,
|
| + MediaPermission* media_permission,
|
| const CreateFetcherCB& create_fetcher_cb,
|
| const SessionMessageCB& session_message_cb,
|
| const SessionClosedCB& session_closed_cb,
|
| @@ -320,10 +326,10 @@ scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create(
|
| if (!IsAvailable())
|
| return nullptr;
|
|
|
| - return CreateInternal(key_system, security_level, create_fetcher_cb,
|
| - session_message_cb, session_closed_cb,
|
| - legacy_session_error_cb, session_keys_change_cb,
|
| - session_expiration_update_cb);
|
| + return CreateInternal(key_system, security_origin, security_level,
|
| + media_permission, create_fetcher_cb, session_message_cb,
|
| + session_closed_cb, legacy_session_error_cb,
|
| + session_keys_change_cb, session_expiration_update_cb);
|
| }
|
|
|
| // static
|
| @@ -337,15 +343,15 @@ scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport(
|
| if (!AreMediaDrmApisAvailable())
|
| return nullptr;
|
|
|
| - return MediaDrmBridge::Create(key_system, security_level, create_fetcher_cb,
|
| - SessionMessageCB(), SessionClosedCB(),
|
| - LegacySessionErrorCB(), SessionKeysChangeCB(),
|
| - SessionExpirationUpdateCB());
|
| + return MediaDrmBridge::Create(
|
| + key_system, GURL(), security_level, nullptr, create_fetcher_cb,
|
| + SessionMessageCB(), SessionClosedCB(), LegacySessionErrorCB(),
|
| + SessionKeysChangeCB(), SessionExpirationUpdateCB());
|
| }
|
|
|
| void MediaDrmBridge::SetServerCertificate(
|
| const std::vector<uint8_t>& certificate,
|
| - scoped_ptr<media::SimpleCdmPromise> promise) {
|
| + scoped_ptr<SimpleCdmPromise> promise) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DVLOG(2) << __FUNCTION__ << "(" << certificate.size() << " bytes)";
|
|
|
| @@ -364,65 +370,38 @@ void MediaDrmBridge::SetServerCertificate(
|
|
|
| void MediaDrmBridge::CreateSessionAndGenerateRequest(
|
| SessionType session_type,
|
| - media::EmeInitDataType init_data_type,
|
| + EmeInitDataType init_data_type,
|
| const std::vector<uint8_t>& init_data,
|
| - scoped_ptr<media::NewSessionCdmPromise> promise) {
|
| + scoped_ptr<NewSessionCdmPromise> promise) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DVLOG(2) << __FUNCTION__;
|
|
|
| - if (session_type != media::MediaKeys::TEMPORARY_SESSION) {
|
| + if (session_type != MediaKeys::TEMPORARY_SESSION) {
|
| NOTIMPLEMENTED() << "EME persistent sessions not yet supported on Android.";
|
| promise->reject(NOT_SUPPORTED_ERROR, 0,
|
| "Only the temporary session type is supported.");
|
| return;
|
| }
|
|
|
| - JNIEnv* env = AttachCurrentThread();
|
| - ScopedJavaLocalRef<jbyteArray> j_init_data;
|
| - ScopedJavaLocalRef<jobjectArray> j_optional_parameters;
|
| -
|
| - MediaClientAndroid* client = GetMediaClientAndroid();
|
| - if (client) {
|
| - MediaDrmBridgeDelegate* delegate =
|
| - client->GetMediaDrmBridgeDelegate(scheme_uuid_);
|
| - if (delegate) {
|
| - std::vector<uint8_t> init_data_from_delegate;
|
| - std::vector<std::string> optional_parameters_from_delegate;
|
| - if (!delegate->OnCreateSession(init_data_type, init_data,
|
| - &init_data_from_delegate,
|
| - &optional_parameters_from_delegate)) {
|
| - promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid init data.");
|
| - return;
|
| - }
|
| - if (!init_data_from_delegate.empty()) {
|
| - j_init_data =
|
| - base::android::ToJavaByteArray(env, init_data_from_delegate.data(),
|
| - init_data_from_delegate.size());
|
| - }
|
| - if (!optional_parameters_from_delegate.empty()) {
|
| - j_optional_parameters = base::android::ToJavaArrayOfStrings(
|
| - env, optional_parameters_from_delegate);
|
| - }
|
| - }
|
| - }
|
| -
|
| - if (j_init_data.is_null()) {
|
| - j_init_data =
|
| - base::android::ToJavaByteArray(env, init_data.data(), init_data.size());
|
| + // TODO(xhwang): |media_permission_| is optional here because when running
|
| + // in the browser process BrowserCdmManager does the permission check. Make
|
| + // |media_permission_| mandatory when BrowserCdmManager is deprecated.
|
| + // See http://crbug.com/581746
|
| + if (!media_permission_) {
|
| + CreateSessionAndGenerateRequestIfPermitted(init_data_type, init_data,
|
| + std::move(promise), true);
|
| + } else {
|
| + media_permission_->HasPermission(
|
| + MediaPermission::PROTECTED_MEDIA_IDENTIFIER, security_origin_,
|
| + base::Bind(&MediaDrmBridge::CreateSessionAndGenerateRequestIfPermitted,
|
| + weak_factory_.GetWeakPtr(), init_data_type, init_data,
|
| + base::Passed(&promise)));
|
| }
|
| -
|
| - ScopedJavaLocalRef<jstring> j_mime =
|
| - ConvertUTF8ToJavaString(env, ConvertInitDataType(init_data_type));
|
| - uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise));
|
| - Java_MediaDrmBridge_createSessionFromNative(
|
| - env, j_media_drm_.obj(), j_init_data.obj(), j_mime.obj(),
|
| - j_optional_parameters.obj(), promise_id);
|
| }
|
|
|
| -void MediaDrmBridge::LoadSession(
|
| - SessionType session_type,
|
| - const std::string& session_id,
|
| - scoped_ptr<media::NewSessionCdmPromise> promise) {
|
| +void MediaDrmBridge::LoadSession(SessionType session_type,
|
| + const std::string& session_id,
|
| + scoped_ptr<NewSessionCdmPromise> promise) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DVLOG(2) << __FUNCTION__;
|
|
|
| @@ -430,10 +409,9 @@ void MediaDrmBridge::LoadSession(
|
| promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported.");
|
| }
|
|
|
| -void MediaDrmBridge::UpdateSession(
|
| - const std::string& session_id,
|
| - const std::vector<uint8_t>& response,
|
| - scoped_ptr<media::SimpleCdmPromise> promise) {
|
| +void MediaDrmBridge::UpdateSession(const std::string& session_id,
|
| + const std::vector<uint8_t>& response,
|
| + scoped_ptr<SimpleCdmPromise> promise) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DVLOG(2) << __FUNCTION__;
|
|
|
| @@ -449,7 +427,7 @@ void MediaDrmBridge::UpdateSession(
|
| }
|
|
|
| void MediaDrmBridge::CloseSession(const std::string& session_id,
|
| - scoped_ptr<media::SimpleCdmPromise> promise) {
|
| + scoped_ptr<SimpleCdmPromise> promise) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DVLOG(2) << __FUNCTION__;
|
|
|
| @@ -462,9 +440,8 @@ void MediaDrmBridge::CloseSession(const std::string& session_id,
|
| promise_id);
|
| }
|
|
|
| -void MediaDrmBridge::RemoveSession(
|
| - const std::string& session_id,
|
| - scoped_ptr<media::SimpleCdmPromise> promise) {
|
| +void MediaDrmBridge::RemoveSession(const std::string& session_id,
|
| + scoped_ptr<SimpleCdmPromise> promise) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DVLOG(2) << __FUNCTION__;
|
|
|
| @@ -762,7 +739,9 @@ void MediaDrmBridge::OnResetDeviceCredentialsCompleted(
|
|
|
| MediaDrmBridge::MediaDrmBridge(
|
| const std::vector<uint8_t>& scheme_uuid,
|
| + const GURL& security_origin,
|
| SecurityLevel security_level,
|
| + MediaPermission* media_permission,
|
| const CreateFetcherCB& create_fetcher_cb,
|
| const SessionMessageCB& session_message_cb,
|
| const SessionClosedCB& session_closed_cb,
|
| @@ -770,6 +749,8 @@ MediaDrmBridge::MediaDrmBridge(
|
| const SessionKeysChangeCB& session_keys_change_cb,
|
| const SessionExpirationUpdateCB& session_expiration_update_cb)
|
| : scheme_uuid_(scheme_uuid),
|
| + security_origin_(security_origin),
|
| + media_permission_(media_permission),
|
| create_fetcher_cb_(create_fetcher_cb),
|
| session_message_cb_(session_message_cb),
|
| session_closed_cb_(session_closed_cb),
|
| @@ -862,6 +843,58 @@ void MediaDrmBridge::NotifyMediaCryptoReady(JavaObjectPtr j_media_crypto) {
|
| IsProtectedSurfaceRequired());
|
| }
|
|
|
| +void MediaDrmBridge::CreateSessionAndGenerateRequestIfPermitted(
|
| + EmeInitDataType init_data_type,
|
| + const std::vector<uint8_t>& init_data,
|
| + scoped_ptr<NewSessionCdmPromise> promise,
|
| + bool permitted) {
|
| + if (!permitted) {
|
| + promise->reject(MediaKeys::NOT_SUPPORTED_ERROR, 0, "Permission denied.");
|
| + return;
|
| + }
|
| +
|
| + JNIEnv* env = AttachCurrentThread();
|
| + ScopedJavaLocalRef<jbyteArray> j_init_data;
|
| + ScopedJavaLocalRef<jobjectArray> j_optional_parameters;
|
| +
|
| + MediaClientAndroid* client = GetMediaClientAndroid();
|
| + if (client) {
|
| + MediaDrmBridgeDelegate* delegate =
|
| + client->GetMediaDrmBridgeDelegate(scheme_uuid_);
|
| + if (delegate) {
|
| + std::vector<uint8_t> init_data_from_delegate;
|
| + std::vector<std::string> optional_parameters_from_delegate;
|
| + if (!delegate->OnCreateSession(init_data_type, init_data,
|
| + &init_data_from_delegate,
|
| + &optional_parameters_from_delegate)) {
|
| + promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid init data.");
|
| + return;
|
| + }
|
| + if (!init_data_from_delegate.empty()) {
|
| + j_init_data =
|
| + base::android::ToJavaByteArray(env, init_data_from_delegate.data(),
|
| + init_data_from_delegate.size());
|
| + }
|
| + if (!optional_parameters_from_delegate.empty()) {
|
| + j_optional_parameters = base::android::ToJavaArrayOfStrings(
|
| + env, optional_parameters_from_delegate);
|
| + }
|
| + }
|
| + }
|
| +
|
| + if (j_init_data.is_null()) {
|
| + j_init_data =
|
| + base::android::ToJavaByteArray(env, init_data.data(), init_data.size());
|
| + }
|
| +
|
| + ScopedJavaLocalRef<jstring> j_mime =
|
| + ConvertUTF8ToJavaString(env, ConvertInitDataType(init_data_type));
|
| + uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise));
|
| + Java_MediaDrmBridge_createSessionFromNative(
|
| + env, j_media_drm_.obj(), j_init_data.obj(), j_mime.obj(),
|
| + j_optional_parameters.obj(), promise_id);
|
| +}
|
| +
|
| void MediaDrmBridge::SendProvisioningRequest(const std::string& default_url,
|
| const std::string& request_data) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
|
|