зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
7aecfc00e9
Коммит
ca728851ca
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче