Bug 1659060 - part1 : treat lock visible if corresponding document has in use picture-in-picture element. r=bryce,smaug

When a tab is in the background, its document visibility would become invisible even if a tab owns a video which is visible because of being used in picture in picture mode.

When a document changes its visibility, the wakelock would change its lockstate from `lock-foreground` to `lock-background`. For `video-playing` wakelock topic, we would only request a real platform lock for `lock-foreground` because we don't want to prevent screen from sleeping if the video is invisible.

Therefore, considering if video is being used in picture in picture mode, when determining the wakelock's visible state. If video is still being used in picture in picture mode, then we would treat wakelock as if it's in foreground in order to keep a screen lock.

Differential Revision: https://phabricator.services.mozilla.com/D90781
This commit is contained in:
alwu 2020-09-23 23:34:12 +00:00
parent 1764384541
commit 06a43c8cd0
4 changed files with 32 additions and 1 deletions

View File

@ -16900,5 +16900,19 @@ void Document::GetConnectedShadowRoots(
}
}
bool Document::HasPictureInPictureChildElement() const {
return mPictureInPictureChildElementCount > 0;
}
void Document::EnableChildElementInPictureInPictureMode() {
mPictureInPictureChildElementCount++;
MOZ_ASSERT(mPictureInPictureChildElementCount >= 0);
}
void Document::DisableChildElementInPictureInPictureMode() {
mPictureInPictureChildElementCount--;
MOZ_ASSERT(mPictureInPictureChildElementCount >= 0);
}
} // namespace dom
} // namespace mozilla

View File

@ -3406,6 +3406,16 @@ class Document : public nsINode,
bool Hidden() const { return mVisibilityState != VisibilityState::Visible; }
dom::VisibilityState VisibilityState() const { return mVisibilityState; }
private:
int32_t mPictureInPictureChildElementCount = 0;
public:
void EnableChildElementInPictureInPictureMode();
void DisableChildElementInPictureInPictureMode();
// True if any child element is being used in picture in picture mode.
bool HasPictureInPictureChildElement() const;
void GetSelectedStyleSheetSet(nsAString& aSheetSet);
void SetSelectedStyleSheetSet(const nsAString& aSheetSet);
void GetLastStyleSheetSet(nsAString& aSheetSet) {

View File

@ -526,6 +526,7 @@ void HTMLVideoElement::MaybeBeginCloningVisually() {
mDecoder->SetSecondaryVideoContainer(
mVisualCloneTarget->GetVideoFrameContainer());
UpdateMediaControlAfterPictureInPictureModeChanged();
OwnerDoc()->EnableChildElementInPictureInPictureMode();
} else if (mSrcStream) {
VideoFrameContainer* container =
mVisualCloneTarget->GetVideoFrameContainer();
@ -538,6 +539,7 @@ void HTMLVideoElement::MaybeBeginCloningVisually() {
SetSecondaryMediaStreamRenderer(container, mSecondaryVideoOutput);
}
UpdateMediaControlAfterPictureInPictureModeChanged();
OwnerDoc()->EnableChildElementInPictureInPictureMode();
}
}
@ -546,6 +548,7 @@ void HTMLVideoElement::EndCloningVisually() {
if (mDecoder) {
mDecoder->SetSecondaryVideoContainer(nullptr);
OwnerDoc()->DisableChildElementInPictureInPictureMode();
} else if (mSrcStream) {
if (mSecondaryVideoOutput) {
mVideoWatchManager.Unwatch(
@ -554,6 +557,7 @@ void HTMLVideoElement::EndCloningVisually() {
mSecondaryVideoOutput = nullptr;
}
SetSecondaryMediaStreamRenderer(nullptr);
OwnerDoc()->DisableChildElementInPictureInPictureMode();
}
Unused << mVisualCloneTarget->SetVisualCloneSource(nullptr);

View File

@ -205,7 +205,10 @@ WakeLock::HandleEvent(Event* aEvent) {
NS_ENSURE_STATE(doc);
bool oldHidden = mHidden;
mHidden = doc->Hidden();
// If document has a child element being used in the picture in picture
// mode, which is always visible to users, then we would consider the
// document as visible as well.
mHidden = doc->Hidden() && !doc->HasPictureInPictureChildElement();
if (mLocked && oldHidden != mHidden) {
hal::ModifyWakeLock(