// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <optional>

#include "base/json/json_reader.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/gmock_expected_support.h"
#include "build/build_config.h"
#include "cc/base/math_util.h"
#include "content/browser/renderer_host/cross_process_frame_connector.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/browser/site_per_process_browsertest.h"
#include "content/common/input/actions_parser.h"
#include "content/common/input/synthetic_pointer_action.h"
#include "content/common/input/synthetic_touchscreen_pinch_gesture.h"
#include "content/public/browser/render_process_host_priority_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/synchronize_visual_properties_interceptor.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/test/render_document_feature.h"
#include "content/test/render_widget_host_visibility_observer.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "third_party/blink/public/mojom/frame/frame.mojom-test-utils.h"

#if defined(USE_AURA)
#include "ui/aura/window_tree_host.h"
#endif

#if BUILDFLAG(IS_MAC)
#include "content/common/input/synthetic_touchpad_pinch_gesture.h"
#include "ui/base/test/scoped_preferred_scroller_style_mac.h"
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "ui/aura/test/test_screen.h"
#endif

namespace content {

namespace {

double GetFrameDeviceScaleFactor(const ToRenderFrameHost& adapter) {
  return EvalJs(adapter, "window.devicePixelRatio;").ExtractDouble();
}

// Layout child frames in cross_site_iframe_factory.html so that they are the
// same width as the viewport, and 75% of the height of the window. This is for
// testing viewport intersection. Note this does not recurse into child frames
// and re-layout in the same way since children might be in a different origin.
void LayoutNonRecursiveForTestingViewportIntersection(
    const ToRenderFrameHost& execution_target) {
  static const char kRafScript[] = R"(
      let width = window.innerWidth;
      let height = window.innerHeight * 0.75;
      for (let i = 0; i < window.frames.length; i++) {
        let child = document.getElementById("child-" + i);
        child.width = width;
        child.height = height;
      }
  )";
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(execution_target, kRafScript, "")
                  .error.empty());
}

// Check |intersects_viewport| on widget and process.
bool CheckIntersectsViewport(bool expected, FrameTreeNode* node) {
  RenderProcessHostPriorityClient::Priority priority =
      node->current_frame_host()->GetRenderWidgetHost()->GetPriority();
  return priority.intersects_viewport == expected &&
         node->current_frame_host()->GetProcess()->GetIntersectsViewport() ==
             expected;
}

// Helper function to generate a click on the given RenderWidgetHost.  The
// mouse event is forwarded directly to the RenderWidgetHost without any
// hit-testing.
void SimulateMouseClick(RenderWidgetHost* rwh, int x, int y) {
  blink::WebMouseEvent mouse_event(
      blink::WebInputEvent::Type::kMouseDown,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  mouse_event.button = blink::WebPointerProperties::Button::kLeft;
  mouse_event.SetPositionInWidget(x, y);
  rwh->ForwardMouseEvent(mouse_event);
}

}  // namespace

// Class to monitor incoming UpdateViewportIntersection messages. The caller has
// to guarantee that `rfph` lives at least as long as
// UpdateViewportIntersectionMessageFilter.
class UpdateViewportIntersectionMessageFilter
    : public blink::mojom::RemoteFrameHostInterceptorForTesting {
 public:
  explicit UpdateViewportIntersectionMessageFilter(
      content::RenderFrameProxyHost* rfph)
      : intersection_state_(blink::mojom::ViewportIntersectionState::New()),
        swapped_impl_(rfph->frame_host_receiver_for_testing(), this) {}

  ~UpdateViewportIntersectionMessageFilter() override = default;

  const blink::mojom::ViewportIntersectionStatePtr& GetIntersectionState()
      const {
    return intersection_state_;
  }

  blink::mojom::RemoteFrameHost* GetForwardingInterface() override {
    return swapped_impl_.old_impl();
  }

  void UpdateViewportIntersection(
      blink::mojom::ViewportIntersectionStatePtr intersection_state,
      const std::optional<blink::FrameVisualProperties>& visual_properties)
      override {
    intersection_state_ = std::move(intersection_state);
    msg_received_ = true;
    if (run_loop_)
      run_loop_->Quit();
  }

  bool MessageReceived() const { return msg_received_; }

  void Clear() {
    msg_received_ = false;
    intersection_state_ = blink::mojom::ViewportIntersectionState::New();
  }

  void Wait() {
    DCHECK(!run_loop_);
    if (msg_received_) {
      msg_received_ = false;
      return;
    }
    std::unique_ptr<base::RunLoop> run_loop(new base::RunLoop);
    run_loop_ = run_loop.get();
    run_loop_->Run();
    run_loop_ = nullptr;
    msg_received_ = false;
  }

  void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }

 private:
  raw_ptr<base::RunLoop> run_loop_ = nullptr;
  bool msg_received_;
  blink::mojom::ViewportIntersectionStatePtr intersection_state_;
  mojo::test::ScopedSwapImplForTesting<blink::mojom::RemoteFrameHost>
      swapped_impl_;
};

// TODO(tonikitoo): Move to fake_remote_frame.h|cc in case it is useful
// for other tests.
class FakeRemoteMainFrame : public blink::mojom::RemoteMainFrame {
 public:
  FakeRemoteMainFrame() = default;
  ~FakeRemoteMainFrame() override = default;

  void Init(
      mojo::PendingAssociatedReceiver<blink::mojom::RemoteMainFrame> receiver) {
    receiver_.Bind(std::move(receiver));
  }

  // blink::mojom::RemoteMainFrame overrides:
  void UpdateTextAutosizerPageInfo(
      blink::mojom::TextAutosizerPageInfoPtr page_info) override {}

 private:
  mojo::AssociatedReceiver<blink::mojom::RemoteMainFrame> receiver_{this};
};

// This class intercepts RenderFrameProxyHost creations, and overrides their
// respective blink::mojom::RemoteMainFrame instances, so that it can watch for
// text autosizer page info updates.
class UpdateTextAutosizerInfoProxyObserver
    : public RenderFrameProxyHost::TestObserver {
 public:
  UpdateTextAutosizerInfoProxyObserver() {
    RenderFrameProxyHost::SetObserverForTesting(this);
  }
  ~UpdateTextAutosizerInfoProxyObserver() override {
    RenderFrameProxyHost::SetObserverForTesting(nullptr);
  }

  const blink::mojom::TextAutosizerPageInfo& TextAutosizerPageInfo(
      RenderFrameProxyHost* proxy) {
    return remote_frames_[proxy]->page_info();
  }

 private:
  class Remote : public FakeRemoteMainFrame {
   public:
    explicit Remote(RenderFrameProxyHost* proxy) {
      Init(proxy->BindRemoteMainFrameReceiverForTesting());
    }
    void UpdateTextAutosizerPageInfo(
        blink::mojom::TextAutosizerPageInfoPtr page_info) override {
      page_info_ = *page_info;
    }
    const blink::mojom::TextAutosizerPageInfo& page_info() {
      return page_info_;
    }

   private:
    blink::mojom::TextAutosizerPageInfo page_info_;
  };

  void OnRemoteMainFrameBound(RenderFrameProxyHost* proxy_host) override {
    remote_frames_[proxy_host] = std::make_unique<Remote>(proxy_host);
  }

  std::map<RenderFrameProxyHost*, std::unique_ptr<Remote>> remote_frames_;
};

// Class to intercept incoming TextAutosizerPageInfoChanged messages. The caller
// has to guarantee that `render_frame_host` lives at least as long as
// TextAutosizerPageInfoInterceptor.
class TextAutosizerPageInfoInterceptor
    : public blink::mojom::LocalMainFrameHostInterceptorForTesting {
 public:
  explicit TextAutosizerPageInfoInterceptor(
      RenderFrameHostImpl* render_frame_host)
      : swapped_impl_(
            render_frame_host->local_main_frame_host_receiver_for_testing(),
            this) {}

  ~TextAutosizerPageInfoInterceptor() override = default;

  LocalMainFrameHost* GetForwardingInterface() override {
    return swapped_impl_.old_impl();
  }

  void WaitForPageInfo(std::optional<int> target_main_frame_width,
                       std::optional<float> target_device_scale_adjustment) {
    if (remote_page_info_seen_)
      return;
    target_main_frame_width_ = target_main_frame_width;
    target_device_scale_adjustment_ = target_device_scale_adjustment;
    run_loop_ = std::make_unique<base::RunLoop>();
    run_loop_->Run();
    run_loop_.reset();
  }

  const blink::mojom::TextAutosizerPageInfo& GetTextAutosizerPageInfo() {
    return *remote_page_info_;
  }

  void TextAutosizerPageInfoChanged(
      blink::mojom::TextAutosizerPageInfoPtr remote_page_info) override {
    if ((!target_main_frame_width_ ||
         remote_page_info->main_frame_width != target_main_frame_width_) &&
        (!target_device_scale_adjustment_ ||
         remote_page_info->device_scale_adjustment !=
             target_device_scale_adjustment_)) {
      return;
    }
    remote_page_info_ = remote_page_info.Clone();
    remote_page_info_seen_ = true;
    if (run_loop_)
      run_loop_->Quit();
    GetForwardingInterface()->TextAutosizerPageInfoChanged(
        std::move(remote_page_info));
  }

 private:
  bool remote_page_info_seen_ = false;
  blink::mojom::TextAutosizerPageInfoPtr remote_page_info_ =
      blink::mojom::TextAutosizerPageInfo::New(/*main_frame_width=*/0,
                                               /*main_frame_layout_width=*/0,
                                               /*device_scale_adjustment=*/1.f);
  std::unique_ptr<base::RunLoop> run_loop_;
  std::optional<int> target_main_frame_width_;
  std::optional<float> target_device_scale_adjustment_;
  mojo::test::ScopedSwapImplForTesting<blink::mojom::LocalMainFrameHost>
      swapped_impl_;
};

class SitePerProcessHighDPIBrowserTest : public SitePerProcessBrowserTest {
 public:
  const double kDeviceScaleFactor = 2.0;

  SitePerProcessHighDPIBrowserTest() = default;

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTestBase::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(
        switches::kForceDeviceScaleFactor,
        base::StringPrintf("%f", kDeviceScaleFactor));
  }
};

IN_PROC_BROWSER_TEST_P(SitePerProcessHighDPIBrowserTest,
                       SubframeLoadsWithCorrectDeviceScaleFactor) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // On Android forcing device scale factor does not work for tests, therefore
  // we ensure that make frame and iframe have the same DIP scale there, but
  // not necessarily kDeviceScaleFactor.
  const double expected_dip_scale =
#if BUILDFLAG(IS_ANDROID)
      GetFrameDeviceScaleFactor(web_contents());
#else
      SitePerProcessHighDPIBrowserTest::kDeviceScaleFactor;
#endif

  EXPECT_EQ(expected_dip_scale, GetFrameDeviceScaleFactor(web_contents()));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(expected_dip_scale, GetFrameDeviceScaleFactor(root));
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* child = root->child_at(0);
  EXPECT_EQ(expected_dip_scale, GetFrameDeviceScaleFactor(child));
}

class SitePerProcessCompositorViewportBrowserTest
    : public SitePerProcessBrowserTestBase,
      public testing::WithParamInterface<double> {
 public:
  SitePerProcessCompositorViewportBrowserTest() = default;

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTestBase::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor,
                                    base::StringPrintf("%f", GetParam()));
  }
};

