// 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 "content/renderer/render_frame_proxy.h"

#include <stdint.h>
#include <map>
#include <utility>

#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "components/viz/common/features.h"
#include "content/common/content_switches_internal.h"
#include "content/common/frame_messages.h"
#include "content/common/frame_owner_properties.h"
#include "content/common/frame_replication_state.h"
#include "content/common/input_messages.h"
#include "content/common/page_messages.h"
#include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/screen_info.h"
#include "content/renderer/child_frame_compositing_helper.h"
#include "content/renderer/frame_owner_properties.h"
#include "content/renderer/loader/web_url_request_util.h"
#include "content/renderer/mash_util.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "content/renderer/render_widget.h"
#include "content/renderer/resource_timing_info_conversions.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/WebKit/common/feature_policy/feature_policy.h"
#include "third_party/WebKit/common/frame_policy.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebRect.h"
#include "third_party/WebKit/public/platform/WebResourceTimingInfo.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebTriggeringEventInfo.h"
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "ui/base/ui_base_switches_util.h"

#if defined(USE_AURA)
#include "content/renderer/mus/mus_embedded_frame.h"
#include "content/renderer/mus/renderer_window_tree_client.h"
#endif

namespace content {

namespace {

// Facilitates lookup of RenderFrameProxy by routing_id.
typedef std::map<int, RenderFrameProxy*> RoutingIDProxyMap;
static base::LazyInstance<RoutingIDProxyMap>::DestructorAtExit
    g_routing_id_proxy_map = LAZY_INSTANCE_INITIALIZER;

// Facilitates lookup of RenderFrameProxy by WebRemoteFrame.
typedef std::map<blink::WebRemoteFrame*, RenderFrameProxy*> FrameProxyMap;
base::LazyInstance<FrameProxyMap>::DestructorAtExit g_frame_proxy_map =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

// static
RenderFrameProxy* RenderFrameProxy::CreateProxyToReplaceFrame(
    RenderFrameImpl* frame_to_replace,
    int routing_id,
    blink::WebTreeScopeType scope) {
  CHECK_NE(routing_id, MSG_ROUTING_NONE);

  std::unique_ptr<RenderFrameProxy> proxy(new RenderFrameProxy(routing_id));
  proxy->unique_name_ = frame_to_replace->unique_name();
  proxy->devtools_frame_token_ = frame_to_replace->GetDevToolsFrameToken();

  // When a RenderFrame is replaced by a RenderProxy, the WebRemoteFrame should
  // always come from WebRemoteFrame::create and a call to WebFrame::swap must
  // follow later.
  blink::WebRemoteFrame* web_frame =
      blink::WebRemoteFrame::Create(scope, proxy.get());

  // If frame_to_replace has a RenderFrameProxy parent, then its
  // RenderWidget will be destroyed along with it, so the new
  // RenderFrameProxy uses its parent's RenderWidget.
  RenderWidget* widget =
      (!frame_to_replace->GetWebFrame()->Parent() ||
       frame_to_replace->GetWebFrame()->Parent()->IsWebLocalFrame())
          ? frame_to_replace->GetRenderWidget()
          : RenderFrameProxy::FromWebFrame(
                frame_to_replace->GetWebFrame()->Parent()->ToWebRemoteFrame())
                ->render_widget();
  proxy->Init(web_frame, frame_to_replace->render_view(), widget);
  return proxy.release();
}

RenderFrameProxy* RenderFrameProxy::CreateFrameProxy(
    int routing_id,
    int render_view_routing_id,
    blink::WebFrame* opener,
    int parent_routing_id,
    const FrameReplicationState& replicated_state) {
  RenderFrameProxy* parent = nullptr;
  if (parent_routing_id != MSG_ROUTING_NONE) {
    parent = RenderFrameProxy::FromRoutingID(parent_routing_id);
    // It is possible that the parent proxy has been detached in this renderer
    // process, just as the parent's real frame was creating this child frame.
    // In this case, do not create the proxy. See https://crbug.com/568670.
    if (!parent)
      return nullptr;
  }

  std::unique_ptr<RenderFrameProxy> proxy(new RenderFrameProxy(routing_id));
  RenderViewImpl* render_view = nullptr;
  RenderWidget* render_widget = nullptr;
  blink::WebRemoteFrame* web_frame = nullptr;

  if (!parent) {
    // Create a top level WebRemoteFrame.
    render_view = RenderViewImpl::FromRoutingID(render_view_routing_id);
    web_frame = blink::WebRemoteFrame::CreateMainFrame(
        render_view->GetWebView(), proxy.get(), opener);
    render_widget = render_view->GetWidget();

    // If the RenderView is reused by this proxy after having been used for a
    // pending RenderFrame that was discarded, its swapped out state needs to
    // be updated, as the OnSwapOut flow which normally does this won't happen
    // in that case.  See https://crbug.com/653746 and
    // https://crbug.com/651980.
    if (!render_view->is_swapped_out())
      render_view->SetSwappedOut(true);
  } else {
    // Create a frame under an existing parent. The parent is always expected
    // to be a RenderFrameProxy, because navigations initiated by local frames
    // should not wind up here.

    web_frame = parent->web_frame()->CreateRemoteChild(
        replicated_state.scope,
        blink::WebString::FromUTF8(replicated_state.name),
        replicated_state.frame_policy.sandbox_flags,
        replicated_state.frame_policy.container_policy, proxy.get(), opener);
    proxy->unique_name_ = replicated_state.unique_name;
    render_view = parent->render_view();
    render_widget = parent->render_widget();
  }

  proxy->Init(web_frame, render_view, render_widget);

  // Initialize proxy's WebRemoteFrame with the security origin and other
  // replicated information.
  // TODO(dcheng): Calling this when parent_routing_id != MSG_ROUTING_NONE is
  // mostly redundant, since we already pass the name and sandbox flags in
  // createLocalChild(). We should update the Blink interface so it also takes
  // the origin. Then it will be clear that the replication call is only needed
  // for the case of setting up a main frame proxy.
  proxy->SetReplicatedState(replicated_state);

  return proxy.release();
}

// static
RenderFrameProxy* RenderFrameProxy::FromRoutingID(int32_t routing_id) {
  RoutingIDProxyMap* proxies = g_routing_id_proxy_map.Pointer();
  RoutingIDProxyMap::iterator it = proxies->find(routing_id);
  return it == proxies->end() ? NULL : it->second;
}

// static
RenderFrameProxy* RenderFrameProxy::FromWebFrame(
    blink::WebRemoteFrame* web_frame) {
  // TODO(dcheng): Turn this into a DCHECK() if it doesn't crash on canary.
  CHECK(web_frame);
  FrameProxyMap::iterator iter = g_frame_proxy_map.Get().find(web_frame);
  if (iter != g_frame_proxy_map.Get().end()) {
    RenderFrameProxy* proxy = iter->second;
    DCHECK_EQ(web_frame, proxy->web_frame());
    return proxy;
  }
  // Reaching this is not expected: this implies that the |web_frame| in
  // question is not managed by the content API, or the associated
  // RenderFrameProxy is already deleted--in which case, it's not safe to touch
  // |web_frame|.
  NOTREACHED();
  return nullptr;
}

RenderFrameProxy::RenderFrameProxy(int routing_id)
    : routing_id_(routing_id),
      provisional_frame_routing_id_(MSG_ROUTING_NONE),
      web_frame_(nullptr),
      render_view_(nullptr),
      render_widget_(nullptr) {
  std::pair<RoutingIDProxyMap::iterator, bool> result =
      g_routing_id_proxy_map.Get().insert(std::make_pair(routing_id_, this));
  CHECK(result.second) << "Inserting a duplicate item.";
  RenderThread::Get()->AddRoute(routing_id_, this);
}

RenderFrameProxy::~RenderFrameProxy() {
  render_widget_->UnregisterRenderFrameProxy(this);

  CHECK(!web_frame_);
  RenderThread::Get()->RemoveRoute(routing_id_);
  g_routing_id_proxy_map.Get().erase(routing_id_);
}

void RenderFrameProxy::Init(blink::WebRemoteFrame* web_frame,
                            RenderViewImpl* render_view,
                            RenderWidget* render_widget) {
  CHECK(web_frame);
  CHECK(render_view);
  CHECK(render_widget);

  web_frame_ = web_frame;
  render_view_ = render_view;
  render_widget_ = render_widget;

  render_widget_->RegisterRenderFrameProxy(this);

  std::pair<FrameProxyMap::iterator, bool> result =
      g_frame_proxy_map.Get().insert(std::make_pair(web_frame_, this));
  CHECK(result.second) << "Inserted a duplicate item.";

  enable_surface_synchronization_ = features::IsSurfaceSynchronizationEnabled();

  compositing_helper_.reset(
      ChildFrameCompositingHelper::CreateForRenderFrameProxy(this));

  pending_resize_params_.screen_info = render_widget_->screen_info();

#if defined(USE_AURA)
  if (IsRunningWithMus()) {
    RendererWindowTreeClient* renderer_window_tree_client =
        RendererWindowTreeClient::Get(render_widget_->routing_id());
    // It's possible a MusEmbeddedFrame has already been scheduled for creation
    // (that is, RendererWindowTreeClient::Embed() was called). Call to
    // OnRenderFrameProxyCreated() to potentially get the MusEmbeddedFrame.
    // OnRenderFrameProxyCreated() returns null if Embed() was not called.
    mus_embedded_frame_ =
        renderer_window_tree_client->OnRenderFrameProxyCreated(this);
  }
#endif
}

void RenderFrameProxy::ResendResizeParams() {
  // Reset |sent_resize_params_| in order to allocate a new viz::LocalSurfaceId.
  sent_resize_params_ = base::nullopt;
  WasResized();
}

void RenderFrameProxy::WillBeginCompositorFrame() {
  if (compositing_helper_->surface_id().is_valid()) {
    FrameHostMsg_HittestData_Params params;
    params.surface_id = compositing_helper_->surface_id();
    params.ignored_for_hittest = web_frame_->IsIgnoredForHitTest();
    render_widget_->QueueMessage(
        new FrameHostMsg_HittestData(render_widget_->routing_id(), params),
        MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE);
  }
}

void RenderFrameProxy::OnScreenInfoChanged(const ScreenInfo& screen_info) {
  pending_resize_params_.screen_info = screen_info;
  WasResized();
}

void RenderFrameProxy::SetReplicatedState(const FrameReplicationState& state) {
  DCHECK(web_frame_);

  web_frame_->SetReplicatedOrigin(
      state.origin, state.has_potentially_trustworthy_unique_origin);

#if DCHECK_IS_ON()
  blink::WebSecurityOrigin security_origin_before_sandbox_flags =
      web_frame_->GetSecurityOrigin();
#endif

  web_frame_->SetReplicatedSandboxFlags(state.active_sandbox_flags);

#if DCHECK_IS_ON()
  // If |state.has_potentially_trustworthy_unique_origin| is set,
  // - |state.origin| should be unique (this is checked in
  //   blink::SecurityOrigin::SetUniqueOriginIsPotentiallyTrustworthy() in
  //   SetReplicatedOrigin()), and thus
  // - The security origin is not updated by SetReplicatedSandboxFlags() and
  //   thus we don't have to apply |has_potentially_trustworthy_unique_origin|
  //   flag after SetReplicatedSandboxFlags().
  if (state.has_potentially_trustworthy_unique_origin)
    DCHECK(security_origin_before_sandbox_flags ==
           web_frame_->GetSecurityOrigin());
#endif

  web_frame_->SetReplicatedName(blink::WebString::FromUTF8(state.name));
  web_frame_->SetReplicatedInsecureRequestPolicy(state.insecure_request_policy);
  web_frame_->SetReplicatedInsecureNavigationsSet(
      state.insecure_navigations_set);
  web_frame_->SetReplicatedFeaturePolicyHeader(state.feature_policy_header);
  if (state.has_received_user_gesture)
    web_frame_->SetHasReceivedUserGesture();
  web_frame_->SetHasReceivedUserGestureBeforeNavigation(
      state.has_received_user_gesture_before_nav);

  web_frame_->ResetReplicatedContentSecurityPolicy();
  OnAddContentSecurityPolicies(state.accumulated_csp_headers);
}

// Update the proxy's FrameOwner with new sandbox flags and container policy
// that were set by its parent in another process.
//
// Normally, when a frame's sandbox attribute is changed dynamically, the
// frame's FrameOwner is updated with the new sandbox flags right away, while
// the frame's SecurityContext is updated when the frame is navigated and the
// new sandbox flags take effect.
//
// Currently, there is no use case for a proxy's pending FrameOwner sandbox
// flags, so there's no message sent to proxies when the sandbox attribute is
// first updated.  Instead, the active flags are updated when they take effect,
// by OnDidSetActiveSandboxFlags. The proxy's FrameOwner flags are updated here
// with the caveat that the FrameOwner won't learn about updates to its flags
// until they take effect.
void RenderFrameProxy::OnDidUpdateFramePolicy(
    const blink::FramePolicy& frame_policy) {
  DCHECK(web_frame()->Parent());
  web_frame_->SetFrameOwnerPolicy(frame_policy.sandbox_flags,
                                  frame_policy.container_policy);
}

// Update the proxy's SecurityContext with new sandbox flags that were set
// during navigation. Unlike changes to the FrameOwner, which are handled by
// OnDidUpdateFramePolicy, these flags should be considered effective
// immediately.
//
// These flags are needed on the remote frame's SecurityContext to ensure that
// sandbox flags are inherited properly if this proxy ever parents a local
// frame.
void RenderFrameProxy::OnDidSetActiveSandboxFlags(
    blink::WebSandboxFlags active_sandbox_flags) {
  web_frame_->SetReplicatedSandboxFlags(active_sandbox_flags);
}

void RenderFrameProxy::SetChildFrameSurface(
    const viz::SurfaceInfo& surface_info,
    const viz::SurfaceSequence& sequence) {
  // If this WebFrame has already been detached, its parent will be null. This
  // can happen when swapping a WebRemoteFrame with a WebLocalFrame, where this
  // message may arrive after the frame was removed from the frame tree, but
  // before the frame has been destroyed. http://crbug.com/446575.
  if (!web_frame()->Parent())
    return;

  if (!enable_surface_synchronization_) {
    compositing_helper_->SetPrimarySurfaceId(surface_info.id(),
                                             local_frame_size());
  }
  compositing_helper_->SetFallbackSurfaceId(surface_info.id(),
                                            local_frame_size(), sequence);
}

bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
  // Forward Page IPCs to the RenderView.
  if ((IPC_MESSAGE_CLASS(msg) == PageMsgStart)) {
    if (render_view())
      return render_view()->OnMessageReceived(msg);

    return false;
  }

  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(RenderFrameProxy, msg)
    IPC_MESSAGE_HANDLER(FrameMsg_DeleteProxy, OnDeleteProxy)
    IPC_MESSAGE_HANDLER(FrameMsg_ChildFrameProcessGone, OnChildFrameProcessGone)
    IPC_MESSAGE_HANDLER(FrameMsg_SetChildFrameSurface, OnSetChildFrameSurface)
    IPC_MESSAGE_HANDLER(FrameMsg_UpdateOpener, OnUpdateOpener)
    IPC_MESSAGE_HANDLER(FrameMsg_ViewChanged, OnViewChanged)
    IPC_MESSAGE_HANDLER(FrameMsg_DidStartLoading, OnDidStartLoading)
    IPC_MESSAGE_HANDLER(FrameMsg_DidStopLoading, OnDidStopLoading)
    IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateFramePolicy, OnDidUpdateFramePolicy)
    IPC_MESSAGE_HANDLER(FrameMsg_DidSetActiveSandboxFlags,
                        OnDidSetActiveSandboxFlags)
    IPC_MESSAGE_HANDLER(FrameMsg_ForwardResourceTimingToParent,
                        OnForwardResourceTimingToParent)
    IPC_MESSAGE_HANDLER(FrameMsg_DispatchLoad, OnDispatchLoad)
    IPC_MESSAGE_HANDLER(FrameMsg_Collapse, OnCollapse)
    IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateName, OnDidUpdateName)
    IPC_MESSAGE_HANDLER(FrameMsg_AddContentSecurityPolicies,
                        OnAddContentSecurityPolicies)
    IPC_MESSAGE_HANDLER(FrameMsg_ResetContentSecurityPolicy,
                        OnResetContentSecurityPolicy)
    IPC_MESSAGE_HANDLER(FrameMsg_EnforceInsecureRequestPolicy,
                        OnEnforceInsecureRequestPolicy)
    IPC_MESSAGE_HANDLER(FrameMsg_EnforceInsecureNavigationsSet,
                        OnEnforceInsecureNavigationsSet)
    IPC_MESSAGE_HANDLER(FrameMsg_SetFrameOwnerProperties,
                        OnSetFrameOwnerProperties)
    IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateOrigin, OnDidUpdateOrigin)
    IPC_MESSAGE_HANDLER(InputMsg_SetFocus, OnSetPageFocus)
    IPC_MESSAGE_HANDLER(FrameMsg_ResizeDueToAutoResize, OnResizeDueToAutoResize)
    IPC_MESSAGE_HANDLER(FrameMsg_SetFocusedFrame, OnSetFocusedFrame)
    IPC_MESSAGE_HANDLER(FrameMsg_WillEnterFullscreen, OnWillEnterFullscreen)
    IPC_MESSAGE_HANDLER(FrameMsg_SetHasReceivedUserGesture,
                        OnSetHasReceivedUserGesture)
    IPC_MESSAGE_HANDLER(FrameMsg_ScrollRectToVisible, OnScrollRectToVisible)
    IPC_MESSAGE_HANDLER(FrameMsg_SetHasReceivedUserGestureBeforeNavigation,
                        OnSetHasReceivedUserGestureBeforeNavigation)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  // Note: If |handled| is true, |this| may have been deleted.
  return handled;
}

bool RenderFrameProxy::Send(IPC::Message* message) {
  return RenderThread::Get()->Send(message);
}

void RenderFrameProxy::OnDeleteProxy() {
  DCHECK(web_frame_);
  web_frame_->Detach();
}

void RenderFrameProxy::OnChildFrameProcessGone() {
  compositing_helper_->ChildFrameGone();
}

void RenderFrameProxy::OnSetChildFrameSurface(
    const viz::SurfaceInfo& surface_info,
    const viz::SurfaceSequence& sequence) {
  SetChildFrameSurface(surface_info, sequence);
}

void RenderFrameProxy::OnUpdateOpener(int opener_routing_id) {
  blink::WebFrame* opener = RenderFrameImpl::ResolveOpener(opener_routing_id);
  web_frame_->SetOpener(opener);
}

void RenderFrameProxy::OnDidStartLoading() {
  web_frame_->DidStartLoading();
}

void RenderFrameProxy::OnViewChanged(const viz::FrameSinkId& frame_sink_id) {
  // In mash the FrameSinkId comes from RendererWindowTreeClient.
  if (!switches::IsMusHostingViz())
    frame_sink_id_ = frame_sink_id;

  // Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
  // changes.
  ResendResizeParams();
}

void RenderFrameProxy::OnDidStopLoading() {
  web_frame_->DidStopLoading();
}

void RenderFrameProxy::OnForwardResourceTimingToParent(
    const ResourceTimingInfo& info) {
  web_frame_->ForwardResourceTimingToParent(
      ResourceTimingInfoToWebResourceTimingInfo(info));
}

void RenderFrameProxy::OnDispatchLoad() {
  web_frame_->DispatchLoadEventForFrameOwner();
}

void RenderFrameProxy::OnCollapse(bool collapsed) {
  web_frame_->Collapse(collapsed);
}

void RenderFrameProxy::OnDidUpdateName(const std::string& name,
                                       const std::string& unique_name) {
  web_frame_->SetReplicatedName(blink::WebString::FromUTF8(name));
  unique_name_ = unique_name;
}

void RenderFrameProxy::OnAddContentSecurityPolicies(
    const std::vector<ContentSecurityPolicyHeader>& headers) {
  for (const auto& header : headers) {
    web_frame_->AddReplicatedContentSecurityPolicyHeader(
        blink::WebString::FromUTF8(header.header_value), header.type,
        header.source);
  }
}

void RenderFrameProxy::OnResetContentSecurityPolicy() {
  web_frame_->ResetReplicatedContentSecurityPolicy();
}

void RenderFrameProxy::OnEnforceInsecureRequestPolicy(
    blink::WebInsecureRequestPolicy policy) {
  web_frame_->SetReplicatedInsecureRequestPolicy(policy);
}

void RenderFrameProxy::OnEnforceInsecureNavigationsSet(
    const std::vector<uint32_t>& set) {
  web_frame_->SetReplicatedInsecureNavigationsSet(set);
}

void RenderFrameProxy::OnSetFrameOwnerProperties(
    const FrameOwnerProperties& properties) {
  web_frame_->SetFrameOwnerProperties(
      ConvertFrameOwnerPropertiesToWebFrameOwnerProperties(properties));
}

void RenderFrameProxy::OnDidUpdateOrigin(
    const url::Origin& origin,
    bool is_potentially_trustworthy_unique_origin) {
  web_frame_->SetReplicatedOrigin(origin,
                                  is_potentially_trustworthy_unique_origin);
}

void RenderFrameProxy::OnSetPageFocus(bool is_focused) {
  render_view_->SetFocus(is_focused);
}

void RenderFrameProxy::OnSetFocusedFrame() {
  // This uses focusDocumentView rather than setFocusedFrame so that blur
  // events are properly dispatched on any currently focused elements.
  render_view_->webview()->FocusDocumentView(web_frame_);
}

void RenderFrameProxy::OnWillEnterFullscreen() {
  web_frame_->WillEnterFullscreen();
}

void RenderFrameProxy::OnSetHasReceivedUserGesture() {
  web_frame_->SetHasReceivedUserGesture();
}

