diff --git a/content/base/public/Element.h b/content/base/public/Element.h index 3af4ec90b5b..e1b140925ea 100644 --- a/content/base/public/Element.h +++ b/content/base/public/Element.h @@ -1124,8 +1124,8 @@ protected: Attr* GetAttributeNodeNSInternal(const nsAString& aNamespaceURI, const nsAString& aLocalName); - inline void RegisterFreezableElement(); - inline void UnregisterFreezableElement(); + inline void RegisterActivityObserver(); + inline void UnregisterActivityObserver(); /** * Add/remove this element to the documents id cache diff --git a/content/base/public/ElementInlines.h b/content/base/public/ElementInlines.h index 9da1ba543ff..8e0e6194bef 100644 --- a/content/base/public/ElementInlines.h +++ b/content/base/public/ElementInlines.h @@ -14,15 +14,15 @@ namespace mozilla { namespace dom { inline void -Element::RegisterFreezableElement() +Element::RegisterActivityObserver() { - OwnerDoc()->RegisterFreezableElement(this); + OwnerDoc()->RegisterActivityObserver(this); } inline void -Element::UnregisterFreezableElement() +Element::UnregisterActivityObserver() { - OwnerDoc()->UnregisterFreezableElement(this); + OwnerDoc()->UnregisterActivityObserver(this); } } diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index e0adffdf67c..17a9c9b0bcc 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -1697,10 +1697,17 @@ public: */ bool IsActive() const { return mDocumentContainer && !mRemovedFromDocShell; } - void RegisterFreezableElement(nsIContent* aContent); - bool UnregisterFreezableElement(nsIContent* aContent); - typedef void (* FreezableElementEnumerator)(nsIContent*, void*); - void EnumerateFreezableElements(FreezableElementEnumerator aEnumerator, + /** + * Register/Unregister the ActivityObserver into mActivityObservers to listen + * the document's activity changes such as OnPageHide, visibility, activity. + * The ActivityObserver objects can be nsIObjectLoadingContent or + * nsIDocumentActivity or HTMLMEdiaElement. + */ + void RegisterActivityObserver(nsISupports* aSupports); + bool UnregisterActivityObserver(nsISupports* aSupports); + // Enumerate all the observers in mActivityObservers by the aEnumerator. + typedef void (* ActivityObserverEnumerator)(nsISupports*, void*); + void EnumerateActivityObservers(ActivityObserverEnumerator aEnumerator, void* aData); // Indicates whether mAnimationController has been (lazily) initialized. @@ -2385,11 +2392,12 @@ protected: nsRefPtr mAttrStyleSheet; nsRefPtr mStyleAttrStyleSheet; - // The set of all object, embed, applet, video and audio elements for - // which this is the owner document. (They might not be in the document.) + // The set of all object, embed, applet, video/audio elements or + // nsIObjectLoadingContent or nsIDocumentActivity for which this is the + // owner document. (They might not be in the document.) // These are non-owning pointers, the elements are responsible for removing // themselves when they go away. - nsAutoPtr > > mFreezableElements; + nsAutoPtr > > mActivityObservers; // The set of all links that need their status resolved. Links must add themselves // to this set by calling RegisterPendingLinkUpdate when added to a document and must diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index b1cd6ca1b67..b576f2b66eb 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -6567,12 +6567,13 @@ nsContentUtils::HaveEqualPrincipals(nsIDocument* aDoc1, nsIDocument* aDoc2) } static void -CheckForWindowedPlugins(nsIContent* aContent, void* aResult) +CheckForWindowedPlugins(nsISupports* aSupports, void* aResult) { - if (!aContent->IsInDoc()) { + nsCOMPtr content(do_QueryInterface(aSupports)); + if (!content || !content->IsInDoc()) { return; } - nsCOMPtr olc(do_QueryInterface(aContent)); + nsCOMPtr olc(do_QueryInterface(content)); if (!olc) { return; } @@ -6592,7 +6593,7 @@ static bool DocTreeContainsWindowedPlugins(nsIDocument* aDoc, void* aResult) { if (!nsContentUtils::IsChromeDoc(aDoc)) { - aDoc->EnumerateFreezableElements(CheckForWindowedPlugins, aResult); + aDoc->EnumerateActivityObservers(CheckForWindowedPlugins, aResult); } if (*static_cast(aResult)) { // Return false to stop iteration, we found a windowed plugin. diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 0763c19f381..58b7914c137 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -219,6 +219,7 @@ #include "nsCharSeparatedTokenizer.h" #include "mozilla/dom/XPathEvaluator.h" #include "nsIDocumentEncoder.h" +#include "nsIDocumentActivity.h" #include "nsIStructuredCloneContainer.h" #include "nsIMutableArray.h" #include "nsContentPermissionHelper.h" @@ -4357,18 +4358,24 @@ nsDocument::SetScopeObject(nsIGlobalObject* aGlobal) } static void -NotifyActivityChanged(nsIContent *aContent, void *aUnused) +NotifyActivityChanged(nsISupports *aSupports, void *aUnused) { - nsCOMPtr domMediaElem(do_QueryInterface(aContent)); + nsCOMPtr domMediaElem(do_QueryInterface(aSupports)); if (domMediaElem) { - HTMLMediaElement* mediaElem = static_cast(aContent); + nsCOMPtr content(do_QueryInterface(domMediaElem)); + MOZ_ASSERT(content, "aSupports is not a content"); + HTMLMediaElement* mediaElem = static_cast(content.get()); mediaElem->NotifyOwnerDocumentActivityChanged(); } - nsCOMPtr objectLoadingContent(do_QueryInterface(aContent)); + nsCOMPtr objectLoadingContent(do_QueryInterface(aSupports)); if (objectLoadingContent) { nsObjectLoadingContent* olc = static_cast(objectLoadingContent.get()); olc->NotifyOwnerDocumentActivityChanged(); } + nsCOMPtr objectDocumentActivity(do_QueryInterface(aSupports)); + if (objectDocumentActivity) { + objectDocumentActivity->NotifyOwnerDocumentActivityChanged(); + } } void @@ -4380,7 +4387,7 @@ nsIDocument::SetContainer(nsDocShell* aContainer) mDocumentContainer = WeakPtr(); } - EnumerateFreezableElements(NotifyActivityChanged, nullptr); + EnumerateActivityObservers(NotifyActivityChanged, nullptr); if (!aContainer) { return; } @@ -8511,7 +8518,7 @@ nsDocument::RemovedFromDocShell() return; mRemovedFromDocShell = true; - EnumerateFreezableElements(NotifyActivityChanged, nullptr); + EnumerateActivityObservers(NotifyActivityChanged, nullptr); uint32_t i, count = mChildren.ChildCount(); for (i = 0; i < count; ++i) { @@ -8763,7 +8770,7 @@ nsDocument::OnPageShow(bool aPersisted, { mVisible = true; - EnumerateFreezableElements(NotifyActivityChanged, nullptr); + EnumerateActivityObservers(NotifyActivityChanged, nullptr); EnumerateExternalResources(NotifyPageShow, &aPersisted); Element* root = GetRootElement(); @@ -8892,7 +8899,7 @@ nsDocument::OnPageHide(bool aPersisted, UpdateVisibilityState(); EnumerateExternalResources(NotifyPageHide, &aPersisted); - EnumerateFreezableElements(NotifyActivityChanged, nullptr); + EnumerateActivityObservers(NotifyActivityChanged, nullptr); if (IsFullScreenDoc()) { // If this document was fullscreen, we should exit fullscreen in this @@ -9589,48 +9596,48 @@ nsDocument::SetChangeScrollPosWhenScrollingToRef(bool aValue) } void -nsIDocument::RegisterFreezableElement(nsIContent* aContent) +nsIDocument::RegisterActivityObserver(nsISupports* aSupports) { - if (!mFreezableElements) { - mFreezableElements = new nsTHashtable >(); - if (!mFreezableElements) + if (!mActivityObservers) { + mActivityObservers = new nsTHashtable >(); + if (!mActivityObservers) return; } - mFreezableElements->PutEntry(aContent); + mActivityObservers->PutEntry(aSupports); } bool -nsIDocument::UnregisterFreezableElement(nsIContent* aContent) +nsIDocument::UnregisterActivityObserver(nsISupports* aSupports) { - if (!mFreezableElements) + if (!mActivityObservers) return false; - if (!mFreezableElements->GetEntry(aContent)) + if (!mActivityObservers->GetEntry(aSupports)) return false; - mFreezableElements->RemoveEntry(aContent); + mActivityObservers->RemoveEntry(aSupports); return true; } -struct EnumerateFreezablesData { - nsIDocument::FreezableElementEnumerator mEnumerator; +struct EnumerateActivityObserversData { + nsIDocument::ActivityObserverEnumerator mEnumerator; void* mData; }; static PLDHashOperator -EnumerateFreezables(nsPtrHashKey* aEntry, void* aData) +EnumerateObservers(nsPtrHashKey* aEntry, void* aData) { - EnumerateFreezablesData* data = static_cast(aData); + EnumerateActivityObserversData* data = static_cast(aData); data->mEnumerator(aEntry->GetKey(), data->mData); return PL_DHASH_NEXT; } void -nsIDocument::EnumerateFreezableElements(FreezableElementEnumerator aEnumerator, +nsIDocument::EnumerateActivityObservers(ActivityObserverEnumerator aEnumerator, void* aData) { - if (!mFreezableElements) + if (!mActivityObservers) return; - EnumerateFreezablesData data = { aEnumerator, aData }; - mFreezableElements->EnumerateEntries(EnumerateFreezables, &data); + EnumerateActivityObserversData data = { aEnumerator, aData }; + mActivityObservers->EnumerateEntries(EnumerateObservers, &data); } void @@ -11826,7 +11833,7 @@ nsDocument::UpdateVisibilityState() /* bubbles = */ true, /* cancelable = */ false); - EnumerateFreezableElements(NotifyActivityChanged, nullptr); + EnumerateActivityObservers(NotifyActivityChanged, nullptr); } } diff --git a/content/base/src/nsNodeUtils.cpp b/content/base/src/nsNodeUtils.cpp index b13ebc0fb42..7c95fc830de 100644 --- a/content/base/src/nsNodeUtils.cpp +++ b/content/base/src/nsNodeUtils.cpp @@ -471,7 +471,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep, if (aNode->IsElement()) { Element* element = aNode->AsElement(); oldDoc->ClearBoxObjectFor(element); - wasRegistered = oldDoc->UnregisterFreezableElement(element); + wasRegistered = oldDoc->UnregisterActivityObserver(element); } aNode->mNodeInfo.swap(newNodeInfo); @@ -484,7 +484,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep, // XXX what if oldDoc is null, we don't know if this should be // registered or not! Can that really happen? if (wasRegistered) { - newDoc->RegisterFreezableElement(aNode->AsElement()); + newDoc->RegisterActivityObserver(aNode->AsElement()); } nsPIDOMWindow* window = newDoc->GetInnerWindow(); diff --git a/content/html/content/src/HTMLMediaElement.cpp b/content/html/content/src/HTMLMediaElement.cpp index a94cfc40ba6..ed798554e26 100644 --- a/content/html/content/src/HTMLMediaElement.cpp +++ b/content/html/content/src/HTMLMediaElement.cpp @@ -2031,7 +2031,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed& aNodeInfo) mPaused.SetOuter(this); - RegisterFreezableElement(); + RegisterActivityObserver(); NotifyOwnerDocumentActivityChanged(); } @@ -2043,7 +2043,7 @@ HTMLMediaElement::~HTMLMediaElement() if (mVideoFrameContainer) { mVideoFrameContainer->ForgetElement(); } - UnregisterFreezableElement(); + UnregisterActivityObserver(); if (mDecoder) { ShutdownDecoder(); } diff --git a/content/html/content/src/HTMLObjectElement.cpp b/content/html/content/src/HTMLObjectElement.cpp index 234833ed192..7fbfe1789cc 100644 --- a/content/html/content/src/HTMLObjectElement.cpp +++ b/content/html/content/src/HTMLObjectElement.cpp @@ -29,7 +29,7 @@ HTMLObjectElement::HTMLObjectElement(already_AddRefed& aNodeInfo, : nsGenericHTMLFormElement(aNodeInfo), mIsDoneAddingChildren(!aFromParser) { - RegisterFreezableElement(); + RegisterActivityObserver(); SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK); // is always barred from constraint validation. @@ -41,7 +41,7 @@ HTMLObjectElement::HTMLObjectElement(already_AddRefed& aNodeInfo, HTMLObjectElement::~HTMLObjectElement() { - UnregisterFreezableElement(); + UnregisterActivityObserver(); DestroyImageLoadingContent(); } diff --git a/content/html/content/src/HTMLSharedObjectElement.cpp b/content/html/content/src/HTMLSharedObjectElement.cpp index 2b3a058bd2e..d4fd59a3525 100644 --- a/content/html/content/src/HTMLSharedObjectElement.cpp +++ b/content/html/content/src/HTMLSharedObjectElement.cpp @@ -28,7 +28,7 @@ HTMLSharedObjectElement::HTMLSharedObjectElement(already_AddRefed& : nsGenericHTMLElement(aNodeInfo), mIsDoneAddingChildren(mNodeInfo->Equals(nsGkAtoms::embed) || !aFromParser) { - RegisterFreezableElement(); + RegisterActivityObserver(); SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK); // By default we're in the loading state @@ -57,7 +57,7 @@ HTMLSharedObjectElement::SetItemValueText(const nsAString& aValue) HTMLSharedObjectElement::~HTMLSharedObjectElement() { - UnregisterFreezableElement(); + UnregisterActivityObserver(); DestroyImageLoadingContent(); } diff --git a/content/media/moz.build b/content/media/moz.build index e65c8ea9051..bdc0cc6647c 100644 --- a/content/media/moz.build +++ b/content/media/moz.build @@ -92,6 +92,7 @@ EXPORTS += [ 'MediaStreamGraph.h', 'MediaTaskQueue.h', 'MP3FrameParser.h', + 'nsIDocumentActivity.h', 'RtspMediaResource.h', 'SharedBuffer.h', 'SharedThreadPool.h', diff --git a/content/media/nsIDocumentActivity.h b/content/media/nsIDocumentActivity.h new file mode 100644 index 00000000000..7ce979d5d6a --- /dev/null +++ b/content/media/nsIDocumentActivity.h @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsIDocumentActivity_h__ +#define nsIDocumentActivity_h__ + +#include "nsISupports.h" + +#define NS_IDOCUMENTACTIVITY_IID \ +{ 0x9b9f584e, 0xefa8, 0x11e3, \ + { 0xbb, 0x74, 0x5e, 0xdd, 0x1d, 0x5d, 0x46, 0xb0 } } + +class nsIDocumentActivity : public nsISupports +{ +public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENTACTIVITY_IID) + + virtual void NotifyOwnerDocumentActivityChanged() = 0; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentActivity, NS_IDOCUMENTACTIVITY_IID) + +/* Use this macro when declaring classes that implement this interface. */ +#define NS_DECL_NSIDOCUMENTACTIVITY \ + virtual void NotifyOwnerDocumentActivityChanged() MOZ_OVERRIDE; + +#endif /* nsIDocumentActivity_h__ */ diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 54fef646acf..aecb7af87a7 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -8398,9 +8398,9 @@ PresShell::RemoveOverrideStyleSheet(nsIStyleSheet *aSheet) } static void -FreezeElement(nsIContent *aContent, void * /* unused */) +FreezeElement(nsISupports *aSupports, void * /* unused */) { - nsCOMPtr olc(do_QueryInterface(aContent)); + nsCOMPtr olc(do_QueryInterface(aSupports)); if (olc) { olc->StopPluginInstance(); } @@ -8423,7 +8423,7 @@ PresShell::Freeze() MaybeReleaseCapturingContent(); - mDocument->EnumerateFreezableElements(FreezeElement, nullptr); + mDocument->EnumerateActivityObservers(FreezeElement, nullptr); if (mCaret) { SetCaretEnabled(false); @@ -8472,9 +8472,9 @@ PresShell::FireOrClearDelayedEvents(bool aFireEvents) } static void -ThawElement(nsIContent *aContent, void *aShell) +ThawElement(nsISupports *aSupports, void *aShell) { - nsCOMPtr olc(do_QueryInterface(aContent)); + nsCOMPtr olc(do_QueryInterface(aSupports)); if (olc) { olc->AsyncStartPluginInstance(); } @@ -8499,7 +8499,7 @@ PresShell::Thaw() presContext->RefreshDriver()->Thaw(); } - mDocument->EnumerateFreezableElements(ThawElement, this); + mDocument->EnumerateActivityObservers(ThawElement, this); if (mDocument) mDocument->EnumerateSubDocuments(ThawSubDocument, nullptr); @@ -10384,9 +10384,14 @@ SetExternalResourceIsActive(nsIDocument* aDocument, void* aClosure) } static void -SetPluginIsActive(nsIContent* aContent, void* aClosure) +SetPluginIsActive(nsISupports* aSupports, void* aClosure) { - nsIFrame *frame = aContent->GetPrimaryFrame(); + nsCOMPtr content(do_QueryInterface(aSupports)); + if (!content) { + return; + } + + nsIFrame *frame = content->GetPrimaryFrame(); nsIObjectFrame *objectFrame = do_QueryFrame(frame); if (objectFrame) { objectFrame->SetIsDocumentActive(*static_cast(aClosure)); @@ -10408,7 +10413,7 @@ PresShell::SetIsActive(bool aIsActive) // Propagate state-change to my resource documents' PresShells mDocument->EnumerateExternalResources(SetExternalResourceIsActive, &aIsActive); - mDocument->EnumerateFreezableElements(SetPluginIsActive, + mDocument->EnumerateActivityObservers(SetPluginIsActive, &aIsActive); nsresult rv = UpdateImageLockingState(); #ifdef ACCESSIBILITY diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index a75fe8da710..665052143ca 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -1989,13 +1989,17 @@ nsObjectFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot) } /*static*/ void -nsObjectFrame::BeginSwapDocShells(nsIContent* aContent, void*) +nsObjectFrame::BeginSwapDocShells(nsISupports* aSupports, void*) { - NS_PRECONDITION(aContent, ""); + NS_PRECONDITION(aSupports, ""); + nsCOMPtr content(do_QueryInterface(aSupports)); + if (!content) { + return; + } // This function is called from a document content enumerator so we need // to filter out the nsObjectFrames and ignore the rest. - nsIObjectFrame* obj = do_QueryFrame(aContent->GetPrimaryFrame()); + nsIObjectFrame* obj = do_QueryFrame(content->GetPrimaryFrame()); if (!obj) return; @@ -2006,13 +2010,17 @@ nsObjectFrame::BeginSwapDocShells(nsIContent* aContent, void*) } /*static*/ void -nsObjectFrame::EndSwapDocShells(nsIContent* aContent, void*) +nsObjectFrame::EndSwapDocShells(nsISupports* aSupports, void*) { - NS_PRECONDITION(aContent, ""); + NS_PRECONDITION(aSupports, ""); + nsCOMPtr content(do_QueryInterface(aSupports)); + if (!content) { + return; + } // This function is called from a document content enumerator so we need // to filter out the nsObjectFrames and ignore the rest. - nsIObjectFrame* obj = do_QueryFrame(aContent->GetPrimaryFrame()); + nsIObjectFrame* obj = do_QueryFrame(content->GetPrimaryFrame()); if (!obj) return; diff --git a/layout/generic/nsObjectFrame.h b/layout/generic/nsObjectFrame.h index b863f2fd3fb..fca3aeeca62 100644 --- a/layout/generic/nsObjectFrame.h +++ b/layout/generic/nsObjectFrame.h @@ -182,17 +182,17 @@ public: nsRect GetPaintedRect(nsDisplayPlugin* aItem); /** - * If aContent has a nsObjectFrame, then prepare it for a DocShell swap. + * If aSupports has a nsObjectFrame, then prepare it for a DocShell swap. * @see nsSubDocumentFrame::BeginSwapDocShells. * There will be a call to EndSwapDocShells after we were moved to the * new view tree. */ - static void BeginSwapDocShells(nsIContent* aContent, void*); + static void BeginSwapDocShells(nsISupports* aSupports, void*); /** - * If aContent has a nsObjectFrame, then set it up after a DocShell swap. + * If aSupports has a nsObjectFrame, then set it up after a DocShell swap. * @see nsSubDocumentFrame::EndSwapDocShells. */ - static void EndSwapDocShells(nsIContent* aContent, void*); + static void EndSwapDocShells(nsISupports* aSupports, void*); nsIWidget* GetWidget() MOZ_OVERRIDE { return mInnerView ? mWidget : nullptr; } diff --git a/layout/generic/nsSubDocumentFrame.cpp b/layout/generic/nsSubDocumentFrame.cpp index 4fca61ee89c..fa40ed672d8 100644 --- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -1004,7 +1004,7 @@ BeginSwapDocShellsForDocument(nsIDocument* aDocument, void*) ::DestroyDisplayItemDataForFrames(rootFrame); } } - aDocument->EnumerateFreezableElements( + aDocument->EnumerateActivityObservers( nsObjectFrame::BeginSwapDocShells, nullptr); aDocument->EnumerateSubDocuments(BeginSwapDocShellsForDocument, nullptr); return true; @@ -1101,7 +1101,7 @@ EndSwapDocShellsForDocument(nsIDocument* aDocument, void*) } } - aDocument->EnumerateFreezableElements( + aDocument->EnumerateActivityObservers( nsObjectFrame::EndSwapDocShells, nullptr); aDocument->EnumerateSubDocuments(EndSwapDocShellsForDocument, nullptr); return true;