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 "third_party/blink/renderer/core/frame/remote_frame.h"
6 
7 #include "cc/layers/surface_layer.h"
8 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
9 #include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h"
10 #include "third_party/blink/public/mojom/frame/intrinsic_sizing_info.mojom-blink.h"
11 #include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
12 #include "third_party/blink/public/platform/interface_registry.h"
13 #include "third_party/blink/public/web/web_frame.h"
14 #include "third_party/blink/public/web/web_view.h"
15 #include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_options.h"
16 #include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"
17 #include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
18 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
19 #include "third_party/blink/renderer/core/frame/local_frame.h"
20 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
21 #include "third_party/blink/renderer/core/frame/remote_dom_window.h"
22 #include "third_party/blink/renderer/core/frame/remote_frame_client.h"
23 #include "third_party/blink/renderer/core/frame/remote_frame_owner.h"
24 #include "third_party/blink/renderer/core/frame/remote_frame_view.h"
25 #include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
26 #include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
27 #include "third_party/blink/renderer/core/inspector/console_message.h"
28 #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
29 #include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h"
30 #include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
31 #include "third_party/blink/renderer/core/layout/layout_view.h"
32 #include "third_party/blink/renderer/core/loader/frame_load_request.h"
33 #include "third_party/blink/renderer/core/loader/frame_loader.h"
34 #include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
35 #include "third_party/blink/renderer/core/page/page.h"
36 #include "third_party/blink/renderer/core/page/plugin_script_forbidden_scope.h"
37 #include "third_party/blink/renderer/core/paint/paint_layer.h"
38 #include "third_party/blink/renderer/core/probe/core_probes.h"
39 #include "third_party/blink/renderer/core/timing/dom_window_performance.h"
40 #include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
41 #include "third_party/blink/renderer/platform/heap/heap.h"
42 #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h"
43 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
44 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h"
45 #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
46 #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
47 #include "third_party/blink/renderer/platform/weborigin/security_policy.h"
48 
49 namespace blink {
50 
51 namespace {
DeNormalizeRect(const gfx::RectF & normalized,const IntRect & base)52 FloatRect DeNormalizeRect(const gfx::RectF& normalized, const IntRect& base) {
53   FloatRect result(normalized);
54   result.Scale(base.Width(), base.Height());
55   result.MoveBy(FloatPoint(base.Location()));
56   return result;
57 }
58 
59 }  // namespace
60 
RemoteFrame(RemoteFrameClient * client,Page & page,FrameOwner * owner,WindowAgentFactory * inheriting_agent_factory,InterfaceRegistry * interface_registry,AssociatedInterfaceProvider * associated_interface_provider)61 RemoteFrame::RemoteFrame(
62     RemoteFrameClient* client,
63     Page& page,
64     FrameOwner* owner,
65     WindowAgentFactory* inheriting_agent_factory,
66     InterfaceRegistry* interface_registry,
67     AssociatedInterfaceProvider* associated_interface_provider)
68     : Frame(client,
69             page,
70             owner,
71             MakeGarbageCollected<RemoteWindowProxyManager>(*this),
72             inheriting_agent_factory) {
73   dom_window_ = MakeGarbageCollected<RemoteDOMWindow>(*this);
74 
75   interface_registry->AddAssociatedInterface(WTF::BindRepeating(
76       &RemoteFrame::BindToReceiver, WrapWeakPersistent(this)));
77 
78   associated_interface_provider->GetInterface(
79       remote_frame_host_remote_.BindNewEndpointAndPassReceiver());
80 
81   UpdateInertIfPossible();
82   UpdateInheritedEffectiveTouchActionIfPossible();
83   UpdateVisibleToHitTesting();
84   Initialize();
85 }
86 
~RemoteFrame()87 RemoteFrame::~RemoteFrame() {
88   DCHECK(!view_);
89 }
90 
Trace(Visitor * visitor)91 void RemoteFrame::Trace(Visitor* visitor) {
92   visitor->Trace(view_);
93   visitor->Trace(security_context_);
94   Frame::Trace(visitor);
95 }
96 
Navigate(FrameLoadRequest & frame_request,WebFrameLoadType frame_load_type)97 void RemoteFrame::Navigate(FrameLoadRequest& frame_request,
98                            WebFrameLoadType frame_load_type) {
99   if (!navigation_rate_limiter().CanProceed())
100     return;
101 
102   frame_request.SetFrameType(IsMainFrame()
103                                  ? mojom::RequestContextFrameType::kTopLevel
104                                  : mojom::RequestContextFrameType::kNested);
105 
106   const KURL& url = frame_request.GetResourceRequest().Url();
107   if (!frame_request.CanDisplay(url)) {
108     if (frame_request.OriginDocument()) {
109       frame_request.OriginDocument()->AddConsoleMessage(
110           MakeGarbageCollected<ConsoleMessage>(
111               mojom::ConsoleMessageSource::kSecurity,
112               mojom::ConsoleMessageLevel::kError,
113               "Not allowed to load local resource: " + url.ElidedString()));
114     }
115     return;
116   }
117 
118   // The process where this frame actually lives won't have sufficient
119   // information to upgrade the url, since it won't have access to the
120   // originDocument. Do it now.
121   const FetchClientSettingsObject* fetch_client_settings_object = nullptr;
122   if (frame_request.OriginDocument()) {
123     fetch_client_settings_object = &frame_request.OriginDocument()
124                                         ->Fetcher()
125                                         ->GetProperties()
126                                         .GetFetchClientSettingsObject();
127   }
128   LocalFrame* frame = frame_request.OriginDocument()
129                           ? frame_request.OriginDocument()->GetFrame()
130                           : nullptr;
131   MixedContentChecker::UpgradeInsecureRequest(
132       frame_request.GetResourceRequest(), fetch_client_settings_object,
133       frame_request.OriginDocument()
134           ? frame_request.OriginDocument()->ToExecutionContext()
135           : nullptr,
136       frame_request.GetFrameType(),
137       frame ? frame->GetContentSettingsClient() : nullptr);
138 
139   // Navigations in portal contexts do not create back/forward entries.
140   if (GetPage()->InsidePortal() &&
141       frame_load_type == WebFrameLoadType::kStandard) {
142     frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
143   }
144 
145   bool is_opener_navigation = false;
146   bool initiator_frame_has_download_sandbox_flag = false;
147   bool initiator_frame_is_ad = false;
148 
149   if (frame) {
150     is_opener_navigation = frame->Client()->Opener() == this;
151     initiator_frame_has_download_sandbox_flag =
152         frame->GetSecurityContext() &&
153         frame->GetSecurityContext()->IsSandboxed(
154             mojom::blink::WebSandboxFlags::kDownloads);
155     initiator_frame_is_ad = frame->IsAdSubframe();
156     if (frame_request.ClientRedirectReason() != ClientNavigationReason::kNone) {
157       probe::FrameRequestedNavigation(frame, this, url,
158                                       frame_request.ClientRedirectReason());
159     }
160   }
161 
162   Client()->Navigate(frame_request.GetResourceRequest(),
163                      frame_load_type == WebFrameLoadType::kReplaceCurrentItem,
164                      is_opener_navigation,
165                      initiator_frame_has_download_sandbox_flag,
166                      initiator_frame_is_ad, frame_request.GetBlobURLToken());
167 }
168 
DetachImpl(FrameDetachType type)169 void RemoteFrame::DetachImpl(FrameDetachType type) {
170   PluginScriptForbiddenScope forbid_plugin_destructor_scripting;
171   DetachChildren();
172   if (!Client())
173     return;
174 
175   // Clean up the frame's view if needed. A remote frame only has a view if
176   // the parent is a local frame.
177   if (view_)
178     view_->Dispose();
179   GetWindowProxyManager()->ClearForClose();
180   SetView(nullptr);
181   // ... the RemoteDOMWindow will need to be informed of detachment,
182   // as otherwise it will keep a strong reference back to this RemoteFrame.
183   // That combined with wrappers (owned and kept alive by RemoteFrame) keeping
184   // persistent strong references to RemoteDOMWindow will prevent the GCing
185   // of all these objects. Break the cycle by notifying of detachment.
186   To<RemoteDOMWindow>(dom_window_.Get())->FrameDetached();
187   if (cc_layer_)
188     SetCcLayer(nullptr, false, false);
189   receiver_.reset();
190 }
191 
DetachDocument()192 bool RemoteFrame::DetachDocument() {
193   DetachChildren();
194   return !!GetPage();
195 }
196 
CheckCompleted()197 void RemoteFrame::CheckCompleted() {
198   // Notify the client so that the corresponding LocalFrame can do the check.
199   GetRemoteFrameHostRemote().CheckCompleted();
200 }
201 
GetSecurityContext() const202 const RemoteSecurityContext* RemoteFrame::GetSecurityContext() const {
203   return &security_context_;
204 }
205 
ShouldClose()206 bool RemoteFrame::ShouldClose() {
207   // TODO(nasko): Implement running the beforeunload handler in the actual
208   // LocalFrame running in a different process and getting back a real result.
209   return true;
210 }
211 
SetIsInert(bool inert)212 void RemoteFrame::SetIsInert(bool inert) {
213   if (inert != is_inert_)
214     GetRemoteFrameHostRemote().SetIsInert(inert);
215   is_inert_ = inert;
216 }
217 
SetInheritedEffectiveTouchAction(TouchAction touch_action)218 void RemoteFrame::SetInheritedEffectiveTouchAction(TouchAction touch_action) {
219   if (inherited_effective_touch_action_ != touch_action)
220     GetRemoteFrameHostRemote().SetInheritedEffectiveTouchAction(touch_action);
221   inherited_effective_touch_action_ = touch_action;
222 }
223 
BubbleLogicalScrollFromChildFrame(mojom::blink::ScrollDirection direction,ScrollGranularity granularity,Frame * child)224 bool RemoteFrame::BubbleLogicalScrollFromChildFrame(
225     mojom::blink::ScrollDirection direction,
226     ScrollGranularity granularity,
227     Frame* child) {
228   DCHECK(child->Client());
229   To<LocalFrame>(child)
230       ->GetLocalFrameHostRemote()
231       .BubbleLogicalScrollInParentFrame(direction, granularity);
232   return false;
233 }
234 
RenderFallbackContent()235 void RemoteFrame::RenderFallbackContent() {
236   // TODO(ekaramad): If the owner renders its own content, then the current
237   // ContentFrame() should detach and free-up the OOPIF process (see
238   // https://crbug.com/850223).
239   auto* owner = DeprecatedLocalOwner();
240   DCHECK(IsA<HTMLObjectElement>(owner));
241   owner->RenderFallbackContent(this);
242 }
243 
AddResourceTimingFromChild(mojom::blink::ResourceTimingInfoPtr timing)244 void RemoteFrame::AddResourceTimingFromChild(
245     mojom::blink::ResourceTimingInfoPtr timing) {
246   HTMLFrameOwnerElement* owner_element = To<HTMLFrameOwnerElement>(Owner());
247   DCHECK(owner_element);
248 
249   // TODO(https://crbug.com/900700): Take a Mojo pending receiver for
250   // WorkerTimingContainer for navigation from the calling function.
251   DOMWindowPerformance::performance(*owner_element->GetDocument().domWindow())
252       ->AddResourceTiming(std::move(timing), owner_element->localName(),
253                           /*worker_timing_receiver=*/mojo::NullReceiver());
254 }
255 
DidStartLoading()256 void RemoteFrame::DidStartLoading() {
257   SetIsLoading(true);
258 }
259 
DidStopLoading()260 void RemoteFrame::DidStopLoading() {
261   SetIsLoading(false);
262 
263   // When a subframe finishes loading, the parent should check if *all*
264   // subframes have finished loading (which may mean that the parent can declare
265   // that the parent itself has finished loading). This remote-subframe-focused
266   // code has a local-subframe equivalent in FrameLoader::DidFinishNavigation.
267   Frame* parent = Tree().Parent();
268   if (parent)
269     parent->CheckCompleted();
270 }
271 
DidFocus()272 void RemoteFrame::DidFocus() {
273   GetRemoteFrameHostRemote().DidFocusFrame();
274 }
275 
SetView(RemoteFrameView * view)276 void RemoteFrame::SetView(RemoteFrameView* view) {
277   // Oilpan: as RemoteFrameView performs no finalization actions,
278   // no explicit Dispose() of it needed here. (cf. LocalFrameView::Dispose().)
279   view_ = view;
280 }
281 
CreateView()282 void RemoteFrame::CreateView() {
283   // If the RemoteFrame does not have a LocalFrame parent, there's no need to
284   // create a EmbeddedContentView for it.
285   if (!DeprecatedLocalOwner())
286     return;
287 
288   DCHECK(!DeprecatedLocalOwner()->OwnedEmbeddedContentView());
289 
290   SetView(MakeGarbageCollected<RemoteFrameView>(this));
291 
292   if (OwnerLayoutObject())
293     DeprecatedLocalOwner()->SetEmbeddedContentView(view_);
294 }
295 
GetRemoteFrameHostRemote()296 mojom::blink::RemoteFrameHost& RemoteFrame::GetRemoteFrameHostRemote() {
297   return *remote_frame_host_remote_.get();
298 }
299 
Client() const300 RemoteFrameClient* RemoteFrame::Client() const {
301   return static_cast<RemoteFrameClient*>(Frame::Client());
302 }
303 
DidChangeVisibleToHitTesting()304 void RemoteFrame::DidChangeVisibleToHitTesting() {
305   if (!cc_layer_ || !is_surface_layer_)
306     return;
307 
308   static_cast<cc::SurfaceLayer*>(cc_layer_)->SetHasPointerEventsNone(
309       IsIgnoredForHitTest());
310 }
311 
SetReplicatedFeaturePolicyHeaderAndOpenerPolicies(const ParsedFeaturePolicy & parsed_header,const FeaturePolicy::FeatureState & opener_feature_state)312 void RemoteFrame::SetReplicatedFeaturePolicyHeaderAndOpenerPolicies(
313     const ParsedFeaturePolicy& parsed_header,
314     const FeaturePolicy::FeatureState& opener_feature_state) {
315   feature_policy_header_ = parsed_header;
316   if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
317     DCHECK(opener_feature_state.empty() || IsMainFrame());
318     if (OpenerFeatureState().empty()) {
319       SetOpenerFeatureState(opener_feature_state);
320     }
321   }
322   ApplyReplicatedFeaturePolicyHeader();
323 }
324 
SetReplicatedSandboxFlags(mojom::blink::WebSandboxFlags flags)325 void RemoteFrame::SetReplicatedSandboxFlags(
326     mojom::blink::WebSandboxFlags flags) {
327   security_context_.ResetAndEnforceSandboxFlags(flags);
328 }
329 
SetInsecureRequestPolicy(mojom::blink::InsecureRequestPolicy policy)330 void RemoteFrame::SetInsecureRequestPolicy(
331     mojom::blink::InsecureRequestPolicy policy) {
332   security_context_.SetInsecureRequestPolicy(policy);
333 }
334 
SetInsecureNavigationsSet(const WebVector<unsigned> & set)335 void RemoteFrame::SetInsecureNavigationsSet(const WebVector<unsigned>& set) {
336   security_context_.SetInsecureNavigationsSet(set);
337 }
338 
WillEnterFullscreen()339 void RemoteFrame::WillEnterFullscreen() {
340   // This should only ever be called when the FrameOwner is local.
341   HTMLFrameOwnerElement* owner_element = To<HTMLFrameOwnerElement>(Owner());
342 
343   // Call |requestFullscreen()| on |ownerElement| to make it the pending
344   // fullscreen element in anticipation of the coming |didEnterFullscreen()|
345   // call.
346   //
347   // PrefixedForCrossProcessDescendant is necessary because:
348   //  - The fullscreen element ready check and other checks should be bypassed.
349   //  - |ownerElement| will need :-webkit-full-screen-ancestor style in addition
350   //    to :fullscreen.
351   //
352   // TODO(alexmos): currently, this assumes prefixed requests, but in the
353   // future, this should plumb in information about which request type
354   // (prefixed or unprefixed) to use for firing fullscreen events.
355   Fullscreen::RequestFullscreen(
356       *owner_element, FullscreenOptions::Create(),
357       Fullscreen::RequestType::kPrefixedForCrossProcessDescendant);
358 }
359 
AddReplicatedContentSecurityPolicies(WTF::Vector<network::mojom::blink::ContentSecurityPolicyHeaderPtr> headers)360 void RemoteFrame::AddReplicatedContentSecurityPolicies(
361     WTF::Vector<network::mojom::blink::ContentSecurityPolicyHeaderPtr>
362         headers) {
363   for (auto& header : headers) {
364     GetSecurityContext()->GetContentSecurityPolicy()->AddPolicyFromHeaderValue(
365         header->header_value, header->type, header->source);
366   }
367 }
368 
ResetReplicatedContentSecurityPolicy()369 void RemoteFrame::ResetReplicatedContentSecurityPolicy() {
370   security_context_.ResetReplicatedContentSecurityPolicy();
371 }
372 
EnforceInsecureNavigationsSet(const WTF::Vector<uint32_t> & set)373 void RemoteFrame::EnforceInsecureNavigationsSet(
374     const WTF::Vector<uint32_t>& set) {
375   security_context_.SetInsecureNavigationsSet(set);
376 }
377 
SetFrameOwnerProperties(mojom::blink::FrameOwnerPropertiesPtr properties)378 void RemoteFrame::SetFrameOwnerProperties(
379     mojom::blink::FrameOwnerPropertiesPtr properties) {
380   Frame::ApplyFrameOwnerProperties(std::move(properties));
381 }
382 
EnforceInsecureRequestPolicy(mojom::blink::InsecureRequestPolicy policy)383 void RemoteFrame::EnforceInsecureRequestPolicy(
384     mojom::blink::InsecureRequestPolicy policy) {
385   SetInsecureRequestPolicy(policy);
386 }
387 
SetReplicatedOrigin(const scoped_refptr<const SecurityOrigin> & origin,bool is_potentially_trustworthy_unique_origin)388 void RemoteFrame::SetReplicatedOrigin(
389     const scoped_refptr<const SecurityOrigin>& origin,
390     bool is_potentially_trustworthy_unique_origin) {
391   scoped_refptr<SecurityOrigin> security_origin = origin->IsolatedCopy();
392   security_origin->SetOpaqueOriginIsPotentiallyTrustworthy(
393       is_potentially_trustworthy_unique_origin);
394   security_context_.SetReplicatedOrigin(security_origin);
395   ApplyReplicatedFeaturePolicyHeader();
396 
397   // If the origin of a remote frame changed, the accessibility object for the
398   // owner element now points to a different child.
399   //
400   // TODO(dmazzoni, dcheng): there's probably a better way to solve this.
401   // Run SitePerProcessAccessibilityBrowserTest.TwoCrossSiteNavigations to
402   // ensure an alternate fix works.  http://crbug.com/566222
403   FrameOwner* owner = Owner();
404   HTMLElement* owner_element = DynamicTo<HTMLFrameOwnerElement>(owner);
405   if (owner_element) {
406     AXObjectCache* cache = owner_element->GetDocument().ExistingAXObjectCache();
407     if (cache)
408       cache->ChildrenChanged(owner_element);
409   }
410 }
411 
SetReplicatedAdFrameType(mojom::blink::AdFrameType ad_frame_type)412 void RemoteFrame::SetReplicatedAdFrameType(
413     mojom::blink::AdFrameType ad_frame_type) {
414   if (ad_frame_type_ == mojom::blink::AdFrameType::kNonAd) {
415     ad_frame_type_ = ad_frame_type;
416   } else {
417     DCHECK_EQ(ad_frame_type_, ad_frame_type);
418   }
419 }
420 
DispatchLoadEventForFrameOwner()421 void RemoteFrame::DispatchLoadEventForFrameOwner() {
422   DCHECK(Owner()->IsLocal());
423   Owner()->DispatchLoad();
424 }
425 
Collapse(bool collapsed)426 void RemoteFrame::Collapse(bool collapsed) {
427   FrameOwner* owner = Owner();
428   To<HTMLFrameOwnerElement>(owner)->SetCollapsed(collapsed);
429 }
430 
Focus()431 void RemoteFrame::Focus() {
432   FocusImpl();
433 }
434 
SetHadStickyUserActivationBeforeNavigation(bool value)435 void RemoteFrame::SetHadStickyUserActivationBeforeNavigation(bool value) {
436   Frame::SetHadStickyUserActivationBeforeNavigation(value);
437 }
438 
SetNeedsOcclusionTracking(bool needs_tracking)439 void RemoteFrame::SetNeedsOcclusionTracking(bool needs_tracking) {
440   View()->SetNeedsOcclusionTracking(needs_tracking);
441 }
442 
BubbleLogicalScroll(mojom::blink::ScrollDirection direction,ui::ScrollGranularity granularity)443 void RemoteFrame::BubbleLogicalScroll(mojom::blink::ScrollDirection direction,
444                                       ui::ScrollGranularity granularity) {
445   Frame* parent_frame = Client()->Parent();
446   DCHECK(parent_frame);
447   DCHECK(parent_frame->IsLocalFrame());
448 
449   parent_frame->BubbleLogicalScrollFromChildFrame(direction, granularity, this);
450 }
451 
UpdateUserActivationState(mojom::blink::UserActivationUpdateType update_type)452 void RemoteFrame::UpdateUserActivationState(
453     mojom::blink::UserActivationUpdateType update_type) {
454   switch (update_type) {
455     case mojom::blink::UserActivationUpdateType::kNotifyActivation:
456       NotifyUserActivationInLocalTree();
457       break;
458     case mojom::blink::UserActivationUpdateType::kConsumeTransientActivation:
459       ConsumeTransientUserActivationInLocalTree();
460       break;
461     case mojom::blink::UserActivationUpdateType::kClearActivation:
462       ClearUserActivationInLocalTree();
463       break;
464     case mojom::blink::UserActivationUpdateType::
465         kNotifyActivationPendingBrowserVerification:
466       NOTREACHED() << "Unexpected UserActivationUpdateType from browser";
467       break;
468   }
469 }
470 
SetEmbeddingToken(const base::UnguessableToken & embedding_token)471 void RemoteFrame::SetEmbeddingToken(
472     const base::UnguessableToken& embedding_token) {
473   FrameOwner* owner = Owner();
474   To<HTMLFrameOwnerElement>(owner)->SetEmbeddingToken(embedding_token);
475 }
476 
SetPageFocus(bool is_focused)477 void RemoteFrame::SetPageFocus(bool is_focused) {
478   WebFrame::FromFrame(this)->View()->SetFocus(is_focused);
479 }
480 
ScrollRectToVisible(const gfx::Rect & rect_to_scroll,mojom::blink::ScrollIntoViewParamsPtr params)481 void RemoteFrame::ScrollRectToVisible(
482     const gfx::Rect& rect_to_scroll,
483     mojom::blink::ScrollIntoViewParamsPtr params) {
484   Element* owner_element = DeprecatedLocalOwner();
485   LayoutObject* owner_object = owner_element->GetLayoutObject();
486   if (!owner_object) {
487     // The LayoutObject could be nullptr by the time we get here. For instance
488     // <iframe>'s style might have been set to 'display: none' right after
489     // scrolling starts in the OOPIF's process (see https://crbug.com/777811).
490     return;
491   }
492 
493   // Schedule the scroll.
494   PhysicalRect absolute_rect = owner_object->LocalToAncestorRect(
495       PhysicalRect(LayoutUnit(rect_to_scroll.x()),
496                    LayoutUnit(rect_to_scroll.y()),
497                    LayoutUnit(rect_to_scroll.width()),
498                    LayoutUnit(rect_to_scroll.height())),
499       owner_object->View());
500 
501   if (!params->zoom_into_rect ||
502       !owner_object->GetDocument().GetFrame()->LocalFrameRoot().IsMainFrame()) {
503     owner_object->ScrollRectToVisible(absolute_rect, std::move(params));
504     return;
505   }
506 
507   // ZoomAndScrollToFocusedEditableElementRect will scroll only the layout and
508   // visual viewports. Ensure the element is actually visible in the viewport
509   // scrolling layer. (i.e. isn't clipped by some other content).
510   auto relative_element_bounds = params->relative_element_bounds;
511   auto relative_caret_bounds = params->relative_caret_bounds;
512 
513   params->stop_at_main_frame_layout_viewport = true;
514   absolute_rect =
515       owner_object->ScrollRectToVisible(absolute_rect, std::move(params));
516 
517   IntRect rect_in_document =
518       owner_object->GetDocument()
519           .GetFrame()
520           ->LocalFrameRoot()
521           .View()
522           ->RootFrameToDocument(EnclosingIntRect(
523               owner_element->GetDocument().View()->ConvertToRootFrame(
524                   absolute_rect)));
525   IntRect element_bounds_in_document = EnclosingIntRect(
526       DeNormalizeRect(relative_element_bounds, rect_in_document));
527   IntRect caret_bounds_in_document = EnclosingIntRect(
528       DeNormalizeRect(relative_caret_bounds, rect_in_document));
529 
530   // This is due to something such as scroll focused editable element into
531   // view on Android which also requires an automatic zoom into legible scale.
532   // This is handled by main frame's WebView.
533   WebFrame::FromFrame(this)->View()->ZoomAndScrollToFocusedEditableElementRect(
534       element_bounds_in_document, caret_bounds_in_document, true);
535 }
536 
IntrinsicSizingInfoOfChildChanged(mojom::blink::IntrinsicSizingInfoPtr info)537 void RemoteFrame::IntrinsicSizingInfoOfChildChanged(
538     mojom::blink::IntrinsicSizingInfoPtr info) {
539   FrameOwner* owner = Owner();
540   // Only communication from HTMLPluginElement-owned subframes is allowed
541   // at present. This includes <embed> and <object> tags.
542   if (!owner || !owner->IsPlugin())
543     return;
544 
545   // TODO(https://crbug.com/1044304): Should either remove the native
546   // C++ Blink type and use the Mojo type everywhere or typemap the
547   // Mojo type to the pre-existing native C++ Blink type.
548   IntrinsicSizingInfo sizing_info;
549   sizing_info.size = FloatSize(info->size);
550   sizing_info.aspect_ratio = FloatSize(info->aspect_ratio);
551   sizing_info.has_width = info->has_width;
552   sizing_info.has_height = info->has_height;
553   View()->SetIntrinsicSizeInfo(sizing_info);
554 
555   owner->IntrinsicSizingInfoChanged();
556 }
557 
558 // Update the proxy's SecurityContext with new sandbox flags or feature policy
559 // that were set during navigation. Unlike changes to the FrameOwner, which are
560 // handled by RenderFrameProxy::OnDidUpdateFramePolicy, these changes should be
561 // considered effective immediately.
562 //
563 // These flags / policy are needed on the remote frame's SecurityContext to
564 // ensure that sandbox flags and feature policy are inherited properly if this
565 // proxy ever parents a local frame.
DidSetFramePolicyHeaders(mojom::blink::WebSandboxFlags sandbox_flags,const Vector<ParsedFeaturePolicyDeclaration> & parsed_feature_policy)566 void RemoteFrame::DidSetFramePolicyHeaders(
567     mojom::blink::WebSandboxFlags sandbox_flags,
568     const Vector<ParsedFeaturePolicyDeclaration>& parsed_feature_policy) {
569   SetReplicatedSandboxFlags(sandbox_flags);
570   // Convert from WTF::Vector<ParsedFeaturePolicyDeclaration>
571   // to std::vector<ParsedFeaturePolicyDeclaration>, since ParsedFeaturePolicy
572   // is an alias for the later.
573   //
574   // TODO(crbug.com/1047273): Remove this conversion by switching
575   // ParsedFeaturePolicy to operate over Vector
576   ParsedFeaturePolicy parsed_feature_policy_copy(parsed_feature_policy.size());
577   for (size_t i = 0; i < parsed_feature_policy.size(); ++i)
578     parsed_feature_policy_copy[i] = parsed_feature_policy[i];
579   SetReplicatedFeaturePolicyHeaderAndOpenerPolicies(
580       parsed_feature_policy_copy, FeaturePolicy::FeatureState());
581 }
582 
583 // Update the proxy's FrameOwner with new sandbox flags and container policy
584 // that were set by its parent in another process.
585 //
586 // Normally, when a frame's sandbox attribute is changed dynamically, the
587 // frame's FrameOwner is updated with the new sandbox flags right away, while
588 // the frame's SecurityContext is updated when the frame is navigated and the
589 // new sandbox flags take effect.
590 //
591 // Currently, there is no use case for a proxy's pending FrameOwner sandbox
592 // flags, so there's no message sent to proxies when the sandbox attribute is
593 // first updated.  Instead, the active flags are updated when they take effect,
594 // by OnDidSetActiveSandboxFlags. The proxy's FrameOwner flags are updated here
595 // with the caveat that the FrameOwner won't learn about updates to its flags
596 // until they take effect.
DidUpdateFramePolicy(const FramePolicy & frame_policy)597 void RemoteFrame::DidUpdateFramePolicy(const FramePolicy& frame_policy) {
598   // At the moment, this is only used to replicate sandbox flags and container
599   // policy for frames with a remote owner.
600   SECURITY_CHECK(IsA<RemoteFrameOwner>(Owner()));
601   To<RemoteFrameOwner>(Owner())->SetFramePolicy(frame_policy);
602 }
603 
GetMainFrameViewportSize() const604 IntSize RemoteFrame::GetMainFrameViewportSize() const {
605   HTMLFrameOwnerElement* owner = DeprecatedLocalOwner();
606   DCHECK(owner);
607   DCHECK(owner->GetDocument().GetFrame());
608   return owner->GetDocument().GetFrame()->GetMainFrameViewportSize();
609 }
610 
GetMainFrameScrollOffset() const611 IntPoint RemoteFrame::GetMainFrameScrollOffset() const {
612   HTMLFrameOwnerElement* owner = DeprecatedLocalOwner();
613   DCHECK(owner);
614   DCHECK(owner->GetDocument().GetFrame());
615   return owner->GetDocument().GetFrame()->GetMainFrameScrollOffset();
616 }
617 
IsIgnoredForHitTest() const618 bool RemoteFrame::IsIgnoredForHitTest() const {
619   HTMLFrameOwnerElement* owner = DeprecatedLocalOwner();
620   if (!owner || !owner->GetLayoutObject())
621     return false;
622 
623   return owner->OwnerType() == FrameOwnerElementType::kPortal ||
624          !visible_to_hit_testing_;
625 }
626 
SetCcLayer(cc::Layer * cc_layer,bool prevent_contents_opaque_changes,bool is_surface_layer)627 void RemoteFrame::SetCcLayer(cc::Layer* cc_layer,
628                              bool prevent_contents_opaque_changes,
629                              bool is_surface_layer) {
630   DCHECK(Owner());
631 
632   cc_layer_ = cc_layer;
633   prevent_contents_opaque_changes_ = prevent_contents_opaque_changes;
634   is_surface_layer_ = is_surface_layer;
635   if (cc_layer_) {
636     if (is_surface_layer) {
637       static_cast<cc::SurfaceLayer*>(cc_layer_)->SetHasPointerEventsNone(
638           IsIgnoredForHitTest());
639     }
640   }
641 
642   To<HTMLFrameOwnerElement>(Owner())->SetNeedsCompositingUpdate();
643 }
644 
AdvanceFocus(mojom::blink::FocusType type,LocalFrame * source)645 void RemoteFrame::AdvanceFocus(mojom::blink::FocusType type,
646                                LocalFrame* source) {
647   Client()->AdvanceFocus(type, source);
648 }
649 
DetachChildren()650 void RemoteFrame::DetachChildren() {
651   using FrameVector = HeapVector<Member<Frame>>;
652   FrameVector children_to_detach;
653   children_to_detach.ReserveCapacity(Tree().ChildCount());
654   for (Frame* child = Tree().FirstChild(); child;
655        child = child->Tree().NextSibling())
656     children_to_detach.push_back(child);
657   for (const auto& child : children_to_detach)
658     child->Detach(FrameDetachType::kRemove);
659 }
660 
ApplyReplicatedFeaturePolicyHeader()661 void RemoteFrame::ApplyReplicatedFeaturePolicyHeader() {
662   const FeaturePolicy* parent_feature_policy = nullptr;
663   if (Frame* parent_frame = Client()->Parent()) {
664     parent_feature_policy =
665         parent_frame->GetSecurityContext()->GetFeaturePolicy();
666   }
667   ParsedFeaturePolicy container_policy;
668   if (Owner())
669     container_policy = Owner()->GetFramePolicy().container_policy;
670   const FeaturePolicy::FeatureState& opener_feature_state =
671       OpenerFeatureState();
672   security_context_.InitializeFeaturePolicy(
673       feature_policy_header_, container_policy, parent_feature_policy,
674       opener_feature_state.empty() ? nullptr : &opener_feature_state);
675 }
676 
BindToReceiver(blink::RemoteFrame * frame,mojo::PendingAssociatedReceiver<mojom::blink::RemoteFrame> receiver)677 void RemoteFrame::BindToReceiver(
678     blink::RemoteFrame* frame,
679     mojo::PendingAssociatedReceiver<mojom::blink::RemoteFrame> receiver) {
680   DCHECK(frame);
681   frame->receiver_.Bind(std::move(receiver));
682 }
683 
684 }  // namespace blink
685