Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/**
* Test the wakelock usage for video being used in the picture-in-picuture (PIP)
* mode. When video is playing in PIP window, we would always request a video
* wakelock, and request audio wakelock only when video is audible.
*/
add_task(async function testCheckWakelockForPIPVideo() {
await checkWakelockWhenChangeTabVisibility({
description: "playing a PIP video",
lockAudio: true,
lockVideo: true,
});
await checkWakelockWhenChangeTabVisibility({
description: "playing a muted PIP video",
additionalParams: {
muted: true,
},
lockAudio: false,
lockVideo: true,
});
await checkWakelockWhenChangeTabVisibility({
description: "playing a volume=0 PIP video",
additionalParams: {
volume: 0.0,
},
lockAudio: false,
lockVideo: true,
});
});
/**
* Following are helper functions and variables.
*/
const PAGE_URL =
const AUDIO_WAKELOCK_NAME = "audio-playing";
const VIDEO_WAKELOCK_NAME = "video-playing";
const TEST_VIDEO_ID = "v";
// Import this in order to use `triggerPictureInPicture()`.
Services.scriptloader.loadSubScript(
this
);
async function checkWakelockWhenChangeTabVisibility({
description,
additionalParams,
lockAudio,
lockVideo,
}) {
const originalTab = gBrowser.selectedTab;
info(`start a new tab for '${description}'`);
const tab = await BrowserTestUtils.openNewForegroundTab(
window.gBrowser,
PAGE_URL
);
info(`wait for PIP video starting playing`);
await startPIPVideo(tab, additionalParams);
await waitForExpectedWakeLockState(AUDIO_WAKELOCK_NAME, {
needLock: lockAudio,
isForegroundLock: true,
});
await waitForExpectedWakeLockState(VIDEO_WAKELOCK_NAME, {
needLock: lockVideo,
isForegroundLock: true,
});
info(
`switch tab to background and still own foreground locks due to visible PIP video`
);
await BrowserTestUtils.switchTab(window.gBrowser, originalTab);
await waitForExpectedWakeLockState(AUDIO_WAKELOCK_NAME, {
needLock: lockAudio,
isForegroundLock: true,
});
await waitForExpectedWakeLockState(VIDEO_WAKELOCK_NAME, {
needLock: lockVideo,
isForegroundLock: true,
});
info(`pausing PIP video should release all locks`);
await pausePIPVideo(tab);
await waitForExpectedWakeLockState(AUDIO_WAKELOCK_NAME, {
needLock: false,
});
await waitForExpectedWakeLockState(VIDEO_WAKELOCK_NAME, {
needLock: false,
});
info(`resuming PIP video should request locks again`);
await resumePIPVideo(tab);
await waitForExpectedWakeLockState(AUDIO_WAKELOCK_NAME, {
needLock: lockAudio,
isForegroundLock: true,
});
await waitForExpectedWakeLockState(VIDEO_WAKELOCK_NAME, {
needLock: lockVideo,
isForegroundLock: true,
});
info(`switch tab to foreground again`);
await BrowserTestUtils.switchTab(window.gBrowser, tab);
await waitForExpectedWakeLockState(AUDIO_WAKELOCK_NAME, {
needLock: lockAudio,
isForegroundLock: true,
});
await waitForExpectedWakeLockState(VIDEO_WAKELOCK_NAME, {
needLock: lockVideo,
isForegroundLock: true,
});
info(`remove tab`);
await BrowserTestUtils.closeWindow(tab.PIPWindow);
BrowserTestUtils.removeTab(tab);
}
async function startPIPVideo(tab, { muted, volume } = {}) {
tab.PIPWindow = await triggerPictureInPicture(
tab.linkedBrowser,
TEST_VIDEO_ID
);
await SpecialPowers.spawn(
tab.linkedBrowser,
[muted, volume, TEST_VIDEO_ID],
async (muted, volume, Id) => {
const video = content.document.getElementById(Id);
if (muted) {
video.muted = muted;
}
if (volume !== undefined) {
video.volume = volume;
}
ok(
await video.play().then(
() => true,
() => false
),
`video started playing.`
);
}
);
}
function pausePIPVideo(tab) {
return SpecialPowers.spawn(tab.linkedBrowser, [TEST_VIDEO_ID], Id => {
content.document.getElementById(Id).pause();
});
}
function resumePIPVideo(tab) {
return SpecialPowers.spawn(tab.linkedBrowser, [TEST_VIDEO_ID], async Id => {
await content.document.getElementById(Id).play();
});
}