Backed out 3 changesets (bug 1535437, bug 1591253) for perma fails on browser_resizeVideo.js. CLOSED TREE

Backed out changeset 8222591127e9 (bug 1591253)
Backed out changeset d95a64f744b0 (bug 1535437)
Backed out changeset d5a82a15e3a5 (bug 1535437)
This commit is contained in:
Razvan Maries 2019-12-04 23:14:45 +02:00
parent 2bceb8b822
commit fbea30c915
8 changed files with 46 additions and 432 deletions

View File

@ -868,16 +868,6 @@ class PictureInPictureChild extends JSWindowActorChild {
}
break;
}
case "resize": {
let video = event.target;
if (this.inPictureInPicture(video)) {
this.sendAsyncMessage("PictureInPicture:Resize", {
videoHeight: video.videoHeight,
videoWidth: video.videoWidth,
});
}
break;
}
}
}
@ -1053,7 +1043,6 @@ class PictureInPictureChild extends JSWindowActorChild {
originatingVideo.addEventListener("play", this);
originatingVideo.addEventListener("pause", this);
originatingVideo.addEventListener("volumechange", this);
originatingVideo.addEventListener("resize", this);
}
}
@ -1070,7 +1059,6 @@ class PictureInPictureChild extends JSWindowActorChild {
originatingVideo.removeEventListener("play", this);
originatingVideo.removeEventListener("pause", this);
originatingVideo.removeEventListener("volumechange", this);
originatingVideo.removeEventListener("resize", this);
}
}

View File

