Bug 1530862 - Add an Init() method to HTMLMediaElement to be called right after construction to do any AddRef / Release-ing. r=jya,mccr8,smaug

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mike Conley 2019-02-28 19:02:55 +00:00
Родитель 7aecfc00e9
Коммит ca728851ca
6 изменённых файлов: 71 добавлений и 10 удалений

Просмотреть файл

@ -20,12 +20,31 @@
#include "mozilla/dom/TimeRanges.h" #include "mozilla/dom/TimeRanges.h"
#include "AudioStream.h" #include "AudioStream.h"
NS_IMPL_NS_NEW_HTML_ELEMENT(Audio) nsGenericHTMLElement* NS_NewHTMLAudioElement(
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser) {
mozilla::dom::HTMLAudioElement* element =
new mozilla::dom::HTMLAudioElement(std::move(aNodeInfo));
element->Init();
return element;
}
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
NS_IMPL_ELEMENT_CLONE(HTMLAudioElement) nsresult HTMLAudioElement::Clone(mozilla::dom::NodeInfo* aNodeInfo,
nsINode** aResult) const {
*aResult = nullptr;
RefPtr<mozilla::dom::NodeInfo> ni(aNodeInfo);
HTMLAudioElement* it = new HTMLAudioElement(ni.forget());
it->Init();
nsCOMPtr<nsINode> kungFuDeathGrip = it;
nsresult rv = const_cast<HTMLAudioElement*>(this)->CopyInnerTo(it);
if (NS_SUCCEEDED(rv)) {
kungFuDeathGrip.swap(*aResult);
}
return rv;
}
HTMLAudioElement::HTMLAudioElement(already_AddRefed<NodeInfo>&& aNodeInfo) HTMLAudioElement::HTMLAudioElement(already_AddRefed<NodeInfo>&& aNodeInfo)
: HTMLMediaElement(std::move(aNodeInfo)) { : HTMLMediaElement(std::move(aNodeInfo)) {
@ -54,7 +73,8 @@ already_AddRefed<HTMLAudioElement> HTMLAudioElement::Audio(
RefPtr<mozilla::dom::NodeInfo> nodeInfo = doc->NodeInfoManager()->GetNodeInfo( RefPtr<mozilla::dom::NodeInfo> nodeInfo = doc->NodeInfoManager()->GetNodeInfo(
nsGkAtoms::audio, nullptr, kNameSpaceID_XHTML, ELEMENT_NODE); nsGkAtoms::audio, nullptr, kNameSpaceID_XHTML, ELEMENT_NODE);
RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(nodeInfo.forget()); RefPtr<HTMLAudioElement> audio =
static_cast<HTMLAudioElement*>(NS_NewHTMLAudioElement(nodeInfo.forget()));
audio->SetHTMLAttr(nsGkAtoms::preload, NS_LITERAL_STRING("auto"), aRv); audio->SetHTMLAttr(nsGkAtoms::preload, NS_LITERAL_STRING("auto"), aRv);
if (aRv.Failed()) { if (aRv.Failed()) {
return nullptr; return nullptr;

Просмотреть файл

@ -3498,13 +3498,27 @@ HTMLMediaElement::HTMLMediaElement(
mShutdownObserver(new ShutdownObserver), mShutdownObserver(new ShutdownObserver),
mPlayed(new TimeRanges(ToSupports(OwnerDoc()))), mPlayed(new TimeRanges(ToSupports(OwnerDoc()))),
mPaused(true, "HTMLMediaElement::mPaused"), mPaused(true, "HTMLMediaElement::mPaused"),
mAudioTrackList(new AudioTrackList(OwnerDoc()->GetParentObject(), this)),
mVideoTrackList(new VideoTrackList(OwnerDoc()->GetParentObject(), this)),
mErrorSink(new ErrorSink(this)), mErrorSink(new ErrorSink(this)),
mAudioChannelWrapper(new AudioChannelAgentCallback(this)), mAudioChannelWrapper(new AudioChannelAgentCallback(this)),
mSink(MakePair(nsString(), RefPtr<AudioDeviceInfo>())) { mSink(MakePair(nsString(), RefPtr<AudioDeviceInfo>())) {
MOZ_ASSERT(mMainThreadEventTarget); MOZ_ASSERT(mMainThreadEventTarget);
MOZ_ASSERT(mAbstractMainThread); MOZ_ASSERT(mAbstractMainThread);
// Please don't add anything to this constructor or the initialization
// list that can cause AddRef to be called. This prevents subclasses
// from overriding AddRef in a way that works with our refcount
// logging mechanisms. Put these things inside of the ::Init method
// instead.
}
void HTMLMediaElement::Init() {
MOZ_ASSERT(mRefCnt == 0 && !mRefCnt.IsPurple(),
"HTMLMediaElement::Init called when AddRef has been called "
"at least once already, probably in the constructor. Please "
"see the documentation in the HTMLMediaElement constructor.");
MOZ_ASSERT(!mRefCnt.IsPurple());
mAudioTrackList = new AudioTrackList(OwnerDoc()->GetParentObject(), this);
mVideoTrackList = new VideoTrackList(OwnerDoc()->GetParentObject(), this);
DecoderDoctorLogger::LogConstruction(this); DecoderDoctorLogger::LogConstruction(this);
@ -3525,9 +3539,12 @@ HTMLMediaElement::HTMLMediaElement(
MediaShutdownManager::InitStatics(); MediaShutdownManager::InitStatics();
mShutdownObserver->Subscribe(this); mShutdownObserver->Subscribe(this);
mInitialized = true;
} }
HTMLMediaElement::~HTMLMediaElement() { HTMLMediaElement::~HTMLMediaElement() {
MOZ_ASSERT(mInitialized,
"HTMLMediaElement must be initialized before it is destroyed.");
NS_ASSERTION( NS_ASSERTION(
!mHasSelfReference, !mHasSelfReference,
"How can we be destroyed if we're still holding a self reference?"); "How can we be destroyed if we're still holding a self reference?");

Просмотреть файл

@ -117,6 +117,7 @@ class HTMLMediaElement : public nsGenericHTMLElement,
explicit HTMLMediaElement( explicit HTMLMediaElement(
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo); already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
void Init();
void ReportCanPlayTelemetry(); void ReportCanPlayTelemetry();
@ -1750,6 +1751,9 @@ class HTMLMediaElement : public nsGenericHTMLElement,
// threshold. // threshold.
void ReportPlayedTimeAfterBlockedTelemetry(); void ReportPlayedTimeAfterBlockedTelemetry();
// True if Init() has been called after construction
bool mInitialized = false;
// True if user has called load(), seek() or element has started playing // True if user has called load(), seek() or element has started playing
// before. It's *only* use for checking autoplay policy // before. It's *only* use for checking autoplay policy
bool mIsBlessed = false; bool mIsBlessed = false;

Просмотреть файл

@ -35,14 +35,33 @@
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
NS_IMPL_NS_NEW_HTML_ELEMENT(Video) nsGenericHTMLElement* NS_NewHTMLVideoElement(
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser) {
mozilla::dom::HTMLVideoElement* element =
new mozilla::dom::HTMLVideoElement(std::move(aNodeInfo));
element->Init();
return element;
}
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
static bool sVideoStatsEnabled; static bool sVideoStatsEnabled;
NS_IMPL_ELEMENT_CLONE(HTMLVideoElement) nsresult HTMLVideoElement::Clone(mozilla::dom::NodeInfo* aNodeInfo,
nsINode** aResult) const {
*aResult = nullptr;
RefPtr<mozilla::dom::NodeInfo> ni(aNodeInfo);
HTMLVideoElement* it = new HTMLVideoElement(ni.forget());
it->Init();
nsCOMPtr<nsINode> kungFuDeathGrip = it;
nsresult rv = const_cast<HTMLVideoElement*>(this)->CopyInnerTo(it);
if (NS_SUCCEEDED(rv)) {
kungFuDeathGrip.swap(*aResult);
}
return rv;
}
HTMLVideoElement::HTMLVideoElement(already_AddRefed<NodeInfo>&& aNodeInfo) HTMLVideoElement::HTMLVideoElement(already_AddRefed<NodeInfo>&& aNodeInfo)
: HTMLMediaElement(std::move(aNodeInfo)), mIsOrientationLocked(false) { : HTMLMediaElement(std::move(aNodeInfo)), mIsOrientationLocked(false) {
@ -308,7 +327,8 @@ void HTMLVideoElement::ReleaseVideoWakeLockIfExists() {
} }
} }
void HTMLVideoElement::Init() { /* static */
void HTMLVideoElement::InitStatics() {
Preferences::AddBoolVarCache(&sVideoStatsEnabled, Preferences::AddBoolVarCache(&sVideoStatsEnabled,
"media.video_stats.enabled"); "media.video_stats.enabled");
} }

Просмотреть файл

@ -38,7 +38,7 @@ class HTMLVideoElement final : public HTMLMediaElement {
nsAttrValue& aResult) override; nsAttrValue& aResult) override;
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override; NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
static void Init(); static void InitStatics();
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction()
const override; const override;

Просмотреть файл

@ -255,7 +255,7 @@ nsresult nsLayoutStatics::Initialize() {
nsCookieService::AppClearDataObserverInit(); nsCookieService::AppClearDataObserverInit();
nsApplicationCacheService::AppClearDataObserverInit(); nsApplicationCacheService::AppClearDataObserverInit();
HTMLVideoElement::Init(); HTMLVideoElement::InitStatics();
nsGenericHTMLFrameElement::InitStatics(); nsGenericHTMLFrameElement::InitStatics();
#ifdef MOZ_XUL #ifdef MOZ_XUL