зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1627999 - part9 : handle the owner browsing context change for the media element. r=chunmin
This patch will do : - update the media status when media changes its owner browsing context The advantage of doing so : - make the media status in `ContextMediaInfo` correcly More details : `ContextMediaInfo` stores the media status of each browsing context, but actually the media doesn't always need to stay in one browsing context. We can move it to other browsing contexts (iframe) by appending it to other browsing context's document body. For example, in [1], we move the video from the main frame to another iframe. Therefore, when we move the media to a new browsing context, we should also update its media status (controlledMedia/playing/audio number) for its previous owner browsing context. [1] https://searchfox.org/mozilla-central/source/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-to-other-document.html Differential Revision: https://phabricator.services.mozilla.com/D75477
This commit is contained in:
Родитель
3c416fbc0a
Коммит
386dc9b342
|
@ -425,6 +425,7 @@ class HTMLMediaElement::MediaControlEventListener final
|
|||
// We have already been stopped, do not notify stop twice.
|
||||
return;
|
||||
}
|
||||
NotifyMediaStoppedPlaying();
|
||||
NotifyPlaybackStateChanged(MediaPlaybackState::eStopped);
|
||||
|
||||
// Remove ourselves from media agent, which would stop receiving event.
|
||||
|
@ -507,20 +508,62 @@ class HTMLMediaElement::MediaControlEventListener final
|
|||
}
|
||||
}
|
||||
|
||||
void UpdateOwnerBrowsingContextIfNeeded() {
|
||||
// Has not notified any information about the owner context yet.
|
||||
if (!IsStarted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BrowsingContext* currentBC = GetCurrentBrowsingContext();
|
||||
MOZ_ASSERT(currentBC && mOwnerBrowsingContext);
|
||||
// Still in the same browsing context, no need to update.
|
||||
if (currentBC == mOwnerBrowsingContext) {
|
||||
return;
|
||||
}
|
||||
MEDIACONTROL_LOG("Change browsing context from %" PRIu64 " to %" PRIu64,
|
||||
mOwnerBrowsingContext->Id(), currentBC->Id());
|
||||
// This situation would happen when we start a media in an original browsing
|
||||
// context, then we move it to another browsing context, such as an iframe,
|
||||
// so its owner browsing context would be changed. Therefore, we should
|
||||
// reset the media status for the previous browsing context by calling
|
||||
// `Stop()`, in which the listener would notify `ePaused` (if it's playing)
|
||||
// and `eStop`. Then calls `Start()`, in which the listener would notify
|
||||
// `eStart` to the new browsing context. If the media was playing before,
|
||||
// we would also notify `ePlayed`.
|
||||
bool wasInPlayingState = mState == MediaPlaybackState::ePlayed;
|
||||
Stop();
|
||||
Unused << Start();
|
||||
if (wasInPlayingState) {
|
||||
NotifyMediaStartedPlaying();
|
||||
}
|
||||
}
|
||||
|
||||
BrowsingContext* GetBrowsingContext() const override {
|
||||
nsPIDOMWindowInner* window = Owner()->OwnerDoc()->GetInnerWindow();
|
||||
return window ? window->GetBrowsingContext() : nullptr;
|
||||
return mOwnerBrowsingContext;
|
||||
}
|
||||
|
||||
private:
|
||||
~MediaControlEventListener() = default;
|
||||
|
||||
// The media can be moved around different browsing context, so this context
|
||||
// might be different from `mOwnerBrowsingContext` that we use to initialize
|
||||
// the `ContentMediaAgent`.
|
||||
BrowsingContext* GetCurrentBrowsingContext() const {
|
||||
nsPIDOMWindowInner* window = Owner()->OwnerDoc()->GetInnerWindow();
|
||||
return window ? window->GetBrowsingContext() : nullptr;
|
||||
}
|
||||
|
||||
bool InitMediaAgent() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mControlAgent = ContentMediaAgent::Get(GetBrowsingContext());
|
||||
BrowsingContext* currentBC = GetCurrentBrowsingContext();
|
||||
mControlAgent = ContentMediaAgent::Get(currentBC);
|
||||
if (!mControlAgent) {
|
||||
return false;
|
||||
}
|
||||
mOwnerBrowsingContext = currentBC;
|
||||
MOZ_ASSERT(mOwnerBrowsingContext);
|
||||
MEDIACONTROL_LOG("Init agent in browsing context %" PRIu64,
|
||||
mOwnerBrowsingContext->Id());
|
||||
mControlAgent->AddReceiver(this);
|
||||
return true;
|
||||
}
|
||||
|
@ -552,6 +595,7 @@ class HTMLMediaElement::MediaControlEventListener final
|
|||
RefPtr<ContentMediaAgent> mControlAgent;
|
||||
bool mIsPictureInPictureEnabled = false;
|
||||
bool mIsOwnerAudible = false;
|
||||
BrowsingContext* MOZ_NON_OWNING_REF mOwnerBrowsingContext = nullptr;
|
||||
};
|
||||
|
||||
class HTMLMediaElement::MediaStreamTrackListener
|
||||
|
@ -4643,6 +4687,9 @@ nsresult HTMLMediaElement::BindToTree(BindContext& aContext, nsINode& aParent) {
|
|||
}
|
||||
|
||||
NotifyDecoderActivityChanges();
|
||||
if (mMediaControlEventListener) {
|
||||
mMediaControlEventListener->UpdateOwnerBrowsingContextIfNeeded();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -7797,7 +7844,6 @@ void HTMLMediaElement::StartListeningMediaControlEventIfNeeded() {
|
|||
|
||||
void HTMLMediaElement::StopListeningMediaControlEventIfNeeded() {
|
||||
if (mMediaControlEventListener && mMediaControlEventListener->IsStarted()) {
|
||||
mMediaControlEventListener->NotifyMediaStoppedPlaying();
|
||||
mMediaControlEventListener->Stop();
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче