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

#include "cc/layers/picture_layer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/web/web_frame_content_dumper.h"
#include "third_party/blink/public/web/web_hit_test_result.h"
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/testing/sim/sim_compositor.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"

using testing::_;

namespace blink {

using namespace html_names;

// NOTE: This test uses <iframe sandbox> to create cross origin iframes.

class FrameThrottlingTest : public PaintTestConfigurations, public SimTest {
 protected:
  void SetUp() override {
    SimTest::SetUp();
    WebView().MainFrameWidget()->Resize(WebSize(640, 480));
  }

  SimCanvas::Commands CompositeFrame() {
    auto commands = Compositor().BeginFrame();
    // Ensure intersection observer notifications get delivered.
    test::RunPendingTasks();
    return commands;
  }

  // Number of rectangles that make up the root layer's touch handler region.
  size_t TouchHandlerRegionSize() {
    size_t result = 0;
    PaintLayer* layer =
        WebView().MainFrameImpl()->GetFrame()->ContentLayoutObject()->Layer();
    GraphicsLayer* own_graphics_layer =
        layer->GraphicsLayerBacking(&layer->GetLayoutObject());
    if (own_graphics_layer) {
      result += own_graphics_layer->CcLayer()
                    ->touch_action_region()
                    .region()
                    .GetRegionComplexity();
    }
    GraphicsLayer* child_graphics_layer = layer->GraphicsLayerBacking();
    if (child_graphics_layer && child_graphics_layer != own_graphics_layer) {
      result += child_graphics_layer->CcLayer()
                    ->touch_action_region()
                    .region()
                    .GetRegionComplexity();
    }
    return result;
  }

