diff --git a/toolkit/actors/PictureInPictureChild.jsm b/toolkit/actors/PictureInPictureChild.jsm index 47288cf6b958..eb45816a8101 100644 --- a/toolkit/actors/PictureInPictureChild.jsm +++ b/toolkit/actors/PictureInPictureChild.jsm @@ -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); } } diff --git a/toolkit/components/pictureinpicture/PictureInPicture.jsm b/toolkit/components/pictureinpicture/PictureInPicture.jsm index cfbe26358b4b..0eac3e475c43 100644 --- a/toolkit/components/pictureinpicture/PictureInPicture.jsm +++ b/toolkit/components/pictureinpicture/PictureInPicture.jsm @@ -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) { diff --git a/toolkit/components/pictureinpicture/tests/browser.ini b/toolkit/components/pictureinpicture/tests/browser.ini index 43c3a70ca41e..8dd2c9811cf0 100644 --- a/toolkit/components/pictureinpicture/tests/browser.ini +++ b/toolkit/components/pictureinpicture/tests/browser.ini @@ -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] diff --git a/toolkit/components/pictureinpicture/tests/browser_resizeVideo.js b/toolkit/components/pictureinpicture/tests/browser_resizeVideo.js deleted file mode 100644 index 2565a34829bf..000000000000 --- a/toolkit/components/pictureinpicture/tests/browser_resizeVideo.js +++ /dev/null @@ -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