Move RenderThread to content\renderer.

TBR=avi
Review URL: http://codereview.chromium.org/6861005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81673 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 09c5ad1..44a84ff 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -87,6 +87,8 @@
         'renderer/plugin_channel_host.h',
         'renderer/render_process_observer.cc',
         'renderer/render_process_observer.h',
+        'renderer/render_thread.cc',
+        'renderer/render_thread.h',
         'renderer/render_view.cc',
         'renderer/render_view.h',
         'renderer/render_view_linux.cc',
@@ -130,10 +132,10 @@
         'renderer/renderer_webstoragenamespace_impl.h',
         'renderer/speech_input_dispatcher.cc',
         'renderer/speech_input_dispatcher.h',
-	'renderer/transport_texture_host.cc',
-	'renderer/transport_texture_host.h',
-	'renderer/transport_texture_service.cc',
-	'renderer/transport_texture_service.h',
+        'renderer/transport_texture_host.cc',
+        'renderer/transport_texture_host.h',
+        'renderer/transport_texture_service.cc',
+        'renderer/transport_texture_service.h',
         'renderer/video_decode_accelerator_host.cc',
         'renderer/video_decode_accelerator_host.h',
         'renderer/webgraphicscontext3d_command_buffer_impl.cc',
diff --git a/content/renderer/audio_device.cc b/content/renderer/audio_device.cc
index 4813e07..1940f20 100644
--- a/content/renderer/audio_device.cc
+++ b/content/renderer/audio_device.cc
@@ -6,10 +6,10 @@
 
 #include "base/memory/singleton.h"
 #include "base/message_loop.h"
-#include "chrome/renderer/render_thread.h"
 #include "content/common/audio_messages.h"
 #include "content/common/child_process.h"
 #include "content/common/view_messages.h"
+#include "content/renderer/render_thread.h"
 #include "media/audio/audio_util.h"
 
 scoped_refptr<AudioMessageFilter> AudioDevice::filter_;
diff --git a/content/renderer/audio_input_device.cc b/content/renderer/audio_input_device.cc
index f1e7815..2b565e9 100644
--- a/content/renderer/audio_input_device.cc
+++ b/content/renderer/audio_input_device.cc
@@ -6,10 +6,10 @@
 
 #include "base/memory/singleton.h"
 #include "base/message_loop.h"
-#include "chrome/renderer/render_thread.h"
 #include "content/common/audio_messages.h"
 #include "content/common/child_process.h"
 #include "content/common/view_messages.h"
+#include "content/renderer/render_thread.h"
 #include "media/audio/audio_util.h"
 
 scoped_refptr<AudioInputMessageFilter> AudioInputDevice::filter_;
diff --git a/content/renderer/command_buffer_proxy.cc b/content/renderer/command_buffer_proxy.cc
index e374386..e4d3734 100644
--- a/content/renderer/command_buffer_proxy.cc
+++ b/content/renderer/command_buffer_proxy.cc
@@ -8,11 +8,11 @@
 #include "base/process_util.h"
 #include "base/shared_memory.h"
 #include "base/task.h"
-#include "chrome/renderer/render_thread.h"
 #include "content/common/gpu_messages.h"
 #include "content/common/plugin_messages.h"
 #include "content/common/view_messages.h"
 #include "content/renderer/plugin_channel_host.h"
+#include "content/renderer/render_thread.h"
 #include "gpu/command_buffer/common/cmd_buffer_common.h"
 #include "ui/gfx/size.h"
 
diff --git a/content/renderer/gpu_channel_host.cc b/content/renderer/gpu_channel_host.cc
index 89d39bf..7630462 100644
--- a/content/renderer/gpu_channel_host.cc
+++ b/content/renderer/gpu_channel_host.cc
@@ -4,11 +4,11 @@
 
 #include "content/renderer/gpu_channel_host.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/child_process.h"
 #include "content/common/gpu_messages.h"
 #include "content/renderer/command_buffer_proxy.h"
 #include "content/renderer/gpu_video_service_host.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/transport_texture_service.h"
 #include "googleurl/src/gurl.h"
 
diff --git a/content/renderer/gpu_video_service_host.cc b/content/renderer/gpu_video_service_host.cc
index cb12ae31..c1ed5dbdd 100644
--- a/content/renderer/gpu_video_service_host.cc
+++ b/content/renderer/gpu_video_service_host.cc
@@ -4,9 +4,9 @@
 
 #include "content/renderer/gpu_video_service_host.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/renderer/gpu_video_decoder_host.h"
 #include "content/common/gpu_messages.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/video_decode_accelerator_host.h"
 #include "media/video/video_decode_accelerator.h"
 
diff --git a/content/renderer/indexed_db_dispatcher.cc b/content/renderer/indexed_db_dispatcher.cc
index 7572bdf..06c2be0 100644
--- a/content/renderer/indexed_db_dispatcher.cc
+++ b/content/renderer/indexed_db_dispatcher.cc
@@ -4,8 +4,8 @@
 
 #include "content/renderer/indexed_db_dispatcher.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/indexed_db_messages.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_view.h"
 #include "content/renderer/renderer_webidbcursor_impl.h"
 #include "content/renderer/renderer_webidbdatabase_impl.h"
diff --git a/content/renderer/media/audio_renderer_impl.cc b/content/renderer/media/audio_renderer_impl.cc
index e4730cb..87228d3 100644
--- a/content/renderer/media/audio_renderer_impl.cc
+++ b/content/renderer/media/audio_renderer_impl.cc
@@ -6,8 +6,8 @@
 
 #include <math.h>
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/audio_messages.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_view.h"
 #include "media/base/filter_host.h"
 
diff --git a/content/renderer/notification_provider.cc b/content/renderer/notification_provider.cc
index 0385e70..d1aecba 100644
--- a/content/renderer/notification_provider.cc
+++ b/content/renderer/notification_provider.cc
@@ -8,9 +8,9 @@
 #include "base/task.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/common/render_messages.h"
-#include "chrome/renderer/render_thread.h"
 #include "content/common/desktop_notification_messages.h"
 #include "content/common/view_messages.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_view.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
diff --git a/content/renderer/pepper_platform_context_3d_impl.cc b/content/renderer/pepper_platform_context_3d_impl.cc
index 5ce3bd9..fb56bb3d 100644
--- a/content/renderer/pepper_platform_context_3d_impl.cc
+++ b/content/renderer/pepper_platform_context_3d_impl.cc
@@ -4,8 +4,8 @@
 
 #include "content/renderer/pepper_platform_context_3d_impl.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/renderer/command_buffer_proxy.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/renderer_gl_context.h"
 #include "content/renderer/gpu_channel_host.h"
 #include "googleurl/src/gurl.h"
diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc
index 209351d..fda4d02 100644
--- a/content/renderer/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper_plugin_delegate_impl.cc
@@ -16,7 +16,6 @@
 #include "base/time.h"
 #include "chrome/common/pepper_plugin_registry.h"
 #include "chrome/common/render_messages.h"
-#include "chrome/renderer/render_thread.h"
 #include "content/common/audio_messages.h"
 #include "content/common/child_process_messages.h"
 #include "content/common/child_thread.h"
@@ -31,6 +30,7 @@
 #include "content/renderer/gpu_channel_host.h"
 #include "content/renderer/p2p/p2p_transport_impl.h"
 #include "content/renderer/pepper_platform_context_3d_impl.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_view.h"
 #include "content/renderer/render_widget_fullscreen_pepper.h"
 #include "content/renderer/webgraphicscontext3d_command_buffer_impl.h"