  void UpdateAllLifecyclePhases() {
    GetDocument().View()->UpdateAllLifecyclePhases(
        DocumentLifecycle::LifecycleUpdateReason::kTest);
  }
};

INSTANTIATE_PAINT_TEST_CASE_P(FrameThrottlingTest);

TEST_P(FrameThrottlingTest, ThrottleInvisibleFrames) {
  SimRequest main_resource("https://example.com/", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe sandbox id=frame></iframe>");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* frame_document = frame_element->contentDocument();

  // Initially both frames are visible.
  EXPECT_FALSE(GetDocument().View()->IsHiddenForThrottling());
  EXPECT_FALSE(frame_document->View()->IsHiddenForThrottling());

  // Moving the child fully outside the parent makes it invisible.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_FALSE(GetDocument().View()->IsHiddenForThrottling());
  EXPECT_TRUE(frame_document->View()->IsHiddenForThrottling());

  // A partially visible child is considered visible.
  frame_element->setAttribute(kStyleAttr,
                              "transform: translate(-50px, 0px, 0px)");
  CompositeFrame();
  EXPECT_FALSE(GetDocument().View()->IsHiddenForThrottling());
  EXPECT_FALSE(frame_document->View()->IsHiddenForThrottling());
}

TEST_P(FrameThrottlingTest, HiddenSameOriginFramesAreNotThrottled) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame src=iframe.html></iframe>");
  frame_resource.Complete("<iframe id=innerFrame></iframe>");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* frame_document = frame_element->contentDocument();

  HTMLIFrameElement* inner_frame_element =
      ToHTMLIFrameElement(frame_document->getElementById("innerFrame"));
  auto* inner_frame_document = inner_frame_element->contentDocument();

  EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
  EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
  EXPECT_FALSE(inner_frame_document->View()->CanThrottleRendering());

  // Hidden same origin frames are not throttled.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
  EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
  EXPECT_FALSE(inner_frame_document->View()->CanThrottleRendering());
}

TEST_P(FrameThrottlingTest, HiddenCrossOriginFramesAreThrottled) {
  // Create a document with doubly nested iframes.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame src=iframe.html></iframe>");
  frame_resource.Complete("<iframe id=innerFrame sandbox></iframe>");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* frame_document = frame_element->contentDocument();

  auto* inner_frame_element =
      ToHTMLIFrameElement(frame_document->getElementById("innerFrame"));
  auto* inner_frame_document = inner_frame_element->contentDocument();

  EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
  EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
  EXPECT_FALSE(inner_frame_document->View()->CanThrottleRendering());

  // Hidden cross origin frames are throttled.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
  EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
  EXPECT_TRUE(inner_frame_document->View()->CanThrottleRendering());
}

TEST_P(FrameThrottlingTest, IntersectionObservationOverridesThrottling) {
  // Create a document with doubly nested iframes.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame src=iframe.html></iframe>");
  frame_resource.Complete("<iframe id=innerFrame sandbox></iframe>");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* frame_document = frame_element->contentDocument();

  auto* inner_frame_element =
      ToHTMLIFrameElement(frame_document->getElementById("innerFrame"));
  auto* inner_frame_document = inner_frame_element->contentDocument();

  DocumentLifecycle::AllowThrottlingScope throttling_scope(
      GetDocument().Lifecycle());

  // Hidden cross origin frames are throttled.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
  EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
  EXPECT_TRUE(inner_frame_document->View()->ShouldThrottleRendering());

  // An intersection observation overrides...
  inner_frame_document->View()->SetIntersectionObservationState(
      LocalFrameView::kRequired);
  EXPECT_FALSE(inner_frame_document->View()->ShouldThrottleRendering());
  inner_frame_document->View()->ScheduleAnimation();

  LayoutView* inner_view = inner_frame_document->View()->GetLayoutView();

  inner_view->SetNeedsLayout("test");
  inner_view->Compositor()->SetNeedsCompositingUpdate(
      kCompositingUpdateRebuildTree);
  inner_view->SetShouldDoFullPaintInvalidation(
      PaintInvalidationReason::kForTesting);
  inner_view->Layer()->SetNeedsRepaint();
  EXPECT_TRUE(inner_frame_document->View()
                  ->GetLayoutView()
                  ->ShouldDoFullPaintInvalidation());
  inner_view->Compositor()->SetNeedsCompositingUpdate(
      kCompositingUpdateRebuildTree);
  EXPECT_EQ(kCompositingUpdateRebuildTree,
            inner_view->Compositor()->pending_update_type_);
  EXPECT_TRUE(inner_view->Layer()->NeedsRepaint());

  CompositeFrame();
  // ...but only for one frame.
  EXPECT_TRUE(inner_frame_document->View()->ShouldThrottleRendering());

  EXPECT_FALSE(inner_view->NeedsLayout());
  EXPECT_TRUE(inner_frame_document->View()
                  ->GetLayoutView()
                  ->ShouldDoFullPaintInvalidation());
  EXPECT_EQ(kCompositingUpdateRebuildTree,
            inner_view->Compositor()->pending_update_type_);
  EXPECT_TRUE(inner_view->Layer()->NeedsRepaint());
}

TEST_P(FrameThrottlingTest, HiddenCrossOriginZeroByZeroFramesAreNotThrottled) {
  // Create a document with doubly nested iframes.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame src=iframe.html></iframe>");
  frame_resource.Complete(
      "<iframe id=innerFrame width=0 height=0 sandbox></iframe>");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* frame_document = frame_element->contentDocument();

  auto* inner_frame_element =
      ToHTMLIFrameElement(frame_document->getElementById("innerFrame"));
  auto* inner_frame_document = inner_frame_element->contentDocument();

  EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
  EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
  EXPECT_FALSE(inner_frame_document->View()->CanThrottleRendering());

  // The frame is not throttled because its dimensions are 0x0.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
  EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
  EXPECT_FALSE(inner_frame_document->View()->CanThrottleRendering());
}

TEST_P(FrameThrottlingTest, ThrottledLifecycleUpdate) {
  SimRequest main_resource("https://example.com/", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe sandbox id=frame></iframe>");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* frame_document = frame_element->contentDocument();

  // Enable throttling for the child frame.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_TRUE(frame_document->View()->CanThrottleRendering());
  EXPECT_EQ(DocumentLifecycle::kPaintClean,
            frame_document->Lifecycle().GetState());

  // Mutating the throttled frame followed by a beginFrame will not result in
  // a complete lifecycle update.
  // TODO(skyostil): these expectations are either wrong, or the test is
  // not exercising the code correctly. PaintClean means the entire lifecycle
  // ran.
  frame_element->setAttribute(kWidthAttr, "50");
  CompositeFrame();

  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
    EXPECT_EQ(DocumentLifecycle::kPaintClean,
              frame_document->Lifecycle().GetState());

    // A hit test will not force a complete lifecycle update.
    WebView().HitTestResultAt(gfx::Point());
    EXPECT_EQ(DocumentLifecycle::kPaintClean,
              frame_document->Lifecycle().GetState());
  } else {
    // TODO(chrishtr): fix this test by manually resetting to
    // kVisualUpdatePending before call to CompositeFrame.
    EXPECT_EQ(DocumentLifecycle::kPaintClean,
              frame_document->Lifecycle().GetState());

    // A hit test will not force a complete lifecycle update.
    WebView().HitTestResultAt(gfx::Point());
    EXPECT_EQ(DocumentLifecycle::kPaintClean,
              frame_document->Lifecycle().GetState());
  }
}

TEST_P(FrameThrottlingTest, UnthrottlingFrameSchedulesAnimation) {
  SimRequest main_resource("https://example.com/", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe sandbox id=frame></iframe>");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));

  // First make the child hidden to enable throttling.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_FALSE(Compositor().NeedsBeginFrame());

  // Then bring it back on-screen. This should schedule an animation update.
  frame_element->setAttribute(kStyleAttr, "");
  CompositeFrame();
  EXPECT_TRUE(Compositor().NeedsBeginFrame());
}

TEST_P(FrameThrottlingTest, MutatingThrottledFrameDoesNotCauseAnimation) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete("<style> html { background: red; } </style>");

  // Check that the frame initially shows up.
  auto commands1 = CompositeFrame();
  EXPECT_TRUE(commands1.Contains(SimCanvas::kRect, "red"));

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));

  // Move the frame offscreen to throttle it.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  // Mutating the throttled frame should not cause an animation to be scheduled.
  frame_element->contentDocument()->documentElement()->setAttribute(
      kStyleAttr, "background: green");
  EXPECT_FALSE(Compositor().NeedsBeginFrame());

  // Move the frame back on screen to unthrottle it.
  frame_element->setAttribute(kStyleAttr, "");
  EXPECT_TRUE(Compositor().NeedsBeginFrame());

  // The first frame we composite after unthrottling won't contain the
  // frame's new contents because unthrottling happens at the end of the
  // lifecycle update. We need to do another composite to refresh the frame's
  // contents.
  auto commands2 = CompositeFrame();
  EXPECT_FALSE(commands2.Contains(SimCanvas::kRect, "green"));
  EXPECT_TRUE(Compositor().NeedsBeginFrame());

  auto commands3 = CompositeFrame();
  EXPECT_TRUE(commands3.Contains(SimCanvas::kRect, "green"));
}

TEST_P(FrameThrottlingTest, SynchronousLayoutInThrottledFrame) {
  // Create a hidden frame which is throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete("<div id=div></div>");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));

  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();

  // Change the size of a div in the throttled frame.
  auto* div_element = frame_element->contentDocument()->getElementById("div");
  div_element->setAttribute(kStyleAttr, "width: 50px");

  // Querying the width of the div should do a synchronous layout update even
  // though the frame is being throttled.
  EXPECT_EQ(50, div_element->clientWidth());
}

