Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / renderer / render_frame_impl.cc
index 9c6ca8e..ec72834 100644 (file)
 #include "content/child/plugin_messages.h"
 #include "content/child/quota_dispatcher.h"
 #include "content/child/request_extra_data.h"
+#include "content/child/service_worker/service_worker_handle_reference.h"
 #include "content/child/service_worker/service_worker_network_provider.h"
 #include "content/child/service_worker/service_worker_provider_context.h"
 #include "content/child/service_worker/web_service_worker_provider_impl.h"
-#include "content/child/web_socket_stream_handle_impl.h"
+#include "content/child/web_url_loader_impl.h"
 #include "content/child/web_url_request_util.h"
 #include "content/child/webmessageportchannel_impl.h"
 #include "content/child/websocket_bridge.h"
 #include "content/common/frame_messages.h"
 #include "content/common/input_messages.h"
 #include "content/common/service_worker/service_worker_types.h"
-#include "content/common/socket_stream_handle_data.h"
 #include "content/common/swapped_out_messages.h"
 #include "content/common/view_messages.h"
 #include "content/public/common/bindings_policy.h"
 #include "content/public/common/content_constants.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/context_menu_params.h"
+#include "content/public/common/page_state.h"
+#include "content/public/common/resource_response.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
 #include "content/public/renderer/browser_plugin_delegate.h"
@@ -50,9 +52,8 @@
 #include "content/public/renderer/document_state.h"
 #include "content/public/renderer/navigation_state.h"
 #include "content/public/renderer/render_frame_observer.h"
+#include "content/public/renderer/renderer_ppapi_host.h"
 #include "content/renderer/accessibility/renderer_accessibility.h"
-#include "content/renderer/accessibility/renderer_accessibility_complete.h"
-#include "content/renderer/accessibility/renderer_accessibility_focus_only.h"
 #include "content/renderer/browser_plugin/browser_plugin.h"
 #include "content/renderer/browser_plugin/browser_plugin_manager.h"
 #include "content/renderer/child_frame_compositing_helper.h"
@@ -70,6 +71,7 @@
 #include "content/renderer/manifest/manifest_manager.h"
 #include "content/renderer/media/audio_renderer_mixer_manager.h"
 #include "content/renderer/media/crypto/encrypted_media_player_support_impl.h"
+#include "content/renderer/media/crypto/render_cdm_factory.h"
 #include "content/renderer/media/media_stream_dispatcher.h"
 #include "content/renderer/media/media_stream_renderer_factory.h"
 #include "content/renderer/media/midi_dispatcher.h"
 #include "content/renderer/media/user_media_client_impl.h"
 #include "content/renderer/media/webcontentdecryptionmodule_impl.h"
 #include "content/renderer/media/webmediaplayer_ms.h"
+#include "content/renderer/mojo/service_registry_js_wrapper.h"
 #include "content/renderer/notification_permission_dispatcher.h"
 #include "content/renderer/notification_provider.h"
 #include "content/renderer/npapi/plugin_channel_host.h"
 #include "content/renderer/push_messaging_dispatcher.h"
+#include "content/renderer/push_permission_dispatcher.h"
 #include "content/renderer/render_frame_proxy.h"
 #include "content/renderer/render_process.h"
 #include "content/renderer/render_thread_impl.h"
 #include "content/renderer/shared_worker_repository.h"
 #include "content/renderer/v8_value_converter_impl.h"
 #include "content/renderer/websharedworker_proxy.h"
+#include "gin/modules/module_registry.h"
 #include "media/base/audio_renderer_mixer_input.h"
+#include "media/base/renderer.h"
 #include "media/blink/webmediaplayer_impl.h"
 #include "media/blink/webmediaplayer_params.h"
 #include "media/filters/gpu_video_accelerator_factories.h"
+#include "mojo/edk/js/core.h"
+#include "mojo/edk/js/support.h"
 #include "net/base/data_url.h"
 #include "net/base/net_errors.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "third_party/WebKit/public/web/WebNavigationPolicy.h"
 #include "third_party/WebKit/public/web/WebPlugin.h"
 #include "third_party/WebKit/public/web/WebPluginParams.h"
+#include "third_party/WebKit/public/web/WebPluginPlaceholder.h"
 #include "third_party/WebKit/public/web/WebRange.h"
 #include "third_party/WebKit/public/web/WebScriptSource.h"
 #include "third_party/WebKit/public/web/WebSearchableFormData.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/pepper/pepper_webplugin_impl.h"
 #include "content/renderer/pepper/plugin_module.h"
+#include "content/renderer/pepper/plugin_power_saver_helper.h"
 #endif
 
 #if defined(ENABLE_WEBRTC)
 #include "content/renderer/media/android/webmediaplayer_android.h"
 #endif
 
-#if defined(ENABLE_BROWSER_CDMS)
+#if defined(ENABLE_PEPPER_CDMS)
+#include "content/renderer/media/crypto/pepper_cdm_wrapper_impl.h"
+#elif defined(ENABLE_BROWSER_CDMS)
 #include "content/renderer/media/crypto/renderer_cdm_manager.h"
 #endif
 
@@ -365,6 +377,109 @@ static bool IsNonLocalTopLevelNavigation(const GURL& url,
   return false;
 }
 
