Commit 14b71949 authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃
Browse files

Bug 2063031 - Spoof video PiP size under RFP. r=media-playback-reviewers,kpatenio,alwu,tjr

parent d209b455
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -47,6 +47,11 @@ int32_t PictureInPictureWindow::Width() const {
  if (!IsStateOpened()) {
    return 0;
  }
  RefPtr<HTMLVideoElement> videoElement = mAssociatedVideoElement.get();
  if (videoElement && videoElement->OwnerDoc()->ShouldResistFingerprinting(
                          RFPTarget::ScreenRect)) {
    return VideoSizeForRFP().width;
  }
  return mWidth;
}

@@ -57,14 +62,54 @@ int32_t PictureInPictureWindow::Height() const {
  if (!IsStateOpened()) {
    return 0;
  }
  RefPtr<HTMLVideoElement> videoElement = mAssociatedVideoElement.get();
  if (videoElement && videoElement->OwnerDoc()->ShouldResistFingerprinting(
                          RFPTarget::ScreenRect)) {
    return VideoSizeForRFP().height;
  }
  return mHeight;
}

gfx::IntSize PictureInPictureWindow::VideoSizeForRFP() const {
  RefPtr<HTMLVideoElement> videoElement = mAssociatedVideoElement.get();
  if (!videoElement) {
    return {0, 0};
  }

  // From PictureInPicture.sys.mjs: "The Picture in Picture window will be a
  // maximum of a quarter of the screen height, and a third of the screen
  // width.".
  // Pretend we are maximizing the video in a 1920x1080 display.
  const uint32_t maxWidth = 1920 / 3;
  const uint32_t maxHeight = 1080 / 4;
  uint32_t width = videoElement->VideoWidth();
  uint32_t height = videoElement->VideoHeight();
  if ((height > maxHeight || width > maxWidth) && height > 0) {
    double aspectRatio = static_cast<double>(width) / height;
    if (width >= height) {
      width = maxWidth;
      height = static_cast<uint32_t>(round(maxWidth / aspectRatio));
    } else {
      height = maxHeight;
      width = static_cast<uint32_t>(round(maxHeight * aspectRatio));
    }
  }
  return {width, height};
}

void PictureInPictureWindow::NotifyDimensionsChanged(int32_t aWidth,
                                                     int32_t aHeight) {
  mWidth = aWidth;
  mHeight = aHeight;

  RefPtr<HTMLVideoElement> videoElement = mAssociatedVideoElement.get();
  if (videoElement && videoElement->OwnerDoc()->ShouldResistFingerprinting(
                          RFPTarget::ScreenRect)) {
    // With RFP, we spoof the window size to a fixed size that depends on the
    // video, therefore it does not make sense to trigger a resize event.
    return;
  }

  // When the size of a Picture-in-Picture window pipWindow changes,
  // the user agent MUST queue a task to fire an event named resize at
  // pipWindow.
+2 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ class PictureInPictureWindow final : public DOMEventTargetHelper {
 private:
  bool IsStateOpened() const { return mOpened; }

  gfx::IntSize VideoSizeForRFP() const;

  WeakPtr<HTMLVideoElement> mAssociatedVideoElement;
  int32_t mWidth = 0;
  int32_t mHeight = 0;
+3 −3
Original line number Diff line number Diff line
@@ -315,7 +315,7 @@ bool HTMLVideoElement::IsInteractiveHTMLContent() const {
         HTMLMediaElement::IsInteractiveHTMLContent();
}

gfx::IntSize HTMLVideoElement::GetVideoIntrinsicDimensions() {
gfx::IntSize HTMLVideoElement::GetVideoIntrinsicDimensions() const {
  const auto& sz = mMediaInfo.mVideo.mDisplay;

  // Prefer the size of the container as it's more up to date.
@@ -324,7 +324,7 @@ gfx::IntSize HTMLVideoElement::GetVideoIntrinsicDimensions() {
      .valueOr(sz);
}

uint32_t HTMLVideoElement::VideoWidth() {
uint32_t HTMLVideoElement::VideoWidth() const {
  if (!HasVideo()) {
    return 0;
  }
@@ -336,7 +336,7 @@ uint32_t HTMLVideoElement::VideoWidth() {
  return size.width;
}

uint32_t HTMLVideoElement::VideoHeight() {
uint32_t HTMLVideoElement::VideoHeight() const {
  if (!HasVideo()) {
    return 0;
  }
+3 −3
Original line number Diff line number Diff line
@@ -96,9 +96,9 @@ class HTMLVideoElement final : public HTMLMediaElement {
    SetUnsignedIntAttr(nsGkAtoms::height, aValue, 0, aRv);
  }

  uint32_t VideoWidth();
  uint32_t VideoWidth() const;

  uint32_t VideoHeight();
  uint32_t VideoHeight() const;

  VideoRotation RotationDegrees() const { return mMediaInfo.mVideo.mRotation; }

@@ -179,7 +179,7 @@ class HTMLVideoElement final : public HTMLMediaElement {
  void CreateVideoWakeLockIfNeeded();
  void ReleaseVideoWakeLockIfExists();

  gfx::IntSize GetVideoIntrinsicDimensions();
  gfx::IntSize GetVideoIntrinsicDimensions() const;

  RefPtr<WakeLock> mScreenWakeLock;

+2 −0
Original line number Diff line number Diff line
@@ -158,6 +158,8 @@ support-files = ["test-page-with-nan-video-duration.html"]

["browser_removeVideoElement.js"]

["browser_resistFingerprinting.js"]

["browser_resizeVideo.js"]
skip-if = [
  "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11'", # Bug 1594223
Loading