diff --git a/content/renderer/render_thread.cc b/content/renderer/render_thread.cc
new file mode 100644
index 0000000..794f1e2
--- /dev/null
+++ b/content/renderer/render_thread.cc
@@ -0,0 +1,867 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/render_thread.h"
+
+#include <algorithm>
+#include <limits>
+#include <map>
+#include <vector>
+
+#include "base/command_line.h"
+#include "base/debug/trace_event.h"
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/stats_table.h"
+#include "base/process_util.h"
+#include "base/shared_memory.h"
+#include "base/string_util.h"
+#include "base/task.h"
+#include "base/threading/thread_local.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/safe_browsing/safebrowsing_messages.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/renderer/render_process_impl.h"
+#include "content/common/appcache/appcache_dispatcher.h"
+#include "content/common/database_messages.h"
+#include "content/common/db_message_filter.h"
+#include "content/common/dom_storage_messages.h"
+#include "content/common/gpu_messages.h"
+#include "content/common/plugin_messages.h"
+#include "content/common/renderer_preferences.h"
+#include "content/common/resource_messages.h"
+#include "content/common/view_messages.h"
+#include "content/common/web_database_observer_impl.h"
+#include "content/plugin/npobject_util.h"
+#include "content/renderer/content_renderer_client.h"
+#include "content/renderer/cookie_message_filter.h"
+#include "content/renderer/gpu_channel_host.h"
+#include "content/renderer/gpu_video_service_host.h"
+#include "content/renderer/indexed_db_dispatcher.h"
+#include "content/renderer/plugin_channel_host.h"
+#include "content/renderer/render_process_observer.h"
+#include "content/renderer/render_view.h"
+#include "content/renderer/render_view_visitor.h"
+#include "content/renderer/renderer_webidbfactory_impl.h"
+#include "content/renderer/renderer_webkitclient_impl.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ipc/ipc_platform_file.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_util.h"
+#include "third_party/sqlite/sqlite3.h"
+#include "third_party/tcmalloc/chromium/src/google/malloc_extension.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebColor.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebCrossOriginPreflightResultCache.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDatabase.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFontCache.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptController.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageEventDispatcher.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+#include "v8/include/v8.h"
+#include "webkit/extensions/v8/benchmarking_extension.h"
+#include "webkit/extensions/v8/playback_extension.h"
+#include "webkit/glue/webkit_glue.h"
+
+// TODO(port)
+#if defined(OS_WIN)
+#include "content/plugin/plugin_channel.h"
+#else
+#include "base/memory/scoped_handle.h"
+#include "content/plugin/plugin_channel_base.h"
+#endif
+
+#if defined(OS_WIN)
+#include <windows.h>
+#include <objbase.h>
+#endif
+
+#if defined(OS_POSIX)
+#include "ipc/ipc_channel_posix.h"
+#endif
+
+using WebKit::WebCache;
+using WebKit::WebCrossOriginPreflightResultCache;
+using WebKit::WebFontCache;
+using WebKit::WebFrame;
+using WebKit::WebRuntimeFeatures;
+using WebKit::WebSecurityPolicy;
+using WebKit::WebScriptController;
+using WebKit::WebString;
+using WebKit::WebStorageEventDispatcher;
+using WebKit::WebView;
+
+namespace {
+static const double kInitialIdleHandlerDelayS = 1.0 /* seconds */;
+
+// Keep the global RenderThread in a TLS slot so it is impossible to access
+// incorrectly from the wrong thread.
+static base::LazyInstance<base::ThreadLocalPointer<RenderThread> > lazy_tls(
+    base::LINKER_INITIALIZED);
+
+class RenderViewContentSettingsSetter : public RenderViewVisitor {
+ public:
+  RenderViewContentSettingsSetter(const GURL& url,
+                                  const ContentSettings& content_settings)
+      : url_(url),
+        content_settings_(content_settings) {
+  }
+
+  virtual bool Visit(RenderView* render_view) {
+    if (GURL(render_view->webview()->mainFrame()->url()) == url_)
+      render_view->SetContentSettings(content_settings_);
+    return true;
+  }
+
+ private:
+  GURL url_;
+  ContentSettings content_settings_;
+
+  DISALLOW_COPY_AND_ASSIGN(RenderViewContentSettingsSetter);
+};
+
+class RenderViewZoomer : public RenderViewVisitor {
+ public:
+  RenderViewZoomer(const GURL& url, double zoom_level)
+      : zoom_level_(zoom_level) {
+    host_ = net::GetHostOrSpecFromURL(url);
+  }
+
+  virtual bool Visit(RenderView* render_view) {
+    WebView* webview = render_view->webview();  // Guaranteed non-NULL.
+
+    // Don't set zoom level for full-page plugin since they don't use the same
+    // zoom settings.
+    if (webview->mainFrame()->document().isPluginDocument())
+      return true;
+
+    if (net::GetHostOrSpecFromURL(GURL(webview->mainFrame()->url())) == host_)
+      webview->setZoomLevel(false, zoom_level_);
+    return true;
+  }
+
+ private:
+  std::string host_;
+  double zoom_level_;
+
+  DISALLOW_COPY_AND_ASSIGN(RenderViewZoomer);
+};
+
+}  // namespace
+
+// When we run plugins in process, we actually run them on the render thread,
+// which means that we need to make the render thread pump UI events.
+RenderThread::RenderThread() {
+  Init();
+}
+
+RenderThread::RenderThread(const std::string& channel_name)
+    : ChildThread(channel_name) {
+  Init();
+}
+
+void RenderThread::Init() {
+  TRACE_EVENT_BEGIN("RenderThread::Init", 0, "");
+
+#if defined(OS_MACOSX)
+  // On Mac, the select popups are rendered by the browser.
+  WebKit::WebView::setUseExternalPopupMenus(true);
+#endif
+
+  lazy_tls.Pointer()->Set(this);
+#if defined(OS_WIN)
+  // If you are running plugins in this thread you need COM active but in
+  // the normal case you don't.
+  if (RenderProcessImpl::InProcessPlugins())
+    CoInitialize(0);
+#endif
+
+  // In single process the single process is all there is.
+  is_incognito_process_ = false;
+  suspend_webkit_shared_timer_ = true;
+  notify_webkit_of_modal_loop_ = true;
+  plugin_refresh_allowed_ = true;
+  widget_count_ = 0;
+  hidden_widget_count_ = 0;
+  idle_notification_delay_in_s_ = kInitialIdleHandlerDelayS;
+  task_factory_.reset(new ScopedRunnableMethodFactory<RenderThread>(this));
+
+  appcache_dispatcher_.reset(new AppCacheDispatcher(this));
+  indexed_db_dispatcher_.reset(new IndexedDBDispatcher());
+
+  db_message_filter_ = new DBMessageFilter();
+  AddFilter(db_message_filter_.get());
+
+  cookie_message_filter_ = new CookieMessageFilter();
+  AddFilter(cookie_message_filter_.get());
+
+  content::GetContentClient()->renderer()->RenderThreadStarted();
+
+  TRACE_EVENT_END("RenderThread::Init", 0, "");
+}
+
+RenderThread::~RenderThread() {
+  FOR_EACH_OBSERVER(
+      RenderProcessObserver, observers_, OnRenderProcessShutdown());
+
+  // Wait for all databases to be closed.
+  if (web_database_observer_impl_.get())
+    web_database_observer_impl_->WaitForAllDatabasesToClose();
+
+  // Shutdown in reverse of the initialization order.
+  RemoveFilter(db_message_filter_.get());
+  db_message_filter_ = NULL;
+
+  // Shutdown the file thread if it's running.
+  if (file_thread_.get())
+    file_thread_->Stop();
+
+  if (webkit_client_.get())
+    WebKit::shutdown();
+
+  lazy_tls.Pointer()->Set(NULL);
+
+  // TODO(port)
+#if defined(OS_WIN)
+  // Clean up plugin channels before this thread goes away.
+  PluginChannelBase::CleanupChannels();
+  // Don't call COM if the renderer is in the sandbox.
+  if (RenderProcessImpl::InProcessPlugins())
+    CoUninitialize();
+#endif
+}
+
+RenderThread* RenderThread::current() {
+  return lazy_tls.Pointer()->Get();
+}
+
+int32 RenderThread::RoutingIDForCurrentContext() {
+  int32 routing_id = MSG_ROUTING_CONTROL;
+  if (v8::Context::InContext()) {
+    WebFrame* frame = WebFrame::frameForCurrentContext();
+    if (frame) {
+      RenderView* view = RenderView::FromWebView(frame->view());
+      if (view)
+        routing_id = view->routing_id();
+    }
+  } else {
+    DLOG(WARNING) << "Not called within a script context!";
+  }
+  return routing_id;
+}
+
+bool RenderThread::Send(IPC::Message* msg) {
+  // Certain synchronous messages cannot always be processed synchronously by
+  // the browser, e.g., Chrome frame communicating with the embedding browser.
+  // This could cause a complete hang of Chrome if a windowed plug-in is trying
+  // to communicate with the renderer thread since the browser's UI thread
+  // could be stuck (within a Windows API call) trying to synchronously
+  // communicate with the plug-in.  The remedy is to pump messages on this
+  // thread while the browser is processing this request. This creates an
+  // opportunity for re-entrancy into WebKit, so we need to take care to disable
+  // callbacks, timers, and pending network loads that could trigger such
+  // callbacks.
+  bool pumping_events = false, may_show_cookie_prompt = false;
+  if (msg->is_sync()) {
+    if (msg->is_caller_pumping_messages()) {
+      pumping_events = true;
+    } else {
+      // We only need to pump events for chrome frame processes as the
+      // cookie policy is controlled by the host browser (IE). If the
+      // policy is set to prompt then the host would put up UI which
+      // would require plugins if any to also pump to ensure that we
+      // don't have a deadlock.
+      if (CommandLine::ForCurrentProcess()->HasSwitch(
+              switches::kChromeFrame)) {
+        switch (msg->type()) {
+          case ViewHostMsg_GetCookies::ID:
+          case ViewHostMsg_GetRawCookies::ID:
+          case ViewHostMsg_CookiesEnabled::ID:
+          case DOMStorageHostMsg_SetItem::ID:
+          case ResourceHostMsg_SyncLoad::ID:
+          case DatabaseHostMsg_Allow::ID:
+            may_show_cookie_prompt = true;
+            pumping_events = true;
+            break;
+          default:
+            break;
+        }
+      }
+    }
+  }
+
+  bool suspend_webkit_shared_timer = true;  // default value
+  std::swap(suspend_webkit_shared_timer, suspend_webkit_shared_timer_);
+
+  bool notify_webkit_of_modal_loop = true;  // default value
+  std::swap(notify_webkit_of_modal_loop, notify_webkit_of_modal_loop_);
+
+  gfx::NativeViewId host_window = 0;
+
+  if (pumping_events) {
+    // See ViewMsg_SignalCookiePromptEvent.
+    if (may_show_cookie_prompt) {
+      static_cast<IPC::SyncMessage*>(msg)->set_pump_messages_event(
+          cookie_message_filter_->pump_messages_event());
+    }
+
+    if (suspend_webkit_shared_timer)
+      webkit_client_->SuspendSharedTimer();
+
+    if (notify_webkit_of_modal_loop)
+      WebView::willEnterModalLoop();
+
+    RenderWidget* widget =
+        static_cast<RenderWidget*>(ResolveRoute(msg->routing_id()));
+    if (widget) {
+      host_window = widget->host_window();
+      PluginChannelHost::Broadcast(
+          new PluginMsg_SignalModalDialogEvent(host_window));
+    }
+  }
+
+  bool rv = ChildThread::Send(msg);
+
+  if (pumping_events) {
+    if (host_window) {
+      PluginChannelHost::Broadcast(
+          new PluginMsg_ResetModalDialogEvent(host_window));
+    }
+
+    if (notify_webkit_of_modal_loop)
+      WebView::didExitModalLoop();
+
+    if (suspend_webkit_shared_timer)
+      webkit_client_->ResumeSharedTimer();
+
+    // We may end up nesting calls to Send, so we defer the reset until we
+    // return to the top-most message loop.
+    if (may_show_cookie_prompt &&
+        cookie_message_filter_->pump_messages_event()->IsSignaled()) {
+      MessageLoop::current()->PostNonNestableTask(FROM_HERE,
+          NewRunnableMethod(cookie_message_filter_.get(),
+                            &CookieMessageFilter::ResetPumpMessagesEvent));
+    }
+  }
+
+  return rv;
+}
+
+void RenderThread::AddRoute(int32 routing_id,
+                            IPC::Channel::Listener* listener) {
+  widget_count_++;
+  return ChildThread::AddRoute(routing_id, listener);
+}
+
+void RenderThread::RemoveRoute(int32 routing_id) {
+  widget_count_--;
+  return ChildThread::RemoveRoute(routing_id);
+}
+
+void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
+  channel()->AddFilter(filter);
+}
+
+void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
+  channel()->RemoveFilter(filter);
+}
+
+void RenderThread::WidgetHidden() {
+  DCHECK(hidden_widget_count_ < widget_count_);
+  hidden_widget_count_++;
+
+  if (!content::GetContentClient()->renderer()->
+          RunIdleHandlerWhenWidgetsHidden()) {
+    return;
+  }
+
+  if (widget_count_ && hidden_widget_count_ == widget_count_)
+    ScheduleIdleHandler(kInitialIdleHandlerDelayS);
+}
+
+void RenderThread::WidgetRestored() {
+  DCHECK_GT(hidden_widget_count_, 0);
+  hidden_widget_count_--;
+  if (!content::GetContentClient()->renderer()->
+          RunIdleHandlerWhenWidgetsHidden()) {
+    return;
+  }
+
+  idle_timer_.Stop();
+}
+
+bool RenderThread::IsIncognitoProcess() const {
+  return is_incognito_process_;
+}
+
+void RenderThread::AddObserver(RenderProcessObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void RenderThread::RemoveObserver(RenderProcessObserver* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+void RenderThread::DoNotSuspendWebKitSharedTimer() {
+  suspend_webkit_shared_timer_ = false;
+}
+
+void RenderThread::DoNotNotifyWebKitOfModalLoop() {
+  notify_webkit_of_modal_loop_ = false;
+}
+
+void RenderThread::OnSetContentSettingsForCurrentURL(
+    const GURL& url,
+    const ContentSettings& content_settings) {
+  RenderViewContentSettingsSetter setter(url, content_settings);
+  RenderView::ForEach(&setter);
+}
+
+void RenderThread::OnSetZoomLevelForCurrentURL(const GURL& url,
+                                               double zoom_level) {
+  RenderViewZoomer zoomer(url, zoom_level);
+  RenderView::ForEach(&zoomer);
+}
+
+void RenderThread::OnDOMStorageEvent(
+    const DOMStorageMsg_Event_Params& params) {
+  if (!dom_storage_event_dispatcher_.get())
+    dom_storage_event_dispatcher_.reset(WebStorageEventDispatcher::create());
+  dom_storage_event_dispatcher_->dispatchStorageEvent(params.key,
+      params.old_value, params.new_value, params.origin, params.url,
+      params.storage_type == DOM_STORAGE_LOCAL);
+}
+
+bool RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
+  ObserverListBase<RenderProcessObserver>::Iterator it(observers_);
+  RenderProcessObserver* observer;
+  while ((observer = it.GetNext()) != NULL) {
+    if (observer->OnControlMessageReceived(msg))
+      return true;
+  }
+
+  // Some messages are handled by delegates.
+  if (appcache_dispatcher_->OnMessageReceived(msg))
+    return true;
+  if (indexed_db_dispatcher_->OnMessageReceived(msg))
+    return true;
+
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)
+    IPC_MESSAGE_HANDLER(ViewMsg_SetContentSettingsForCurrentURL,
+                        OnSetContentSettingsForCurrentURL)
+    IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForCurrentURL,
+                        OnSetZoomLevelForCurrentURL)
+    IPC_MESSAGE_HANDLER(ViewMsg_SetIsIncognitoProcess, OnSetIsIncognitoProcess)
+    IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)
+    IPC_MESSAGE_HANDLER(ViewMsg_SetCSSColors, OnSetCSSColors)
+    // TODO(port): removed from render_messages_internal.h;
+    // is there a new non-windows message I should add here?
+    IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)
+    IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)
+    IPC_MESSAGE_HANDLER(ViewMsg_ClearCache, OnClearCache)
+#if defined(USE_TCMALLOC)
+    IPC_MESSAGE_HANDLER(ViewMsg_GetRendererTcmalloc, OnGetRendererTcmalloc)
+#endif
+    IPC_MESSAGE_HANDLER(ViewMsg_GetV8HeapStats, OnGetV8HeapStats)
+    IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats, OnGetCacheResourceStats)
+    IPC_MESSAGE_HANDLER(ViewMsg_PurgeMemory, OnPurgeMemory)
+    IPC_MESSAGE_HANDLER(ViewMsg_PurgePluginListCache, OnPurgePluginListCache)
+    IPC_MESSAGE_HANDLER(DOMStorageMsg_Event, OnDOMStorageEvent)
+    IPC_MESSAGE_HANDLER(GpuMsg_GpuChannelEstablished, OnGpuChannelEstablished)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+void RenderThread::OnSetNextPageID(int32 next_page_id) {
+  // This should only be called at process initialization time, so we shouldn't
+  // have to worry about thread-safety.
+  RenderView::SetNextPageID(next_page_id);
+}
+
+// Called when to register CSS Color name->system color mappings.
+// We update the colors one by one and then tell WebKit to refresh all render
+// views.
+void RenderThread::OnSetCSSColors(
+    const std::vector<CSSColors::CSSColorMapping>& colors) {
+  EnsureWebKitInitialized();
+  size_t num_colors = colors.size();
+  scoped_array<WebKit::WebColorName> color_names(
+      new WebKit::WebColorName[num_colors]);
+  scoped_array<WebKit::WebColor> web_colors(new WebKit::WebColor[num_colors]);
+  size_t i = 0;
+  for (std::vector<CSSColors::CSSColorMapping>::const_iterator it =
+          colors.begin();
+       it != colors.end();
+       ++it, ++i) {
+    color_names[i] = it->first;
+    web_colors[i] = it->second;
+  }
+  WebKit::setNamedColors(color_names.get(), web_colors.get(), num_colors);
+}
+
+void RenderThread::OnCreateNewView(const ViewMsg_New_Params& params) {
+  EnsureWebKitInitialized();
+  // When bringing in render_view, also bring in webkit's glue and jsbindings.
+  RenderView::Create(
+      this,
+      params.parent_window,
+      MSG_ROUTING_NONE,
+      params.renderer_preferences,
+      params.web_preferences,
+      new SharedRenderViewCounter(0),
+      params.view_id,
+      params.session_storage_namespace_id,
+      params.frame_name);
+}
+
+void RenderThread::OnSetCacheCapacities(size_t min_dead_capacity,
+                                        size_t max_dead_capacity,
+                                        size_t capacity) {
+  EnsureWebKitInitialized();
+  WebCache::setCapacities(
+      min_dead_capacity, max_dead_capacity, capacity);
+}
+
+void RenderThread::OnClearCache() {
+  EnsureWebKitInitialized();
+  WebCache::clear();
+}
+
+void RenderThread::OnGetCacheResourceStats() {
+  EnsureWebKitInitialized();
+  WebCache::ResourceTypeStats stats;
+  WebCache::getResourceTypeStats(&stats);
+  Send(new ViewHostMsg_ResourceTypeStats(stats));
+}
+
+#if defined(USE_TCMALLOC)
+void RenderThread::OnGetRendererTcmalloc() {
+  std::string result;
+  char buffer[1024 * 32];
+  base::ProcessId pid = base::GetCurrentProcId();
+  MallocExtension::instance()->GetStats(buffer, sizeof(buffer));
+  result.append(buffer);
+  Send(new ViewHostMsg_RendererTcmalloc(pid, result));
+}
+#endif
+
+void RenderThread::OnGetV8HeapStats() {
+  v8::HeapStatistics heap_stats;
+  v8::V8::GetHeapStatistics(&heap_stats);
+  Send(new ViewHostMsg_V8HeapStats(heap_stats.total_heap_size(),
+                                   heap_stats.used_heap_size()));
+}
+
+void RenderThread::CloseCurrentConnections() {
+  Send(new ViewHostMsg_CloseCurrentConnections());
+}
+
+void RenderThread::SetCacheMode(bool enabled) {
+  Send(new ViewHostMsg_SetCacheMode(enabled));
+}
+
+void RenderThread::ClearCache(bool preserve_ssl_host_info) {
+  int rv;
+  Send(new ViewHostMsg_ClearCache(preserve_ssl_host_info, &rv));
+}
+
+void RenderThread::ClearHostResolverCache() {
+  int rv;
+  Send(new ViewHostMsg_ClearHostResolverCache(&rv));
+}
+
+void RenderThread::ClearPredictorCache() {
+  int rv;
+  Send(new ViewHostMsg_ClearPredictorCache(&rv));
+}
+
+void RenderThread::EnableSpdy(bool enable) {
+  Send(new ViewHostMsg_EnableSpdy(enable));
+}
+
+void RenderThread::EstablishGpuChannel(
+    content::CauseForGpuLaunch cause_for_gpu_launch) {
+  if (gpu_channel_.get()) {
+    // Do nothing if we already have a GPU channel or are already
+    // establishing one.
+    if (gpu_channel_->state() == GpuChannelHost::kUnconnected ||
+        gpu_channel_->state() == GpuChannelHost::kConnected)
+      return;
+
+    // Recreate the channel if it has been lost.
+    if (gpu_channel_->state() == GpuChannelHost::kLost)
+      gpu_channel_ = NULL;
+  }
+
+  if (!gpu_channel_.get())
+    gpu_channel_ = new GpuChannelHost;
+
+  // Ask the browser for the channel name.
+  Send(new GpuHostMsg_EstablishGpuChannel(cause_for_gpu_launch));
+}
+
+GpuChannelHost* RenderThread::EstablishGpuChannelSync(
+    content::CauseForGpuLaunch cause_for_gpu_launch) {
+  EstablishGpuChannel(cause_for_gpu_launch);
+  Send(new GpuHostMsg_SynchronizeGpu());
+  return GetGpuChannel();
+}
+
+GpuChannelHost* RenderThread::GetGpuChannel() {
+  if (!gpu_channel_.get())
+    return NULL;
+
+  if (gpu_channel_->state() != GpuChannelHost::kConnected)
+    return NULL;
+
+  return gpu_channel_.get();
+}
+
+static void* CreateHistogram(
+    const char *name, int min, int max, size_t buckets) {
+  if (min <= 0)
+    min = 1;
+  base::Histogram* histogram = base::Histogram::FactoryGet(
+      name, min, max, buckets, base::Histogram::kUmaTargetedHistogramFlag);
+  return histogram;
+}
+
+static void AddHistogramSample(void* hist, int sample) {
+  base::Histogram* histogram = static_cast<base::Histogram*>(hist);
+  histogram->Add(sample);
+}
+
+void RenderThread::EnsureWebKitInitialized() {
+  if (webkit_client_.get())
+    return;
+
+  v8::V8::SetCounterFunction(base::StatsTable::FindLocation);
+  v8::V8::SetCreateHistogramFunction(CreateHistogram);
+  v8::V8::SetAddHistogramSampleFunction(AddHistogramSample);
+
+  webkit_client_.reset(new RendererWebKitClientImpl);
+  WebKit::initialize(webkit_client_.get());
+
+  WebScriptController::enableV8SingleThreadMode();
+
+  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+
+  webkit_glue::EnableWebCoreLogChannels(
+      command_line.GetSwitchValueASCII(switches::kWebCoreLogChannels));
+
+  // chrome: pages should not be accessible by normal content, and should
+  // also be unable to script anything but themselves (to help limit the damage
+  // that a corrupt chrome: page could cause).
+  WebString chrome_ui_scheme(ASCIIToUTF16(chrome::kChromeUIScheme));
+  WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(chrome_ui_scheme);
+
+  // chrome-extension: resources shouldn't trigger insecure content warnings.
+  WebString extension_scheme(ASCIIToUTF16(chrome::kExtensionScheme));
+  WebSecurityPolicy::registerURLSchemeAsSecure(extension_scheme);
+
+  if (command_line.HasSwitch(switches::kEnableBenchmarking))
+    RegisterExtension(extensions_v8::BenchmarkingExtension::Get());
+
+  if (command_line.HasSwitch(switches::kPlaybackMode) ||
+      command_line.HasSwitch(switches::kRecordMode) ||
+      command_line.HasSwitch(switches::kNoJsRandomness)) {
+    RegisterExtension(extensions_v8::PlaybackExtension::Get());
+  }
+
+  web_database_observer_impl_.reset(new WebDatabaseObserverImpl(this));
+  WebKit::WebDatabase::setObserver(web_database_observer_impl_.get());
+
+  WebRuntimeFeatures::enableMediaPlayer(
+      RenderProcess::current()->HasInitializedMediaLibrary());
+
+  WebRuntimeFeatures::enableSockets(
+      !command_line.HasSwitch(switches::kDisableWebSockets));
+
+  WebRuntimeFeatures::enableDatabase(
+      !command_line.HasSwitch(switches::kDisableDatabases));
+
+  WebRuntimeFeatures::enableDataTransferItems(
+      !command_line.HasSwitch(switches::kDisableDataTransferItems));
+
+  WebRuntimeFeatures::enableApplicationCache(
+      !command_line.HasSwitch(switches::kDisableApplicationCache));
+
+  WebRuntimeFeatures::enableNotifications(
+      !command_line.HasSwitch(switches::kDisableDesktopNotifications));
+
+  WebRuntimeFeatures::enableLocalStorage(
+      !command_line.HasSwitch(switches::kDisableLocalStorage));
+  WebRuntimeFeatures::enableSessionStorage(
+      !command_line.HasSwitch(switches::kDisableSessionStorage));
+
+  WebRuntimeFeatures::enableIndexedDatabase(
+      !command_line.HasSwitch(switches::kDisableIndexedDatabase));
+
+  WebRuntimeFeatures::enableGeolocation(
+      !command_line.HasSwitch(switches::kDisableGeolocation));
+
+  WebRuntimeFeatures::enableWebAudio(
+      command_line.HasSwitch(switches::kEnableWebAudio));
+
+  WebRuntimeFeatures::enablePushState(true);
+
+#ifdef TOUCH_UI
+  WebRuntimeFeatures::enableTouch(true);
+#else
+  // TODO(saintlou): in the future touch should always be enabled
+  WebRuntimeFeatures::enableTouch(false);
+#endif
+
+  WebRuntimeFeatures::enableDeviceMotion(
+      command_line.HasSwitch(switches::kEnableDeviceMotion));
+
+  WebRuntimeFeatures::enableDeviceOrientation(
+      !command_line.HasSwitch(switches::kDisableDeviceOrientation));
+
+  WebRuntimeFeatures::enableSpeechInput(
+      !command_line.HasSwitch(switches::kDisableSpeechInput));
+
+  WebRuntimeFeatures::enableFileSystem(
+      !command_line.HasSwitch(switches::kDisableFileSystem));
+
+  WebRuntimeFeatures::enableJavaScriptI18NAPI(
+      !command_line.HasSwitch(switches::kDisableJavaScriptI18NAPI));
+
+  FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized());
+}
+
+void RenderThread::IdleHandler() {
+#if (defined(OS_WIN) || defined(OS_LINUX)) && defined(USE_TCMALLOC)
+  MallocExtension::instance()->ReleaseFreeMemory();
+#endif
+
+  v8::V8::IdleNotification();
+
+  // Schedule next invocation.
+  // Dampen the delay using the algorithm:
+  //    delay = delay + 1 / (delay + 2)
+  // Using floor(delay) has a dampening effect such as:
+  //    1s, 1, 1, 2, 2, 2, 2, 3, 3, ...
+  // Note that idle_notification_delay_in_s_ would be reset to
+  // kInitialIdleHandlerDelayS in RenderThread::WidgetHidden.
+  ScheduleIdleHandler(idle_notification_delay_in_s_ +
+                      1.0 / (idle_notification_delay_in_s_ + 2.0));
+
+  FOR_EACH_OBSERVER(RenderProcessObserver, observers_, IdleNotification());
+}
+
+void RenderThread::ScheduleIdleHandler(double initial_delay_s) {
+  idle_notification_delay_in_s_ = initial_delay_s;
+  idle_timer_.Stop();
+  idle_timer_.Start(
+      base::TimeDelta::FromSeconds(static_cast<int64>(initial_delay_s)),
+      this, &RenderThread::IdleHandler);
+}
+
+void RenderThread::OnPurgeMemory() {
+  EnsureWebKitInitialized();
+
+  // Clear the object cache (as much as possible; some live objects cannot be
+  // freed).
+  WebCache::clear();
+
+  // Clear the font/glyph cache.
+  WebFontCache::clear();
+
+  // Clear the Cross-Origin Preflight cache.
+  WebCrossOriginPreflightResultCache::clear();
+
+  // Release all freeable memory from the SQLite process-global page cache (a
+  // low-level object which backs the Connection-specific page caches).
+  while (sqlite3_release_memory(std::numeric_limits<int>::max()) > 0) {
+  }
+
+  // Repeatedly call the V8 idle notification until it returns true ("nothing
+  // more to free").  Note that it makes more sense to do this than to implement
+  // a new "delete everything" pass because object references make it difficult
+  // to free everything possible in just one pass.
+  while (!v8::V8::IdleNotification()) {
+  }
+
+#if (defined(OS_WIN) || defined(OS_LINUX)) && defined(USE_TCMALLOC)
+  // Tell tcmalloc to release any free pages it's still holding.
+  MallocExtension::instance()->ReleaseFreeMemory();
+#endif
+}
+
+void RenderThread::OnPurgePluginListCache(bool reload_pages) {
+  EnsureWebKitInitialized();
+  // The call below will cause a GetPlugins call with refresh=true, but at this
+  // point we already know that the browser has refreshed its list, so disable
+  // refresh temporarily to prevent each renderer process causing the list to be
+  // regenerated.
+  plugin_refresh_allowed_ = false;
+  WebKit::resetPluginCache(reload_pages);
+  plugin_refresh_allowed_ = true;
+}
+
+void RenderThread::OnSetIsIncognitoProcess(bool is_incognito_process) {
+  is_incognito_process_ = is_incognito_process;
+}
+
+void RenderThread::OnGpuChannelEstablished(
+    const IPC::ChannelHandle& channel_handle,
+    base::ProcessHandle renderer_process_for_gpu,
+    const GPUInfo& gpu_info) {
+  gpu_channel_->set_gpu_info(gpu_info);
+  content::GetContentClient()->SetGpuInfo(gpu_info);
+
+  if (!channel_handle.name.empty() && renderer_process_for_gpu != 0) {
+    // Connect to the GPU process if a channel name was received.
+    gpu_channel_->Connect(channel_handle, renderer_process_for_gpu);
+  } else {
+    // Otherwise cancel the connection.
+    gpu_channel_ = NULL;
+  }
+}
+
+scoped_refptr<base::MessageLoopProxy>
+RenderThread::GetFileThreadMessageLoopProxy() {
+  DCHECK(message_loop() == MessageLoop::current());
+  if (!file_thread_.get()) {
+    file_thread_.reset(new base::Thread("Renderer::FILE"));
+    file_thread_->Start();
+  }
+  return file_thread_->message_loop_proxy();
+}
+
+bool RenderThread::AllowScriptExtension(const std::string& v8_extension_name,
+                                        const GURL& url,
+                                        int extension_group) {
+  // If we don't know about it, it was added by WebCore, so we should allow it.
+  if (v8_extensions_.find(v8_extension_name) == v8_extensions_.end())
+    return true;
+
+  ObserverListBase<RenderProcessObserver>::Iterator it(observers_);
+  RenderProcessObserver* observer;
+  while ((observer = it.GetNext()) != NULL) {
+    if (observer->AllowScriptExtension(v8_extension_name, url, extension_group))
+      return true;
+  }
+
+  return false;
+}
+
+void RenderThread::RegisterExtension(v8::Extension* extension) {
+  WebScriptController::registerExtension(extension);
+  v8_extensions_.insert(extension->name());
+}
diff --git a/content/renderer/render_thread.h b/content/renderer/render_thread.h
new file mode 100644
index 0000000..d3cb4b3
--- /dev/null
+++ b/content/renderer/render_thread.h
@@ -0,0 +1,329 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_RENDER_THREAD_H_
+#define CONTENT_RENDERER_RENDER_THREAD_H_
+#pragma once
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/observer_list.h"
+#include "base/shared_memory.h"
+#include "base/time.h"
+#include "base/timer.h"
+#include "build/build_config.h"
+#include "content/common/child_thread.h"
+#include "content/common/css_colors.h"
+#include "content/common/gpu_process_launch_causes.h"
+#include "ipc/ipc_channel_proxy.h"
+#include "ui/gfx/native_widget_types.h"
+
+class AppCacheDispatcher;
+class CookieMessageFilter;
+class DBMessageFilter;
+class FilePath;
+class GpuChannelHost;
+class IndexedDBDispatcher;
+class RendererHistogram;
+class RendererHistogramSnapshots;
+class RenderProcessObserver;
+class RendererNetPredictor;
+class RendererWebKitClientImpl;
+class SkBitmap;
+class WebDatabaseObserverImpl;
+
+struct ContentSettings;
+struct RendererPreferences;
+struct DOMStorageMsg_Event_Params;
+struct GPUInfo;
+struct ViewMsg_New_Params;
+struct WebPreferences;
+
+namespace base {
+class MessageLoopProxy;
+class Thread;
+}
+
+namespace IPC {
+struct ChannelHandle;
+}
+
+namespace WebKit {
+class WebStorageEventDispatcher;
+}
+
+namespace v8 {
+class Extension;
+}
+
+// The RenderThreadBase is the minimal interface that a RenderView/Widget
+// expects from a render thread. The interface basically abstracts a way to send
+// and receive messages.
+//
+// TODO(brettw): This has two different and opposing usage patterns which
+// make it confusing.
+//
+// In the first mode, callers call RenderThread::current() to get the one and
+// only global RenderThread (bug 10837: this should be renamed get()). Then
+// they access it. Since RenderThread is a concrete class, this can be NULL
+// during unit tests. Callers need to NULL check this every time. Some callers
+// don't happen to get called during unit tests and don't do the NULL checks,
+// which is also confusing since it's not clear if you need to or not.
+//
+// In the second mode, the abstract base class RenderThreadBase is passed to
+// RenderView and RenderWidget. Normally, this points to
+// RenderThread::current() so it's quite confusing which accessing mode should
+// be used. However, during unit testing, this class is replaced with a mock
+// to support testing functions, and is guaranteed non-NULL.
+//
+// It might be nice not to have the ::current() call and put all of the
+// functions on the abstract class so they can be mocked. However, there are
+// some standalone functions like in ChromiumBridge that are not associated
+// with a view that need to access the current thread to send messages to the
+// browser process. These need the ::current() paradigm. So instead, we should
+// probably remove the render_thread_ parameter to RenderView/Widget in
+// preference to just getting the global singleton. We can make it easier to
+// understand by moving everything to the abstract interface and saying that
+// there should never be a NULL RenderThread::current(). Tests would be
+// responsible for setting up the mock one.
+class RenderThreadBase {
+ public:
+  virtual ~RenderThreadBase() {}
+
+  virtual bool Send(IPC::Message* msg) = 0;
+
+  // Called to add or remove a listener for a particular message routing ID.
+  // These methods normally get delegated to a MessageRouter.
+  virtual void AddRoute(int32 routing_id, IPC::Channel::Listener* listener) = 0;
+  virtual void RemoveRoute(int32 routing_id) = 0;
+
+  virtual void AddFilter(IPC::ChannelProxy::MessageFilter* filter) = 0;
+  virtual void RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) = 0;
+
+  // Called by a RenderWidget when it is hidden or restored.
+  virtual void WidgetHidden() = 0;
+  virtual void WidgetRestored() = 0;
+
+  // True if this process is running in an incognito profile.
+  virtual bool IsIncognitoProcess() const = 0;
+};
+
+// The RenderThread class represents a background thread where RenderView
+// instances live.  The RenderThread supports an API that is used by its
+// consumer to talk indirectly to the RenderViews and supporting objects.
+// Likewise, it provides an API for the RenderViews to talk back to the main
+// process (i.e., their corresponding TabContents).
+//
+// Most of the communication occurs in the form of IPC messages.  They are
+// routed to the RenderThread according to the routing IDs of the messages.
+// The routing IDs correspond to RenderView instances.
+class RenderThread : public RenderThreadBase,
+                     public ChildThread {
+ public:
+  // Grabs the IPC channel name from the command line.
+  RenderThread();
+  // Constructor that's used when running in single process mode.
+  explicit RenderThread(const std::string& channel_name);
+  virtual ~RenderThread();
+
+  // Returns the one render thread for this process.  Note that this should only
+  // be accessed when running on the render thread itself
+  //
+  // TODO(brettw) this should be on the abstract base class instead of here,
+  // and return the base class' interface instead. Currently this causes
+  // problems with testing. See the comment above RenderThreadBase above.
+  static RenderThread* current();
+
+  // Returns the routing ID of the RenderWidget containing the current script
+  // execution context (corresponding to WebFrame::frameForCurrentContext).
+  static int32 RoutingIDForCurrentContext();
+
+  // Overridden from RenderThreadBase.
+  virtual bool Send(IPC::Message* msg);
+  virtual void AddRoute(int32 routing_id, IPC::Channel::Listener* listener);
+  virtual void RemoveRoute(int32 routing_id);
+  virtual void AddFilter(IPC::ChannelProxy::MessageFilter* filter);
+  virtual void RemoveFilter(IPC::ChannelProxy::MessageFilter* filter);
+  virtual void WidgetHidden();
+  virtual void WidgetRestored();
+  virtual bool IsIncognitoProcess() const;
+
+  void AddObserver(RenderProcessObserver* observer);
+  void RemoveObserver(RenderProcessObserver* observer);
+
+  // These methods modify how the next message is sent.  Normally, when sending
+  // a synchronous message that runs a nested message loop, we need to suspend
+  // callbacks into WebKit.  This involves disabling timers and deferring
+  // resource loads.  However, there are exceptions when we need to customize
+  // the behavior.
+  void DoNotSuspendWebKitSharedTimer();
+  void DoNotNotifyWebKitOfModalLoop();
+
+  AppCacheDispatcher* appcache_dispatcher() const {
+    return appcache_dispatcher_.get();
+  }
+
+  IndexedDBDispatcher* indexed_db_dispatcher() const {
+    return indexed_db_dispatcher_.get();
+  }
+
+  bool plugin_refresh_allowed() const { return plugin_refresh_allowed_; }
+
+  double idle_notification_delay_in_s() const {
+    return idle_notification_delay_in_s_;
+  }
+  void set_idle_notification_delay_in_s(double idle_notification_delay_in_s) {
+    idle_notification_delay_in_s_ = idle_notification_delay_in_s;
+  }
+
+  // Sends a message to the browser to close all connections.
+  void CloseCurrentConnections();
+
+  // Sends a message to the browser to enable or disable the disk cache.
+  void SetCacheMode(bool enabled);
+
+  // Sends a message to the browser to clear the disk cache.
+  // |preserve_ssl_host_info| is a flag indicating if the cache should purge
+  // entries related to cached SSL information.
+  void ClearCache(bool preserve_ssl_host_info);
+
+  // Sends a message to the browser to clear thed host cache.
+  void ClearHostResolverCache();
+
+  // Sends a message to the browser to clear the predictor cache.
+  void ClearPredictorCache();
+
+  // Sends a message to the browser to enable/disable spdy.
+  void EnableSpdy(bool enable);
+
+  // Asynchronously establish a channel to the GPU plugin if not previously
+  // established or if it has been lost (for example if the GPU plugin crashed).
+  // Use GetGpuChannel() to determine when the channel is ready for use.
+  void EstablishGpuChannel(content::CauseForGpuLaunch);
+
+  // Synchronously establish a channel to the GPU plugin if not previously
+  // established or if it has been lost (for example if the GPU plugin crashed).
+  // If there is a pending asynchronous request, it will be completed by the
+  // time this routine returns.
+  GpuChannelHost* EstablishGpuChannelSync(content::CauseForGpuLaunch);
+
+  // Get the GPU channel. Returns NULL if the channel is not established or
+  // has been lost.
+  GpuChannelHost* GetGpuChannel();
+
+  // Returns a MessageLoopProxy instance corresponding to the message loop
+  // of the thread on which file operations should be run. Must be called
+  // on the renderer's main thread.
+  scoped_refptr<base::MessageLoopProxy> GetFileThreadMessageLoopProxy();
+
+  // This function is called for every registered V8 extension each time a new
+  // script context is created. Returns true if the given V8 extension is
+  // allowed to run on the given URL and extension group.
+  bool AllowScriptExtension(const std::string& v8_extension_name,
+                            const GURL& url,
+                            int extension_group);
+
+  // Hack for http://crbug.com/71735.
+  // TODO(jamesr): remove once http://crbug.com/72007 is fixed.
+  RendererWebKitClientImpl* GetWebKitClientImpl() const {
+    return webkit_client_.get();
+  }
+
+  // Schedule a call to IdleHandler with the given initial delay.
+  void ScheduleIdleHandler(double initial_delay_s);
+
+  // A task we invoke periodically to assist with idle cleanup.
+  void IdleHandler();
+
+  // Registers the given V8 extension with WebKit.
+  void RegisterExtension(v8::Extension* extension);
+
+ private:
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
+
+  void Init();
+
+  void OnSetZoomLevelForCurrentURL(const GURL& url, double zoom_level);
+  void OnSetContentSettingsForCurrentURL(
+      const GURL& url, const ContentSettings& content_settings);
+  void OnDOMStorageEvent(const DOMStorageMsg_Event_Params& params);
+  void OnSetNextPageID(int32 next_page_id);
+  void OnSetIsIncognitoProcess(bool is_incognito_process);
+  void OnSetCSSColors(const std::vector<CSSColors::CSSColorMapping>& colors);
+  void OnCreateNewView(const ViewMsg_New_Params& params);
+  void OnTransferBitmap(const SkBitmap& bitmap, int resource_id);
+  void OnSetCacheCapacities(size_t min_dead_capacity,
+                            size_t max_dead_capacity,
+                            size_t capacity);
+  void OnClearCache();
+  void OnGetCacheResourceStats();
+
+  // Send tcmalloc info to browser.
+  void OnGetRendererTcmalloc();
+  void OnGetV8HeapStats();
+
+  void OnPurgeMemory();
+  void OnPurgePluginListCache(bool reload_pages);
+
+  void OnGpuChannelEstablished(const IPC::ChannelHandle& channel_handle,
+                               base::ProcessHandle renderer_process_for_gpu,
+                               const GPUInfo& gpu_info);
+
+  void OnGetAccessibilityTree();
+
+  // We initialize WebKit as late as possible.
+  void EnsureWebKitInitialized();
+
+  // These objects live solely on the render thread.
+  scoped_ptr<ScopedRunnableMethodFactory<RenderThread> > task_factory_;
+  scoped_ptr<AppCacheDispatcher> appcache_dispatcher_;
+  scoped_ptr<IndexedDBDispatcher> indexed_db_dispatcher_;
+  scoped_ptr<RendererWebKitClientImpl> webkit_client_;
+  scoped_ptr<WebKit::WebStorageEventDispatcher> dom_storage_event_dispatcher_;
+
+  // Used on the renderer and IPC threads.
+  scoped_refptr<DBMessageFilter> db_message_filter_;
+  scoped_refptr<CookieMessageFilter> cookie_message_filter_;
+
+  // Used on multiple script execution context threads.
+  scoped_ptr<WebDatabaseObserverImpl> web_database_observer_impl_;
+
+  // If true, then a GetPlugins call is allowed to rescan the disk.
+  bool plugin_refresh_allowed_;
+
+  // The count of RenderWidgets running through this thread.
+  int widget_count_;
+
+  // The count of hidden RenderWidgets running through this thread.
+  int hidden_widget_count_;
+
+  // The current value of the idle notification timer delay.
+  double idle_notification_delay_in_s_;
+
+  // True if this renderer is incognito.
+  bool is_incognito_process_;
+
+  bool suspend_webkit_shared_timer_;
+  bool notify_webkit_of_modal_loop_;
+
+  // Timer that periodically calls IdleHandler.
+  base::RepeatingTimer<RenderThread> idle_timer_;
+
+  // The channel from the renderer process to the GPU process.
+  scoped_refptr<GpuChannelHost> gpu_channel_;
+
+  // A lazily initiated thread on which file operations are run.
+  scoped_ptr<base::Thread> file_thread_;
+
+  // Map of registered v8 extensions. The key is the extension name.
+  std::set<std::string> v8_extensions_;
+
+  ObserverList<RenderProcessObserver> observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(RenderThread);
+};
+
+#endif  // CONTENT_RENDERER_RENDER_THREAD_H_
diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc
index f659173..8adbd10 100644
--- a/content/renderer/render_view.cc
+++ b/content/renderer/render_view.cc
@@ -39,7 +39,6 @@
 #include "chrome/renderer/external_host_bindings.h"
 #include "chrome/renderer/localized_error.h"
 #include "chrome/renderer/render_process.h"
