render_frame_host_impl.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/render_frame_host_impl.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/containers/hash_tables.h"
8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/lazy_instance.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/user_metrics_action.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/child_process_security_policy_impl.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/frame_host/cross_process_frame_connector.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/frame_host/cross_site_transferring_request.h"
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/frame_tree.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/frame_host/frame_tree_node.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/frame_host/navigator.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/frame_host/render_frame_host_delegate.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/common/frame_messages.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/input_messages.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/inter_process_time_ticks_converter.h"
2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/common/swapped_out_messages.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/content_browser_client.h"
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/render_process_host.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/url_constants.h"
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "url/gurl.h"
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::TimeDelta;
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content {
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// The (process id, routing id) pair that identifies one RenderFrame.
35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)typedef std::pair<int32, int32> RenderFrameHostID;
36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*>
37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    RoutingIDFrameMap;
38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static base::LazyInstance<RoutingIDFrameMap> g_routing_id_frame_map =
39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)RenderFrameHost* RenderFrameHost::FromID(int render_process_id,
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         int render_frame_id) {
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return RenderFrameHostImpl::FromID(render_process_id, render_frame_id);
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// static
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)RenderFrameHostImpl* RenderFrameHostImpl::FromID(
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int process_id, int routing_id) {
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RoutingIDFrameMap* frames = g_routing_id_frame_map.Pointer();
51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RoutingIDFrameMap::iterator it = frames->find(
52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      RenderFrameHostID(process_id, routing_id));
53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return it == frames->end() ? NULL : it->second;
54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)RenderFrameHostImpl::RenderFrameHostImpl(
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RenderViewHostImpl* render_view_host,
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RenderFrameHostDelegate* delegate,
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FrameTree* frame_tree,
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    FrameTreeNode* frame_tree_node,
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int routing_id,
62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    bool is_swapped_out)
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : render_view_host_(render_view_host),
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      delegate_(delegate),
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      cross_process_frame_connector_(NULL),
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      frame_tree_(frame_tree),
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      frame_tree_node_(frame_tree_node),
68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      routing_id_(routing_id),
69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      is_swapped_out_(is_swapped_out) {
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_tree_->RegisterRenderFrameHost(this);
71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  GetProcess()->AddRoute(routing_id_, this);
72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  g_routing_id_frame_map.Get().insert(std::make_pair(
73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      RenderFrameHostID(GetProcess()->GetID(), routing_id_),
74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      this));
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)RenderFrameHostImpl::~RenderFrameHostImpl() {
78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  GetProcess()->RemoveRoute(routing_id_);
79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  g_routing_id_frame_map.Get().erase(
80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      RenderFrameHostID(GetProcess()->GetID(), routing_id_));
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (delegate_)
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    delegate_->RenderFrameDeleted(this);
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Notify the FrameTree that this RFH is going away, allowing it to shut down
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the corresponding RenderViewHost if it is no longer needed.
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_tree_->UnregisterRenderFrameHost(this);
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int RenderFrameHostImpl::GetRoutingID() {
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return routing_id_;
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SiteInstance* RenderFrameHostImpl::GetSiteInstance() {
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return render_view_host_->GetSiteInstance();
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)RenderProcessHost* RenderFrameHostImpl::GetProcess() {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(nasko): This should return its own process, once we have working
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // cross-process navigation for subframes.
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return render_view_host_->GetProcess();
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)RenderFrameHost* RenderFrameHostImpl::GetParent() {
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FrameTreeNode* parent_node = frame_tree_node_->parent();
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!parent_node)
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return NULL;
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return parent_node->current_frame_host();
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const std::string& RenderFrameHostImpl::GetFrameName() {
11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return frame_tree_node_->frame_name();
11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool RenderFrameHostImpl::IsCrossProcessSubframe() {
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FrameTreeNode* parent_node = frame_tree_node_->parent();
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!parent_node)
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetSiteInstance() !=
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      parent_node->current_frame_host()->GetSiteInstance();
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)GURL RenderFrameHostImpl::GetLastCommittedURL() {
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return frame_tree_node_->current_url();
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::NativeView RenderFrameHostImpl::GetNativeView() {
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderWidgetHostView* view = render_view_host_->GetView();
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!view)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NULL;
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return view->GetNativeView();
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::DispatchBeforeUnload(bool for_cross_site_transition) {
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(creis): Support subframes.
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!GetParent());
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!render_view_host_->IsRenderViewLive()) {
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // We don't have a live renderer, so just skip running beforeunload.
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_view_host_->is_waiting_for_beforeunload_ack_ = true;
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_view_host_->unload_ack_is_for_cross_site_transition_ =
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        for_cross_site_transition;
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::TimeTicks now = base::TimeTicks::Now();
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    OnBeforeUnloadACK(true, now, now);
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This may be called more than once (if the user clicks the tab close button
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // several times, or if she clicks the tab close button then the browser close
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // button), and we only send the message once.
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (render_view_host_->is_waiting_for_beforeunload_ack_) {
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Some of our close messages could be for the tab, others for cross-site
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // transitions. We always want to think it's for closing the tab if any
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // of the messages were, since otherwise it might be impossible to close
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // (if there was a cross-site "close" request pending when the user clicked
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // the close button). We want to keep the "for cross site" flag only if
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // both the old and the new ones are also for cross site.
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_view_host_->unload_ack_is_for_cross_site_transition_ =
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        render_view_host_->unload_ack_is_for_cross_site_transition_ &&
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        for_cross_site_transition;
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Start the hang monitor in case the renderer hangs in the beforeunload
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // handler.
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_view_host_->is_waiting_for_beforeunload_ack_ = true;
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_view_host_->unload_ack_is_for_cross_site_transition_ =
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        for_cross_site_transition;
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Increment the in-flight event count, to ensure that input events won't
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // cancel the timeout timer.
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_view_host_->increment_in_flight_event_count();
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_view_host_->StartHangMonitorTimeout(
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS));
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    send_before_unload_start_time_ = base::TimeTicks::Now();
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Send(new FrameMsg_BeforeUnload(routing_id_));
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::NotifyContextMenuClosed(
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const CustomContextMenuContext& context) {
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Send(new FrameMsg_ContextMenuClosed(routing_id_, context));
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::ExecuteCustomContextMenuCommand(
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int action, const CustomContextMenuContext& context) {
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Send(new FrameMsg_CustomContextMenuAction(routing_id_, context, action));
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::Cut() {
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Send(new InputMsg_Cut(routing_id_));
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RecordAction(base::UserMetricsAction("Cut"));
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::Copy() {
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Send(new InputMsg_Copy(routing_id_));
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RecordAction(base::UserMetricsAction("Copy"));
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::Paste() {
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Send(new InputMsg_Paste(routing_id_));
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RecordAction(base::UserMetricsAction("Paste"));
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::InsertCSS(const std::string& css) {
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Send(new FrameMsg_CSSInsertRequest(routing_id_, css));
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::ExecuteJavaScript(
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::string16& javascript) {
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Send(new FrameMsg_JavaScriptExecuteRequest(routing_id_,
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             javascript,
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             0, false));
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::ExecuteJavaScript(
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)     const base::string16& javascript,
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)     const JavaScriptResultCallback& callback) {
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static int next_id = 1;
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int key = next_id++;
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Send(new FrameMsg_JavaScriptExecuteRequest(routing_id_,
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             javascript,
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             key, true));
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  javascript_callbacks_.insert(std::make_pair(key, callback));
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)RenderViewHost* RenderFrameHostImpl::GetRenderViewHost() {
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return render_view_host_;
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool RenderFrameHostImpl::Send(IPC::Message* message) {
228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return GetProcess()->Send(message);
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Filter out most IPC messages if this renderer is swapped out.
23323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // We still want to handle certain ACKs to keep our state consistent.
23423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // TODO(nasko): Only check RenderViewHost state, as this object's own state
23523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // isn't yet properly updated. Transition this check once the swapped out
23623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // state is correct in RenderFrameHost itself.
23723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (render_view_host_->IsSwappedOut()) {
23823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (!SwappedOutMessages::CanHandleWhileSwappedOut(msg)) {
23923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      // If this is a synchronous message and we decided not to handle it,
24023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      // we must send an error reply, or else the renderer will be stuck
24123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      // and won't respond to future requests.
24223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      if (msg.is_sync()) {
24323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
24423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        reply->set_reply_error();
24523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        Send(reply);
24623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      }
24723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      // Don't continue looking for someone to handle it.
24823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      return true;
24923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
25023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
25123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (delegate_->OnMessageReceived(this, msg))
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return true;
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (cross_process_frame_connector_ &&
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      cross_process_frame_connector_->OnMessageReceived(msg))
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool handled = true;
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool msg_is_ok = true;
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP_EX(RenderFrameHostImpl, msg, msg_is_ok)
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_Detach, OnDetach)
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_FrameFocused, OnFrameFocused)
2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartProvisionalLoadForFrame,
2658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                        OnDidStartProvisionalLoadForFrame)
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_DidFailProvisionalLoadWithError,
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnDidFailProvisionalLoadWithError)
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_DidRedirectProvisionalLoad,
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnDidRedirectProvisionalLoad)
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_DidFailLoadWithError,
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnDidFailLoadWithError)
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_DidCommitProvisionalLoad,
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                OnNavigate(msg))
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading)
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading)
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL)
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_BeforeUnload_ACK, OnBeforeUnloadACK)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_SwapOut_ACK, OnSwapOutACK)
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_ContextMenu, OnContextMenu)
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_JavaScriptExecuteResponse,
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        OnJavaScriptExecuteResponse)
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_END_MESSAGE_MAP_EX()
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!msg_is_ok) {
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // The message had a handler, but its de-serialization failed.
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Kill the renderer.
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RecordAction(base::UserMetricsAction("BadMessageTerminate_RFH"));
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GetProcess()->ReceivedBadMessage();
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return handled;
292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void RenderFrameHostImpl::Init() {
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetProcess()->ResumeRequestsForView(routing_id_);
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::OnCreateChildFrame(int new_routing_id,
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             const std::string& frame_name) {
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RenderFrameHostImpl* new_frame = frame_tree_->AddFrame(
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      frame_tree_node_, new_routing_id, frame_name);
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (delegate_)
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    delegate_->RenderFrameCreated(new_frame);
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::OnDetach() {
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  frame_tree_->RemoveFrame(frame_tree_node_);
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::OnFrameFocused() {
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  frame_tree_->SetFocusedFrame(frame_tree_node_);
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::OnOpenURL(
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const FrameHostMsg_OpenURL_Params& params) {
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GURL validated_url(params.url);
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetProcess()->FilterURL(false, &validated_url);
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  frame_tree_node_->navigator()->RequestOpenURL(
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      this, validated_url, params.referrer, params.disposition,
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      params.should_replace_current_entry, params.user_gesture);
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void RenderFrameHostImpl::OnDidStartProvisionalLoadForFrame(
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int parent_routing_id,
3268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    bool is_main_frame,
3278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const GURL& url) {
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  frame_tree_node_->navigator()->DidStartProvisionalLoad(
329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      this, parent_routing_id, is_main_frame, url);
3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::OnDidFailProvisionalLoadWithError(
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) {
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_tree_node_->navigator()->DidFailProvisionalLoadWithError(this, params);
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::OnDidFailLoadWithError(
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& url,
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool is_main_frame,
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int error_code,
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& error_description) {
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL validated_url(url);
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetProcess()->FilterURL(false, &validated_url);
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_tree_node_->navigator()->DidFailLoadWithError(
346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      this, validated_url, is_main_frame, error_code,
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      error_description);
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::OnDidRedirectProvisionalLoad(
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int32 page_id,
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& source_url,
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& target_url) {
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_tree_node_->navigator()->DidRedirectProvisionalLoad(
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this, page_id, source_url, target_url);
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Called when the renderer navigates.  For every frame loaded, we'll get this
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// notification containing parameters identifying the navigation.
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Subframes are identified by the page transition type.  For subframes loaded
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// as part of a wider page load, the page_id will be the same as for the top
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// level frame.  If the user explicitly requests a subframe navigation, we will
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// get a new page_id because we need to create a new navigation entry for that
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// action.
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::OnNavigate(const IPC::Message& msg) {
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Read the parameters out of the IPC message directly to avoid making another
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // copy when we filter the URLs.
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PickleIterator iter(msg);
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params validated_params;
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!IPC::ParamTraits<FrameHostMsg_DidCommitProvisionalLoad_Params>::
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Read(&msg, &iter, &validated_params))
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If we're waiting for a cross-site beforeunload ack from this renderer and
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // we receive a Navigate message from the main frame, then the renderer was
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // navigating already and sent it before hearing the ViewMsg_Stop message.
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We do not want to cancel the pending navigation in this case, since the
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // old page will soon be stopped.  Instead, treat this as a beforeunload ack
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to allow the pending navigation to continue.
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (render_view_host_->is_waiting_for_beforeunload_ack_ &&
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      render_view_host_->unload_ack_is_for_cross_site_transition_ &&
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PageTransitionIsMainFrame(validated_params.transition)) {
384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    OnBeforeUnloadACK(true, send_before_unload_start_time_,
385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      base::TimeTicks::Now());
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If we're waiting for an unload ack from this renderer and we receive a
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Navigate message, then the renderer was navigating before it received the
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // unload request.  It will either respond to the unload request soon or our
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // timer will expire.  Either way, we should ignore this message, because we
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // have already committed to closing this renderer.
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (render_view_host_->IsWaitingForUnloadACK())
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderProcessHost* process = GetProcess();
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Attempts to commit certain off-limits URL should be caught more strictly
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // than our FilterURL checks below.  If a renderer violates this policy, it
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // should be killed.
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!CanCommitURL(validated_params.url)) {
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    VLOG(1) << "Blocked URL " << validated_params.url.spec();
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    validated_params.url = GURL(kAboutBlankURL);
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RecordAction(base::UserMetricsAction("CanCommitURL_BlockedAndKilled"));
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Kills the process.
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    process->ReceivedBadMessage();
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Now that something has committed, we don't need to track whether the
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // initial page has been accessed.
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  render_view_host_->has_accessed_initial_document_ = false;
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Without this check, an evil renderer can trick the browser into creating
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // a navigation entry for a banned URL.  If the user clicks the back button
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // followed by the forward button (or clicks reload, or round-trips through
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // session restore, etc), we'll think that the browser commanded the
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // renderer to load the URL and grant the renderer the privileges to request
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the URL.  To prevent this attack, we block the renderer from inserting
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // banned URLs into the navigation controller in the first place.
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  process->FilterURL(false, &validated_params.url);
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  process->FilterURL(true, &validated_params.referrer.url);
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (std::vector<GURL>::iterator it(validated_params.redirects.begin());
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      it != validated_params.redirects.end(); ++it) {
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    process->FilterURL(false, &(*it));
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  process->FilterURL(true, &validated_params.searchable_form_url);
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Without this check, the renderer can trick the browser into using
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // filenames it can't access in a future session restore.
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!render_view_host_->CanAccessFilesOfPageState(
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          validated_params.page_state)) {
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetProcess()->ReceivedBadMessage();
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_tree_node()->navigator()->DidNavigate(this, validated_params);
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int RenderFrameHostImpl::GetEnabledBindings() {
441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return render_view_host_->GetEnabledBindings();
442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::OnCrossSiteResponse(
445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const GlobalRequestID& global_request_id,
446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request,
447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::vector<GURL>& transfer_url_chain,
448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const Referrer& referrer,
449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PageTransition page_transition,
450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool should_replace_current_entry) {
451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  frame_tree_node_->render_manager()->OnCrossSiteResponse(
452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      this, global_request_id, cross_site_transferring_request.Pass(),
453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      transfer_url_chain, referrer, page_transition,
454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      should_replace_current_entry);
455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::SwapOut() {
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (render_view_host_->IsRenderViewLive()) {
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Send(new FrameMsg_SwapOut(routing_id_));
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Our RenderViewHost doesn't have a live renderer, so just skip the unload
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // event.
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    OnSwappedOut(true);
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::OnDidStartLoading() {
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->DidStartLoading(this);
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::OnDidStopLoading() {
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->DidStopLoading(this);
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::OnBeforeUnloadACK(
476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool proceed,
477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::TimeTicks& renderer_before_unload_start_time,
478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::TimeTicks& renderer_before_unload_end_time) {
479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(creis): Support beforeunload on subframes.
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (GetParent()) {
481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NOTREACHED() << "Should only receive BeforeUnload_ACK from the main frame.";
482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_view_host_->decrement_in_flight_event_count();
486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_view_host_->StopHangMonitorTimeout();
487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If this renderer navigated while the beforeunload request was in flight, we
488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // may have cleared this state in OnNavigate, in which case we can ignore
489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // this message.
490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!render_view_host_->is_waiting_for_beforeunload_ack_ ||
491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      render_view_host_->rvh_state_ != RenderViewHostImpl::STATE_DEFAULT) {
492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
494a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_view_host_->is_waiting_for_beforeunload_ack_ = false;
496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::TimeTicks before_unload_end_time;
498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!send_before_unload_start_time_.is_null() &&
499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !renderer_before_unload_start_time.is_null() &&
500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !renderer_before_unload_end_time.is_null()) {
501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // When passing TimeTicks across process boundaries, we need to compensate
502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // for any skew between the processes. Here we are converting the
503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // renderer's notion of before_unload_end_time to TimeTicks in the browser
504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // process. See comments in inter_process_time_ticks_converter.h for more.
505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    InterProcessTimeTicksConverter converter(
506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        LocalTimeTicks::FromTimeTicks(send_before_unload_start_time_),
507a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        LocalTimeTicks::FromTimeTicks(base::TimeTicks::Now()),
508a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        RemoteTimeTicks::FromTimeTicks(renderer_before_unload_start_time),
509a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        RemoteTimeTicks::FromTimeTicks(renderer_before_unload_end_time));
510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    LocalTimeTicks browser_before_unload_end_time =
511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        converter.ToLocalTimeTicks(
512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            RemoteTimeTicks::FromTimeTicks(renderer_before_unload_end_time));
513a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    before_unload_end_time = browser_before_unload_end_time.ToTimeTicks();
514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  frame_tree_node_->render_manager()->OnBeforeUnloadACK(
516a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      render_view_host_->unload_ack_is_for_cross_site_transition_, proceed,
517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      before_unload_end_time);
518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If canceled, notify the delegate to cancel its pending navigation entry.
520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!proceed)
521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_view_host_->GetDelegate()->DidCancelLoading();
522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::OnSwapOutACK() {
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OnSwappedOut(false);
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::OnSwappedOut(bool timed_out) {
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_tree_node_->render_manager()->SwappedOutFrame(this);
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::OnContextMenu(const ContextMenuParams& params) {
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Validate the URLs in |params|.  If the renderer can't request the URLs
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // directly, don't show them in the context menu.
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ContextMenuParams validated_params(params);
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderProcessHost* process = GetProcess();
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We don't validate |unfiltered_link_url| so that this field can be used
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // when users want to copy the original link URL.
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  process->FilterURL(true, &validated_params.link_url);
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  process->FilterURL(true, &validated_params.src_url);
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  process->FilterURL(false, &validated_params.page_url);
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  process->FilterURL(true, &validated_params.frame_url);
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->ShowContextMenu(this, validated_params);
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RenderFrameHostImpl::OnJavaScriptExecuteResponse(
549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int id, const base::ListValue& result) {
550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const base::Value* result_value;
551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!result.Get(0, &result_value)) {
552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Programming error or rogue renderer.
553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NOTREACHED() << "Got bad arguments for OnJavaScriptExecuteResponse";
554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::map<int, JavaScriptResultCallback>::iterator it =
558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      javascript_callbacks_.find(id);
559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (it != javascript_callbacks_.end()) {
560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    it->second.Run(result_value);
561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    javascript_callbacks_.erase(it);
562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NOTREACHED() << "Received script response for unknown request";
564a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
566a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::SetPendingShutdown(const base::Closure& on_swap_out) {
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  render_view_host_->SetPendingShutdown(on_swap_out);
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool RenderFrameHostImpl::CanCommitURL(const GURL& url) {
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(creis): We should also check for WebUI pages here.  Also, when the
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // out-of-process iframes implementation is ready, we should check for
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // cross-site URLs that are not allowed to commit in this process.
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Give the client a chance to disallow URLs from committing.
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return GetContentClient()->browser()->CanCommitURL(GetProcess(), url);
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::Navigate(const FrameMsg_Navigate_Params& params) {
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT0("frame_host", "RenderFrameHostImpl::Navigate");
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Browser plugin guests are not allowed to navigate outside web-safe schemes,
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // so do not grant them the ability to request additional URLs.
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!GetProcess()->IsGuest()) {
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL(
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        GetProcess()->GetID(), params.url);
5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (params.url.SchemeIs(kDataScheme) &&
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        params.base_url_for_data_url.SchemeIs(kFileScheme)) {
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // If 'data:' is used, and we have a 'file:' base url, grant access to
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // local files.
5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL(
5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GetProcess()->GetID(), params.base_url_for_data_url);
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Only send the message if we aren't suspended at the start of a cross-site
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // request.
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (render_view_host_->navigations_suspended_) {
5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Shouldn't be possible to have a second navigation while suspended, since
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // navigations will only be suspended during a cross-site request.  If a
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // second navigation occurs, RenderFrameHostManager will cancel this pending
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // RFH and create a new pending RFH.
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(!render_view_host_->suspended_nav_params_.get());
6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    render_view_host_->suspended_nav_params_.reset(
6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new FrameMsg_Navigate_Params(params));
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Get back to a clean state, in case we start a new navigation without
6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // completing a RVH swap or unload handler.
6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    render_view_host_->SetState(RenderViewHostImpl::STATE_DEFAULT);
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Send(new FrameMsg_Navigate(routing_id_, params));
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Force the throbber to start. We do this because Blink's "started
6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // loading" message will be received asynchronously from the UI of the
6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // browser. But we want to keep the throbber in sync with what's happening
6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in the UI. For example, we want to start throbbing immediately when the
6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // user naivgates even if the renderer is delayed. There is also an issue
6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // with the throbber starting because the WebUI (which controls whether the
6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // favicon is displayed) happens synchronously. If the start loading
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // messages was asynchronous, then the default favicon would flash in.
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Blink doesn't send throb notifications for JavaScript URLs, so we
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // don't want to either.
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!params.url.SchemeIs(kJavaScriptScheme))
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delegate_->DidStartLoading(this);
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RenderFrameHostImpl::NavigateToURL(const GURL& url) {
6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameMsg_Navigate_Params params;
6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.page_id = -1;
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.pending_history_list_offset = -1;
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.current_history_list_offset = -1;
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.current_history_list_length = 0;
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.url = url;
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.transition = PAGE_TRANSITION_LINK;
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Navigate(params);
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace content
642