@ -70,11 +70,6 @@ class PictureInPictureParent extends JSWindowActorParent {
PictureInPicture.handlePictureInPictureRequest(browser, videoData);
break;
}
case "PictureInPicture:Resize": {
let videoData = aMessage.data;
PictureInPicture.resizePictureInPictureWindow(videoData);
break;
}
case "PictureInPicture:Close": {
/**
* Content has requested that its Picture in Picture window go away.
@ -279,76 +274,7 @@ var PictureInPicture = {
* Resolves once the window has opened and loaded the player component.
*/
async openPipWindow(parentWin, videoData) {
let { top, left, width, height } = this.fitToScreen(parentWin, videoData);
let features =
`${PLAYER_FEATURES},top=${top},left=${left},` +
`outerWidth=${width},outerHeight=${height}`;
let pipWindow = Services.ww.openWindow(
parentWin,
PLAYER_URI,
null,
features,
null
);
TelemetryStopwatch.start(
"FX_PICTURE_IN_PICTURE_WINDOW_OPEN_DURATION",
pipWindow,
{
inSeconds: true,
}
);
return new Promise(resolve => {
pipWindow.addEventListener(
"load",
() => {
resolve(pipWindow);
},
{ once: true }
);
});
},
/**
* Calculate the desired size and position for a Picture in Picture window
* for the provided window and videoData.
*
* @param windowOrPlayer (chrome window|player window)
* The window hosting the browser that requested the Picture in
* Picture window. If this is an existing player window then the returned
* player size and position will be determined based on the existing
* player window's size and position.
*
* @param videoData (object)
* An object containing the following properties:
*
* videoHeight (int):
* The preferred height of the video.
*
* videoWidth (int):
* The preferred width of the video.
*
* @returns object
* The size and position for the player window.
*
* top (int):
* The top position for the player window.
*
* left (int):
* The left position for the player window.
*
* width (int):
* The width of the player window.
*
* height (int):
* The height of the player window.
*/
fitToScreen(windowOrPlayer, videoData) {
let { videoHeight, videoWidth } = videoData;
let isPlayerWindow = windowOrPlayer == this.getWeakPipPlayer();
// The Picture in Picture window will open on the same display as the
// originating window, and anchor to the bottom right.
@ -356,8 +282,8 @@ var PictureInPicture = {
Ci.nsIScreenManager
);
let screen = screenManager.screenForRect(
windowOrPlayer.screenX,
windowOrPlayer.screenY,
parentWin.screenX,
parentWin.screenY,
1,
1
);
@ -391,87 +317,36 @@ var PictureInPicture = {
screenTop.value =
(screenTop.value - fullTop.value) * scaleFactor + fullTop.value;
// If we have a player window, maintain the previous player window's size by
// clamping the new video's largest dimension to the player window's
// largest dimension.
//
// Otherwise the Picture in Picture window will be a maximum of a quarter of
// the screen height, and a third of the screen width.
let preferredSize;
if (isPlayerWindow) {
let prevWidth = windowOrPlayer.innerWidth;
let prevHeight = windowOrPlayer.innerHeight;
preferredSize = prevWidth >= prevHeight ? prevWidth : prevHeight;
}
const MAX_HEIGHT = preferredSize || screenHeight.value / 4;
const MAX_WIDTH = preferredSize || screenWidth.value / 3;
// For now, the Picture in Picture window will be a maximum of a quarter
// of the screen height, and a third of the screen width.
const MAX_HEIGHT = screenHeight.value / 4;
const MAX_WIDTH = screenWidth.value / 3;
let width = videoWidth;
let height = videoHeight;
let aspectRatio = videoWidth / videoHeight;
let resultWidth = videoWidth;
let resultHeight = videoHeight;
if (
videoHeight > MAX_HEIGHT ||
videoWidth > MAX_WIDTH ||
(isPlayerWindow && videoHeight < MAX_HEIGHT && videoWidth < MAX_WIDTH)
) {
// We're bigger than the max, or smaller than the previous player window.
// Take the largest dimension and clamp it to the associated max.
// Recalculate the other dimension to maintain aspect ratio.
if (videoHeight > MAX_HEIGHT || videoWidth > MAX_WIDTH) {
let aspectRatio = videoWidth / videoHeight;
// We're bigger than the max - take the largest dimension and clamp
// it to the associated max. Recalculate the other dimension to maintain
// aspect ratio.
if (videoWidth >= videoHeight) {
// We're clamping the width, so the height must be adjusted to match
// the original aspect ratio. Since aspect ratio is width over height,
// that means we need to _divide_ the MAX_WIDTH by the aspect ratio to
// calculate the appropriate height.
width = MAX_WIDTH;
height = Math.round(MAX_WIDTH / aspectRatio);
resultWidth = MAX_WIDTH;
resultHeight = Math.round(MAX_WIDTH / aspectRatio);
} else {
// We're clamping the height, so the width must be adjusted to match
// the original aspect ratio. Since aspect ratio is width over height,
// this means we need to _multiply_ the MAX_HEIGHT by the aspect ratio
// to calculate the appropriate width.
height = MAX_HEIGHT;
width = Math.round(MAX_HEIGHT * aspectRatio);
resultHeight = MAX_HEIGHT;
resultWidth = Math.round(MAX_HEIGHT * aspectRatio);
}
}
// Figure out where to position the window on screen. If we have a player
// window this will account for any change in video size. Otherwise the
// video will be positioned in the bottom right.
if (isPlayerWindow) {
// We might need to move the window to keep its positioning in a similar
// part of the screen.
//
// Find the distance from each edge of the screen of the old video, we'll
// keep the closest edge in the same spot.
let prevWidth = windowOrPlayer.innerWidth;
let prevHeight = windowOrPlayer.innerHeight;
let distanceLeft = windowOrPlayer.screenX;
let distanceRight =
screenWidth.value - windowOrPlayer.screenX - prevWidth;
let distanceTop = windowOrPlayer.screenY;
let distanceBottom =
screenHeight.value - windowOrPlayer.screenY - prevHeight;
let left = windowOrPlayer.screenX;
let top = windowOrPlayer.screenY;
if (distanceRight < distanceLeft) {
// Closer to the right edge than the left. Move the window right by
// the difference in the video widths.
left += prevWidth - width;
}
if (distanceBottom < distanceTop) {
// Closer to the bottom edge than the top. Move the window down by
// the difference in the video heights.
top += prevHeight - height;
}
return { top, left, width, height };
}
// Now that we have the dimensions of the video, we need to figure out how
// to position it in the bottom right corner. Since we know the width of the
// available rect, we need to subtract the dimensions of the window we're
@ -487,24 +362,39 @@ var PictureInPicture = {
// the screenLeft and screenTop values, which tell us where this screen is
// located relative to the "origin" in absolute coordinates.
let isRTL = Services.locale.isAppLocaleRTL;
let left = isRTL
let pipLeft = isRTL
? screenLeft.value
: screenLeft.value + screenWidth.value - width;
let top = screenTop.value + screenHeight.value - height;
: screenLeft.value + screenWidth.value - resultWidth;
let pipTop = screenTop.value + screenHeight.value - resultHeight;
let features =
`${PLAYER_FEATURES},top=${pipTop},left=${pipLeft},` +
`outerWidth=${resultWidth},outerHeight=${resultHeight}`;
return { top, left, width, height };
},
let pipWindow = Services.ww.openWindow(
parentWin,
PLAYER_URI,
null,
features,
null
);
resizePictureInPictureWindow(videoData) {
let win = this.getWeakPipPlayer();
TelemetryStopwatch.start(
"FX_PICTURE_IN_PICTURE_WINDOW_OPEN_DURATION",
pipWindow,
{
inSeconds: true,
}
);
if (!win) {
return;
}
let { top, left, width, height } = this.fitToScreen(win, videoData);
win.resizeTo(width, height);
win.moveTo(left, top);
return new Promise(resolve => {
pipWindow.addEventListener(
"load",
() => {
resolve(pipWindow);
},
{ once: true }
);
});
},
openToggleContextMenu(window, data) {

View File

@ -10,8 +10,6 @@ support-files =
test-transparent-overlay-1.html
test-transparent-overlay-2.html
test-video.mp4
test-video-cropped.mp4
test-video-vertical.mp4
prefs =
media.videocontrols.picture-in-picture.enabled=true
@ -31,8 +29,6 @@ skip-if = os == "mac" # Bug 1599376
skip-if = debug
[browser_removeVideoElement.js]
[browser_rerequestPiP.js]
[browser_resizeVideo.js]
skip-if = os == 'linux' # Bug 1594223
[browser_showMessage.js]
[browser_stripVideoStyles.js]
[browser_thirdPartyIframe.js]

View File

@ -1,249 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Run the resize test on a player window.
*
* @param browser (xul:browser)
* The browser that has the source video.
*
* @param videoID (string)
* The id of the video in the browser to test.
*
* @param pipWin (player window)
* A player window to run the tests on.
*
* @param opts (object)
* The options for the test.
*
* pinX (boolean):
* If true, the video's X position shouldn't change when resized.
*
* pinY (boolean):
* If true, the video's Y position shouldn't change when resized.
*/
async function testVideo(browser, videoID, pipWin, { pinX, pinY } = {}) {
async function switchVideoSource(src) {
let videoResized = BrowserTestUtils.waitForEvent(pipWin, "resize");
await ContentTask.spawn(
browser,
{ src, videoID },
async ({ src, videoID }) => {
let doc = content.document;
let video = doc.getElementById(videoID);
video.src = src;
}
);
await videoResized;
}
/**
* Check the new screen position against the previous one. When
* pinX or pinY is true then the top left corner is checked in that
* dimension. Otherwise, the bottom right corner is checked.
*
* The video position is determined by the screen edge it's closest
* to, so in the default bottom right its bottom right corner should
* match the previous video's bottom right corner. For the top left,
* the top left corners should match.
*/
function checkPosition(
previousScreenX,
previousScreenY,
previousWidth,
previousHeight,
newScreenX,
newScreenY,
newWidth,
newHeight
) {
if (pinX) {
Assert.equal(
previousScreenX,
newScreenX,
"New video is still in the same X position"
);
} else {
Assert.equal(
previousScreenX + previousWidth,
newScreenX + newWidth,
"New video ends at the same screen X position"
);
}
if (pinY) {
Assert.equal(
previousScreenY,
newScreenY,
"New video is still in the same Y position"
);
} else {
Assert.equal(
previousScreenY + previousHeight,
newScreenY + newHeight,
"New video ends at the same screen Y position"
);
}
}
Assert.ok(pipWin, "Got PiP window.");
let initialWidth = pipWin.innerWidth;
let initialHeight = pipWin.innerHeight;
let initialAspectRatio = initialWidth / initialHeight;
Assert.equal(
Math.floor(initialAspectRatio * 100),
177, // 16 / 9 = 1.777777777
"Original aspect ratio is 16:9"
);
// Store the window position for later.
let initialScreenX = pipWin.mozInnerScreenX;
let initialScreenY = pipWin.mozInnerScreenY;
await switchVideoSource("test-video-cropped.mp4");
let resizedWidth = pipWin.innerWidth;
let resizedHeight = pipWin.innerHeight;
let resizedAspectRatio = resizedWidth / resizedHeight;
Assert.equal(
Math.floor(resizedAspectRatio * 100),
133, // 4 / 3 = 1.333333333
"Resized aspect ratio is 4:3"
);
Assert.equal(initialWidth, resizedWidth, "Resized video has the same width");
Assert.greater(resizedHeight, initialHeight, "Resized video grew vertically");
let resizedScreenX = pipWin.mozInnerScreenX;
let resizedScreenY = pipWin.mozInnerScreenY;
checkPosition(
initialScreenX,
initialScreenY,
initialWidth,
initialHeight,
resizedScreenX,
resizedScreenY,
resizedWidth,
resizedHeight
);
await switchVideoSource("test-video-vertical.mp4");
let verticalWidth = pipWin.innerWidth;
let verticalHeight = pipWin.innerHeight;
let verticalAspectRatio = verticalWidth / verticalHeight;
Assert.equal(
Math.floor(verticalAspectRatio * 100),
50, // 1 / 2 = 0.5
"Vertical aspect ratio is 1:2"
);
Assert.less(verticalWidth, resizedWidth, "Vertical video width shrunk");
Assert.equal(
resizedWidth,
verticalHeight,
"Vertical video height matches previous width"
);
let verticalScreenX = pipWin.mozInnerScreenX;
let verticalScreenY = pipWin.mozInnerScreenY;
checkPosition(
resizedScreenX,
resizedScreenY,
resizedWidth,
resizedHeight,
verticalScreenX,
verticalScreenY,
verticalWidth,
verticalHeight
);
await switchVideoSource("test-video.mp4");
let restoredWidth = pipWin.innerWidth;
let restoredHeight = pipWin.innerHeight;
let restoredAspectRatio = restoredWidth / restoredHeight;
Assert.equal(
Math.floor(restoredAspectRatio * 100),
177,
"Restored aspect ratio is still 16:9"
);
Assert.equal(
initialWidth,
pipWin.innerWidth,
"Restored video has its original width"
);
Assert.equal(
initialHeight,
pipWin.innerHeight,
"Restored video has its original height"
);
let restoredScreenX = pipWin.mozInnerScreenX;
let restoredScreenY = pipWin.mozInnerScreenY;
checkPosition(
initialScreenX,
initialScreenY,
initialWidth,
initialHeight,
restoredScreenX,
restoredScreenY,
restoredWidth,
restoredHeight
);
}
/**
* Tests that if a <video> element is resized the Picture-in-Picture window
* will be resized to match the new dimensions.
*/
add_task(async () => {
for (let videoID of ["with-controls", "no-controls"]) {
info(`Testing ${videoID} case.`);
await BrowserTestUtils.withNewTab(
{
url: TEST_PAGE,
gBrowser,
},
async browser => {
let pipWin = await triggerPictureInPicture(browser, videoID);
await testVideo(browser, videoID, pipWin);
pipWin.moveTo(0, 0);
await testVideo(browser, videoID, pipWin, { pinX: true, pinY: true });
await BrowserTestUtils.closeWindow(pipWin);
}
);
}
});
/**
* Tests that the RTL video starts on the left and is pinned in the X dimension.
*/
add_task(async () => {
await SpecialPowers.pushPrefEnv({ set: [["intl.l10n.pseudo", "bidi"]] });
for (let videoID of ["with-controls", "no-controls"]) {
info(`Testing ${videoID} case.`);
await BrowserTestUtils.withNewTab(
{
url: TEST_PAGE,
gBrowser,
},
async browser => {
let pipWin = await triggerPictureInPicture(browser, videoID);
await testVideo(browser, videoID, pipWin, { pinX: true });
await BrowserTestUtils.closeWindow(pipWin);
}
);
}
await SpecialPowers.popPrefEnv();
});

View File

@ -46,7 +46,6 @@ async function triggerPictureInPicture(browser, videoID) {
});
let win = await domWindowOpened;
await BrowserTestUtils.waitForEvent(win, "load");
await win.promiseDocumentFlushed(() => {});
await videoReady;
return win;
}

View File

@ -1864,13 +1864,8 @@ void nsWindow::Resize(double aWidth, double aHeight, bool aRepaint) {
ClearThemeRegion();
double oldScale = mDefaultScale;
mResizeState = RESIZING;
VERIFY(
::SetWindowPos(mWnd, nullptr, 0, 0, width, GetHeight(height), flags));
mResizeState = NOT_RESIZING;
if (mAspectRatio != 0.0) {
LockAspectRatio(true);
}
if (WinUtils::LogToPhysFactor(mWnd) != oldScale) {
ChangedDPI();
}
@ -1918,13 +1913,8 @@ void nsWindow::Resize(double aX, double aY, double aWidth, double aHeight,
ClearThemeRegion();
double oldScale = mDefaultScale;
mResizeState = RESIZING;
VERIFY(
::SetWindowPos(mWnd, nullptr, x, y, width, GetHeight(height), flags));
mResizeState = NOT_RESIZING;
if (mAspectRatio != 0.0) {
LockAspectRatio(true);
}
if (WinUtils::LogToPhysFactor(mWnd) != oldScale) {
ChangedDPI();
}