Bug 1623486 - part4 : update Picture-in-Picture mode status from media element. r=chunmin,padenot

Video element can start the Picture-in-Picture mode **BEFORE** or **AFTER** we start the listener for the media cotrol, so we have to ensure we always propagate this information to the chrome process via `ContentMediaAgent`.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
alwu 2020-04-01 23:04:58 +00:00
parent 44bd719954
commit 09a518586f
3 changed files with 37 additions and 1 deletions

View File

@ -472,6 +472,17 @@ class HTMLMediaElement::MediaControlEventListener final
}
}
void SetPictureInPictureModeEnabled(bool aIsEnabled) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsStarted());
if (mIsPictureInPictureEnabled == aIsEnabled) {
return;
}
mIsPictureInPictureEnabled = aIsEnabled;
mControlAgent->NotifyPictureInPictureModeChanged(
this, mIsPictureInPictureEnabled);
}
void OnKeyPressed(MediaControlKeysEvent aEvent) override {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsStarted());
@ -528,6 +539,7 @@ class HTMLMediaElement::MediaControlEventListener final
ControlledMediaState mState = ControlledMediaState::eStopped;
WeakPtr<HTMLMediaElement> mElement;
RefPtr<ContentMediaAgent> mControlAgent;
bool mIsPictureInPictureEnabled = false;
bool mIsOwnerAudible = false;
};
@ -7736,6 +7748,11 @@ void HTMLMediaElement::StartListeningMediaControlEventIfNeeded() {
// but the audible state update could happen before that. Therefore, we have
// to manually update media's audible state as well.
mMediaControlEventListener->UpdateMediaAudibleState(IsAudible());
// Picture-in-Picture mode can be enabled before we start the listener so we
// manually update the status here in case not to forgot to propagate that.
mMediaControlEventListener->SetPictureInPictureModeEnabled(
IsBeingUsedInPictureInPictureMode());
}
void HTMLMediaElement::StopListeningMediaControlEventIfNeeded() {
@ -7795,6 +7812,19 @@ void HTMLMediaElement::ClearStopMediaControlTimerIfNeeded() {
}
}
void HTMLMediaElement::UpdateMediaControlAfterPictureInPictureModeChanged() {
// Hasn't started to connect with media control, no need to update anything.
if (!mMediaControlEventListener || !mMediaControlEventListener->IsStarted()) {
return;
}
if (IsBeingUsedInPictureInPictureMode()) {
mMediaControlEventListener->SetPictureInPictureModeEnabled(true);
} else {
mMediaControlEventListener->SetPictureInPictureModeEnabled(false);
CreateStopMediaControlTimerIfNeeded();
}
}
bool HTMLMediaElement::IsBeingUsedInPictureInPictureMode() const {
if (!IsVideo()) {
return false;

View File

@ -1346,6 +1346,10 @@ class HTMLMediaElement : public nsGenericHTMLElement,
// key events.
void ClearStopMediaControlTimerIfNeeded();
// This function is used to update the status of media control when the media
// changes its status of being used in the Picture-in-Picture mode.
void UpdateMediaControlAfterPictureInPictureModeChanged();
// The current decoder. Load() has been called on this decoder.
// At most one of mDecoder and mSrcStream can be non-null.
RefPtr<MediaDecoder> mDecoder;

View File

@ -552,6 +552,7 @@ void HTMLVideoElement::MaybeBeginCloningVisually() {
if (container) {
mDecoder->SetSecondaryVideoContainer(container);
}
UpdateMediaControlAfterPictureInPictureModeChanged();
} else if (mSrcStream) {
VideoFrameContainer* container =
mVisualCloneTarget->GetVideoFrameContainer();
@ -561,6 +562,7 @@ void HTMLVideoElement::MaybeBeginCloningVisually() {
this, container, mAbstractMainThread);
mSelectedVideoStreamTrack->AddVideoOutput(mSecondaryVideoOutput);
}
UpdateMediaControlAfterPictureInPictureModeChanged();
}
}
@ -582,7 +584,7 @@ void HTMLVideoElement::EndCloningVisually() {
Unused << mVisualCloneTarget->SetVisualCloneSource(nullptr);
Unused << SetVisualCloneTarget(nullptr);
CreateStopMediaControlTimerIfNeeded();
UpdateMediaControlAfterPictureInPictureModeChanged();
if (IsInComposedDoc() && !StaticPrefs::media_cloneElementVisually_testing()) {
NotifyUAWidgetSetupOrChange();