TEST_P(FrameThrottlingTest, UnthrottlingTriggersRepaint) {
  // Create a hidden frame which is throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete("<style> html { background: green; } </style>");

  // Move the frame offscreen to throttle it.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  // Scroll down to unthrottle the frame. The first frame we composite after
  // scrolling won't contain the frame yet, but will schedule another repaint.
  WebView().MainFrameImpl()->GetFrameView()->LayoutViewport()->SetScrollOffset(
      ScrollOffset(0, 480), kProgrammaticScroll);
  auto commands = CompositeFrame();
  EXPECT_FALSE(commands.Contains(SimCanvas::kRect, "green"));

  // Now the frame contents should be visible again.
  auto commands2 = CompositeFrame();
  EXPECT_TRUE(commands2.Contains(SimCanvas::kRect, "green"));
}

TEST_P(FrameThrottlingTest, UnthrottlingTriggersRepaintInCompositedChild) {
  // Create a hidden frame with a composited child layer.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete(R"HTML(
    <style>
    div {
      width: 100px;
      height: 100px;
      background-color: green;
      transform: translateZ(0);
    }
    </style><div></div>
  )HTML");

  // Move the frame offscreen to throttle it.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  // Scroll down to unthrottle the frame. The first frame we composite after
  // scrolling won't contain the frame yet, but will schedule another repaint.
  WebView().MainFrameImpl()->GetFrameView()->LayoutViewport()->SetScrollOffset(
      ScrollOffset(0, 480), kProgrammaticScroll);
  auto commands = CompositeFrame();
  EXPECT_FALSE(commands.Contains(SimCanvas::kRect, "green"));

  // Now the composited child contents should be visible again.
  auto commands2 = CompositeFrame();
  EXPECT_TRUE(commands2.Contains(SimCanvas::kRect, "green"));
}

TEST_P(FrameThrottlingTest, ChangeStyleInThrottledFrame) {
  // Create a hidden frame which is throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete("<style> html { background: red; } </style>");

  // Move the frame offscreen to throttle it.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  // Change the background color of the frame's contents from red to green.
  frame_element->contentDocument()->body()->setAttribute(kStyleAttr,
                                                         "background: green");

  // Scroll down to unthrottle the frame.
  WebView().MainFrameImpl()->GetFrameView()->LayoutViewport()->SetScrollOffset(
      ScrollOffset(0, 480), kProgrammaticScroll);
  auto commands = CompositeFrame();
  EXPECT_FALSE(commands.Contains(SimCanvas::kRect, "red"));
  EXPECT_FALSE(commands.Contains(SimCanvas::kRect, "green"));

  // Make sure the new style shows up instead of the old one.
  auto commands2 = CompositeFrame();
  EXPECT_TRUE(commands2.Contains(SimCanvas::kRect, "green"));
}

TEST_P(FrameThrottlingTest, ChangeOriginInThrottledFrame) {
  // Create a hidden frame which is throttled.
  SimRequest main_resource("http://example.com/", "text/html");
  SimRequest frame_resource("http://sub.example.com/iframe.html", "text/html");
  LoadURL("http://example.com/");
  main_resource.Complete(
      "<iframe style='position: absolute; top: 10000px' id=frame "
      "src=http://sub.example.com/iframe.html></iframe>");
  frame_resource.Complete("");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));

  CompositeFrame();

  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_TRUE(
      frame_element->contentDocument()->GetFrame()->IsCrossOriginSubframe());
  EXPECT_FALSE(frame_element->contentDocument()
                   ->View()
                   ->GetLayoutView()
                   ->NeedsPaintPropertyUpdate());

  NonThrowableExceptionState exception_state;

  // Security policy requires setting domain on both frames.
  GetDocument().setDomain(String("example.com"), exception_state);
  frame_element->contentDocument()->setDomain(String("example.com"),
                                              exception_state);

  EXPECT_FALSE(
      frame_element->contentDocument()->GetFrame()->IsCrossOriginSubframe());
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_TRUE(frame_element->contentDocument()
                  ->View()
                  ->GetLayoutView()
                  ->NeedsPaintPropertyUpdate());
}

TEST_P(FrameThrottlingTest, ThrottledFrameWithFocus) {
  WebView().GetSettings()->SetJavaScriptEnabled(true);
  ScopedCompositedSelectionUpdateForTest composited_selection_update(true);

  // Create a hidden frame which is throttled and has a text selection.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete(
      "<iframe id=frame sandbox=allow-scripts src=iframe.html></iframe>");
  frame_resource.Complete(
      "some text to select\n"
      "<script>\n"
      "var range = document.createRange();\n"
      "range.selectNode(document.body);\n"
      "window.getSelection().addRange(range);\n"
      "</script>\n");

  // Move the frame offscreen to throttle it.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  // Give the frame focus and do another composite. The selection in the
  // compositor should be cleared because the frame is throttled.
  EXPECT_FALSE(Compositor().HasSelection());
  GetDocument().GetPage()->GetFocusController().SetFocusedFrame(
      frame_element->contentDocument()->GetFrame());
  GetDocument().body()->setAttribute(kStyleAttr, "background: green");
  CompositeFrame();
  EXPECT_FALSE(Compositor().HasSelection());
}