// DISABLED: crbug.com/1071995
IN_PROC_BROWSER_TEST_P(SitePerProcessCompositorViewportBrowserTest,
                       DISABLED_OopifCompositorViewportSizeRelativeToParent) {
  // Load page with very tall OOPIF.
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/super_tall_parent.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* child = root->child_at(0);

  GURL nested_site_url(
      embedded_test_server()->GetURL("b.com", "/super_tall_page.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, nested_site_url));

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  // Observe frame submission from parent.
  RenderFrameSubmissionObserver parent_observer(
      root->current_frame_host()
          ->GetRenderWidgetHost()
          ->render_frame_metadata_provider());
  parent_observer.WaitForAnyFrameSubmission();
  gfx::Size parent_viewport_size =
      parent_observer.LastRenderFrameMetadata().viewport_size_in_pixels;

  // Observe frame submission from child.
  RenderFrameSubmissionObserver child_observer(
      child->current_frame_host()
          ->GetRenderWidgetHost()
          ->render_frame_metadata_provider());
  child_observer.WaitForAnyFrameSubmission();
  gfx::Size child_viewport_size =
      child_observer.LastRenderFrameMetadata().viewport_size_in_pixels;

  // Verify child's compositor viewport is no more than about 30% larger than
  // the parent's. See RemoteFrameView::GetCompositingRect() for explanation of
  // the choice of 30%. Add +1 to child viewport height to account for rounding.
  EXPECT_GE(ceilf(1.3f * parent_viewport_size.height()),
            child_viewport_size.height() - 1);

  // Verify the child's ViewBounds are much larger.
  RenderWidgetHostViewBase* child_rwhv = static_cast<RenderWidgetHostViewBase*>(
      child->current_frame_host()->GetRenderWidgetHost()->GetView());
  // 30,000 is based on div/iframe sizes in the test HTML files.
  EXPECT_LT(30000, child_rwhv->GetViewBounds().height());
}

#if BUILDFLAG(IS_ANDROID)
// Android doesn't support forcing device scale factor in tests.
INSTANTIATE_TEST_SUITE_P(SitePerProcess,
                         SitePerProcessCompositorViewportBrowserTest,
                         testing::Values(1.0));
#else
INSTANTIATE_TEST_SUITE_P(SitePerProcess,
                         SitePerProcessCompositorViewportBrowserTest,
                         testing::Values(1.0, 1.5, 2.0));
#endif

#if BUILDFLAG(IS_CHROMEOS)
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SubframeUpdateToCorrectDeviceScaleFactor) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  EXPECT_EQ(1.0, GetFrameDeviceScaleFactor(web_contents()));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* child = root->child_at(0);
  EXPECT_EQ(1.0, GetFrameDeviceScaleFactor(child));

  double expected_dip_scale = 2.0;

  // TODO(oshima): allow DeviceScaleFactor change on other platforms
  // (win, linux, mac, android and mus).
  aura::TestScreen* test_screen =
      static_cast<aura::TestScreen*>(display::Screen::GetScreen());
  test_screen->CreateHostForPrimaryDisplay();
  test_screen->SetDeviceScaleFactor(expected_dip_scale);

  // This forces |expected_dip_scale| to be applied to the aura::WindowTreeHost
  // and aura::Window.
  aura::WindowTreeHost* window_tree_host = shell()->window()->GetHost();
  window_tree_host->SetBoundsInPixels(window_tree_host->GetBoundsInPixels());

  // Wait until dppx becomes 2 if the frame's dpr hasn't beeen updated
  // to 2 yet.
  const char kScript[] = R"(
      new Promise(resolve => {
        if (window.devicePixelRatio == 2)
          resolve(window.devicePixelRatio);
        window.matchMedia('screen and (min-resolution: 2dppx)')
            .addListener(function(e) {
          if (e.matches) {
            resolve(window.devicePixelRatio);
          }
        });
      });
      )";
  // Make sure that both main frame and iframe are updated to 2x.
  EXPECT_EQ(expected_dip_scale, EvalJs(child, kScript).ExtractDouble());

  EXPECT_EQ(expected_dip_scale,
            EvalJs(web_contents(), kScript).ExtractDouble());
}

#endif

// Tests that when a large OOPIF has been scaled, the compositor raster area
// sent from the embedder is correct.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
// Temporarily disabled on Android because this doesn't account for browser
// control height or page scale factor.
// Flaky on Mac. https://crbug.com/840314
#define MAYBE_ScaledIframeRasterSize DISABLED_ScaledframeRasterSize
#else
#define MAYBE_ScaledIframeRasterSize ScaledIframeRasterSize
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_ScaledIframeRasterSize) {
  GURL http_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_scaled_large_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), http_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  FrameTreeNode* child = root->child_at(0);
  RenderFrameProxyHost* child_proxy =
      child->render_manager()->GetProxyToParent();
  auto filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(child_proxy);

  // Force a lifecycle update and wait for it to finish; by the time this call
  // returns, the viewport intersection IPC should already have been received
  // by the browser process and handled by the filter.
  EvalJsResult eval_result = EvalJsAfterLifecycleUpdate(
      root->current_frame_host(),
      "document.getElementsByTagName('div')[0].scrollTo(0, 5000);",
      "document.getElementsByTagName('div')[0].getBoundingClientRect().top;");
  ASSERT_TRUE(eval_result.error.empty());
  int div_offset_top = eval_result.ExtractInt();
  gfx::Rect compositing_rect =
      filter->GetIntersectionState()->compositor_visible_rect;

  float device_scale_factor = 1.0f;
  device_scale_factor = GetFrameDeviceScaleFactor(shell()->web_contents());

  // The math below replicates the calculations in
  // RemoteFrameView::GetCompositingRect(). That could be subject to tweaking,
  // which would have to be reflected in these test expectations. Also, any
  // changes to Blink that would affect the size of the frame rect or the
  // visible viewport would need to be accounted for.
  // The multiplication by 5 accounts for the 0.2 scale factor in the test,
  // which increases the area that has to be drawn in the OOPIF.
  int view_height = root->current_frame_host()
                        ->GetRenderWidgetHost()
                        ->GetView()
                        ->GetViewBounds()
                        .height() *
                    5 * device_scale_factor;

  // The raster size is expanded by a factor of 1.3 to allow for some scrolling
  // without requiring re-raster. The expanded area to be rasterized should be
  // centered around the iframe's visible area within the parent document, hence
  // the expansion in each direction (top, bottom, left, right) is
  // (0.15 * viewport dimension).
  int expansion = ceilf(view_height * 0.15f);
  int expected_height = view_height + expansion * 2;

  // 5000 = div scroll offset in scaled pixels
  // 5 = scale factor from top-level document to iframe contents
  // 2 = iframe border in scaled pixels
  int expected_offset =
      ((5000 - (div_offset_top * 5) - 2) * device_scale_factor) - expansion;

  // Allow a small amount for rounding differences from applying page and
  // device scale factors at different times.
  float tolerance = ceilf(device_scale_factor);
  EXPECT_NEAR(compositing_rect.height(), expected_height, tolerance);
  EXPECT_NEAR(compositing_rect.y(), expected_offset, tolerance);
}

// Similar to ScaledIFrameRasterSize but with nested OOPIFs to ensure
// propagation works correctly.
#if BUILDFLAG(IS_ANDROID)
// Temporarily disabled on Android because this doesn't account for browser
// control height or page scale factor.
#define MAYBE_ScaledNestedIframeRasterSize DISABLED_ScaledNestedIframeRasterSize
#else
#define MAYBE_ScaledNestedIframeRasterSize ScaledNestedIframeRasterSize
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_ScaledNestedIframeRasterSize) {
  GURL http_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_scaled_large_frames_nested.html"));
  EXPECT_TRUE(NavigateToURL(shell(), http_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();
  FrameTreeNode* child_b = root->child_at(0);

  EXPECT_TRUE(NavigateToURLFromRenderer(
      child_b,
      embedded_test_server()->GetURL(
          "bar.com", "/frame_tree/page_with_large_scrollable_frame.html")));

  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   +--Site B ------- proxies for A C\n"
      "        +--Site C -- proxies for A B\n"
      "Where A = http://a.com/\n"
      "      B = http://bar.com/\n"
      "      C = http://baz.com/",
      DepictFrameTree(root));

  // This adds the filter to the immediate child iframe. It verifies that the
  // child sets the nested iframe's compositing rect correctly.
  FrameTreeNode* child_c = child_b->child_at(0);
  RenderFrameProxyHost* child_c_proxy =
      child_c->render_manager()->GetProxyToParent();
  auto filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(child_c_proxy);

  // Scroll the child frame so that it is partially clipped. This will cause the
  // top 10 pixels of the child frame to be clipped. Applying the scale factor
  // means that in the coordinate system of the subframes, 50px are clipped.
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(root->current_frame_host(),
                                         "window.scrollBy(0, 10)", "")
                  .error.empty());

  // This scrolls the div containing in the 'Site B' iframe that contains the
  // 'Site C' iframe, and then we verify that the 'Site C' frame receives the
  // correct compositor frame. Force a lifecycle update after the scroll and
  // wait for it to finish; by the time this call returns, the viewport
  // intersection IPC should already have been received by the browser process
  // and handled by the filter. Extract the page offset of the leaf iframe
  // within the middle document.
  EvalJsResult child_eval_result = EvalJsAfterLifecycleUpdate(
      child_b->current_frame_host(),
      "document.getElementsByTagName('div')[0].scrollTo(0, 5000);",
      "document.getElementsByTagName('div')[0].getBoundingClientRect().top;");
  ASSERT_TRUE(child_eval_result.error.empty());
  int child_div_offset_top = child_eval_result.ExtractInt();

  gfx::Rect compositing_rect =
      filter->GetIntersectionState()->compositor_visible_rect;

  float scale_factor = 1.0f;
  scale_factor = GetFrameDeviceScaleFactor(shell()->web_contents());

  // See comment in ScaledIframeRasterSize for explanation of this. In this
  // case, the raster area of the large iframe should be restricted to
  // approximately the area of its containing frame which is unclipped by the
  // main frame. The containing frame is clipped by 50 pixels at the top, due
  // to the scroll offset of the main frame, so we subtract that from the full
  // height of the containing frame.
  int view_height = (child_b->current_frame_host()
                         ->GetRenderWidgetHost()
                         ->GetView()
                         ->GetViewBounds()
                         .height() -
                     50) *
                    scale_factor;
  // 30% padding is added to the view_height to prevent frequent re-rasters.
  // The extra padding is centered around the view height, hence expansion by
  // 0.15 in each direction.
  int expansion = ceilf(view_height * 0.15f);
  int expected_height = view_height + expansion * 2;

  // Explanation of terms:
  //   5000 = offset from top of nested iframe to top of containing div, due to
  //          scroll offset of div. This needs to be scaled by DSF or the test
  //          will fail on HighDPI devices.
  //   child_div_offset_top = offset of containing div from top of child frame
  //   50 = offset of child frame's intersection with the top document viewport
  //       from the top of the child frame (i.e, clipped amount at top of child)
  //   view_height * 0.15 = padding added to the top of the compositing rect
  //                        (half the the 30% total padding)
  int expected_offset = (5000 * scale_factor) -
                        ((child_div_offset_top - 50) * scale_factor) -
                        expansion;

  // Allow a small amount for rounding differences from applying page and
  // device scale factors at different times.
  EXPECT_NEAR(compositing_rect.height(), expected_height, ceilf(scale_factor));
  EXPECT_NEAR(compositing_rect.y(), expected_offset, ceilf(scale_factor));
}