-#include "chrome/renderer/render_thread.h"
 #include "chrome/renderer/searchbox.h"
 #include "chrome/renderer/visitedlink_slave.h"
 #include "content/common/appcache/appcache_dispatcher.h"
@@ -66,6 +65,7 @@
 #include "content/renderer/notification_provider.h"
 #include "content/renderer/p2p/socket_dispatcher.h"
 #include "content/renderer/plugin_channel_host.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_view_observer.h"
 #include "content/renderer/render_view_visitor.h"
 #include "content/renderer/render_widget_fullscreen_pepper.h"
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 3f3fc75..2ebb16e 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -13,8 +13,8 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/renderer/render_process.h"
-#include "chrome/renderer/render_thread.h"
 #include "content/common/view_messages.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/renderer_webkitclient_impl.h"
 #include "gpu/common/gpu_trace_event.h"
 #include "ipc/ipc_sync_message.h"
diff --git a/content/renderer/render_widget_fullscreen.cc b/content/renderer/render_widget_fullscreen.cc
index e32c4d9..c5e1b29 100644
--- a/content/renderer/render_widget_fullscreen.cc
+++ b/content/renderer/render_widget_fullscreen.cc
@@ -4,8 +4,8 @@
 
 #include "content/renderer/render_widget_fullscreen.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/view_messages.h"
