summaryrefslogtreecommitdiff
path: root/chromium/content/renderer/render_frame_proxy.h
blob: 5aa6af9bd8c8cdc80aa9dc489ea686a27e3b1e79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
// 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 "cc/paint/paint_canvas.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_proxy.mojom.h"
#include "content/common/frame_visual_properties.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 "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/mojom/frame/frame.mojom.h"
#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h"
#include "third_party/blink/public/mojom/input/focus_type.mojom-forward.h"
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-forward.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"

namespace blink {
struct WebRect;
}

namespace content {

class BlinkInterfaceRegistryImpl;
class ChildFrameCompositingHelper;
class RenderFrameImpl;
class RenderViewImpl;
class RenderWidget;
struct FrameReplicationState;

// 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,
                                        public ChildFrameCompositor,
                                        public blink::WebRemoteFrameClient,
                                        public mojom::RenderFrameProxy {
 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::mojom::TreeScopeType scope,
      const base::UnguessableToken& proxy_frame_token);

  // 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,
      const base::UnguessableToken& opener_frame_token,
      int parent_routing_id,
      const FrameReplicationState& replicated_state,
      const base::UnguessableToken& frame_token,
      const base::UnguessableToken& devtools_frame_token);

  // Creates a RenderFrameProxy to be used with a portal owned by |parent|.
  // |routing_id| is the routing id of this new RenderFrameProxy.
  static RenderFrameProxy* CreateProxyForPortal(
      RenderFrameImpl* parent,
      int proxy_routing_id,
      const base::UnguessableToken& frame_token,
      const base::UnguessableToken& devtools_frame_token,
      const blink::WebElement& portal_element);

  // 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;

  // IPC::Listener
  bool OnMessageReceived(const IPC::Message& msg) override;
  void OnAssociatedInterfaceRequest(
      const std::string& interface_name,
      mojo::ScopedInterfaceEndpointHandle handle) override;

  // Propagate VisualProperties updates from a local root RenderWidget to the
  // child RenderWidget represented by this proxy, which is hosted in another
  // renderer frame tree.
  // TODO(danakj): These should all be grouped into a single method, then we
  // would only get one update per UpdateVisualProperties IPC received in the
  // RenderWidget, and we would only need to send one update to the browser as
  // a result.
  void OnScreenInfoChanged(const ScreenInfo& screen_info);
  void OnZoomLevelChanged(double zoom_level);
  void OnRootWindowSegmentsChanged(
      std::vector<gfx::Rect> root_widget_window_segments);
  void OnPageScaleFactorChanged(float page_scale_factor,
                                bool is_pinch_gesture_active);
  void OnVisibleViewportSizeChanged(const gfx::Size& visible_viewport_size);
  void UpdateCaptureSequenceNumber(uint32_t capture_sequence_number);

  // 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_; }

  void SynchronizeVisualProperties();

  const gfx::Rect& screen_space_rect() const {
    return pending_visual_properties_.screen_space_rect;
  }

  const gfx::Size& local_frame_size() const {
    return pending_visual_properties_.local_frame_size;
  }

  const ScreenInfo& screen_info() const {
    return pending_visual_properties_.screen_info;
  }

  const viz::FrameSinkId& frame_sink_id() const { return frame_sink_id_; }

  // blink::WebRemoteFrameClient implementation:
  void FrameDetached(DetachType type) override;
  blink::AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override;

  void Navigate(
      const blink::WebURLRequest& request,
      blink::WebLocalFrame* initiator_frame,
      bool should_replace_current_entry,
      bool is_opener_navigation,
      bool initiator_frame_has_download_sandbox_flag,
      bool blocking_downloads_in_sandbox_enabled,
      bool initiator_frame_is_ad,
      blink::CrossVariantMojoRemote<blink::mojom::BlobURLTokenInterfaceBase>
          blob_url_token,
      const base::Optional<blink::WebImpression>& impression) override;
  void FrameRectsChanged(const blink::WebRect& local_frame_rect,
                         const blink::WebRect& screen_space_rect) override;
  void UpdateRemoteViewportIntersection(
      const blink::ViewportIntersectionState& intersection_state) override;
  base::UnguessableToken GetDevToolsFrameToken() override;
  uint32_t Print(const blink::WebRect& rect, cc::PaintCanvas* canvas) override;

  void DidStartLoading();

  void WasEvicted();

  bool is_pinch_gesture_active_for_testing() {
    return pending_visual_properties_.is_pinch_gesture_active;
  }

  // Called when the associated FrameSinkId has changed.
  void FrameSinkIdChanged(const viz::FrameSinkId& frame_sink_id);

 private:
  RenderFrameProxy(int routing_id);

  void Init(blink::WebRemoteFrame* frame,
            RenderViewImpl* render_view,
            RenderWidget* render_widget,
            bool parent_is_local);

  void ResendVisualProperties();

  mojom::RenderFrameProxyHost* GetFrameProxyHost();

  // IPC handlers
  void OnDeleteProxy();
  void OnCompositorFrameSwapped(const IPC::Message& message);
  void OnDidUpdateName(const std::string& name, const std::string& unique_name);
  void OnEnforceInsecureRequestPolicy(
      blink::mojom::InsecureRequestPolicy policy);

  // mojom::RenderFrameProxy implementation:
  void EnableAutoResize(const gfx::Size& min_size,
                        const gfx::Size& max_size) override;
  void DisableAutoResize() override;
  void DidUpdateVisualProperties(
      const cc::RenderFrameMetadata& metadata) override;
  void ChildProcessGone() override;
  void SetFrameSinkId(const viz::FrameSinkId& frame_sink_id) override;

  // ChildFrameCompositor:
  cc::Layer* GetLayer() override;
  void SetLayer(scoped_refptr<cc::Layer> layer,
                bool prevent_contents_opaque_changes,
                bool is_surface_layer) override;
  SkBitmap* GetSadPageBitmap() override;

  const viz::LocalSurfaceId& GetLocalSurfaceId() const;

  // 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_ = nullptr;
  std::string unique_name_;

  // Provides the mojo interface to this RenderFrameProxy's
  // RenderFrameProxyHost.
  mojo::AssociatedRemote<mojom::RenderFrameProxyHost> frame_proxy_host_remote_;
  std::unique_ptr<blink::AssociatedInterfaceProvider>
      remote_associated_interfaces_;

  // Mojo receiver to this content::mojom::RenderFrameProxy.
  mojo::AssociatedReceiver<mojom::RenderFrameProxy>
      render_frame_proxy_receiver_{this};

  // Can be nullptr when this RenderFrameProxy's parent is not a RenderFrame.
  std::unique_ptr<ChildFrameCompositingHelper> compositing_helper_;

  RenderViewImpl* render_view_ = nullptr;

  // The RenderWidget of the nearest ancestor local root. If the proxy has no
  // local root ancestor (eg it is a proxy of the root frame) then the pointer
  // is null.
  RenderWidget* ancestor_render_widget_ = nullptr;

  // 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<FrameVisualProperties> sent_visual_properties_;

  // The current set of ResizeParams. This may or may not match
  // |sent_visual_properties_|.
  FrameVisualProperties pending_visual_properties_;

  bool crashed_ = false;

  viz::FrameSinkId frame_sink_id_;
  std::unique_ptr<viz::ParentLocalSurfaceIdAllocator>
      parent_local_surface_id_allocator_;

  // The layer used to embed the out-of-process content.
  scoped_refptr<cc::Layer> embedded_layer_;

  service_manager::BinderRegistry binder_registry_;
  blink::AssociatedInterfaceRegistry associated_interfaces_;
  std::unique_ptr<BlinkInterfaceRegistryImpl> blink_interface_registry_;

  DISALLOW_COPY_AND_ASSIGN(RenderFrameProxy);
};

}  // namespace content

#endif  // CONTENT_RENDERER_RENDER_FRAME_PROXY_H_