TEST_P(FrameThrottlingTest, ScrollingCoordinatorShouldSkipThrottledFrame) {
  // TODO(crbug.com/809638): Make this test pass for CAP.
  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
    return;

  // Create a hidden frame which is throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete(
      "<style> html { background-image: linear-gradient(red, blue); "
      "background-attachment: fixed; } </style>");

  // Move the frame offscreen to throttle it.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  // Change style of the frame's content to make it in VisualUpdatePending
  // state.
  frame_element->contentDocument()->body()->setAttribute(kStyleAttr,
                                                         "background: green");
  // Change root frame's layout so that the next lifecycle update will call
  // ScrollingCoordinator::UpdateAfterPaint().
  GetDocument().body()->setAttribute(kStyleAttr, "margin: 20px");
  EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
            frame_element->contentDocument()->Lifecycle().GetState());

  DocumentLifecycle::AllowThrottlingScope throttling_scope(
      GetDocument().Lifecycle());
  // This will call ScrollingCoordinator::UpdateAfterPaint() and should not
  // cause assert failure about isAllowedToQueryCompositingState() in the
  // throttled frame.
  UpdateAllLifecyclePhases();
  test::RunPendingTasks();
  EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
            frame_element->contentDocument()->Lifecycle().GetState());
  // The fixed background in the throttled sub frame should not cause main
  // thread scrolling.
  EXPECT_FALSE(
      GetDocument().View()->LayoutViewport()->ShouldScrollOnMainThread());

  // Make the frame visible by changing its transform. This doesn't cause a
  // layout, but should still unthrottle the frame.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(0px)");
  CompositeFrame();
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  // The fixed background in the throttled sub frame should be considered.
  EXPECT_TRUE(frame_element->contentDocument()
                  ->View()
                  ->LayoutViewport()
                  ->ShouldScrollOnMainThread());
  EXPECT_FALSE(
      GetDocument().View()->LayoutViewport()->ShouldScrollOnMainThread());
}

TEST_P(FrameThrottlingTest, ScrollingCoordinatorShouldSkipThrottledLayer) {
  WebView().GetSettings()->SetJavaScriptEnabled(true);
  WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);

  // Create a hidden frame which is throttled and has a touch handler inside a
  // composited layer.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete(
      "<iframe id=frame sandbox=allow-scripts src=iframe.html></iframe>");
  frame_resource.Complete(
      "<div id=div style='transform: translateZ(0)' ontouchstart='foo()'>touch "
      "handler</div>");

  // Move the frame offscreen to throttle it.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  // Change style of the frame's content to make it in VisualUpdatePending
  // state.
  frame_element->contentDocument()->body()->setAttribute(kStyleAttr,
                                                         "background: green");
  // Change root frame's layout so that the next lifecycle update will call
  // ScrollingCoordinator::UpdateAfterPaint().
  GetDocument().body()->setAttribute(kStyleAttr, "margin: 20px");
  EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
            frame_element->contentDocument()->Lifecycle().GetState());

  DocumentLifecycle::AllowThrottlingScope throttling_scope(
      GetDocument().Lifecycle());
  // This will call ScrollingCoordinator::UpdateAfterPaint() and should not
  // cause an assert failure about isAllowedToQueryCompositingState() in the
  // throttled frame.
  UpdateAllLifecyclePhases();
  test::RunPendingTasks();
  EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
            frame_element->contentDocument()->Lifecycle().GetState());
}

TEST_P(FrameThrottlingTest,
       ScrollingCoordinatorShouldSkipCompositedThrottledFrame) {
  // TODO(crbug.com/922419): The test is broken for LayoutNG.
  if (RuntimeEnabledFeatures::LayoutNGEnabled())
    return;

  WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);

  // Create a hidden frame which is throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete("<div style='height: 2000px'></div>");

  // Move the frame offscreen to throttle it.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  // Change style of the frame's content to make it in VisualUpdatePending
  // state.
  frame_element->contentDocument()->body()->setAttribute(kStyleAttr,
                                                         "background: green");
  // Change root frame's layout so that the next lifecycle update will call
  // ScrollingCoordinator::UpdateAfterPaint().
  GetDocument().body()->setAttribute(kStyleAttr, "margin: 20px");
  EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
            frame_element->contentDocument()->Lifecycle().GetState());

  DocumentLifecycle::AllowThrottlingScope throttling_scope(
      GetDocument().Lifecycle());
  // This will call ScrollingCoordinator::UpdateAfterPaint() and should not
  // cause an assert failure about isAllowedToQueryCompositingState() in the
  // throttled frame.
  CompositeFrame();
  EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
            frame_element->contentDocument()->Lifecycle().GetState());

  // Make the frame visible by changing its transform. This doesn't cause a
  // layout, but should still unthrottle the frame.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(0px)");
  CompositeFrame();  // Unthrottle the frame.

  EXPECT_FALSE(
      frame_element->contentDocument()->View()->ShouldThrottleRendering());
  CompositeFrame();  // Handle the pending visual update of the unthrottled
                     // frame.
  EXPECT_EQ(DocumentLifecycle::kPaintClean,
            frame_element->contentDocument()->Lifecycle().GetState());
  // TODO(szager): Re-enable this check for CAP when it properly sets the
  // bits for composited scrolling.
  if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
    EXPECT_TRUE(frame_element->contentDocument()
                    ->View()
                    ->LayoutViewport()
                    ->UsesCompositedScrolling());
  }
}

TEST_P(FrameThrottlingTest, UnthrottleByTransformingWithoutLayout) {
  // Create a hidden frame which is throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete("");

  // Move the frame offscreen to throttle it.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  // Make the frame visible by changing its transform. This doesn't cause a
  // layout, but should still unthrottle the frame.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(0px)");
  CompositeFrame();
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
}