+#include "content/renderer/render_thread.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebWidget.h"
 
 using WebKit::WebWidget;
diff --git a/content/renderer/render_widget_fullscreen_pepper.cc b/content/renderer/render_widget_fullscreen_pepper.cc
index b4624bd..d3e2e20 100644
--- a/content/renderer/render_widget_fullscreen_pepper.cc
+++ b/content/renderer/render_widget_fullscreen_pepper.cc
@@ -5,11 +5,11 @@
 #include "content/renderer/render_widget_fullscreen_pepper.h"
 
 #include "base/message_loop.h"
-#include "chrome/renderer/render_thread.h"
+#include "content/common/view_messages.h"
 #include "content/renderer/renderer_gl_context.h"
 #include "content/renderer/gpu_channel_host.h"
 #include "content/renderer/pepper_platform_context_3d_impl.h"
-#include "content/common/view_messages.h"
+#include "content/renderer/render_thread.h"
 #include "gpu/command_buffer/client/gles2_implementation.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
diff --git a/content/renderer/render_widget_unittest.cc b/content/renderer/render_widget_unittest.cc
index 88983dd..0998c6a 100644
--- a/content/renderer/render_widget_unittest.cc
+++ b/content/renderer/render_widget_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/memory/ref_counted.h"
 #include "chrome/renderer/mock_render_process.h"
 #include "chrome/renderer/mock_render_thread.h"
-#include "chrome/renderer/render_thread.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_widget.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupType.h"
 
diff --git a/content/renderer/renderer_gl_context.cc b/content/renderer/renderer_gl_context.cc
index e55357d..f913a3b 100644
--- a/content/renderer/renderer_gl_context.cc
+++ b/content/renderer/renderer_gl_context.cc
@@ -10,12 +10,12 @@
 #include "base/memory/singleton.h"
 #include "base/memory/weak_ptr.h"
 #include "base/shared_memory.h"
-#include "chrome/renderer/render_thread.h"
 #include "content/common/view_messages.h"
 #include "content/renderer/command_buffer_proxy.h"
 #include "content/renderer/gpu_channel_host.h"
 #include "content/renderer/gpu_video_service_host.h"
 #include "content/renderer/media/gles2_video_decode_context.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_widget.h"
 #include "content/renderer/transport_texture_host.h"
 #include "content/renderer/transport_texture_service.h"
diff --git a/content/renderer/renderer_webapplicationcachehost_impl.cc b/content/renderer/renderer_webapplicationcachehost_impl.cc
index c22d4e31..52ce5e0 100644
--- a/content/renderer/renderer_webapplicationcachehost_impl.cc
+++ b/content/renderer/renderer_webapplicationcachehost_impl.cc
@@ -5,8 +5,8 @@
 #include "content/renderer/renderer_webapplicationcachehost_impl.h"
 
 #include "chrome/common/content_settings_types.h"