// Tests that when an OOPIF is inside a multicolumn container, its compositing
// rect is set correctly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       IframeInMulticolCompositingRect) {
  GURL http_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_iframe_in_multicol.html"));
  EXPECT_TRUE(NavigateToURL(shell(), http_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  FrameTreeNode* child = root->child_at(0);
  RenderFrameProxyHost* child_proxy =
      child->render_manager()->GetProxyToParent();
  auto filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(child_proxy);

  // Force a lifecycle update and wait for it to finish. Changing the width of
  // the iframe should cause the parent renderer to propagate a new
  // ViewportIntersectionState while running the rendering pipeline. By the time
  // this call returns, the viewport intersection IPC should already have been
  // received by the browser process and handled by the filter.
  EvalJsResult eval_result = EvalJsAfterLifecycleUpdate(
      root->current_frame_host(),
      "document.querySelector('iframe').style.width = '250px'", "");
  ASSERT_TRUE(filter->MessageReceived());
  gfx::Rect compositing_rect =
      filter->GetIntersectionState()->compositor_visible_rect;

  float scale_factor = 1.0f;
  scale_factor = GetFrameDeviceScaleFactor(shell()->web_contents());

  gfx::Point visible_offset(0, 0);
  gfx::Size visible_size =
      gfx::ScaleToFlooredSize(gfx::Size(250, 150), scale_factor, scale_factor);
  gfx::Rect visible_rect(visible_offset, visible_size);
  float tolerance = ceilf(scale_factor);
  EXPECT_NEAR(compositing_rect.x(), visible_rect.x(), tolerance);
  EXPECT_NEAR(compositing_rect.y(), visible_rect.y(), tolerance);
  EXPECT_NEAR(compositing_rect.width(), visible_rect.width(), tolerance);
  EXPECT_NEAR(compositing_rect.height(), visible_rect.height(), tolerance);
  EXPECT_TRUE(compositing_rect.Contains(visible_rect));
}

// Flaky on multiple platforms (crbug.com/1094562).
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DISABLED_FrameViewportIntersectionTestSimple) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c),d,e(f))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  RenderFrameProxyHost* child2_proxy =
      root->child_at(2)->render_manager()->GetProxyToParent();
  auto child2_filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(child2_proxy);

  // Force lifecycle update in root and child2 to make sure child2 has sent
  // viewport intersection into to grand child before child2 becomes throttled.
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(root->current_frame_host(), "", "")
                  .error.empty());
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(
                  root->child_at(2)->current_frame_host(), "", "")
                  .error.empty());
  child2_filter->Clear();

  LayoutNonRecursiveForTestingViewportIntersection(shell()->web_contents());

  // Root should always intersect.
  EXPECT_TRUE(CheckIntersectsViewport(true, root));
  // Child 0 should be entirely in viewport.
  EXPECT_TRUE(CheckIntersectsViewport(true, root->child_at(0)));
  // Make sure child0 has has a chance to propagate viewport intersection to
  // grand child.
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(
                  root->child_at(0)->current_frame_host(), "", "")
                  .error.empty());
  // Grand child should match parent.
  EXPECT_TRUE(CheckIntersectsViewport(true, root->child_at(0)->child_at(0)));
  // Child 1 should be partially in viewport.
  EXPECT_TRUE(CheckIntersectsViewport(true, root->child_at(1)));
  // Child 2 should be not be in viewport.
  EXPECT_TRUE(CheckIntersectsViewport(false, root->child_at(2)));
  // Can't use EvalJsAfterLifecycleUpdate on child2, because it's
  // render-throttled. But it should still have propagated state down to the
  // grandchild.
  child2_filter->Wait();
  // Grand child should match parent.
  EXPECT_TRUE(CheckIntersectsViewport(false, root->child_at(2)->child_at(0)));
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       FrameViewportOffsetTestSimple) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // This will catch b sending viewport intersection information to c.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  RenderFrameProxyHost* iframe_c_proxy =
      root->child_at(0)->child_at(0)->render_manager()->GetProxyToParent();
  auto filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(iframe_c_proxy);

  // Use EvalJsAfterLifecycleUpdate to force animation frames in `a` and `b` to
  // ensure that the viewport intersection for initial layout state has been
  // propagated. The layout of `a` will not change again, so we can read back
  // its layout info after the animation frame. The layout of `b` will change,
  // so we don't read back its layout yet.
  std::string script(R"(
    let iframe = document.querySelector("iframe");
    [iframe.offsetLeft, iframe.offsetTop];
  )");
  EvalJsResult iframe_b_result =
      EvalJsAfterLifecycleUpdate(root->current_frame_host(), "", script);
  base::Value::List iframe_b_offset = iframe_b_result.ExtractList();
  int iframe_b_offset_left = iframe_b_offset[0].GetInt();
  int iframe_b_offset_top = iframe_b_offset[1].GetInt();

  // Make sure a new IPC is sent after dirty-ing layout.
  filter->Clear();

  // Dirty layout in `b` to generate a new IPC to `c`. This will be the final
  // layout state for `b`, so read back layout info here.
  std::string raf_script(R"(
    let iframe = document.querySelector("iframe");
    let margin = getComputedStyle(iframe).marginTop.replace("px", "");
    iframe.style.margin = String(parseInt(margin) + 1) + "px";
  )");
  EvalJsResult iframe_c_result = EvalJsAfterLifecycleUpdate(
      root->child_at(0)->current_frame_host(), raf_script, script);
  base::Value::List iframe_c_offset = iframe_c_result.ExtractList();
  int iframe_c_offset_left = iframe_c_offset[0].GetInt();
  int iframe_c_offset_top = iframe_c_offset[1].GetInt();

  // The IPC should already have been sent
  EXPECT_TRUE(filter->MessageReceived());

  // +4 for a 2px border on each iframe.
  gfx::Vector2dF expected(iframe_b_offset_left + iframe_c_offset_left + 4,
                          iframe_b_offset_top + iframe_c_offset_top + 4);
  const float device_scale_factor =
      root->render_manager()->GetRenderWidgetHostView()->GetDeviceScaleFactor();
  // Convert from CSS to physical pixels
  expected.Scale(device_scale_factor);
  gfx::Transform actual = filter->GetIntersectionState()->main_frame_transform;
  const std::optional<gfx::PointF> viewport_offset_source_point =
      actual.InverseMapPoint(gfx::PointF());
  ASSERT_TRUE(viewport_offset_source_point.has_value());
  const gfx::Vector2dF viewport_offset =
      gfx::PointF() - viewport_offset_source_point.value();
  float tolerance = ceilf(device_scale_factor);
  EXPECT_NEAR(expected.x(), viewport_offset.x(), tolerance);
  EXPECT_NEAR(expected.y(), viewport_offset.y(), tolerance);
}

// TODO(crbug.com/40743132): Flaky test.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessBrowserTest,
    DISABLED_NestedIframeTransformedIntoViewViewportIntersection) {
  GURL http_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_frame_transformed_into_viewport.html"));
  EXPECT_TRUE(NavigateToURL(shell(), http_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();
  FrameTreeNode* child_b = root->child_at(0);

  EXPECT_TRUE(NavigateToURLFromRenderer(
      child_b,
      embedded_test_server()->GetURL(
          "bar.com", "/frame_tree/page_with_cross_origin_frame_at_half.html")));

  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   +--Site B ------- proxies for A C\n"
      "        +--Site C -- proxies for A B\n"
      "Where A = http://a.com/\n"
      "      B = http://bar.com/\n"
      "      C = http://baz.com/",
      DepictFrameTree(root));

  FrameTreeNode* child_c = child_b->child_at(0);
  RenderFrameProxyHost* child_c_proxy =
      child_c->render_manager()->GetProxyToParent();
  auto filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(child_c_proxy);

  // Scroll the div containing the 'Site B' iframe to trigger a viewport
  // intersection update.
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(
                  child_b->current_frame_host(),
                  "document.getElementsByTagName('div')[0].scrollTo(0, 5000);",
                  "")
                  .error.empty());
  ASSERT_TRUE(filter->MessageReceived());

  // Check that we currently intersect with the viewport.
  gfx::Rect viewport_intersection =
      filter->GetIntersectionState()->viewport_intersection;

  EXPECT_GT(viewport_intersection.height(), 0);
  EXPECT_GT(viewport_intersection.width(), 0);
}