TEST_P(FrameThrottlingTest, ThrottledTopLevelEventHandlerIgnored) {
  // TODO(crbug.com/809638): Make this test pass for CAP.
  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
    return;

  WebView().GetSettings()->SetJavaScriptEnabled(true);
  EXPECT_EQ(0u, TouchHandlerRegionSize());

  // Create a frame which is throttled and has two different types of
  // top-level touchstart handlers.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete(
      "<iframe id=frame sandbox=allow-scripts src=iframe.html></iframe>");
  frame_resource.Complete(R"HTML(
    <script>
    window.addEventListener('touchstart', function(){}, {passive: false});
    document.addEventListener('touchstart', function(){}, {passive: false});
    </script>
  )HTML");
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  DocumentLifecycle::AllowThrottlingScope throttling_scope(
      GetDocument().Lifecycle());
  CompositeFrame();  // Throttle the frame.
  CompositeFrame();  // Update touch handler regions.

  // In here, throttle iframe doesn't throttle the main frame.
  EXPECT_TRUE(
      frame_element->contentDocument()->View()->ShouldThrottleRendering());
  EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());

  // In this test, the iframe has the same origin as the main frame, so we have
  // two documents but one graphics layer tree. The test throttles the iframe
  // document only. In ScrollingCoordinator::UpdateLayerTouchActionRects, we
  // check whether the document associated with a certain grahpics layer is
  // throttled or not. Since the layers are associated with the main document
  // which is not throttled, we expect the main document to have one touch
  // handler region.
  // In the Non-PaintTouchActionRects world, the
  // AccumulateDocumentTouchEventTargetRects goes through every document and
  // check whether the document is throttled or not. So we expect no touch
  // handler region.
  if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
    EXPECT_EQ(1u, TouchHandlerRegionSize());
  else
    EXPECT_EQ(0u, TouchHandlerRegionSize());

  // Unthrottling the frame makes the touch handlers active again. Note that
  // both handlers get combined into the same rectangle in the region, so
  // there is only one rectangle in total.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(0px)");
  CompositeFrame();  // Unthrottle the frame.
  CompositeFrame();  // Update touch handler regions.
  EXPECT_EQ(1u, TouchHandlerRegionSize());
}

TEST_P(FrameThrottlingTest, ThrottledEventHandlerIgnored) {
  // TODO(crbug.com/809638): Make this test pass for CAP.
  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
    return;

  WebView().GetSettings()->SetJavaScriptEnabled(true);
  EXPECT_EQ(0u, TouchHandlerRegionSize());

  // Create a frame which is throttled and has a non-top-level touchstart
  // handler.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete(
      "<iframe id=frame sandbox=allow-scripts src=iframe.html></iframe>");
  frame_resource.Complete(R"HTML(
    <div id=d>touch handler</div>
    <script>
    document.querySelector('#d').addEventListener('touchstart',
    function(){});
    </script>
  )HTML");
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  DocumentLifecycle::AllowThrottlingScope throttling_scope(
      GetDocument().Lifecycle());
  CompositeFrame();  // Throttle the frame.
  CompositeFrame();  // Update touch handler regions.

  // In here, throttle iframe doesn't throttle the main frame.
  EXPECT_TRUE(
      frame_element->contentDocument()->View()->ShouldThrottleRendering());
  EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering());

  // In this test, the iframe has the same origin as the main frame, so we have
  // two documents but one graphics layer tree. The test throttles the iframe
  // document only. In ScrollingCoordinator::UpdateLayerTouchActionRects, we
  // check whether the document associated with a certain grahpics layer is
  // throttled or not. Since the layers are associated with the main document
  // which is not throttled, we expect the main document to have one touch
  // handler region.
  // In the Non-PaintTouchActionRects world, the
  // AccumulateDocumentTouchEventTargetRects goes through every document and
  // check whether the document is throttled or not. So we expect no touch
  // handler region.
  if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
    EXPECT_EQ(1u, TouchHandlerRegionSize());
  else
    EXPECT_EQ(0u, TouchHandlerRegionSize());

  // Unthrottling the frame makes the touch handler active again.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(0px)");
  CompositeFrame();  // Unthrottle the frame.
  CompositeFrame();  // Update touch handler regions.
  EXPECT_EQ(1u, TouchHandlerRegionSize());
}

TEST_P(FrameThrottlingTest, DumpThrottledFrame) {
  WebView().GetSettings()->SetJavaScriptEnabled(true);

  // Create a frame which is throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete(
      "main <iframe id=frame sandbox=allow-scripts src=iframe.html></iframe>");
  frame_resource.Complete("");
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  LocalFrame* local_frame = ToLocalFrame(frame_element->ContentFrame());
  local_frame->GetScriptController().ExecuteScriptInMainWorld(
      "document.body.innerHTML = 'throttled'");
  EXPECT_FALSE(Compositor().NeedsBeginFrame());

  // The dumped contents should not include the throttled frame.
  DocumentLifecycle::AllowThrottlingScope throttling_scope(
      GetDocument().Lifecycle());
  WebString result = WebFrameContentDumper::DumpWebViewAsText(&WebView(), 1024);
  EXPECT_NE(std::string::npos, result.Utf8().find("main"));
  EXPECT_EQ(std::string::npos, result.Utf8().find("throttled"));
}

TEST_P(FrameThrottlingTest, PaintingViaGraphicsLayerIsThrottled) {
  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
    return;

  WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);

  // Create a hidden frame which is throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete("throttled");

  // Before the iframe is throttled, we should create all drawing items.
  auto commands_not_throttled = CompositeFrame();
  EXPECT_EQ(6u, commands_not_throttled.DrawCount());

  // Move the frame offscreen to throttle it and make sure it is backed by a
  // graphics layer.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr,
                              "transform: translateY(480px) translateZ(0px)");
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  // If painting of the iframe is throttled, we should only receive drawing
  // commands for the main frame.
  auto commands_throttled = Compositor().PaintFrame();
  EXPECT_EQ(5u, commands_throttled.DrawCount());
  EXPECT_FALSE(Compositor().NeedsBeginFrame());
}

