зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1395922 - [P1] Refactor code and move them into specific functions. r=cpearce
MozReview-Commit-ID: 9lwRH66Wllp --HG-- extra : rebase_source : 8202008d996adb19547a46f051427053c1d48193
This commit is contained in:
Родитель
b954c1f10b
Коммит
87d6236019
|
@ -1485,6 +1485,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTM
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioTrackList)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioTrackList)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVideoTrackList)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVideoTrackList)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeys)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeys)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIncomingMediaKeys)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectedVideoStreamTrack)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectedVideoStreamTrack)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingPlayPromises)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingPlayPromises)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSeekDOMPromise)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSeekDOMPromise)
|
||||||
|
@ -1514,6 +1515,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLE
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioTrackList)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioTrackList)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mVideoTrackList)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mVideoTrackList)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMediaKeys)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMediaKeys)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIncomingMediaKeys)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelectedVideoStreamTrack)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelectedVideoStreamTrack)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingPlayPromises)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingPlayPromises)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSeekDOMPromise)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSeekDOMPromise)
|
||||||
|
@ -3985,6 +3987,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
|
||||||
mPlaybackRate(1.0),
|
mPlaybackRate(1.0),
|
||||||
mPreservesPitch(true),
|
mPreservesPitch(true),
|
||||||
mPlayed(new TimeRanges(ToSupports(OwnerDoc()))),
|
mPlayed(new TimeRanges(ToSupports(OwnerDoc()))),
|
||||||
|
mAttachingMediaKey(false),
|
||||||
mCurrentPlayRangeStart(-1.0),
|
mCurrentPlayRangeStart(-1.0),
|
||||||
mLoadedDataFired(false),
|
mLoadedDataFired(false),
|
||||||
mAutoplaying(true),
|
mAutoplaying(true),
|
||||||
|
@ -7015,6 +7018,142 @@ HTMLMediaElement::ContainsRestrictedContent()
|
||||||
return GetMediaKeys() != nullptr;
|
return GetMediaKeys() != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLMediaElement::RemoveMediaKeys()
|
||||||
|
{
|
||||||
|
LOG(LogLevel::Debug, ("%s", __func__));
|
||||||
|
// 5.2.3 Stop using the CDM instance represented by the mediaKeys attribute
|
||||||
|
// to decrypt media data and remove the association with the media element.
|
||||||
|
mMediaKeys->Unbind();
|
||||||
|
mMediaKeys = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HTMLMediaElement::TryRemoveMediaKeysAssociation(DetailedPromise* aPromise)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mMediaKeys);
|
||||||
|
LOG(LogLevel::Debug, ("%s", __func__));
|
||||||
|
// 5.2.1 If the user agent or CDM do not support removing the association,
|
||||||
|
// let this object's attaching media keys value be false and reject promise
|
||||||
|
// with a new DOMException whose name is NotSupportedError.
|
||||||
|
// 5.2.2 If the association cannot currently be removed, let this object's
|
||||||
|
// attaching media keys value be false and reject promise with a new
|
||||||
|
// DOMException whose name is InvalidStateError.
|
||||||
|
if (mDecoder) {
|
||||||
|
// We don't support swapping out the MediaKeys once we've started to
|
||||||
|
// setup the playback pipeline. Note this also means we don't need to worry
|
||||||
|
// about handling disassociating the MediaKeys from the MediaDecoder.
|
||||||
|
aPromise->MaybeReject(
|
||||||
|
NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||||
|
NS_LITERAL_CSTRING(
|
||||||
|
"Can't change MediaKeys on HTMLMediaElement after load has started"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RemoveMediaKeys();
|
||||||
|
|
||||||
|
// 5.2.4 If the preceding step failed, let this object's attaching media
|
||||||
|
// keys value be false and reject promise with a new DOMException whose
|
||||||
|
// name is the appropriate error name.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HTMLMediaElement::DetachExistingMediaKeys(DetailedPromise* aPromise)
|
||||||
|
{
|
||||||
|
LOG(LogLevel::Debug, ("%s", __func__));
|
||||||
|
// 5.1 If mediaKeys is not null, CDM instance represented by mediaKeys is
|
||||||
|
// already in use by another media element, and the user agent is unable
|
||||||
|
// to use it with this element, let this object's attaching media keys
|
||||||
|
// value be false and reject promise with a new DOMException whose name
|
||||||
|
// is QuotaExceededError.
|
||||||
|
if (mIncomingMediaKeys && mIncomingMediaKeys->IsBoundToMediaElement()) {
|
||||||
|
aPromise->MaybeReject(
|
||||||
|
NS_ERROR_DOM_QUOTA_EXCEEDED_ERR,
|
||||||
|
NS_LITERAL_CSTRING(
|
||||||
|
"MediaKeys object is already bound to another HTMLMediaElement"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.2 If the mediaKeys attribute is not null, run the following steps:
|
||||||
|
if (mMediaKeys) {
|
||||||
|
return TryRemoveMediaKeysAssociation(aPromise);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLMediaElement::MakeAssociationWithCDMResolved(DetailedPromise* aPromise)
|
||||||
|
{
|
||||||
|
LOG(LogLevel::Debug, ("%s", __func__));
|
||||||
|
|
||||||
|
// 5.4 Set the mediaKeys attribute to mediaKeys.
|
||||||
|
mMediaKeys = mIncomingMediaKeys;
|
||||||
|
// 5.5 Let this object's attaching media keys value be false.
|
||||||
|
ResetSetMediaKeysTempVariables();
|
||||||
|
// 5.6 Resolve promise.
|
||||||
|
aPromise->MaybeResolveWithUndefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HTMLMediaElement::TryMakeAssociationWithCDM(CDMProxy* aProxy)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aProxy);
|
||||||
|
LOG(LogLevel::Debug, ("%s", __func__));
|
||||||
|
// 5.3.3 Queue a task to run the "Attempt to Resume Playback If Necessary"
|
||||||
|
// algorithm on the media element.
|
||||||
|
// Note: Setting the CDMProxy on the MediaDecoder will unblock playback.
|
||||||
|
if (mDecoder) {
|
||||||
|
mDecoder->SetCDMProxy(aProxy);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HTMLMediaElement::AttachNewMediaKeys(DetailedPromise* aPromise)
|
||||||
|
{
|
||||||
|
LOG(LogLevel::Debug,
|
||||||
|
("%s incoming MediaKeys(%p)", __func__, mIncomingMediaKeys.get()));
|
||||||
|
|
||||||
|
// 5.3. If mediaKeys is not null, run the following steps:
|
||||||
|
if (mIncomingMediaKeys) {
|
||||||
|
auto cdmProxy = mIncomingMediaKeys->GetCDMProxy();
|
||||||
|
if (!cdmProxy) {
|
||||||
|
aPromise->MaybeReject(
|
||||||
|
NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||||
|
NS_LITERAL_CSTRING(
|
||||||
|
"CDM crashed before binding MediaKeys object to HTMLMediaElement"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.3.1 Associate the CDM instance represented by mediaKeys with the
|
||||||
|
// media element for decrypting media data.
|
||||||
|
if (NS_FAILED(mIncomingMediaKeys->Bind(this))) {
|
||||||
|
// 5.3.2 If the preceding step failed, run the following steps:
|
||||||
|
|
||||||
|
// 5.3.2.1 Set the mediaKeys attribute to null.
|
||||||
|
mMediaKeys = nullptr;
|
||||||
|
// 5.3.2.2 Let this object's attaching media keys value be false.
|
||||||
|
ResetSetMediaKeysTempVariables();
|
||||||
|
// 5.3.2.3 Reject promise with a new DOMException whose name is
|
||||||
|
// the appropriate error name.
|
||||||
|
aPromise->MaybeReject(
|
||||||
|
NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||||
|
NS_LITERAL_CSTRING(
|
||||||
|
"Failed to bind MediaKeys object to HTMLMediaElement"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return TryMakeAssociationWithCDM(cdmProxy);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLMediaElement::ResetSetMediaKeysTempVariables()
|
||||||
|
{
|
||||||
|
mAttachingMediaKey = false;
|
||||||
|
mIncomingMediaKeys = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
|
HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
|
@ -7050,85 +7189,34 @@ HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
|
||||||
|
|
||||||
// 2. If this object's attaching media keys value is true, return a
|
// 2. If this object's attaching media keys value is true, return a
|
||||||
// promise rejected with a new DOMException whose name is InvalidStateError.
|
// promise rejected with a new DOMException whose name is InvalidStateError.
|
||||||
// 3. Let this object's attaching media keys value be true.
|
if (mAttachingMediaKey) {
|
||||||
// 4. Let promise be a new promise.
|
promise->MaybeReject(
|
||||||
// 5. Run the following steps in parallel:
|
NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||||
|
NS_LITERAL_CSTRING("A MediaKeys object is in attaching operation."));
|
||||||
// 5.1 If mediaKeys is not null, CDM instance represented by mediaKeys is
|
|
||||||
// already in use by another media element, and the user agent is unable
|
|
||||||
// to use it with this element, let this object's attaching media keys
|
|
||||||
// value be false and reject promise with a new DOMException whose name
|
|
||||||
// is QuotaExceededError.
|
|
||||||
if (aMediaKeys && aMediaKeys->IsBoundToMediaElement()) {
|
|
||||||
promise->MaybeReject(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR,
|
|
||||||
NS_LITERAL_CSTRING("MediaKeys object is already bound to another HTMLMediaElement"));
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5.2 If the mediaKeys attribute is not null, run the following steps:
|
// 3. Let this object's attaching media keys value be true.
|
||||||
if (mMediaKeys) {
|
mAttachingMediaKey = true;
|
||||||
// 5.2.1 If the user agent or CDM do not support removing the association,
|
mIncomingMediaKeys = aMediaKeys;
|
||||||
// let this object's attaching media keys value be false and reject promise
|
|
||||||
// with a new DOMException whose name is NotSupportedError.
|
|
||||||
|
|
||||||
// 5.2.2 If the association cannot currently be removed, let this object's
|
// 4. Let promise be a new promise.
|
||||||
// attaching media keys value be false and reject promise with a new
|
// 5. Run the following steps in parallel:
|
||||||
// DOMException whose name is InvalidStateError.
|
|
||||||
if (mDecoder) {
|
|
||||||
// We don't support swapping out the MediaKeys once we've started to
|
|
||||||
// setup the playback pipeline. Note this also means we don't need to worry
|
|
||||||
// about handling disassociating the MediaKeys from the MediaDecoder.
|
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
|
|
||||||
NS_LITERAL_CSTRING("Can't change MediaKeys on HTMLMediaElement after load has started"));
|
|
||||||
return promise.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5.2.3 Stop using the CDM instance represented by the mediaKeys attribute
|
// 5.1 & 5.2
|
||||||
// to decrypt media data and remove the association with the media element.
|
if (!DetachExistingMediaKeys(promise)) {
|
||||||
mMediaKeys->Unbind();
|
ResetSetMediaKeysTempVariables();
|
||||||
mMediaKeys = nullptr;
|
return promise.forget();
|
||||||
|
|
||||||
// 5.2.4 If the preceding step failed, let this object's attaching media
|
|
||||||
// keys value be false and reject promise with a new DOMException whose
|
|
||||||
// name is the appropriate error name.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5.3. If mediaKeys is not null, run the following steps:
|
// 5.3
|
||||||
if (aMediaKeys) {
|
if (!AttachNewMediaKeys(promise)) {
|
||||||
if (!aMediaKeys->GetCDMProxy()) {
|
ResetSetMediaKeysTempVariables();
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
|
return promise.forget();
|
||||||
NS_LITERAL_CSTRING("CDM crashed before binding MediaKeys object to HTMLMediaElement"));
|
|
||||||
return promise.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5.3.1 Associate the CDM instance represented by mediaKeys with the
|
|
||||||
// media element for decrypting media data.
|
|
||||||
if (NS_FAILED(aMediaKeys->Bind(this))) {
|
|
||||||
// 5.3.2 If the preceding step failed, run the following steps:
|
|
||||||
// 5.3.2.1 Set the mediaKeys attribute to null.
|
|
||||||
mMediaKeys = nullptr;
|
|
||||||
// 5.3.2.2 Let this object's attaching media keys value be false.
|
|
||||||
// 5.3.2.3 Reject promise with a new DOMException whose name is
|
|
||||||
// the appropriate error name.
|
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
|
|
||||||
NS_LITERAL_CSTRING("Failed to bind MediaKeys object to HTMLMediaElement"));
|
|
||||||
return promise.forget();
|
|
||||||
}
|
|
||||||
// 5.3.3 Queue a task to run the "Attempt to Resume Playback If Necessary"
|
|
||||||
// algorithm on the media element.
|
|
||||||
// Note: Setting the CDMProxy on the MediaDecoder will unblock playback.
|
|
||||||
if (mDecoder) {
|
|
||||||
mDecoder->SetCDMProxy(aMediaKeys->GetCDMProxy());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5.4 Set the mediaKeys attribute to mediaKeys.
|
// 5.4, 5.5, 5.6
|
||||||
mMediaKeys = aMediaKeys;
|
MakeAssociationWithCDMResolved(promise);
|
||||||
|
|
||||||
// 5.5 Let this object's attaching media keys value be false.
|
|
||||||
|
|
||||||
// 5.6 Resolve promise.
|
|
||||||
promise->MaybeResolveWithUndefined();
|
|
||||||
|
|
||||||
// 6. Return promise.
|
// 6. Return promise.
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
|
|
|
@ -1332,6 +1332,14 @@ protected:
|
||||||
const nsAttrValueOrString& aValue,
|
const nsAttrValueOrString& aValue,
|
||||||
bool aNotify) override;
|
bool aNotify) override;
|
||||||
|
|
||||||
|
bool DetachExistingMediaKeys(DetailedPromise* aPromise);
|
||||||
|
bool TryRemoveMediaKeysAssociation(DetailedPromise* aPromise);
|
||||||
|
void RemoveMediaKeys();
|
||||||
|
bool AttachNewMediaKeys(DetailedPromise* aPromise);
|
||||||
|
bool TryMakeAssociationWithCDM(CDMProxy* aProxy);
|
||||||
|
void MakeAssociationWithCDMResolved(DetailedPromise* aPromise);
|
||||||
|
void ResetSetMediaKeysTempVariables();
|
||||||
|
|
||||||
// The current decoder. Load() has been called on this decoder.
|
// The current decoder. Load() has been called on this decoder.
|
||||||
// At most one of mDecoder and mSrcStream can be non-null.
|
// At most one of mDecoder and mSrcStream can be non-null.
|
||||||
RefPtr<MediaDecoder> mDecoder;
|
RefPtr<MediaDecoder> mDecoder;
|
||||||
|
@ -1534,6 +1542,9 @@ protected:
|
||||||
|
|
||||||
// Encrypted Media Extension media keys.
|
// Encrypted Media Extension media keys.
|
||||||
RefPtr<MediaKeys> mMediaKeys;
|
RefPtr<MediaKeys> mMediaKeys;
|
||||||
|
RefPtr<MediaKeys> mIncomingMediaKeys;
|
||||||
|
// Used to indicate if the MediaKeys attaching operation is on-going or not.
|
||||||
|
bool mAttachingMediaKey;
|
||||||
|
|
||||||
// Stores the time at the start of the current 'played' range.
|
// Stores the time at the start of the current 'played' range.
|
||||||
double mCurrentPlayRangeStart;
|
double mCurrentPlayRangeStart;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче