// 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. #ifndef CONTENT_RENDERER_RENDER_FRAME_PROXY_H_ #define CONTENT_RENDERER_RENDER_FRAME_PROXY_H_ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "content/common/content_export.h" #include "content/common/frame_messages.h" #include "content/common/frame_resize_params.h" #include "content/public/common/screen_info.h" #include "content/renderer/child_frame_compositor.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/public/platform/web_canvas.h" #include "third_party/blink/public/platform/web_focus_type.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/public/web/web_remote_frame.h" #include "third_party/blink/public/web/web_remote_frame_client.h" #include "url/origin.h" #if defined(USE_AURA) #include "content/renderer/mus/mus_embedded_frame_delegate.h" #endif namespace blink { struct FramePolicy; struct WebRect; struct WebScrollIntoViewParams; } namespace viz { class SurfaceInfo; } namespace content { class ChildFrameCompositingHelper; class RenderFrameImpl; class RenderViewImpl; class RenderWidget; struct ContentSecurityPolicyHeader; struct FrameOwnerProperties; struct FrameReplicationState; struct ResourceTimingInfo; #if defined(USE_AURA) && !defined(TOOLKIT_QT) class MusEmbeddedFrame; #endif // When a page's frames are rendered by multiple processes, each renderer has a // full copy of the frame tree. It has full RenderFrames for the frames it is // responsible for rendering and placeholder objects for frames rendered by // other processes. This class is the renderer-side object for the placeholder. // RenderFrameProxy allows us to keep existing window references valid over // cross-process navigations and route cross-site asynchronous JavaScript calls, // such as postMessage. // // For now, RenderFrameProxy is created when RenderFrame is swapped out. It // acts as a wrapper and is used for sending and receiving IPC messages. It is // deleted when the RenderFrame is swapped back in or the node of the frame // tree is deleted. // // Long term, RenderFrameProxy will be created to replace the RenderFrame in the // frame tree and the RenderFrame will be deleted after its unload handler has // finished executing. It will still be responsible for routing IPC messages // which are valid for cross-site interactions between frames. // RenderFrameProxy will be deleted when the node in the frame tree is deleted // or when navigating the frame causes it to return to this process and a new // RenderFrame is created for it. class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener, public IPC::Sender, #if defined(USE_AURA) && !defined(TOOLKIT_QT) public MusEmbeddedFrameDelegate, #endif public ChildFrameCompositor, public blink::WebRemoteFrameClient { public: // This method should be used to create a RenderFrameProxy, which will replace // an existing RenderFrame during its cross-process navigation from the // current process to a different one. |routing_id| will be ID of the newly // created RenderFrameProxy. |frame_to_replace| is the frame that the new // proxy will eventually swap places with. static RenderFrameProxy* CreateProxyToReplaceFrame( RenderFrameImpl* frame_to_replace, int routing_id, blink::WebTreeScopeType scope); // This method should be used to create a RenderFrameProxy, when there isn't // an existing RenderFrame. It should be called to construct a local // representation of a RenderFrame that has been created in another process -- // for example, after a cross-process navigation or after the addition of a // new frame local to some other process. |routing_id| will be the ID of the // newly created RenderFrameProxy. |render_view_routing_id| identifies the // RenderView to be associated with this frame. |opener|, if supplied, is the // new frame's opener. |parent_routing_id| is the routing ID of the // RenderFrameProxy to which the new frame is parented. // // |parent_routing_id| always identifies a RenderFrameProxy (never a // RenderFrame) because a new child of a local frame should always start out // as a frame, not a proxy. static RenderFrameProxy* CreateFrameProxy( int routing_id, int render_view_routing_id, blink::WebFrame* opener, int parent_routing_id, const FrameReplicationState& replicated_state, const base::UnguessableToken& devtools_frame_token); // Returns the RenderFrameProxy for the given routing ID. static RenderFrameProxy* FromRoutingID(int routing_id); // Returns the RenderFrameProxy given a WebRemoteFrame. |web_frame| must not // be null, nor will this method return null. static RenderFrameProxy* FromWebFrame(blink::WebRemoteFrame* web_frame); ~RenderFrameProxy() override; // IPC::Sender bool Send(IPC::Message* msg) override; // Out-of-process child frames receive a signal from RenderWidgetCompositor // when a compositor frame will begin. void WillBeginCompositorFrame(); // Out-of-process child frames receive a signal from RenderWidget when the // ScreenInfo has changed. void OnScreenInfoChanged(const ScreenInfo& screen_info); // Pass replicated information, such as security origin, to this // RenderFrameProxy's WebRemoteFrame. void SetReplicatedState(const FrameReplicationState& state); int routing_id() { return routing_id_; } RenderViewImpl* render_view() { return render_view_; } blink::WebRemoteFrame* web_frame() { return web_frame_; } const std::string& unique_name() const { return unique_name_; } void set_provisional_frame_routing_id(int routing_id) { provisional_frame_routing_id_ = routing_id; } int provisional_frame_routing_id() { return provisional_frame_routing_id_; } // Returns the widget used for the local frame root. RenderWidget* render_widget() { return render_widget_; } #if defined(USE_AURA) && !defined(TOOLKIT_QT) void SetMusEmbeddedFrame( std::unique_ptr mus_embedded_frame); #endif void WasResized(); const gfx::Rect& screen_space_rect() const { return pending_resize_params_.screen_space_rect; } const gfx::Size& local_frame_size() const { return pending_resize_params_.local_frame_size; } const ScreenInfo& screen_info() const { return pending_resize_params_.screen_info; } uint64_t auto_size_sequence_number() const { return pending_resize_params_.auto_resize_sequence_number; } const viz::FrameSinkId& frame_sink_id() const { return frame_sink_id_; } // blink::WebRemoteFrameClient implementation: void FrameDetached(DetachType type) override; void CheckCompleted() override; void ForwardPostMessage(blink::WebLocalFrame* sourceFrame, blink::WebRemoteFrame* targetFrame, blink::WebSecurityOrigin target, blink::WebDOMMessageEvent event, bool has_user_gesture) override; void Navigate(const blink::WebURLRequest& request, bool should_replace_current_entry) override; void FrameRectsChanged(const blink::WebRect& local_frame_rect, const blink::WebRect& screen_space_rect) override; void UpdateRemoteViewportIntersection( const blink::WebRect& viewport_intersection) override; void VisibilityChanged(bool visible) override; void SetIsInert(bool) override; void UpdateRenderThrottlingStatus(bool is_throttled, bool subtree_throttled) override; void DidChangeOpener(blink::WebFrame* opener) override; void AdvanceFocus(blink::WebFocusType type, blink::WebLocalFrame* source) override; void FrameFocused() override; base::UnguessableToken GetDevToolsFrameToken() override; uint32_t Print(const blink::WebRect& rect, blink::WebCanvas* canvas) override; // IPC handlers void OnDidStartLoading(); private: RenderFrameProxy(int routing_id); void Init(blink::WebRemoteFrame* frame, RenderViewImpl* render_view, RenderWidget* render_widget); void ResendResizeParams(); void SetChildFrameSurface(const viz::SurfaceInfo& surface_info); // IPC::Listener bool OnMessageReceived(const IPC::Message& msg) override; // IPC handlers void OnDeleteProxy(); void OnChildFrameProcessGone(); void OnCompositorFrameSwapped(const IPC::Message& message); // TODO(fsamuel): Rename OnFirstSurfaceActivation(). void OnSetChildFrameSurface(const viz::SurfaceInfo& surface_info); void OnIntrinsicSizingInfoOfChildChanged( blink::WebIntrinsicSizingInfo sizing_info); void OnUpdateOpener(int opener_routing_id); void OnViewChanged(const FrameMsg_ViewChanged_Params& params); void OnDidStopLoading(); void OnDidUpdateFramePolicy(const blink::FramePolicy& frame_policy); void OnDidSetFramePolicyHeaders( blink::WebSandboxFlags active_sandbox_flags, blink::ParsedFeaturePolicy parsed_feature_policy); void OnForwardResourceTimingToParent( const ResourceTimingInfo& resource_timing); void OnDispatchLoad(); void OnCollapse(bool collapsed); void OnDidUpdateName(const std::string& name, const std::string& unique_name); void OnAddContentSecurityPolicies( const std::vector& header); void OnResetContentSecurityPolicy(); void OnEnforceInsecureRequestPolicy(blink::WebInsecureRequestPolicy policy); void OnEnforceInsecureNavigationsSet(const std::vector& set); void OnSetFrameOwnerProperties(const FrameOwnerProperties& properties); void OnDidUpdateOrigin(const url::Origin& origin, bool is_potentially_trustworthy_unique_origin); void OnSetPageFocus(bool is_focused); void OnSetFocusedFrame(); void OnWillEnterFullscreen(); void OnSetHasReceivedUserGesture(); void OnScrollRectToVisible(const gfx::Rect& rect_to_scroll, const blink::WebScrollIntoViewParams& params); void OnResizeDueToAutoResize(uint64_t sequence_number); void OnEnableAutoResize(const gfx::Size& min_size, const gfx::Size& max_size); void OnDisableAutoResize(); void OnSetHasReceivedUserGestureBeforeNavigation(bool value); #if defined(USE_AURA) && !defined(TOOLKIT_QT) // MusEmbeddedFrameDelegate void OnMusEmbeddedFrameSurfaceChanged( const viz::SurfaceInfo& surface_info) override; void OnMusEmbeddedFrameSinkIdAllocated( const viz::FrameSinkId& frame_sink_id) override; #endif // ChildFrameCompositor: blink::WebLayer* GetLayer() override; void SetLayer(std::unique_ptr web_layer) override; SkBitmap* GetSadPageBitmap() override; // The routing ID by which this RenderFrameProxy is known. const int routing_id_; // The routing ID of the provisional RenderFrame (if any) that is meant to // replace this RenderFrameProxy in the frame tree. int provisional_frame_routing_id_; // Stores the WebRemoteFrame we are associated with. blink::WebRemoteFrame* web_frame_; std::string unique_name_; std::unique_ptr compositing_helper_; RenderViewImpl* render_view_; RenderWidget* render_widget_; // Contains token to be used as a frame id in the devtools protocol. // It is derived from the content's devtools_frame_token, is // defined by the browser and passed into Blink upon frame creation. base::UnguessableToken devtools_frame_token_; // TODO(fsamuel): Most RenderFrameProxys don't host viz::Surfaces and // therefore don't care to synchronize ResizeParams with viz::LocalSurfaceIds. // Perhaps this can be moved to ChildFrameCompositingHelper? // The last ResizeParams sent to the browser process, if any. base::Optional sent_resize_params_; // The current set of ResizeParams. This may or may not match // |sent_resize_params_|. FrameResizeParams pending_resize_params_; bool crashed_ = false; viz::FrameSinkId frame_sink_id_; viz::LocalSurfaceId local_surface_id_; viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_; bool enable_surface_synchronization_ = false; gfx::Rect last_intersection_rect_; gfx::Rect last_compositor_visible_rect_; #if defined(USE_AURA) && !defined(TOOLKIT_QT) std::unique_ptr mus_embedded_frame_; #endif // The layer used to embed the out-of-process content. std::unique_ptr web_layer_; DISALLOW_COPY_AND_ASSIGN(RenderFrameProxy); }; } // namespace content #endif // CONTENT_RENDERER_RENDER_FRAME_PROXY_H_