Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / web_contents / web_contents_impl.cc
index 0f3ea7a..32cb7ff 100644 (file)
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "content/browser/accessibility/accessibility_mode_helper.h"
+#include "content/browser/accessibility/browser_accessibility_state_impl.h"
 #include "content/browser/browser_plugin/browser_plugin_embedder.h"
 #include "content/browser/browser_plugin/browser_plugin_guest.h"
-#include "content/browser/browser_plugin/browser_plugin_guest_manager.h"
 #include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/devtools/render_view_devtools_agent_host.h"
 #include "content/browser/dom_storage/dom_storage_context_wrapper.h"
 #include "content/browser/frame_host/navigator_impl.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/frame_host/render_widget_host_view_child_frame.h"
+#include "content/browser/geolocation/geolocation_dispatcher_host.h"
 #include "content/browser/host_zoom_map_impl.h"
 #include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/manifest/manifest_manager_host.h"
+#include "content/browser/media/audio_stream_monitor.h"
+#include "content/browser/media/capture/web_contents_audio_muter.h"
+#include "content/browser/media/midi_dispatcher_host.h"
 #include "content/browser/message_port_message_filter.h"
 #include "content/browser/message_port_service.h"
 #include "content/browser/power_save_blocker_impl.h"
@@ -44,6 +50,7 @@
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
+#include "content/browser/screen_orientation/screen_orientation_dispatcher_host_impl.h"
 #include "content/browser/site_instance_impl.h"
 #include "content/browser/web_contents/web_contents_view_guest.h"
 #include "content/browser/webui/generic_handler.h"
@@ -58,6 +65,7 @@
 #include "content/common/view_messages.h"
 #include "content/public/browser/ax_event_notification_details.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_plugin_guest_manager.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/download_manager.h"
@@ -69,7 +77,9 @@
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/browser/render_widget_host_iterator.h"
 #include "content/public/browser/resource_request_details.h"
+#include "content/public/browser/screen_orientation_dispatcher_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents_delegate.h"
@@ -81,6 +91,7 @@
 #include "content/public/common/result_codes.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
+#include "content/public/common/web_preferences.h"
 #include "net/base/mime_util.h"
 #include "net/base/net_util.h"
 #include "net/http/http_cache.h"
 #include "ui/gfx/display.h"
 #include "ui/gfx/screen.h"
 #include "ui/gl/gl_switches.h"
-#include "webkit/common/webpreferences.h"
 
 #if defined(OS_ANDROID)
+#include "content/browser/android/content_view_core_impl.h"
 #include "content/browser/android/date_time_chooser_android.h"
 #include "content/browser/media/android/browser_media_player_manager.h"
-#include "content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h"
 #include "content/browser/web_contents/web_contents_android.h"
-#include "content/common/java_bridge_messages.h"
 #include "content/public/browser/android/content_view_core.h"
 #endif
 
 #if defined(OS_MACOSX)
 #include "base/mac/foundation_util.h"
-#include "ui/gl/io_surface_support_mac.h"
 #endif
 
 // Cross-Site Navigations
 namespace content {
 namespace {
 
+const int kMinimumDelayBetweenLoadingUpdatesMS = 100;
+
+// This matches what Blink's ProgressTracker has traditionally used for a
+// minimum progress value.
+const double kMinimumLoadingProgress = 0.1;
+
 const char kDotGoogleDotCom[] = ".google.com";
 
 #if defined(OS_ANDROID)
@@ -170,7 +184,7 @@ const char kWebContentsAndroidKey[] = "web_contents_android";
 base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> >
 g_created_callbacks = LAZY_INSTANCE_INITIALIZER;
 
-static int StartDownload(content::RenderFrameHost* rfh,
+static int StartDownload(RenderFrameHost* rfh,
                          const GURL& url,
                          bool is_favicon,
                          uint32_t max_bitmap_size) {
@@ -222,12 +236,18 @@ void SendToAllFramesInternal(IPC::Message* message, RenderFrameHost* rfh) {
   rfh->Send(message_copy);
 }
 
-void RunRenderFrameDeleted(
-    ObserverList<WebContentsObserver>* observer_list,
-    RenderFrameHost* render_frame_host) {
-  FOR_EACH_OBSERVER(WebContentsObserver,
-                    *observer_list,
-                    RenderFrameDeleted(render_frame_host));
+void AddRenderWidgetHostViewToSet(std::set<RenderWidgetHostView*>* set,
+                                  RenderFrameHost* rfh) {
+  RenderWidgetHostView* rwhv = static_cast<RenderFrameHostImpl*>(rfh)
+                                   ->frame_tree_node()
+                                   ->render_manager()
+                                   ->GetRenderWidgetHostView();
+  set->insert(rwhv);
+}
+
+void SetAccessibilityModeOnFrame(AccessibilityMode mode,
+                                 RenderFrameHost* frame_host) {
+  static_cast<RenderFrameHostImpl*>(frame_host)->SetAccessibilityMode(mode);
 }
 
 }  // namespace
@@ -329,10 +349,13 @@ WebContentsImpl::WebContentsImpl(
       frame_tree_(new NavigatorImpl(&controller_, this),
                   this, this, this, this),
       is_loading_(false),
+      is_load_to_different_document_(false),
       crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING),
       crashed_error_code_(0),
       waiting_for_response_(false),
       load_state_(net::LOAD_STATE_IDLE, base::string16()),
+      loading_total_progress_(0.0),
+      loading_frames_in_progress_(0),
       upload_size_(0),
       upload_position_(0),
       displayed_insecure_content_(false),
@@ -347,13 +370,18 @@ WebContentsImpl::WebContentsImpl(
       closed_by_user_gesture_(false),
       minimum_zoom_percent_(static_cast<int>(kMinimumZoomFactor * 100)),
       maximum_zoom_percent_(static_cast<int>(kMaximumZoomFactor * 100)),
-      temporary_zoom_settings_(false),
       totalPinchGestureAmount_(0),
       currentPinchZoomStepDelta_(0),
       render_view_message_source_(NULL),
       fullscreen_widget_routing_id_(MSG_ROUTING_NONE),
+      fullscreen_widget_had_focus_at_shutdown_(false),
       is_subframe_(false),
-      last_dialog_suppressed_(false) {
+      force_disable_overscroll_content_(false),
+      last_dialog_suppressed_(false),
+      accessibility_mode_(
+          BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()),
+      audio_stream_monitor_(this),
+      loading_weak_factory_(this) {
   for (size_t i = 0; i < g_created_callbacks.Get().size(); i++)
     g_created_callbacks.Get().at(i).Run(this);
   frame_tree_.SetFrameRemoveListener(
@@ -392,23 +420,30 @@ WebContentsImpl::~WebContentsImpl() {
       Source<WebContents>(this),
       NotificationService::NoDetails());
 
-  base::Callback<void(RenderFrameHost*)> run_render_frame_deleted_callback =
-      base::Bind(&RunRenderFrameDeleted, base::Unretained(&observers_));
-  frame_tree_.ForEach(base::Bind(&ForEachPendingFrameInternal,
-                                 run_render_frame_deleted_callback));
+  // Destroy all frame tree nodes except for the root; this notifies observers.
+  frame_tree_.ResetForMainFrameSwap();
+  GetRenderManager()->ResetProxyHosts();
 
-  RenderViewHost* pending_rvh = GetRenderManager()->pending_render_view_host();
-  if (pending_rvh) {
+  // Manually call the observer methods for the root frame tree node.
+  RenderFrameHostManager* root = GetRenderManager();
+  if (root->pending_frame_host()) {
     FOR_EACH_OBSERVER(WebContentsObserver,
                       observers_,
-                      RenderViewDeleted(pending_rvh));
+                      RenderFrameDeleted(root->pending_frame_host()));
   }
+  FOR_EACH_OBSERVER(WebContentsObserver,
+                    observers_,
+                    RenderFrameDeleted(root->current_frame_host()));
 
-  ForEachFrame(run_render_frame_deleted_callback);
+  if (root->pending_render_view_host()) {
+    FOR_EACH_OBSERVER(WebContentsObserver,
+                      observers_,
+                      RenderViewDeleted(root->pending_render_view_host()));
+  }
 
   FOR_EACH_OBSERVER(WebContentsObserver,
                     observers_,
-                    RenderViewDeleted(GetRenderManager()->current_host()));
+                    RenderViewDeleted(root->current_host()));
 
   FOR_EACH_OBSERVER(WebContentsObserver,
                     observers_,
@@ -429,33 +464,42 @@ WebContentsImpl* WebContentsImpl::CreateWithOpener(
     WebContentsImpl* opener) {
   TRACE_EVENT0("browser", "WebContentsImpl::CreateWithOpener");
   WebContentsImpl* new_contents = new WebContentsImpl(
-      params.browser_context, opener);
+      params.browser_context, params.opener_suppressed ? NULL : opener);
 
+  if (params.guest_delegate) {
+    // This makes |new_contents| act as a guest.
+    // For more info, see comment above class BrowserPluginGuest.
+    BrowserPluginGuest::Create(new_contents, params.guest_delegate);
+    // We are instantiating a WebContents for browser plugin. Set its subframe
+    // bit to true.
+    new_contents->is_subframe_ = true;
+  }
   new_contents->Init(params);
   return new_contents;
 }
 
 // static
-BrowserPluginGuest* WebContentsImpl::CreateGuest(
-    BrowserContext* browser_context,
-    SiteInstance* site_instance,
-    int guest_instance_id,
-    scoped_ptr<base::DictionaryValue> extra_params) {
-  WebContentsImpl* new_contents = new WebContentsImpl(browser_context, NULL);
-
-  // This makes |new_contents| act as a guest.
-  // For more info, see comment above class BrowserPluginGuest.
-  BrowserPluginGuest::Create(
-      guest_instance_id, site_instance, new_contents, extra_params.Pass());
-
-  WebContents::CreateParams create_params(browser_context, site_instance);
-  new_contents->Init(create_params);
-
-  // We are instantiating a WebContents for browser plugin. Set its subframe bit
-  // to true.
-  new_contents->is_subframe_ = true;
-
-  return new_contents->browser_plugin_guest_.get();
+std::vector<WebContentsImpl*> WebContentsImpl::GetAllWebContents() {
+  std::vector<WebContentsImpl*> result;
+  scoped_ptr<RenderWidgetHostIterator> widgets(
+      RenderWidgetHostImpl::GetRenderWidgetHosts());
+  std::set<WebContentsImpl*> web_contents_set;
+  while (RenderWidgetHost* rwh = widgets->GetNextHost()) {
+    if (!rwh->IsRenderView())
+      continue;
+    RenderViewHost* rvh = RenderViewHost::From(rwh);
+    if (!rvh)
+      continue;
+    WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
+    if (!web_contents)
+      continue;
+    WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents);
+    if (web_contents_set.find(wci) == web_contents_set.end()) {
+      web_contents_set.insert(wci);
+      result.push_back(wci);
+    }
+  }
+  return result;
 }
 
 RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() {
@@ -478,35 +522,39 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
 
   ObserverListBase<WebContentsObserver>::Iterator it(observers_);
   WebContentsObserver* observer;
-  while ((observer = it.GetNext()) != NULL)
-    if (observer->OnMessageReceived(message))
-      return true;
+  if (render_frame_host) {
+    while ((observer = it.GetNext()) != NULL)
+      if (observer->OnMessageReceived(message, render_frame_host))
+        return true;
+  } else {
+    while ((observer = it.GetNext()) != NULL)
+      if (observer->OnMessageReceived(message))
+        return true;
+  }
 
   // Message handlers should be aware of which
   // RenderViewHost/RenderFrameHost sent the message, which is temporarily
   // stored in render_(view|frame)_message_source_.
-  if (render_frame_host) {
-    if (RenderViewDevToolsAgentHost::DispatchIPCMessage(
-        render_frame_host->GetRenderViewHost(), message))
-        return true;
+  if (render_frame_host)
     render_frame_message_source_ = render_frame_host;
-  } else {
-    if (RenderViewDevToolsAgentHost::DispatchIPCMessage(
-        render_view_host, message))
-        return true;
+  else
     render_view_message_source_ = render_view_host;
-  }
 
   bool handled = true;
-  bool message_is_ok = true;
-  IPC_BEGIN_MESSAGE_MAP_EX(WebContentsImpl, message, message_is_ok)
+  IPC_BEGIN_MESSAGE_MAP(WebContentsImpl, message)
     IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung)
     IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed)
     IPC_MESSAGE_HANDLER(FrameHostMsg_DomOperationResponse,
                         OnDomOperationResponse)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeThemeColor,
+                        OnThemeColorChanged)
     IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishDocumentLoad,
                         OnDocumentLoadedInFrame)
     IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishLoad, OnDidFinishLoad)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeLoadProgress,
+                        OnDidChangeLoadProgress)
     IPC_MESSAGE_HANDLER(FrameHostMsg_OpenColorChooser, OnOpenColorChooser)
     IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser)
     IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser,
@@ -515,6 +563,8 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
                         OnMediaPlayingNotification)
     IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification,
                         OnMediaPausedNotification)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_DidFirstVisuallyNonEmptyPaint,
