Bug 1189196 - Process MediaKeySystemConfiguration in navigator.requestMediaKeySystemAccess. r=jwwang

This commit is contained in:
Chris Pearce 2015-10-27 14:10:51 +13:00
parent 8f694da3f9
commit 69145d47cd
3 changed files with 121 additions and 8 deletions

View File

@ -381,31 +381,110 @@ GMPDecryptsAndGeckoDecodesAAC(mozIGeckoMediaPluginService* aGMPService,
) && MP4Decoder::CanHandleMediaType(aContentType);
}
static bool
IsSupportedAudio(mozIGeckoMediaPluginService* aGMPService,
const nsAString& aKeySystem,
const nsAString& aAudioType)
{
return IsAACContentType(aAudioType) &&
(GMPDecryptsAndDecodesAAC(aGMPService, aKeySystem) ||
GMPDecryptsAndGeckoDecodesAAC(aGMPService, aKeySystem, aAudioType));
}
static bool
IsSupportedVideo(mozIGeckoMediaPluginService* aGMPService,
const nsAString& aKeySystem,
const nsAString& aVideoType)
{
return IsH264ContentType(aVideoType) &&
(GMPDecryptsAndDecodesH264(aGMPService, aKeySystem) ||
GMPDecryptsAndGeckoDecodesH264(aGMPService, aKeySystem, aVideoType));
}
static bool
IsSupported(mozIGeckoMediaPluginService* aGMPService,
const nsAString& aKeySystem,
const MediaKeySystemConfiguration& aConfig)
{
if (aConfig.mInitDataType.IsEmpty() &&
aConfig.mAudioType.IsEmpty() &&
aConfig.mVideoType.IsEmpty()) {
// Not an old-style request.
return false;
}
// Backwards compatibility with legacy MediaKeySystemConfiguration method.
if (!aConfig.mInitDataType.IsEmpty() &&
!aConfig.mInitDataType.EqualsLiteral("cenc")) {
return false;
}
if (!aConfig.mAudioType.IsEmpty() &&
(!IsAACContentType(aConfig.mAudioType) ||
(!GMPDecryptsAndDecodesAAC(aGMPService, aKeySystem) &&
!GMPDecryptsAndGeckoDecodesAAC(aGMPService, aKeySystem, aConfig.mAudioType)))) {
!IsSupportedAudio(aGMPService, aKeySystem, aConfig.mAudioType)) {
return false;
}
if (!aConfig.mVideoType.IsEmpty() &&
(!IsH264ContentType(aConfig.mVideoType) ||
(!GMPDecryptsAndDecodesH264(aGMPService, aKeySystem) &&
!GMPDecryptsAndGeckoDecodesH264(aGMPService, aKeySystem, aConfig.mVideoType)))) {
!IsSupportedVideo(aGMPService, aKeySystem, aConfig.mVideoType)) {
return false;
}
return true;
}
static bool
GetSupportedConfig(mozIGeckoMediaPluginService* aGMPService,
const nsAString& aKeySystem,
const MediaKeySystemConfiguration& aCandidate,
MediaKeySystemConfiguration& aOutConfig)
{
MediaKeySystemConfiguration config;
config.mLabel = aCandidate.mLabel;
if (aCandidate.mInitDataTypes.WasPassed()) {
nsTArray<nsString> initDataTypes;
for (const nsString& candidate : aCandidate.mInitDataTypes.Value()) {
if (candidate.EqualsLiteral("cenc")) {
initDataTypes.AppendElement(candidate);
}
}
if (initDataTypes.IsEmpty()) {
return false;
}
config.mInitDataTypes.Construct();
config.mInitDataTypes.Value().Assign(initDataTypes);
}
if (aCandidate.mAudioCapabilities.WasPassed()) {
nsTArray<MediaKeySystemMediaCapability> caps;
for (const MediaKeySystemMediaCapability& cap : aCandidate.mAudioCapabilities.Value()) {
if (IsSupportedAudio(aGMPService, aKeySystem, cap.mContentType)) {
caps.AppendElement(cap);
}
}
if (caps.IsEmpty()) {
return false;
}
config.mAudioCapabilities.Construct();
config.mAudioCapabilities.Value().Assign(caps);
}
if (aCandidate.mVideoCapabilities.WasPassed()) {
nsTArray<MediaKeySystemMediaCapability> caps;
for (const MediaKeySystemMediaCapability& cap : aCandidate.mVideoCapabilities.Value()) {
if (IsSupportedVideo(aGMPService, aKeySystem, cap.mContentType)) {
caps.AppendElement(cap);
}
}
if (caps.IsEmpty()) {
return false;
}
config.mVideoCapabilities.Construct();
config.mVideoCapabilities.Value().Assign(caps);
}
aOutConfig = config;
return true;
}
// Backwards compatibility with legacy requestMediaKeySystemAccess with fields
// from old MediaKeySystemOptions dictionary.
/* static */
bool
MediaKeySystemAccess::IsSupported(const nsAString& aKeySystem,
@ -431,6 +510,34 @@ MediaKeySystemAccess::IsSupported(const nsAString& aKeySystem,
return false;
}
/* static */
bool
MediaKeySystemAccess::GetSupportedConfig(const nsAString& aKeySystem,
const Sequence<MediaKeySystemConfiguration>& aConfigs,
MediaKeySystemConfiguration& aOutConfig)
{
nsCOMPtr<mozIGeckoMediaPluginService> mps =
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
if (NS_WARN_IF(!mps)) {
return false;
}
if (!HaveGMPFor(mps,
NS_ConvertUTF16toUTF8(aKeySystem),
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR))) {
return false;
}
for (const MediaKeySystemConfiguration& config : aConfigs) {
if (mozilla::dom::GetSupportedConfig(mps, aKeySystem, config, aOutConfig)) {
return true;
}
}
return false;
}
/* static */
void
MediaKeySystemAccess::NotifyObservers(nsIDOMWindow* aWindow,

View File

@ -45,7 +45,7 @@ public:
void GetKeySystem(nsString& aRetVal) const;
void GetConfiguration(MediaKeySystemConfiguration& aConfig);
already_AddRefed<Promise> CreateMediaKeys(ErrorResult& aRv);
@ -66,6 +66,10 @@ public:
const nsACString& aVersion,
nsACString& aOutMessage);
static bool GetSupportedConfig(const nsAString& aKeySystem,
const Sequence<MediaKeySystemConfiguration>& aConfigs,
MediaKeySystemConfiguration& aOutConfig);
private:
nsCOMPtr<nsPIDOMWindow> mParent;
const nsString mKeySystem;

View File

@ -173,7 +173,9 @@ MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
}
MediaKeySystemConfiguration config;
if (aConfigs.IsEmpty() ||
// TODO: Remove IsSupported() check here once we remove backwards
// compatibility with initial implementation...
if (MediaKeySystemAccess::GetSupportedConfig(keySystem, aConfigs, config) ||
MediaKeySystemAccess::IsSupported(keySystem, aConfigs)) {
RefPtr<MediaKeySystemAccess> access(
new MediaKeySystemAccess(mWindow, keySystem, NS_ConvertUTF8toUTF16(cdmVersion), config));