// Verify that OOPIF select element popup menu coordinates account for scroll
// offset in containers embedding frame.
// TODO(crbug.com/40583339): Reenable this.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DISABLED_PopupMenuInTallIframeTest) {
  GURL main_url(embedded_test_server()->GetURL(
      "/frame_tree/page_with_tall_positioned_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child_node = root->child_at(0);
  GURL site_url(embedded_test_server()->GetURL(
      "baz.com", "/site_isolation/page-with-select.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child_node, site_url));

  RenderFrameProxyHost* root_proxy = root->render_manager()->GetProxyToParent();
  auto filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(root_proxy);

  // Position the select element so that it is out of the viewport, then scroll
  // it into view.
  EXPECT_TRUE(ExecJs(child_node,
                     "document.querySelector('select').style.top='2000px';"));
  EXPECT_TRUE(ExecJs(root, "window.scrollTo(0, 1900);"));

  // Wait for a viewport intersection update to be dispatched to the child, and
  // ensure it is processed by the browser before continuing.
  filter->Wait();
  {
    // This yields the UI thread in order to ensure that the new viewport
    // intersection is sent to the to child renderer before the mouse click
    // below.
    base::RunLoop loop;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, loop.QuitClosure());
    loop.Run();
  }

  auto show_popup_waiter = std::make_unique<ShowPopupWidgetWaiter>(
      web_contents(), child_node->current_frame_host());
  SimulateMouseClick(child_node->current_frame_host()->GetRenderWidgetHost(),
                     55, 2005);

  // Dismiss the popup.
  SimulateMouseClick(child_node->current_frame_host()->GetRenderWidgetHost(), 1,
                     1);

  // The test passes if this wait returns, indicating that the popup was
  // scrolled into view and the OOPIF renderer displayed it. Other tests verify
  // the correctness of popup menu coordinates.
  show_popup_waiter->Wait();
}

// Test to verify that viewport intersection is propagated to nested OOPIFs
// even when a parent OOPIF has been throttled.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NestedFrameViewportIntersectionUpdated) {
  GURL main_url(embedded_test_server()->GetURL(
      "foo.com", "/frame_tree/scrollable_page_with_positioned_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child_node = root->child_at(0);
  GURL site_url(embedded_test_server()->GetURL(
      "bar.com", "/frame_tree/page_with_positioned_frame.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child_node, site_url));

  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   +--Site B ------- proxies for A C\n"
      "        +--Site C -- proxies for A B\n"
      "Where A = http://foo.com/\n"
      "      B = http://bar.com/\n"
      "      C = http://baz.com/",
      DepictFrameTree(root));

  // This will intercept messages sent from B to C, describing C's viewport
  // intersection.
  RenderFrameProxyHost* child_proxy =
      child_node->render_manager()->GetProxyToParent();
  auto filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(child_proxy);

  // Run requestAnimationFrame in A and B to make sure initial layout has
  // completed and initial IPCs sent.
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(root->current_frame_host(), "", "")
                  .error.empty());
  ASSERT_TRUE(
      EvalJsAfterLifecycleUpdate(child_node->current_frame_host(), "", "")
          .error.empty());
  filter->Clear();

  // Scroll the child frame out of view, causing it to become throttled.
  ASSERT_TRUE(ExecJs(root->current_frame_host(), "window.scrollTo(0, 5000)"));
  filter->Wait();
  EXPECT_TRUE(filter->GetIntersectionState()->viewport_intersection.IsEmpty());

  // Scroll the frame back into view.
  ASSERT_TRUE(ExecJs(root->current_frame_host(), "window.scrollTo(0, 0)"));
  filter->Wait();
  EXPECT_FALSE(filter->GetIntersectionState()->viewport_intersection.IsEmpty());
}

// Test to verify that the main frame document intersection
// is propagated to out of process iframes by scrolling a nested iframe
// in and out of intersecting with the main frame document.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NestedFrameMainFrameDocumentIntersectionUpdated) {
  GURL main_url(embedded_test_server()->GetURL(
      "foo.com", "/frame_tree/scrollable_page_with_positioned_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child_node_b = root->child_at(0);
  GURL site_url(embedded_test_server()->GetURL(
      "bar.com", "/frame_tree/scrollable_page_with_positioned_frame.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child_node_b, site_url));

  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   +--Site B ------- proxies for A C\n"
      "        +--Site C -- proxies for A B\n"
      "Where A = http://foo.com/\n"
      "      B = http://bar.com/\n"
      "      C = http://baz.com/",
      DepictFrameTree(root));

  FrameTreeNode* child_node_c = child_node_b->child_at(0);
  RenderFrameProxyHost* child_proxy_c =
      child_node_c->render_manager()->GetProxyToParent();
  auto filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(child_proxy_c);

  // Run requestAnimationFrame in A and B to make sure initial layout has
  // completed and initial IPC's sent.
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(root->current_frame_host(), "", "")
                  .error.empty());
  ASSERT_TRUE(
      EvalJsAfterLifecycleUpdate(child_node_b->current_frame_host(), "", "")
          .error.empty());
  filter->Clear();

  // Scroll the child frame out of view, causing it to become throttled.
  ASSERT_TRUE(
      ExecJs(child_node_b->current_frame_host(), "window.scrollTo(0, 5000)"));
  filter->Wait();
  EXPECT_TRUE(
      filter->GetIntersectionState()->main_frame_intersection.IsEmpty());

  // Scroll the frame back into view.
  ASSERT_TRUE(
      ExecJs(child_node_b->current_frame_host(), "window.scrollTo(0, 0)"));
  filter->Wait();
  EXPECT_FALSE(
      filter->GetIntersectionState()->main_frame_intersection.IsEmpty());
}

// Tests that outermost_main_frame_scroll_position is not shared by frames in
// the same process. This is a regression test for https://crbug.com/1063760.
//
// Set up the frame tree to be A(B1(C1),B2(C2)). Send IPC's with different
// ViewportIntersection information to B1 and B2, and then check that the
// information they propagate to C1 and C2 is different.
// Disabled because of https://crbug.com/1136263
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DISABLED_MainFrameScrollOffset) {
  GURL a_url = embedded_test_server()->GetURL(
      "a.com", "/frame_tree/scrollable_page_with_two_frames.html");
  GURL b_url = embedded_test_server()->GetURL(
      "b.com", "/frame_tree/page_with_large_iframe.html");
  GURL c_url = embedded_test_server()->GetURL("c.com", "/title1.html");

  EXPECT_TRUE(NavigateToURL(shell(), a_url));
  FrameTreeNode* a_node = web_contents()->GetPrimaryFrameTree().root();

  FrameTreeNode* b1_node = a_node->child_at(0);
  EXPECT_TRUE(NavigateToURLFromRenderer(b1_node, b_url));

  FrameTreeNode* c1_node = b1_node->child_at(0);
  EXPECT_TRUE(NavigateToURLFromRenderer(c1_node, c_url));

  FrameTreeNode* b2_node = a_node->child_at(1);
  EXPECT_TRUE(NavigateToURLFromRenderer(b2_node, b_url));

  FrameTreeNode* c2_node = b2_node->child_at(0);
  EXPECT_TRUE(NavigateToURLFromRenderer(c2_node, c_url));

  // This will intercept messages sent from B1 to C1, describing C1's viewport
  // intersection.
  RenderFrameProxyHost* c1_proxy =
      c1_node->render_manager()->GetProxyToParent();
  auto b1_to_c1_message_filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(c1_proxy);

  // This will intercept messages sent from B2 to C2, describing C2's viewport
  // intersection.
  RenderFrameProxyHost* c2_proxy =
      c2_node->render_manager()->GetProxyToParent();
  auto b2_to_c2_message_filter =
      std::make_unique<UpdateViewportIntersectionMessageFilter>(c2_proxy);

  // Running requestAnimationFrame will ensure that any pending IPC's have been
  // sent by the renderer and received by the browser.
  auto flush_ipcs = [](FrameTreeNode* node) {
    ASSERT_TRUE(EvalJsAfterLifecycleUpdate(node->current_frame_host(), "", "")
                    .error.empty());
  };

  flush_ipcs(a_node);
  flush_ipcs(b1_node);
  flush_ipcs(b2_node);
  b1_to_c1_message_filter->Clear();
  b2_to_c2_message_filter->Clear();

  // Now that everything is in a stable, consistent state, we will send viewport
  // intersection IPC's to B1 and B2 that contain a different
  // outermost_main_frame_scroll_position, and then verify that each of them
  // propagates their own value of outermost_main_frame_scroll_position to C1
  // and C2, respectively. The IPC code mimics messages that A would send to B1
  // and B2.
  auto b1_intersection_state = b1_node->render_manager()
                                   ->GetProxyToParent()
                                   ->cross_process_frame_connector()
                                   ->intersection_state();

  b1_intersection_state.outermost_main_frame_scroll_position.Offset(10, 0);
  // A change in outermost_main_frame_scroll_position by itself will not cause
  // B1 to be marked dirty, so we also modify viewport_intersection.
  b1_intersection_state.viewport_intersection.set_y(
      b1_intersection_state.viewport_intersection.y() + 7);
  b1_intersection_state.viewport_intersection.set_height(
      b1_intersection_state.viewport_intersection.height() - 7);

  ForceUpdateViewportIntersection(b1_node, b1_intersection_state);

  auto b2_intersection_state = b2_node->render_manager()
                                   ->GetProxyToParent()
                                   ->cross_process_frame_connector()
                                   ->intersection_state();

  b2_intersection_state.outermost_main_frame_scroll_position.Offset(20, 0);
  b2_intersection_state.viewport_intersection.set_y(
      b2_intersection_state.viewport_intersection.y() + 7);
  b2_intersection_state.viewport_intersection.set_height(
      b2_intersection_state.viewport_intersection.height() - 7);

  ForceUpdateViewportIntersection(b2_node, b2_intersection_state);

  // Once IPC's have been flushed to the C frames, we should see conflicting
  // values for outermost_main_frame_scroll_position.
  flush_ipcs(b1_node);
  flush_ipcs(b2_node);
  ASSERT_TRUE(b1_to_c1_message_filter->MessageReceived());
  ASSERT_TRUE(b2_to_c2_message_filter->MessageReceived());
  EXPECT_EQ(b1_to_c1_message_filter->GetIntersectionState()
                ->outermost_main_frame_scroll_position,
            gfx::Point(10, 0));
  EXPECT_EQ(b2_to_c2_message_filter->GetIntersectionState()
                ->outermost_main_frame_scroll_position,
            gfx::Point(20, 0));
  b1_to_c1_message_filter->Clear();
  b2_to_c2_message_filter->Clear();

  // If we scroll the main frame, it should propagate IPC's which re-synchronize
  // the values for all child frames.
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(a_node->current_frame_host(),
                                         "window.scrollTo(0, 5)", "")
                  .error.empty());
  flush_ipcs(b1_node);
  flush_ipcs(b2_node);
  ASSERT_TRUE(b1_to_c1_message_filter->MessageReceived());
  ASSERT_TRUE(b2_to_c2_message_filter->MessageReceived());

  // Window scroll offset will be scaled by device scale factor
  const float device_scale_factor = a_node->render_manager()
                                        ->GetRenderWidgetHostView()
                                        ->GetDeviceScaleFactor();
  float expected_y = device_scale_factor * 5.0;
  EXPECT_NEAR(b1_to_c1_message_filter->GetIntersectionState()
                  ->outermost_main_frame_scroll_position.y(),
              expected_y, 1.f);
  EXPECT_NEAR(b2_to_c2_message_filter->GetIntersectionState()
                  ->outermost_main_frame_scroll_position.y(),
              expected_y, 1.f);
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       FrameViewportIntersectionTestAggregate) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c,a,b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Each immediate child is sized to 100% width and 75% height.
  LayoutNonRecursiveForTestingViewportIntersection(shell()->web_contents());

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Child 2 does not intersect, but shares widget with the main frame.
  FrameTreeNode* node = root->child_at(2);
  RenderProcessHostPriorityClient::Priority priority =
      node->current_frame_host()->GetRenderWidgetHost()->GetPriority();
  EXPECT_TRUE(priority.intersects_viewport);
  EXPECT_TRUE(
      node->current_frame_host()->GetProcess()->GetIntersectsViewport());

  // Child 3 does not intersect, but shares a process with child 0.
  node = root->child_at(3);
  priority = node->current_frame_host()->GetRenderWidgetHost()->GetPriority();
  EXPECT_FALSE(priority.intersects_viewport);
  EXPECT_TRUE(
      node->current_frame_host()->GetProcess()->GetIntersectsViewport());
}

// Tests that when a non-root frame in an iframe, performs a RAF to emulate a
// scroll, that metrics are reported.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, ScrollByRAF) {
  base::HistogramTester histogram_tester;
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(b))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1U, root->child_count());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "        +--Site B -- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  // Layout all three frames, so that the animation has a region to mark dirty.
  LayoutNonRecursiveForTestingViewportIntersection(root->current_frame_host());
  LayoutNonRecursiveForTestingViewportIntersection(
      root->child_at(0)->current_frame_host());
  LayoutNonRecursiveForTestingViewportIntersection(
      root->child_at(0)->child_at(0)->current_frame_host());

  // Add a div to the nested iframe, so that it can be animated.
  RenderFrameSubmissionObserver frame_observer(root->child_at(0)->child_at(0));
  std::string addContent(R"(
      var d = document.createElement('div');
      d.id = 'animationtarget';
      d.innerHTML = 'Hey Listen!';
      document.body.appendChild(d);
    )");
  ASSERT_TRUE(
      EvalJsAfterLifecycleUpdate(
          root->child_at(0)->child_at(0)->current_frame_host(), "", addContent)
          .error.empty());
  frame_observer.WaitForAnyFrameSubmission();

  // Fetch the initial metrics, as adding a div can incidentally trigger RAF
  // metrics.
  FetchHistogramsFromChildProcesses();
  auto initial_samples = histogram_tester.GetAllSamples(
      "Graphics.Smoothness.PercentDroppedFrames3.MainThread.RAF");
  ASSERT_EQ(initial_samples.size(), 0u);

  const int pre_scroll_frame_count = frame_observer.render_frame_count();

  // Run a RAF that takes more than one frame, as metrics due to not track
  // frames where WillBeginMainFrame occurs before it is triggered. Subsequent
  // RAFs in the sequence will be measured.
  std::string scrollByRAF(R"(
     var offset = 0;
      function run() {
        let child = document.getElementById("animationtarget");
        var rect = child.getBoundingClientRect();
        child.style = 'transform: translateY(' + parseInt(offset)+'px);';
        offset += 1;
        requestAnimationFrame(run);
      }
      run();
     )");
  ASSERT_TRUE(
      EvalJsAfterLifecycleUpdate(
          root->child_at(0)->child_at(0)->current_frame_host(), scrollByRAF, "")
          .error.empty());

  // There will have been one frame before the RAF sequence. The minimum for
  // reporting if 100 frames, however we need to wait at least one extra frame.
  // On Android the animation begins during the initial call to
  // EvalJsAfterLifecycleUpdate. However on Linux the first translate is not
  // applied until the subsequent frame. So we wait for the minimum, then verify
  // afterwards.
  const int kExpectedNumberFrames = 101 + pre_scroll_frame_count;
  while (frame_observer.render_frame_count() < kExpectedNumberFrames)
    frame_observer.WaitForAnyFrameSubmission();

  // We now wait for FrameSequenceTracker to time out in order for it to report.
  // This will occur once the minimum 100 frames have been produced, and 5s have
  // passed. If the test times out then the bug is back.
  while (histogram_tester
             .GetAllSamples(
                 "Graphics.Smoothness.PercentDroppedFrames3.MainThread.RAF")
             .empty()) {
    frame_observer.WaitForAnyFrameSubmission();
    FetchHistogramsFromChildProcesses();
  }
}

