Bug 1095438 - Refine the dormant rules for the MediaElement, take bind/unbind-from-tree and document-hidden into account. r=jwwang

This commit is contained in:
Benjamin Chen 2014-12-15 15:34:28 +08:00
parent 81596d1ba2
commit d9b312b60a
2 changed files with 32 additions and 3 deletions

View File

@ -2027,7 +2027,8 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
mAudioChannelFaded(false),
mPlayingThroughTheAudioChannel(false),
mDisableVideo(false),
mWaitingFor(MediaWaitingFor::None)
mWaitingFor(MediaWaitingFor::None),
mElementInTreeState(ELEMENT_NOT_INTREE)
{
#ifdef PR_LOGGING
if (!gMediaElementLog) {
@ -2479,8 +2480,14 @@ nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParen
UpdatePreloadAction();
}
if (mDecoder) {
mDecoder->SetDormantIfNecessary(false);
// When the MediaElement is binding to tree, the dormant status is
// aligned to document's hidden status.
nsIDocument* ownerDoc = OwnerDoc();
if (ownerDoc) {
mDecoder->SetDormantIfNecessary(ownerDoc->Hidden());
}
}
mElementInTreeState = ELEMENT_INTREE;
return rv;
}
@ -2494,6 +2501,7 @@ void HTMLMediaElement::UnbindFromTree(bool aDeep,
if (mDecoder) {
mDecoder->SetDormantIfNecessary(true);
}
mElementInTreeState = ELEMENT_NOT_INTREE_HAD_INTREE;
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
@ -3561,7 +3569,15 @@ void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
if (mDecoder) {
mDecoder->SetElementVisibility(!ownerDoc->Hidden());
mDecoder->SetDormantIfNecessary(ownerDoc->Hidden());
if (mElementInTreeState == ELEMENT_NOT_INTREE_HAD_INTREE) {
mDecoder->SetDormantIfNecessary(true);
} else if (mElementInTreeState == ELEMENT_NOT_INTREE ||
mElementInTreeState == ELEMENT_INTREE) {
// The MediaElement had never been binded to tree, or in the tree now,
// align to document.
mDecoder->SetDormantIfNecessary(ownerDoc->Hidden());
}
}
// SetVisibilityState will update mMuted with MUTED_BY_AUDIO_CHANNEL via the

View File

@ -1297,6 +1297,19 @@ protected:
nsRefPtr<VideoTrackList> mVideoTrackList;
MediaWaitingFor mWaitingFor;
enum ElementInTreeState {
// The MediaElement is not in the DOM tree now.
ELEMENT_NOT_INTREE,
// The MediaElement is in the DOM tree now.
ELEMENT_INTREE,
// The MediaElement is not in the DOM tree now but had been binded to the
// tree before.
ELEMENT_NOT_INTREE_HAD_INTREE
};
ElementInTreeState mElementInTreeState;
};
} // namespace dom