1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/renderer/render_frame_proxy.h"
6 
7 #include <stdint.h>
8 #include <map>
9 #include <memory>
10 #include <utility>
11 
12 #include "base/command_line.h"
13 #include "base/lazy_instance.h"
14 #include "base/memory/ptr_util.h"
15 #include "components/viz/common/surfaces/local_surface_id_allocation.h"
16 #include "content/common/content_switches_internal.h"
17 #include "content/common/frame_replication_state.h"
18 #include "content/common/input_messages.h"
19 #include "content/common/page_messages.h"
20 #include "content/common/unfreezable_frame_messages.h"
21 #include "content/common/view_messages.h"
22 #include "content/public/common/content_client.h"
23 #include "content/public/common/content_switches.h"
24 #include "content/public/common/screen_info.h"
25 #include "content/public/common/use_zoom_for_dsf_policy.h"
26 #include "content/public/renderer/content_renderer_client.h"
27 #include "content/renderer/child_frame_compositing_helper.h"
28 #include "content/renderer/loader/web_url_request_util.h"
29 #include "content/renderer/mojo/blink_interface_registry_impl.h"
30 #include "content/renderer/render_frame_impl.h"
31 #include "content/renderer/render_thread_impl.h"
32 #include "content/renderer/render_view_impl.h"
33 #include "content/renderer/render_widget.h"
34 #include "ipc/ipc_message_macros.h"
35 #include "mojo/public/cpp/bindings/pending_associated_remote.h"
36 #include "printing/buildflags/buildflags.h"
37 #include "third_party/blink/public/common/feature_policy/feature_policy.h"
38 #include "third_party/blink/public/common/frame/frame_policy.h"
39 #include "third_party/blink/public/common/navigation/triggering_event_info.h"
40 #include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom.h"
41 #include "third_party/blink/public/platform/url_conversion.h"
42 #include "third_party/blink/public/platform/web_rect.h"
43 #include "third_party/blink/public/platform/web_string.h"
44 #include "third_party/blink/public/web/web_local_frame.h"
45 #include "third_party/blink/public/web/web_view.h"
46 #include "ui/gfx/geometry/size_conversions.h"
47 
48 #if BUILDFLAG(ENABLE_PRINTING)
49 // nogncheck because dependency on //printing is conditional upon
50 // enable_basic_printing flags.
51 #include "printing/metafile_skia.h"          // nogncheck
52 #endif
53 
54 namespace content {
55 
56 namespace {
57 
58 // Facilitates lookup of RenderFrameProxy by routing_id.
59 typedef std::map<int, RenderFrameProxy*> RoutingIDProxyMap;
60 static base::LazyInstance<RoutingIDProxyMap>::DestructorAtExit
61     g_routing_id_proxy_map = LAZY_INSTANCE_INITIALIZER;
62 
63 // Facilitates lookup of RenderFrameProxy by WebRemoteFrame.
64 typedef std::map<blink::WebRemoteFrame*, RenderFrameProxy*> FrameProxyMap;
65 base::LazyInstance<FrameProxyMap>::DestructorAtExit g_frame_proxy_map =
66     LAZY_INSTANCE_INITIALIZER;
67 
68 }  // namespace
69 
70 // static
CreateProxyToReplaceFrame(RenderFrameImpl * frame_to_replace,int routing_id,blink::WebTreeScopeType scope)71 RenderFrameProxy* RenderFrameProxy::CreateProxyToReplaceFrame(
72     RenderFrameImpl* frame_to_replace,
73     int routing_id,
74     blink::WebTreeScopeType scope) {
75   CHECK_NE(routing_id, MSG_ROUTING_NONE);
76 
77   std::unique_ptr<RenderFrameProxy> proxy(new RenderFrameProxy(routing_id));
78   proxy->unique_name_ = frame_to_replace->unique_name();
79   proxy->devtools_frame_token_ = frame_to_replace->GetDevToolsFrameToken();
80 
81   // When a RenderFrame is replaced by a RenderProxy, the WebRemoteFrame should
82   // always come from WebRemoteFrame::create and a call to WebFrame::swap must
83   // follow later.
84   blink::WebRemoteFrame* web_frame = blink::WebRemoteFrame::Create(
85       scope, proxy.get(), proxy->blink_interface_registry_.get(),
86       proxy->GetRemoteAssociatedInterfaces());
87 
88   RenderWidget* ancestor_widget = nullptr;
89   bool parent_is_local = false;
90 
91   // A top level frame proxy doesn't have a RenderWidget pointer. The pointer
92   // is to an ancestor local frame's RenderWidget and there are no ancestors.
93   if (frame_to_replace->GetWebFrame()->Parent()) {
94     if (frame_to_replace->GetWebFrame()->Parent()->IsWebLocalFrame()) {
95       // If the frame was a local frame, get its local root's RenderWidget.
96       ancestor_widget = frame_to_replace->GetLocalRootRenderWidget();
97       parent_is_local = true;
98     } else {
99       // Otherwise, grab the pointer from the parent RenderFrameProxy, as
100       // it would already have the correct pointer. A proxy with a proxy child
101       // must be created before its child, so the first proxy in a descendant
102       // chain is either the root or has a local parent frame.
103       RenderFrameProxy* parent = RenderFrameProxy::FromWebFrame(
104           frame_to_replace->GetWebFrame()->Parent()->ToWebRemoteFrame());
105       ancestor_widget = parent->ancestor_render_widget_;
106     }
107   }
108 
109   proxy->Init(web_frame, frame_to_replace->render_view(), ancestor_widget,
110               parent_is_local);
111   return proxy.release();
112 }
113 
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)114 RenderFrameProxy* RenderFrameProxy::CreateFrameProxy(
115     int routing_id,
116     int render_view_routing_id,
117     blink::WebFrame* opener,
118     int parent_routing_id,
119     const FrameReplicationState& replicated_state,
120     const base::UnguessableToken& devtools_frame_token) {
121   RenderFrameProxy* parent = nullptr;
122   if (parent_routing_id != MSG_ROUTING_NONE) {
123     parent = RenderFrameProxy::FromRoutingID(parent_routing_id);
124     // It is possible that the parent proxy has been detached in this renderer
125     // process, just as the parent's real frame was creating this child frame.
126     // In this case, do not create the proxy. See https://crbug.com/568670.
127     if (!parent)
128       return nullptr;
129   }
130 
131   std::unique_ptr<RenderFrameProxy> proxy(new RenderFrameProxy(routing_id));
132   proxy->devtools_frame_token_ = devtools_frame_token;
133   RenderViewImpl* render_view = nullptr;
134   RenderWidget* ancestor_widget = nullptr;
135   blink::WebRemoteFrame* web_frame = nullptr;
136 
137   if (!parent) {
138     // Create a top level WebRemoteFrame.
139     render_view = RenderViewImpl::FromRoutingID(render_view_routing_id);
140     web_frame = blink::WebRemoteFrame::CreateMainFrame(
141         render_view->GetWebView(), proxy.get(),
142         proxy->blink_interface_registry_.get(),
143         proxy->GetRemoteAssociatedInterfaces(), opener);
144     // Root frame proxy has no ancestors to point to their RenderWidget.
145   } else {
146     // Create a frame under an existing parent. The parent is always expected
147     // to be a RenderFrameProxy, because navigations initiated by local frames
148     // should not wind up here.
149     web_frame = parent->web_frame()->CreateRemoteChild(
150         replicated_state.scope,
151         blink::WebString::FromUTF8(replicated_state.name),
152         replicated_state.frame_policy,
153         replicated_state.frame_owner_element_type, proxy.get(),
154         proxy->blink_interface_registry_.get(),
155         proxy->GetRemoteAssociatedInterfaces(), opener);
156     proxy->unique_name_ = replicated_state.unique_name;
157     render_view = parent->render_view();
158     ancestor_widget = parent->ancestor_render_widget_;
159   }
160 
161   proxy->Init(web_frame, render_view, ancestor_widget, false);
162 
163   // Initialize proxy's WebRemoteFrame with the security origin and other
164   // replicated information.
165   // TODO(dcheng): Calling this when parent_routing_id != MSG_ROUTING_NONE is
166   // mostly redundant, since we already pass the name and sandbox flags in
167   // createLocalChild(). We should update the Blink interface so it also takes
168   // the origin. Then it will be clear that the replication call is only needed
169   // for the case of setting up a main frame proxy.
170   proxy->SetReplicatedState(replicated_state);
171 
172   return proxy.release();
173 }
174 
CreateProxyForPortal(RenderFrameImpl * parent,int proxy_routing_id,const base::UnguessableToken & devtools_frame_token,const blink::WebElement & portal_element)175 RenderFrameProxy* RenderFrameProxy::CreateProxyForPortal(
176     RenderFrameImpl* parent,
177     int proxy_routing_id,
178     const base::UnguessableToken& devtools_frame_token,
179     const blink::WebElement& portal_element) {
180   auto proxy = base::WrapUnique(new RenderFrameProxy(proxy_routing_id));
181   proxy->devtools_frame_token_ = devtools_frame_token;
182   blink::WebRemoteFrame* web_frame = blink::WebRemoteFrame::CreateForPortal(
183       blink::WebTreeScopeType::kDocument, proxy.get(),
184       proxy->blink_interface_registry_.get(),
185       proxy->GetRemoteAssociatedInterfaces(), portal_element);
186   proxy->Init(web_frame, parent->render_view(),
187               parent->GetLocalRootRenderWidget(), true);
188   return proxy.release();
189 }
190 
191 // static
FromRoutingID(int32_t routing_id)192 RenderFrameProxy* RenderFrameProxy::FromRoutingID(int32_t routing_id) {
193   RoutingIDProxyMap* proxies = g_routing_id_proxy_map.Pointer();
194   auto it = proxies->find(routing_id);
195   return it == proxies->end() ? NULL : it->second;
196 }
197 
198 // static
FromWebFrame(blink::WebRemoteFrame * web_frame)199 RenderFrameProxy* RenderFrameProxy::FromWebFrame(
200     blink::WebRemoteFrame* web_frame) {
201   // TODO(dcheng): Turn this into a DCHECK() if it doesn't crash on canary.
202   CHECK(web_frame);
203   auto iter = g_frame_proxy_map.Get().find(web_frame);
204   if (iter != g_frame_proxy_map.Get().end()) {
205     RenderFrameProxy* proxy = iter->second;
206     DCHECK_EQ(web_frame, proxy->web_frame());
207     return proxy;
208   }
209   // Reaching this is not expected: this implies that the |web_frame| in
210   // question is not managed by the content API, or the associated
211   // RenderFrameProxy is already deleted--in which case, it's not safe to touch
212   // |web_frame|.
213   NOTREACHED();
214   return nullptr;
215 }
216 
RenderFrameProxy(int routing_id)217 RenderFrameProxy::RenderFrameProxy(int routing_id)
218     : routing_id_(routing_id),
219       provisional_frame_routing_id_(MSG_ROUTING_NONE),
220       // TODO(samans): Investigate if it is safe to delay creation of this
221       // object until a FrameSinkId is provided.
222       parent_local_surface_id_allocator_(
223           std::make_unique<viz::ParentLocalSurfaceIdAllocator>()) {
224   std::pair<RoutingIDProxyMap::iterator, bool> result =
225       g_routing_id_proxy_map.Get().insert(std::make_pair(routing_id_, this));
226   CHECK(result.second) << "Inserting a duplicate item.";
227   RenderThread::Get()->AddRoute(routing_id_, this);
228   blink_interface_registry_.reset(new BlinkInterfaceRegistryImpl(
229       binder_registry_.GetWeakPtr(), associated_interfaces_.GetWeakPtr()));
230 }
231 
~RenderFrameProxy()232 RenderFrameProxy::~RenderFrameProxy() {
233   if (ancestor_render_widget_)
234     ancestor_render_widget_->UnregisterRenderFrameProxy(this);
235 
236   CHECK(!web_frame_);
237   RenderThread::Get()->RemoveRoute(routing_id_);
238   g_routing_id_proxy_map.Get().erase(routing_id_);
239 }
240 
Init(blink::WebRemoteFrame * web_frame,RenderViewImpl * render_view,RenderWidget * ancestor_widget,bool parent_is_local)241 void RenderFrameProxy::Init(blink::WebRemoteFrame* web_frame,
242                             RenderViewImpl* render_view,
243                             RenderWidget* ancestor_widget,
244                             bool parent_is_local) {
245   CHECK(web_frame);
246   CHECK(render_view);
247 
248   web_frame_ = web_frame;
249   render_view_ = render_view;
250   ancestor_render_widget_ = ancestor_widget;
251 
252   // |ancestor_render_widget_| can be null if this is a proxy for a remote main
253   // frame, or a subframe of that proxy. We don't need to register as an
254   // observer [since there is no ancestor RenderWidget]. The observer is used to
255   // propagate VisualProperty changes down the frame/process hierarchy. Remote
256   // main frame proxies do not participate in this flow.
257   if (ancestor_render_widget_) {
258     ancestor_render_widget_->RegisterRenderFrameProxy(this);
259     pending_visual_properties_.screen_info =
260         ancestor_render_widget_->GetOriginalScreenInfo();
261   }
262 
263   std::pair<FrameProxyMap::iterator, bool> result =
264       g_frame_proxy_map.Get().insert(std::make_pair(web_frame_, this));
265   CHECK(result.second) << "Inserted a duplicate item.";
266 
267   if (parent_is_local)
268     compositing_helper_ = std::make_unique<ChildFrameCompositingHelper>(this);
269 }
270 
ResendVisualProperties()271 void RenderFrameProxy::ResendVisualProperties() {
272   // Reset |sent_visual_properties_| in order to allocate a new
273   // viz::LocalSurfaceId.
274   sent_visual_properties_ = base::nullopt;
275   SynchronizeVisualProperties();
276 }
277 
OnScreenInfoChanged(const ScreenInfo & screen_info)278 void RenderFrameProxy::OnScreenInfoChanged(const ScreenInfo& screen_info) {
279   DCHECK(ancestor_render_widget_);
280 
281   pending_visual_properties_.screen_info = screen_info;
282   if (crashed_) {
283     // Update the sad page to match the current ScreenInfo.
284     compositing_helper_->ChildFrameGone(local_frame_size(),
285                                         screen_info.device_scale_factor);
286     return;
287   }
288   SynchronizeVisualProperties();
289 }
290 
OnZoomLevelChanged(double zoom_level)291 void RenderFrameProxy::OnZoomLevelChanged(double zoom_level) {
292   DCHECK(ancestor_render_widget_);
293 
294   pending_visual_properties_.zoom_level = zoom_level;
295   SynchronizeVisualProperties();
296 }
297 
OnPageScaleFactorChanged(float page_scale_factor,bool is_pinch_gesture_active)298 void RenderFrameProxy::OnPageScaleFactorChanged(float page_scale_factor,
299                                                 bool is_pinch_gesture_active) {
300   DCHECK(ancestor_render_widget_);
301 
302   pending_visual_properties_.page_scale_factor = page_scale_factor;
303   pending_visual_properties_.is_pinch_gesture_active = is_pinch_gesture_active;
304   SynchronizeVisualProperties();
305 }
306 
OnVisibleViewportSizeChanged(const gfx::Size & visible_viewport_size)307 void RenderFrameProxy::OnVisibleViewportSizeChanged(
308     const gfx::Size& visible_viewport_size) {
309   DCHECK(ancestor_render_widget_);
310 
311   pending_visual_properties_.visible_viewport_size = visible_viewport_size;
312   SynchronizeVisualProperties();
313 }
314 
UpdateCaptureSequenceNumber(uint32_t capture_sequence_number)315 void RenderFrameProxy::UpdateCaptureSequenceNumber(
316     uint32_t capture_sequence_number) {
317   DCHECK(ancestor_render_widget_);
318 
319   pending_visual_properties_.capture_sequence_number = capture_sequence_number;
320   SynchronizeVisualProperties();
321 }
322 
SetReplicatedState(const FrameReplicationState & state)323 void RenderFrameProxy::SetReplicatedState(const FrameReplicationState& state) {
324   DCHECK(web_frame_);
325 
326   web_frame_->SetReplicatedOrigin(
327       state.origin, state.has_potentially_trustworthy_unique_origin);
328 
329 #if DCHECK_IS_ON()
330   blink::WebSecurityOrigin security_origin_before_sandbox_flags =
331       web_frame_->GetSecurityOrigin();
332 #endif
333 
334   web_frame_->SetReplicatedSandboxFlags(state.active_sandbox_flags);
335 
336 #if DCHECK_IS_ON()
337   // If |state.has_potentially_trustworthy_unique_origin| is set,
338   // - |state.origin| should be unique (this is checked in
339   //   blink::SecurityOrigin::SetUniqueOriginIsPotentiallyTrustworthy() in
340   //   SetReplicatedOrigin()), and thus
341   // - The security origin is not updated by SetReplicatedSandboxFlags() and
342   //   thus we don't have to apply |has_potentially_trustworthy_unique_origin|
343   //   flag after SetReplicatedSandboxFlags().
344   if (state.has_potentially_trustworthy_unique_origin)
345     DCHECK(security_origin_before_sandbox_flags ==
346            web_frame_->GetSecurityOrigin());
347 #endif
348 
349   web_frame_->SetReplicatedName(blink::WebString::FromUTF8(state.name));
350   web_frame_->SetReplicatedInsecureRequestPolicy(state.insecure_request_policy);
351   web_frame_->SetReplicatedInsecureNavigationsSet(
352       state.insecure_navigations_set);
353   web_frame_->SetReplicatedAdFrameType(state.ad_frame_type);
354   web_frame_->SetReplicatedFeaturePolicyHeaderAndOpenerPolicies(
355       state.feature_policy_header, state.opener_feature_state);
356   if (state.has_received_user_gesture) {
357     web_frame_->UpdateUserActivationState(
358         blink::mojom::UserActivationUpdateType::kNotifyActivation);
359   }
360   web_frame_->SetHadStickyUserActivationBeforeNavigation(
361       state.has_received_user_gesture_before_nav);
362 
363   web_frame_->ResetReplicatedContentSecurityPolicy();
364   for (const auto& header : state.accumulated_csp_headers) {
365     web_frame_->AddReplicatedContentSecurityPolicyHeader(
366         blink::WebString::FromUTF8(header.header_value), header.type,
367         header.source);
368   }
369 }
370 
OnMessageReceived(const IPC::Message & msg)371 bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
372   // Page IPCs are routed via the main frame (both local and remote) and then
373   // forwarded to the RenderView. See comment in
374   // RenderFrameHostManager::SendPageMessage() for more information.
375   if ((IPC_MESSAGE_CLASS(msg) == PageMsgStart)) {
376     if (render_view())
377       return render_view()->OnMessageReceived(msg);
378 
379     return false;
380   }
381 
382   bool handled = true;
383   IPC_BEGIN_MESSAGE_MAP(RenderFrameProxy, msg)
384     IPC_MESSAGE_HANDLER(FrameMsg_UpdateOpener, OnUpdateOpener)
385     IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateName, OnDidUpdateName)
386     IPC_MESSAGE_HANDLER(FrameMsg_TransferUserActivationFrom,
387                         OnTransferUserActivationFrom)
388     IPC_MESSAGE_HANDLER(UnfreezableFrameMsg_DeleteProxy, OnDeleteProxy)
389     IPC_MESSAGE_UNHANDLED(handled = false)
390   IPC_END_MESSAGE_MAP()
391 
392   // Note: If |handled| is true, |this| may have been deleted.
393   return handled;
394 }
395 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)396 void RenderFrameProxy::OnAssociatedInterfaceRequest(
397     const std::string& interface_name,
398     mojo::ScopedInterfaceEndpointHandle handle) {
399   if (interface_name == blink::mojom::RemoteFrame::Name_) {
400     associated_interfaces_.TryBindInterface(interface_name, &handle);
401   } else if (interface_name == content::mojom::RenderFrameProxy::Name_) {
402     render_frame_proxy_receiver_.Bind(
403         mojo::PendingAssociatedReceiver<mojom::RenderFrameProxy>(
404             std::move(handle)));
405   }
406 }
407 
Send(IPC::Message * message)408 bool RenderFrameProxy::Send(IPC::Message* message) {
409   return RenderThread::Get()->Send(message);
410 }
411 
OnDeleteProxy()412 void RenderFrameProxy::OnDeleteProxy() {
413   DCHECK(web_frame_);
414   web_frame_->Detach();
415 }
416 
ChildProcessGone()417 void RenderFrameProxy::ChildProcessGone() {
418   crashed_ = true;
419   compositing_helper_->ChildFrameGone(local_frame_size(),
420                                       screen_info().device_scale_factor);
421 }
422 
OnUpdateOpener(int opener_routing_id)423 void RenderFrameProxy::OnUpdateOpener(int opener_routing_id) {
424   blink::WebFrame* opener = RenderFrameImpl::ResolveWebFrame(opener_routing_id);
425   web_frame_->SetOpener(opener);
426 }
427 
DidStartLoading()428 void RenderFrameProxy::DidStartLoading() {
429   web_frame_->DidStartLoading();
430 }
431 
OnDidUpdateName(const std::string & name,const std::string & unique_name)432 void RenderFrameProxy::OnDidUpdateName(const std::string& name,
433                                        const std::string& unique_name) {
434   web_frame_->SetReplicatedName(blink::WebString::FromUTF8(name));
435   unique_name_ = unique_name;
436 }
437 
OnTransferUserActivationFrom(int32_t source_routing_id)438 void RenderFrameProxy::OnTransferUserActivationFrom(int32_t source_routing_id) {
439   RenderFrameProxy* source_proxy =
440       RenderFrameProxy::FromRoutingID(source_routing_id);
441   if (!source_proxy)
442     return;
443   web_frame()->TransferUserActivationFrom(source_proxy->web_frame());
444 }
445 
DidUpdateVisualProperties(const cc::RenderFrameMetadata & metadata)446 void RenderFrameProxy::DidUpdateVisualProperties(
447     const cc::RenderFrameMetadata& metadata) {
448   if (!parent_local_surface_id_allocator_->UpdateFromChild(
449           metadata.local_surface_id_allocation.value_or(
450               viz::LocalSurfaceIdAllocation()))) {
451     return;
452   }
453 
454   // The viz::LocalSurfaceId has changed so we call SynchronizeVisualProperties
455   // here to embed it.
456   SynchronizeVisualProperties();
457 }
458 
EnableAutoResize(const gfx::Size & min_size,const gfx::Size & max_size)459 void RenderFrameProxy::EnableAutoResize(const gfx::Size& min_size,
460                                         const gfx::Size& max_size) {
461   DCHECK(ancestor_render_widget_);
462 
463   pending_visual_properties_.auto_resize_enabled = true;
464   pending_visual_properties_.min_size_for_auto_resize = min_size;
465   pending_visual_properties_.max_size_for_auto_resize = max_size;
466   SynchronizeVisualProperties();
467 }
468 
DisableAutoResize()469 void RenderFrameProxy::DisableAutoResize() {
470   DCHECK(ancestor_render_widget_);
471 
472   pending_visual_properties_.auto_resize_enabled = false;
473   SynchronizeVisualProperties();
474 }
475 
SetFrameSinkId(const viz::FrameSinkId & frame_sink_id)476 void RenderFrameProxy::SetFrameSinkId(const viz::FrameSinkId& frame_sink_id) {
477   FrameSinkIdChanged(frame_sink_id);
478 }
479 
SynchronizeVisualProperties()480 void RenderFrameProxy::SynchronizeVisualProperties() {
481   DCHECK(ancestor_render_widget_);
482 
483   if (!frame_sink_id_.is_valid() || crashed_)
484     return;
485 
486   // Note that the following flag is true if the capture sequence number
487   // actually changed. That is, it is false if we did not have
488   // |sent_visual_properties_|, which is different from
489   // |synchronized_props_changed| below.
490   bool capture_sequence_number_changed =
491       sent_visual_properties_ &&
492       sent_visual_properties_->capture_sequence_number !=
493           pending_visual_properties_.capture_sequence_number;
494 
495   if (web_frame_) {
496     pending_visual_properties_.compositor_viewport =
497         web_frame_->GetCompositingRect();
498   }
499 
500   bool synchronized_props_changed =
501       !sent_visual_properties_ ||
502       sent_visual_properties_->auto_resize_enabled !=
503           pending_visual_properties_.auto_resize_enabled ||
504       sent_visual_properties_->min_size_for_auto_resize !=
505           pending_visual_properties_.min_size_for_auto_resize ||
506       sent_visual_properties_->max_size_for_auto_resize !=
507           pending_visual_properties_.max_size_for_auto_resize ||
508       sent_visual_properties_->local_frame_size !=
509           pending_visual_properties_.local_frame_size ||
510       sent_visual_properties_->screen_space_rect.size() !=
511           pending_visual_properties_.screen_space_rect.size() ||
512       sent_visual_properties_->screen_info !=
513           pending_visual_properties_.screen_info ||
514       sent_visual_properties_->zoom_level !=
515           pending_visual_properties_.zoom_level ||
516       sent_visual_properties_->page_scale_factor !=
517           pending_visual_properties_.page_scale_factor ||
518       sent_visual_properties_->is_pinch_gesture_active !=
519           pending_visual_properties_.is_pinch_gesture_active ||
520       sent_visual_properties_->visible_viewport_size !=
521           pending_visual_properties_.visible_viewport_size ||
522       sent_visual_properties_->compositor_viewport !=
523           pending_visual_properties_.compositor_viewport ||
524       capture_sequence_number_changed;
525 
526   if (synchronized_props_changed) {
527     parent_local_surface_id_allocator_->GenerateId();
528     pending_visual_properties_.local_surface_id_allocation =
529         parent_local_surface_id_allocator_
530             ->GetCurrentLocalSurfaceIdAllocation();
531   }
532 
533   // If we're synchronizing surfaces, then use an infinite deadline to ensure
534   // everything is synchronized.
535   cc::DeadlinePolicy deadline = capture_sequence_number_changed
536                                     ? cc::DeadlinePolicy::UseInfiniteDeadline()
537                                     : cc::DeadlinePolicy::UseDefaultDeadline();
538   viz::SurfaceId surface_id(frame_sink_id_, GetLocalSurfaceId());
539   compositing_helper_->SetSurfaceId(
540       surface_id, pending_visual_properties_.compositor_viewport.size(),
541       deadline);
542 
543   bool rect_changed = !sent_visual_properties_ ||
544                       sent_visual_properties_->screen_space_rect !=
545                           pending_visual_properties_.screen_space_rect;
546   bool visual_properties_changed = synchronized_props_changed || rect_changed;
547 
548   if (!visual_properties_changed)
549     return;
550 
551   // Let the browser know about the updated view rect.
552   Send(new FrameHostMsg_SynchronizeVisualProperties(
553       routing_id_, frame_sink_id_, pending_visual_properties_));
554   sent_visual_properties_ = pending_visual_properties_;
555 
556   TRACE_EVENT_WITH_FLOW2(
557       TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
558       "RenderFrameProxy::SynchronizeVisualProperties Send Message",
559       TRACE_ID_GLOBAL(pending_visual_properties_.local_surface_id_allocation
560                           .local_surface_id()
561                           .submission_trace_id()),
562       TRACE_EVENT_FLAG_FLOW_OUT, "message",
563       "FrameHostMsg_SynchronizeVisualProperties", "local_surface_id",
564       pending_visual_properties_.local_surface_id_allocation.local_surface_id()
565           .ToString());
566 }
567 
FrameDetached(DetachType type)568 void RenderFrameProxy::FrameDetached(DetachType type) {
569   if (type == DetachType::kRemove) {
570     // Let the browser process know this subframe is removed, so that it is
571     // destroyed in its current process.
572     Send(new FrameHostMsg_Detach(routing_id_));
573   }
574 
575   web_frame_->Close();
576 
577   // If this proxy was associated with a provisional RenderFrame, and we're not
578   // in the process of swapping with it, clean it up as well.
579   if (type == DetachType::kRemove &&
580       provisional_frame_routing_id_ != MSG_ROUTING_NONE) {
581     RenderFrameImpl* provisional_frame =
582         RenderFrameImpl::FromRoutingID(provisional_frame_routing_id_);
583     // |provisional_frame| should always exist.  If it was deleted via
584     // FrameMsg_Delete right before this proxy was removed,
585     // RenderFrameImpl::frameDetached would've cleared this proxy's
586     // |provisional_frame_routing_id_| and we wouldn't get here.
587     CHECK(provisional_frame);
588     provisional_frame->GetWebFrame()->Detach();
589   }
590 
591   // Remove the entry in the WebFrame->RenderFrameProxy map, as the |web_frame_|
592   // is no longer valid.
593   auto it = g_frame_proxy_map.Get().find(web_frame_);
594   CHECK(it != g_frame_proxy_map.Get().end());
595   CHECK_EQ(it->second, this);
596   g_frame_proxy_map.Get().erase(it);
597 
598   web_frame_ = nullptr;
599 
600   delete this;
601 }
602 
ForwardPostMessage(blink::WebLocalFrame * source_frame,blink::WebRemoteFrame * target_frame,blink::WebSecurityOrigin target_origin,blink::WebDOMMessageEvent event)603 void RenderFrameProxy::ForwardPostMessage(
604     blink::WebLocalFrame* source_frame,
605     blink::WebRemoteFrame* target_frame,
606     blink::WebSecurityOrigin target_origin,
607     blink::WebDOMMessageEvent event) {
608   DCHECK(!web_frame_ || web_frame_ == target_frame);
609 
610   FrameMsg_PostMessage_Params params;
611   params.message =
612       new base::RefCountedData<blink::TransferableMessage>(event.AsMessage());
613   params.source_origin = event.Origin().Utf16();
614   if (!target_origin.IsNull())
615     params.target_origin = target_origin.ToString().Utf16();
616 
617   // Include the routing ID for the source frame (if one exists), which the
618   // browser process will translate into the routing ID for the equivalent
619   // frame in the target process.
620   params.source_routing_id = MSG_ROUTING_NONE;
621   if (source_frame) {
622     RenderFrameImpl* source_render_frame =
623         RenderFrameImpl::FromWebFrame(source_frame);
624     if (source_render_frame)
625       params.source_routing_id = source_render_frame->GetRoutingID();
626   }
627 
628   Send(new FrameHostMsg_RouteMessageEvent(routing_id_, params));
629 }
630 
Navigate(const blink::WebURLRequest & request,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,mojo::ScopedMessagePipeHandle blob_url_token)631 void RenderFrameProxy::Navigate(const blink::WebURLRequest& request,
632                                 bool should_replace_current_entry,
633                                 bool is_opener_navigation,
634                                 bool initiator_frame_has_download_sandbox_flag,
635                                 bool blocking_downloads_in_sandbox_enabled,
636                                 bool initiator_frame_is_ad,
637                                 mojo::ScopedMessagePipeHandle blob_url_token) {
638   // The request must always have a valid initiator origin.
639   DCHECK(!request.RequestorOrigin().IsNull());
640 
641   FrameHostMsg_OpenURL_Params params;
642   params.url = request.Url();
643   params.initiator_origin = request.RequestorOrigin();
644   params.post_body = GetRequestBodyForWebURLRequest(request);
645   DCHECK_EQ(!!params.post_body, request.HttpMethod().Utf8() == "POST");
646   params.extra_headers = GetWebURLRequestHeadersAsString(request);
647   params.referrer.url = blink::WebStringToGURL(request.ReferrerString());
648   params.referrer.policy = request.GetReferrerPolicy();
649   params.disposition = WindowOpenDisposition::CURRENT_TAB;
650   params.should_replace_current_entry = should_replace_current_entry;
651   params.user_gesture = request.HasUserGesture();
652   params.triggering_event_info = blink::TriggeringEventInfo::kUnknown;
653   params.blob_url_token = blob_url_token.release();
654 
655   // Note: For the AdFrame/Sandbox download policy here it only covers the case
656   // where the navigation initiator frame is ad. The download_policy may be
657   // further augmented in RenderFrameProxyHost::OnOpenURL if the navigating
658   // frame is ad or sandboxed.
659   RenderFrameImpl::MaybeSetDownloadFramePolicy(
660       is_opener_navigation, request, web_frame_->GetSecurityOrigin(),
661       initiator_frame_has_download_sandbox_flag,
662       blocking_downloads_in_sandbox_enabled, initiator_frame_is_ad,
663       &params.download_policy);
664 
665   Send(new FrameHostMsg_OpenURL(routing_id_, params));
666 }
667 
FrameRectsChanged(const blink::WebRect & local_frame_rect,const blink::WebRect & screen_space_rect)668 void RenderFrameProxy::FrameRectsChanged(
669     const blink::WebRect& local_frame_rect,
670     const blink::WebRect& screen_space_rect) {
671   DCHECK(ancestor_render_widget_);
672 
673   pending_visual_properties_.screen_space_rect = gfx::Rect(screen_space_rect);
674   pending_visual_properties_.local_frame_size =
675       gfx::Size(local_frame_rect.width, local_frame_rect.height);
676   pending_visual_properties_.screen_info =
677       ancestor_render_widget_->GetOriginalScreenInfo();
678   if (crashed_) {
679     // Update the sad page to match the current size.
680     compositing_helper_->ChildFrameGone(local_frame_size(),
681                                         screen_info().device_scale_factor);
682     return;
683   }
684   SynchronizeVisualProperties();
685 }
686 
UpdateRemoteViewportIntersection(const blink::ViewportIntersectionState & intersection_state)687 void RenderFrameProxy::UpdateRemoteViewportIntersection(
688     const blink::ViewportIntersectionState& intersection_state) {
689   DCHECK(ancestor_render_widget_);
690   // TODO(szager): compositor_viewport is propagated twice, via
691   // ViewportIntersectionState and also via FrameVisualProperties. It should
692   // only go through FrameVisualProperties.
693   if (pending_visual_properties_.compositor_viewport !=
694       gfx::Rect(intersection_state.compositor_visible_rect)) {
695     SynchronizeVisualProperties();
696   }
697   Send(new FrameHostMsg_UpdateViewportIntersection(routing_id_,
698                                                    intersection_state));
699 }
700 
DidChangeOpener(blink::WebFrame * opener)701 void RenderFrameProxy::DidChangeOpener(blink::WebFrame* opener) {
702   // A proxy shouldn't normally be disowning its opener.  It is possible to get
703   // here when a proxy that is being detached clears its opener, in which case
704   // there is no need to notify the browser process.
705   if (!opener)
706     return;
707 
708   // Only a LocalFrame (i.e., the caller of window.open) should be able to
709   // update another frame's opener.
710   DCHECK(opener->IsWebLocalFrame());
711 
712   int opener_routing_id =
713       RenderFrameImpl::FromWebFrame(opener->ToWebLocalFrame())->GetRoutingID();
714   Send(new FrameHostMsg_DidChangeOpener(routing_id_, opener_routing_id));
715 }
716 
AdvanceFocus(blink::mojom::FocusType type,blink::WebLocalFrame * source)717 void RenderFrameProxy::AdvanceFocus(blink::mojom::FocusType type,
718                                     blink::WebLocalFrame* source) {
719   int source_routing_id = RenderFrameImpl::FromWebFrame(source)->GetRoutingID();
720   Send(new FrameHostMsg_AdvanceFocus(routing_id_, type, source_routing_id));
721 }
722 
GetDevToolsFrameToken()723 base::UnguessableToken RenderFrameProxy::GetDevToolsFrameToken() {
724   return devtools_frame_token_;
725 }
726 
GetLayer()727 cc::Layer* RenderFrameProxy::GetLayer() {
728   return embedded_layer_.get();
729 }
730 
SetLayer(scoped_refptr<cc::Layer> layer,bool prevent_contents_opaque_changes,bool is_surface_layer)731 void RenderFrameProxy::SetLayer(scoped_refptr<cc::Layer> layer,
732                                 bool prevent_contents_opaque_changes,
733                                 bool is_surface_layer) {
734   if (web_frame()) {
735     web_frame()->SetCcLayer(layer.get(), prevent_contents_opaque_changes,
736                             is_surface_layer);
737   }
738   embedded_layer_ = std::move(layer);
739 }
740 
GetSadPageBitmap()741 SkBitmap* RenderFrameProxy::GetSadPageBitmap() {
742   return GetContentClient()->renderer()->GetSadWebViewBitmap();
743 }
744 
Print(const blink::WebRect & rect,cc::PaintCanvas * canvas)745 uint32_t RenderFrameProxy::Print(const blink::WebRect& rect,
746                                  cc::PaintCanvas* canvas) {
747 #if BUILDFLAG(ENABLE_PRINTING)
748   auto* metafile = canvas->GetPrintingMetafile();
749   DCHECK(metafile);
750 
751   // Create a place holder content for the remote frame so it can be replaced
752   // with actual content later.
753   uint32_t content_id =
754       metafile->CreateContentForRemoteFrame(rect, routing_id_);
755 
756   // Inform browser to print the remote subframe.
757   Send(new FrameHostMsg_PrintCrossProcessSubframe(
758       routing_id_, rect, metafile->GetDocumentCookie()));
759   return content_id;
760 #else
761   return 0;
762 #endif
763 }
764 
GetLocalSurfaceId() const765 const viz::LocalSurfaceId& RenderFrameProxy::GetLocalSurfaceId() const {
766   return parent_local_surface_id_allocator_
767       ->GetCurrentLocalSurfaceIdAllocation()
768       .local_surface_id();
769 }
770 
GetFrameProxyHost()771 mojom::RenderFrameProxyHost* RenderFrameProxy::GetFrameProxyHost() {
772   if (!frame_proxy_host_remote_.is_bound())
773     GetRemoteAssociatedInterfaces()->GetInterface(&frame_proxy_host_remote_);
774   return frame_proxy_host_remote_.get();
775 }
776 
777 blink::AssociatedInterfaceProvider*
GetRemoteAssociatedInterfaces()778 RenderFrameProxy::GetRemoteAssociatedInterfaces() {
779   if (!remote_associated_interfaces_) {
780     ChildThreadImpl* thread = ChildThreadImpl::current();
781     if (thread) {
782       mojo::PendingAssociatedRemote<blink::mojom::AssociatedInterfaceProvider>
783           remote_interfaces;
784       thread->GetRemoteRouteProvider()->GetRoute(
785           routing_id_, remote_interfaces.InitWithNewEndpointAndPassReceiver());
786       remote_associated_interfaces_ =
787           std::make_unique<blink::AssociatedInterfaceProvider>(
788               std::move(remote_interfaces));
789     } else {
790       // In some tests the thread may be null,
791       // so set up a self-contained interface provider instead.
792       remote_associated_interfaces_ =
793           std::make_unique<blink::AssociatedInterfaceProvider>(nullptr);
794     }
795   }
796   return remote_associated_interfaces_.get();
797 }
798 
WasEvicted()799 void RenderFrameProxy::WasEvicted() {
800   // On eviction, the last SurfaceId is invalidated. We need to allocate a new
801   // id.
802   ResendVisualProperties();
803 }
804 
FrameSinkIdChanged(const viz::FrameSinkId & frame_sink_id)805 void RenderFrameProxy::FrameSinkIdChanged(
806     const viz::FrameSinkId& frame_sink_id) {
807   crashed_ = false;
808   // The same ParentLocalSurfaceIdAllocator cannot provide LocalSurfaceIds for
809   // two different frame sinks, so recreate it here.
810   if (frame_sink_id_ != frame_sink_id) {
811     parent_local_surface_id_allocator_ =
812         std::make_unique<viz::ParentLocalSurfaceIdAllocator>();
813   }
814   frame_sink_id_ = frame_sink_id;
815 
816   // Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
817   // changes.
818   ResendVisualProperties();
819 }
820 
821 }  // namespace content
822