// Make sure that when a relevant feature of the main frame changes, e.g. the
// frame width, that the browser is notified.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, TextAutosizerPageInfo) {
  UpdateTextAutosizerInfoProxyObserver update_text_autosizer_info_observer;

  blink::web_pref::WebPreferences prefs =
      web_contents()->GetOrCreateWebPreferences();
  prefs.text_autosizing_enabled = true;

  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  web_contents()->SetWebPreferences(prefs);

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1U, root->child_count());
  FrameTreeNode* b_child = root->child_at(0);

  blink::mojom::TextAutosizerPageInfo received_page_info;
  auto interceptor = std::make_unique<TextAutosizerPageInfoInterceptor>(
      web_contents()->GetPrimaryMainFrame());
#if BUILDFLAG(IS_ANDROID)
  prefs.device_scale_adjustment += 0.05f;
  // Change the device scale adjustment to trigger a RemotePageInfo update.
  web_contents()->SetWebPreferences(prefs);
  // Make sure we receive a ViewHostMsg from the main frame's renderer.
  interceptor->WaitForPageInfo(std::optional<int>(),
                               prefs.device_scale_adjustment);
  // Make sure the correct page message is sent to the child.
  base::RunLoop().RunUntilIdle();
  received_page_info = interceptor->GetTextAutosizerPageInfo();
  EXPECT_EQ(prefs.device_scale_adjustment,
            received_page_info.device_scale_adjustment);
#else
  // Resize the main frame, then wait to observe that the RemotePageInfo message
  // arrives.
  auto* view = web_contents()->GetRenderWidgetHostView();
  gfx::Rect old_bounds = view->GetViewBounds();
  gfx::Rect new_bounds(
      old_bounds.origin(),
      gfx::Size(old_bounds.width() - 20, old_bounds.height() - 20));

  view->SetBounds(new_bounds);
  // Make sure we receive a ViewHostMsg from the main frame's renderer.
  interceptor->WaitForPageInfo(new_bounds.width(), std::optional<float>());
  // Make sure the correct page message is sent to the child.
  base::RunLoop().RunUntilIdle();
  received_page_info = interceptor->GetTextAutosizerPageInfo();
  EXPECT_EQ(new_bounds.width(), received_page_info.main_frame_width);
#endif  // BUILDFLAG(IS_ANDROID)

  // Dynamically create a new, cross-process frame to test sending the cached
  // TextAutosizerPageInfo.

  GURL c_url = embedded_test_server()->GetURL("c.com", "/title1.html");
  // The following is a hack so we can get an IPC watcher connected to the
  // RenderProcessHost for C before the `blink::WebView` is created for it, and
  // the TextAutosizerPageInfo IPC is sent to it.
  scoped_refptr<SiteInstance> c_site =
      web_contents()->GetSiteInstance()->GetRelatedSiteInstance(c_url);
  // Force creation of a render process for c's SiteInstance, this will get
  // used when we dynamically create the new frame.
  auto* c_rph = static_cast<RenderProcessHostImpl*>(c_site->GetProcess());
  ASSERT_TRUE(c_rph);
  ASSERT_NE(c_rph, root->current_frame_host()->GetProcess());
  ASSERT_NE(c_rph, b_child->current_frame_host()->GetProcess());

  // Create the subframe now.
  std::string create_frame_script = base::StringPrintf(
      "var new_iframe = document.createElement('iframe');"
      "new_iframe.src = '%s';"
      "document.body.appendChild(new_iframe);",
      c_url.spec().c_str());
  EXPECT_TRUE(ExecJs(root, create_frame_script));
  ASSERT_EQ(2U, root->child_count());

  // Ensure IPC is sent.
  base::RunLoop().RunUntilIdle();
  blink::mojom::TextAutosizerPageInfo page_info_sent_to_remote_main_frames =
      update_text_autosizer_info_observer.TextAutosizerPageInfo(
          web_contents()
              ->GetRenderManager()
              ->GetAllProxyHostsForTesting()
              .begin()
              ->second.get());

  EXPECT_EQ(received_page_info.main_frame_width,
            page_info_sent_to_remote_main_frames.main_frame_width);
  EXPECT_EQ(received_page_info.main_frame_layout_width,
            page_info_sent_to_remote_main_frames.main_frame_layout_width);
  EXPECT_EQ(received_page_info.device_scale_adjustment,
            page_info_sent_to_remote_main_frames.device_scale_adjustment);
}

// Test that the physical backing size and view bounds for a scaled out-of-
// process iframe are set and updated correctly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CompositorViewportPixelSizeTest) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_scaled_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* parent_iframe_node = root->child_at(0);

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site A ------- proxies for B\n"
      "        +--Site B -- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://baz.com/",
      DepictFrameTree(root));

  FrameTreeNode* nested_iframe_node = parent_iframe_node->child_at(0);
  RenderFrameProxyHost* proxy_to_parent =
      nested_iframe_node->render_manager()->GetProxyToParent();
  CrossProcessFrameConnector* connector =
      proxy_to_parent->cross_process_frame_connector();
  RenderWidgetHostViewBase* rwhv_nested =
      static_cast<RenderWidgetHostViewBase*>(
          nested_iframe_node->current_frame_host()
              ->GetRenderWidgetHost()
              ->GetView());

  RenderFrameSubmissionObserver frame_observer(nested_iframe_node);
  frame_observer.WaitForMetadataChange();

  // Verify that applying a CSS scale transform does not impact the size of the
  // content of the nested iframe.
  // The screen_space_rect_in_dip may be off by 1 due to rounding. There is no
  // good way to avoid this due to various device-scale-factor. (e.g. when
  // dsf=3.375, ceil(round(50 * 3.375) / 3.375) = 51. Thus, we allow the screen
  // size in dip to be off by 1 here.
  EXPECT_NEAR(50, connector->rect_in_parent_view_in_dip().size().width(), 1);
  EXPECT_NEAR(50, connector->rect_in_parent_view_in_dip().size().height(), 1);
  EXPECT_EQ(gfx::Size(100, 100), rwhv_nested->GetViewBounds().size());
  EXPECT_EQ(gfx::Size(100, 100), connector->local_frame_size_in_dip());
  EXPECT_EQ(connector->local_frame_size_in_pixels(),
            rwhv_nested->GetCompositorViewportPixelSize());
}

// Verify an OOPIF resize handler doesn't fire immediately after load without
// the frame having been resized. See https://crbug.com/826457.
// TODO(crbug.com/40809978): Test is very flaky on many platforms.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DISABLED_NoResizeAfterIframeLoad) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  FrameTreeNode* iframe = root->child_at(0);
  GURL site_url =
      embedded_test_server()->GetURL("b.com", "/page_with_resize_handler.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(iframe, site_url));
  base::RunLoop().RunUntilIdle();

  // Should be zero because the iframe only has its initial size from parent.
  EXPECT_EQ(0, EvalJs(iframe->current_frame_host(), "resize_count;"));
}

// Test that the view bounds for an out-of-process iframe are set and updated
// correctly, including accounting for local frame offsets in the parent and
// scroll positions.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, ViewBoundsInNestedFrameTest) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();
  RenderWidgetHostViewBase* rwhv_root = static_cast<RenderWidgetHostViewBase*>(
      root->current_frame_host()->GetRenderWidgetHost()->GetView());
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* parent_iframe_node = root->child_at(0);
  GURL site_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_positioned_frame.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(parent_iframe_node, site_url));
  RenderFrameSubmissionObserver frame_observer(shell()->web_contents());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site A ------- proxies for B\n"
      "        +--Site B -- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://baz.com/",
      DepictFrameTree(root));

  FrameTreeNode* nested_iframe_node = parent_iframe_node->child_at(0);
  RenderWidgetHostViewBase* rwhv_nested =
      static_cast<RenderWidgetHostViewBase*>(
          nested_iframe_node->current_frame_host()
              ->GetRenderWidgetHost()
              ->GetView());
  WaitForHitTestData(nested_iframe_node->current_frame_host());

  float scale_factor =
      frame_observer.LastRenderFrameMetadata().page_scale_factor;

  // Get the view bounds of the nested iframe, which should account for the
  // relative offset of its direct parent within the root frame.
  gfx::Rect bounds = rwhv_nested->GetViewBounds();

  RenderFrameProxyHost* parent_iframe_proxy =
      nested_iframe_node->render_manager()->GetProxyToParent();
  auto interceptor = std::make_unique<SynchronizeVisualPropertiesInterceptor>(
      parent_iframe_proxy);

  // Scroll the parent frame downward to verify that the child rect gets updated
  // correctly.
  blink::WebMouseWheelEvent scroll_event(
      blink::WebInputEvent::Type::kMouseWheel,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());

  scroll_event.SetPositionInWidget(
      std::floor((bounds.x() - rwhv_root->GetViewBounds().x() - 5) *
                 scale_factor),
      std::floor((bounds.y() - rwhv_root->GetViewBounds().y() - 5) *
                 scale_factor));
  scroll_event.delta_x = 0.0f;
  scroll_event.delta_y = -30.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  rwhv_root->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
  interceptor->WaitForRect();

  // The precise amount of scroll for the first view position update is not
  // deterministic, so this simply verifies that the OOPIF moved from its
  // earlier position.
  gfx::Rect update_rect = interceptor->last_rect();
  EXPECT_LT(update_rect.y(), bounds.y() - rwhv_root->GetViewBounds().y());
}

// Verify that "scrolling" property on frame elements propagates to child frames
// correctly.
// Does not work on android since android has scrollbars overlaid.
// TODO(bokan): Pretty soon most/all platforms will use overlay scrollbars. This
// test should find a better way to check for scrollability. crbug.com/662196.
// Flaky on Linux. crbug.com/790929.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#define MAYBE_FrameOwnerPropertiesPropagationScrolling \
  DISABLED_FrameOwnerPropertiesPropagationScrolling
#else
#define MAYBE_FrameOwnerPropertiesPropagationScrolling \
  FrameOwnerPropertiesPropagationScrolling
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_FrameOwnerPropertiesPropagationScrolling) {
#if BUILDFLAG(IS_MAC)
  ui::test::ScopedPreferredScrollerStyle scroller_style_override(false);
#endif
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_owner_properties_scrolling.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1u, root->child_count());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  FrameTreeNode* child = root->child_at(0);

  // If the available client width within the iframe is smaller than the
  // frame element's width, we assume there's a scrollbar.
  // Also note that just comparing clientHeight and scrollHeight of the frame's
  // document will not work.
  auto has_scrollbar = [](RenderFrameHostImpl* rfh) {
    int client_width = EvalJs(rfh, "document.body.clientWidth").ExtractInt();
    const int kFrameElementWidth = 200;
    return client_width < kFrameElementWidth;
  };

  auto set_scrolling_property = [](RenderFrameHostImpl* parent_rfh,
                                   const std::string& value) {
    EXPECT_TRUE(ExecJs(
        parent_rfh,
        base::StringPrintf("document.getElementById('child-1').setAttribute("
                           "    'scrolling', '%s');",
                           value.c_str())));
  };

  // Run the test over variety of parent/child cases.
  GURL urls[] = {// Remote to remote.
                 embedded_test_server()->GetURL("c.com", "/tall_page.html"),
                 // Remote to local.
                 embedded_test_server()->GetURL("a.com", "/tall_page.html"),
                 // Local to remote.
                 embedded_test_server()->GetURL("b.com", "/tall_page.html")};
  const std::string scrolling_values[] = {"yes", "auto", "no"};

  for (const auto& scrolling_value : scrolling_values) {
    bool expect_scrollbar = scrolling_value != "no";
    set_scrolling_property(root->current_frame_host(), scrolling_value);
    for (const auto& url : urls) {
      EXPECT_TRUE(NavigateToURLFromRenderer(child, url));
      EXPECT_EQ(expect_scrollbar, has_scrollbar(child->current_frame_host()));
    }
  }
}

