Bug 1495904 - Have HTMLMediaElement::Seek() return synchronous errors synchronously instead of causing uncatchable promise rejections in web console. Enforce existing fastSeek() and mediaElement.currentPosition = value behavior (which is to ignore... r=pehrsons

...errors) if srcObject is a MediaStream. r?pehrsons

Differential Revision: https://phabricator.services.mozilla.com/D7566

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan-Ivar Bruaroey 2018-10-05 15:43:32 +00:00
parent ae01f9393f
commit fd1e15d444

View File

@ -2700,6 +2700,7 @@ HTMLMediaElement::FastSeek(double aTime, ErrorResult& aRv)
LOG(LogLevel::Debug, ("Reporting telemetry VIDEO_FASTSEEK_USED"));
Telemetry::Accumulate(Telemetry::VIDEO_FASTSEEK_USED, 1);
RefPtr<Promise> tobeDropped = Seek(aTime, SeekTarget::PrevSyncPoint, aRv);
aRv.SuppressException();
}
already_AddRefed<Promise>
@ -2725,6 +2726,7 @@ HTMLMediaElement::SetCurrentTime(double aCurrentTime, ErrorResult& aRv)
LOG(LogLevel::Debug,
("%p SetCurrentTime(%f) called by JS", this, aCurrentTime));
RefPtr<Promise> tobeDropped = Seek(aCurrentTime, SeekTarget::Accurate, aRv);
aRv.SuppressException();
}
/**
@ -2760,11 +2762,13 @@ HTMLMediaElement::Seek(double aTime,
SeekTarget::Type aSeekType,
ErrorResult& aRv)
{
// Note: Seek is called both by synchronous code that expects errors thrown in
// aRv, as well as asynchronous code that expects a promise. Make sure all
// synchronous errors are returned using aRv, not promise rejections.
// aTime should be non-NaN.
MOZ_ASSERT(!mozilla::IsNaN(aTime));
RefPtr<Promise> promise = CreateDOMPromise(aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -2779,8 +2783,8 @@ HTMLMediaElement::Seek(double aTime,
if (mSrcStream) {
// do nothing since media streams have an empty Seekable range.
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
if (mPlayed && mCurrentPlayRangeStart != -1.0) {
@ -2801,29 +2805,29 @@ HTMLMediaElement::Seek(double aTime,
if (mReadyState == HAVE_NOTHING) {
mDefaultPlaybackStartPosition = aTime;
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
if (!mDecoder) {
// mDecoder must always be set in order to reach this point.
NS_ASSERTION(mDecoder, "SetCurrentTime failed: no decoder");
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
// Clamp the seek target to inside the seekable ranges.
media::TimeIntervals seekableIntervals = mDecoder->GetSeekable();
if (seekableIntervals.IsInvalid()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); // This will reject the promise.
return promise.forget();
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
RefPtr<TimeRanges> seekable =
new TimeRanges(ToSupports(OwnerDoc()), seekableIntervals);
uint32_t length = seekable->Length();
if (length == 0) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
// If the position we want to seek to is not in a seekable range, we seek
@ -2886,9 +2890,7 @@ HTMLMediaElement::Seek(double aTime,
AddRemoveSelfReference();
// Keep the DOM promise.
mSeekDOMPromise = promise;
return promise.forget();
return do_AddRef(mSeekDOMPromise = CreateDOMPromise(aRv));
}
double