+WebURLRequest CreateURLRequestForNavigation(
+    const CommonNavigationParams& common_params,
+    const RequestNavigationParams& request_params,
+    scoped_ptr<StreamOverrideParameters> stream_override,
+    bool is_view_source_mode_enabled) {
+  WebURLRequest request(common_params.url);
+  if (is_view_source_mode_enabled)
+    request.setCachePolicy(WebURLRequest::ReturnCacheDataElseLoad);
+
+  if (common_params.referrer.url.is_valid()) {
+    WebString web_referrer = WebSecurityPolicy::generateReferrerHeader(
+        common_params.referrer.policy,
+        common_params.url,
+        WebString::fromUTF8(common_params.referrer.url.spec()));
+    if (!web_referrer.isEmpty())
+      request.setHTTPReferrer(web_referrer, common_params.referrer.policy);
+  }
+
+  if (!request_params.extra_headers.empty()) {
+    for (net::HttpUtil::HeadersIterator i(request_params.extra_headers.begin(),
+                                          request_params.extra_headers.end(),
+                                          "\n");
+         i.GetNext();) {
+      request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
+                                 WebString::fromUTF8(i.values()));
+    }
+  }
+
+  if (request_params.is_post) {
+    request.setHTTPMethod(WebString::fromUTF8("POST"));
+
+    // Set post data.
+    WebHTTPBody http_body;
+    http_body.initialize();
+    const char* data = NULL;
+    if (request_params.browser_initiated_post_data.size()) {
+      data = reinterpret_cast<const char*>(
+          &request_params.browser_initiated_post_data.front());
+    }
+    http_body.appendData(
+        WebData(data, request_params.browser_initiated_post_data.size()));
+    request.setHTTPBody(http_body);
+  }
+
+  RequestExtraData* extra_data = new RequestExtraData();
+  extra_data->set_stream_override(stream_override.Pass());
+  request.setExtraData(extra_data);
+  return request;
+}
+
+void UpdateFrameNavigationTiming(WebFrame* frame,
+                                 base::TimeTicks browser_navigation_start,
+                                 base::TimeTicks renderer_navigation_start) {
+  // The browser provides the navigation_start time to bootstrap the
+  // Navigation Timing information for the browser-initiated navigations. In
+  // case of cross-process navigations, this carries over the time of
+  // finishing the onbeforeunload handler of the previous page.
+  DCHECK(!browser_navigation_start.is_null());
+  if (frame->provisionalDataSource()) {
+    // |browser_navigation_start| is likely before this process existed, so we
+    // can't use InterProcessTimeTicksConverter. We need at least to ensure
+    // that the browser-side navigation start we set is not later than the one
+    // on the renderer side.
+    base::TimeTicks navigation_start = std::min(
+        browser_navigation_start, renderer_navigation_start);
+    double navigation_start_seconds =
+        (navigation_start - base::TimeTicks()).InSecondsF();
+    frame->provisionalDataSource()->setNavigationStartTime(
+        navigation_start_seconds);
+    // TODO(clamy): We need to provide additional timing values for the
+    // Navigation Timing API to work with browser-side navigations.
+  }
+}
+
+// PlzNavigate
+FrameHostMsg_BeginNavigation_Params MakeBeginNavigationParams(
+    const blink::WebURLRequest& request) {
+  FrameHostMsg_BeginNavigation_Params params;
+  params.method = request.httpMethod().latin1();
+  params.headers = GetWebURLRequestHeaders(request);
+  params.load_flags = GetLoadFlagsForWebURLRequest(request);
+  // TODO(clamy): fill the http body.
+  params.has_user_gesture = request.hasUserGesture();
+  return params;
+}
+
+// PlzNavigate
+CommonNavigationParams MakeCommonNavigationParams(
+    const blink::WebURLRequest& request) {
+  const RequestExtraData kEmptyData;
+  const RequestExtraData* extra_data =
+      static_cast<RequestExtraData*>(request.extraData());
+  if (!extra_data)
+    extra_data = &kEmptyData;
+  CommonNavigationParams params;
+  params.url = request.url();
+  params.referrer = Referrer(
+      GURL(request.httpHeaderField(WebString::fromUTF8("Referer")).latin1()),
+      request.referrerPolicy());
+  params.transition = extra_data->transition_type();
+  return params;
+}
+
 }  // namespace
 
 static RenderFrameImpl* (*g_create_render_frame_impl)(RenderViewImpl*, int32) =
@@ -391,24 +506,37 @@ RenderFrameImpl* RenderFrameImpl::FromRoutingID(int32 routing_id) {
 }
 
 // static
-void RenderFrameImpl::CreateFrame(int routing_id, int parent_routing_id) {
+void RenderFrameImpl::CreateFrame(int routing_id,
+                                  int parent_routing_id,
+                                  int proxy_routing_id) {
   // TODO(nasko): For now, this message is only sent for subframes, as the
   // top level frame is created when the RenderView is created through the
   // ViewMsg_New IPC.
   CHECK_NE(MSG_ROUTING_NONE, parent_routing_id);
 
-  RenderFrameProxy* proxy = RenderFrameProxy::FromRoutingID(parent_routing_id);
-
-  // If the browser is sending a valid parent routing id, it should already be
-  // created and registered.
-  CHECK(proxy);
-  blink::WebRemoteFrame* parent_web_frame = proxy->web_frame();
-
-  // Create the RenderFrame and WebLocalFrame, linking the two.
-  RenderFrameImpl* render_frame =
-      RenderFrameImpl::Create(proxy->render_view(), routing_id);
-  blink::WebLocalFrame* web_frame =
-      parent_web_frame->createLocalChild("", render_frame);
+  blink::WebLocalFrame* web_frame;
+  RenderFrameImpl* render_frame;
+  if (proxy_routing_id == MSG_ROUTING_NONE) {
+    RenderFrameProxy* parent_proxy =
+        RenderFrameProxy::FromRoutingID(parent_routing_id);
+    // If the browser is sending a valid parent routing id, it should already
+    // be created and registered.
+    CHECK(parent_proxy);
+    blink::WebRemoteFrame* parent_web_frame = parent_proxy->web_frame();
+
+    // Create the RenderFrame and WebLocalFrame, linking the two.
+    render_frame =
+        RenderFrameImpl::Create(parent_proxy->render_view(), routing_id);
+    web_frame = parent_web_frame->createLocalChild("", render_frame);
+  } else {
+    RenderFrameProxy* proxy =
+        RenderFrameProxy::FromRoutingID(proxy_routing_id);
+    CHECK(proxy);
+    render_frame = RenderFrameImpl::Create(proxy->render_view(), routing_id);
+    web_frame = blink::WebLocalFrame::create(render_frame);
+    render_frame->proxy_routing_id_ = proxy_routing_id;
+    web_frame->initializeToReplaceRemoteFrame(proxy->web_frame());
+  }
   render_frame->SetWebFrame(web_frame);
   render_frame->Initialize();
 }
@@ -441,6 +569,10 @@ RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id)
       is_swapped_out_(false),
       render_frame_proxy_(NULL),
       is_detaching_(false),
+      proxy_routing_id_(MSG_ROUTING_NONE),
+#if defined(ENABLE_PLUGINS)
+      plugin_power_saver_helper_(NULL),
+#endif
       cookie_jar_(this),
       selection_text_offset_(0),
       selection_range_(gfx::Range::InvalidRange()),
@@ -476,10 +608,16 @@ RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id)
 
   render_view_->RegisterRenderFrame(this);
 
+  // Everything below subclasses RenderFrameObserver and is automatically
+  // deleted when the RenderFrame gets deleted.
 #if defined(OS_ANDROID)
   new GinJavaBridgeDispatcher(this);
 #endif
 
+#if defined(ENABLE_PLUGINS)
+  plugin_power_saver_helper_ = new PluginPowerSaverHelper(this);
+#endif
+
 #if defined(ENABLE_NOTIFICATIONS)
   notification_provider_ = new NotificationProvider(this);
 #endif