+                        OnFirstVisuallyNonEmptyPaint)
     IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache,
                         OnDidLoadResourceFromMemoryCache)
     IPC_MESSAGE_HANDLER(ViewHostMsg_DidDisplayInsecureContent,
@@ -526,19 +576,19 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
     IPC_MESSAGE_HANDLER(ViewHostMsg_EnumerateDirectory, OnEnumerateDirectory)
     IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterProtocolHandler,
                         OnRegisterProtocolHandler)
+    IPC_MESSAGE_HANDLER(ViewHostMsg_UnregisterProtocolHandler,
+                        OnUnregisterProtocolHandler)
     IPC_MESSAGE_HANDLER(ViewHostMsg_Find_Reply, OnFindReply)
     IPC_MESSAGE_HANDLER(ViewHostMsg_AppCacheAccessed, OnAppCacheAccessed)
     IPC_MESSAGE_HANDLER(ViewHostMsg_WebUISend, OnWebUISend)
+#if defined(ENABLE_PLUGINS)
     IPC_MESSAGE_HANDLER(ViewHostMsg_RequestPpapiBrokerPermission,
                         OnRequestPpapiBrokerPermission)
-    IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginHostMsg_AllocateInstanceID,
-                                OnBrowserPluginMessage(message))
     IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginHostMsg_Attach,
                                 OnBrowserPluginMessage(message))
+#endif
     IPC_MESSAGE_HANDLER(ImageHostMsg_DidDownloadImage, OnDidDownloadImage)
     IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFaviconURL, OnUpdateFaviconURL)
-    IPC_MESSAGE_HANDLER(ViewHostMsg_DidFirstVisuallyNonEmptyPaint,
-                        OnFirstVisuallyNonEmptyPaint)
     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowValidationMessage,
                         OnShowValidationMessage)
     IPC_MESSAGE_HANDLER(ViewHostMsg_HideValidationMessage,
@@ -550,19 +600,12 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
                         OnFindMatchRectsReply)
     IPC_MESSAGE_HANDLER(ViewHostMsg_OpenDateTimeDialog,
                         OnOpenDateTimeDialog)
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(JavaBridgeHostMsg_GetChannelHandle,
-                                    OnJavaBridgeGetChannelHandle)
 #endif
     IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP_EX()
+  IPC_END_MESSAGE_MAP()
   render_view_message_source_ = NULL;
   render_frame_message_source_ = NULL;
 
-  if (!message_is_ok) {
-    RecordAction(base::UserMetricsAction("BadMessageTerminate_RVD"));
-    GetRenderProcessHost()->ReceivedBadMessage();
-  }
-
   return handled;
 }
 
@@ -603,6 +646,10 @@ const GURL& WebContentsImpl::GetLastCommittedURL() const {
   return entry ? entry->GetVirtualURL() : GURL::EmptyGURL();
 }
 
+ScreenOrientationDispatcherHost* WebContentsImpl::GetScreenOrientationDispatcherHost() {
+  return screen_orientation_dispatcher_host_.get();
+}
+
 WebContentsDelegate* WebContentsImpl::GetDelegate() {
   return delegate_;
 }
@@ -618,7 +665,7 @@ void WebContentsImpl::SetDelegate(WebContentsDelegate* delegate) {
     delegate_->Attach(this);
     // Ensure the visible RVH reflects the new delegate's preferences.
     if (view_)
-      view_->SetOverscrollControllerEnabled(delegate->CanOverscrollContent());
+      view_->SetOverscrollControllerEnabled(CanOverscrollContent());
   }
 }
 
@@ -651,20 +698,6 @@ RenderViewHost* WebContentsImpl::GetRenderViewHost() const {
   return GetRenderManager()->current_host();
 }
 
