зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1471165 - P1. Simulate required MediaCapabilities members in optional dictionary. r=bz
Summary: In order to allow for optional dictionaries with required members See https://github.com/heycam/webidl/issues/76 for more information. Reviewers: bzbarsky Tags: #secure-revision Bug #: 1471165 Differential Revision: https://phabricator.services.mozilla.com/D1833
This commit is contained in:
Родитель
cab83f1874
Коммит
138b0b299d
|
@ -262,10 +262,16 @@ MakeMediaExtendedMIMEType(const nsAString& aType)
|
|||
Maybe<MediaExtendedMIMEType>
|
||||
MakeMediaExtendedMIMEType(const dom::VideoConfiguration& aConfig)
|
||||
{
|
||||
if (aConfig.mContentType.IsEmpty()) {
|
||||
MOZ_ASSERT(aConfig.mContentType.WasPassed() &&
|
||||
aConfig.mFramerate.WasPassed() &&
|
||||
aConfig.mWidth.WasPassed() &&
|
||||
aConfig.mHeight.WasPassed() &&
|
||||
aConfig.mBitrate.WasPassed(),
|
||||
"All dictionary members must be present");
|
||||
if (aConfig.mContentType.Value().IsEmpty()) {
|
||||
return Nothing();
|
||||
}
|
||||
nsContentTypeParser parser(aConfig.mContentType);
|
||||
nsContentTypeParser parser(aConfig.mContentType.Value());
|
||||
nsAutoString mime;
|
||||
nsresult rv = parser.GetType(mime);
|
||||
if (!NS_SUCCEEDED(rv) || mime.IsEmpty()) {
|
||||
|
@ -282,28 +288,30 @@ MakeMediaExtendedMIMEType(const dom::VideoConfiguration& aConfig)
|
|||
bool haveCodecs = NS_SUCCEEDED(rv);
|
||||
|
||||
auto framerate =
|
||||
MediaExtendedMIMEType::ComputeFractionalString(aConfig.mFramerate);
|
||||
MediaExtendedMIMEType::ComputeFractionalString(aConfig.mFramerate.Value());
|
||||
if (!framerate) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
return Some(MediaExtendedMIMEType(NS_ConvertUTF16toUTF8(aConfig.mContentType),
|
||||
mime8,
|
||||
haveCodecs,
|
||||
codecs,
|
||||
aConfig.mWidth,
|
||||
aConfig.mHeight,
|
||||
framerate.ref(),
|
||||
aConfig.mBitrate));
|
||||
return Some(
|
||||
MediaExtendedMIMEType(NS_ConvertUTF16toUTF8(aConfig.mContentType.Value()),
|
||||
mime8,
|
||||
haveCodecs,
|
||||
codecs,
|
||||
aConfig.mWidth.Value(),
|
||||
aConfig.mHeight.Value(),
|
||||
framerate.ref(),
|
||||
aConfig.mBitrate.Value()));
|
||||
}
|
||||
|
||||
Maybe<MediaExtendedMIMEType>
|
||||
MakeMediaExtendedMIMEType(const dom::AudioConfiguration& aConfig)
|
||||
{
|
||||
if (aConfig.mContentType.IsEmpty()) {
|
||||
if (!aConfig.mContentType.WasPassed() ||
|
||||
aConfig.mContentType.Value().IsEmpty()) {
|
||||
return Nothing();
|
||||
}
|
||||
nsContentTypeParser parser(aConfig.mContentType);
|
||||
nsContentTypeParser parser(aConfig.mContentType.Value());
|
||||
nsAutoString mime;
|
||||
nsresult rv = parser.GetType(mime);
|
||||
if (!NS_SUCCEEDED(rv) || mime.IsEmpty()) {
|
||||
|
@ -335,7 +343,7 @@ MakeMediaExtendedMIMEType(const dom::AudioConfiguration& aConfig)
|
|||
}
|
||||
|
||||
return Some(MediaExtendedMIMEType(
|
||||
NS_ConvertUTF16toUTF8(aConfig.mContentType),
|
||||
NS_ConvertUTF16toUTF8(aConfig.mContentType.Value()),
|
||||
mime8,
|
||||
haveCodecs,
|
||||
codecs,
|
||||
|
|
|
@ -32,6 +32,54 @@ MediaCapabilities::MediaCapabilities(nsIGlobalObject* aParent)
|
|||
{
|
||||
}
|
||||
|
||||
static void
|
||||
ThrowWithMemberName(ErrorResult& aRv,
|
||||
const char* aCategory,
|
||||
const char* aMember)
|
||||
{
|
||||
auto str = nsPrintfCString("'%s' member of %s", aMember, aCategory);
|
||||
aRv.ThrowTypeError<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>(
|
||||
NS_ConvertUTF8toUTF16(str));
|
||||
}
|
||||
|
||||
static void
|
||||
CheckVideoConfigurationSanity(const VideoConfiguration& aConfig,
|
||||
const char* aCategory,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!aConfig.mContentType.WasPassed()) {
|
||||
ThrowWithMemberName(aRv, "contentType", aCategory);
|
||||
return;
|
||||
}
|
||||
if (!aConfig.mWidth.WasPassed()) {
|
||||
ThrowWithMemberName(aRv, "width", aCategory);
|
||||
return;
|
||||
}
|
||||
if (!aConfig.mHeight.WasPassed()) {
|
||||
ThrowWithMemberName(aRv, "height", aCategory);
|
||||
return;
|
||||
}
|
||||
if (!aConfig.mBitrate.WasPassed()) {
|
||||
ThrowWithMemberName(aRv, "bitrate", aCategory);
|
||||
return;
|
||||
}
|
||||
if (!aConfig.mFramerate.WasPassed()) {
|
||||
ThrowWithMemberName(aRv, "framerate", aCategory);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CheckAudioConfigurationSanity(const AudioConfiguration& aConfig,
|
||||
const char* aCategory,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!aConfig.mContentType.WasPassed()) {
|
||||
ThrowWithMemberName(aRv, "contentType", aCategory);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MediaCapabilities::DecodingInfo(
|
||||
const MediaDecodingConfiguration& aConfiguration,
|
||||
|
@ -52,6 +100,25 @@ MediaCapabilities::DecodingInfo(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Here we will throw rather than rejecting a promise in order to simulate
|
||||
// optional dictionaries with required members (see bug 1368949)
|
||||
if (aConfiguration.mVideo.IsAnyMemberPresent()) {
|
||||
// Check that all VideoConfiguration required members are present.
|
||||
CheckVideoConfigurationSanity(
|
||||
aConfiguration.mVideo, "MediaDecodingConfiguration", aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (aConfiguration.mAudio.IsAnyMemberPresent()) {
|
||||
// Check that all AudioConfiguration required members are present.
|
||||
CheckAudioConfigurationSanity(
|
||||
aConfiguration.mAudio, "MediaDecodingConfiguration", aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool supported = true;
|
||||
Maybe<MediaContainerType> videoContainer;
|
||||
Maybe<MediaContainerType> audioContainer;
|
||||
|
@ -68,8 +135,8 @@ MediaCapabilities::DecodingInfo(
|
|||
// We have a video configuration and it is valid. Check if it is supported.
|
||||
supported &=
|
||||
aConfiguration.mType == MediaDecodingType::File
|
||||
? CheckTypeForFile(aConfiguration.mVideo.mContentType)
|
||||
: CheckTypeForMediaSource(aConfiguration.mVideo.mContentType);
|
||||
? CheckTypeForFile(aConfiguration.mVideo.mContentType.Value())
|
||||
: CheckTypeForMediaSource(aConfiguration.mVideo.mContentType.Value());
|
||||
}
|
||||
if (aConfiguration.mAudio.IsAnyMemberPresent()) {
|
||||
audioContainer = CheckAudioConfiguration(aConfiguration.mAudio);
|
||||
|
@ -80,8 +147,8 @@ MediaCapabilities::DecodingInfo(
|
|||
// We have an audio configuration and it is valid. Check if it is supported.
|
||||
supported &=
|
||||
aConfiguration.mType == MediaDecodingType::File
|
||||
? CheckTypeForFile(aConfiguration.mAudio.mContentType)
|
||||
: CheckTypeForMediaSource(aConfiguration.mAudio.mContentType);
|
||||
? CheckTypeForFile(aConfiguration.mAudio.mContentType.Value())
|
||||
: CheckTypeForMediaSource(aConfiguration.mAudio.mContentType.Value());
|
||||
}
|
||||
|
||||
if (!supported) {
|
||||
|
@ -323,6 +390,25 @@ MediaCapabilities::EncodingInfo(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Here we will throw rather than rejecting a promise in order to simulate
|
||||
// optional dictionaries with required members (see bug 1368949)
|
||||
if (aConfiguration.mVideo.IsAnyMemberPresent()) {
|
||||
// Check that all VideoConfiguration required members are present.
|
||||
CheckVideoConfigurationSanity(
|
||||
aConfiguration.mVideo, "MediaDecodingConfiguration", aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (aConfiguration.mAudio.IsAnyMemberPresent()) {
|
||||
// Check that all AudioConfiguration required members are present.
|
||||
CheckAudioConfigurationSanity(
|
||||
aConfiguration.mAudio, "MediaDecodingConfiguration", aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool supported = true;
|
||||
|
||||
// If configuration.video is present and is not a valid video configuration,
|
||||
|
@ -333,7 +419,8 @@ MediaCapabilities::EncodingInfo(
|
|||
return nullptr;
|
||||
}
|
||||
// We have a video configuration and it is valid. Check if it is supported.
|
||||
supported &= CheckTypeForEncoder(aConfiguration.mVideo.mContentType);
|
||||
supported &=
|
||||
CheckTypeForEncoder(aConfiguration.mVideo.mContentType.Value());
|
||||
}
|
||||
if (aConfiguration.mAudio.IsAnyMemberPresent()) {
|
||||
if (!CheckAudioConfiguration(aConfiguration.mAudio)) {
|
||||
|
@ -341,7 +428,8 @@ MediaCapabilities::EncodingInfo(
|
|||
return nullptr;
|
||||
}
|
||||
// We have an audio configuration and it is valid. Check if it is supported.
|
||||
supported &= CheckTypeForEncoder(aConfiguration.mAudio.mContentType);
|
||||
supported &=
|
||||
CheckTypeForEncoder(aConfiguration.mAudio.mContentType.Value());
|
||||
}
|
||||
|
||||
auto info = MakeUnique<MediaCapabilitiesInfo>(supported, supported, false);
|
||||
|
|
|
@ -32,16 +32,22 @@ enum MediaEncodingType {
|
|||
"transmission"
|
||||
};
|
||||
|
||||
// all members are specified as required in the spec.
|
||||
// We enforce that requirement in the MediaCapabilities code instead
|
||||
// See https://github.com/heycam/webidl/issues/76
|
||||
dictionary VideoConfiguration {
|
||||
required DOMString contentType;
|
||||
required unsigned long width;
|
||||
required unsigned long height;
|
||||
required unsigned long long bitrate;
|
||||
required DOMString framerate;
|
||||
DOMString contentType;
|
||||
unsigned long width;
|
||||
unsigned long height;
|
||||
unsigned long long bitrate;
|
||||
DOMString framerate;
|
||||
};
|
||||
|
||||
// contentType member is specified as required in the spec.
|
||||
// We enforce that requirement in the MediaCapabilities code instead
|
||||
// See https://github.com/heycam/webidl/issues/76
|
||||
dictionary AudioConfiguration {
|
||||
required DOMString contentType;
|
||||
DOMString contentType;
|
||||
DOMString channels;
|
||||
unsigned long long bitrate;
|
||||
unsigned long samplerate;
|
||||
|
@ -57,8 +63,6 @@ interface MediaCapabilitiesInfo {
|
|||
|
||||
[Exposed=(Window, Worker), Func="mozilla::dom::MediaCapabilities::Enabled"]
|
||||
interface MediaCapabilities {
|
||||
// As per https://github.com/WICG/media-capabilities/issues/91 we mark the
|
||||
// methods as always returning a new object.
|
||||
[NewObject]
|
||||
Promise<MediaCapabilitiesInfo> decodingInfo(MediaDecodingConfiguration configuration);
|
||||
[NewObject]
|
||||
|
|
Загрузка…
Ссылка в новой задаче