TEST_P(FrameThrottlingTest, ThrottleInnerCompositedLayer) {
  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
    return;

  WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);

  // Create a hidden frame which is throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete(
      "<div id=div style='will-change: transform; background: blue'>DIV</div>");
  auto commands_not_throttled = CompositeFrame();

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  // The inner div is composited.
  auto* inner_div = frame_element->contentDocument()->getElementById("div");
  EXPECT_NE(nullptr,
            inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking());

  // Before the iframe is throttled, we should create all drawing commands.
  EXPECT_EQ(7u, commands_not_throttled.DrawCount());

  // Move the frame offscreen to throttle it.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
  // The inner div should still be composited.
  EXPECT_NE(nullptr,
            inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking());

  // If painting of the iframe is throttled, we should only receive drawing
  // commands for the main frame.
  auto commands_throttled = Compositor().PaintFrame();
  EXPECT_EQ(5u, commands_throttled.DrawCount());

  // Remove compositing trigger of inner_div.
  inner_div->setAttribute(kStyleAttr, "background: yellow; overflow: hidden");
  // Do an unthrottled style and layout update, simulating the situation
  // triggered by script style/layout access.
  GetDocument().View()->UpdateLifecycleToLayoutClean();
  {
    // And a throttled full lifecycle update.
    DocumentLifecycle::AllowThrottlingScope throttling_scope(
        GetDocument().Lifecycle());
    UpdateAllLifecyclePhases();
  }
  // The inner div should still be composited because compositing update is
  // throttled, though the inner_div's self-painting status has been updated.
  EXPECT_FALSE(inner_div->GetLayoutBox()->Layer()->IsSelfPaintingLayer());
  {
    DisableCompositingQueryAsserts disabler;
    EXPECT_NE(nullptr,
              inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking());
  }

  auto commands_throttled1 = CompositeFrame();
  EXPECT_EQ(5u, commands_throttled1.DrawCount());

  // Move the frame back on screen.
  frame_element->setAttribute(kStyleAttr, "");
  CompositeFrame();
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  auto commands_not_throttled1 = CompositeFrame();
  // The inner div is no longer composited.
  EXPECT_EQ(nullptr,
            inner_div->GetLayoutBox()->Layer()->GraphicsLayerBacking());

  // After the iframe is unthrottled, we should create all drawing items.
  EXPECT_EQ(7u, commands_not_throttled1.DrawCount());
}

TEST_P(FrameThrottlingTest, ThrottleSubtreeAtomically) {
  // TODO(crbug.com/922419): The test is broken for LayoutNG.
  if (RuntimeEnabledFeatures::LayoutNGEnabled())
    return;

  // Create two nested frames which are throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");
  SimRequest child_frame_resource("https://example.com/child-iframe.html",
                                  "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete(
      "<iframe id=child-frame sandbox src=child-iframe.html></iframe>");
  child_frame_resource.Complete("");

  // Move both frames offscreen, but don't run the intersection observers yet.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* child_frame_element = ToHTMLIFrameElement(
      frame_element->contentDocument()->getElementById("child-frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  Compositor().BeginFrame();
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_FALSE(
      child_frame_element->contentDocument()->View()->CanThrottleRendering());

  // Only run the intersection observer for the parent frame. Both frames
  // should immediately become throttled. This simulates the case where a task
  // such as BeginMainFrame runs in the middle of dispatching intersection
  // observer notifications.
  frame_element->contentDocument()
      ->View()
      ->UpdateRenderThrottlingStatusForTesting();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_TRUE(
      child_frame_element->contentDocument()->View()->CanThrottleRendering());

  // Both frames should still be throttled after the second notification.
  child_frame_element->contentDocument()
      ->View()
      ->UpdateRenderThrottlingStatusForTesting();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_TRUE(
      child_frame_element->contentDocument()->View()->CanThrottleRendering());

  // Move the frame back on screen but don't update throttling yet.
  frame_element->setAttribute(kStyleAttr, "transform: translateY(0px)");
  Compositor().BeginFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_TRUE(
      child_frame_element->contentDocument()->View()->CanThrottleRendering());

  // Update throttling for the child. It should remain throttled because the
  // parent is still throttled.
  child_frame_element->contentDocument()
      ->View()
      ->UpdateRenderThrottlingStatusForTesting();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_TRUE(
      child_frame_element->contentDocument()->View()->CanThrottleRendering());

  // Updating throttling on the parent should unthrottle both frames.
  frame_element->contentDocument()
      ->View()
      ->UpdateRenderThrottlingStatusForTesting();
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_FALSE(
      child_frame_element->contentDocument()->View()->CanThrottleRendering());
}

TEST_P(FrameThrottlingTest, SkipPaintingLayersInThrottledFrames) {
  WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);

  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete(
      "<div id=div style='transform: translateZ(0); background: "
      "red'>layer</div>");
  auto commands = CompositeFrame();
  EXPECT_TRUE(commands.Contains(SimCanvas::kRect, "red"));

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  auto* frame_document = frame_element->contentDocument();
  EXPECT_EQ(DocumentLifecycle::kPaintClean,
            frame_document->Lifecycle().GetState());

  // Simulate the paint for a graphics layer being externally invalidated
  // (e.g., by video playback).
  frame_document->View()
      ->GetLayoutView()
      ->InvalidatePaintForViewAndCompositedLayers();

  // The layer inside the throttled frame should not get painted.
  auto commands2 = CompositeFrame();
  EXPECT_FALSE(commands2.Contains(SimCanvas::kRect, "red"));
}