-#include "chrome/renderer/render_thread.h"
 #include "content/common/view_messages.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_view.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
diff --git a/content/renderer/renderer_webcookiejar_impl.cc b/content/renderer/renderer_webcookiejar_impl.cc
index 3bbb5511..1fd573b 100644
--- a/content/renderer/renderer_webcookiejar_impl.cc
+++ b/content/renderer/renderer_webcookiejar_impl.cc
@@ -6,7 +6,7 @@
 
 #include "base/utf_string_conversions.h"
 #include "content/common/view_messages.h"
-#include "chrome/renderer/render_thread.h"
+#include "content/renderer/render_thread.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCookie.h"
 #include "webkit/glue/webcookie.h"
 
diff --git a/content/renderer/renderer_webidbcursor_impl.cc b/content/renderer/renderer_webidbcursor_impl.cc
index 1bad2376..21332e1 100644
--- a/content/renderer/renderer_webidbcursor_impl.cc
+++ b/content/renderer/renderer_webidbcursor_impl.cc
@@ -4,9 +4,9 @@
 
 #include "content/renderer/renderer_webidbcursor_impl.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/indexed_db_messages.h"
 #include "content/renderer/indexed_db_dispatcher.h"
+#include "content/renderer/render_thread.h"
 
 using WebKit::WebExceptionCode;
 using WebKit::WebIDBCallbacks;