void RenderFrameProxy::OnScrollRectToVisible(
    const gfx::Rect& rect_to_scroll,
    const blink::WebScrollIntoViewParams& params) {
  web_frame_->ScrollRectToVisible(rect_to_scroll, params);
}

void RenderFrameProxy::OnResizeDueToAutoResize(uint64_t sequence_number) {
  pending_resize_params_.sequence_number = sequence_number;
  WasResized();
}

#if defined(USE_AURA)
void RenderFrameProxy::SetMusEmbeddedFrame(
    std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame) {
  mus_embedded_frame_ = std::move(mus_embedded_frame);
}
#endif

void RenderFrameProxy::WasResized() {
  if (!frame_sink_id_.is_valid())
    return;

  bool synchronized_params_changed =
      !sent_resize_params_ ||
      sent_resize_params_->local_frame_size !=
          pending_resize_params_.local_frame_size ||
      sent_resize_params_->screen_space_rect.size() !=
          pending_resize_params_.screen_space_rect.size() ||
      sent_resize_params_->screen_info != pending_resize_params_.screen_info ||
      sent_resize_params_->sequence_number !=
          pending_resize_params_.sequence_number;

  if (synchronized_params_changed)
    local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();

  viz::SurfaceId surface_id(frame_sink_id_, local_surface_id_);
  if (enable_surface_synchronization_) {
    compositing_helper_->SetPrimarySurfaceId(surface_id, local_frame_size());
  }

  bool rect_changed =
      !sent_resize_params_ || sent_resize_params_->screen_space_rect !=
                                  pending_resize_params_.screen_space_rect;
  bool resize_params_changed = synchronized_params_changed || rect_changed;

#if defined(USE_AURA)
  if (rect_changed && mus_embedded_frame_) {
    mus_embedded_frame_->SetWindowBounds(local_surface_id_,
                                         gfx::Rect(local_frame_size()));
  }
#endif

  if (resize_params_changed) {
    // Let the browser know about the updated view rect.
    Send(new FrameHostMsg_UpdateResizeParams(
        routing_id_, screen_space_rect(), local_frame_size(), screen_info(),
        auto_size_sequence_number(), surface_id));
    sent_resize_params_ = pending_resize_params_;
  }
}