TEST_P(FrameThrottlingTest, SynchronousLayoutInAnimationFrameCallback) {
  WebView().GetSettings()->SetJavaScriptEnabled(true);

  // Prepare a page with two cross origin frames (from the same origin so they
  // are able to access eachother).
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest first_frame_resource("https://thirdparty.com/first.html",
                                  "text/html");
  SimRequest second_frame_resource("https://thirdparty.com/second.html",
                                   "text/html");
  LoadURL("https://example.com/");
  main_resource.Complete(R"HTML(
    <iframe id=first name=first
    src='https://thirdparty.com/first.html'></iframe>\n
    <iframe id=second name=second
    src='https://thirdparty.com/second.html'></iframe>
  )HTML");

  // The first frame contains just a simple div. This frame will be made
  // throttled.
  first_frame_resource.Complete("<div id=d>first frame</div>");

  // The second frame just used to execute a requestAnimationFrame callback.
  second_frame_resource.Complete("");

  // Throttle the first frame.
  auto* first_frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("first"));
  first_frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_TRUE(
      first_frame_element->contentDocument()->View()->CanThrottleRendering());

  // Run a animation frame callback in the second frame which mutates the
  // contents of the first frame and causes a synchronous style update. This
  // should not result in an unexpected lifecycle state even if the first
  // frame is throttled during the animation frame callback.
  auto* second_frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("second"));
  LocalFrame* local_frame = ToLocalFrame(second_frame_element->ContentFrame());
  local_frame->GetScriptController().ExecuteScriptInMainWorld(
      "window.requestAnimationFrame(function() {\n"
      "  var throttledFrame = window.parent.frames.first;\n"
      "  throttledFrame.document.documentElement.style = 'margin: 50px';\n"
      "  throttledFrame.document.querySelector('#d').getBoundingClientRect();\n"
      "});\n");
  CompositeFrame();
}

TEST_P(FrameThrottlingTest, AllowOneAnimationFrame) {
  WebView().GetSettings()->SetJavaScriptEnabled(true);

  // Prepare a page with two cross origin frames (from the same origin so they
  // are able to access eachother).
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://thirdparty.com/frame.html", "text/html");
  LoadURL("https://example.com/");
  main_resource.Complete(
      "<iframe id=frame style=\"position: fixed; top: -10000px\" "
      "src='https://thirdparty.com/frame.html'></iframe>");

  frame_resource.Complete(R"HTML(
    <script>
    window.requestAnimationFrame(() => { window.didRaf = true; });
    </script>
  )HTML");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());

  LocalFrame* local_frame = ToLocalFrame(frame_element->ContentFrame());
  v8::HandleScope scope(v8::Isolate::GetCurrent());
  v8::Local<v8::Value> result =
      local_frame->GetScriptController().ExecuteScriptInMainWorldAndReturnValue(
          ScriptSourceCode("window.didRaf;"), KURL(),
          SanitizeScriptErrors::kSanitize);
  EXPECT_TRUE(result->IsTrue());
}

TEST_P(FrameThrottlingTest, UpdatePaintPropertiesOnUnthrottling) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete("<div id='div'>Inner</div>");
  CompositeFrame();

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* frame_document = frame_element->contentDocument();
  auto* inner_div = frame_document->getElementById("div");
  auto* inner_div_object = inner_div->GetLayoutObject();
  EXPECT_FALSE(frame_document->View()->ShouldThrottleRendering());

  frame_element->setAttribute(html_names::kStyleAttr,
                              "transform: translateY(1000px)");
  CompositeFrame();
  EXPECT_TRUE(frame_document->View()->CanThrottleRendering());
  EXPECT_FALSE(inner_div_object->FirstFragment().PaintProperties());

  // Mutating the throttled frame should not cause paint property update.
  inner_div->setAttribute(html_names::kStyleAttr,
                          "transform: translateY(20px)");
  EXPECT_FALSE(Compositor().NeedsBeginFrame());
  EXPECT_TRUE(frame_document->View()->CanThrottleRendering());
  {
    DocumentLifecycle::AllowThrottlingScope throttling_scope(
        GetDocument().Lifecycle());
    UpdateAllLifecyclePhases();
  }
  EXPECT_FALSE(inner_div_object->FirstFragment().PaintProperties());

  // Move the frame back on screen to unthrottle it.
  frame_element->setAttribute(html_names::kStyleAttr, "");
  // The first update unthrottles the frame, the second actually update layout
  // and paint properties etc.
  CompositeFrame();
  CompositeFrame();
  EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
  EXPECT_EQ(TransformationMatrix().Translate(0, 20),
            inner_div->GetLayoutObject()
                ->FirstFragment()
                .PaintProperties()
                ->Transform()
                ->Matrix());
}

TEST_P(FrameThrottlingTest, DisplayNoneNotThrottled) {
  SimRequest main_resource("https://example.com/", "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete(
      "<style>iframe { transform: translateY(480px); }</style>"
      "<iframe sandbox id=frame></iframe>");

  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* frame_document = frame_element->contentDocument();

  // Initially the frame is throttled as it is offscreen.
  CompositeFrame();
  EXPECT_TRUE(frame_document->View()->CanThrottleRendering());

  // Setting display:none unthrottles the frame.
  frame_element->setAttribute(kStyleAttr, "display: none");
  CompositeFrame();
  EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
}