// Verify that "marginwidth" and "marginheight" properties on frame elements
// propagate to child frames correctly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       FrameOwnerPropertiesPropagationMargin) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_owner_properties_margin.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1u, root->child_count());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  FrameTreeNode* child = root->child_at(0);

  EXPECT_EQ("10", EvalJs(child, "document.body.getAttribute('marginwidth');"));
  EXPECT_EQ("50", EvalJs(child, "document.body.getAttribute('marginheight');"));

  // Run the test over variety of parent/child cases.
  GURL urls[] = {// Remote to remote.
                 embedded_test_server()->GetURL("c.com", "/title2.html"),
                 // Remote to local.
                 embedded_test_server()->GetURL("a.com", "/title1.html"),
                 // Local to remote.
                 embedded_test_server()->GetURL("b.com", "/title2.html")};

  int current_margin_width = 15;
  int current_margin_height = 25;

  // Before each navigation, we change the marginwidth and marginheight
  // properties of the frame. We then check whether those properties are applied
  // correctly after the navigation has completed.
  for (const auto& url : urls) {
    // Change marginwidth and marginheight before navigating.
    EXPECT_TRUE(ExecJs(
        root,
        base::StringPrintf("var child = document.getElementById('child-1');"
                           "child.setAttribute('marginwidth', '%d');"
                           "child.setAttribute('marginheight', '%d');",
                           current_margin_width, current_margin_height)));

    EXPECT_TRUE(NavigateToURLFromRenderer(child, url));

    EXPECT_EQ(base::NumberToString(current_margin_width),
              EvalJs(child, "document.body.getAttribute('marginwidth');"));
    EXPECT_EQ(base::NumberToString(current_margin_height),
              EvalJs(child, "document.body.getAttribute('marginheight');"));

    current_margin_width += 5;
    current_margin_height += 10;
  }
}

// Verify that "csp" property on frame elements propagates to child frames
// correctly. See https://crbug.com/647588
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       FrameOwnerPropertiesPropagationCSP) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_owner_properties_csp.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1u, root->child_count());

  // The document in the iframe is blocked by CSPEE. An error page is loaded, it
  // stays in the process of the main document.
  EXPECT_EQ(
      " Site A\n"
      "   +--Site A\n"
      "Where A = http://a.com/",
      DepictFrameTree(root));

  FrameTreeNode* child = root->child_at(0);

  EXPECT_EQ(
      "object-src \'none\'",
      EvalJs(root, "document.getElementById('child-1').getAttribute('csp');"));

  // Run the test over variety of parent/child cases.
  struct {
    std::string csp_value;
    GURL url;
    bool should_block;
  } testCases[]{
      // Remote to remote.
      {"default-src a.com",
       embedded_test_server()->GetURL("c.com", "/title2.html"), true},
      // Remote to local.
      {"default-src b.com",
       embedded_test_server()->GetURL("a.com", "/title1.html"), true},
      // Local to remote.
      {"img-src c.com", embedded_test_server()->GetURL("b.com", "/title2.html"),
       true},
  };

  // Before each navigation, we change the csp property of the frame.
  // We then check whether that property is applied
  // correctly after the navigation has completed.
  for (const auto& testCase : testCases) {
    // Change csp before navigating.
    EXPECT_TRUE(ExecJs(
        root,
        base::StringPrintf("document.getElementById('child-1').setAttribute("
                           "    'csp', '%s');",
                           testCase.csp_value.c_str())));

    NavigateFrameToURL(child, testCase.url);
    EXPECT_EQ(testCase.csp_value, child->csp_attribute()->header->header_value);
    // TODO(amalika): add checks that the CSP replication takes effect

    const url::Origin child_origin =
        child->current_frame_host()->GetLastCommittedOrigin();

    EXPECT_EQ(testCase.should_block, child_origin.opaque());
    EXPECT_EQ(url::Origin::Create(testCase.url.DeprecatedGetOriginAsURL())
                  .GetTupleOrPrecursorTupleIfOpaque(),
              child_origin.GetTupleOrPrecursorTupleIfOpaque());
  }
}

// This test verifies that changing the CSS visibility of a cross-origin
// <iframe> is forwarded to its corresponding RenderWidgetHost and all other
// RenderWidgetHosts corresponding to the nested cross-origin frame.
// TODO(crbug.com/40865141): Flaky on mac and android.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
#define MAYBE_CSSVisibilityChanged DISABLED_CSSVisibilityChanged
#else
#define MAYBE_CSSVisibilityChanged CSSVisibilityChanged
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, MAYBE_CSSVisibilityChanged) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(b(c(d(d(a))))))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Find all child RenderWidgetHosts.
  std::vector<RenderWidgetHostImpl*> child_widget_hosts;
  FrameTreeNode* first_cross_process_child =
      web_contents()->GetPrimaryFrameTree().root()->child_at(0);
  for (auto* ftn : web_contents()->GetPrimaryFrameTree().SubtreeNodes(
           first_cross_process_child)) {
    RenderFrameHostImpl* frame_host = ftn->current_frame_host();
    if (!frame_host->is_local_root())
      continue;

    child_widget_hosts.push_back(frame_host->GetRenderWidgetHost());
  }

  // Ignoring the root, there is exactly 4 local roots and hence 5
  // RenderWidgetHosts on the page.
  EXPECT_EQ(4U, child_widget_hosts.size());

  // Initially all the RenderWidgetHosts should be visible.
  for (size_t index = 0; index < child_widget_hosts.size(); ++index) {
    EXPECT_FALSE(child_widget_hosts[index]->is_hidden())
        << "The RWH at distance " << index + 1U
        << " from root RWH should not be hidden.";
  }

  std::string show_script =
      "document.querySelector('iframe').style.visibility = 'visible';";
  std::string hide_script =
      "document.querySelector('iframe').style.visibility = 'hidden';";

  // Define observers for notifications about hiding child RenderWidgetHosts.
  std::vector<std::unique_ptr<RenderWidgetHostVisibilityObserver>>
      hide_widget_host_observers(child_widget_hosts.size());
  for (size_t index = 0U; index < child_widget_hosts.size(); ++index) {
    hide_widget_host_observers[index] =
        std::make_unique<RenderWidgetHostVisibilityObserver>(
            child_widget_hosts[index], false);
  }

  EXPECT_TRUE(ExecJs(shell(), hide_script));
  for (size_t index = 0U; index < child_widget_hosts.size(); ++index) {
    EXPECT_TRUE(hide_widget_host_observers[index]->WaitUntilSatisfied())
        << "Expected RenderWidgetHost at distance " << index + 1U
        << " from root RenderWidgetHost to become hidden.";
  }

  // Define observers for notifications about showing child RenderWidgetHosts.
  std::vector<std::unique_ptr<RenderWidgetHostVisibilityObserver>>
      show_widget_host_observers(child_widget_hosts.size());
  for (size_t index = 0U; index < child_widget_hosts.size(); ++index) {
    show_widget_host_observers[index] =
        std::make_unique<RenderWidgetHostVisibilityObserver>(
            child_widget_hosts[index], true);
  }

  EXPECT_TRUE(ExecJs(shell(), show_script));
  for (size_t index = 0U; index < child_widget_hosts.size(); ++index) {
    EXPECT_TRUE(show_widget_host_observers[index]->WaitUntilSatisfied())
        << "Expected RenderWidgetHost at distance " << index + 1U
        << " from root RenderWidgetHost to become shown.";
  }
}

// This test verifies that hiding an OOPIF in CSS will stop generating
// compositor frames for the OOPIF and any nested OOPIFs inside it. This holds
// even when the whole page is shown.
#if BUILDFLAG(IS_MAC)
// Flaky on Mac. https://crbug.com/1505297
#define MAYBE_HiddenOOPIFWillNotGenerateCompositorFrames \
  DISABLED_HiddenOOPIFWillNotGenerateCompositorFrames
#else
#define MAYBE_HiddenOOPIFWillNotGenerateCompositorFrames \
  HiddenOOPIFWillNotGenerateCompositorFrames
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_HiddenOOPIFWillNotGenerateCompositorFrames) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_two_frames.html"));
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), main_url);

  GURL cross_site_url_b =
      embedded_test_server()->GetURL("b.com", "/counter.html");

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), cross_site_url_b));

  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), cross_site_url_b));

  // Now inject code in the first frame to create a nested OOPIF.
  RenderFrameHostCreatedObserver new_frame_created_observer(
      shell()->web_contents(), 1);
  ASSERT_TRUE(
      ExecJs(root->child_at(0)->current_frame_host(),
             "document.body.appendChild(document.createElement('iframe'));"));
  new_frame_created_observer.Wait();

  GURL cross_site_url_a =
      embedded_test_server()->GetURL("a.com", "/counter.html");

  // Navigate the nested frame.
  TestFrameNavigationObserver observer(root->child_at(0)->child_at(0));
  ASSERT_TRUE(ExecJs(root->child_at(0)->current_frame_host(),
                     JsReplace("document.querySelector('iframe').src = $1",
                               cross_site_url_a)));
  observer.Wait();

  RenderWidgetHostViewChildFrame* first_child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          root->child_at(0)->current_frame_host()->GetView());
  RenderWidgetHostViewChildFrame* second_child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          root->child_at(1)->current_frame_host()->GetView());
  RenderWidgetHostViewChildFrame* nested_child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          root->child_at(0)->child_at(0)->current_frame_host()->GetView());

  RenderFrameSubmissionObserver first_frame_counter(
      first_child_view->host_->render_frame_metadata_provider());
  RenderFrameSubmissionObserver second_frame_counter(
      second_child_view->host_->render_frame_metadata_provider());
  RenderFrameSubmissionObserver third_frame_counter(
      nested_child_view->host_->render_frame_metadata_provider());

  const int kFrameCountLimit = 20;

  // Wait for a minimum number of compositor frames for the second frame.
  while (second_frame_counter.render_frame_count() < kFrameCountLimit)
    second_frame_counter.WaitForAnyFrameSubmission();
  ASSERT_LE(kFrameCountLimit, second_frame_counter.render_frame_count());

  // Now make sure all frames have roughly the counter value in the sense that
  // no counter value is more than twice any other.
  float ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
                static_cast<float>(second_frame_counter.render_frame_count());
  EXPECT_GT(2.5f, ratio + 1 / ratio) << "Ratio is: " << ratio;

  ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
          static_cast<float>(third_frame_counter.render_frame_count());
  EXPECT_GT(2.5f, ratio + 1 / ratio) << "Ratio is: " << ratio;

  // Make sure all views can become visible.
  EXPECT_TRUE(first_child_view->CanBecomeVisible());
  EXPECT_TRUE(second_child_view->CanBecomeVisible());
  EXPECT_TRUE(nested_child_view->CanBecomeVisible());

  // Hide the first frame and wait for the notification to be posted by its
  // RenderWidgetHost.
  RenderWidgetHostVisibilityObserver hide_observer(
      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), false);

  // Hide the first frame.
  ASSERT_TRUE(ExecJs(
      shell(),
      "document.getElementsByName('frame1')[0].style.visibility = 'hidden'"));
  ASSERT_TRUE(hide_observer.WaitUntilSatisfied());
  EXPECT_TRUE(first_child_view->FrameConnectorForTesting()->IsHidden());

  // Verify that only the second view can become visible now.
  EXPECT_FALSE(first_child_view->CanBecomeVisible());
  EXPECT_TRUE(second_child_view->CanBecomeVisible());
  EXPECT_FALSE(nested_child_view->CanBecomeVisible());

  // Now hide and show the WebContents (to simulate a tab switch).
  shell()->web_contents()->WasHidden();
  shell()->web_contents()->WasShown();

  first_frame_counter.ResetCounter();
  second_frame_counter.ResetCounter();
  third_frame_counter.ResetCounter();

  // We expect the second counter to keep running.
  while (second_frame_counter.render_frame_count() < kFrameCountLimit)
    second_frame_counter.WaitForAnyFrameSubmission();
  ASSERT_LT(kFrameCountLimit, second_frame_counter.render_frame_count() + 1);

  // Verify that the counter for other two frames did not count much.
  ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
          static_cast<float>(second_frame_counter.render_frame_count());
  EXPECT_GT(0.5f, ratio) << "Ratio is: " << ratio;

  ratio = static_cast<float>(third_frame_counter.render_frame_count()) /
          static_cast<float>(second_frame_counter.render_frame_count());
  EXPECT_GT(0.5f, ratio) << "Ratio is: " << ratio;
}