void RenderFrameProxy::OnSetHasReceivedUserGestureBeforeNavigation(bool value) {
  web_frame_->SetHasReceivedUserGestureBeforeNavigation(value);
}

void RenderFrameProxy::FrameDetached(DetachType type) {
#if defined(USE_AURA)
  mus_embedded_frame_.reset();
#endif

  if (type == DetachType::kRemove && web_frame_->Parent()) {
    // Let the browser process know this subframe is removed, so that it is
    // destroyed in its current process.
    Send(new FrameHostMsg_Detach(routing_id_));
  }

  web_frame_->Close();

  // If this proxy was associated with a provisional RenderFrame, and we're not
  // in the process of swapping with it, clean it up as well.
  if (type == DetachType::kRemove &&
      provisional_frame_routing_id_ != MSG_ROUTING_NONE) {
    RenderFrameImpl* provisional_frame =
        RenderFrameImpl::FromRoutingID(provisional_frame_routing_id_);
    // |provisional_frame| should always exist.  If it was deleted via
    // FrameMsg_Delete right before this proxy was removed,
    // RenderFrameImpl::frameDetached would've cleared this proxy's
    // |provisional_frame_routing_id_| and we wouldn't get here.
    CHECK(provisional_frame);
    provisional_frame->GetWebFrame()->Detach();
  }

  // Remove the entry in the WebFrame->RenderFrameProxy map, as the |web_frame_|
  // is no longer valid.
  FrameProxyMap::iterator it = g_frame_proxy_map.Get().find(web_frame_);
  CHECK(it != g_frame_proxy_map.Get().end());
  CHECK_EQ(it->second, this);
  g_frame_proxy_map.Get().erase(it);

  web_frame_ = nullptr;

  delete this;
}