TEST_P(FrameThrottlingTest, DisplayNoneChildrenRemainThrottled) {
  // Create two nested frames which are throttled.
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");
  SimRequest child_frame_resource("https://example.com/child-iframe.html",
                                  "text/html");

  LoadURL("https://example.com/");
  main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
  frame_resource.Complete(
      "<iframe id=child-frame sandbox src=child-iframe.html></iframe>");
  child_frame_resource.Complete("");

  // Move both frames offscreen to make them throttled.
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* child_frame_element = ToHTMLIFrameElement(
      frame_element->contentDocument()->getElementById("child-frame"));
  frame_element->setAttribute(kStyleAttr, "transform: translateY(480px)");
  CompositeFrame();
  EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_TRUE(
      child_frame_element->contentDocument()->View()->CanThrottleRendering());

  // Setting display:none for the parent frame unthrottles the parent but not
  // the child. This behavior matches Safari.
  frame_element->setAttribute(kStyleAttr, "display: none");
  CompositeFrame();
  EXPECT_FALSE(
      frame_element->contentDocument()->View()->CanThrottleRendering());
  EXPECT_TRUE(
      child_frame_element->contentDocument()->View()->CanThrottleRendering());
}

TEST_P(FrameThrottlingTest, RebuildCompositedLayerTreeOnLayerRemoval) {
  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
    return;

  // This test verifies removal of PaintLayer due to style change will force
  // unthrottling a frame. This is because destructing PaintLayer would cause
  // CompositedLayerMapping and composited layers to be destructed and detach
  // from layer tree immediately. Layers could have dangling scroll/clip
  // parent if compositing update were omitted.
  WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);

  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");
  LoadURL("https://example.com/");
  main_resource.Complete(
      "<iframe sandbox id='frame' src='iframe.html' style='position:relative; "
      "top:1000px;'></iframe>");
  frame_resource.Complete(R"HTML(
    <div id='scroller' style='overflow:scroll; width:300px; height:200px;'>
      <div style='height:1000px;'></div>
      <div id='sibling' style='transform:translateZ(0);'>Foo</div>
    </div>
  )HTML");

  CompositeFrame();
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  {
    DocumentLifecycle::AllowThrottlingScope throttling_scope(
        GetDocument().Lifecycle());
    EXPECT_TRUE(
        frame_element->contentDocument()->View()->ShouldThrottleRendering());
  }

  auto* scroller_element =
      frame_element->contentDocument()->getElementById("scroller");
  ASSERT_TRUE(scroller_element->GetLayoutObject()->HasLayer());
  auto* scroller_layer =
      ToLayoutBoxModelObject(scroller_element->GetLayoutObject())->Layer();
  EXPECT_TRUE(scroller_layer->NeedsCompositedScrolling());

  auto* sibling_element =
      frame_element->contentDocument()->getElementById("sibling");
  ASSERT_TRUE(sibling_element->GetLayoutObject()->HasLayer());
  auto* sibling_layer =
      ToLayoutBoxModelObject(sibling_element->GetLayoutObject())->Layer();
  auto* sibling_clm = sibling_layer->GetCompositedLayerMapping();
  ASSERT_TRUE(sibling_clm);

  scroller_element->setAttribute(kStyleAttr, "overflow:visible;");
  EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
            frame_element->contentDocument()->Lifecycle().GetState());

  // This simulates a javascript query to layout results, e.g.
  // document.body.offsetTop, which will force style & layout to be computed,
  // whether the frame is throttled or not.
  frame_element->contentDocument()
      ->UpdateStyleAndLayoutIgnorePendingStylesheets();
  EXPECT_EQ(DocumentLifecycle::kLayoutClean,
            frame_element->contentDocument()->Lifecycle().GetState());
  {
    DocumentLifecycle::AllowThrottlingScope throttling_scope(
        GetDocument().Lifecycle());
    EXPECT_FALSE(
        frame_element->contentDocument()->View()->ShouldThrottleRendering());
  }

  CompositeFrame();
  {
    DocumentLifecycle::AllowThrottlingScope throttling_scope(
        GetDocument().Lifecycle());
    EXPECT_TRUE(
        frame_element->contentDocument()->View()->ShouldThrottleRendering());
  }
  EXPECT_EQ(DocumentLifecycle::kCompositingClean,
            frame_element->contentDocument()->Lifecycle().GetState());
}

TEST_P(FrameThrottlingTest, LifecycleUpdateAfterUnthrottledCompositingUpdate) {
  SimRequest main_resource("https://example.com/", "text/html");
  SimRequest frame_resource("https://example.com/iframe.html", "text/html");

  LoadURL("https://example.com/");
  // The frame is initially throttled.
  main_resource.Complete(R"HTML(
    <iframe id='frame' sandbox src='iframe.html'
        style='transform: translateY(480px)'></iframe>
  )HTML");
  frame_resource.Complete("<div id='div'>Foo</div>");

  CompositeFrame();
  auto* frame_element =
      ToHTMLIFrameElement(GetDocument().getElementById("frame"));
  auto* frame_document = frame_element->contentDocument();
  EXPECT_TRUE(frame_document->View()->CanThrottleRendering());
  EXPECT_FALSE(frame_document->View()->ShouldThrottleRendering());

  frame_document->getElementById("div")->setAttribute(kStyleAttr,
                                                      "will-change: transform");
  GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling();

  {
    // Then do a full lifecycle with throttling enabled. This should not crash.
    DocumentLifecycle::AllowThrottlingScope throttling_scope(
        GetDocument().Lifecycle());
    EXPECT_TRUE(frame_document->View()->ShouldThrottleRendering());
    UpdateAllLifecyclePhases();
  }
}

}  // namespace blink