@@ -496,6 +634,9 @@ RenderFrameImpl::~RenderFrameImpl() {
     render_view_->UnregisterVideoHoleFrame(this);
 #endif
 
+  if (render_frame_proxy_)
+    delete render_frame_proxy_;
+
   render_view_->UnregisterRenderFrame(this);
   g_routing_id_frame_map.Get().erase(routing_id_);
   RenderThread::Get()->RemoveRoute(routing_id_);
@@ -533,6 +674,10 @@ RenderWidget* RenderFrameImpl::GetRenderWidget() {
 void RenderFrameImpl::PepperPluginCreated(RendererPpapiHost* host) {
   FOR_EACH_OBSERVER(RenderFrameObserver, observers_,
                     DidCreatePepperPlugin(host));
+  if (host->GetPluginName() == kFlashPluginName) {
+    RenderThread::Get()->RecordAction(
+        base::UserMetricsAction("FrameLoadWithFlash"));
+  }
 }
 
 void RenderFrameImpl::PepperDidChangeCursor(
@@ -627,7 +772,6 @@ void RenderFrameImpl::SimulateImeConfirmComposition(
   render_view_->OnImeConfirmComposition(text, replacement_range, false);
 }
 
-
 void RenderFrameImpl::OnImeSetComposition(
     const base::string16& text,
     const std::vector<blink::WebCompositionUnderline>& underlines,
@@ -707,7 +851,11 @@ void RenderFrameImpl::OnImeConfirmComposition(
   pepper_composition_text_.clear();
 }
 
-#endif  // ENABLE_PLUGINS
+PluginPowerSaverHelper* RenderFrameImpl::plugin_power_saver_helper() {
+  DCHECK(plugin_power_saver_helper_);
+  return plugin_power_saver_helper_;
+}
+#endif  // defined(ENABLE_PLUGINS)
 
 MediaStreamDispatcher* RenderFrameImpl::GetMediaStreamDispatcher() {
   if (!web_user_media_client_)
@@ -781,6 +929,8 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(InputMsg_SelectAll, OnSelectAll)
     IPC_MESSAGE_HANDLER(InputMsg_SelectRange, OnSelectRange)
     IPC_MESSAGE_HANDLER(InputMsg_Unselect, OnUnselect)
+    IPC_MESSAGE_HANDLER(InputMsg_MoveRangeSelectionExtent,
+                        OnMoveRangeSelectionExtent)
     IPC_MESSAGE_HANDLER(InputMsg_Replace, OnReplace)
     IPC_MESSAGE_HANDLER(InputMsg_ReplaceMisspelling, OnReplaceMisspelling)
     IPC_MESSAGE_HANDLER(InputMsg_ExtendSelectionAndDelete,
@@ -804,6 +954,8 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(FrameMsg_SetAccessibilityMode,
                         OnSetAccessibilityMode)
     IPC_MESSAGE_HANDLER(FrameMsg_DisownOpener, OnDisownOpener)
+    IPC_MESSAGE_HANDLER(FrameMsg_RequestNavigation, OnRequestNavigation)
+    IPC_MESSAGE_HANDLER(FrameMsg_CommitNavigation, OnCommitNavigation)
 #if defined(OS_ANDROID)
     IPC_MESSAGE_HANDLER(FrameMsg_SelectPopupMenuItems, OnSelectPopupMenuItems)
 #elif defined(OS_MACOSX)
@@ -817,65 +969,40 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
 
 void RenderFrameImpl::OnNavigate(const FrameMsg_Navigate_Params& params) {
   TRACE_EVENT2("navigation", "RenderFrameImpl::OnNavigate",
-               "id", routing_id_, "url", params.url.possibly_invalid_spec());
-  MaybeHandleDebugURL(params.url);
-  if (!render_view_->webview())
-    return;
-
-  FOR_EACH_OBSERVER(
-      RenderViewObserver, render_view_->observers_, Navigate(params.url));
-
-  bool is_reload = RenderViewImpl::IsReload(params);
+               "id", routing_id_,
+               "url", params.common_params.url.possibly_invalid_spec());
+  bool is_reload =
+      RenderViewImpl::IsReload(params.common_params.navigation_type);
   WebURLRequest::CachePolicy cache_policy =
       WebURLRequest::UseProtocolCachePolicy;
-
-  // If this is a stale back/forward (due to a recent navigation the browser
-  // didn't know about), ignore it.
-  if (render_view_->IsBackForwardToStaleEntry(params, is_reload))
+  if (!RenderFrameImpl::PrepareRenderViewForNavigation(
+      params.common_params.url, params.common_params.navigation_type,
+      params.commit_params.page_state, true, params.pending_history_list_offset,
+      params.page_id, &is_reload, &cache_policy)) {
     return;
-
-  // Swap this renderer back in if necessary.
-  if (render_view_->is_swapped_out_ &&
-      GetWebFrame() == render_view_->webview()->mainFrame()) {
-    // We marked the view as hidden when swapping the view out, so be sure to
-    // reset the visibility state before navigating to the new URL.
-    render_view_->webview()->setVisibilityState(
-        render_view_->visibilityState(), false);
-
-    // If this is an attempt to reload while we are swapped out, we should not
-    // reload swappedout://, but the previous page, which is stored in
-    // params.state.  Setting is_reload to false will treat this like a back
-    // navigation to accomplish that.
-    is_reload = false;
-    cache_policy = WebURLRequest::ReloadIgnoringCacheData;
-
-    // We refresh timezone when a view is swapped in since timezone
-    // can get out of sync when the system timezone is updated while
-    // the view is swapped out.
-    RenderThreadImpl::NotifyTimezoneChange();
-
-    render_view_->SetSwappedOut(false);
-    is_swapped_out_ = false;
   }
 
+  int pending_history_list_offset = params.pending_history_list_offset;
+  int current_history_list_offset = params.current_history_list_offset;
+  int current_history_list_length = params.current_history_list_length;
   if (params.should_clear_history_list) {
-    CHECK_EQ(params.pending_history_list_offset, -1);
-    CHECK_EQ(params.current_history_list_offset, -1);
-    CHECK_EQ(params.current_history_list_length, 0);
+    CHECK_EQ(pending_history_list_offset, -1);
+    CHECK_EQ(current_history_list_offset, -1);
+    CHECK_EQ(current_history_list_length, 0);
   }
-  render_view_->history_list_offset_ = params.current_history_list_offset;
-  render_view_->history_list_length_ = params.current_history_list_length;
+  render_view_->history_list_offset_ = current_history_list_offset;
+  render_view_->history_list_length_ = current_history_list_length;
   if (render_view_->history_list_length_ >= 0) {
     render_view_->history_page_ids_.resize(
         render_view_->history_list_length_, -1);
   }
-  if (params.pending_history_list_offset >= 0 &&
-      params.pending_history_list_offset < render_view_->history_list_length_) {
-    render_view_->history_page_ids_[params.pending_history_list_offset] =
+  if (pending_history_list_offset >= 0 &&
+      pending_history_list_offset < render_view_->history_list_length_) {
+    render_view_->history_page_ids_[pending_history_list_offset] =
         params.page_id;
   }
 
-  GetContentClient()->SetActiveURL(params.url);
+  GetContentClient()->SetActiveURL(params.common_params.url);
 
   WebFrame* frame = frame_;
   if (!params.frame_to_navigate.empty()) {
@@ -901,20 +1028,20 @@ void RenderFrameImpl::OnNavigate(const FrameMsg_Navigate_Params& params) {
   // back/forward navigation event.
   if (is_reload) {
     bool reload_original_url =
-        (params.navigation_type ==
-            FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
-    bool ignore_cache = (params.navigation_type ==
-                             FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE);
+        (params.common_params.navigation_type ==
+         FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
+    bool ignore_cache = (params.common_params.navigation_type ==
+                         FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE);
 
     if (reload_original_url)
-      frame->reloadWithOverrideURL(params.url, true);
+      frame->reloadWithOverrideURL(params.common_params.url, true);
     else
       frame->reload(ignore_cache);
-  } else if (params.page_state.IsValid()) {
+  } else if (params.commit_params.page_state.IsValid()) {
     // We must know the page ID of the page we are navigating back to.
     DCHECK_NE(params.page_id, -1);
     scoped_ptr<HistoryEntry> entry =
-        PageStateToHistoryEntry(params.page_state);
+        PageStateToHistoryEntry(params.commit_params.page_state);
     if (entry) {
       // Ensure we didn't save the swapped out URL in UpdateState, since the
       // browser should never be telling us to navigate to swappedout://.
@@ -924,7 +1051,8 @@ void RenderFrameImpl::OnNavigate(const FrameMsg_Navigate_Params& params) {
   } else if (!params.base_url_for_data_url.is_empty()) {
     // A loadData request with a specified base URL.
     std::string mime_type, charset, data;
-    if (net::DataURL::Parse(params.url, &mime_type, &charset, &data)) {
+    if (net::DataURL::Parse(
+            params.common_params.url, &mime_type, &charset, &data)) {
       frame->loadData(
           WebData(data.c_str(), data.length()),
           WebString::fromUTF8(mime_type),
@@ -933,75 +1061,28 @@ void RenderFrameImpl::OnNavigate(const FrameMsg_Navigate_Params& params) {
           params.history_url_for_data_url,
           false);
     } else {
-      CHECK(false) <<
-          "Invalid URL passed: " << params.url.possibly_invalid_spec();
+      CHECK(false) << "Invalid URL passed: "
+                   << params.common_params.url.possibly_invalid_spec();
     }
   } else {
     // Navigate to the given URL.
-    WebURLRequest request(params.url);
+    WebURLRequest request =
+        CreateURLRequestForNavigation(params.common_params,
+                                      params.request_params,
+                                      scoped_ptr<StreamOverrideParameters>(),
+                                      frame->isViewSourceModeEnabled());
 
     // A session history navigation should have been accompanied by state.
     CHECK_EQ(params.page_id, -1);
 
-    if (frame->isViewSourceModeEnabled())
-      request.setCachePolicy(WebURLRequest::ReturnCacheDataElseLoad);
-
-    if (params.referrer.url.is_valid()) {
-      WebString referrer = WebSecurityPolicy::generateReferrerHeader(
-          params.referrer.policy,
-          params.url,
-          WebString::fromUTF8(params.referrer.url.spec()));
-      if (!referrer.isEmpty())
-        request.setHTTPReferrer(referrer, params.referrer.policy);
-    }
-
-    if (!params.extra_headers.empty()) {
-      for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(),
-                                            params.extra_headers.end(), "\n");
-           i.GetNext(); ) {
-        request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
-                                   WebString::fromUTF8(i.values()));
-      }
-    }
-
-    if (params.is_post) {
-      request.setHTTPMethod(WebString::fromUTF8("POST"));
-
-      // Set post data.
-      WebHTTPBody http_body;
-      http_body.initialize();
-      const char* data = NULL;
-      if (params.browser_initiated_post_data.size()) {
-        data = reinterpret_cast<const char*>(
-            &params.browser_initiated_post_data.front());
-      }
-      http_body.appendData(
-          WebData(data, params.browser_initiated_post_data.size()));
-      request.setHTTPBody(http_body);
-    }
-
     // Record this before starting the load, we need a lower bound of this time
     // to sanitize the navigationStart override set below.
     base::TimeTicks renderer_navigation_start = base::TimeTicks::Now();
     frame->loadRequest(request);
 
-    // The browser provides the navigation_start time to bootstrap the
-    // Navigation Timing information for the browser-initiated navigations. In
-    // case of cross-process navigations, this carries over the time of
-    // finishing the onbeforeunload handler of the previous page.
-    DCHECK(!params.browser_navigation_start.is_null());
-    if (frame->provisionalDataSource()) {
-      // |browser_navigation_start| is likely before this process existed, so we
-      // can't use InterProcessTimeTicksConverter. We need at least to ensure
-      // that the browser-side navigation start we set is not later than the one
-      // on the renderer side.
-      base::TimeTicks navigation_start = std::min(
-          params.browser_navigation_start, renderer_navigation_start);
-      double navigation_start_seconds =
-          (navigation_start - base::TimeTicks()).InSecondsF();
-      frame->provisionalDataSource()->setNavigationStartTime(
-          navigation_start_seconds);
-    }
+    UpdateFrameNavigationTiming(
+        frame, params.commit_params.browser_navigation_start,
+        renderer_navigation_start);
   }
 
   // In case LoadRequest failed before DidCreateDataSource was called.
@@ -1013,6 +1094,10 @@ void RenderFrameImpl::BindServiceRegistry(
   service_registry_.BindRemoteServiceProvider(service_provider_handle.Pass());
 }
 
+ManifestManager* RenderFrameImpl::manifest_manager() {
+  return manifest_manager_;
+}
+
 void RenderFrameImpl::OnBeforeUnload() {
   TRACE_EVENT1("navigation", "RenderFrameImpl::OnBeforeUnload",
                "id", routing_id_);
@@ -1043,12 +1128,15 @@ void RenderFrameImpl::OnSwapOut(int proxy_routing_id) {
     // clearing the page.  We also allow this process to exit if there are no
     // other active RenderFrames in it.
 
-    // Send an UpdateState message before we get swapped out. Create the
-    // RenderFrameProxy as well so its routing id is registered for receiving
-    // IPC messages.
+    // Send an UpdateState message before we get swapped out.
     render_view_->SyncNavigationState();
-    proxy = RenderFrameProxy::CreateProxyToReplaceFrame(this,
-                                                        proxy_routing_id);
+
+    // If we need a proxy to replace this, create it now so its routing id is
+    // registered for receiving IPC messages.
+    if (proxy_routing_id != MSG_ROUTING_NONE) {
+      proxy = RenderFrameProxy::CreateProxyToReplaceFrame(this,
+                                                          proxy_routing_id);
+    }
 
     // Synchronously run the unload handler before sending the ACK.
     // TODO(creis): Call dispatchUnloadEvent unconditionally here to support
@@ -1070,9 +1158,9 @@ void RenderFrameImpl::OnSwapOut(int proxy_routing_id) {
     // frame?
     OnStop();
 
-    // Transfer settings such as initial drawing parameters to the remote frame
-    // that will replace this frame.
-    if (!is_main_frame)
+    // Transfer settings such as initial drawing parameters to the remote frame,
+    // if one is created, that will replace this frame.
+    if (!is_main_frame && proxy)
       proxy->web_frame()->initializeFromFrame(frame_);
 
     // Replace the page with a blank dummy URL. The unload handler will not be
@@ -1205,13 +1293,13 @@ void RenderFrameImpl::OnSelectAll() {
   frame_->executeCommand(WebString::fromUTF8("SelectAll"), GetFocusedElement());
 }
 
-void RenderFrameImpl::OnSelectRange(const gfx::Point& start,
-                                    const gfx::Point& end) {
+void RenderFrameImpl::OnSelectRange(const gfx::Point& base,
+                                    const gfx::Point& extent) {
   // This IPC is dispatched by RenderWidgetHost, so use its routing id.
-  Send(new ViewHostMsg_SelectRange_ACK(GetRenderWidget()->routing_id()));
+  Send(new InputHostMsg_SelectRange_ACK(GetRenderWidget()->routing_id()));
 
   base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
-  frame_->selectRange(start, end);
+  frame_->selectRange(base, extent);
 }
 
 void RenderFrameImpl::OnUnselect() {
@@ -1219,6 +1307,15 @@ void RenderFrameImpl::OnUnselect() {
   frame_->executeCommand(WebString::fromUTF8("Unselect"), GetFocusedElement());
 }
 
+void RenderFrameImpl::OnMoveRangeSelectionExtent(const gfx::Point& point) {
+  // This IPC is dispatched by RenderWidgetHost, so use its routing id.
+  Send(new InputHostMsg_MoveRangeSelectionExtent_ACK(
+      GetRenderWidget()->routing_id()));
+
+  base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
+  frame_->moveRangeSelectionExtent(point);
+}
+
 void RenderFrameImpl::OnReplace(const base::string16& text) {
   if (!frame_->hasSelection())
     frame_->selectWordAroundCaret();
@@ -1316,6 +1413,11 @@ void RenderFrameImpl::OnSetAccessibilityMode(AccessibilityMode new_mode) {
     return;
   accessibility_mode_ = new_mode;
   if (renderer_accessibility_) {
+    // Note: this isn't called automatically by the destructor because
+    // there'd be no point in calling it in frame teardown, only if there's
+    // an accessibility mode change but the frame is persisting.
+    renderer_accessibility_->DisableAccessibility();
+
     delete renderer_accessibility_;
     renderer_accessibility_ = NULL;
   }
@@ -1323,11 +1425,7 @@ void RenderFrameImpl::OnSetAccessibilityMode(AccessibilityMode new_mode) {
     return;
 
   if (accessibility_mode_ & AccessibilityModeFlagFullTree)
-    renderer_accessibility_ = new RendererAccessibilityComplete(this);
-#if !defined(OS_ANDROID)
-  else
-    renderer_accessibility_ = new RendererAccessibilityFocusOnly(this);
-#endif
+    renderer_accessibility_ = new RendererAccessibility(this);
 }
 
 void RenderFrameImpl::OnDisownOpener() {
@@ -1403,26 +1501,6 @@ void RenderFrameImpl::OnBeginExitTransition(const std::string& css_selector) {
   frame_->document().beginExitTransition(WebString::fromUTF8(css_selector));
 }
 
-bool RenderFrameImpl::ShouldUpdateSelectionTextFromContextMenuParams(
-    const base::string16& selection_text,
-    size_t selection_text_offset,
-    const gfx::Range& selection_range,
-    const ContextMenuParams& params) {
-  base::string16 trimmed_selection_text;
-  if (!selection_text.empty() && !selection_range.is_empty()) {
-    const int start = selection_range.GetMin() - selection_text_offset;
-    const size_t length = selection_range.length();
-    if (start >= 0 && start + length <= selection_text.length()) {
-      base::TrimWhitespace(selection_text.substr(start, length), base::TRIM_ALL,
-                           &trimmed_selection_text);
-    }
-  }
-  base::string16 trimmed_params_text;
-  base::TrimWhitespace(params.selection_text, base::TRIM_ALL,
-                       &trimmed_params_text);
-  return trimmed_params_text != trimmed_selection_text;
-}
-
 bool RenderFrameImpl::RunJavaScriptMessage(JavaScriptMessageType type,
                                            const base::string16& message,
                                            const base::string16& default_value,
@@ -1550,8 +1628,47 @@ void RenderFrameImpl::AttachGuest(int element_instance_id) {
   render_view_->GetBrowserPluginManager()->Attach(element_instance_id);
 }
 
+void RenderFrameImpl::SetSelectedText(const base::string16& selection_text,
+                                      size_t offset,
+                                      const gfx::Range& range) {
+  // Use the routing id of Render Widget Host.
+  Send(new ViewHostMsg_SelectionChanged(GetRenderWidget()->routing_id(),
+                                        selection_text,
+                                        offset,
+                                        range));
+}
+
+void RenderFrameImpl::EnsureMojoBuiltinsAreAvailable(
+    v8::Isolate* isolate,
+    v8::Handle<v8::Context> context) {
+  gin::ModuleRegistry* registry = gin::ModuleRegistry::From(context);
+  if (registry->available_modules().count(mojo::js::Core::kModuleName))
+    return;
+
+  v8::HandleScope handle_scope(isolate);
+  registry->AddBuiltinModule(
+      isolate, mojo::js::Core::kModuleName, mojo::js::Core::GetModule(isolate));
+  registry->AddBuiltinModule(isolate,
+                             mojo::js::Support::kModuleName,
+                             mojo::js::Support::GetModule(isolate));
+  registry->AddBuiltinModule(
+      isolate,
+      ServiceRegistryJsWrapper::kModuleName,
+      ServiceRegistryJsWrapper::Create(isolate, &service_registry_).ToV8());
+}
+
 // blink::WebFrameClient implementation ----------------------------------------
 
+blink::WebPluginPlaceholder* RenderFrameImpl::createPluginPlaceholder(
+    blink::WebLocalFrame* frame,
+    const blink::WebPluginParams& params) {
+  DCHECK_EQ(frame_, frame);
+  return GetContentClient()
+      ->renderer()
+      ->CreatePluginPlaceholder(this, frame, params)
+      .release();
+}
+
 blink::WebPlugin* RenderFrameImpl::createPlugin(
     blink::WebLocalFrame* frame,
     const blink::WebPluginParams& params) {
@@ -1564,8 +1681,8 @@ blink::WebPlugin* RenderFrameImpl::createPlugin(
 
   if (base::UTF16ToUTF8(params.mimeType) == kBrowserPluginMimeType) {
     scoped_ptr<BrowserPluginDelegate> browser_plugin_delegate(
-        GetContentClient()->renderer()->CreateBrowserPluginDelegate(
-            this, std::string()));
+        GetContentClient()->renderer()->CreateBrowserPluginDelegate(this,
+            kBrowserPluginMimeType, GURL(params.url)));
     return render_view_->GetBrowserPluginManager()->CreateBrowserPlugin(
         render_view_.get(), frame, browser_plugin_delegate.Pass());
   }
@@ -1580,10 +1697,10 @@ blink::WebPlugin* RenderFrameImpl::createPlugin(
   if (!found)
     return NULL;
 
-  if (info.type == content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN) {
+  if (info.type == WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN) {
     scoped_ptr<BrowserPluginDelegate> browser_plugin_delegate(
         GetContentClient()->renderer()->CreateBrowserPluginDelegate(
-            this, base::UTF16ToUTF8(params.mimeType)));
+            this, mime_type, GURL(params.url)));
     return render_view_->GetBrowserPluginManager()->CreateBrowserPlugin(
         render_view_.get(), frame, browser_plugin_delegate.Pass());
   }
@@ -1645,10 +1762,8 @@ blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
       GetTizenMediaPlayerManager(), params);
   return media_player;
 #endif
-  return new media::WebMediaPlayerImpl(frame,
-                                       client,
-                                       weak_factory_.GetWeakPtr(),
-                                       params);
+  return new media::WebMediaPlayerImpl(
+      frame, client, weak_factory_.GetWeakPtr(), nullptr, params);
 #endif  // defined(OS_ANDROID)
 }
 
@@ -1668,14 +1783,18 @@ RenderFrameImpl::createContentDecryptionModule(
     const blink::WebSecurityOrigin& security_origin,
     const blink::WebString& key_system) {
   DCHECK(!frame_ || frame_ == frame);
-  return WebContentDecryptionModuleImpl::Create(
+
 #if defined(ENABLE_PEPPER_CDMS)
-      frame,
+  RenderCdmFactory cdm_factory(
+      base::Bind(&PepperCdmWrapperImpl::Create, frame));
 #elif defined(ENABLE_BROWSER_CDMS)
-      GetCdmManager(),
+  RenderCdmFactory cdm_factory(GetCdmManager());
+#else
+  RenderCdmFactory cdm_factory;
 #endif
-      security_origin,
-      key_system);
+
+  return WebContentDecryptionModuleImpl::Create(&cdm_factory, security_origin,
+                                                key_system);
 }
 
 blink::WebApplicationCacheHost* RenderFrameImpl::createApplicationCacheHost(
@@ -2157,7 +2276,7 @@ void RenderFrameImpl::didFailProvisionalLoad(blink::WebLocalFrame* frame,
         navigation_state->pending_history_list_offset();
     render_view_->pending_navigation_params_->should_clear_history_list =
         navigation_state->history_list_was_cleared();
-    render_view_->pending_navigation_params_->transition =
+    render_view_->pending_navigation_params_->common_params.transition =
         navigation_state->transition_type();
     render_view_->pending_navigation_params_->request_time =
         document_state->request_time();
@@ -2181,6 +2300,14 @@ void RenderFrameImpl::didCommitProvisionalLoad(
       DocumentState::FromDataSource(frame->dataSource());
   NavigationState* navigation_state = document_state->navigation_state();
 
+  if (proxy_routing_id_ != MSG_ROUTING_NONE) {
+    RenderFrameProxy* proxy =
+        RenderFrameProxy::FromRoutingID(proxy_routing_id_);
+    CHECK(proxy);
+    proxy->web_frame()->swap(frame_);
+    proxy_routing_id_ = MSG_ROUTING_NONE;
+  }
+
   // When we perform a new navigation, we need to update the last committed
   // session history entry with state for the page we are leaving. Do this
   // before updating the HistoryController state.
@@ -2255,7 +2382,9 @@ void RenderFrameImpl::didCommitProvisionalLoad(
     }
   }
 
-  Send(new FrameHostMsg_DidAssignPageId(routing_id_, render_view_->page_id_));
+  bool sent = Send(
+      new FrameHostMsg_DidAssignPageId(routing_id_, render_view_->page_id_));
+  CHECK(sent);  // http://crbug.com/407376
 
   FOR_EACH_OBSERVER(RenderViewObserver, render_view_->observers_,
                     DidCommitProvisionalLoad(frame, is_new_navigation));
@@ -2334,7 +2463,6 @@ void RenderFrameImpl::didReceiveTitle(blink::WebLocalFrame* frame,
 
     base::string16 shortened_title = title16.substr(0, kMaxTitleChars);
     Send(new FrameHostMsg_UpdateTitle(routing_id_,
-                                      render_view_->page_id_,
                                       shortened_title, direction));
   }
 
@@ -2456,13 +2584,40 @@ void RenderFrameImpl::didUpdateCurrentHistoryItem(blink::WebLocalFrame* frame) {
   render_view_->didUpdateCurrentHistoryItem(frame);
 }
 
+// TODO(zhenw): This will be removed once the blink side implementation is done.
 void RenderFrameImpl::addNavigationTransitionData(
     const blink::WebString& allowed_destination_host_pattern,
     const blink::WebString& selector,
     const blink::WebString& markup) {
-  Send(new FrameHostMsg_AddNavigationTransitionData(
-      routing_id_, allowed_destination_host_pattern.utf8(), selector.utf8(),
-      markup.utf8()));
+  FrameHostMsg_AddNavigationTransitionData_Params params;
+  params.render_frame_id = routing_id_;
+  params.allowed_destination_host_pattern =
+      allowed_destination_host_pattern.utf8();
+  params.selector = selector.utf8();
+  params.markup = markup.utf8();
+
+  Send(new FrameHostMsg_AddNavigationTransitionData(params));
+}
+
+void RenderFrameImpl::addNavigationTransitionData(
+    const blink::WebString& allowed_destination_host_pattern,
+    const blink::WebString& selector,
+    const blink::WebString& markup,
+    const blink::WebVector<blink::WebString>& web_names,
+    const blink::WebVector<blink::WebRect>& web_rects) {
+  FrameHostMsg_AddNavigationTransitionData_Params params;
+  params.render_frame_id = routing_id_;
+  params.allowed_destination_host_pattern =
+      allowed_destination_host_pattern.utf8();
+  params.selector = selector.utf8();
+  params.markup = markup.utf8();
+  params.elements.resize(web_names.size());
+  for (size_t i = 0; i < web_names.size(); i++) {
+    params.elements[i].name = web_names[i].utf8();
+    params.elements[i].rect = gfx::Rect(web_rects[i]);
+  }
+
+  Send(new FrameHostMsg_AddNavigationTransitionData(params));
 }
 
 void RenderFrameImpl::didChangeThemeColor() {
@@ -2514,9 +2669,9 @@ blink::WebColorChooser* RenderFrameImpl::createColorChooser(
     const blink::WebVector<blink::WebColorSuggestion>& suggestions) {
   RendererWebColorChooserImpl* color_chooser =
       new RendererWebColorChooserImpl(this, client);
-  std::vector<content::ColorSuggestion> color_suggestions;
+  std::vector<ColorSuggestion> color_suggestions;
   for (size_t i = 0; i < suggestions.size(); i++) {
-    color_suggestions.push_back(content::ColorSuggestion(suggestions[i]));
+    color_suggestions.push_back(ColorSuggestion(suggestions[i]));
   }
   color_chooser->Open(static_cast<SkColor>(initial_color), color_suggestions);
   return color_chooser;
@@ -2587,23 +2742,6 @@ void RenderFrameImpl::showContextMenu(const blink::WebContextMenuData& data) {
     params.y = GetRenderWidget()->host_context_menu_location().y();
   }
 
-  // Plugins, e.g. PDF, don't currently update the render view when their
-  // selected text changes, but the context menu params do contain the updated
-  // selection. If that's the case, update the render view's state just prior
-  // to showing the context menu.
-  // TODO(asvitkine): http://crbug.com/152432
-  if (ShouldUpdateSelectionTextFromContextMenuParams(
-          selection_text_, selection_text_offset_, selection_range_, params)) {
-    selection_text_ = params.selection_text;
-    // TODO(asvitkine): Text offset and range is not available in this case.
-    selection_text_offset_ = 0;
-    selection_range_ = gfx::Range(0, selection_text_.length());
-    // This IPC is dispatched by RenderWidetHost, so use its routing ID.
-    Send(new ViewHostMsg_SelectionChanged(
-        GetRenderWidget()->routing_id(), selection_text_,
-        selection_text_offset_, selection_range_));
-  }
-
   // Serializing a GURL longer than kMaxURLChars will fail, so don't do
   // it.  We replace it with an empty GURL so the appropriate items are disabled
   // in the context menu.
@@ -2692,8 +2830,10 @@ void RenderFrameImpl::willSendRequest(
   // user agent on its own. Similarly, it may indicate that we should set an
   // X-Requested-With header. This must be done here to avoid breaking CORS
   // checks.
+  // PlzNavigate: there may also be a stream url associated with the request.
   WebString custom_user_agent;
   WebString requested_with;
+  scoped_ptr<StreamOverrideParameters> stream_override;
   if (request.extraData()) {
     RequestExtraData* old_extra_data =
         static_cast<RequestExtraData*>(request.extraData());
@@ -2713,6 +2853,7 @@ void RenderFrameImpl::willSendRequest(
       else
         request.setHTTPHeaderField("X-Requested-With", requested_with);
     }
+    stream_override = old_extra_data->TakeStreamOverrideOwnership();
   }
 
   // Add the default accept header for frame request if it has not been set
@@ -2790,6 +2931,7 @@ void RenderFrameImpl::willSendRequest(
   extra_data->set_transferred_request_request_id(
       navigation_state->transferred_request_request_id());
   extra_data->set_service_worker_provider_id(provider_id);
+  extra_data->set_stream_override(stream_override.Pass());
   request.setExtraData(extra_data);
 
   DocumentState* top_document_state =
@@ -2866,6 +3008,8 @@ void RenderFrameImpl::didReceiveResponse(
         extra_data->connection_info());
     document_state->set_was_fetched_via_proxy(
         extra_data->was_fetched_via_proxy());
+    document_state->set_proxy_server(
+        extra_data->proxy_server());
   }
   InternalDocumentStateData* internal_data =
       InternalDocumentStateData::FromDocumentState(document_state);
@@ -3047,13 +3191,6 @@ void RenderFrameImpl::requestStorageQuota(
       QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks));
 }
 
-void RenderFrameImpl::willOpenSocketStream(
-    blink::WebSocketStreamHandle* handle) {
-  WebSocketStreamHandleImpl* impl =
-      static_cast<WebSocketStreamHandleImpl*>(handle);
-  impl->SetUserData(handle, new SocketStreamHandleData(routing_id_));
-}
-
 void RenderFrameImpl::willOpenWebSocket(blink::WebSocketHandle* handle) {
   WebSocketBridge* impl = static_cast<WebSocketBridge*>(handle);
   impl->set_render_frame_id(routing_id_);
@@ -3065,6 +3202,12 @@ blink::WebGeolocationClient* RenderFrameImpl::geolocationClient() {
   return geolocation_dispatcher_;
 }
 
+void RenderFrameImpl::requestPushPermission(blink::WebCallback* callback) {
+  if (!push_permission_dispatcher_)
+    push_permission_dispatcher_ = new PushPermissionDispatcher(this);
+  push_permission_dispatcher_->RequestPermission(callback);
+}
+
 blink::WebPushClient* RenderFrameImpl::pushClient() {
   if (!push_messaging_dispatcher_)
     push_messaging_dispatcher_ = new PushMessagingDispatcher(this);
@@ -3141,11 +3284,22 @@ bool RenderFrameImpl::willCheckAndDispatchMessageEvent(
 blink::WebString RenderFrameImpl::userAgentOverride(blink::WebLocalFrame* frame,
                                                     const blink::WebURL& url) {
   DCHECK(!frame_ || frame_ == frame);
+  std::string user_agent_override_for_url =
+      GetContentClient()->renderer()->GetUserAgentOverrideForURL(GURL(url));
+  if (!user_agent_override_for_url.empty())
+    return WebString::fromUTF8(user_agent_override_for_url);
+
   if (!render_view_->webview() || !render_view_->webview()->mainFrame() ||
       render_view_->renderer_preferences_.user_agent_override.empty()) {
     return blink::WebString();
   }
 
+  // TODO(nasko): When the top-level frame is remote, there is no WebDataSource
+  // associated with it, so the checks below are not valid. Temporarily
+  // return early and fix properly as part of https://crbug.com/426555.
+  if (render_view_->webview()->mainFrame()->isWebRemoteFrame())
+    return blink::WebString();
+
   // If we're in the middle of committing a load, the data source we need
   // will still be provisional.
   WebFrame* main_frame = render_view_->webview()->mainFrame();
@@ -3194,10 +3348,6 @@ void RenderFrameImpl::didLoseWebGLContext(blink::WebLocalFrame* frame,
       arb_robustness_status_code));
 }
 
-void RenderFrameImpl::forwardInputEvent(const blink::WebInputEvent* event) {
-  Send(new FrameHostMsg_ForwardInputEvent(routing_id_, event));
-}
-
 blink::WebScreenOrientationClient*
     RenderFrameImpl::webScreenOrientationClient() {
   if (!screen_orientation_dispatcher_)
@@ -3205,27 +3355,43 @@ blink::WebScreenOrientationClient*
   return screen_orientation_dispatcher_;
 }
 
-bool RenderFrameImpl::isControlledByServiceWorker() {
-  // If we're in the middle of committing a load, the data source we need
-  // will still be provisional.
-  WebFrame* main_frame = render_view_->webview()->mainFrame();
-  WebDataSource* data_source = NULL;
-  if (main_frame->provisionalDataSource())
-    data_source = main_frame->provisionalDataSource();
-  else
-    data_source = main_frame->dataSource();
+bool RenderFrameImpl::isControlledByServiceWorker(WebDataSource& data_source) {
   ServiceWorkerNetworkProvider* provider =
       ServiceWorkerNetworkProvider::FromDocumentState(
-          DocumentState::FromDataSource(data_source));
+          DocumentState::FromDataSource(&data_source));
   return provider->context()->controller_handle_id() !=
       kInvalidServiceWorkerHandleId;
 }
 
+int64_t RenderFrameImpl::serviceWorkerID(WebDataSource& data_source) {
+  ServiceWorkerNetworkProvider* provider =
+      ServiceWorkerNetworkProvider::FromDocumentState(
+          DocumentState::FromDataSource(&data_source));
+
+  if (provider->context()->controller())
+    return provider->context()->controller()->version_id();
+  return kInvalidServiceWorkerVersionId;
+}
+
 void RenderFrameImpl::postAccessibilityEvent(const blink::WebAXObject& obj,
                                              blink::WebAXEvent event) {
   HandleWebAccessibilityEvent(obj, event);
 }
 
+void RenderFrameImpl::handleAccessibilityFindInPageResult(
+    int identifier,
+    int match_index,
+    const blink::WebAXObject& start_object,
+    int start_offset,
+    const blink::WebAXObject& end_object,
+    int end_offset) {
+  if (renderer_accessibility_) {
+    renderer_accessibility_->HandleAccessibilityFindInPageResult(
+        identifier, match_index, start_object, start_offset,
+        end_object, end_offset);
+  }
+}
+
 void RenderFrameImpl::didChangeManifest(blink::WebLocalFrame* frame)
 {
   DCHECK(!frame_ || frame_ == frame);
@@ -3357,6 +3523,8 @@ void RenderFrameImpl::SendDidCommitProvisionalLoad(blink::WebFrame* frame) {
       // Reset the zoom levels for plugins.
       render_view_->webview()->setZoomLevel(0);
     } else {
+      // If the zoom level is not found, then do nothing. In-page navigation
+      // relies on not changing the zoom level in this case.
       if (host_zoom != render_view_->host_zoom_levels_.end())
         render_view_->webview()->setZoomLevel(host_zoom->second);
     }
@@ -3492,6 +3660,83 @@ void RenderFrameImpl::FocusedNodeChanged(const WebNode& node) {
     renderer_accessibility_->FocusedNodeChanged(node);
 }
 
+// PlzNavigate
+void RenderFrameImpl::OnRequestNavigation(
+    const CommonNavigationParams& common_params,
+    const RequestNavigationParams& request_params) {
+  CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kEnableBrowserSideNavigation));
+
+  // TODO(clamy): Execute the beforeunload event.
+
+  WebURLRequest request =
+      CreateURLRequestForNavigation(common_params,
+                                    request_params,
+                                    scoped_ptr<StreamOverrideParameters>(),
+                                    frame_->isViewSourceModeEnabled());
+
+  // Note: At this stage, the goal is to apply all the modifications the
+  // renderer wants to make to the request, and then send it to the browser, so
+  // that the actual network request can be started. Ideally, all such
+  // modifications should take place in willSendRequest, and in the
+  // implementation of willSendRequest for the various InspectorAgents
+  // (devtools).
+  //
+  // TODO(clamy): Apply devtools override.
+  // TODO(clamy): Make sure that navigation requests are not modified somewhere
+  // else in blink.
+  willSendRequest(frame_, 0, request, blink::WebURLResponse());
+
+  // TODO(clamy): Same-document navigations should not be sent back to the
+  // browser.
+  Send(new FrameHostMsg_BeginNavigation(routing_id_,
+                                        MakeBeginNavigationParams(request),
+                                        MakeCommonNavigationParams(request)));
+}
+
+// PlzNavigate
+void RenderFrameImpl::OnCommitNavigation(
+    const ResourceResponseHead& response,
+    const GURL& stream_url,
+    const CommonNavigationParams& common_params,
+    const CommitNavigationParams& commit_params) {
+  CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kEnableBrowserSideNavigation));
+  bool is_reload = false;
+  WebURLRequest::CachePolicy cache_policy =
+      WebURLRequest::UseProtocolCachePolicy;
+  if (!RenderFrameImpl::PrepareRenderViewForNavigation(
+      common_params.url, common_params.navigation_type,
+      commit_params.page_state, false, -1, -1, &is_reload, &cache_policy)) {
+    return;
+  }
+
+  GetContentClient()->SetActiveURL(common_params.url);
+
+  // Create a WebURLRequest that blink can use to get access to the body of the
+  // response through a stream in the browser. Blink will then commit the
+  // navigation.
+  // TODO(clamy): Have the navigation commit directly, without going through
+  // loading a WebURLRequest.
+  scoped_ptr<StreamOverrideParameters> stream_override(
+      new StreamOverrideParameters());
+  stream_override->stream_url = stream_url;
+  stream_override->response = response;
+  WebURLRequest request =
+      CreateURLRequestForNavigation(common_params,
+                                    RequestNavigationParams(),
+                                    stream_override.Pass(),
+                                    frame_->isViewSourceModeEnabled());
+
+  // Record this before starting the load. A lower bound of this time is needed
+  // to sanitize the navigationStart override set below.
+  base::TimeTicks renderer_navigation_start = base::TimeTicks::Now();
+  frame_->loadRequest(request);
+  UpdateFrameNavigationTiming(
+      frame_, commit_params.browser_navigation_start,
+      renderer_navigation_start);
+}
+
 WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
     RenderFrame* render_frame,
     const NavigationPolicyInfo& info) {
@@ -3558,13 +3803,12 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
           navigation_state()->is_content_initiated();
 
   // Experimental:
-  // If --enable-strict-site-isolation or --site-per-process is enabled, send
-  // all top-level navigations to the browser to let it swap processes when
-  // crossing site boundaries.  This is currently expected to break some script
-  // calls and navigations, such as form submissions.
+  // If --enable-strict-site-isolation is enabled, send all top-level
+  // navigations to the browser to let it swap processes when crossing site
+  // boundaries.  This is currently expected to break some script calls and
+  // navigations, such as form submissions.
   bool force_swap_due_to_flag =
-      command_line.HasSwitch(switches::kEnableStrictSiteIsolation) ||
-      command_line.HasSwitch(switches::kSitePerProcess);
+      command_line.HasSwitch(switches::kEnableStrictSiteIsolation);
   if (force_swap_due_to_flag &&
       !info.frame->parent() && (is_content_initiated || info.isRedirect)) {
     WebString origin_str = info.frame->document().securityOrigin().toString();
@@ -3576,7 +3820,11 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
             frame_url,
             url,
             net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
-    if (!same_domain_or_host || frame_url.scheme() != url.scheme()) {
+    // Only keep same-site (domain + scheme) and data URLs in the same process.
+    bool is_same_site =
+        (same_domain_or_host && frame_url.scheme() == url.scheme()) ||
+        url.SchemeIs(url::kDataScheme);
+    if (!is_same_site) {
       OpenURL(info.frame, url, referrer, info.defaultPolicy);
       return blink::WebNavigationPolicyIgnore;
     }
@@ -3814,9 +4062,7 @@ void RenderFrameImpl::SyncSelectionIfRequired() {
     selection_text_ = text;
     selection_text_offset_ = offset;
     selection_range_ = range;
-    // This IPC is dispatched by RenderWidetHost, so use its routing ID.
-    Send(new ViewHostMsg_SelectionChanged(
-        GetRenderWidget()->routing_id(), text, offset, range));
+    SetSelectedText(text, offset, range);
   }
   GetRenderWidget()->UpdateSelectionBounds();
 }
@@ -3867,6 +4113,55 @@ RenderFrameImpl::CreateRendererFactory() {
 #endif
 }
 
+bool RenderFrameImpl::PrepareRenderViewForNavigation(
+    const GURL& url,
+    FrameMsg_Navigate_Type::Value navigate_type,
+    const PageState& state,
+    bool check_history,
+    int pending_history_list_offset,
+    int32 page_id,
+    bool* is_reload,
+    WebURLRequest::CachePolicy* cache_policy) {
+  MaybeHandleDebugURL(url);
+  if (!render_view_->webview())
+    return false;
+
+  FOR_EACH_OBSERVER(
+      RenderViewObserver, render_view_->observers_, Navigate(url));
+
+  // If this is a stale back/forward (due to a recent navigation the browser
+  // didn't know about), ignore it.
+  if (check_history && render_view_->IsBackForwardToStaleEntry(
+      state, pending_history_list_offset, page_id, *is_reload))
+    return false;
+
+  if (!render_view_->is_swapped_out_ ||
+      GetWebFrame() != render_view_->webview()->mainFrame())
+    return true;
+
+  // This is a swapped out main frame, so swap the renderer back in.
+  // We marked the view as hidden when swapping the view out, so be sure to
+  // reset the visibility state before navigating to the new URL.
+  render_view_->webview()->setVisibilityState(
+      render_view_->visibilityState(), false);
+
+  // If this is an attempt to reload while we are swapped out, we should not
+  // reload swappedout://, but the previous page, which is stored in
+  // params.state.  Setting is_reload to false will treat this like a back
+  // navigation to accomplish that.
+  *is_reload = false;
+  *cache_policy = WebURLRequest::ReloadIgnoringCacheData;
+
+  // We refresh timezone when a view is swapped in since timezone
+  // can get out of sync when the system timezone is updated while
+  // the view is swapped out.
+  RenderThreadImpl::NotifyTimezoneChange();
+
+  render_view_->SetSwappedOut(false);
+  is_swapped_out_ = false;
+  return true;
+}
+
 GURL RenderFrameImpl::GetLoadingUrl() const {
   WebDataSource* ds = frame_->dataSource();
   if (ds->hasUnreachableURL())