diff --git a/content/renderer/renderer_webidbdatabase_impl.cc b/content/renderer/renderer_webidbdatabase_impl.cc
index da99ed7..1b0aed5 100644
--- a/content/renderer/renderer_webidbdatabase_impl.cc
+++ b/content/renderer/renderer_webidbdatabase_impl.cc
@@ -4,9 +4,9 @@
 
 #include "content/renderer/renderer_webidbdatabase_impl.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/indexed_db_messages.h"
 #include "content/renderer/indexed_db_dispatcher.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/renderer_webidbobjectstore_impl.h"
 #include "content/renderer/renderer_webidbtransaction_impl.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
diff --git a/content/renderer/renderer_webidbfactory_impl.cc b/content/renderer/renderer_webidbfactory_impl.cc
index a8de8e3..87b11b54 100644
--- a/content/renderer/renderer_webidbfactory_impl.cc
+++ b/content/renderer/renderer_webidbfactory_impl.cc
@@ -5,7 +5,7 @@
 #include "content/renderer/renderer_webidbfactory_impl.h"
 
 #include "chrome/common/render_messages.h"
-#include "chrome/renderer/render_thread.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/indexed_db_dispatcher.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMStringList.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
diff --git a/content/renderer/renderer_webidbindex_impl.cc b/content/renderer/renderer_webidbindex_impl.cc
index 72c0e84..10aaf180 100644
--- a/content/renderer/renderer_webidbindex_impl.cc
+++ b/content/renderer/renderer_webidbindex_impl.cc
@@ -4,9 +4,9 @@
 
 #include "content/renderer/renderer_webidbindex_impl.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/indexed_db_messages.h"
 #include "content/renderer/indexed_db_dispatcher.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/renderer_webidbtransaction_impl.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
