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"
10 #include "base/command_line.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/time/time.h"
13 #include "content/child/appcache/appcache_dispatcher.h"
14 #include "content/child/plugin_messages.h"
15 #include "content/child/quota_dispatcher.h"
16 #include "content/child/request_extra_data.h"
17 #include "content/child/service_worker/web_service_worker_provider_impl.h"
18 #include "content/common/frame_messages.h"
19 #include "content/common/socket_stream_handle_data.h"
20 #include "content/common/swapped_out_messages.h"
21 #include "content/common/view_messages.h"
22 #include "content/public/common/content_constants.h"
23 #include "content/public/common/content_switches.h"
24 #include "content/public/common/url_constants.h"
25 #include "content/public/renderer/content_renderer_client.h"
26 #include "content/public/renderer/document_state.h"
27 #include "content/public/renderer/navigation_state.h"
28 #include "content/renderer/browser_plugin/browser_plugin.h"
29 #include "content/renderer/browser_plugin/browser_plugin_manager.h"
30 #include "content/renderer/internal_document_state_data.h"
31 #include "content/renderer/npapi/plugin_channel_host.h"
32 #include "content/renderer/render_thread_impl.h"
33 #include "content/renderer/render_view_impl.h"
34 #include "content/renderer/renderer_webapplicationcachehost_impl.h"
35 #include "content/renderer/websharedworker_proxy.h"
36 #include "net/base/net_errors.h"
37 #include "net/http/http_util.h"
38 #include "third_party/WebKit/public/platform/WebString.h"
39 #include "third_party/WebKit/public/platform/WebURL.h"
40 #include "third_party/WebKit/public/platform/WebURLError.h"
41 #include "third_party/WebKit/public/platform/WebURLResponse.h"
42 #include "third_party/WebKit/public/platform/WebVector.h"
43 #include "third_party/WebKit/public/web/WebDocument.h"
44 #include "third_party/WebKit/public/web/WebFrame.h"
45 #include "third_party/WebKit/public/web/WebNavigationPolicy.h"
46 #include "third_party/WebKit/public/web/WebPlugin.h"
47 #include "third_party/WebKit/public/web/WebPluginParams.h"
48 #include "third_party/WebKit/public/web/WebSearchableFormData.h"
49 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
50 #include "third_party/WebKit/public/web/WebStorageQuotaCallbacks.h"
51 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
52 #include "third_party/WebKit/public/web/WebView.h"
53 #include "webkit/child/weburlresponse_extradata_impl.h"
55 #if defined(ENABLE_WEBRTC)
56 #include "content/renderer/media/rtc_peer_connection_handler.h"
59 using WebKit::WebDataSource;
60 using WebKit::WebDocument;
61 using WebKit::WebFrame;
62 using WebKit::WebNavigationPolicy;
63 using WebKit::WebPluginParams;
64 using WebKit::WebReferrerPolicy;
65 using WebKit::WebSearchableFormData;
66 using WebKit::WebSecurityOrigin;
67 using WebKit::WebServiceWorkerProvider;
68 using WebKit::WebStorageQuotaCallbacks;
69 using WebKit::WebString;
71 using WebKit::WebURLError;
72 using WebKit::WebURLRequest;
73 using WebKit::WebURLResponse;
74 using WebKit::WebUserGestureIndicator;
75 using WebKit::WebVector;
76 using WebKit::WebView;
78 using base::TimeDelta;
79 using webkit_glue::WebURLResponseExtraDataImpl;
85 typedef std::map<WebKit::WebFrame*, RenderFrameImpl*> FrameMap;
86 base::LazyInstance<FrameMap> g_child_frame_map = LAZY_INSTANCE_INITIALIZER;
90 static RenderFrameImpl* (*g_create_render_frame_impl)(RenderViewImpl*, int32) =
94 RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view,
96 DCHECK(routing_id != MSG_ROUTING_NONE);
98 if (g_create_render_frame_impl)
99 return g_create_render_frame_impl(render_view, routing_id);
101 return new RenderFrameImpl(render_view, routing_id);
105 void RenderFrameImpl::InstallCreateHook(
106 RenderFrameImpl* (*create_render_frame_impl)(RenderViewImpl*, int32)) {
107 CHECK(!g_create_render_frame_impl);
108 g_create_render_frame_impl = create_render_frame_impl;
111 // RenderFrameImpl ----------------------------------------------------------
112 RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id)
113 : render_view_(render_view),
114 routing_id_(routing_id),
115 is_swapped_out_(false),
116 is_detaching_(false) {
119 RenderFrameImpl::~RenderFrameImpl() {
122 int RenderFrameImpl::GetRoutingID() const {
126 bool RenderFrameImpl::Send(IPC::Message* message) {
128 ((is_swapped_out_ || render_view_->is_swapped_out()) &&
129 !SwappedOutMessages::CanSendWhileSwappedOut(message))) {
134 return RenderThread::Get()->Send(message);
137 bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
138 // TODO(ajwong): Fill in with message handlers as various components
139 // are migrated over to understand frames.
143 // WebKit::WebFrameClient implementation -------------------------------------
145 WebKit::WebPlugin* RenderFrameImpl::createPlugin(
146 WebKit::WebFrame* frame,
147 const WebKit::WebPluginParams& params) {
148 WebKit::WebPlugin* plugin = NULL;
149 if (GetContentClient()->renderer()->OverrideCreatePlugin(
150 render_view_, frame, params, &plugin)) {
154 #if defined(ENABLE_PLUGINS)
155 if (UTF16ToASCII(params.mimeType) == kBrowserPluginMimeType) {
156 return render_view_->GetBrowserPluginManager()->CreateBrowserPlugin(
157 render_view_, frame, params);
161 std::string mime_type;
162 bool found = render_view_->GetPluginInfo(
163 params.url, frame->top()->document().url(), params.mimeType.utf8(),
168 WebPluginParams params_to_use = params;
169 params_to_use.mimeType = WebString::fromUTF8(mime_type);
170 return render_view_->CreatePlugin(frame, info, params_to_use);
173 #endif // defined(ENABLE_PLUGINS)
176 WebKit::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
177 WebKit::WebFrame* frame,
178 const WebKit::WebURL& url,
179 WebKit::WebMediaPlayerClient* client) {
180 // TODO(nasko): Moving the implementation here involves moving a few media
181 // related client objects here or referencing them in the RenderView. Needs
182 // more work to understand where the proper place for those objects is.
183 return render_view_->createMediaPlayer(frame, url, client);
186 WebKit::WebApplicationCacheHost* RenderFrameImpl::createApplicationCacheHost(
187 WebKit::WebFrame* frame,
188 WebKit::WebApplicationCacheHostClient* client) {
189 if (!frame || !frame->view())
191 return new RendererWebApplicationCacheHostImpl(
192 RenderViewImpl::FromWebView(frame->view()), client,
193 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy());
196 WebKit::WebWorkerPermissionClientProxy*
197 RenderFrameImpl::createWorkerPermissionClientProxy(WebFrame* frame) {
198 if (!frame || !frame->view())
200 return GetContentClient()->renderer()->CreateWorkerPermissionClientProxy(
201 RenderViewImpl::FromWebView(frame->view()), frame);
204 WebKit::WebCookieJar* RenderFrameImpl::cookieJar(WebKit::WebFrame* frame) {
205 return render_view_->cookieJar(frame);
208 WebKit::WebServiceWorkerProvider* RenderFrameImpl::createServiceWorkerProvider(
209 WebKit::WebFrame* frame,
210 WebKit::WebServiceWorkerProviderClient* client) {
211 return new WebServiceWorkerProviderImpl(
212 ChildThread::current()->thread_safe_sender(),
213 ChildThread::current()->service_worker_message_filter(),
214 GURL(frame->document().securityOrigin().toString()),
215 make_scoped_ptr(client));
218 void RenderFrameImpl::didAccessInitialDocument(WebKit::WebFrame* frame) {
219 render_view_->didAccessInitialDocument(frame);
222 WebKit::WebFrame* RenderFrameImpl::createChildFrame(
223 WebKit::WebFrame* parent,
224 const WebKit::WebString& name) {
225 RenderFrameImpl* child_render_frame = this;
226 long long child_frame_identifier = WebFrame::generateEmbedderIdentifier();
227 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) {
228 // Synchronously notify the browser of a child frame creation to get the
229 // routing_id for the RenderFrame.
231 Send(new FrameHostMsg_CreateChildFrame(GetRoutingID(),
232 parent->identifier(),
233 child_frame_identifier,
236 child_render_frame = RenderFrameImpl::Create(render_view_, routing_id);
239 WebKit::WebFrame* web_frame = WebFrame::create(child_render_frame,
240 child_frame_identifier);
242 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) {
243 g_child_frame_map.Get().insert(
244 std::make_pair(web_frame, child_render_frame));
250 void RenderFrameImpl::didDisownOpener(WebKit::WebFrame* frame) {
251 render_view_->didDisownOpener(frame);
254 void RenderFrameImpl::frameDetached(WebKit::WebFrame* frame) {
255 // Currently multiple WebCore::Frames can send frameDetached to a single
256 // RenderFrameImpl. This is legacy behavior from when RenderViewImpl served
257 // as a shared WebFrameClient for multiple Webcore::Frame objects. It also
258 // prevents this class from entering the |is_detaching_| state because
259 // even though one WebCore::Frame may have detached itself, others will
260 // still need to use this object.
261 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) {
262 // TODO(ajwong): Add CHECK(!is_detaching_) once we guarantee each
263 // RenderFrameImpl is only used by one WebCore::Frame.
264 is_detaching_ = true;
267 int64 parent_frame_id = -1;
269 parent_frame_id = frame->parent()->identifier();
271 render_view_->Send(new FrameHostMsg_Detach(GetRoutingID(), parent_frame_id,
272 frame->identifier()));
274 // Call back to RenderViewImpl for observers to be notified.
275 // TODO(nasko): Remove once we have RenderFrameObserver.
276 render_view_->frameDetached(frame);
278 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) {
279 FrameMap::iterator it = g_child_frame_map.Get().find(frame);
280 DCHECK(it != g_child_frame_map.Get().end());
281 DCHECK_EQ(it->second, this);
283 g_child_frame_map.Get().erase(it);
289 void RenderFrameImpl::willClose(WebKit::WebFrame* frame) {
290 // Call back to RenderViewImpl for observers to be notified.
291 // TODO(nasko): Remove once we have RenderFrameObserver.
292 render_view_->willClose(frame);
295 void RenderFrameImpl::didChangeName(WebKit::WebFrame* frame,
296 const WebKit::WebString& name) {
297 if (!render_view_->renderer_preferences_.report_frame_name_changes)
301 new ViewHostMsg_UpdateFrameName(render_view_->GetRoutingID(),
307 void RenderFrameImpl::didMatchCSS(
308 WebKit::WebFrame* frame,
309 const WebKit::WebVector<WebKit::WebString>& newly_matching_selectors,
310 const WebKit::WebVector<WebKit::WebString>& stopped_matching_selectors) {
311 render_view_->didMatchCSS(
312 frame, newly_matching_selectors, stopped_matching_selectors);
315 void RenderFrameImpl::loadURLExternally(WebKit::WebFrame* frame,
316 const WebKit::WebURLRequest& request,
317 WebKit::WebNavigationPolicy policy) {
318 loadURLExternally(frame, request, policy, WebString());
321 void RenderFrameImpl::loadURLExternally(
322 WebKit::WebFrame* frame,
323 const WebKit::WebURLRequest& request,
324 WebKit::WebNavigationPolicy policy,
325 const WebKit::WebString& suggested_name) {
326 Referrer referrer(RenderViewImpl::GetReferrerFromRequest(frame, request));
327 if (policy == WebKit::WebNavigationPolicyDownload) {
328 render_view_->Send(new ViewHostMsg_DownloadUrl(render_view_->GetRoutingID(),
329 request.url(), referrer,
332 render_view_->OpenURL(frame, request.url(), referrer, policy);
336 WebKit::WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation(
337 WebKit::WebFrame* frame,
338 WebKit::WebDataSource::ExtraData* extra_data,
339 const WebKit::WebURLRequest& request,
340 WebKit::WebNavigationType type,
341 WebKit::WebNavigationPolicy default_policy,
343 return render_view_->decidePolicyForNavigation(
344 frame, extra_data, request, type, default_policy, is_redirect);
347 WebKit::WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation(
348 WebKit::WebFrame* frame,
349 const WebKit::WebURLRequest& request,
350 WebKit::WebNavigationType type,
351 WebKit::WebNavigationPolicy default_policy,
353 return render_view_->decidePolicyForNavigation(
354 frame, request, type, default_policy, is_redirect);
357 void RenderFrameImpl::willSendSubmitEvent(WebKit::WebFrame* frame,
358 const WebKit::WebFormElement& form) {
359 // Call back to RenderViewImpl for observers to be notified.
360 // TODO(nasko): Remove once we have RenderFrameObserver.
361 render_view_->willSendSubmitEvent(frame, form);
364 void RenderFrameImpl::willSubmitForm(WebKit::WebFrame* frame,
365 const WebKit::WebFormElement& form) {
366 DocumentState* document_state =
367 DocumentState::FromDataSource(frame->provisionalDataSource());
368 NavigationState* navigation_state = document_state->navigation_state();
369 InternalDocumentStateData* internal_data =
370 InternalDocumentStateData::FromDocumentState(document_state);
372 if (PageTransitionCoreTypeIs(navigation_state->transition_type(),
373 PAGE_TRANSITION_LINK)) {
374 navigation_state->set_transition_type(PAGE_TRANSITION_FORM_SUBMIT);
377 // Save these to be processed when the ensuing navigation is committed.
378 WebSearchableFormData web_searchable_form_data(form);
379 internal_data->set_searchable_form_url(web_searchable_form_data.url());
380 internal_data->set_searchable_form_encoding(
381 web_searchable_form_data.encoding().utf8());
383 // Call back to RenderViewImpl for observers to be notified.
384 // TODO(nasko): Remove once we have RenderFrameObserver.
385 render_view_->willSubmitForm(frame, form);
388 void RenderFrameImpl::didCreateDataSource(WebKit::WebFrame* frame,
389 WebKit::WebDataSource* datasource) {
390 // TODO(nasko): Move implementation here. Needed state:
391 // * pending_navigation_params_
394 // * PopulateDocumentStateFromPending
395 // * CreateNavigationStateFromPending
396 render_view_->didCreateDataSource(frame, datasource);
399 void RenderFrameImpl::didStartProvisionalLoad(WebKit::WebFrame* frame) {
400 WebDataSource* ds = frame->provisionalDataSource();
402 // In fast/loader/stop-provisional-loads.html, we abort the load before this
403 // callback is invoked.
407 DocumentState* document_state = DocumentState::FromDataSource(ds);
409 // We should only navigate to swappedout:// when is_swapped_out_ is true.
410 CHECK((ds->request().url() != GURL(kSwappedOutURL)) ||
411 render_view_->is_swapped_out()) <<
412 "Heard swappedout:// when not swapped out.";
414 // Update the request time if WebKit has better knowledge of it.
415 if (document_state->request_time().is_null()) {
416 double event_time = ds->triggeringEventTime();
417 if (event_time != 0.0)
418 document_state->set_request_time(Time::FromDoubleT(event_time));
421 // Start time is only set after request time.
422 document_state->set_start_load_time(Time::Now());
424 bool is_top_most = !frame->parent();
426 render_view_->set_navigation_gesture(
427 WebUserGestureIndicator::isProcessingUserGesture() ?
428 NavigationGestureUser : NavigationGestureAuto);
429 } else if (ds->replacesCurrentHistoryItem()) {
430 // Subframe navigations that don't add session history items must be
431 // marked with AUTO_SUBFRAME. See also didFailProvisionalLoad for how we
432 // handle loading of error pages.
433 document_state->navigation_state()->set_transition_type(
434 PAGE_TRANSITION_AUTO_SUBFRAME);
438 RenderViewObserver, render_view_->observers(),
439 DidStartProvisionalLoad(frame));
441 Send(new FrameHostMsg_DidStartProvisionalLoadForFrame(
442 routing_id_, frame->identifier(),
443 frame->parent() ? frame->parent()->identifier() : -1,
444 is_top_most, ds->request().url()));
447 void RenderFrameImpl::didReceiveServerRedirectForProvisionalLoad(
448 WebKit::WebFrame* frame) {
449 // TODO(nasko): Move implementation here. Needed state:
451 render_view_->didReceiveServerRedirectForProvisionalLoad(frame);
454 void RenderFrameImpl::didFailProvisionalLoad(
455 WebKit::WebFrame* frame,
456 const WebKit::WebURLError& error) {
457 // TODO(nasko): Move implementation here. Needed state:
459 // * pending_navigation_params_
461 // * MaybeLoadAlternateErrorPage
462 // * LoadNavigationErrorPage
463 render_view_->didFailProvisionalLoad(frame, error);
466 void RenderFrameImpl::didCommitProvisionalLoad(WebKit::WebFrame* frame,
467 bool is_new_navigation) {
468 // TODO(nasko): Move implementation here. Needed state:
471 // * history_list_offset_
472 // * history_list_length_
473 // * history_page_ids_
476 // * UpdateSessionHistory
478 render_view_->didCommitProvisionalLoad(frame, is_new_navigation);
481 void RenderFrameImpl::didClearWindowObject(WebKit::WebFrame* frame) {
482 // TODO(nasko): Move implementation here. Needed state:
483 // * enabled_bindings_
484 // * dom_automation_controller_
485 // * stats_collection_controller_
486 render_view_->didClearWindowObject(frame);
489 void RenderFrameImpl::didCreateDocumentElement(WebKit::WebFrame* frame) {
490 // Notify the browser about non-blank documents loading in the top frame.
491 GURL url = frame->document().url();
492 if (url.is_valid() && url.spec() != kAboutBlankURL) {
493 // TODO(nasko): Check if webview()->mainFrame() is the same as the
494 // frame->tree()->top().
495 if (frame == render_view_->webview()->mainFrame()) {
496 render_view_->Send(new ViewHostMsg_DocumentAvailableInMainFrame(
497 render_view_->GetRoutingID()));
501 // Call back to RenderViewImpl for observers to be notified.
502 // TODO(nasko): Remove once we have RenderFrameObserver.
503 render_view_->didCreateDocumentElement(frame);
506 void RenderFrameImpl::didReceiveTitle(WebKit::WebFrame* frame,
507 const WebKit::WebString& title,
508 WebKit::WebTextDirection direction) {
509 // TODO(nasko): Investigate wheather implementation should move here.
510 render_view_->didReceiveTitle(frame, title, direction);
513 void RenderFrameImpl::didChangeIcon(WebKit::WebFrame* frame,
514 WebKit::WebIconURL::Type icon_type) {
515 // TODO(nasko): Investigate wheather implementation should move here.
516 render_view_->didChangeIcon(frame, icon_type);
519 void RenderFrameImpl::didFinishDocumentLoad(WebKit::WebFrame* frame) {
520 // TODO(nasko): Move implementation here. No state needed, just observers
521 // notification in before updating encoding.
522 render_view_->didFinishDocumentLoad(frame);
525 void RenderFrameImpl::didHandleOnloadEvents(WebKit::WebFrame* frame) {
526 // TODO(nasko): Move implementation here. Needed state:
528 render_view_->didHandleOnloadEvents(frame);
531 void RenderFrameImpl::didFailLoad(WebKit::WebFrame* frame,
532 const WebKit::WebURLError& error) {
533 // TODO(nasko): Move implementation here. No state needed.
534 render_view_->didFailLoad(frame, error);
537 void RenderFrameImpl::didFinishLoad(WebKit::WebFrame* frame) {
538 // TODO(nasko): Move implementation here. No state needed, just observers
539 // notification before sending message to the browser process.
540 render_view_->didFinishLoad(frame);
543 void RenderFrameImpl::didNavigateWithinPage(WebKit::WebFrame* frame,
544 bool is_new_navigation) {
545 // TODO(nasko): Move implementation here. No state needed, just observers
546 // notification before sending message to the browser process.
547 render_view_->didNavigateWithinPage(frame, is_new_navigation);
550 void RenderFrameImpl::didUpdateCurrentHistoryItem(WebKit::WebFrame* frame) {
551 // TODO(nasko): Move implementation here. Needed methods:
552 // * StartNavStateSyncTimerIfNecessary
553 render_view_->didUpdateCurrentHistoryItem(frame);
556 void RenderFrameImpl::willRequestAfterPreconnect(
557 WebKit::WebFrame* frame,
558 WebKit::WebURLRequest& request) {
559 WebKit::WebReferrerPolicy referrer_policy = WebKit::WebReferrerPolicyDefault;
560 WebString custom_user_agent;
562 if (request.extraData()) {
563 // This will only be called before willSendRequest, so only ExtraData
564 // members we have to copy here is on WebURLRequestExtraDataImpl.
565 webkit_glue::WebURLRequestExtraDataImpl* old_extra_data =
566 static_cast<webkit_glue::WebURLRequestExtraDataImpl*>(
567 request.extraData());
569 referrer_policy = old_extra_data->referrer_policy();
570 custom_user_agent = old_extra_data->custom_user_agent();
573 bool was_after_preconnect_request = true;
574 // The args after |was_after_preconnect_request| are not used, and set to
575 // correct values at |willSendRequest|.
576 request.setExtraData(new webkit_glue::WebURLRequestExtraDataImpl(
577 referrer_policy, custom_user_agent, was_after_preconnect_request));
580 void RenderFrameImpl::willSendRequest(
581 WebKit::WebFrame* frame,
583 WebKit::WebURLRequest& request,
584 const WebKit::WebURLResponse& redirect_response) {
585 // The request my be empty during tests.
586 if (request.url().isEmpty())
589 WebFrame* top_frame = frame->top();
592 WebDataSource* provisional_data_source = top_frame->provisionalDataSource();
593 WebDataSource* top_data_source = top_frame->dataSource();
594 WebDataSource* data_source =
595 provisional_data_source ? provisional_data_source : top_data_source;
597 PageTransition transition_type = PAGE_TRANSITION_LINK;
598 DocumentState* document_state = DocumentState::FromDataSource(data_source);
599 DCHECK(document_state);
600 InternalDocumentStateData* internal_data =
601 InternalDocumentStateData::FromDocumentState(document_state);
602 NavigationState* navigation_state = document_state->navigation_state();
603 transition_type = navigation_state->transition_type();
605 GURL request_url(request.url());
607 if (GetContentClient()->renderer()->WillSendRequest(
611 request.firstPartyForCookies(),
613 request.setURL(WebURL(new_url));
616 if (internal_data->is_cache_policy_override_set())
617 request.setCachePolicy(internal_data->cache_policy_override());
619 WebKit::WebReferrerPolicy referrer_policy;
620 if (internal_data->is_referrer_policy_set()) {
621 referrer_policy = internal_data->referrer_policy();
622 internal_data->clear_referrer_policy();
624 referrer_policy = frame->document().referrerPolicy();
627 // The request's extra data may indicate that we should set a custom user
628 // agent. This needs to be done here, after WebKit is through with setting the
629 // user agent on its own.
630 WebString custom_user_agent;
631 bool was_after_preconnect_request = false;
632 if (request.extraData()) {
633 webkit_glue::WebURLRequestExtraDataImpl* old_extra_data =
634 static_cast<webkit_glue::WebURLRequestExtraDataImpl*>(
635 request.extraData());
636 custom_user_agent = old_extra_data->custom_user_agent();
637 was_after_preconnect_request =
638 old_extra_data->was_after_preconnect_request();
640 if (!custom_user_agent.isNull()) {
641 if (custom_user_agent.isEmpty())
642 request.clearHTTPHeaderField("User-Agent");
644 request.setHTTPHeaderField("User-Agent", custom_user_agent);
648 request.setExtraData(
649 new RequestExtraData(referrer_policy,
651 was_after_preconnect_request,
652 (frame == top_frame),
654 GURL(frame->document().securityOrigin().toString()),
655 frame->parent() == top_frame,
656 frame->parent() ? frame->parent()->identifier() : -1,
657 navigation_state->allow_download(),
659 navigation_state->transferred_request_child_id(),
660 navigation_state->transferred_request_request_id()));
662 DocumentState* top_document_state =
663 DocumentState::FromDataSource(top_data_source);
664 if (top_document_state) {
665 // TODO(gavinp): separate out prefetching and prerender field trials
666 // if the rel=prerender rel type is sticking around.
667 if (request.targetType() == WebURLRequest::TargetIsPrefetch)
668 top_document_state->set_was_prefetcher(true);
670 if (was_after_preconnect_request)
671 top_document_state->set_was_after_preconnect_request(true);
674 // This is an instance where we embed a copy of the routing id
675 // into the data portion of the message. This can cause problems if we
676 // don't register this id on the browser side, since the download manager
677 // expects to find a RenderViewHost based off the id.
678 request.setRequestorID(render_view_->GetRoutingID());
679 request.setHasUserGesture(WebUserGestureIndicator::isProcessingUserGesture());
681 if (!navigation_state->extra_headers().empty()) {
682 for (net::HttpUtil::HeadersIterator i(
683 navigation_state->extra_headers().begin(),
684 navigation_state->extra_headers().end(), "\n");
686 request.setHTTPHeaderField(WebString::fromUTF8(i.name()),
687 WebString::fromUTF8(i.values()));
691 if (!render_view_->renderer_preferences_.enable_referrers)
692 request.clearHTTPHeaderField("Referer");
695 void RenderFrameImpl::didReceiveResponse(
696 WebKit::WebFrame* frame,
698 const WebKit::WebURLResponse& response) {
699 // Only do this for responses that correspond to a provisional data source
700 // of the top-most frame. If we have a provisional data source, then we
701 // can't have any sub-resources yet, so we know that this response must
702 // correspond to a frame load.
703 if (!frame->provisionalDataSource() || frame->parent())
706 // If we are in view source mode, then just let the user see the source of
707 // the server's error page.
708 if (frame->isViewSourceModeEnabled())
711 DocumentState* document_state =
712 DocumentState::FromDataSource(frame->provisionalDataSource());
713 int http_status_code = response.httpStatusCode();
715 // Record page load flags.
716 WebURLResponseExtraDataImpl* extra_data =
717 RenderViewImpl::GetExtraDataFromResponse(response);
719 document_state->set_was_fetched_via_spdy(
720 extra_data->was_fetched_via_spdy());
721 document_state->set_was_npn_negotiated(
722 extra_data->was_npn_negotiated());
723 document_state->set_npn_negotiated_protocol(
724 extra_data->npn_negotiated_protocol());
725 document_state->set_was_alternate_protocol_available(
726 extra_data->was_alternate_protocol_available());
727 document_state->set_connection_info(
728 extra_data->connection_info());
729 document_state->set_was_fetched_via_proxy(
730 extra_data->was_fetched_via_proxy());
732 InternalDocumentStateData* internal_data =
733 InternalDocumentStateData::FromDocumentState(document_state);
734 internal_data->set_http_status_code(http_status_code);
735 // Whether or not the http status code actually corresponds to an error is
736 // only checked when the page is done loading, if |use_error_page| is
738 internal_data->set_use_error_page(true);
741 void RenderFrameImpl::didFinishResourceLoad(WebKit::WebFrame* frame,
742 unsigned identifier) {
743 // TODO(nasko): Move implementation here. Needed state:
746 // * LoadNavigationErrorPage
747 render_view_->didFinishResourceLoad(frame, identifier);
750 void RenderFrameImpl::didLoadResourceFromMemoryCache(
751 WebKit::WebFrame* frame,
752 const WebKit::WebURLRequest& request,
753 const WebKit::WebURLResponse& response) {
754 // The recipients of this message have no use for data: URLs: they don't
755 // affect the page's insecure content list and are not in the disk cache. To
756 // prevent large (1M+) data: URLs from crashing in the IPC system, we simply
757 // filter them out here.
758 GURL url(request.url());
759 if (url.SchemeIs("data"))
762 // Let the browser know we loaded a resource from the memory cache. This
763 // message is needed to display the correct SSL indicators.
764 render_view_->Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(
765 render_view_->GetRoutingID(),
767 response.securityInfo(),
768 request.httpMethod().utf8(),
769 response.mimeType().utf8(),
770 ResourceType::FromTargetType(request.targetType())));
773 void RenderFrameImpl::didDisplayInsecureContent(WebKit::WebFrame* frame) {
774 render_view_->Send(new ViewHostMsg_DidDisplayInsecureContent(
775 render_view_->GetRoutingID()));
778 void RenderFrameImpl::didRunInsecureContent(
779 WebKit::WebFrame* frame,
780 const WebKit::WebSecurityOrigin& origin,
781 const WebKit::WebURL& target) {
782 render_view_->Send(new ViewHostMsg_DidRunInsecureContent(
783 render_view_->GetRoutingID(),
784 origin.toString().utf8(),
788 void RenderFrameImpl::didAbortLoading(WebKit::WebFrame* frame) {
789 #if defined(ENABLE_PLUGINS)
790 if (frame != render_view_->webview()->mainFrame())
792 PluginChannelHost::Broadcast(
793 new PluginHostMsg_DidAbortLoading(render_view_->GetRoutingID()));
797 void RenderFrameImpl::didExhaustMemoryAvailableForScript(
798 WebKit::WebFrame* frame) {
799 render_view_->Send(new ViewHostMsg_JSOutOfMemory(
800 render_view_->GetRoutingID()));
803 void RenderFrameImpl::didCreateScriptContext(WebKit::WebFrame* frame,
804 v8::Handle<v8::Context> context,
807 GetContentClient()->renderer()->DidCreateScriptContext(
808 frame, context, extension_group, world_id);
811 void RenderFrameImpl::willReleaseScriptContext(WebKit::WebFrame* frame,
812 v8::Handle<v8::Context> context,
814 GetContentClient()->renderer()->WillReleaseScriptContext(
815 frame, context, world_id);
818 void RenderFrameImpl::didFirstVisuallyNonEmptyLayout(WebKit::WebFrame* frame) {
819 render_view_->didFirstVisuallyNonEmptyLayout(frame);
822 void RenderFrameImpl::didChangeContentsSize(WebKit::WebFrame* frame,
823 const WebKit::WebSize& size) {
824 // TODO(nasko): Move implementation here. Needed state:
825 // * cached_has_main_frame_horizontal_scrollbar_
826 // * cached_has_main_frame_vertical_scrollbar_
827 render_view_->didChangeContentsSize(frame, size);
830 void RenderFrameImpl::didChangeScrollOffset(WebKit::WebFrame* frame) {
831 // TODO(nasko): Move implementation here. Needed methods:
832 // * StartNavStateSyncTimerIfNecessary
833 render_view_->didChangeScrollOffset(frame);
836 void RenderFrameImpl::willInsertBody(WebKit::WebFrame* frame) {
837 if (!frame->parent()) {
838 render_view_->Send(new ViewHostMsg_WillInsertBody(
839 render_view_->GetRoutingID()));
843 void RenderFrameImpl::reportFindInPageMatchCount(int request_id,
846 int active_match_ordinal = -1; // -1 = don't update active match ordinal
848 active_match_ordinal = 0;
850 render_view_->Send(new ViewHostMsg_Find_Reply(
851 render_view_->GetRoutingID(), request_id, count,
852 gfx::Rect(), active_match_ordinal, final_update));
855 void RenderFrameImpl::reportFindInPageSelection(
857 int active_match_ordinal,
858 const WebKit::WebRect& selection_rect) {
859 render_view_->Send(new ViewHostMsg_Find_Reply(
860 render_view_->GetRoutingID(), request_id, -1, selection_rect,
861 active_match_ordinal, false));
864 void RenderFrameImpl::requestStorageQuota(
865 WebKit::WebFrame* frame,
866 WebKit::WebStorageQuotaType type,
867 unsigned long long requested_size,
868 WebKit::WebStorageQuotaCallbacks* callbacks) {
870 WebSecurityOrigin origin = frame->document().securityOrigin();
871 if (origin.isUnique()) {
872 // Unique origins cannot store persistent state.
873 callbacks->didFail(WebKit::WebStorageQuotaErrorAbort);
876 ChildThread::current()->quota_dispatcher()->RequestStorageQuota(
877 render_view_->GetRoutingID(), GURL(origin.toString()),
878 static_cast<quota::StorageType>(type), requested_size,
879 QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks));
882 void RenderFrameImpl::willOpenSocketStream(
883 WebKit::WebSocketStreamHandle* handle) {
884 SocketStreamHandleData::AddToHandle(handle, render_view_->GetRoutingID());
887 void RenderFrameImpl::willStartUsingPeerConnectionHandler(
888 WebKit::WebFrame* frame,
889 WebKit::WebRTCPeerConnectionHandler* handler) {
890 #if defined(ENABLE_WEBRTC)
891 static_cast<RTCPeerConnectionHandler*>(handler)->associateWithFrame(frame);
895 bool RenderFrameImpl::willCheckAndDispatchMessageEvent(
896 WebKit::WebFrame* sourceFrame,
897 WebKit::WebFrame* targetFrame,
898 WebKit::WebSecurityOrigin targetOrigin,
899 WebKit::WebDOMMessageEvent event) {
900 // TODO(nasko): Move implementation here. Needed state:
902 return render_view_->willCheckAndDispatchMessageEvent(
903 sourceFrame, targetFrame, targetOrigin, event);
906 WebKit::WebString RenderFrameImpl::userAgentOverride(
907 WebKit::WebFrame* frame,
908 const WebKit::WebURL& url) {
909 if (!render_view_->webview() || !render_view_->webview()->mainFrame() ||
910 render_view_->renderer_preferences_.user_agent_override.empty()) {
911 return WebKit::WebString();
914 // If we're in the middle of committing a load, the data source we need
915 // will still be provisional.
916 WebFrame* main_frame = render_view_->webview()->mainFrame();
917 WebDataSource* data_source = NULL;
918 if (main_frame->provisionalDataSource())
919 data_source = main_frame->provisionalDataSource();
921 data_source = main_frame->dataSource();
923 InternalDocumentStateData* internal_data = data_source ?
924 InternalDocumentStateData::FromDataSource(data_source) : NULL;
925 if (internal_data && internal_data->is_overriding_user_agent())
926 return WebString::fromUTF8(
927 render_view_->renderer_preferences_.user_agent_override);
928 return WebKit::WebString();
931 WebKit::WebString RenderFrameImpl::doNotTrackValue(WebKit::WebFrame* frame) {
932 if (render_view_->renderer_preferences_.enable_do_not_track)
933 return WebString::fromUTF8("1");
937 bool RenderFrameImpl::allowWebGL(WebKit::WebFrame* frame, bool default_value) {
942 render_view_->Send(new ViewHostMsg_Are3DAPIsBlocked(
943 render_view_->GetRoutingID(),
944 GURL(frame->top()->document().securityOrigin().toString()),
945 THREE_D_API_TYPE_WEBGL,
950 void RenderFrameImpl::didLoseWebGLContext(WebKit::WebFrame* frame,
951 int arb_robustness_status_code) {
952 render_view_->Send(new ViewHostMsg_DidLose3DContext(
953 GURL(frame->top()->document().securityOrigin().toString()),
954 THREE_D_API_TYPE_WEBGL,
955 arb_robustness_status_code));
958 } // namespace content