1 // Copyright 2013 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.
5 #include "content/renderer/render_frame_impl.h"
7 #include "base/command_line.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/time/time.h"
10 #include "content/child/appcache/appcache_dispatcher.h"
11 #include "content/child/plugin_messages.h"
12 #include "content/child/quota_dispatcher.h"
13 #include "content/child/request_extra_data.h"
14 #include "content/common/frame_messages.h"
15 #include "content/common/socket_stream_handle_data.h"
16 #include "content/common/swapped_out_messages.h"
17 #include "content/common/view_messages.h"
18 #include "content/public/common/content_constants.h"
19 #include "content/public/common/content_switches.h"
20 #include "content/public/common/url_constants.h"
21 #include "content/public/renderer/content_renderer_client.h"
22 #include "content/public/renderer/document_state.h"
23 #include "content/public/renderer/navigation_state.h"
24 #include "content/renderer/browser_plugin/browser_plugin.h"
25 #include "content/renderer/browser_plugin/browser_plugin_manager.h"
26 #include "content/renderer/internal_document_state_data.h"
27 #include "content/renderer/npapi/plugin_channel_host.h"
28 #include "content/renderer/render_thread_impl.h"
29 #include "content/renderer/render_view_impl.h"
30 #include "content/renderer/renderer_webapplicationcachehost_impl.h"
31 #include "content/renderer/websharedworker_proxy.h"
32 #include "net/base/net_errors.h"
33 #include "net/http/http_util.h"
34 #include "third_party/WebKit/public/platform/WebString.h"
35 #include "third_party/WebKit/public/platform/WebURL.h"
36 #include "third_party/WebKit/public/platform/WebURLError.h"
37 #include "third_party/WebKit/public/platform/WebURLResponse.h"
38 #include "third_party/WebKit/public/platform/WebVector.h"
39 #include "third_party/WebKit/public/web/WebDocument.h"
40 #include "third_party/WebKit/public/web/WebFrame.h"
41 #include "third_party/WebKit/public/web/WebNavigationPolicy.h"
42 #include "third_party/WebKit/public/web/WebPlugin.h"
43 #include "third_party/WebKit/public/web/WebPluginParams.h"
44 #include "third_party/WebKit/public/web/WebSearchableFormData.h"
45 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
46 #include "third_party/WebKit/public/web/WebStorageQuotaCallbacks.h"
47 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
48 #include "third_party/WebKit/public/web/WebView.h"
49 #include "webkit/child/weburlresponse_extradata_impl.h"
51 #if defined(ENABLE_WEBRTC)
52 #include "content/renderer/media/rtc_peer_connection_handler.h"
55 using WebKit::WebDataSource
;
56 using WebKit::WebDocument
;
57 using WebKit::WebFrame
;
58 using WebKit::WebNavigationPolicy
;
59 using WebKit::WebPluginParams
;
60 using WebKit::WebReferrerPolicy
;
61 using WebKit::WebSearchableFormData
;
62 using WebKit::WebSecurityOrigin
;
63 using WebKit::WebStorageQuotaCallbacks
;
64 using WebKit::WebString
;
66 using WebKit::WebURLError
;
67 using WebKit::WebURLRequest
;
68 using WebKit::WebURLResponse
;
69 using WebKit::WebUserGestureIndicator
;
70 using WebKit::WebVector
;
71 using WebKit::WebView
;
73 using base::TimeDelta
;
74 using webkit_glue::WebURLResponseExtraDataImpl
;
80 typedef std::map
<WebKit::WebFrame
*, RenderFrameImpl
*> FrameMap
;
81 base::LazyInstance
<FrameMap
> g_child_frame_map
= LAZY_INSTANCE_INITIALIZER
;
85 static RenderFrameImpl
* (*g_create_render_frame_impl
)(RenderViewImpl
*, int32
) =
89 RenderFrameImpl
* RenderFrameImpl::Create(RenderViewImpl
* render_view
,
91 DCHECK(routing_id
!= MSG_ROUTING_NONE
);
93 if (g_create_render_frame_impl
)
94 return g_create_render_frame_impl(render_view
, routing_id
);
96 return new RenderFrameImpl(render_view
, routing_id
);
100 void RenderFrameImpl::InstallCreateHook(
101 RenderFrameImpl
* (*create_render_frame_impl
)(RenderViewImpl
*, int32
)) {
102 CHECK(!g_create_render_frame_impl
);
103 g_create_render_frame_impl
= create_render_frame_impl
;
106 // RenderFrameImpl ----------------------------------------------------------
107 RenderFrameImpl::RenderFrameImpl(RenderViewImpl
* render_view
, int routing_id
)
108 : render_view_(render_view
),
109 routing_id_(routing_id
),
110 is_swapped_out_(false),
111 is_detaching_(false) {
114 RenderFrameImpl::~RenderFrameImpl() {
117 int RenderFrameImpl::GetRoutingID() const {
121 bool RenderFrameImpl::Send(IPC::Message
* message
) {
123 ((is_swapped_out_
|| render_view_
->is_swapped_out()) &&
124 !SwappedOutMessages::CanSendWhileSwappedOut(message
))) {
129 return RenderThread::Get()->Send(message
);
132 bool RenderFrameImpl::OnMessageReceived(const IPC::Message
& msg
) {
133 // TODO(ajwong): Fill in with message handlers as various components
134 // are migrated over to understand frames.
138 // WebKit::WebFrameClient implementation -------------------------------------
140 WebKit::WebPlugin
* RenderFrameImpl::createPlugin(
141 WebKit::WebFrame
* frame
,
142 const WebKit::WebPluginParams
& params
) {
143 WebKit::WebPlugin
* plugin
= NULL
;
144 if (GetContentClient()->renderer()->OverrideCreatePlugin(
145 render_view_
, frame
, params
, &plugin
)) {
149 #if defined(ENABLE_PLUGINS)
150 if (UTF16ToASCII(params
.mimeType
) == kBrowserPluginMimeType
) {
151 return render_view_
->GetBrowserPluginManager()->CreateBrowserPlugin(
152 render_view_
, frame
, params
);
156 std::string mime_type
;
157 bool found
= render_view_
->GetPluginInfo(
158 params
.url
, frame
->top()->document().url(), params
.mimeType
.utf8(),
163 WebPluginParams params_to_use
= params
;
164 params_to_use
.mimeType
= WebString::fromUTF8(mime_type
);
165 return render_view_
->CreatePlugin(frame
, info
, params_to_use
);
168 #endif // defined(ENABLE_PLUGINS)
171 WebKit::WebSharedWorker
* RenderFrameImpl::createSharedWorker(
172 WebKit::WebFrame
* frame
,
173 const WebKit::WebURL
& url
,
174 const WebKit::WebString
& name
,
175 unsigned long long document_id
) {
176 int route_id
= MSG_ROUTING_NONE
;
178 bool url_mismatch
= false;
179 ViewHostMsg_CreateWorker_Params params
;
182 params
.document_id
= document_id
;
183 params
.render_view_route_id
= render_view_
->GetRoutingID();
184 params
.route_id
= MSG_ROUTING_NONE
;
185 params
.script_resource_appcache_id
= 0;
186 render_view_
->Send(new ViewHostMsg_LookupSharedWorker(
187 params
, &exists
, &route_id
, &url_mismatch
));
191 return new WebSharedWorkerProxy(RenderThreadImpl::current(),
195 render_view_
->GetRoutingID());
199 WebKit::WebMediaPlayer
* RenderFrameImpl::createMediaPlayer(
200 WebKit::WebFrame
* frame
,
201 const WebKit::WebURL
& url
,
202 WebKit::WebMediaPlayerClient
* client
) {
203 // TODO(nasko): Moving the implementation here involves moving a few media
204 // related client objects here or referencing them in the RenderView. Needs
205 // more work to understand where the proper place for those objects is.
206 return render_view_
->createMediaPlayer(frame
, url
, client
);
209 WebKit::WebApplicationCacheHost
* RenderFrameImpl::createApplicationCacheHost(
210 WebKit::WebFrame
* frame
,
211 WebKit::WebApplicationCacheHostClient
* client
) {
212 if (!frame
|| !frame
->view())
214 return new RendererWebApplicationCacheHostImpl(
215 RenderViewImpl::FromWebView(frame
->view()), client
,
216 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy());
219 WebKit::WebCookieJar
* RenderFrameImpl::cookieJar(WebKit::WebFrame
* frame
) {
220 return render_view_
->cookieJar(frame
);
223 void RenderFrameImpl::didAccessInitialDocument(WebKit::WebFrame
* frame
) {
224 render_view_
->didAccessInitialDocument(frame
);
227 WebKit::WebFrame
* RenderFrameImpl::createChildFrame(
228 WebKit::WebFrame
* parent
,
229 const WebKit::WebString
& name
) {
230 RenderFrameImpl
* child_render_frame
= this;
231 long long child_frame_identifier
= WebFrame::generateEmbedderIdentifier();
232 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess
)) {
233 // Synchronously notify the browser of a child frame creation to get the
234 // routing_id for the RenderFrame.
236 Send(new FrameHostMsg_CreateChildFrame(GetRoutingID(),
237 parent
->identifier(),
238 child_frame_identifier
,
241 child_render_frame
= RenderFrameImpl::Create(render_view_
, routing_id
);
244 WebKit::WebFrame
* web_frame
= WebFrame::create(child_render_frame
,
245 child_frame_identifier
);
247 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess
)) {
248 g_child_frame_map
.Get().insert(
249 std::make_pair(web_frame
, child_render_frame
));
255 void RenderFrameImpl::didDisownOpener(WebKit::WebFrame
* frame
) {
256 render_view_
->didDisownOpener(frame
);
259 void RenderFrameImpl::frameDetached(WebKit::WebFrame
* frame
) {
260 // Currently multiple WebCore::Frames can send frameDetached to a single
261 // RenderFrameImpl. This is legacy behavior from when RenderViewImpl served
262 // as a shared WebFrameClient for multiple Webcore::Frame objects. It also
263 // prevents this class from entering the |is_detaching_| state because
264 // even though one WebCore::Frame may have detached itself, others will
265 // still need to use this object.
266 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess
)) {
267 // TODO(ajwong): Add CHECK(!is_detaching_) once we guarantee each
268 // RenderFrameImpl is only used by one WebCore::Frame.
269 is_detaching_
= true;
272 int64 parent_frame_id
= -1;
274 parent_frame_id
= frame
->parent()->identifier();
276 render_view_
->Send(new FrameHostMsg_Detach(GetRoutingID(), parent_frame_id
,
277 frame
->identifier()));
279 // Call back to RenderViewImpl for observers to be notified.
280 // TODO(nasko): Remove once we have RenderFrameObserver.
281 render_view_
->frameDetached(frame
);
283 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess
)) {
284 FrameMap::iterator it
= g_child_frame_map
.Get().find(frame
);
285 DCHECK(it
!= g_child_frame_map
.Get().end());
286 DCHECK_EQ(it
->second
, this);
288 g_child_frame_map
.Get().erase(it
);
294 void RenderFrameImpl::willClose(WebKit::WebFrame
* frame
) {
295 // Call back to RenderViewImpl for observers to be notified.
296 // TODO(nasko): Remove once we have RenderFrameObserver.
297 render_view_
->willClose(frame
);
300 void RenderFrameImpl::didChangeName(WebKit::WebFrame
* frame
,
301 const WebKit::WebString
& name
) {
302 if (!render_view_
->renderer_preferences_
.report_frame_name_changes
)
306 new ViewHostMsg_UpdateFrameName(render_view_
->GetRoutingID(),
312 void RenderFrameImpl::didMatchCSS(
313 WebKit::WebFrame
* frame
,
314 const WebKit::WebVector
<WebKit::WebString
>& newly_matching_selectors
,
315 const WebKit::WebVector
<WebKit::WebString
>& stopped_matching_selectors
) {
316 render_view_
->didMatchCSS(
317 frame
, newly_matching_selectors
, stopped_matching_selectors
);
320 void RenderFrameImpl::loadURLExternally(WebKit::WebFrame
* frame
,
321 const WebKit::WebURLRequest
& request
,
322 WebKit::WebNavigationPolicy policy
) {
323 loadURLExternally(frame
, request
, policy
, WebString());
326 void RenderFrameImpl::loadURLExternally(
327 WebKit::WebFrame
* frame
,
328 const WebKit::WebURLRequest
& request
,
329 WebKit::WebNavigationPolicy policy
,
330 const WebKit::WebString
& suggested_name
) {
331 Referrer
referrer(RenderViewImpl::GetReferrerFromRequest(frame
, request
));
332 if (policy
== WebKit::WebNavigationPolicyDownload
) {
333 render_view_
->Send(new ViewHostMsg_DownloadUrl(render_view_
->GetRoutingID(),
334 request
.url(), referrer
,
337 render_view_
->OpenURL(frame
, request
.url(), referrer
, policy
);
341 WebKit::WebNavigationPolicy
RenderFrameImpl::decidePolicyForNavigation(
342 WebKit::WebFrame
* frame
,
343 WebKit::WebDataSource::ExtraData
* extra_data
,
344 const WebKit::WebURLRequest
& request
,
345 WebKit::WebNavigationType type
,
346 WebKit::WebNavigationPolicy default_policy
,
348 return render_view_
->decidePolicyForNavigation(
349 frame
, extra_data
, request
, type
, default_policy
, is_redirect
);
352 WebKit::WebNavigationPolicy
RenderFrameImpl::decidePolicyForNavigation(
353 WebKit::WebFrame
* frame
,
354 const WebKit::WebURLRequest
& request
,
355 WebKit::WebNavigationType type
,
356 WebKit::WebNavigationPolicy default_policy
,
358 return render_view_
->decidePolicyForNavigation(
359 frame
, request
, type
, default_policy
, is_redirect
);
362 void RenderFrameImpl::willSendSubmitEvent(WebKit::WebFrame
* frame
,
363 const WebKit::WebFormElement
& form
) {
364 // Call back to RenderViewImpl for observers to be notified.
365 // TODO(nasko): Remove once we have RenderFrameObserver.
366 render_view_
->willSendSubmitEvent(frame
, form
);
369 void RenderFrameImpl::willSubmitForm(WebKit::WebFrame
* frame
,
370 const WebKit::WebFormElement
& form
) {
371 DocumentState
* document_state
=
372 DocumentState::FromDataSource(frame
->provisionalDataSource());
373 NavigationState
* navigation_state
= document_state
->navigation_state();
374 InternalDocumentStateData
* internal_data
=
375 InternalDocumentStateData::FromDocumentState(document_state
);
377 if (PageTransitionCoreTypeIs(navigation_state
->transition_type(),
378 PAGE_TRANSITION_LINK
)) {
379 navigation_state
->set_transition_type(PAGE_TRANSITION_FORM_SUBMIT
);
382 // Save these to be processed when the ensuing navigation is committed.
383 WebSearchableFormData
web_searchable_form_data(form
);
384 internal_data
->set_searchable_form_url(web_searchable_form_data
.url());
385 internal_data
->set_searchable_form_encoding(
386 web_searchable_form_data
.encoding().utf8());
388 // Call back to RenderViewImpl for observers to be notified.
389 // TODO(nasko): Remove once we have RenderFrameObserver.
390 render_view_
->willSubmitForm(frame
, form
);
393 void RenderFrameImpl::didCreateDataSource(WebKit::WebFrame
* frame
,
394 WebKit::WebDataSource
* datasource
) {
395 // TODO(nasko): Move implementation here. Needed state:
396 // * pending_navigation_params_
399 // * PopulateDocumentStateFromPending
400 // * CreateNavigationStateFromPending
401 render_view_
->didCreateDataSource(frame
, datasource
);
404 void RenderFrameImpl::didStartProvisionalLoad(WebKit::WebFrame
* frame
) {
405 WebDataSource
* ds
= frame
->provisionalDataSource();
407 // In fast/loader/stop-provisional-loads.html, we abort the load before this
408 // callback is invoked.
412 DocumentState
* document_state
= DocumentState::FromDataSource(ds
);
414 // We should only navigate to swappedout:// when is_swapped_out_ is true.
415 CHECK((ds
->request().url() != GURL(kSwappedOutURL
)) ||
416 render_view_
->is_swapped_out()) <<
417 "Heard swappedout:// when not swapped out.";
419 // Update the request time if WebKit has better knowledge of it.
420 if (document_state
->request_time().is_null()) {
421 double event_time
= ds
->triggeringEventTime();
422 if (event_time
!= 0.0)
423 document_state
->set_request_time(Time::FromDoubleT(event_time
));
426 // Start time is only set after request time.
427 document_state
->set_start_load_time(Time::Now());
429 bool is_top_most
= !frame
->parent();
431 render_view_
->set_navigation_gesture(
432 WebUserGestureIndicator::isProcessingUserGesture() ?
433 NavigationGestureUser
: NavigationGestureAuto
);
434 } else if (ds
->replacesCurrentHistoryItem()) {
435 // Subframe navigations that don't add session history items must be
436 // marked with AUTO_SUBFRAME. See also didFailProvisionalLoad for how we
437 // handle loading of error pages.
438 document_state
->navigation_state()->set_transition_type(
439 PAGE_TRANSITION_AUTO_SUBFRAME
);
443 RenderViewObserver
, render_view_
->observers(),
444 DidStartProvisionalLoad(frame
));
446 Send(new FrameHostMsg_DidStartProvisionalLoadForFrame(
447 routing_id_
, frame
->identifier(),
448 frame
->parent() ? frame
->parent()->identifier() : -1,
449 is_top_most
, ds
->request().url()));
452 void RenderFrameImpl::didReceiveServerRedirectForProvisionalLoad(
453 WebKit::WebFrame
* frame
) {
454 // TODO(nasko): Move implementation here. Needed state:
456 render_view_
->didReceiveServerRedirectForProvisionalLoad(frame
);
459 void RenderFrameImpl::didFailProvisionalLoad(
460 WebKit::WebFrame
* frame
,
461 const WebKit::WebURLError
& error
) {
462 // TODO(nasko): Move implementation here. Needed state:
464 // * pending_navigation_params_
466 // * MaybeLoadAlternateErrorPage
467 // * LoadNavigationErrorPage
468 render_view_
->didFailProvisionalLoad(frame
, error
);
471 void RenderFrameImpl::didCommitProvisionalLoad(WebKit::WebFrame
* frame
,
472 bool is_new_navigation
) {
473 // TODO(nasko): Move implementation here. Needed state:
476 // * history_list_offset_
477 // * history_list_length_
478 // * history_page_ids_
481 // * UpdateSessionHistory
483 render_view_
->didCommitProvisionalLoad(frame
, is_new_navigation
);
486 void RenderFrameImpl::didClearWindowObject(WebKit::WebFrame
* frame
) {
487 // TODO(nasko): Move implementation here. Needed state:
488 // * enabled_bindings_
489 // * dom_automation_controller_
490 // * stats_collection_controller_
491 render_view_
->didClearWindowObject(frame
);
494 void RenderFrameImpl::didCreateDocumentElement(WebKit::WebFrame
* frame
) {
495 // Notify the browser about non-blank documents loading in the top frame.
496 GURL url
= frame
->document().url();
497 if (url
.is_valid() && url
.spec() != kAboutBlankURL
) {
498 // TODO(nasko): Check if webview()->mainFrame() is the same as the
499 // frame->tree()->top().
500 if (frame
== render_view_
->webview()->mainFrame()) {
501 render_view_
->Send(new ViewHostMsg_DocumentAvailableInMainFrame(
502 render_view_
->GetRoutingID()));
506 // Call back to RenderViewImpl for observers to be notified.
507 // TODO(nasko): Remove once we have RenderFrameObserver.
508 render_view_
->didCreateDocumentElement(frame
);
511 void RenderFrameImpl::didReceiveTitle(WebKit::WebFrame
* frame
,
512 const WebKit::WebString
& title
,
513 WebKit::WebTextDirection direction
) {
514 // TODO(nasko): Investigate wheather implementation should move here.
515 render_view_
->didReceiveTitle(frame
, title
, direction
);
518 void RenderFrameImpl::didChangeIcon(WebKit::WebFrame
* frame
,
519 WebKit::WebIconURL::Type icon_type
) {
520 // TODO(nasko): Investigate wheather implementation should move here.
521 render_view_
->didChangeIcon(frame
, icon_type
);
524 void RenderFrameImpl::didFinishDocumentLoad(WebKit::WebFrame
* frame
) {
525 // TODO(nasko): Move implementation here. No state needed, just observers
526 // notification in before updating encoding.
527 render_view_
->didFinishDocumentLoad(frame
);
530 void RenderFrameImpl::didHandleOnloadEvents(WebKit::WebFrame
* frame
) {
531 // TODO(nasko): Move implementation here. Needed state:
533 render_view_
->didHandleOnloadEvents(frame
);
536 void RenderFrameImpl::didFailLoad(WebKit::WebFrame
* frame
,
537 const WebKit::WebURLError
& error
) {
538 // TODO(nasko): Move implementation here. No state needed.
539 render_view_
->didFailLoad(frame
, error
);
542 void RenderFrameImpl::didFinishLoad(WebKit::WebFrame
* frame
) {
543 // TODO(nasko): Move implementation here. No state needed, just observers
544 // notification before sending message to the browser process.
545 render_view_
->didFinishLoad(frame
);
548 void RenderFrameImpl::didNavigateWithinPage(WebKit::WebFrame
* frame
,
549 bool is_new_navigation
) {
550 // TODO(nasko): Move implementation here. No state needed, just observers
551 // notification before sending message to the browser process.
552 render_view_
->didNavigateWithinPage(frame
, is_new_navigation
);
555 void RenderFrameImpl::didUpdateCurrentHistoryItem(WebKit::WebFrame
* frame
) {
556 // TODO(nasko): Move implementation here. Needed methods:
557 // * StartNavStateSyncTimerIfNecessary
558 render_view_
->didUpdateCurrentHistoryItem(frame
);
561 void RenderFrameImpl::willRequestAfterPreconnect(
562 WebKit::WebFrame
* frame
,
563 WebKit::WebURLRequest
& request
) {
564 WebKit::WebReferrerPolicy referrer_policy
= WebKit::WebReferrerPolicyDefault
;
565 WebString custom_user_agent
;
567 if (request
.extraData()) {
568 // This will only be called before willSendRequest, so only ExtraData
569 // members we have to copy here is on WebURLRequestExtraDataImpl.
570 webkit_glue::WebURLRequestExtraDataImpl
* old_extra_data
=
571 static_cast<webkit_glue::WebURLRequestExtraDataImpl
*>(
572 request
.extraData());
574 referrer_policy
= old_extra_data
->referrer_policy();
575 custom_user_agent
= old_extra_data
->custom_user_agent();
578 bool was_after_preconnect_request
= true;
579 // The args after |was_after_preconnect_request| are not used, and set to
580 // correct values at |willSendRequest|.
581 request
.setExtraData(new webkit_glue::WebURLRequestExtraDataImpl(
582 referrer_policy
, custom_user_agent
, was_after_preconnect_request
));
585 void RenderFrameImpl::willSendRequest(
586 WebKit::WebFrame
* frame
,
588 WebKit::WebURLRequest
& request
,
589 const WebKit::WebURLResponse
& redirect_response
) {
590 // The request my be empty during tests.
591 if (request
.url().isEmpty())
594 WebFrame
* top_frame
= frame
->top();
597 WebDataSource
* provisional_data_source
= top_frame
->provisionalDataSource();
598 WebDataSource
* top_data_source
= top_frame
->dataSource();
599 WebDataSource
* data_source
=
600 provisional_data_source
? provisional_data_source
: top_data_source
;
602 PageTransition transition_type
= PAGE_TRANSITION_LINK
;
603 DocumentState
* document_state
= DocumentState::FromDataSource(data_source
);
604 DCHECK(document_state
);
605 InternalDocumentStateData
* internal_data
=
606 InternalDocumentStateData::FromDocumentState(document_state
);
607 NavigationState
* navigation_state
= document_state
->navigation_state();
608 transition_type
= navigation_state
->transition_type();
610 GURL
request_url(request
.url());
612 if (GetContentClient()->renderer()->WillSendRequest(
616 request
.firstPartyForCookies(),
618 request
.setURL(WebURL(new_url
));
621 if (internal_data
->is_cache_policy_override_set())
622 request
.setCachePolicy(internal_data
->cache_policy_override());
624 WebKit::WebReferrerPolicy referrer_policy
;
625 if (internal_data
->is_referrer_policy_set()) {
626 referrer_policy
= internal_data
->referrer_policy();
627 internal_data
->clear_referrer_policy();
629 referrer_policy
= frame
->document().referrerPolicy();
632 // The request's extra data may indicate that we should set a custom user
633 // agent. This needs to be done here, after WebKit is through with setting the
634 // user agent on its own.
635 WebString custom_user_agent
;
636 bool was_after_preconnect_request
= false;
637 if (request
.extraData()) {
638 webkit_glue::WebURLRequestExtraDataImpl
* old_extra_data
=
639 static_cast<webkit_glue::WebURLRequestExtraDataImpl
*>(
640 request
.extraData());
641 custom_user_agent
= old_extra_data
->custom_user_agent();
642 was_after_preconnect_request
=
643 old_extra_data
->was_after_preconnect_request();
645 if (!custom_user_agent
.isNull()) {
646 if (custom_user_agent
.isEmpty())
647 request
.clearHTTPHeaderField("User-Agent");
649 request
.setHTTPHeaderField("User-Agent", custom_user_agent
);
653 request
.setExtraData(
654 new RequestExtraData(referrer_policy
,
656 was_after_preconnect_request
,
657 (frame
== top_frame
),
659 GURL(frame
->document().securityOrigin().toString()),
660 frame
->parent() == top_frame
,
661 frame
->parent() ? frame
->parent()->identifier() : -1,
662 navigation_state
->allow_download(),
664 navigation_state
->transferred_request_child_id(),
665 navigation_state
->transferred_request_request_id()));
667 DocumentState
* top_document_state
=
668 DocumentState::FromDataSource(top_data_source
);
669 if (top_document_state
) {
670 // TODO(gavinp): separate out prefetching and prerender field trials
671 // if the rel=prerender rel type is sticking around.
672 if (request
.targetType() == WebURLRequest::TargetIsPrefetch
)
673 top_document_state
->set_was_prefetcher(true);
675 if (was_after_preconnect_request
)
676 top_document_state
->set_was_after_preconnect_request(true);
679 // This is an instance where we embed a copy of the routing id
680 // into the data portion of the message. This can cause problems if we
681 // don't register this id on the browser side, since the download manager
682 // expects to find a RenderViewHost based off the id.
683 request
.setRequestorID(render_view_
->GetRoutingID());
684 request
.setHasUserGesture(WebUserGestureIndicator::isProcessingUserGesture());
686 if (!navigation_state
->extra_headers().empty()) {
687 for (net::HttpUtil::HeadersIterator
i(
688 navigation_state
->extra_headers().begin(),
689 navigation_state
->extra_headers().end(), "\n");
691 request
.setHTTPHeaderField(WebString::fromUTF8(i
.name()),
692 WebString::fromUTF8(i
.values()));
696 if (!render_view_
->renderer_preferences_
.enable_referrers
)
697 request
.clearHTTPHeaderField("Referer");
700 void RenderFrameImpl::didReceiveResponse(
701 WebKit::WebFrame
* frame
,
703 const WebKit::WebURLResponse
& response
) {
704 // Only do this for responses that correspond to a provisional data source
705 // of the top-most frame. If we have a provisional data source, then we
706 // can't have any sub-resources yet, so we know that this response must
707 // correspond to a frame load.
708 if (!frame
->provisionalDataSource() || frame
->parent())
711 // If we are in view source mode, then just let the user see the source of
712 // the server's error page.
713 if (frame
->isViewSourceModeEnabled())
716 DocumentState
* document_state
=
717 DocumentState::FromDataSource(frame
->provisionalDataSource());
718 int http_status_code
= response
.httpStatusCode();
720 // Record page load flags.
721 WebURLResponseExtraDataImpl
* extra_data
=
722 RenderViewImpl::GetExtraDataFromResponse(response
);
724 document_state
->set_was_fetched_via_spdy(
725 extra_data
->was_fetched_via_spdy());
726 document_state
->set_was_npn_negotiated(
727 extra_data
->was_npn_negotiated());
728 document_state
->set_npn_negotiated_protocol(
729 extra_data
->npn_negotiated_protocol());
730 document_state
->set_was_alternate_protocol_available(
731 extra_data
->was_alternate_protocol_available());
732 document_state
->set_connection_info(
733 extra_data
->connection_info());
734 document_state
->set_was_fetched_via_proxy(
735 extra_data
->was_fetched_via_proxy());
737 InternalDocumentStateData
* internal_data
=
738 InternalDocumentStateData::FromDocumentState(document_state
);
739 internal_data
->set_http_status_code(http_status_code
);
740 // Whether or not the http status code actually corresponds to an error is
741 // only checked when the page is done loading, if |use_error_page| is
743 internal_data
->set_use_error_page(true);
746 void RenderFrameImpl::didFinishResourceLoad(WebKit::WebFrame
* frame
,
747 unsigned identifier
) {
748 // TODO(nasko): Move implementation here. Needed state:
751 // * LoadNavigationErrorPage
752 render_view_
->didFinishResourceLoad(frame
, identifier
);
755 void RenderFrameImpl::didLoadResourceFromMemoryCache(
756 WebKit::WebFrame
* frame
,
757 const WebKit::WebURLRequest
& request
,
758 const WebKit::WebURLResponse
& response
) {
759 // The recipients of this message have no use for data: URLs: they don't
760 // affect the page's insecure content list and are not in the disk cache. To
761 // prevent large (1M+) data: URLs from crashing in the IPC system, we simply
762 // filter them out here.
763 GURL
url(request
.url());
764 if (url
.SchemeIs("data"))
767 // Let the browser know we loaded a resource from the memory cache. This
768 // message is needed to display the correct SSL indicators.
769 render_view_
->Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(
770 render_view_
->GetRoutingID(),
772 response
.securityInfo(),
773 request
.httpMethod().utf8(),
774 response
.mimeType().utf8(),
775 ResourceType::FromTargetType(request
.targetType())));
778 void RenderFrameImpl::didDisplayInsecureContent(WebKit::WebFrame
* frame
) {
779 render_view_
->Send(new ViewHostMsg_DidDisplayInsecureContent(
780 render_view_
->GetRoutingID()));
783 void RenderFrameImpl::didRunInsecureContent(
784 WebKit::WebFrame
* frame
,
785 const WebKit::WebSecurityOrigin
& origin
,
786 const WebKit::WebURL
& target
) {
787 render_view_
->Send(new ViewHostMsg_DidRunInsecureContent(
788 render_view_
->GetRoutingID(),
789 origin
.toString().utf8(),
793 void RenderFrameImpl::didAbortLoading(WebKit::WebFrame
* frame
) {
794 #if defined(ENABLE_PLUGINS)
795 if (frame
!= render_view_
->webview()->mainFrame())
797 PluginChannelHost::Broadcast(
798 new PluginHostMsg_DidAbortLoading(render_view_
->GetRoutingID()));
802 void RenderFrameImpl::didExhaustMemoryAvailableForScript(
803 WebKit::WebFrame
* frame
) {
804 render_view_
->Send(new ViewHostMsg_JSOutOfMemory(
805 render_view_
->GetRoutingID()));
808 void RenderFrameImpl::didCreateScriptContext(WebKit::WebFrame
* frame
,
809 v8::Handle
<v8::Context
> context
,
812 GetContentClient()->renderer()->DidCreateScriptContext(
813 frame
, context
, extension_group
, world_id
);
816 void RenderFrameImpl::willReleaseScriptContext(WebKit::WebFrame
* frame
,
817 v8::Handle
<v8::Context
> context
,
819 GetContentClient()->renderer()->WillReleaseScriptContext(
820 frame
, context
, world_id
);
823 void RenderFrameImpl::didFirstVisuallyNonEmptyLayout(WebKit::WebFrame
* frame
) {
824 render_view_
->didFirstVisuallyNonEmptyLayout(frame
);
827 void RenderFrameImpl::didChangeContentsSize(WebKit::WebFrame
* frame
,
828 const WebKit::WebSize
& size
) {
829 // TODO(nasko): Move implementation here. Needed state:
830 // * cached_has_main_frame_horizontal_scrollbar_
831 // * cached_has_main_frame_vertical_scrollbar_
832 render_view_
->didChangeContentsSize(frame
, size
);
835 void RenderFrameImpl::didChangeScrollOffset(WebKit::WebFrame
* frame
) {
836 // TODO(nasko): Move implementation here. Needed methods:
837 // * StartNavStateSyncTimerIfNecessary
838 render_view_
->didChangeScrollOffset(frame
);
841 void RenderFrameImpl::willInsertBody(WebKit::WebFrame
* frame
) {
842 if (!frame
->parent()) {
843 render_view_
->Send(new ViewHostMsg_WillInsertBody(
844 render_view_
->GetRoutingID()));
848 void RenderFrameImpl::reportFindInPageMatchCount(int request_id
,
851 int active_match_ordinal
= -1; // -1 = don't update active match ordinal
853 active_match_ordinal
= 0;
855 render_view_
->Send(new ViewHostMsg_Find_Reply(
856 render_view_
->GetRoutingID(), request_id
, count
,
857 gfx::Rect(), active_match_ordinal
, final_update
));
860 void RenderFrameImpl::reportFindInPageSelection(
862 int active_match_ordinal
,
863 const WebKit::WebRect
& selection_rect
) {
864 render_view_
->Send(new ViewHostMsg_Find_Reply(
865 render_view_
->GetRoutingID(), request_id
, -1, selection_rect
,
866 active_match_ordinal
, false));
869 void RenderFrameImpl::requestStorageQuota(
870 WebKit::WebFrame
* frame
,
871 WebKit::WebStorageQuotaType type
,
872 unsigned long long requested_size
,
873 WebKit::WebStorageQuotaCallbacks
* callbacks
) {
875 WebSecurityOrigin origin
= frame
->document().securityOrigin();
876 if (origin
.isUnique()) {
877 // Unique origins cannot store persistent state.
878 callbacks
->didFail(WebKit::WebStorageQuotaErrorAbort
);
881 ChildThread::current()->quota_dispatcher()->RequestStorageQuota(
882 render_view_
->GetRoutingID(), GURL(origin
.toString()),
883 static_cast<quota::StorageType
>(type
), requested_size
,
884 QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks
));
887 void RenderFrameImpl::willOpenSocketStream(
888 WebKit::WebSocketStreamHandle
* handle
) {
889 SocketStreamHandleData::AddToHandle(handle
, render_view_
->GetRoutingID());
892 void RenderFrameImpl::willStartUsingPeerConnectionHandler(
893 WebKit::WebFrame
* frame
,
894 WebKit::WebRTCPeerConnectionHandler
* handler
) {
895 #if defined(ENABLE_WEBRTC)
896 static_cast<RTCPeerConnectionHandler
*>(handler
)->associateWithFrame(frame
);
900 bool RenderFrameImpl::willCheckAndDispatchMessageEvent(
901 WebKit::WebFrame
* sourceFrame
,
902 WebKit::WebFrame
* targetFrame
,
903 WebKit::WebSecurityOrigin targetOrigin
,
904 WebKit::WebDOMMessageEvent event
) {
905 // TODO(nasko): Move implementation here. Needed state:
907 return render_view_
->willCheckAndDispatchMessageEvent(
908 sourceFrame
, targetFrame
, targetOrigin
, event
);
911 WebKit::WebString
RenderFrameImpl::userAgentOverride(
912 WebKit::WebFrame
* frame
,
913 const WebKit::WebURL
& url
) {
914 if (!render_view_
->webview() || !render_view_
->webview()->mainFrame() ||
915 render_view_
->renderer_preferences_
.user_agent_override
.empty()) {
916 return WebKit::WebString();
919 // If we're in the middle of committing a load, the data source we need
920 // will still be provisional.
921 WebFrame
* main_frame
= render_view_
->webview()->mainFrame();
922 WebDataSource
* data_source
= NULL
;
923 if (main_frame
->provisionalDataSource())
924 data_source
= main_frame
->provisionalDataSource();
926 data_source
= main_frame
->dataSource();
928 InternalDocumentStateData
* internal_data
= data_source
?
929 InternalDocumentStateData::FromDataSource(data_source
) : NULL
;
930 if (internal_data
&& internal_data
->is_overriding_user_agent())
931 return WebString::fromUTF8(
932 render_view_
->renderer_preferences_
.user_agent_override
);
933 return WebKit::WebString();
936 WebKit::WebString
RenderFrameImpl::doNotTrackValue(WebKit::WebFrame
* frame
) {
937 if (render_view_
->renderer_preferences_
.enable_do_not_track
)
938 return WebString::fromUTF8("1");
942 bool RenderFrameImpl::allowWebGL(WebKit::WebFrame
* frame
, bool default_value
) {
947 render_view_
->Send(new ViewHostMsg_Are3DAPIsBlocked(
948 render_view_
->GetRoutingID(),
949 GURL(frame
->top()->document().securityOrigin().toString()),
950 THREE_D_API_TYPE_WEBGL
,
955 void RenderFrameImpl::didLoseWebGLContext(WebKit::WebFrame
* frame
,
956 int arb_robustness_status_code
) {
957 render_view_
->Send(new ViewHostMsg_DidLose3DContext(
958 GURL(frame
->top()->document().securityOrigin().toString()),
959 THREE_D_API_TYPE_WEBGL
,
960 arb_robustness_status_code
));
963 } // namespace content