void RenderFrameProxy::ForwardPostMessage(
    blink::WebLocalFrame* source_frame,
    blink::WebRemoteFrame* target_frame,
    blink::WebSecurityOrigin target_origin,
    blink::WebDOMMessageEvent event) {
  DCHECK(!web_frame_ || web_frame_ == target_frame);

  FrameMsg_PostMessage_Params params;
  params.is_data_raw_string = false;
  params.data = event.Data().ToString().Utf16();
  params.source_origin = event.Origin().Utf16();
  if (!target_origin.IsNull())
    params.target_origin = target_origin.ToString().Utf16();

  params.message_ports = event.ReleaseChannels().ReleaseVector();

  // Include the routing ID for the source frame (if one exists), which the
  // browser process will translate into the routing ID for the equivalent
  // frame in the target process.
  params.source_routing_id = MSG_ROUTING_NONE;
  if (source_frame) {
    RenderFrameImpl* source_render_frame =
        RenderFrameImpl::FromWebFrame(source_frame);
    if (source_render_frame)
      params.source_routing_id = source_render_frame->GetRoutingID();
  }

  Send(new FrameHostMsg_RouteMessageEvent(routing_id_, params));
}

void RenderFrameProxy::Navigate(const blink::WebURLRequest& request,
                                bool should_replace_current_entry) {
  FrameHostMsg_OpenURL_Params params;
  params.url = request.Url();
  params.uses_post = request.HttpMethod().Utf8() == "POST";
  params.resource_request_body = GetRequestBodyForWebURLRequest(request);
  params.extra_headers = GetWebURLRequestHeadersAsString(request);
  params.referrer = Referrer(blink::WebStringToGURL(request.HttpHeaderField(
                                 blink::WebString::FromUTF8("Referer"))),
                             request.GetReferrerPolicy());
  params.disposition = WindowOpenDisposition::CURRENT_TAB;
  params.should_replace_current_entry = should_replace_current_entry;
  params.user_gesture = request.HasUserGesture();
  params.triggering_event_info = blink::WebTriggeringEventInfo::kUnknown;
  params.suggested_filename =
      request.GetSuggestedFilename().has_value()
          ? base::Optional<std::string>(request.GetSuggestedFilename()->Utf8())
          : base::nullopt;

  Send(new FrameHostMsg_OpenURL(routing_id_, params));
}

