// Copyright 2014 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 "third_party/blink/renderer/core/frame/remote_frame_view.h"

#include "third_party/blink/renderer/core/dom/element_visibility_observer.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/remote_frame.h"
#include "third_party/blink/renderer/core/frame/remote_frame_client.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"

namespace blink {

RemoteFrameView::RemoteFrameView(RemoteFrame* remote_frame)
    : remote_frame_(remote_frame), is_attached_(false) {
  DCHECK(remote_frame);
}

RemoteFrameView::~RemoteFrameView() = default;

LocalFrameView* RemoteFrameView::ParentFrameView() const {
  if (!is_attached_)
    return nullptr;

  Frame* parent_frame = remote_frame_->Tree().Parent();
  if (parent_frame && parent_frame->IsLocalFrame())
    return ToLocalFrame(parent_frame)->View();

  return nullptr;
}

void RemoteFrameView::AttachToLayout() {
  DCHECK(!is_attached_);
  is_attached_ = true;
  if (ParentFrameView()->IsVisible())
    SetParentVisible(true);

  SetupRenderThrottling();
  subtree_throttled_ = ParentFrameView()->CanThrottleRendering();

  FrameRectsChanged();
}

void RemoteFrameView::DetachFromLayout() {
  DCHECK(is_attached_);
  SetParentVisible(false);
  is_attached_ = false;
}

RemoteFrameView* RemoteFrameView::Create(RemoteFrame* remote_frame) {
  RemoteFrameView* view = new RemoteFrameView(remote_frame);
  view->Show();
  return view;
}

void RemoteFrameView::UpdateViewportIntersectionsForSubtree() {
  LayoutEmbeddedContent* owner = remote_frame_->OwnerLayoutObject();
  if (!owner)
    return;

  LocalFrameView* local_root_view =
      ToLocalFrame(remote_frame_->Tree().Parent())->LocalFrameRoot().View();
  if (!local_root_view)
    return;

  IntRect viewport_intersection;
  bool occluded_or_obscured = false;
  DocumentLifecycle::LifecycleState parent_state =
      owner->GetDocument().Lifecycle().GetState();

  // If the parent LocalFrameView is throttled and out-of-date, then we can't
  // get any useful information.
  if (parent_state >= DocumentLifecycle::kLayoutClean) {
    // Start with rect in remote frame's coordinate space. Then
    // mapToVisualRectInAncestorSpace will move it to the local root's
    // coordinate space and account for any clip from containing elements such
    // as a scrollable div. Passing nullptr as an argument to
    // mapToVisualRectInAncestorSpace causes it to be clipped to the viewport,
    // even if there are RemoteFrame ancestors in the frame tree.
    LayoutRect rect(0, 0, frame_rect_.Width(), frame_rect_.Height());
    rect.Move(owner->PhysicalContentBoxOffset());
    if (owner->MapToVisualRectInAncestorSpace(nullptr, rect,
                                              kUseGeometryMapper)) {
      IntRect root_visible_rect(IntPoint(), local_root_view->Size());
      IntRect intersected_rect = EnclosingIntRect(rect);
      intersected_rect.Intersect(root_visible_rect);

      // Translate the intersection rect from the root frame's coordinate space
      // to the remote frame's coordinate space.
      FloatRect viewport_intersection_float =
          remote_frame_->OwnerLayoutObject()
              ->AncestorToLocalQuad(
                  local_root_view->GetLayoutView(), FloatQuad(intersected_rect),
                  kTraverseDocumentBoundaries | kUseTransforms)
              .BoundingBox();
      viewport_intersection_float.Move(
          -remote_frame_->OwnerLayoutObject()->PhysicalContentBoxOffset());
      viewport_intersection = EnclosingIntRect(viewport_intersection_float);
    }
  }

  if (parent_state >= DocumentLifecycle::kPrePaintClean &&
      RuntimeEnabledFeatures::IntersectionObserverV2Enabled()) {
    // TODO(layout-dev): As an optimization, we should only check for
    // occlusion and effects if the remote frame needs it, i.e., if it has at
    // least one active IntersectionObserver with trackVisibility:true.
    if (owner->GetDocument()
            .GetFrame()
            ->LocalFrameRoot()
            .MayBeOccludedOrObscuredByRemoteAncestor() ||
        owner->HasDistortingVisualEffects()) {
      occluded_or_obscured = true;
    } else {
      HitTestResult result(owner->HitTestForOcclusion());
      occluded_or_obscured =
          result.InnerNode() && result.InnerNode() != owner->GetNode();
    }
  }

  if (viewport_intersection == last_viewport_intersection_ &&
      occluded_or_obscured == last_occluded_or_obscured_) {
    return;
  }

  last_viewport_intersection_ = viewport_intersection;
  last_occluded_or_obscured_ = occluded_or_obscured;
  remote_frame_->Client()->UpdateRemoteViewportIntersection(
      viewport_intersection, occluded_or_obscured);
}

IntRect RemoteFrameView::GetCompositingRect() {
  LocalFrameView* local_root_view =
      ToLocalFrame(remote_frame_->Tree().Parent())->LocalFrameRoot().View();
  if (!local_root_view || !remote_frame_->OwnerLayoutObject())
    return IntRect();

  // For main frames we constrain the rect that gets painted to the viewport.
  // If the local frame root is an OOPIF itself, then we use the root's
  // intersection rect. This represents a conservative maximum for the area
  // that needs to be rastered by the OOPIF compositor.
  IntSize viewport_size = local_root_view->FrameRect().Size();
  if (local_root_view->GetPage()->MainFrame() != local_root_view->GetFrame()) {
    viewport_size =
        local_root_view->GetFrame().RemoteViewportIntersection().Size();
  }

  // The viewport size needs to account for intermediate CSS transforms before
  // being compared to the frame size.
  FloatQuad viewport_quad =
      remote_frame_->OwnerLayoutObject()->AncestorToLocalQuad(
          local_root_view->GetLayoutView(),
          FloatRect(FloatPoint(), FloatSize(viewport_size)),
          kTraverseDocumentBoundaries | kUseTransforms);
  IntSize converted_viewport_size =
      EnclosingIntRect(viewport_quad.BoundingBox()).Size();

  IntSize frame_size = FrameRect().Size();

  // Iframes that fit within the window viewport get fully rastered. For
  // iframes that are larger than the window viewport, add a 30% buffer to the
  // draw area to try to prevent guttering during scroll.
  // TODO(kenrb): The 30% value is arbitrary, it gives 15% overdraw in both
  // directions when the iframe extends beyond both edges of the viewport, and
  // it seems to make guttering rare with slow to medium speed wheel scrolling.
  // Can we collect UMA data to estimate how much extra rastering this causes,
  // and possibly how common guttering is?
  converted_viewport_size.Scale(1.3f);
  converted_viewport_size.SetWidth(
      std::min(frame_size.Width(), converted_viewport_size.Width()));
  converted_viewport_size.SetHeight(
      std::min(frame_size.Height(), converted_viewport_size.Height()));
  IntPoint expanded_origin;
  if (!last_viewport_intersection_.IsEmpty()) {
    IntSize expanded_size =
        last_viewport_intersection_.Size().ExpandedTo(converted_viewport_size);
    expanded_size -= last_viewport_intersection_.Size();
    expanded_size.Scale(0.5f, 0.5f);
    expanded_origin = last_viewport_intersection_.Location() - expanded_size;
    expanded_origin.ClampNegativeToZero();
  }
  return IntRect(expanded_origin, converted_viewport_size);
}

void RemoteFrameView::Dispose() {
  HTMLFrameOwnerElement* owner_element = remote_frame_->DeprecatedLocalOwner();
  // ownerElement can be null during frame swaps, because the
  // RemoteFrameView is disconnected before detachment.
  if (owner_element && owner_element->OwnedEmbeddedContentView() == this)
    owner_element->SetEmbeddedContentView(nullptr);
}

void RemoteFrameView::InvalidateRect(const IntRect& rect) {
  auto* object = remote_frame_->OwnerLayoutObject();
  if (!object)
    return;

  LayoutRect repaint_rect(rect);
  repaint_rect.Move(object->BorderLeft() + object->PaddingLeft(),
                    object->BorderTop() + object->PaddingTop());
  object->InvalidatePaintRectangle(repaint_rect);
}

void RemoteFrameView::SetFrameRect(const IntRect& frame_rect) {
  if (frame_rect == frame_rect_)
    return;

  frame_rect_ = frame_rect;
  FrameRectsChanged();
}

IntRect RemoteFrameView::FrameRect() const {
  IntPoint location(frame_rect_.Location());

  // As an optimization, we don't include the root layer's scroll offset in the
  // frame rect.  As a result, we don't need to recalculate the frame rect every
  // time the root layer scrolls, but we need to add it in here.
  LayoutEmbeddedContent* owner = remote_frame_->OwnerLayoutObject();
  if (owner) {
    LayoutView* owner_layout_view = owner->View();
    DCHECK(owner_layout_view);
    if (owner_layout_view->HasOverflowClip()) {
      IntSize scroll_offset(owner_layout_view->ScrolledContentOffset());
      location.SaturatedMove(-scroll_offset.Width(), -scroll_offset.Height());
    }
  }

  return IntRect(location, frame_rect_.Size());
}

void RemoteFrameView::FrameRectsChanged() {
  // Update the rect to reflect the position of the frame relative to the
  // containing local frame root. The position of the local root within
  // any remote frames, if any, is accounted for by the embedder.
  IntRect frame_rect(FrameRect());
  IntRect screen_space_rect = frame_rect;

  if (LocalFrameView* parent = ParentFrameView()) {
    screen_space_rect = parent->ConvertToRootFrame(screen_space_rect);
  }
  remote_frame_->Client()->FrameRectsChanged(frame_rect, screen_space_rect);
}

void RemoteFrameView::Paint(GraphicsContext& context,
                            const GlobalPaintFlags flags,
                            const CullRect& rect,
                            const IntSize& paint_offset) const {
  // Painting remote frames is only for printing.
  if (!context.Printing())
    return;

  if (!rect.Intersects(FrameRect()))
    return;

  DrawingRecorder recorder(context, *GetFrame().OwnerLayoutObject(),
                           DisplayItem::kDocumentBackground);
  context.Save();
  context.Translate(paint_offset.Width(), paint_offset.Height());

  DCHECK(context.Canvas());
  // Inform the remote frame to print.
  uint32_t content_id = Print(FrameRect(), context.Canvas());

  // Record the place holder id on canvas.
  context.Canvas()->recordCustomData(content_id);
  context.Restore();
}

void RemoteFrameView::UpdateGeometry() {
  if (LayoutEmbeddedContent* layout = remote_frame_->OwnerLayoutObject())
    layout->UpdateGeometry(*this);
}

void RemoteFrameView::Hide() {
  self_visible_ = false;
  remote_frame_->Client()->VisibilityChanged(false);
}

void RemoteFrameView::Show() {
  self_visible_ = true;
  remote_frame_->Client()->VisibilityChanged(true);
}

void RemoteFrameView::SetParentVisible(bool visible) {
  if (parent_visible_ == visible)
    return;

  parent_visible_ = visible;
  if (!self_visible_)
    return;

  remote_frame_->Client()->VisibilityChanged(self_visible_ && parent_visible_);
}

void RemoteFrameView::SetupRenderThrottling() {
  if (visibility_observer_)
    return;

  Element* target_element = GetFrame().DeprecatedLocalOwner();
  if (!target_element)
    return;

  visibility_observer_ = MakeGarbageCollected<ElementVisibilityObserver>(
      target_element, WTF::BindRepeating(
                          [](RemoteFrameView* remote_view, bool is_visible) {
                            remote_view->UpdateRenderThrottlingStatus(
                                !is_visible, remote_view->subtree_throttled_);
                          },
                          WrapWeakPersistent(this)));
  visibility_observer_->Start();
}

void RemoteFrameView::UpdateRenderThrottlingStatus(bool hidden,
                                                   bool subtree_throttled) {
  TRACE_EVENT0("blink", "RemoteFrameView::UpdateRenderThrottlingStatus");
  if (!remote_frame_->Client())
    return;

  bool was_throttled = CanThrottleRendering();

  // Note that we disallow throttling of 0x0 and display:none frames because
  // some sites use them to drive UI logic.
  HTMLFrameOwnerElement* owner_element = remote_frame_->DeprecatedLocalOwner();
  hidden_for_throttling_ = hidden && !frame_rect_.IsEmpty() &&
                           (owner_element && owner_element->GetLayoutObject());
  subtree_throttled_ = subtree_throttled;

  bool is_throttled = CanThrottleRendering();
  if (was_throttled != is_throttled) {
    remote_frame_->Client()->UpdateRenderThrottlingStatus(is_throttled,
                                                          subtree_throttled_);
  }
}

bool RemoteFrameView::CanThrottleRendering() const {
  if (!RuntimeEnabledFeatures::RenderingPipelineThrottlingEnabled())
    return false;
  if (subtree_throttled_)
    return true;
  return hidden_for_throttling_;
}

void RemoteFrameView::SetIntrinsicSizeInfo(
    const IntrinsicSizingInfo& size_info) {
  intrinsic_sizing_info_ = size_info;
  has_intrinsic_sizing_info_ = true;
}

bool RemoteFrameView::GetIntrinsicSizingInfo(
    IntrinsicSizingInfo& sizing_info) const {
  if (!has_intrinsic_sizing_info_)
    return false;

  sizing_info = intrinsic_sizing_info_;
  return true;
}

bool RemoteFrameView::HasIntrinsicSizingInfo() const {
  return has_intrinsic_sizing_info_;
}

uint32_t RemoteFrameView::Print(const IntRect& rect,
                                cc::PaintCanvas* canvas) const {
  return remote_frame_->Client()->Print(rect, canvas);
}

void RemoteFrameView::Trace(blink::Visitor* visitor) {
  visitor->Trace(remote_frame_);
  visitor->Trace(visibility_observer_);
}

}  // namespace blink