diff --git a/content/renderer/renderer_webidbobjectstore_impl.cc b/content/renderer/renderer_webidbobjectstore_impl.cc
index af23fe5..2b6190ff 100644
--- a/content/renderer/renderer_webidbobjectstore_impl.cc
+++ b/content/renderer/renderer_webidbobjectstore_impl.cc
@@ -4,10 +4,10 @@
 
 #include "content/renderer/renderer_webidbobjectstore_impl.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/indexed_db_messages.h"
 #include "content/common/serialized_script_value.h"
 #include "content/renderer/indexed_db_dispatcher.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/renderer_webidbindex_impl.h"
 #include "content/renderer/renderer_webidbtransaction_impl.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMStringList.h"
diff --git a/content/renderer/renderer_webidbtransaction_impl.cc b/content/renderer/renderer_webidbtransaction_impl.cc
index 15a08d4..d09846d1 100644
--- a/content/renderer/renderer_webidbtransaction_impl.cc
+++ b/content/renderer/renderer_webidbtransaction_impl.cc
@@ -4,9 +4,9 @@
 
 #include "content/renderer/renderer_webidbtransaction_impl.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/indexed_db_messages.h"
 #include "content/renderer/indexed_db_dispatcher.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/renderer_webidbobjectstore_impl.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBObjectStore.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBTransactionCallbacks.h"
diff --git a/content/renderer/renderer_webkitclient_impl.cc b/content/renderer/renderer_webkitclient_impl.cc
index 46f189f..3890d39e 100644
--- a/content/renderer/renderer_webkitclient_impl.cc
+++ b/content/renderer/renderer_webkitclient_impl.cc
@@ -13,7 +13,6 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/renderer/net/renderer_net_predictor.h"
-#include "chrome/renderer/render_thread.h"
 #include "chrome/renderer/visitedlink_slave.h"
 #include "content/common/database_util.h"
 #include "content/common/file_system/webfilesystem_impl.h"
@@ -24,6 +23,7 @@
 #include "content/common/webmessageportchannel_impl.h"
 #include "content/plugin/npobject_util.h"
 #include "content/renderer/content_renderer_client.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_view.h"
 #include "content/renderer/renderer_webaudiodevice_impl.h"
 #include "content/renderer/renderer_webidbfactory_impl.h"
diff --git a/content/renderer/renderer_webstoragearea_impl.cc b/content/renderer/renderer_webstoragearea_impl.cc
index fc49eca8..6ff0a70 100644
--- a/content/renderer/renderer_webstoragearea_impl.cc
+++ b/content/renderer/renderer_webstoragearea_impl.cc
@@ -4,8 +4,8 @@
 
 #include "content/renderer/renderer_webstoragearea_impl.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/dom_storage_messages.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_view.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
diff --git a/content/renderer/renderer_webstoragenamespace_impl.cc b/content/renderer/renderer_webstoragenamespace_impl.cc
index 5edfa394..f2d718b 100644
--- a/content/renderer/renderer_webstoragenamespace_impl.cc
+++ b/content/renderer/renderer_webstoragenamespace_impl.cc
@@ -5,7 +5,7 @@
 #include "content/renderer/renderer_webstoragenamespace_impl.h"
 
 #include "chrome/common/render_messages.h"
-#include "chrome/renderer/render_thread.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/renderer_webstoragearea_impl.h"
 
 using WebKit::WebStorageArea;
diff --git a/content/renderer/webgraphicscontext3d_command_buffer_impl.cc b/content/renderer/webgraphicscontext3d_command_buffer_impl.cc
index 39e7919..7915203 100644
--- a/content/renderer/webgraphicscontext3d_command_buffer_impl.cc
+++ b/content/renderer/webgraphicscontext3d_command_buffer_impl.cc
@@ -19,8 +19,8 @@
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
 #include "chrome/common/chrome_switches.h"
-#include "chrome/renderer/render_thread.h"
 #include "content/renderer/gpu_channel_host.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_view.h"
 #include "gpu/command_buffer/common/constants.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
diff --git a/content/renderer/webplugin_delegate_proxy.cc b/content/renderer/webplugin_delegate_proxy.cc
index 01ed651..07f3cae 100644
--- a/content/renderer/webplugin_delegate_proxy.cc
+++ b/content/renderer/webplugin_delegate_proxy.cc
@@ -22,7 +22,6 @@
 #include "base/utf_string_conversions.h"
 #include "chrome/common/child_process_logging.h"
 #include "chrome/common/render_messages.h"
-#include "chrome/renderer/render_thread.h"
 #include "content/common/plugin_messages.h"
 #include "content/common/view_messages.h"
 #include "content/plugin/npobject_proxy.h"
@@ -31,6 +30,7 @@
 #include "content/renderer/command_buffer_proxy.h"
 #include "content/renderer/content_renderer_client.h"
 #include "content/renderer/plugin_channel_host.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/render_view.h"
 #include "ipc/ipc_channel_handle.h"
 #include "net/base/mime_util.h"
diff --git a/content/renderer/websharedworkerrepository_impl.cc b/content/renderer/websharedworkerrepository_impl.cc
index d0f95663..6269fa0 100644
--- a/content/renderer/websharedworkerrepository_impl.cc
+++ b/content/renderer/websharedworkerrepository_impl.cc
@@ -4,8 +4,8 @@
 
 #include "content/renderer/websharedworkerrepository_impl.h"
 
-#include "chrome/renderer/render_thread.h"
 #include "content/common/view_messages.h"
+#include "content/renderer/render_thread.h"
 #include "content/renderer/websharedworker_proxy.h"
 
 WebSharedWorkerRepositoryImpl::WebSharedWorkerRepositoryImpl() {}