void RenderFrameProxy::FrameRectsChanged(
    const blink::WebRect& local_frame_rect,
    const blink::WebRect& screen_space_rect) {
  pending_resize_params_.screen_space_rect = gfx::Rect(screen_space_rect);
  pending_resize_params_.local_frame_size =
      gfx::Size(local_frame_rect.width, local_frame_rect.height);
  pending_resize_params_.screen_info = render_widget_->screen_info();
  WasResized();
}

void RenderFrameProxy::UpdateRemoteViewportIntersection(
    const blink::WebRect& viewportIntersection) {
  Send(new FrameHostMsg_UpdateViewportIntersection(
      routing_id_, gfx::Rect(viewportIntersection)));
}

void RenderFrameProxy::VisibilityChanged(bool visible) {
  Send(new FrameHostMsg_VisibilityChanged(routing_id_, visible));
}

void RenderFrameProxy::SetIsInert(bool inert) {
  Send(new FrameHostMsg_SetIsInert(routing_id_, inert));
}

void RenderFrameProxy::UpdateRenderThrottlingStatus(bool is_throttled,
                                                    bool subtree_throttled) {
  Send(new FrameHostMsg_UpdateRenderThrottlingStatus(routing_id_, is_throttled,
                                                     subtree_throttled));
}

void RenderFrameProxy::DidChangeOpener(blink::WebFrame* opener) {
  // A proxy shouldn't normally be disowning its opener.  It is possible to get
  // here when a proxy that is being detached clears its opener, in which case
  // there is no need to notify the browser process.
  if (!opener)
    return;

  // Only a LocalFrame (i.e., the caller of window.open) should be able to
  // update another frame's opener.
  DCHECK(opener->IsWebLocalFrame());

  int opener_routing_id =
      RenderFrameImpl::FromWebFrame(opener->ToWebLocalFrame())->GetRoutingID();
  Send(new FrameHostMsg_DidChangeOpener(routing_id_, opener_routing_id));
}

void RenderFrameProxy::AdvanceFocus(blink::WebFocusType type,
                                    blink::WebLocalFrame* source) {
  int source_routing_id = RenderFrameImpl::FromWebFrame(source)->GetRoutingID();
  Send(new FrameHostMsg_AdvanceFocus(routing_id_, type, source_routing_id));
}

void RenderFrameProxy::FrameFocused() {
  Send(new FrameHostMsg_FrameFocused(routing_id_));
}

blink::WebString RenderFrameProxy::GetDevToolsFrameToken() {
  return devtools_frame_token_;
}

#if defined(USE_AURA)
void RenderFrameProxy::OnMusEmbeddedFrameSurfaceChanged(
    const viz::SurfaceInfo& surface_info) {
  SetChildFrameSurface(surface_info, viz::SurfaceSequence());
}

void RenderFrameProxy::OnMusEmbeddedFrameSinkIdAllocated(
    const viz::FrameSinkId& frame_sink_id) {
  // RendererWindowTreeClient should only call this when mus is hosting viz.
  DCHECK(switches::IsMusHostingViz());
  frame_sink_id_ = frame_sink_id;
  // Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
  // changes.
  ResendResizeParams();
}
#endif

}  // namespace content