// This test verifies that navigating a hidden OOPIF to cross-origin will not
// lead to creating compositor frames for the new OOPIF renderer.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessBrowserTest,
    HiddenOOPIFWillNotGenerateCompositorFramesAfterNavigation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_two_frames.html"));
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), main_url);

  GURL cross_site_url_b =
      embedded_test_server()->GetURL("b.com", "/counter.html");

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), cross_site_url_b));

  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), cross_site_url_b));

  // Hide the first frame and wait for the notification to be posted by its
  // RenderWidgetHost.
  RenderWidgetHostVisibilityObserver hide_observer(
      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), false);

  // Hide the first frame.
  ASSERT_TRUE(ExecJs(
      shell(),
      "document.getElementsByName('frame1')[0].style.visibility = 'hidden'"));
  ASSERT_TRUE(hide_observer.WaitUntilSatisfied());

  // Now navigate the first frame to another OOPIF process.
  TestFrameNavigationObserver navigation_observer(
      root->child_at(0)->current_frame_host());
  GURL cross_site_url_c =
      embedded_test_server()->GetURL("c.com", "/counter.html");
  ASSERT_TRUE(
      ExecJs(web_contents(),
             JsReplace("document.getElementsByName('frame1')[0].src = $1",
                       cross_site_url_c)));
  navigation_observer.Wait();

  // Now investigate compositor frame creation.
  RenderWidgetHostViewChildFrame* first_child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          root->child_at(0)->current_frame_host()->GetView());

  RenderWidgetHostViewChildFrame* second_child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          root->child_at(1)->current_frame_host()->GetView());

  EXPECT_FALSE(first_child_view->CanBecomeVisible());

  RenderFrameSubmissionObserver first_frame_counter(
      first_child_view->host_->render_frame_metadata_provider());
  RenderFrameSubmissionObserver second_frame_counter(
      second_child_view->host_->render_frame_metadata_provider());

  const int kFrameCountLimit = 20;

  // Wait for a certain number of swapped compositor frames generated for the
  // second child view. During the same interval the first frame should not have
  // swapped any compositor frames.
  while (second_frame_counter.render_frame_count() < kFrameCountLimit)
    second_frame_counter.WaitForAnyFrameSubmission();
  ASSERT_LT(kFrameCountLimit, second_frame_counter.render_frame_count() + 1);

  float ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
                static_cast<float>(second_frame_counter.render_frame_count());
  EXPECT_GT(0.5f, ratio) << "Ratio is: " << ratio;
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, ScreenCoordinates) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  const char* properties[] = {"screenX", "screenY", "outerWidth",
                              "outerHeight"};

  for (const char* property : properties) {
    std::string script = base::StringPrintf("window.%s;", property);
    int root_value = EvalJs(root, script).ExtractInt();
    int child_value = EvalJs(child, script).ExtractInt();
    EXPECT_EQ(root_value, child_value);
  }
}

// Tests that an out-of-process iframe receives the visibilitychange event.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, VisibilityChange) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  EXPECT_TRUE(
      ExecJs(root->child_at(0),
             "var event_fired = 0;\n"
             "document.addEventListener('visibilitychange',\n"
             "                          function() { event_fired++; });\n"));

  shell()->web_contents()->WasHidden();

  EXPECT_EQ(1, EvalJs(root->child_at(0), "event_fired"));

  shell()->web_contents()->WasShown();

  EXPECT_EQ(2, EvalJs(root->child_at(0), "event_fired"));
}

// This test verifies that the main-frame's page scale factor propagates to
// the compositor layertrees in each of the child processes.
// Flaky on all platforms: https://crbug.com/1116774
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DISABLED_PageScaleFactorPropagatesToOOPIFs) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c),d)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(2u, root->child_count());
  FrameTreeNode* child_b = root->child_at(0);
  FrameTreeNode* child_c = root->child_at(1);
  ASSERT_EQ(1U, child_b->child_count());
  FrameTreeNode* child_d = child_b->child_at(0);

  ASSERT_TRUE(child_b);
  ASSERT_TRUE(child_c);
  ASSERT_TRUE(child_d);

  EXPECT_EQ(
      " Site A ------------ proxies for B C D\n"
      "   |--Site B ------- proxies for A C D\n"
      "   |    +--Site C -- proxies for A B D\n"
      "   +--Site D ------- proxies for A B C\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://c.com/\n"
      "      D = http://d.com/",
      DepictFrameTree(root));

  RenderFrameSubmissionObserver observer_a(root);
  RenderFrameSubmissionObserver observer_b(child_b);
  RenderFrameSubmissionObserver observer_c(child_c);
  RenderFrameSubmissionObserver observer_d(child_d);

  // Monitor visual sync messages coming from the mainframe to make sure
  // |is_pinch_gesture_active| goes true during the pinch gesture.
  RenderFrameProxyHost* root_proxy_host =
      child_d->render_manager()->GetProxyToParent();
  auto interceptor_mainframe =
      std::make_unique<SynchronizeVisualPropertiesInterceptor>(root_proxy_host);

  // Monitor frame sync messages coming from child_b as it will need to
  // relay them to child_d.
  RenderFrameProxyHost* child_b_proxy_host =
      child_c->render_manager()->GetProxyToParent();
  auto interceptor_child_b =
      std::make_unique<SynchronizeVisualPropertiesInterceptor>(
          child_b_proxy_host);

  // We need to observe a root frame submission to pick up the initial page
  // scale factor.
  observer_a.WaitForAnyFrameSubmission();

  const float kPageScaleDelta = 2.f;
  // On desktop systems we expect |current_page_scale| to be 1.f, but on
  // Android it will typically be less than 1.f, and may take on arbitrary
  // values.
  float current_page_scale =
      observer_a.LastRenderFrameMetadata().page_scale_factor;
  float target_page_scale = current_page_scale * kPageScaleDelta;

  SyntheticPinchGestureParams params;
  auto* host = static_cast<RenderWidgetHostImpl*>(
      root->current_frame_host()->GetRenderWidgetHost());
  gfx::Rect bounds(host->GetView()->GetViewBounds().size());
  // The synthetic gesture code expects a location in root-view coordinates.
  params.anchor = gfx::PointF(bounds.CenterPoint());
  // In SyntheticPinchGestureParams, |scale_factor| is really a delta.
  params.scale_factor = kPageScaleDelta;
#if BUILDFLAG(IS_MAC)
  auto synthetic_pinch_gesture =
      std::make_unique<SyntheticTouchpadPinchGesture>(params);
#else
  auto synthetic_pinch_gesture =
      std::make_unique<SyntheticTouchscreenPinchGesture>(params);
#endif

  // Send pinch gesture and verify we receive the ack.
  InputEventAckWaiter ack_waiter(host,
                                 blink::WebInputEvent::Type::kGesturePinchEnd);
  host->QueueSyntheticGesture(
      std::move(synthetic_pinch_gesture),
      base::BindOnce([](SyntheticGesture::Result result) {
        EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
      }));
  ack_waiter.Wait();

  // Make sure all the page scale values behave as expected.
  const float kScaleTolerance = 0.1f;
  observer_a.WaitForPageScaleFactor(target_page_scale, kScaleTolerance);
  observer_b.WaitForExternalPageScaleFactor(target_page_scale, kScaleTolerance);
  observer_c.WaitForExternalPageScaleFactor(target_page_scale, kScaleTolerance);
  observer_d.WaitForExternalPageScaleFactor(target_page_scale, kScaleTolerance);

  // The change in |is_pinch_gesture_active| that signals the end of the pinch
  // gesture will occur sometime after the ack for GesturePinchEnd, so we need
  // to wait for it from each renderer. If it's never seen, the test fails by
  // timing out.
  interceptor_mainframe->WaitForPinchGestureEnd();
  interceptor_child_b->WaitForPinchGestureEnd();
}

// Test that the compositing scale factor for an out-of-process iframe are set
// and updated correctly, including accounting for all intermediate transforms.
// TODO(crbug.com/40163506): Flaky test.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DISABLED_CompositingScaleFactorInNestedFrameTest) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_scaled_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  ASSERT_EQ(1U, root->child_count());
  FrameTreeNode* child_b = root->child_at(0);

  EXPECT_TRUE(NavigateToURLFromRenderer(
      child_b, embedded_test_server()->GetURL(
                   "b.com", "/frame_tree/page_with_transformed_iframe.html")));

  ASSERT_EQ(1U, child_b->child_count());
  FrameTreeNode* child_c = child_b->child_at(0);

  EXPECT_TRUE(NavigateToURLFromRenderer(
      child_c, embedded_test_server()->GetURL(
                   "c.com", "/frame_tree/page_with_scaled_frame.html")));

  ASSERT_EQ(1U, child_c->child_count());
  FrameTreeNode* child_d = child_c->child_at(0);

  EXPECT_TRUE(NavigateToURLFromRenderer(
      child_d, embedded_test_server()->GetURL("d.com", "/simple_page.html")));

  EXPECT_EQ(
      " Site A ------------ proxies for B C D\n"
      "   +--Site B ------- proxies for A C D\n"
      "        +--Site C -- proxies for A B D\n"
      "             +--Site D -- proxies for A B C\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://c.com/\n"
      "      D = http://d.com/",
      DepictFrameTree(root));

  // Wait for b.com's frame to have its compositing scale factor set to 0.5,
  // which is the scale factor for b.com's iframe element in the main frame.
  while (true) {
    auto* rwh_b = child_b->current_frame_host()->GetRenderWidgetHost();
    std::optional<blink::VisualProperties> properties =
        rwh_b->LastComputedVisualProperties();
    if (properties && cc::MathUtil::IsFloatNearlyTheSame(
                          properties->compositing_scale_factor, 0.5f)) {
      break;
    }
    base::RunLoop().RunUntilIdle();
  }

  // Wait for c.com's frame to have its compositing scale factor set to 0.5,
  // which is the accumulated scale factor of c.com to the main frame obtained
  // by multiplying the scale factor of c.com's iframe element (1 since
  // transform is rotation only without scale) with the scale factor of its
  // parent frame b.com (0.5).
  while (true) {
    auto* rwh_c = child_c->current_frame_host()->GetRenderWidgetHost();
    std::optional<blink::VisualProperties> properties =
        rwh_c->LastComputedVisualProperties();
    if (properties && cc::MathUtil::IsFloatNearlyTheSame(
                          properties->compositing_scale_factor, 0.5f)) {
      break;
    }
    base::RunLoop().RunUntilIdle();
  }

  // Wait for d.com's frame to have its compositing scale factor set to 0.25,
  // which is the accumulated scale factor of d.com to the main frame obtained
  // by combining the scale factor of d.com's iframe element (0.5) with the
  // scale factor of its parent d.com (0.5).
  while (true) {
    auto* rwh_d = child_d->current_frame_host()->GetRenderWidgetHost();
    std::optional<blink::VisualProperties> properties =
        rwh_d->LastComputedVisualProperties();
    if (properties && cc::MathUtil::IsFloatNearlyTheSame(
                          properties->compositing_scale_factor, 0.25f)) {
      break;
    }
    base::RunLoop().RunUntilIdle();
  }
}

