Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(867)

Unified Diff: media/base/key_systems.cc

Issue 1005903003: Implement robustness strings in requestMediaKeySystemAccess(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix layout tests. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/key_systems.h ('k') | media/base/key_systems_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/key_systems.cc
diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc
index 92bcc38e880877486041d13bbb06c98110eff08d..bf33dccc87bfe8424f95e2a8f329e69fe148310b 100644
--- a/media/base/key_systems.cc
+++ b/media/base/key_systems.cc
@@ -76,6 +76,39 @@ static NamedCodec kCodecStrings[] = {
#endif // defined(USE_PROPRIETARY_CODECS)
};
+static EmeConfigRule ConvertSessionTypeSupport(
+ EmeSessionTypeSupport support) {
+ switch (support) {
+ case EME_SESSION_TYPE_INVALID:
+ NOTREACHED();
+ return EmeConfigRule::NOT_SUPPORTED;
+ case EME_SESSION_TYPE_NOT_SUPPORTED:
+ return EmeConfigRule::NOT_SUPPORTED;
+ case EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER:
+ return EmeConfigRule::IDENTIFIER_REQUIRED;
+ case EME_SESSION_TYPE_SUPPORTED:
+ return EmeConfigRule::SUPPORTED;
+ }
+ NOTREACHED();
+ return EmeConfigRule::NOT_SUPPORTED;
+}
+
+static EmeRobustness ConvertRobustness(const std::string& robustness) {
+ if (robustness.empty())
+ return EmeRobustness::EMPTY;
+ if (robustness == "SW_SECURE_CRYPTO")
+ return EmeRobustness::SW_SECURE_CRYPTO;
+ if (robustness == "SW_SECURE_DECODE")
+ return EmeRobustness::SW_SECURE_DECODE;
+ if (robustness == "HW_SECURE_CRYPTO")
+ return EmeRobustness::HW_SECURE_CRYPTO;
+ if (robustness == "HW_SECURE_DECODE")
+ return EmeRobustness::HW_SECURE_DECODE;
+ if (robustness == "HW_SECURE_ALL")
+ return EmeRobustness::HW_SECURE_ALL;
+ return EmeRobustness::INVALID;
+}
+
static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) {
KeySystemInfo info;
info.key_system = kClearKeyKeySystem;
@@ -103,6 +136,8 @@ static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) {
info.supported_codecs |= EME_CODEC_MP4_ALL;
#endif // defined(USE_PROPRIETARY_CODECS)
+ info.max_audio_robustness = EmeRobustness::EMPTY;
+ info.max_video_robustness = EmeRobustness::EMPTY;
info.persistent_license_support = EME_SESSION_TYPE_NOT_SUPPORTED;
info.persistent_release_message_support = EME_SESSION_TYPE_NOT_SUPPORTED;
info.persistent_state_support = EME_FEATURE_NOT_SUPPORTED;
@@ -191,23 +226,24 @@ class KeySystems {
std::string GetPepperType(const std::string& concrete_key_system);
#endif
- bool IsPersistentLicenseSessionSupported(
+ EmeConfigRule GetRobustnessConfigRule(
const std::string& key_system,
- bool is_permission_granted);
+ EmeMediaType media_type,
+ const std::string& requested_robustness);
- bool IsPersistentReleaseMessageSessionSupported(
- const std::string& key_system,
- bool is_permission_granted);
+ EmeConfigRule GetPersistentLicenseSessionConfigRule(
+ const std::string& key_system);
- bool IsPersistentStateRequirementSupported(
+ EmeConfigRule GetPersistentReleaseMessageSessionConfigRule(
+ const std::string& key_system);
+
+ EmeConfigRule GetPersistentStateConfigRule(
const std::string& key_system,
- EmeFeatureRequirement requirement,
- bool is_permission_granted);
+ EmeFeatureRequirement requirement);
- bool IsDistinctiveIdentifierRequirementSupported(
+ EmeConfigRule GetDistinctiveIdentifierConfigRule(
const std::string& key_system,
- EmeFeatureRequirement requirement,
- bool is_permission_granted);
+ EmeFeatureRequirement requirement);
void AddContainerMask(const std::string& container, uint32 mask);
void AddCodecMask(const std::string& codec, uint32 mask);
@@ -394,45 +430,71 @@ void KeySystems::AddConcreteSupportedKeySystems(
for (const KeySystemInfo& info : concrete_key_systems) {
DCHECK(!info.key_system.empty());
- DCHECK_NE(info.persistent_license_support, EME_SESSION_TYPE_INVALID);
- DCHECK_NE(info.persistent_release_message_support,
- EME_SESSION_TYPE_INVALID);
- // TODO(sandersd): Add REQUESTABLE and REQUESTABLE_WITH_PERMISSION for
- // persistent_state_support once we can block access per-CDM-instance
- // (http://crbug.com/457482).
- DCHECK(info.persistent_state_support == EME_FEATURE_NOT_SUPPORTED ||
- info.persistent_state_support == EME_FEATURE_ALWAYS_ENABLED);
-// TODO(sandersd): Allow REQUESTABLE_WITH_PERMISSION for all key systems on
-// all platforms once we have proper enforcement (http://crbug.com/457482).
-// On Chrome OS, an ID will not be used without permission, but we cannot
-// currently prevent the CDM from requesting the permission again when no
-// there was no initial prompt. Thus, we block "not-allowed" below.
-#if defined(OS_CHROMEOS)
- DCHECK(info.distinctive_identifier_support == EME_FEATURE_NOT_SUPPORTED ||
- (info.distinctive_identifier_support ==
- EME_FEATURE_REQUESTABLE_WITH_PERMISSION &&
- info.key_system == kWidevineKeySystem) ||
- info.distinctive_identifier_support == EME_FEATURE_ALWAYS_ENABLED);
-#else
- DCHECK(info.distinctive_identifier_support == EME_FEATURE_NOT_SUPPORTED ||
- info.distinctive_identifier_support == EME_FEATURE_ALWAYS_ENABLED);
-#endif
+ DCHECK(info.max_audio_robustness != EmeRobustness::INVALID);
+ DCHECK(info.max_video_robustness != EmeRobustness::INVALID);
+ DCHECK(info.persistent_license_support != EME_SESSION_TYPE_INVALID);
+ DCHECK(info.persistent_release_message_support != EME_SESSION_TYPE_INVALID);
+ DCHECK(info.persistent_state_support != EME_FEATURE_INVALID);
+ DCHECK(info.distinctive_identifier_support != EME_FEATURE_INVALID);
+
+ // Supporting persistent state is a prerequsite for supporting persistent
+ // sessions.
if (info.persistent_state_support == EME_FEATURE_NOT_SUPPORTED) {
- DCHECK_EQ(info.persistent_license_support,
- EME_SESSION_TYPE_NOT_SUPPORTED);
- DCHECK_EQ(info.persistent_release_message_support,
- EME_SESSION_TYPE_NOT_SUPPORTED);
+ DCHECK(info.persistent_license_support == EME_SESSION_TYPE_NOT_SUPPORTED);
+ DCHECK(info.persistent_release_message_support ==
+ EME_SESSION_TYPE_NOT_SUPPORTED);
}
- DCHECK(!IsSupportedKeySystem(info.key_system))
- << "Key system '" << info.key_system << "' already registered";
- DCHECK(!parent_key_system_map_.count(info.key_system))
- << "'" << info.key_system << "' is already registered as a parent";
+ else if (info.persistent_state_support ==
+ EME_FEATURE_REQUESTABLE_WITH_IDENTIFIER) {
+ // Must be either NOT_SUPPORTED or SUPPORTED_WITH_IDENTIFIER.
+ DCHECK(info.persistent_license_support != EME_SESSION_TYPE_SUPPORTED);
+ DCHECK(info.persistent_release_message_support !=
+ EME_SESSION_TYPE_SUPPORTED);
+ }
+
+ // persistent-release-message sessions are not currently supported.
+ // http://crbug.com/448888
+ DCHECK(info.persistent_release_message_support ==
+ EME_SESSION_TYPE_NOT_SUPPORTED);
+
+ // Because an optional persistent state value is resolved after an optional
+ // distinctive identifier, persistent state requiring a distinctive
+ // identifier may not resolve correctly.
+ DCHECK(info.persistent_state_support !=
+ EME_FEATURE_REQUESTABLE_WITH_IDENTIFIER);
+
+ // If supported, distinctive identifiers always require permission.
+ DCHECK(info.distinctive_identifier_support != EME_FEATURE_REQUESTABLE);
+
+ // If distinctive identifiers are not supported, then no other features can
+ // require them.
+ if (info.distinctive_identifier_support == EME_FEATURE_NOT_SUPPORTED) {
+ DCHECK(info.persistent_license_support !=
+ EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER);
+ DCHECK(info.persistent_release_message_support !=
+ EME_SESSION_TYPE_SUPPORTED_WITH_IDENTIFIER);
+ }
+
+ // Distinctive identifiers and persistent state can only be reliably blocked
+ // (and therefore be safely configurable) for Pepper-hosted key systems. For
+ // other platforms, only non-configurable values are valid.
+ bool can_block = false;
#if defined(ENABLE_PEPPER_CDMS)
DCHECK_EQ(info.use_aes_decryptor, info.pepper_type.empty());
+ can_block = !info.pepper_type.empty();
#endif
+ if (!can_block) {
+ DCHECK(info.distinctive_identifier_support == EME_FEATURE_NOT_SUPPORTED ||
+ info.distinctive_identifier_support == EME_FEATURE_ALWAYS_ENABLED);
+ DCHECK(info.persistent_state_support == EME_FEATURE_NOT_SUPPORTED ||
+ info.persistent_state_support == EME_FEATURE_ALWAYS_ENABLED);
+ }
+ DCHECK(!IsSupportedKeySystem(info.key_system))
+ << "Key system '" << info.key_system << "' already registered";
+ DCHECK(!parent_key_system_map_.count(info.key_system))
+ << "'" << info.key_system << "' is already registered as a parent";
concrete_key_system_map_[info.key_system] = info;
-
if (!info.parent_key_system.empty()) {
DCHECK(!IsConcreteSupportedKeySystem(info.parent_key_system))
<< "Parent '" << info.parent_key_system << "' "
@@ -620,132 +682,172 @@ std::string KeySystems::GetPepperType(const std::string& concrete_key_system) {
}
#endif
-bool KeySystems::IsPersistentLicenseSessionSupported(
+EmeConfigRule KeySystems::GetRobustnessConfigRule(
const std::string& key_system,
- bool is_permission_granted) {
+ EmeMediaType media_type,
+ const std::string& requested_robustness) {
DCHECK(thread_checker_.CalledOnValidThread());
+ EmeRobustness robustness = ConvertRobustness(requested_robustness);
+ if (robustness == EmeRobustness::INVALID)
+ return EmeConfigRule::NOT_SUPPORTED;
+ if (robustness == EmeRobustness::EMPTY)
+ return EmeConfigRule::SUPPORTED;
+
KeySystemInfoMap::const_iterator key_system_iter =
concrete_key_system_map_.find(key_system);
if (key_system_iter == concrete_key_system_map_.end()) {
NOTREACHED();
- return false;
+ return EmeConfigRule::NOT_SUPPORTED;
}
- switch (key_system_iter->second.persistent_license_support) {
- case EME_SESSION_TYPE_INVALID:
- NOTREACHED();
- return false;
- case EME_SESSION_TYPE_NOT_SUPPORTED:
- return false;
- case EME_SESSION_TYPE_SUPPORTED_WITH_PERMISSION:
- return is_permission_granted;
- case EME_SESSION_TYPE_SUPPORTED:
- return true;
+ EmeRobustness max_robustness = EmeRobustness::INVALID;
+ switch (media_type) {
+ case EmeMediaType::AUDIO:
+ max_robustness = key_system_iter->second.max_audio_robustness;
+ break;
+ case EmeMediaType::VIDEO:
+ max_robustness = key_system_iter->second.max_video_robustness;
+ break;
}
- NOTREACHED();
- return false;
+ // We can compare robustness levels whenever they are not HW_SECURE_CRYPTO
+ // and SW_SECURE_DECODE in some order. If they are exactly those two then the
+ // robustness requirement is not supported.
+ if ((max_robustness == EmeRobustness::HW_SECURE_CRYPTO &&
+ robustness == EmeRobustness::SW_SECURE_DECODE) ||
+ (max_robustness == EmeRobustness::SW_SECURE_DECODE &&
+ robustness == EmeRobustness::HW_SECURE_CRYPTO) ||
+ robustness > max_robustness) {
+ return EmeConfigRule::NOT_SUPPORTED;
+ }
+
+#if defined(OS_CHROMEOS)
+ if (key_system == kWidevineKeySystem) {
+ // Hardware security requires remote attestation.
+ if (robustness >= EmeRobustness::HW_SECURE_CRYPTO)
+ return EmeConfigRule::IDENTIFIER_REQUIRED;
+
+ // For video, recommend remote attestation if HW_SECURE_ALL is available,
+ // because it enables hardware accelerated decoding.
+ // TODO(sandersd): Only do this when hardware accelerated decoding is
+ // available for the requested codecs.
+ if (media_type == EmeMediaType::VIDEO &&
+ max_robustness == EmeRobustness::HW_SECURE_ALL) {
+ return EmeConfigRule::IDENTIFIER_RECOMMENDED;
+ }
+ }
+#endif // defined(OS_CHROMEOS)
+
+ return EmeConfigRule::SUPPORTED;
}
-bool KeySystems::IsPersistentReleaseMessageSessionSupported(
- const std::string& key_system,
- bool is_permission_granted) {
+EmeConfigRule KeySystems::GetPersistentLicenseSessionConfigRule(
+ const std::string& key_system) {
DCHECK(thread_checker_.CalledOnValidThread());
KeySystemInfoMap::const_iterator key_system_iter =
concrete_key_system_map_.find(key_system);
if (key_system_iter == concrete_key_system_map_.end()) {
NOTREACHED();
- return false;
+ return EmeConfigRule::NOT_SUPPORTED;
}
+ return ConvertSessionTypeSupport(
+ key_system_iter->second.persistent_license_support);
+}
- switch (key_system_iter->second.persistent_release_message_support) {
- case EME_SESSION_TYPE_INVALID:
- NOTREACHED();
- return false;
- case EME_SESSION_TYPE_NOT_SUPPORTED:
- return false;
- case EME_SESSION_TYPE_SUPPORTED_WITH_PERMISSION:
- return is_permission_granted;
- case EME_SESSION_TYPE_SUPPORTED:
- return true;
- }
+EmeConfigRule KeySystems::GetPersistentReleaseMessageSessionConfigRule(
+ const std::string& key_system) {
+ DCHECK(thread_checker_.CalledOnValidThread());
- NOTREACHED();
- return false;
+ KeySystemInfoMap::const_iterator key_system_iter =
+ concrete_key_system_map_.find(key_system);
+ if (key_system_iter == concrete_key_system_map_.end()) {
+ NOTREACHED();
+ return EmeConfigRule::NOT_SUPPORTED;
+ }
+ return ConvertSessionTypeSupport(
+ key_system_iter->second.persistent_release_message_support);
}
-bool KeySystems::IsPersistentStateRequirementSupported(
+EmeConfigRule KeySystems::GetPersistentStateConfigRule(
const std::string& key_system,
- EmeFeatureRequirement requirement,
- bool is_permission_granted) {
+ EmeFeatureRequirement requirement) {
DCHECK(thread_checker_.CalledOnValidThread());
KeySystemInfoMap::const_iterator key_system_iter =
concrete_key_system_map_.find(key_system);
if (key_system_iter == concrete_key_system_map_.end()) {
NOTREACHED();
- return false;
+ return EmeConfigRule::NOT_SUPPORTED;
}
- switch (key_system_iter->second.persistent_state_support) {
- case EME_FEATURE_INVALID:
- NOTREACHED();
- return false;
- case EME_FEATURE_NOT_SUPPORTED:
- return requirement != EME_FEATURE_REQUIRED;
- case EME_FEATURE_REQUESTABLE_WITH_PERMISSION:
- return (requirement != EME_FEATURE_REQUIRED) || is_permission_granted;
- case EME_FEATURE_REQUESTABLE:
- return true;
- case EME_FEATURE_ALWAYS_ENABLED:
- // Persistent state does not require user permission, but the session
- // types that use it might.
- return requirement != EME_FEATURE_NOT_ALLOWED;
+ // For NOT_ALLOWED and REQUIRED, the result is as expected. For OPTIONAL, we
+ // return the least restrictive of the two rules; this guarantees that if
+ // OPTIONAL is accepted, then it can always be resolved to some value. (In
+ // fact OPTIONAL is always accepted, because the least restrictive rule is
+ // always SUPPORTED.)
+ //
+ // Note that even if permission is not required for persistent state, it may
+ // be required for specific persistent session types.
+ //
+ // NOT_ALLOWED OPTIONAL REQUIRED
+ // NOT_SUPPORTED SUPPORTED SUPPORTED NOT_SUPPORTED
+ // REQUESTABLE_WITH_IDENTIFIER SUPPORTED SUPPORTED IDENTIFIER_REQ
+ // REQUESTABLE SUPPORTED SUPPORTED SUPPORTED
+ // ALWAYS_ENABLED NOT_SUPPORTED SUPPORTED SUPPORTED
+ EmeFeatureSupport support = key_system_iter->second.persistent_state_support;
+ if (support == EME_FEATURE_NOT_SUPPORTED &&
+ requirement == EME_FEATURE_REQUIRED) {
+ return EmeConfigRule::NOT_SUPPORTED;
}
-
- NOTREACHED();
- return false;
+ if (support == EME_FEATURE_ALWAYS_ENABLED &&
+ requirement == EME_FEATURE_NOT_ALLOWED) {
+ return EmeConfigRule::NOT_SUPPORTED;
+ }
+ if (support == EME_FEATURE_REQUESTABLE_WITH_IDENTIFIER &&
+ requirement == EME_FEATURE_REQUIRED) {
+ return EmeConfigRule::IDENTIFIER_REQUIRED;
+ }
+ return EmeConfigRule::SUPPORTED;
}
-bool KeySystems::IsDistinctiveIdentifierRequirementSupported(
+EmeConfigRule KeySystems::GetDistinctiveIdentifierConfigRule(
const std::string& key_system,
- EmeFeatureRequirement requirement,
- bool is_permission_granted) {
+ EmeFeatureRequirement requirement) {
DCHECK(thread_checker_.CalledOnValidThread());
KeySystemInfoMap::const_iterator key_system_iter =
concrete_key_system_map_.find(key_system);
if (key_system_iter == concrete_key_system_map_.end()) {
NOTREACHED();
- return false;
+ return EmeConfigRule::NOT_SUPPORTED;
}
- switch (key_system_iter->second.distinctive_identifier_support) {
- case EME_FEATURE_INVALID:
- NOTREACHED();
- return false;
- case EME_FEATURE_NOT_SUPPORTED:
- return requirement != EME_FEATURE_REQUIRED;
- case EME_FEATURE_REQUESTABLE_WITH_PERMISSION:
- // TODO(sandersd): Remove this hack once crbug.com/457482 and
- // crbug.com/460616 are addressed.
- // We cannot currently enforce "not-allowed", so don't allow it.
- // Note: Removing this check will expose crbug.com/460616.
- if (requirement == EME_FEATURE_NOT_ALLOWED)
- return false;
- return (requirement != EME_FEATURE_REQUIRED) || is_permission_granted;
- case EME_FEATURE_REQUESTABLE:
- NOTREACHED();
- return true;
- case EME_FEATURE_ALWAYS_ENABLED:
- // Distinctive identifiers always require user permission.
- return (requirement != EME_FEATURE_NOT_ALLOWED) && is_permission_granted;
+ // Permission is required for REQUIRED, but not for NOT_ALLOWED. For OPTIONAL,
+ // we return the least restrictive of the two rules; this guarantees that if
+ // OPTIONAL is accepted, then it can always be resolved to some value.
+ //
+ // NOT_ALLOWED OPTIONAL REQUIRED
+ // NOT_SUPPORTED SUPPORTED SUPPORTED NOT_SUPPORTED
+ // REQUESTABLE_WITH_IDENTIFIER SUPPORTED SUPPORTED IDENTIFIER_REQ
+ // ALWAYS_ENABLED NOT_SUPPORTED IDENTIFIER_REQ IDENTIFIER_REQ
+ EmeFeatureSupport support =
+ key_system_iter->second.distinctive_identifier_support;
+ DCHECK(support != EME_FEATURE_REQUESTABLE);
+ if (support == EME_FEATURE_NOT_SUPPORTED &&
+ requirement == EME_FEATURE_REQUIRED) {
+ return EmeConfigRule::NOT_SUPPORTED;
}
-
- NOTREACHED();
- return false;
+ if (support == EME_FEATURE_ALWAYS_ENABLED &&
+ requirement == EME_FEATURE_NOT_ALLOWED) {
+ return EmeConfigRule::NOT_SUPPORTED;
+ }
+ if (support == EME_FEATURE_ALWAYS_ENABLED ||
+ requirement == EME_FEATURE_REQUIRED) {
+ return EmeConfigRule::IDENTIFIER_REQUIRED;
+ }
+ return EmeConfigRule::SUPPORTED;
}
void KeySystems::AddContainerMask(const std::string& container, uint32 mask) {
@@ -850,34 +952,38 @@ std::string GetPepperType(const std::string& concrete_key_system) {
}
#endif
-bool IsPersistentLicenseSessionSupported(
+EmeConfigRule GetRobustnessConfigRule(
const std::string& key_system,
- bool is_permission_granted) {
- return KeySystems::GetInstance().IsPersistentLicenseSessionSupported(
- key_system, is_permission_granted);
+ EmeMediaType media_type,
+ const std::string& robustness) {
+ return KeySystems::GetInstance().GetRobustnessConfigRule(
+ key_system, media_type, robustness);
}
-bool IsPersistentReleaseMessageSessionSupported(
- const std::string& key_system,
- bool is_permission_granted) {
- return KeySystems::GetInstance().IsPersistentReleaseMessageSessionSupported(
- key_system, is_permission_granted);
+EmeConfigRule GetPersistentLicenseSessionConfigRule(
+ const std::string& key_system) {
+ return KeySystems::GetInstance().GetPersistentLicenseSessionConfigRule(
+ key_system);
+}
+
+EmeConfigRule GetPersistentReleaseMessageSessionConfigRule(
+ const std::string& key_system) {
+ return KeySystems::GetInstance().GetPersistentReleaseMessageSessionConfigRule(
+ key_system);
}
-bool IsPersistentStateRequirementSupported(
+EmeConfigRule GetPersistentStateConfigRule(
const std::string& key_system,
- EmeFeatureRequirement requirement,
- bool is_permission_granted) {
- return KeySystems::GetInstance().IsPersistentStateRequirementSupported(
- key_system, requirement, is_permission_granted);
+ EmeFeatureRequirement requirement) {
+ return KeySystems::GetInstance().GetPersistentStateConfigRule(
+ key_system, requirement);
}
-bool IsDistinctiveIdentifierRequirementSupported(
+EmeConfigRule GetDistinctiveIdentifierConfigRule(
const std::string& key_system,
- EmeFeatureRequirement requirement,
- bool is_permission_granted) {
- return KeySystems::GetInstance().IsDistinctiveIdentifierRequirementSupported(
- key_system, requirement, is_permission_granted);
+ EmeFeatureRequirement requirement) {
+ return KeySystems::GetInstance().GetDistinctiveIdentifierConfigRule(
+ key_system, requirement);
}
// These two functions are for testing purpose only. The declaration in the
« no previous file with comments | « media/base/key_systems.h ('k') | media/base/key_systems_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698