-WebContents* WebContentsImpl::GetEmbedderWebContents() const {
-  BrowserPluginGuest* guest = GetBrowserPluginGuest();
-  if (guest)
-    return guest->embedder_web_contents();
-  return NULL;
-}
-
-int WebContentsImpl::GetEmbeddedInstanceID() const {
-  BrowserPluginGuest* guest = GetBrowserPluginGuest();
-  if (guest)
-    return guest->instance_id();
-  return 0;
-}
-
 int WebContentsImpl::GetRoutingID() const {
   if (!GetRenderViewHost())
     return MSG_ROUTING_NONE;
@@ -692,6 +725,27 @@ WebContentsView* WebContentsImpl::GetView() const {
   return view_.get();
 }
 
+void WebContentsImpl::SetAccessibilityMode(AccessibilityMode mode) {
+  if (mode == accessibility_mode_)
+    return;
+
+  accessibility_mode_ = mode;
+  frame_tree_.ForEach(
+      base::Bind(&ForEachFrameInternal,
+                 base::Bind(&SetAccessibilityModeOnFrame, mode)));
+  frame_tree_.ForEach(
+      base::Bind(&ForEachPendingFrameInternal,
+                 base::Bind(&SetAccessibilityModeOnFrame, mode)));
+}
+
+void WebContentsImpl::AddAccessibilityMode(AccessibilityMode mode) {
+  SetAccessibilityMode(AddAccessibilityModeTo(accessibility_mode_, mode));
+}
+
+void WebContentsImpl::RemoveAccessibilityMode(AccessibilityMode mode) {
+  SetAccessibilityMode(RemoveAccessibilityModeFrom(accessibility_mode_, mode));
+}
+
 WebUI* WebContentsImpl::CreateWebUI(const GURL& url) {
   WebUIImpl* web_ui = new WebUIImpl(this);
   WebUIController* controller = WebUIControllerFactoryRegistry::GetInstance()->
@@ -740,12 +794,25 @@ const std::string& WebContentsImpl::GetUserAgentOverride() const {
   return renderer_preferences_.user_agent_override;
 }
 
+void WebContentsImpl::EnableTreeOnlyAccessibilityMode() {
+  AddAccessibilityMode(AccessibilityModeTreeOnly);
+}
+
+bool WebContentsImpl::IsTreeOnlyAccessibilityModeForTesting() const {
+  return accessibility_mode_ == AccessibilityModeTreeOnly;
+}
+
+bool WebContentsImpl::IsFullAccessibilityModeForTesting() const {
+  return accessibility_mode_ == AccessibilityModeComplete;
+}
+
 #if defined(OS_WIN)
 void WebContentsImpl::SetParentNativeViewAccessible(
 gfx::NativeViewAccessible accessible_parent) {
   accessible_parent_ = accessible_parent;
-  if (GetRenderViewHost())
-    GetRenderViewHostImpl()->SetParentNativeViewAccessible(accessible_parent);
+  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame());
+  if (rfh)
+    rfh->SetParentNativeViewAccessible(accessible_parent);
 }
 #endif
 
@@ -846,8 +913,12 @@ bool WebContentsImpl::IsLoading() const {
   return is_loading_;
 }
 
+bool WebContentsImpl::IsLoadingToDifferentDocument() const {
+  return is_loading_ && is_load_to_different_document_;
+}
+
 bool WebContentsImpl::IsWaitingForResponse() const {
-  return waiting_for_response_;
+  return waiting_for_response_ && is_load_to_different_document_;
 }
 
 const net::LoadStateWithParam& WebContentsImpl::GetLoadState() const {
@@ -875,7 +946,7 @@ std::set<GURL> WebContentsImpl::GetSitesInTab() const {
 }
 
 const std::string& WebContentsImpl::GetEncoding() const {
-  return encoding_;
+  return canonical_encoding_;
 }
 
 bool WebContentsImpl::DisplayedInsecureContent() const {
@@ -921,6 +992,30 @@ int WebContentsImpl::GetCapturerCount() const {
   return capturer_count_;
 }
 
+bool WebContentsImpl::IsAudioMuted() const {
+  return audio_muter_.get() && audio_muter_->is_muting();
+}
+
+void WebContentsImpl::SetAudioMuted(bool mute) {
+  DVLOG(1) << "SetAudioMuted(mute=" << mute << "), was " << IsAudioMuted()
+           << " for WebContentsImpl@" << this;
+
+  if (mute == IsAudioMuted())
+    return;
+
+  if (mute) {
+    if (!audio_muter_)
+      audio_muter_.reset(new WebContentsAudioMuter(this));
+    audio_muter_->StartMuting();
+  } else {
+    DCHECK(audio_muter_);
+    audio_muter_->StopMuting();
+  }
+
+  // Notification for UI updates in response to the changed muting state.
+  NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
+}
+
 bool WebContentsImpl::IsCrashed() const {
   return (crashed_status_ == base::TERMINATION_STATUS_PROCESS_CRASHED ||
           crashed_status_ == base::TERMINATION_STATUS_ABNORMAL_TERMINATION ||
@@ -945,7 +1040,20 @@ bool WebContentsImpl::IsBeingDestroyed() const {
   return is_being_destroyed_;
 }
 
-void WebContentsImpl::NotifyNavigationStateChanged(unsigned changed_flags) {
+void WebContentsImpl::NotifyNavigationStateChanged(
+    InvalidateTypes changed_flags) {
+  // Create and release the audio power save blocker depending on whether the
+  // tab is actively producing audio or not.
+  if (changed_flags == INVALIDATE_TYPE_TAB &&
+      AudioStreamMonitor::monitoring_available()) {
+    if (WasRecentlyAudible()) {
+      if (!audio_power_save_blocker_)
+        CreateAudioPowerSaveBlocker();
+    } else {
+      audio_power_save_blocker_.reset();
+    }
+  }
+
   if (delegate_)
     delegate_->NavigationStateChanged(this, changed_flags);
 }
@@ -956,12 +1064,17 @@ base::TimeTicks WebContentsImpl::GetLastActiveTime() const {
 
 void WebContentsImpl::WasShown() {
   controller_.SetActive(true);
-  RenderWidgetHostView* rwhv = GetRenderWidgetHostView();
-  if (rwhv) {
-    rwhv->Show();
+
+  std::set<RenderWidgetHostView*> widgets = GetRenderWidgetHostViewsInTree();
+  for (std::set<RenderWidgetHostView*>::iterator iter = widgets.begin();
+       iter != widgets.end();
+       iter++) {
+    if (*iter) {
+      (*iter)->Show();
 #if defined(OS_MACOSX)
-    rwhv->SetActive(true);
+      (*iter)->SetActive(true);
 #endif
+    }
   }
 
   last_active_time_ = base::TimeTicks::Now();
@@ -974,6 +1087,10 @@ void WebContentsImpl::WasShown() {
     rvh->ResizeRectChanged(GetRootWindowResizerRect());
   }
 
+  // Restore power save blocker if there are active video players running.
+  if (!active_video_players_.empty() && !video_power_save_blocker_)
+    CreateVideoPowerSaveBlocker();
+
   FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasShown());
 
   should_normally_be_visible_ = true;
@@ -989,9 +1106,16 @@ void WebContentsImpl::WasHidden() {
     // removes the |GetRenderViewHost()|; then when we actually destroy the
     // window, OnWindowPosChanged() notices and calls WasHidden() (which
     // calls us).
-    RenderWidgetHostView* rwhv = GetRenderWidgetHostView();
-    if (rwhv)
-      rwhv->Hide();
+    std::set<RenderWidgetHostView*> widgets = GetRenderWidgetHostViewsInTree();
+    for (std::set<RenderWidgetHostView*>::iterator iter = widgets.begin();
+         iter != widgets.end();
+         iter++) {
+      if (*iter)
+        (*iter)->Hide();
+    }
+
+    // Release any video power save blockers held as video is not visible.
+    video_power_save_blocker_.reset();
   }
 
   FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasHidden());
@@ -1037,11 +1161,21 @@ void WebContentsImpl::Observe(int type,
   switch (type) {
     case NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: {
       RenderWidgetHost* host = Source<RenderWidgetHost>(source).ptr();
-      for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
-           i != pending_widget_views_.end(); ++i) {
-        if (host->GetView() == i->second) {
-          pending_widget_views_.erase(i);
-          break;
+      RenderWidgetHostView* view = host->GetView();
+      if (view == GetFullscreenRenderWidgetHostView()) {
+        // We cannot just call view_->RestoreFocus() here.  On some platforms,
+        // attempting to focus the currently-invisible WebContentsView will be
+        // flat-out ignored.  Therefore, this boolean is used to track whether
+        // we will request focus after the fullscreen widget has been
+        // destroyed.
+        fullscreen_widget_had_focus_at_shutdown_ = (view && view->HasFocus());
+      } else {
+        for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
+             i != pending_widget_views_.end(); ++i) {
+          if (host->GetView() == i->second) {
+            pending_widget_views_.erase(i);
+            break;
+          }
         }
       }
       break;
@@ -1095,9 +1229,16 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
   registrar_.Add(this,
                  NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
                  NotificationService::AllBrowserContextsAndSources());
+
+  geolocation_dispatcher_host_.reset(new GeolocationDispatcherHost(this));
+  midi_dispatcher_host_.reset(new MidiDispatcherHost(this));
+
+  screen_orientation_dispatcher_host_.reset(
+      new ScreenOrientationDispatcherHostImpl(this));
+
+  manifest_manager_host_.reset(new ManifestManagerHost(this));
+
 #if defined(OS_ANDROID)
-  java_bridge_dispatcher_host_manager_.reset(
-      new JavaBridgeDispatcherHostManager(this));
   date_time_chooser_.reset(new DateTimeChooserAndroid());
 #endif
 }
@@ -1146,6 +1287,18 @@ void WebContentsImpl::RemoveObserver(WebContentsObserver* observer) {
   observers_.RemoveObserver(observer);
 }
 
+std::set<RenderWidgetHostView*>
+WebContentsImpl::GetRenderWidgetHostViewsInTree() {
+  std::set<RenderWidgetHostView*> set;
+  if (ShowingInterstitialPage()) {
+    set.insert(GetRenderWidgetHostView());
+  } else {
+    ForEachFrame(
+        base::Bind(&AddRenderWidgetHostViewToSet, base::Unretained(&set)));
+  }
+  return set;
+}
+
 void WebContentsImpl::Activate() {
   if (delegate_)
     delegate_->ActivateContents(this);
@@ -1182,6 +1335,8 @@ void WebContentsImpl::RenderWidgetDeleted(
                       DidDestroyFullscreenWidget(
                           fullscreen_widget_routing_id_));
     fullscreen_widget_routing_id_ = MSG_ROUTING_NONE;
+    if (fullscreen_widget_had_focus_at_shutdown_)
+      view_->RestoreFocus();
   }
 }
 
@@ -1197,7 +1352,6 @@ void WebContentsImpl::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
       browser_plugin_embedder_->HandleKeyboardEvent(event)) {
     return;
   }
-
   if (delegate_)
     delegate_->HandleKeyboardEvent(this, event);
 }
@@ -1234,7 +1388,7 @@ bool WebContentsImpl::HandleGestureEvent(
   // Some platforms (eg. Mac) send GesturePinch events for trackpad pinch-zoom.
   // Use them to implement browser zoom, as for HandleWheelEvent above.
   if (event.type == blink::WebInputEvent::GesturePinchUpdate &&
-      event.sourceDevice == blink::WebGestureEvent::Touchpad) {
+      event.sourceDevice == blink::WebGestureDeviceTouchpad) {
     // The scale difference necessary to trigger a zoom action. Derived from
     // experimentation to find a value that feels reasonable.
     const float kZoomStepValue = 0.6f;
@@ -1269,12 +1423,6 @@ bool WebContentsImpl::HandleGestureEvent(
   return false;
 }
 
-#if defined(OS_WIN)
-gfx::NativeViewAccessible WebContentsImpl::GetParentNativeViewAccessible() {
-  return accessible_parent_;
-}
-#endif
-
 void WebContentsImpl::HandleMouseDown() {
   if (delegate_)
     delegate_->HandleMouseDown();
@@ -1344,7 +1492,7 @@ void WebContentsImpl::CreateNewWindow(
   // script-related windows), by passing in the current SiteInstance.  However,
   // if the opener is being suppressed (in a non-guest), we create a new
   // SiteInstance in its own BrowsingInstance.
-  bool is_guest = GetRenderProcessHost()->IsGuest();
+  bool is_guest = BrowserPluginGuest::IsGuest(this);
 
   // If the opener is to be suppressed, the new window can be in any process.
   // Since routing ids are process specific, we must not have one passed in
@@ -1365,7 +1513,7 @@ void WebContentsImpl::CreateNewWindow(
     if (process_handle != base::kNullProcessHandle) {
       RecordAction(
           base::UserMetricsAction("Terminate_ProcessMismatch_CreateNewWindow"));
-      base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false);
+      base::KillProcess(process_handle, RESULT_CODE_KILLED, false);
     }
     return;
   }
@@ -1407,35 +1555,27 @@ void WebContentsImpl::CreateNewWindow(
 
   // Create the new web contents. This will automatically create the new
   // WebContentsView. In the future, we may want to create the view separately.
-  WebContentsImpl* new_contents =
-      new WebContentsImpl(GetBrowserContext(),
-                          params.opener_suppressed ? NULL : this);
-
-  new_contents->GetController().SetSessionStorageNamespace(
-      partition_id,
-      session_storage_namespace);
   CreateParams create_params(GetBrowserContext(), site_instance.get());
   create_params.routing_id = route_id;
   create_params.main_frame_routing_id = main_frame_route_id;
+  create_params.opener = this;
+  create_params.opener_suppressed = params.opener_suppressed;
+  if (params.disposition == NEW_BACKGROUND_TAB)
+    create_params.initially_hidden = true;
+
+  WebContentsImpl* new_contents = NULL;
   if (!is_guest) {
     create_params.context = view_->GetNativeView();
     create_params.initial_size = GetContainerBounds().size();
-  } else {
-    // This makes |new_contents| act as a guest.
-    // For more info, see comment above class BrowserPluginGuest.
-    int instance_id =
-        BrowserPluginGuestManager::FromBrowserContext(GetBrowserContext())->
-            GetNextInstanceID();
-    WebContentsImpl* new_contents_impl =
-        static_cast<WebContentsImpl*>(new_contents);
-    BrowserPluginGuest::CreateWithOpener(instance_id,
-                                         new_contents_impl->opener() != NULL,
-                                         new_contents_impl,
-                                         GetBrowserPluginGuest());
+    new_contents = static_cast<WebContentsImpl*>(
+        WebContents::Create(create_params));
+  }  else {
+    new_contents = GetBrowserPluginGuest()->CreateNewGuestWindow(create_params);
   }
-  if (params.disposition == NEW_BACKGROUND_TAB)
-    create_params.initially_hidden = true;
-  new_contents->Init(create_params);
+  new_contents->GetController().SetSessionStorageNamespace(
+      partition_id,
+      session_storage_namespace);
+  new_contents->RenderViewCreated(new_contents->GetRenderViewHost());
 
   // Save the window for later if we're not suppressing the opener (since it
   // will be shown immediately).
@@ -1474,7 +1614,7 @@ void WebContentsImpl::CreateNewWindow(
       OpenURLParams open_params(params.target_url,
                                 Referrer(),
                                 CURRENT_TAB,
-                                PAGE_TRANSITION_LINK,
+                                ui::PAGE_TRANSITION_LINK,
                                 true /* is_renderer_initiated */);
       open_params.user_gesture = params.user_gesture;
       new_contents->OpenURL(open_params);
@@ -1507,7 +1647,7 @@ void WebContentsImpl::CreateNewWidget(int render_process_id,
     if (process_handle != base::kNullProcessHandle) {
       RecordAction(
           base::UserMetricsAction("Terminate_ProcessMismatch_CreateNewWidget"));
-      base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false);
+      base::KillProcess(process_handle, RESULT_CODE_KILLED, false);
     }
     return;
   }
@@ -1576,6 +1716,7 @@ void WebContentsImpl::ShowCreatedWidget(int route_id,
 
   if (is_fullscreen) {
     DCHECK_EQ(MSG_ROUTING_NONE, fullscreen_widget_routing_id_);
+    view_->StoreFocus();
     fullscreen_widget_routing_id_ = route_id;
     if (delegate_ && delegate_->EmbedsFullscreenWidget()) {
       widget_host_view->InitAsChild(GetRenderWidgetHostView()->GetNativeView());
@@ -1621,15 +1762,18 @@ WebContentsImpl* WebContentsImpl::GetCreatedWindow(int route_id) {
   RemoveDestructionObserver(new_contents);
 
   // Don't initialize the guest WebContents immediately.
-  if (new_contents->GetRenderProcessHost()->IsGuest())
+  if (BrowserPluginGuest::IsGuest(new_contents))
     return new_contents;
 
   if (!new_contents->GetRenderProcessHost()->HasConnection() ||
       !new_contents->GetRenderViewHost()->GetView())
     return NULL;
 
+  // Resume blocked requests for both the RenderViewHost and RenderFrameHost.
   // TODO(brettw): It seems bogus to reach into here and initialize the host.
   static_cast<RenderViewHostImpl*>(new_contents->GetRenderViewHost())->Init();
+  static_cast<RenderFrameHostImpl*>(new_contents->GetMainFrame())->Init();
+
   return new_contents;
 }
 
@@ -1659,26 +1803,53 @@ void WebContentsImpl::RequestMediaAccessPermission(
     delegate_->RequestMediaAccessPermission(this, request, callback);
   } else {
     callback.Run(MediaStreamDevices(),
-                 MEDIA_DEVICE_INVALID_STATE,
+                 MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN,
                  scoped_ptr<MediaStreamUI>());
   }
 }
 
+bool WebContentsImpl::CheckMediaAccessPermission(const GURL& security_origin,
+                                                 MediaStreamType type) {
+  DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
+         type == MEDIA_DEVICE_VIDEO_CAPTURE);
+  return delegate_ &&
+         delegate_->CheckMediaAccessPermission(this, security_origin, type);
+}
+
 SessionStorageNamespace* WebContentsImpl::GetSessionStorageNamespace(
     SiteInstance* instance) {
   return controller_.GetSessionStorageNamespace(instance);
 }
 
+SessionStorageNamespaceMap WebContentsImpl::GetSessionStorageNamespaceMap() {
+  return controller_.GetSessionStorageNamespaceMap();
+}
+
 FrameTree* WebContentsImpl::GetFrameTree() {
   return &frame_tree_;
 }
 
+AccessibilityMode WebContentsImpl::GetAccessibilityMode() const {
+  return accessibility_mode_;
+}
+
 void WebContentsImpl::AccessibilityEventReceived(
     const std::vector<AXEventNotificationDetails>& details) {
   FOR_EACH_OBSERVER(
       WebContentsObserver, observers_, AccessibilityEventReceived(details));
 }
 
+RenderFrameHost* WebContentsImpl::GetGuestByInstanceID(
+    int browser_plugin_instance_id) {
+  BrowserPluginGuestManager* guest_manager =
+      GetBrowserContext()->GetGuestManager();
+  WebContents* guest = guest_manager->GetGuestByInstanceID(
+      this, browser_plugin_instance_id);
+  if (!guest)
+    return NULL;
+  return guest->GetMainFrame();
+}
+
 void WebContentsImpl::OnShowValidationMessage(
     const gfx::Rect& anchor_in_root_view,
     const base::string16& main_text,
@@ -1704,6 +1875,18 @@ void WebContentsImpl::DidSendScreenRects(RenderWidgetHostImpl* rwh) {
     browser_plugin_embedder_->DidSendScreenRects();
 }
 
+BrowserAccessibilityManager*
+    WebContentsImpl::GetRootBrowserAccessibilityManager() {
+  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame());
+  return rfh ? rfh->browser_accessibility_manager() : NULL;
+}
+
+BrowserAccessibilityManager*
+    WebContentsImpl::GetOrCreateRootBrowserAccessibilityManager() {
+  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame());
+  return rfh ? rfh->GetOrCreateBrowserAccessibilityManager() : NULL;
+}
+
 void WebContentsImpl::UpdatePreferredSize(const gfx::Size& pref_size) {
   const gfx::Size old_size = GetPreferredSize();
   preferred_size_ = pref_size;
@@ -1736,13 +1919,16 @@ bool WebContentsImpl::NavigateToPendingEntry(
     NavigationController::ReloadType reload_type) {
   FrameTreeNode* node = frame_tree_.root();
 
-  // If we are using --site-per-process, we should navigate in the FrameTreeNode
-  // specified in the pending entry.
+  // Navigate in the FrameTreeNode specified in the pending entry, if any.  This
+  // is currently only used in --site-per-process and tests.
   NavigationEntryImpl* pending_entry =
       NavigationEntryImpl::FromNavigationEntry(controller_.GetPendingEntry());
-  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) &&
-      pending_entry->frame_tree_node_id() != -1) {
-    node = frame_tree_.FindByID(pending_entry->frame_tree_node_id());
+  if (pending_entry->frame_tree_node_id() != -1) {
+    FrameTreeNode* subframe =
+        frame_tree_.FindByID(pending_entry->frame_tree_node_id());
+    DCHECK(subframe);
+    if (subframe)
+      node = subframe;
   }
 
   return node->navigator()->NavigateToPendingEntry(
@@ -1968,19 +2154,35 @@ DropData* WebContentsImpl::GetDropData() {
 }
 
 void WebContentsImpl::Focus() {
-  view_->Focus();
+  RenderWidgetHostView* const fullscreen_view =
+      GetFullscreenRenderWidgetHostView();
+  if (fullscreen_view)
+    fullscreen_view->Focus();
+  else
+    view_->Focus();
 }
 
 void WebContentsImpl::SetInitialFocus() {
-  view_->SetInitialFocus();
+  RenderWidgetHostView* const fullscreen_view =
+      GetFullscreenRenderWidgetHostView();
+  if (fullscreen_view)
+    fullscreen_view->Focus();
+  else
+    view_->SetInitialFocus();
 }
 
 void WebContentsImpl::StoreFocus() {
-  view_->StoreFocus();
+  if (!GetFullscreenRenderWidgetHostView())
+    view_->StoreFocus();
 }
 
 void WebContentsImpl::RestoreFocus() {
-  view_->RestoreFocus();
+  RenderWidgetHostView* const fullscreen_view =
+      GetFullscreenRenderWidgetHostView();
+  if (fullscreen_view)
+    fullscreen_view->Focus();
+  else
+    view_->RestoreFocus();
 }
 
 void WebContentsImpl::FocusThroughTabTraversal(bool reverse) {
@@ -1988,6 +2190,12 @@ void WebContentsImpl::FocusThroughTabTraversal(bool reverse) {
     GetRenderManager()->interstitial_page()->FocusThroughTabTraversal(reverse);
     return;
   }
+  RenderWidgetHostView* const fullscreen_view =
+      GetFullscreenRenderWidgetHostView();
+  if (fullscreen_view) {
+    fullscreen_view->Focus();
+    return;
+  }
   GetRenderViewHostImpl()->SetInitialFocus(reverse);
 }
 
@@ -2073,15 +2281,6 @@ void WebContentsImpl::GenerateMHTML(
   MHTMLGenerationManager::GetInstance()->SaveMHTML(this, file, callback);
 }
 
-// TODO(nasko): Rename this method to IsVisibleEntry.
-bool WebContentsImpl::IsActiveEntry(int32 page_id) {
-  NavigationEntryImpl* visible_entry =
-      NavigationEntryImpl::FromNavigationEntry(controller_.GetVisibleEntry());
-  return (visible_entry != NULL &&
-          visible_entry->site_instance() == GetSiteInstance() &&
-          visible_entry->GetPageID() == page_id);
-}
-
 const std::string& WebContentsImpl::GetContentsMimeType() const {
   return contents_mime_type_;
 }
@@ -2096,7 +2295,7 @@ void WebContentsImpl::SetOverrideEncoding(const std::string& encoding) {
 }
 
 void WebContentsImpl::ResetOverrideEncoding() {
-  encoding_.clear();
+  canonical_encoding_.clear();
   Send(new ViewMsg_ResetPageEncodingToDefault(GetRoutingID()));
 }
 
@@ -2170,40 +2369,6 @@ bool WebContentsImpl::GetClosedByUserGesture() const {
   return closed_by_user_gesture_;
 }
 
-double WebContentsImpl::GetZoomLevel() const {
-  HostZoomMapImpl* zoom_map = static_cast<HostZoomMapImpl*>(
-      HostZoomMap::GetForBrowserContext(GetBrowserContext()));
-  if (!zoom_map)
-    return 0;
-
-  double zoom_level;
-  if (temporary_zoom_settings_) {
-    zoom_level = zoom_map->GetTemporaryZoomLevel(
-        GetRenderProcessHost()->GetID(), GetRenderViewHost()->GetRoutingID());
-  } else {
-    GURL url;
-    NavigationEntry* entry = GetController().GetLastCommittedEntry();
-    // Since zoom map is updated using rewritten URL, use rewritten URL
-    // to get the zoom level.
-    url = entry ? entry->GetURL() : GURL::EmptyGURL();
-    zoom_level = zoom_map->GetZoomLevelForHostAndScheme(url.scheme(),
-        net::GetHostOrSpecFromURL(url));
-  }
-  return zoom_level;
-}
-
-int WebContentsImpl::GetZoomPercent(bool* enable_increment,
-                                    bool* enable_decrement) const {
-  *enable_decrement = *enable_increment = false;
-  // Calculate the zoom percent from the factor. Round up to the nearest whole
-  // number.
-  int percent = static_cast<int>(
-      ZoomLevelToZoomFactor(GetZoomLevel()) * 100 + 0.5);
-  *enable_decrement = percent > minimum_zoom_percent_;
-  *enable_increment = percent < maximum_zoom_percent_;
-  return percent;
-}
-
 void WebContentsImpl::ViewSource() {
   if (!delegate_)
     return;
@@ -2236,6 +2401,9 @@ gfx::Size WebContentsImpl::GetPreferredSize() const {
 }
 
 bool WebContentsImpl::GotResponseToLockMouseRequest(bool allowed) {
+  if (GetBrowserPluginGuest())
+    return GetBrowserPluginGuest()->LockMouse(allowed);
+
   return GetRenderViewHost() ?
       GetRenderViewHostImpl()->GotResponseToLockMouseRequest(allowed) : false;
 }
@@ -2284,13 +2452,6 @@ bool WebContentsImpl::IsSubframe() const {
   return is_subframe_;
 }
 
-void WebContentsImpl::SetZoomLevel(double level) {
-  Send(new ViewMsg_SetZoomLevel(GetRoutingID(), level));
-  BrowserPluginEmbedder* embedder = GetBrowserPluginEmbedder();
-  if (embedder)
-    embedder->SetZoomLevel(level);
-}
-
 void WebContentsImpl::Find(int request_id,
                            const base::string16& search_text,
                            const blink::WebFindOptions& options) {
@@ -2306,9 +2467,17 @@ void WebContentsImpl::InsertCSS(const std::string& css) {
       GetMainFrame()->GetRoutingID(), css));
 }
 
+bool WebContentsImpl::WasRecentlyAudible() {
+  return audio_stream_monitor_.WasRecentlyAudible();
+}
+
+void WebContentsImpl::GetManifest(const GetManifestCallback& callback) {
+  manifest_manager_host_->GetManifest(GetMainFrame(), callback);
+}
+
 bool WebContentsImpl::FocusLocationBarByDefault() {
   NavigationEntry* entry = controller_.GetVisibleEntry();
-  if (entry && entry->GetURL() == GURL(kAboutBlankURL))
+  if (entry && entry->GetURL() == GURL(url::kAboutBlankURL))
     return true;
   return delegate_ && delegate_->ShouldFocusLocationBarByDefault(this);
 }
@@ -2320,49 +2489,36 @@ void WebContentsImpl::SetFocusToLocationBar(bool select_all) {
 
 void WebContentsImpl::DidStartProvisionalLoad(
     RenderFrameHostImpl* render_frame_host,
-    int parent_routing_id,
     const GURL& validated_url,
     bool is_error_page,
     bool is_iframe_srcdoc) {
-  bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame();
-  if (is_main_frame)
-    DidChangeLoadProgress(0);
-
   // Notify observers about the start of the provisional load.
-  int render_frame_id = render_frame_host->GetRoutingID();
-  RenderViewHost* render_view_host = render_frame_host->render_view_host();
-  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
-                    DidStartProvisionalLoadForFrame(
-                        render_frame_id, parent_routing_id, is_main_frame,
-                        validated_url, is_error_page, is_iframe_srcdoc,
-                        render_view_host));
+  FOR_EACH_OBSERVER(
+      WebContentsObserver,
+      observers_,
+      DidStartProvisionalLoadForFrame(
+          render_frame_host, validated_url, is_error_page, is_iframe_srcdoc));
+}
 
-  if (is_main_frame) {
-    FOR_EACH_OBSERVER(
-        WebContentsObserver,
-        observers_,
-        ProvisionalChangeToMainFrameUrl(validated_url,
-                                        render_frame_host));
-  }
+void WebContentsImpl::DidStartNavigationTransition(
+    RenderFrameHostImpl* render_frame_host) {
+#if defined(OS_ANDROID)
+  int render_frame_id = render_frame_host->GetRoutingID();
+  GetWebContentsAndroid()->DidStartNavigationTransitionForFrame(
+      render_frame_id);
+#endif
 }
 
 void WebContentsImpl::DidFailProvisionalLoadWithError(
     RenderFrameHostImpl* render_frame_host,
     const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) {
   GURL validated_url(params.url);
-  int render_frame_id = render_frame_host->GetRoutingID();
-  bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame();
-  RenderViewHost* render_view_host = render_frame_host->render_view_host();
-  FOR_EACH_OBSERVER(
-      WebContentsObserver,
-      observers_,
-      DidFailProvisionalLoad(render_frame_id,
-                             params.frame_unique_name,
-                             is_main_frame,
-                             validated_url,
-                             params.error_code,
-                             params.error_description,
-                             render_view_host));
+  FOR_EACH_OBSERVER(WebContentsObserver,
+                    observers_,
+                    DidFailProvisionalLoad(render_frame_host,
+                                           validated_url,
+                                           params.error_code,
+                                           params.error_description));
 }
 
 void WebContentsImpl::DidFailLoadWithError(
@@ -2370,12 +2526,10 @@ void WebContentsImpl::DidFailLoadWithError(
     const GURL& url,
     int error_code,
     const base::string16& error_description) {
-  int render_frame_id = render_frame_host->GetRoutingID();
-  bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame();
-  RenderViewHost* render_view_host = render_frame_host->render_view_host();
-  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
-                    DidFailLoad(render_frame_id, url, is_main_frame, error_code,
-                                error_description, render_view_host));
+  FOR_EACH_OBSERVER(
+      WebContentsObserver,
+      observers_,
+      DidFailLoad(render_frame_host, url, error_code, error_description));
 }
 
 void WebContentsImpl::NotifyChangedNavigationState(
@@ -2427,45 +2581,23 @@ bool WebContentsImpl::ShouldPreserveAbortedURLs() {
   return delegate_->ShouldPreserveAbortedURLs(this);
 }
 
-void WebContentsImpl::DidRedirectProvisionalLoad(
-    RenderFrameHostImpl* render_frame_host,
-    const GURL& validated_target_url) {
-  // Notify observers about the provisional change in the main frame URL.
-  FOR_EACH_OBSERVER(
-      WebContentsObserver,
-      observers_,
-      ProvisionalChangeToMainFrameUrl(validated_target_url,
-                                      render_frame_host));
-}
-
 void WebContentsImpl::DidCommitProvisionalLoad(
     RenderFrameHostImpl* render_frame_host,
-    const base::string16& frame_unique_name,
-    bool is_main_frame,
     const GURL& url,
-    PageTransition transition_type) {
-  int render_frame_id = render_frame_host->GetRoutingID();
-  RenderViewHost* render_view_host = render_frame_host->render_view_host();
+    ui::PageTransition transition_type) {
   // Notify observers about the commit of the provisional load.
-  FOR_EACH_OBSERVER(
-      WebContentsObserver,
-      observers_,
-      DidCommitProvisionalLoadForFrame(render_frame_id,
-                                       frame_unique_name,
-                                       is_main_frame,
-                                       url,
-                                       transition_type,
-                                       render_view_host));
+  FOR_EACH_OBSERVER(WebContentsObserver,
+                    observers_,
+                    DidCommitProvisionalLoadForFrame(
+                        render_frame_host, url, transition_type));
 }
 
 void WebContentsImpl::DidNavigateMainFramePreCommit(
-    const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
+    bool navigation_is_within_page) {
   // Ensure fullscreen mode is exited before committing the navigation to a
   // different page.  The next page will not start out assuming it is in
   // fullscreen mode.
-  if (controller_.IsURLInPageNavigation(params.url,
-                                        params.was_within_same_page,
-                                        NAVIGATION_TYPE_UNKNOWN)) {
+  if (navigation_is_within_page) {
     // No page change?  Then, the renderer and browser can remain in fullscreen.
     return;
   }
@@ -2484,7 +2616,7 @@ void WebContentsImpl::DidNavigateMainFramePostCommit(
     // clicking on a link); see bugs 1184641 and 980803. We don't want to
     // clear the bubble when a user navigates to a named anchor in the same
     // page.
-    UpdateTargetURL(details.entry->GetPageID(), GURL());
+    UpdateTargetURL(GURL());
   }
 
   if (!details.is_in_page) {
@@ -2499,10 +2631,9 @@ void WebContentsImpl::DidNavigateMainFramePostCommit(
   FOR_EACH_OBSERVER(WebContentsObserver, observers_,
                     DidNavigateMainFrame(details, params));
 
-  if (delegate_) {
+  if (delegate_)
     delegate_->DidNavigateMainFramePostCommit(this);
-    view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
-  }
+  view_->SetOverscrollControllerEnabled(CanOverscrollContent());
 }
 
 void WebContentsImpl::DidNavigateAnyFramePostCommit(
@@ -2526,19 +2657,28 @@ void WebContentsImpl::SetMainFrameMimeType(const std::string& mime_type) {
   contents_mime_type_ = mime_type;
 }
 
-bool WebContentsImpl::CanOverscrollContent() {
+bool WebContentsImpl::CanOverscrollContent() const {
+  // Disable overscroll when touch emulation is on. See crbug.com/369938.
+  if (force_disable_overscroll_content_)
+    return false;
+
   if (delegate_)
     return delegate_->CanOverscrollContent();
 
   return false;
 }
 
+void WebContentsImpl::OnThemeColorChanged(SkColor theme_color) {
+  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
+                    DidChangeThemeColor(theme_color));
+}
+
 void WebContentsImpl::OnDidLoadResourceFromMemoryCache(
     const GURL& url,
     const std::string& security_info,
     const std::string& http_method,
     const std::string& mime_type,
-    ResourceType::Type resource_type) {
+    ResourceType resource_type) {
   base::StatsCounter cache("WebKit.CacheHit");
   cache.Increment();
 
@@ -2563,7 +2703,7 @@ void WebContentsImpl::OnDidLoadResourceFromMemoryCache(
 
   if (url.is_valid() && url.SchemeIsHTTPOrHTTPS()) {
     scoped_refptr<net::URLRequestContextGetter> request_context(
-        resource_type == ResourceType::MEDIA ?
+        resource_type == RESOURCE_TYPE_MEDIA ?
             GetBrowserContext()->GetMediaRequestContextForRenderProcess(
                 GetRenderProcessHost()->GetID()) :
             GetBrowserContext()->GetRequestContextForRenderProcess(
@@ -2600,12 +2740,8 @@ void WebContentsImpl::OnDocumentLoadedInFrame() {
   CHECK(!render_view_message_source_);
   RenderFrameHostImpl* rfh =
       static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
-
-  int render_frame_id = rfh->GetRoutingID();
-  RenderViewHost* render_view_host = rfh->render_view_host();
-  FOR_EACH_OBSERVER(WebContentsObserver,
-                    observers_,
-                    DocumentLoadedInFrame(render_frame_id, render_view_host));
+  FOR_EACH_OBSERVER(
+      WebContentsObserver, observers_, DocumentLoadedInFrame(rfh));
 }
 
 void WebContentsImpl::OnDidFinishLoad(
@@ -2623,12 +2759,93 @@ void WebContentsImpl::OnDidFinishLoad(
 
   RenderFrameHostImpl* rfh =
       static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
-  int render_frame_id = rfh->GetRoutingID();
-  RenderViewHost* render_view_host = rfh->render_view_host();
-  bool is_main_frame = rfh->frame_tree_node()->IsMainFrame();
-  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
-                    DidFinishLoad(render_frame_id, validated_url,
-                                  is_main_frame, render_view_host));
+  FOR_EACH_OBSERVER(
+      WebContentsObserver, observers_, DidFinishLoad(rfh, validated_url));
+}
+
+void WebContentsImpl::OnDidStartLoading(bool to_different_document) {
+  RenderFrameHostImpl* rfh =
+      static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
+  int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
+
+  // It is possible to get multiple calls to OnDidStartLoading that don't have
+  // corresponding calls to OnDidStopLoading:
+  // - With "swappedout://" URLs, this happens when a RenderView gets swapped
+  //   out for a cross-process navigation, and it turns into a placeholder for
+  //   one being rendered in a different process.
+  // - Also, there might be more than one RenderFrameHost sharing the same
+  //   FrameTreeNode (and thus sharing its ID) each sending a start.
+  // - But in the future, once clamy@ moves navigation network requests to the
+  //   browser process, there's a good chance that callbacks about starting and
+  //   stopping will all be handled by the browser. When that happens, there
+  //   should no longer be a start/stop call imbalance. TODO(avi): When this
+  //   future arrives, update this code to not allow this case.
+  DCHECK_GE(loading_frames_in_progress_, 0);
+  if (loading_progresses_.find(render_frame_id) == loading_progresses_.end()) {
+    if (loading_frames_in_progress_ == 0)
+      DidStartLoading(rfh, to_different_document);
+    ++loading_frames_in_progress_;
+  }
+
+  loading_progresses_[render_frame_id] = kMinimumLoadingProgress;
+  SendLoadProgressChanged();
+}
+
+void WebContentsImpl::OnDidStopLoading() {
+  RenderFrameHostImpl* rfh =
+      static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
+  int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
+
+  if (loading_progresses_.find(render_frame_id) != loading_progresses_.end()) {
+    // Load stopped while we were still tracking load.  Make sure we update
+    // progress based on this frame's completion.
+    loading_progresses_[render_frame_id] = 1.0;
+    SendLoadProgressChanged();
+    // Then we clean-up our states.
+    if (loading_total_progress_ == 1.0)
+      ResetLoadProgressState();
+  }
+
+  // TODO(japhet): This should be a DCHECK, but the pdf plugin sometimes
+  // calls DidStopLoading() without a matching DidStartLoading().
+  if (loading_frames_in_progress_ == 0)
+    return;
+  --loading_frames_in_progress_;
+  if (loading_frames_in_progress_ == 0)
+    DidStopLoading(rfh);
+}
+
+void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) {
+  RenderFrameHostImpl* rfh =
+      static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
+  int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
+
+  loading_progresses_[render_frame_id] = load_progress;
+
+  // We notify progress change immediately for the first and last updates.
+  // Also, since the message loop may be pretty busy when a page is loaded, it
+  // might not execute a posted task in a timely manner so we make sure to
+  // immediately send progress report if enough time has passed.
+  base::TimeDelta min_delay =
+      base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS);
+  if (load_progress == 1.0 || loading_last_progress_update_.is_null() ||
+      base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) {
+    // If there is a pending task to send progress, it is now obsolete.
+    loading_weak_factory_.InvalidateWeakPtrs();
+    SendLoadProgressChanged();
+    if (loading_total_progress_ == 1.0)
+      ResetLoadProgressState();
+    return;
+  }
+
+  if (loading_weak_factory_.HasWeakPtrs())
+    return;
+
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&WebContentsImpl::SendLoadProgressChanged,
+                 loading_weak_factory_.GetWeakPtr()),
+      min_delay);
 }
 
 void WebContentsImpl::OnGoToEntryAtOffset(int offset) {
@@ -2637,11 +2854,9 @@ void WebContentsImpl::OnGoToEntryAtOffset(int offset) {
 }
 
 void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent,
-                                         int maximum_percent,
-                                         bool remember) {
+                                         int maximum_percent) {
   minimum_zoom_percent_ = minimum_percent;
   maximum_zoom_percent_ = maximum_percent;
-  temporary_zoom_settings_ = !remember;
 }
 
 void WebContentsImpl::OnEnumerateDirectory(int request_id,
@@ -2667,7 +2882,21 @@ void WebContentsImpl::OnRegisterProtocolHandler(const std::string& protocol,
   if (policy->IsPseudoScheme(protocol))
     return;
 
-  delegate_->RegisterProtocolHandler(this, protocol, url, title, user_gesture);
+  delegate_->RegisterProtocolHandler(this, protocol, url, user_gesture);
+}
+
+void WebContentsImpl::OnUnregisterProtocolHandler(const std::string& protocol,
+                                                  const GURL& url,
+                                                  bool user_gesture) {
+  if (!delegate_)
+    return;
+
+  ChildProcessSecurityPolicyImpl* policy =
+      ChildProcessSecurityPolicyImpl::GetInstance();
+  if (policy->IsPseudoScheme(protocol))
+    return;
+
+  delegate_->UnregisterProtocolHandler(this, protocol, url, user_gesture);
 }
 
 void WebContentsImpl::OnFindReply(int request_id,
@@ -2702,11 +2931,6 @@ void WebContentsImpl::OnOpenDateTimeDialog(
                                  value.suggestions);
 }
 
-void WebContentsImpl::OnJavaBridgeGetChannelHandle(IPC::Message* reply_msg) {
-  java_bridge_dispatcher_host_manager_->OnGetChannelHandle(
-      render_frame_message_source_, reply_msg);
-}
-
 #endif
 
 void WebContentsImpl::OnPepperPluginHung(int plugin_child_id,
@@ -2781,6 +3005,7 @@ void WebContentsImpl::OnWebUISend(const GURL& source_url,
     delegate_->WebUISend(this, source_url, name, args);
 }
 
+#if defined(ENABLE_PLUGINS)
 void WebContentsImpl::OnRequestPpapiBrokerPermission(
     int routing_id,
     const GURL& url,
@@ -2814,6 +3039,7 @@ void WebContentsImpl::OnBrowserPluginMessage(const IPC::Message& message) {
   browser_plugin_embedder_.reset(BrowserPluginEmbedder::Create(this));
   browser_plugin_embedder_->OnMessageReceived(message);
 }
+#endif
 
 void WebContentsImpl::OnDidDownloadImage(
     int id,
@@ -2843,37 +3069,70 @@ void WebContentsImpl::OnUpdateFaviconURL(
                     DidUpdateFaviconURL(candidates));
 }
 
-void WebContentsImpl::OnMediaPlayingNotification(int64 player_cookie,
-                                                 bool has_video,
-                                                 bool has_audio) {
-// Chrome OS does its own detection of audio and video.
+void WebContentsImpl::CreateAudioPowerSaveBlocker() {
+  // ChromeOS has its own way of handling power save blocks for media.
 #if !defined(OS_CHROMEOS)
-  scoped_ptr<PowerSaveBlocker> blocker;
-  if (has_video) {
-    blocker = PowerSaveBlocker::Create(
-        PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, "Playing video");
+  DCHECK(!audio_power_save_blocker_);
+  audio_power_save_blocker_ = PowerSaveBlocker::Create(
+      PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, "Playing Audio");
+#endif
+}
+
+void WebContentsImpl::CreateVideoPowerSaveBlocker() {
+  // ChromeOS has its own way of handling power save blocks for media.
+#if !defined(OS_CHROMEOS)
+  DCHECK(!video_power_save_blocker_);
+  DCHECK(!active_video_players_.empty());
+  video_power_save_blocker_ = PowerSaveBlocker::Create(
+      PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, "Playing Video");
 #if defined(OS_ANDROID)
-    static_cast<PowerSaveBlockerImpl*>(blocker.get())
-        ->InitDisplaySleepBlocker(GetView()->GetNativeView());
+  static_cast<PowerSaveBlockerImpl*>(video_power_save_blocker_.get())
+      ->InitDisplaySleepBlocker(GetView()->GetNativeView());
 #endif
-  } else if (has_audio) {
-    blocker = PowerSaveBlocker::Create(
-        PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, "Playing audio");
+#endif
+}
+
+void WebContentsImpl::MaybeReleasePowerSaveBlockers() {
+  // If there are no more audio players and we don't have audio stream
+  // monitoring, release the audio power save blocker here instead of during
+  // NotifyNavigationStateChanged().
+  if (active_audio_players_.empty() &&
+      !AudioStreamMonitor::monitoring_available()) {
+    audio_power_save_blocker_.reset();
+  }
+
+  // If there are no more video players, clear the video power save blocker.
+  if (active_video_players_.empty())
+    video_power_save_blocker_.reset();
+}
+
+void WebContentsImpl::OnMediaPlayingNotification(int64 player_cookie,
+                                                 bool has_video,
+                                                 bool has_audio) {
+  if (has_audio) {
+    AddMediaPlayerEntry(player_cookie, &active_audio_players_);
+
+    // If we don't have audio stream monitoring, allocate the audio power save
+    // blocker here instead of during NotifyNavigationStateChanged().
+    if (!audio_power_save_blocker_ &&
+        !AudioStreamMonitor::monitoring_available()) {
+      CreateAudioPowerSaveBlocker();
+    }
   }
 
-  if (blocker) {
-    power_save_blockers_[render_frame_message_source_][player_cookie] =
-        blocker.release();
+  if (has_video) {
+    AddMediaPlayerEntry(player_cookie, &active_video_players_);
+
+    // If we're not hidden and have just created a player, create a blocker.
+    if (!video_power_save_blocker_ && !IsHidden())
+      CreateVideoPowerSaveBlocker();
   }
-#endif  // !defined(OS_CHROMEOS)
 }
 
 void WebContentsImpl::OnMediaPausedNotification(int64 player_cookie) {
-  // Chrome OS does its own detection of audio and video.
-#if !defined(OS_CHROMEOS)
-  delete power_save_blockers_[render_frame_message_source_][player_cookie];
-  power_save_blockers_[render_frame_message_source_].erase(player_cookie);
-#endif  // !defined(OS_CHROMEOS)
+  RemoveMediaPlayerEntry(player_cookie, &active_audio_players_);
+  RemoveMediaPlayerEntry(player_cookie, &active_video_players_);
+  MaybeReleasePowerSaveBlockers();
 }
 
 void WebContentsImpl::OnFirstVisuallyNonEmptyPaint() {
@@ -2882,8 +3141,8 @@ void WebContentsImpl::OnFirstVisuallyNonEmptyPaint() {
 }
 
 void WebContentsImpl::DidChangeVisibleSSLState() {
-  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
-                    DidChangeVisibleSSLState());
+  if (delegate_)
+    delegate_->VisibleSSLStateChanged(this);
 }
 
 void WebContentsImpl::NotifyBeforeFormRepostWarningShow() {
@@ -2891,7 +3150,6 @@ void WebContentsImpl::NotifyBeforeFormRepostWarningShow() {
                     BeforeFormRepostWarningShow());
 }
 
-
 void WebContentsImpl::ActivateAndShowRepostFormWarningDialog() {
   Activate();
   if (delegate_)
@@ -2923,6 +3181,7 @@ void WebContentsImpl::SetIsLoading(RenderViewHost* render_view_host,
 
   is_loading_ = is_loading;
   waiting_for_response_ = is_loading;
+  is_load_to_different_document_ = to_different_document;
 
   if (delegate_)
     delegate_->LoadingStateChanged(this, to_different_document);
@@ -2930,13 +3189,13 @@ void WebContentsImpl::SetIsLoading(RenderViewHost* render_view_host,
 
   std::string url = (details ? details->url.possibly_invalid_spec() : "NULL");
   if (is_loading) {
-    TRACE_EVENT_ASYNC_BEGIN1("browser", "WebContentsImpl Loading", this,
-                             "URL", url);
+    TRACE_EVENT_ASYNC_BEGIN1("browser,navigation", "WebContentsImpl Loading",
+                             this, "URL", url);
     FOR_EACH_OBSERVER(WebContentsObserver, observers_,
                       DidStartLoading(render_view_host));
   } else {
-    TRACE_EVENT_ASYNC_END1("browser", "WebContentsImpl Loading", this,
-                           "URL", url);
+    TRACE_EVENT_ASYNC_END1("browser,navigation", "WebContentsImpl Loading",
+                           this, "URL", url);
     FOR_EACH_OBSERVER(WebContentsObserver, observers_,
                       DidStopLoading(render_view_host));
   }
@@ -3021,8 +3280,39 @@ bool WebContentsImpl::UpdateTitleForEntry(NavigationEntryImpl* entry,
   return true;
 }
 
-void WebContentsImpl::NotifySwapped(RenderViewHost* old_host,
-                                    RenderViewHost* new_host) {
+void WebContentsImpl::SendLoadProgressChanged() {
+  loading_last_progress_update_ = base::TimeTicks::Now();
+  double progress = 0.0;
+  int frame_count = 0;
+
+  for (LoadingProgressMap::iterator it = loading_progresses_.begin();
+       it != loading_progresses_.end();
+       ++it) {
+    progress += it->second;
+    ++frame_count;
+  }
+  if (frame_count == 0)
+    return;
+  progress /= frame_count;
+  DCHECK(progress <= 1.0);
+
+  if (progress <= loading_total_progress_)
+    return;
+  loading_total_progress_ = progress;
+
+  if (delegate_)
+    delegate_->LoadProgressChanged(this, progress);
+}
+
+void WebContentsImpl::ResetLoadProgressState() {
+  loading_progresses_.clear();
+  loading_total_progress_ = 0.0;
+  loading_weak_factory_.InvalidateWeakPtrs();
+  loading_last_progress_update_ = base::TimeTicks();
+}
+
+void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host,
+                                        RenderViewHost* new_host) {
   // After sending out a swap notification, we need to send a disconnect
   // notification so that clients that pick up a pointer to |this| can NULL the
   // pointer.  See Bug 1230284.
@@ -3044,6 +3334,13 @@ void WebContentsImpl::NotifySwapped(RenderViewHost* old_host,
   RemoveBrowserPluginEmbedder();
 }
 
+void WebContentsImpl::NotifyFrameSwapped(RenderFrameHost* old_host,
+                                         RenderFrameHost* new_host) {
+  FOR_EACH_OBSERVER(WebContentsObserver,
+                    observers_,
+                    RenderFrameHostChanged(old_host, new_host));
+}
+
 // TODO(avi): Remove this entire function because this notification is already
 // covered by two observer functions. http://crbug.com/170921
 void WebContentsImpl::NotifyDisconnected() {
@@ -3078,6 +3375,7 @@ void WebContentsImpl::RenderFrameCreated(RenderFrameHost* render_frame_host) {
   FOR_EACH_OBSERVER(WebContentsObserver,
                     observers_,
                     RenderFrameCreated(render_frame_host));
+  SetAccessibilityModeOnFrame(accessibility_mode_, render_frame_host);
 }
 
 void WebContentsImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
@@ -3094,11 +3392,18 @@ void WebContentsImpl::WorkerCrashed(RenderFrameHost* render_frame_host) {
 
 void WebContentsImpl::ShowContextMenu(RenderFrameHost* render_frame_host,
                                       const ContextMenuParams& params) {
+  ContextMenuParams context_menu_params(params);
   // Allow WebContentsDelegates to handle the context menu operation first.
-  if (delegate_ && delegate_->HandleContextMenu(params))
+  if (GetBrowserPluginGuest()) {
+    WebContentsViewGuest* view_guest =
+        static_cast<WebContentsViewGuest*>(GetView());
+    context_menu_params = view_guest->ConvertContextMenuParams(params);
+  }
+  if (delegate_ && delegate_->HandleContextMenu(context_menu_params))
     return;
 
-  render_view_host_delegate_view_->ShowContextMenu(render_frame_host, params);
+  render_view_host_delegate_view_->ShowContextMenu(render_frame_host,
+                                                   context_menu_params);
 }
 
 void WebContentsImpl::RunJavaScriptMessage(
@@ -3193,6 +3498,12 @@ bool WebContentsImpl::IsNeverVisible() {
   return delegate_->IsNeverVisible(this);
 }
 
+#if defined(OS_WIN)
+gfx::NativeViewAccessible WebContentsImpl::GetParentNativeViewAccessible() {
+  return accessible_parent_;
+}
+#endif
+
 RenderViewHostDelegateView* WebContentsImpl::GetDelegateView() {
   return render_view_host_delegate_view_;
 }
@@ -3221,7 +3532,7 @@ void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
     return;
 
   if (delegate_)
-    view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
+    view_->SetOverscrollControllerEnabled(CanOverscrollContent());
 
   NotificationService::current()->Notify(
       NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
@@ -3251,6 +3562,7 @@ void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
   RenderFrameHost* main_frame = render_view_host->GetMainFrame();
   FOR_EACH_OBSERVER(
       WebContentsObserver, observers_, RenderFrameCreated(main_frame));
+  SetAccessibilityModeOnFrame(accessibility_mode_, main_frame);
 }
 
 void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) {
@@ -3297,14 +3609,19 @@ void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh,
   if (dialog_manager_)
     dialog_manager_->CancelActiveAndPendingDialogs(this);
 
+  if (delegate_)
+    delegate_->HideValidationMessage(this);
+
   SetIsLoading(rvh, false, true, NULL);
   NotifyDisconnected();
   SetIsCrashed(status, error_code);
 
-#if defined(OS_ANDROID)
-  if (GetRenderViewHostImpl()->media_player_manager())
-    GetRenderViewHostImpl()->media_player_manager()->DestroyAllMediaPlayers();
-#endif
+  // Reset the loading progress. TODO(avi): What does it mean to have a
+  // "renderer crash" when there is more than one renderer process serving a
+  // webpage? Once this function is called at a more granular frame level, we
+  // probably will need to more granularly reset the state here.
+  ResetLoadProgressState();
+  loading_frames_in_progress_ = 0;
 
   FOR_EACH_OBSERVER(WebContentsObserver,
                     observers_,
@@ -3346,42 +3663,9 @@ void WebContentsImpl::UpdateState(RenderViewHost* rvh,
   controller_.NotifyEntryChanged(entry, entry_index);
 }
 
-void WebContentsImpl::UpdateTitle(RenderViewHost* rvh,
-                                  int32 page_id,
-                                  const base::string16& title,
-                                  base::i18n::TextDirection title_direction) {
-  // If we have a title, that's a pretty good indication that we've started
-  // getting useful data.
-  SetNotWaitingForResponse();
-
-  // Try to find the navigation entry, which might not be the current one.
-  // For example, it might be from a pending RVH for the pending entry.
-  NavigationEntryImpl* entry = controller_.GetEntryWithPageID(
-      rvh->GetSiteInstance(), page_id);
-
-  // We can handle title updates when we don't have an entry in
-  // UpdateTitleForEntry, but only if the update is from the current RVH.
-  if (!entry && rvh != GetRenderViewHost())
-    return;
-
-  // TODO(evan): make use of title_direction.
-  // http://code.google.com/p/chromium/issues/detail?id=27094
-  if (!UpdateTitleForEntry(entry, title))
-    return;
-
-  // Broadcast notifications when the UI should be updated.
-  if (entry == controller_.GetEntryAtOffset(0))
-    NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE);
-}
-
-void WebContentsImpl::UpdateEncoding(RenderViewHost* render_view_host,
-                                     const std::string& encoding) {
-  SetEncoding(encoding);
-}
-
-void WebContentsImpl::UpdateTargetURL(int32 page_id, const GURL& url) {
+void WebContentsImpl::UpdateTargetURL(const GURL& url) {
   if (delegate_)
-    delegate_->UpdateTargetURL(this, page_id, url);
+    delegate_->UpdateTargetURL(this, url);
 }
 
 void WebContentsImpl::Close(RenderViewHost* rvh) {
@@ -3409,6 +3693,21 @@ void WebContentsImpl::SwappedOut(RenderFrameHost* rfh) {
     delegate_->SwappedOut(this);
 }
 
+void WebContentsImpl::DidDeferAfterResponseStarted(
+    const TransitionLayerData& transition_data) {
+#if defined(OS_ANDROID)
+  GetWebContentsAndroid()->DidDeferAfterResponseStarted(transition_data);
+#endif
+}
+
+bool WebContentsImpl::WillHandleDeferAfterResponseStarted() {
+#if defined(OS_ANDROID)
+  return GetWebContentsAndroid()->WillHandleDeferAfterResponseStarted();
+#else
+  return false;
+#endif
+}
+
 void WebContentsImpl::RequestMove(const gfx::Rect& new_bounds) {
   if (delegate_ && delegate_->IsPopupOrPanel(this))
     delegate_->MoveContents(this, new_bounds);
@@ -3453,11 +3752,6 @@ void WebContentsImpl::DidCancelLoading() {
   NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
 }
 
-void WebContentsImpl::DidChangeLoadProgress(double progress) {
-  if (delegate_)
-    delegate_->LoadProgressChanged(this, progress);
-}
-
 void WebContentsImpl::DidAccessInitialDocument() {
   has_accessed_initial_document_ = true;
 
@@ -3468,21 +3762,23 @@ void WebContentsImpl::DidAccessInitialDocument() {
     controller_.DiscardPendingEntry();
 
   // Update the URL display.
-  NotifyNavigationStateChanged(content::INVALIDATE_TYPE_URL);
+  NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
 }
 
 void WebContentsImpl::DidDisownOpener(RenderFrameHost* render_frame_host) {
-  if (opener_) {
-    // Clear our opener so that future cross-process navigations don't have an
-    // opener assigned.
-    RemoveDestructionObserver(opener_);
-    opener_ = NULL;
-  }
+  // No action is necessary if the opener has already been cleared.
+  if (!opener_)
+    return;
+
+  // Clear our opener so that future cross-process navigations don't have an
+  // opener assigned.
+  RemoveDestructionObserver(opener_);
+  opener_ = NULL;
 
   // Notify all swapped out RenderViewHosts for this tab.  This is important
   // in case we go back to them, or if another window in those processes tries
   // to access window.opener.
-  GetRenderManager()->DidDisownOpener(render_frame_host->GetRenderViewHost());
+  GetRenderManager()->DidDisownOpener(render_frame_host);
 }
 
 void WebContentsImpl::DocumentOnLoadCompleted(
@@ -3497,6 +3793,42 @@ void WebContentsImpl::DocumentOnLoadCompleted(
       NotificationService::NoDetails());
 }
 
+void WebContentsImpl::UpdateTitle(RenderFrameHost* render_frame_host,
+                                  int32 page_id,
+                                  const base::string16& title,
+                                  base::i18n::TextDirection title_direction) {
+  RenderViewHost* rvh = render_frame_host->GetRenderViewHost();
+
+  // If we have a title, that's a pretty good indication that we've started
+  // getting useful data.
+  SetNotWaitingForResponse();
+
+  // Try to find the navigation entry, which might not be the current one.
+  // For example, it might be from a pending RVH for the pending entry.
+  NavigationEntryImpl* entry = controller_.GetEntryWithPageID(
+      rvh->GetSiteInstance(), page_id);
+
+  // We can handle title updates when we don't have an entry in
+  // UpdateTitleForEntry, but only if the update is from the current RVH.
+  // TODO(avi): Change to make decisions based on the RenderFrameHost.
+  if (!entry && rvh != GetRenderViewHost())
+    return;
+
+  // TODO(evan): make use of title_direction.
+  // http://code.google.com/p/chromium/issues/detail?id=27094
+  if (!UpdateTitleForEntry(entry, title))
+    return;
+
+  // Broadcast notifications when the UI should be updated.
+  if (entry == controller_.GetEntryAtOffset(0))
+    NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE);
+}
+
+void WebContentsImpl::UpdateEncoding(RenderFrameHost* render_frame_host,
+                                     const std::string& encoding) {
+  SetEncoding(encoding);
+}
+
 void WebContentsImpl::DocumentAvailableInMainFrame(
     RenderViewHost* render_view_host) {
   FOR_EACH_OBSERVER(WebContentsObserver, observers_,
@@ -3584,7 +3916,7 @@ bool WebContentsImpl::AddMessageToConsole(int32 level,
                                         source_id);
 }
 
-WebPreferences WebContentsImpl::GetWebkitPrefs() {
+WebPreferences WebContentsImpl::ComputeWebkitPrefs() {
   // We want to base the page config off of the actual URL, rather than the
   // virtual URL.
   // TODO(nasko): Investigate how to remove the GetActiveEntry usage here,
@@ -3592,13 +3924,13 @@ WebPreferences WebContentsImpl::GetWebkitPrefs() {
   GURL url = controller_.GetActiveEntry()
       ? controller_.GetActiveEntry()->GetURL() : GURL::EmptyGURL();
 
-  return GetRenderManager()->current_host()->GetWebkitPrefs(url);
+  return GetRenderManager()->current_host()->ComputeWebkitPrefs(url);
 }
 
 int WebContentsImpl::CreateSwappedOutRenderView(
     SiteInstance* instance) {
-  return GetRenderManager()->CreateRenderFrame(instance, MSG_ROUTING_NONE,
-                                               true, true);
+  return GetRenderManager()->CreateRenderFrame(
+      instance, MSG_ROUTING_NONE, true, true, true);
 }
 
 void WebContentsImpl::OnUserGesture() {
@@ -3679,7 +4011,8 @@ void WebContentsImpl::LoadStateChanged(
   if (load_state_.state == net::LOAD_STATE_READING_RESPONSE)
     SetNotWaitingForResponse();
   if (IsLoading()) {
-    NotifyNavigationStateChanged(INVALIDATE_TYPE_LOAD | INVALIDATE_TYPE_TAB);
+    NotifyNavigationStateChanged(static_cast<InvalidateTypes>(
+        INVALIDATE_TYPE_LOAD | INVALIDATE_TYPE_TAB));
   }
 }
 
@@ -3717,15 +4050,21 @@ void WebContentsImpl::CancelModalDialogsForRenderManager() {
     dialog_manager_->CancelActiveAndPendingDialogs(this);
 }
 
-void WebContentsImpl::NotifySwappedFromRenderManager(RenderViewHost* old_host,
-                                                     RenderViewHost* new_host) {
-  NotifySwapped(old_host, new_host);
+void WebContentsImpl::NotifySwappedFromRenderManager(RenderFrameHost* old_host,
+                                                     RenderFrameHost* new_host,
+                                                     bool is_main_frame) {
+  if (is_main_frame) {
+    NotifyViewSwapped(old_host ? old_host->GetRenderViewHost() : NULL,
+                      new_host->GetRenderViewHost());
 
-  // Make sure the visible RVH reflects the new delegate's preferences.
-  if (delegate_)
-    view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
+    // Make sure the visible RVH reflects the new delegate's preferences.
+    if (delegate_)
+      view_->SetOverscrollControllerEnabled(CanOverscrollContent());
+
+    view_->RenderViewSwappedIn(new_host->GetRenderViewHost());
+  }
 
-  view_->RenderViewSwappedIn(new_host);
+  NotifyFrameSwapped(old_host, new_host);
 }
 
 int WebContentsImpl::CreateOpenerRenderViewsForRenderManager(
@@ -3762,8 +4101,8 @@ int WebContentsImpl::CreateOpenerRenderViews(SiteInstance* instance) {
 
   // Create a swapped out RenderView in the given SiteInstance if none exists,
   // setting its opener to the given route_id.  Return the new view's route_id.
-  return GetRenderManager()->CreateRenderFrame(instance, opener_route_id,
-                                               true, true);
+  return GetRenderManager()->CreateRenderFrame(
+      instance, opener_route_id, true, true, true);
 }
 
 NavigationControllerImpl& WebContentsImpl::GetControllerForRenderManager() {
@@ -3782,18 +4121,19 @@ NavigationEntry*
 bool WebContentsImpl::CreateRenderViewForRenderManager(
     RenderViewHost* render_view_host,
     int opener_route_id,
-    CrossProcessFrameConnector* frame_connector) {
-  TRACE_EVENT0("browser", "WebContentsImpl::CreateRenderViewForRenderManager");
+    int proxy_routing_id,
+    bool for_main_frame_navigation) {
+  TRACE_EVENT0("browser,navigation",
+               "WebContentsImpl::CreateRenderViewForRenderManager");
   // Can be NULL during tests.
   RenderWidgetHostViewBase* rwh_view;
   // TODO(kenrb): RenderWidgetHostViewChildFrame special casing is temporary
   // until RenderWidgetHost is attached to RenderFrameHost. We need to special
   // case this because RWH is still a base class of RenderViewHost, and child
   // frame RWHVs are unique in that they do not have their own WebContents.
-  if (frame_connector) {
+  if (!for_main_frame_navigation) {
     RenderWidgetHostViewChildFrame* rwh_view_child =
         new RenderWidgetHostViewChildFrame(render_view_host);
-    frame_connector->set_view(rwh_view_child);
     rwh_view = rwh_view_child;
   } else {
     rwh_view = view_->CreateViewForWidget(render_view_host);
@@ -3811,6 +4151,7 @@ bool WebContentsImpl::CreateRenderViewForRenderManager(
   if (!static_cast<RenderViewHostImpl*>(
           render_view_host)->CreateRenderView(base::string16(),
                                               opener_route_id,
+                                              proxy_routing_id,
                                               max_page_id,
                                               created_with_opener_)) {
     return false;
@@ -3828,45 +4169,57 @@ bool WebContentsImpl::CreateRenderViewForRenderManager(
   return true;
 }
 
+bool WebContentsImpl::CreateRenderFrameForRenderManager(
+    RenderFrameHost* render_frame_host,
+    int parent_routing_id) {
+  TRACE_EVENT0("browser,navigation",
+               "WebContentsImpl::CreateRenderFrameForRenderManager");
+
+  RenderFrameHostImpl* rfh =
+      static_cast<RenderFrameHostImpl*>(render_frame_host);
+  if (!rfh->CreateRenderFrame(parent_routing_id))
+    return false;
+
+  // TODO(nasko): When RenderWidgetHost is owned by RenderFrameHost, the passed
+  // RenderFrameHost will have to be associated with the appropriate
+  // RenderWidgetHostView or a new one should be created here.
+
+  return true;
+}
+
 #if defined(OS_ANDROID)
 
 base::android::ScopedJavaLocalRef<jobject>
 WebContentsImpl::GetJavaWebContents() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  return GetWebContentsAndroid()->GetJavaObject();
+}
 
+WebContentsAndroid* WebContentsImpl::GetWebContentsAndroid() {
   WebContentsAndroid* web_contents_android =
       static_cast<WebContentsAndroid*>(GetUserData(kWebContentsAndroidKey));
   if (!web_contents_android) {
     web_contents_android = new WebContentsAndroid(this);
     SetUserData(kWebContentsAndroidKey, web_contents_android);
   }
-  return web_contents_android->GetJavaObject();
+  return web_contents_android;
 }
 
 bool WebContentsImpl::CreateRenderViewForInitialEmptyDocument() {
   return CreateRenderViewForRenderManager(GetRenderViewHost(),
                                           MSG_ROUTING_NONE,
-                                          NULL);
+                                          MSG_ROUTING_NONE,
+                                          true);
 }
 
 #elif defined(OS_MACOSX)
 
-void WebContentsImpl::SetAllowOverlappingViews(bool overlapping) {
-  view_->SetAllowOverlappingViews(overlapping);
-}
-
-bool WebContentsImpl::GetAllowOverlappingViews() {
-  return view_->GetAllowOverlappingViews();
-}
-
-void WebContentsImpl::SetOverlayView(WebContents* overlay,
-                                     const gfx::Point& offset) {
-  view_->SetOverlayView(static_cast<WebContentsImpl*>(overlay)->GetView(),
-                        offset);
+void WebContentsImpl::SetAllowOtherViews(bool allow) {
+  view_->SetAllowOtherViews(allow);
 }
 
-void WebContentsImpl::RemoveOverlayView() {
-  view_->RemoveOverlayView();
+bool WebContentsImpl::GetAllowOtherViews() {
+  return view_->GetAllowOtherViews();
 }
 
 #endif
@@ -3903,7 +4256,11 @@ void WebContentsImpl::OnDialogClosed(int render_process_id,
 }
 
 void WebContentsImpl::SetEncoding(const std::string& encoding) {
-  encoding_ = GetContentClient()->browser()->
+  if (encoding == last_reported_encoding_)
+    return;
+  last_reported_encoding_ = encoding;
+
+  canonical_encoding_ = GetContentClient()->browser()->
       GetCanonicalEncodingNameByAliasName(encoding);
 }
 
@@ -3941,15 +4298,16 @@ BrowserPluginEmbedder* WebContentsImpl::GetBrowserPluginEmbedder() const {
 
 void WebContentsImpl::ClearPowerSaveBlockers(
     RenderFrameHost* render_frame_host) {
-  STLDeleteValues(&power_save_blockers_[render_frame_host]);
-  power_save_blockers_.erase(render_frame_host);
+  RemoveAllMediaPlayerEntries(render_frame_host, &active_audio_players_);
+  RemoveAllMediaPlayerEntries(render_frame_host, &active_video_players_);
+  MaybeReleasePowerSaveBlockers();
 }
 
 void WebContentsImpl::ClearAllPowerSaveBlockers() {
-  for (PowerSaveBlockerMap::iterator i(power_save_blockers_.begin());
-       i != power_save_blockers_.end(); ++i)
-    STLDeleteValues(&power_save_blockers_[i->first]);
-  power_save_blockers_.clear();
+  active_audio_players_.clear();
+  active_video_players_.clear();
+  audio_power_save_blocker_.reset();
+  video_power_save_blocker_.reset();
 }
 
 gfx::Size WebContentsImpl::GetSizeForNewRenderView() {
@@ -3961,11 +4319,9 @@ gfx::Size WebContentsImpl::GetSizeForNewRenderView() {
   return size;
 }
 
-void WebContentsImpl::OnFrameRemoved(
-    RenderViewHostImpl* render_view_host,
-    int frame_routing_id) {
-   FOR_EACH_OBSERVER(WebContentsObserver, observers_,
-                     FrameDetached(render_view_host, frame_routing_id));
+void WebContentsImpl::OnFrameRemoved(RenderFrameHost* render_frame_host) {
+  FOR_EACH_OBSERVER(
+      WebContentsObserver, observers_, FrameDetached(render_frame_host));
 }
 
 void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
@@ -3976,4 +4332,54 @@ void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
     delegate_->UpdatePreferredSize(this, new_size);
 }
 
+void WebContentsImpl::AddMediaPlayerEntry(int64 player_cookie,
+                                          ActiveMediaPlayerMap* player_map) {
+  const uintptr_t key =
+      reinterpret_cast<uintptr_t>(render_frame_message_source_);
+  DCHECK(std::find((*player_map)[key].begin(),
+                   (*player_map)[key].end(),
+                   player_cookie) == (*player_map)[key].end());
+  (*player_map)[key].push_back(player_cookie);
+}
+
+void WebContentsImpl::RemoveMediaPlayerEntry(int64 player_cookie,
+                                             ActiveMediaPlayerMap* player_map) {
+  const uintptr_t key =
+      reinterpret_cast<uintptr_t>(render_frame_message_source_);
+  ActiveMediaPlayerMap::iterator it = player_map->find(key);
+  if (it == player_map->end())
+    return;
+
+  // Remove the player.
+  PlayerList::iterator player_it =
+      std::find(it->second.begin(), it->second.end(), player_cookie);
+  if (player_it != it->second.end())
+    it->second.erase(player_it);
+
+  // If there are no players left, remove the map entry.
+  if (it->second.empty())
+    player_map->erase(it);
+}
+
+void WebContentsImpl::RemoveAllMediaPlayerEntries(
+    RenderFrameHost* render_frame_host,
+    ActiveMediaPlayerMap* player_map) {
+  ActiveMediaPlayerMap::iterator it =
+      player_map->find(reinterpret_cast<uintptr_t>(render_frame_host));
+  if (it == player_map->end())
+    return;
+  player_map->erase(it);
+}
+
+void WebContentsImpl::ResumeResponseDeferredAtStart() {
+  FrameTreeNode* node = frame_tree_.root();
+  node->render_manager()->ResumeResponseDeferredAtStart();
+}
+
+void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) {
+  force_disable_overscroll_content_ = force_disable;
+  if (view_)
+    view_->SetOverscrollControllerEnabled(CanOverscrollContent());
+}
+
 }  // namespace content