// Test that the compositing scale factor for an out-of-process iframe is set
// to a non-zero value even if intermediate CSS transform has zero scale.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CompositingScaleFactorWithZeroScaleTransform) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_scaled_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  ASSERT_EQ(1U, root->child_count());
  FrameTreeNode* child_b = root->child_at(0);

  EXPECT_TRUE(NavigateToURLFromRenderer(
      child_b,
      embedded_test_server()->GetURL("b.com", "/frame_tree/simple_page.html")));

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  // Wait for b.com's frame to have its compositing scale factor set to 0.5,
  // which is the scale factor for b.com's iframe element in the main frame.
  while (true) {
    auto* rwh_b = child_b->current_frame_host()->GetRenderWidgetHost();
    std::optional<blink::VisualProperties> properties =
        rwh_b->LastComputedVisualProperties();
    if (properties && cc::MathUtil::IsFloatNearlyTheSame(
                          properties->compositing_scale_factor, 0.5f)) {
      break;
    }
    base::RunLoop().RunUntilIdle();
  }

  // Set iframe transform scale to 0.
  EXPECT_TRUE(
      EvalJs(root->current_frame_host(),
             "document.querySelector('iframe').style.transform = 'scale(0)'")
          .error.empty());

  // Wait for b.com frame's compositing scale factor to change, and check that
  // the final value is non-zero.
  while (true) {
    auto* rwh_b = child_b->current_frame_host()->GetRenderWidgetHost();
    std::optional<blink::VisualProperties> properties =
        rwh_b->LastComputedVisualProperties();
    if (properties && !cc::MathUtil::IsFloatNearlyTheSame(
                          properties->compositing_scale_factor, 0.5f)) {
      EXPECT_GT(properties->compositing_scale_factor, 0.0f);
      break;
    }
    base::RunLoop().RunUntilIdle();
  }
}

// Check that when a frame changes a subframe's size twice and then sends a
// postMessage to the subframe, the subframe's onmessage handler sees the new
// size.  In particular, ensure that the postMessage won't get reordered with
// the second resize, which might be throttled if the first resize is still in
// progress. See https://crbug.com/828529.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ResizeAndCrossProcessPostMessagePreserveOrder) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Add an onmessage handler to the subframe to send back its width.
  EXPECT_TRUE(ExecJs(root->child_at(0),
                     WaitForMessageScript("document.body.clientWidth")));

  // Drop the visual properties ACKs from the child renderer.  To do this,
  // unsubscribe the child's RenderWidgetHost from its
  // RenderFrameMetadataProvider, which ensures that
  // DidUpdateVisualProperties() won't be called on it, and the ACK won't be
  // reset.  This simulates that the ACK for the first resize below does not
  // arrive before the second resize IPC arrives from the
  // parent, and that the second resize IPC early-exits in
  // SynchronizeVisualProperties() due to the pending visual properties ACK.
  RenderWidgetHostImpl* rwh =
      root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
  rwh->render_frame_metadata_provider_.RemoveObserver(rwh);

  // Now, resize the subframe twice from the main frame and send it a
  // postMessage. The postMessage handler should see the second updated size.
  EXPECT_TRUE(ExecJs(root, R"(
      var f = document.querySelector('iframe');
      f.width = 500;
      f.offsetTop; // force layout; this sends a resize IPC for width of 500.
      f.width = 700;
      f.offsetTop; // force layout; this sends a resize IPC for width of 700.
      f.contentWindow.postMessage('foo', '*');)"));
  EXPECT_EQ(700, EvalJs(root->child_at(0), "onMessagePromise"));
}

// This test verifies that when scrolling an OOPIF in a pinched-zoomed page,
// that the scroll-delta matches the distance between TouchStart/End as seen
// by the oopif, i.e. the oopif content 'sticks' to the finger during scrolling.
// The relation is not exact, but should be close.
// TODO(crbug.com/40697699): Re-enable the flaky test.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_DisableScrollOopifInPinchZoomedPage \
  DISABLED_ScrollOopifInPinchZoomedPage
#else
#define MAYBE_DisableScrollOopifInPinchZoomedPage ScrollOopifInPinchZoomedPage
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_DisableScrollOopifInPinchZoomedPage) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1u, root->child_count());
  FrameTreeNode* child = root->child_at(0);
  ASSERT_TRUE(child);

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  // Make B scrollable. The call to document.write will erase the html inside
  // the OOPIF, leaving just a vertical column of 'Hello's.
  std::string script =
      "var s = '<div>Hello</div>\\n';\n"
      "document.write(s.repeat(200));";
  EXPECT_TRUE(ExecJs(child, script));

  RenderFrameSubmissionObserver observer_a(root);
  RenderFrameSubmissionObserver observer_b(child);

  // We need to observe a root frame submission to pick up the initial page
  // scale factor.
  observer_a.WaitForAnyFrameSubmission();

  const float kPageScaleDelta = 2.f;
  // On desktop systems we expect |current_page_scale| to be 1.f, but on
  // Android it will typically be less than 1.f, and may take on arbitrary
  // values.
  float original_page_scale =
      observer_a.LastRenderFrameMetadata().page_scale_factor;
  float target_page_scale = original_page_scale * kPageScaleDelta;

  SyntheticPinchGestureParams params;
  auto* host = static_cast<RenderWidgetHostImpl*>(
      root->current_frame_host()->GetRenderWidgetHost());
  RenderWidgetHostViewBase* root_view = host->GetView();
  RenderWidgetHostViewBase* child_view =
      static_cast<RenderWidgetHostImpl*>(
          child->current_frame_host()->GetRenderWidgetHost())
          ->GetView();
  gfx::Rect bounds(root_view->GetViewBounds().size());
  // The synthetic gesture code expects a location in root-view coordinates.
  params.anchor = gfx::PointF(bounds.CenterPoint().x(), 70.f);
  // In SyntheticPinchGestureParams, |scale_factor| is really a delta.
  params.scale_factor = kPageScaleDelta;
#if BUILDFLAG(IS_MAC)
  auto synthetic_pinch_gesture =
      std::make_unique<SyntheticTouchpadPinchGesture>(params);
#else
  auto synthetic_pinch_gesture =
      std::make_unique<SyntheticTouchscreenPinchGesture>(params);
#endif

  // Send pinch gesture and verify we receive the ack.
  {
    InputEventAckWaiter ack_waiter(
        host, blink::WebInputEvent::Type::kGesturePinchEnd);
    host->QueueSyntheticGesture(
        std::move(synthetic_pinch_gesture),
        base::BindOnce([](SyntheticGesture::Result result) {
          EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
        }));
    ack_waiter.Wait();
  }

  // Make sure all the page scale values behave as expected.
  const float kScaleTolerance = 0.07f;
  observer_a.WaitForPageScaleFactor(target_page_scale, kScaleTolerance);
  observer_b.WaitForExternalPageScaleFactor(target_page_scale, kScaleTolerance);
  float final_page_scale =
      observer_a.LastRenderFrameMetadata().page_scale_factor;

  // Verify scroll position of OOPIF.
  float initial_child_scroll = EvalJs(child, "window.scrollY").ExtractDouble();

  // Send touch-initiated gesture scroll sequence to OOPIF.
  // TODO(wjmaclean): GetViewBounds() is broken for OOPIFs when PSF != 1.f, so
  // we calculate it manually. This will need to be update when GetViewBounds()
  // in RenderWidgetHostViewBase is fixed. See https://crbug.com/928825.
  auto child_bounds = child_view->GetViewBounds();
  gfx::PointF child_upper_left =
      child_view->TransformPointToRootCoordSpaceF(gfx::PointF(0, 0));
  gfx::PointF child_lower_right = child_view->TransformPointToRootCoordSpaceF(
      gfx::PointF(child_bounds.width(), child_bounds.height()));
  gfx::PointF scroll_start_location_in_screen =
      gfx::PointF((child_upper_left.x() + child_lower_right.x()) / 2.f,
                  child_lower_right.y() - 10);
  const float kScrollDelta = 100.f;
  gfx::PointF scroll_end_location_in_screen =
      scroll_start_location_in_screen + gfx::Vector2dF(0, -kScrollDelta);

  // Create touch move sequence with discrete touch moves. Include a brief
  // pause at the end to avoid the scroll flinging.
  static constexpr char kActionsTemplate[] = R"HTML(
      [{
        "source" : "touch",
        "actions" : [
          { "name": "pointerDown", "x": %f, "y": %f},
          { "name": "pointerMove", "x": %f, "y": %f},
          { "name": "pause", "duration": 300 },
          { "name": "pointerUp"}
        ]
      }]
  )HTML";
  std::string touch_move_sequence_json = base::StringPrintf(
      kActionsTemplate, scroll_start_location_in_screen.x(),
      scroll_start_location_in_screen.y(), scroll_end_location_in_screen.x(),
      scroll_end_location_in_screen.y());
  ASSERT_OK_AND_ASSIGN(
      auto parsed_json,
      base::JSONReader::ReadAndReturnValueWithError(touch_move_sequence_json));
  ActionsParser actions_parser(std::move(parsed_json));

  ASSERT_TRUE(actions_parser.Parse());
  auto synthetic_scroll_gesture = std::make_unique<SyntheticPointerAction>(
      actions_parser.pointer_action_params());

  {
    auto* child_host = static_cast<RenderWidgetHostImpl*>(
        child->current_frame_host()->GetRenderWidgetHost());
    InputEventAckWaiter ack_waiter(
        child_host, blink::WebInputEvent::Type::kGestureScrollEnd);
    host->QueueSyntheticGesture(
        std::move(synthetic_scroll_gesture),
        base::BindOnce([](SyntheticGesture::Result result) {
          EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
        }));
    ack_waiter.Wait();
  }

  // Verify new scroll position of OOPIF, should match touch sequence delta.
  float expected_scroll_delta = kScrollDelta / final_page_scale;
  float actual_scroll_delta =
      EvalJs(child, "window.scrollY").ExtractDouble() - initial_child_scroll;

  const float kScrollTolerance = 0.2f;
  EXPECT_GT((1.f + kScrollTolerance) * expected_scroll_delta,
            actual_scroll_delta);
  EXPECT_LT((1.f - kScrollTolerance) * expected_scroll_delta,
            actual_scroll_delta);
}

INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessHighDPIBrowserTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
}  // namespace content
