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
Родитель 1764384541
Коммит 06a43c8cd0
4 изменённых файлов: 32 добавлений и 1 удалений

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

@ -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

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

@ -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) {

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

@ -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);

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

@ -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(