Commit 02d9aea8 authored by sandersd's avatar sandersd Committed by Commit bot

Restrict use of hardware-secure codecs based on the RendererPreference.

This passes the value of |use_video_overlay_for_embedded_encrypted_video| from RendererPreferences to requestMediaKeySystemAccess() so that it can correctly block either non-hardware-secure codecs or hardware-secure codecs.

BUG=467779

Review URL: https://codereview.chromium.org/1124863005

Cr-Commit-Position: refs/heads/master@{#329329}
parent 3ee04f75
......@@ -109,6 +109,12 @@ bool CanNavigateLocally(blink::WebFrame* frame,
return false;
}
bool AreSecureCodecsSupported() {
// Hardware-secure codecs are not currently supported by HTML Viewer on any
// platform.
return false;
}
} // namespace
HTMLDocument::HTMLDocument(
......@@ -328,7 +334,8 @@ void HTMLDocument::didNavigateWithinPage(
blink::WebEncryptedMediaClient* HTMLDocument::encryptedMediaClient() {
if (!web_encrypted_media_client_) {
web_encrypted_media_client_.reset(new media::WebEncryptedMediaClientImpl(
GetCdmFactory(), GetMediaPermission()));
base::Bind(&AreSecureCodecsSupported), GetCdmFactory(),
GetMediaPermission()));
}
return web_encrypted_media_client_.get();
}
......
......@@ -3587,6 +3587,11 @@ blink::WebUserMediaClient* RenderFrameImpl::userMediaClient() {
blink::WebEncryptedMediaClient* RenderFrameImpl::encryptedMediaClient() {
if (!web_encrypted_media_client_) {
web_encrypted_media_client_.reset(new media::WebEncryptedMediaClientImpl(
// base::Unretained(this) is safe because WebEncryptedMediaClientImpl
// is destructed before |this|, and does not give away ownership of the
// callback.
base::Bind(&RenderFrameImpl::AreSecureCodecsSupported,
base::Unretained(this)),
GetCdmFactory(), GetMediaPermission()));
}
return web_encrypted_media_client_.get();
......@@ -4927,6 +4932,16 @@ media::MediaPermission* RenderFrameImpl::GetMediaPermission() {
return media_permission_dispatcher_;
}
bool RenderFrameImpl::AreSecureCodecsSupported() {
#if defined(OS_ANDROID)
// Hardware-secure codecs are only supported if secure surfaces are enabled.
return render_view_->renderer_preferences_
.use_video_overlay_for_embedded_encrypted_video;
#else
return false;
#endif // defined(OS_ANDROID)
}
media::CdmFactory* RenderFrameImpl::GetCdmFactory() {
#if defined(ENABLE_BROWSER_CDMS)
if (!cdm_manager_)
......
......@@ -813,6 +813,7 @@ class CONTENT_EXPORT RenderFrameImpl
RendererMediaPlayerManager* GetMediaPlayerManager();
#endif
bool AreSecureCodecsSupported();
media::MediaPermission* GetMediaPermission();
media::CdmFactory* GetCdmFactory();
......
......@@ -129,15 +129,14 @@ enum class EmeConfigRule {
// The configuration option is supported if both a distinctive identifier and
// persistent state are available.
IDENTIFIER_AND_PERSISTENCE_REQUIRED,
#if defined(OS_ANDROID)
// The configuration option is supported if no hardware-secure codecs are used
// (as they would be for video if secure surfaces are enabled).
// The configuration option prevents use of hardware-secure codecs.
// This rule only has meaning on platforms that distinguish hardware-secure
// codecs (ie. Android).
SECURE_CODECS_NOT_ALLOWED,
// The configuration option is supported if only hardware-secure codecs are
// used. This implies that secure surfaces (hole-punching) are required for
// video.
// The configuration option is supported if hardware-secure codecs are used.
// This rule only has meaning on platforms that distinguish hardware-secure
// codecs (ie. Android).
SECURE_CODECS_REQUIRED,
#endif // defined(OS_ANDROID)
// The configuration option is supported without conditions.
SUPPORTED,
};
......
......@@ -716,8 +716,10 @@ EmeConfigRule KeySystemsImpl::GetContentTypeConfigRule(
if ((codec & key_system_codec_mask & container_codec_mask) == 0)
return EmeConfigRule::NOT_SUPPORTED;
#if defined(OS_ANDROID)
// Check whether the codec supports a hardware-secure mode; if not, indicate
// that hardware-secure codecs are not available for all listed codecs.
// Check whether the codec supports a hardware-secure mode. The goal is to
// prevent mixing of non-hardware-secure codecs with hardware-secure codecs,
// since the mode is fixed at CDM creation.
//
// Because the check for regular codec support is early-exit, we don't have
// to consider codecs that are only supported in hardware-secure mode. We
// could do so, and make use of SECURE_CODECS_REQUIRED, if it turns out that
......@@ -725,7 +727,6 @@ EmeConfigRule KeySystemsImpl::GetContentTypeConfigRule(
if ((codec & key_system_secure_codec_mask) == 0)
support = EmeConfigRule::SECURE_CODECS_NOT_ALLOWED;
#endif // defined(OS_ANDROID)
}
return support;
......
......@@ -131,11 +131,12 @@ struct KeySystemConfigSelector::SelectionRequest {
blink::WebVector<blink::WebMediaKeySystemConfiguration>
candidate_configurations;
blink::WebSecurityOrigin security_origin;
base::Callback<void(const blink::WebMediaKeySystemConfiguration&)>
base::Callback<void(const blink::WebMediaKeySystemConfiguration&, bool)>
succeeded_cb;
base::Callback<void(const blink::WebString&)> not_supported_cb;
bool was_permission_requested = false;
bool is_permission_granted = false;
bool are_secure_codecs_supported = false;
};
// Accumulates configuration rules to determine if a feature (additional
......@@ -157,6 +158,10 @@ class KeySystemConfigSelector::ConfigState {
bool IsIdentifierRecommended() const { return is_identifier_recommended_; }
bool AreSecureCodecsRequired() const {
return are_secure_codecs_required_;
}
// Checks whether a rule is compatible with all previously added rules.
bool IsRuleSupported(EmeConfigRule rule) const {
switch (rule) {
......@@ -177,12 +182,10 @@ class KeySystemConfigSelector::ConfigState {
case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED:
return (!is_identifier_not_allowed_ && IsPermissionPossible() &&
!is_persistence_not_allowed_);
#if defined(OS_ANDROID)
case EmeConfigRule::SECURE_CODECS_NOT_ALLOWED:
return !are_secure_codecs_required_;
case EmeConfigRule::SECURE_CODECS_REQUIRED:
return !are_secure_codecs_not_allowed_;
#endif // defined(OS_ANDROID)
case EmeConfigRule::SUPPORTED:
return true;
}
......@@ -216,14 +219,12 @@ class KeySystemConfigSelector::ConfigState {
is_identifier_required_ = true;
is_persistence_required_ = true;
return;
#if defined(OS_ANDROID)
case EmeConfigRule::SECURE_CODECS_NOT_ALLOWED:
are_secure_codecs_not_allowed_ = true;
return;
case EmeConfigRule::SECURE_CODECS_REQUIRED:
are_secure_codecs_required_ = true;
return;
#endif // defined(OS_ANDROID)
case EmeConfigRule::SUPPORTED:
return;
}
......@@ -252,11 +253,10 @@ class KeySystemConfigSelector::ConfigState {
bool is_persistence_required_ = false;
bool is_persistence_not_allowed_ = false;
#if defined(OS_ANDROID)
// Whether a rule has been added that requires or blocks secure codecs.
// Whether a rule has been added that requires or blocks hardware-secure
// codecs.
bool are_secure_codecs_required_ = false;
bool are_secure_codecs_not_allowed_ = false;
#endif // defined(OS_ANDROID)
};
KeySystemConfigSelector::KeySystemConfigSelector(
......@@ -392,7 +392,6 @@ KeySystemConfigSelector::GetSupportedConfiguration(
const blink::WebMediaKeySystemConfiguration& candidate,
ConfigState* config_state,
blink::WebMediaKeySystemConfiguration* accumulated_configuration) {
// TODO(sandersd): Set state of SECURE_CODECS from renderer pref.
// From https://w3c.github.io/encrypted-media/#get-supported-configuration
// 1. Let accumulated configuration be empty. (Done by caller.)
// 2. If the initDataTypes member is present in candidate configuration, run
......@@ -673,7 +672,8 @@ void KeySystemConfigSelector::SelectConfig(
const blink::WebVector<blink::WebMediaKeySystemConfiguration>&
candidate_configurations,
const blink::WebSecurityOrigin& security_origin,
base::Callback<void(const blink::WebMediaKeySystemConfiguration&)>
bool are_secure_codecs_supported,
base::Callback<void(const blink::WebMediaKeySystemConfiguration&, bool)>
succeeded_cb,
base::Callback<void(const blink::WebString&)> not_supported_cb) {
// Continued from requestMediaKeySystemAccess(), step 7, from
......@@ -699,6 +699,7 @@ void KeySystemConfigSelector::SelectConfig(
request->key_system = key_system_ascii;
request->candidate_configurations = candidate_configurations;
request->security_origin = security_origin;
request->are_secure_codecs_supported = are_secure_codecs_supported;
request->succeeded_cb = succeeded_cb;
request->not_supported_cb = not_supported_cb;
SelectConfigInternal(request.Pass());
......@@ -721,6 +722,10 @@ void KeySystemConfigSelector::SelectConfigInternal(
// new MediaKeySystemAccess object.]
ConfigState config_state(request->was_permission_requested,
request->is_permission_granted);
DCHECK(config_state.IsRuleSupported(
EmeConfigRule::SECURE_CODECS_NOT_ALLOWED));
if (!request->are_secure_codecs_supported)
config_state.AddRule(EmeConfigRule::SECURE_CODECS_NOT_ALLOWED);
blink::WebMediaKeySystemConfiguration accumulated_configuration;
ConfigurationSupport support = GetSupportedConfiguration(
request->key_system, request->candidate_configurations[i],
......@@ -741,7 +746,8 @@ void KeySystemConfigSelector::SelectConfigInternal(
weak_factory_.GetWeakPtr(), base::Passed(&request)));
return;
case CONFIGURATION_SUPPORTED:
request->succeeded_cb.Run(accumulated_configuration);
request->succeeded_cb.Run(accumulated_configuration,
config_state.AreSecureCodecsRequired());
return;
}
}
......
......@@ -9,6 +9,7 @@
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "media/base/eme_constants.h"
......@@ -31,8 +32,9 @@ class MediaPermission;
class MEDIA_EXPORT KeySystemConfigSelector {
public:
KeySystemConfigSelector(const KeySystems* key_systems,
MediaPermission* media_permission);
KeySystemConfigSelector(
const KeySystems* key_systems,
MediaPermission* media_permission);
~KeySystemConfigSelector();
......@@ -41,8 +43,10 @@ class MEDIA_EXPORT KeySystemConfigSelector {
const blink::WebVector<blink::WebMediaKeySystemConfiguration>&
candidate_configurations,
const blink::WebSecurityOrigin& security_origin,
base::Callback<void(const blink::WebMediaKeySystemConfiguration&)>
succeeded_cb,
bool are_secure_codecs_supported,
// The second argument is |are_secure_codecs_required|.
base::Callback<void(const blink::WebMediaKeySystemConfiguration&,
bool)> succeeded_cb,
base::Callback<void(const blink::WebString&)> not_supported_cb);
private:
......
......@@ -170,7 +170,7 @@ class KeySystemConfigSelectorTest : public testing::Test {
succeeded_count_ = 0;
not_supported_count_ = 0;
KeySystemConfigSelector(key_systems_.get(), media_permission_.get())
.SelectConfig(key_system_, configs_, security_origin_,
.SelectConfig(key_system_, configs_, security_origin_, false,
base::Bind(&KeySystemConfigSelectorTest::OnSucceeded,
base::Unretained(this)),
base::Bind(&KeySystemConfigSelectorTest::OnNotSupported,
......@@ -209,7 +209,8 @@ class KeySystemConfigSelectorTest : public testing::Test {
return (media_permission_->requests != 0 && not_supported_count_ != 0);
}
void OnSucceeded(const blink::WebMediaKeySystemConfiguration& result) {
void OnSucceeded(const blink::WebMediaKeySystemConfiguration& result,
bool are_secure_codecs_required) {
succeeded_count_++;
config_ = result;
}
......
......@@ -78,9 +78,11 @@ class WebEncryptedMediaClientImpl::Reporter {
};
WebEncryptedMediaClientImpl::WebEncryptedMediaClientImpl(
base::Callback<bool(void)> are_secure_codecs_supported_cb,
CdmFactory* cdm_factory,
MediaPermission* media_permission)
: cdm_factory_(cdm_factory),
: are_secure_codecs_supported_cb_(are_secure_codecs_supported_cb),
cdm_factory_(cdm_factory),
key_system_config_selector_(KeySystems::GetInstance(), media_permission),
weak_factory_(this) {
DCHECK(cdm_factory_);
......@@ -94,7 +96,7 @@ void WebEncryptedMediaClientImpl::requestMediaKeySystemAccess(
GetReporter(request.keySystem())->ReportRequested();
key_system_config_selector_.SelectConfig(
request.keySystem(), request.supportedConfigurations(),
request.securityOrigin(),
request.securityOrigin(), are_secure_codecs_supported_cb_.Run(),
base::Bind(&WebEncryptedMediaClientImpl::OnRequestSucceeded,
weak_factory_.GetWeakPtr(), request),
base::Bind(&WebEncryptedMediaClientImpl::OnRequestNotSupported,
......@@ -114,8 +116,11 @@ void WebEncryptedMediaClientImpl::CreateCdm(
void WebEncryptedMediaClientImpl::OnRequestSucceeded(
blink::WebEncryptedMediaRequest request,
const blink::WebMediaKeySystemConfiguration& accumulated_configuration) {
const blink::WebMediaKeySystemConfiguration& accumulated_configuration,
bool are_secure_codecs_required) {
GetReporter(request.keySystem())->ReportSupported();
// TODO(sandersd): Pass |are_secure_codecs_required| along and use it to
// configure the CDM security level and use of secure surfaces on Android.
request.requestSucceeded(WebContentDecryptionModuleAccessImpl::Create(
request.keySystem(), accumulated_configuration, request.securityOrigin(),
weak_factory_.GetWeakPtr()));
......
......@@ -7,6 +7,7 @@
#include <string>
#include "base/callback.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
......@@ -31,8 +32,10 @@ class MediaPermission;
class MEDIA_EXPORT WebEncryptedMediaClientImpl
: public blink::WebEncryptedMediaClient {
public:
WebEncryptedMediaClientImpl(CdmFactory* cdm_factory,
MediaPermission* media_permission);
WebEncryptedMediaClientImpl(
base::Callback<bool(void)> are_secure_codecs_supported_cb,
CdmFactory* cdm_factory,
MediaPermission* media_permission);
virtual ~WebEncryptedMediaClientImpl();
// WebEncryptedMediaClient implementation.
......@@ -58,7 +61,8 @@ class MEDIA_EXPORT WebEncryptedMediaClientImpl
// accumulated configuration.
void OnRequestSucceeded(
blink::WebEncryptedMediaRequest request,
const blink::WebMediaKeySystemConfiguration& accumulated_configuration);
const blink::WebMediaKeySystemConfiguration& accumulated_configuration,
bool are_secure_codecs_required);
// Complete a requestMediaKeySystemAccess() request with an error message.
void OnRequestNotSupported(blink::WebEncryptedMediaRequest request,
......@@ -71,6 +75,7 @@ class MEDIA_EXPORT WebEncryptedMediaClientImpl
// Reporter singletons.
base::ScopedPtrHashMap<std::string, scoped_ptr<Reporter>> reporters_;
base::Callback<bool(void)> are_secure_codecs_supported_cb_;
CdmFactory* cdm_factory_;
KeySystemConfigSelector key_system_config_selector_;
base::WeakPtrFactory<WebEncryptedMediaClientImpl> weak_factory_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment