From 95d291980d768c38e1f70bc041957870913e07f6 Mon Sep 17 00:00:00 2001
From: "jam@chromium.org"
 <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Fri, 30 Oct 2009 01:49:06 +0000
Subject: Get rid of MessageLoop* caching in extensions code.

BUG=25354
Review URL: http://codereview.chromium.org/345023

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30550 0039d316-1c4b-4281-b951-d872f2087c98
---
 chrome/browser/automation/automation_provider.cc   |   3 -
 chrome/browser/chrome_thread.h                     |   8 +-
 chrome/browser/download/download_manager.cc        |   1 -
 chrome/browser/extensions/crx_installer.cc         |  73 ++++++------
 chrome/browser/extensions/crx_installer.h          |  10 --
 .../extension_disabled_infobar_delegate.cc         |  13 +--
 .../extensions/extension_message_service.cc        |  21 ++--
 .../browser/extensions/extension_message_service.h |   3 -
 chrome/browser/extensions/extension_updater.cc     |  99 +++++++---------
 chrome/browser/extensions/extension_updater.h      |  15 +--
 .../extensions/extension_updater_unittest.cc       |  25 ++---
 chrome/browser/extensions/extensions_service.cc    | 125 +++++++++++----------
 chrome/browser/extensions/extensions_service.h     |  12 +-
 .../extensions/extensions_service_unittest.cc      |  19 ++--
 chrome/browser/extensions/extensions_ui.cc         |   8 +-
 chrome/browser/extensions/image_loading_tracker.cc |  29 ++---
 chrome/browser/extensions/pack_extension_job.cc    |  17 +--
 chrome/browser/extensions/pack_extension_job.h     |   4 +-
 .../extensions/sandboxed_extension_unpacker.cc     |  13 ++-
 .../extensions/sandboxed_extension_unpacker.h      |   2 +-
 chrome/browser/extensions/user_script_listener.cc  |  43 ++++---
 chrome/browser/extensions/user_script_listener.h   |   7 +-
 .../extensions/user_script_listener_unittest.cc    |  14 ++-
 chrome/browser/extensions/user_script_master.cc    |  30 +++--
 chrome/browser/extensions/user_script_master.h     |  17 +--
 .../extensions/user_script_master_unittest.cc      |  19 ++--
 chrome/browser/profile.cc                          |   6 +-
 .../renderer_host/resource_dispatcher_host.cc      |   2 +-
 chrome/browser/utility_process_host.cc             |  10 +-
 chrome/browser/utility_process_host.h              |   6 +-
 chrome/browser/utility_process_host_unittest.cc    |  14 +--
 .../browser/web_resource/web_resource_service.cc   |   8 +-
 32 files changed, 315 insertions(+), 361 deletions(-)

(limited to 'chrome')

diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index f04769f..63d2a45 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -2152,15 +2152,12 @@ void AutomationProvider::InstallExtension(const FilePath& crx_path,
                                       reply_message);
 
     const FilePath& install_dir = service->install_directory();
-    MessageLoop* io_loop = g_browser_process->file_thread()->message_loop();
-
     CrxInstaller::Start(crx_path,
                         install_dir,
                         Extension::INTERNAL,
                         "",  // no expected id
                         false,  // please do not delete crx file
                         true,  // privilege increase allowed
-                        io_loop,
                         service,
                         NULL);  // silent isntall, no UI
   } else {
diff --git a/chrome/browser/chrome_thread.h b/chrome/browser/chrome_thread.h
index c135d34..4240127 100644
--- a/chrome/browser/chrome_thread.h
+++ b/chrome/browser/chrome_thread.h
@@ -121,14 +121,14 @@ class ChromeThread : public base::Thread {
   //   unless you've specifically spun up the threads, but be mindful of it.
   static bool CurrentlyOn(ID identifier);
 
- private:
-  // Common initialization code for the constructors.
-  void Initialize();
-
   // If the current message loop is one of the known threads, returns true and
   // sets identifier to its ID.  Otherwise returns false.
   static bool GetCurrentThreadIdentifier(ID* identifier);
 
+ private:
+  // Common initialization code for the constructors.
+  void Initialize();
+
   static bool PostTaskHelper(
       ID identifier,
       const tracked_objects::Location& from_here,
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index effcf05..3ded94e 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -1252,7 +1252,6 @@ void DownloadManager::OpenChromeExtension(const FilePath& full_path,
                         "",  // no expected id
                         true,  // please delete crx on completion
                         true,  // privilege increase allowed
-                        g_browser_process->file_thread()->message_loop(),
                         service,
                         new ExtensionInstallUI(profile_));
   }
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index 359f45a..6c6259f 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -10,6 +10,7 @@
 #include "base/string_util.h"
 #include "base/task.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_thread.h"
 #include "chrome/browser/extensions/extension_file_util.h"
 #include "chrome/common/extensions/extension_error_reporter.h"
 #include "chrome/common/notification_service.h"
@@ -32,14 +33,12 @@ void CrxInstaller::Start(const FilePath& crx_path,
                          const std::string& expected_id,
                          bool delete_crx,
                          bool allow_privilege_increase,
-                         MessageLoop* file_loop,
                          ExtensionsService* frontend,
                          ExtensionInstallUI* client) {
   // Note: We don't keep a reference because this object manages its own
   // lifetime.
   new CrxInstaller(crx_path, install_directory, install_source, expected_id,
-                   delete_crx, allow_privilege_increase, file_loop, frontend,
-                   client);
+                   delete_crx, allow_privilege_increase, frontend, client);
 }
 
 CrxInstaller::CrxInstaller(const FilePath& crx_path,
@@ -48,7 +47,6 @@ CrxInstaller::CrxInstaller(const FilePath& crx_path,
                            const std::string& expected_id,
                            bool delete_crx,
                            bool allow_privilege_increase,
-                           MessageLoop* file_loop,
                            ExtensionsService* frontend,
                            ExtensionInstallUI* client)
     : crx_path_(crx_path),
@@ -57,8 +55,6 @@ CrxInstaller::CrxInstaller(const FilePath& crx_path,
       expected_id_(expected_id),
       delete_crx_(delete_crx),
       allow_privilege_increase_(allow_privilege_increase),
-      file_loop_(file_loop),
-      ui_loop_(MessageLoop::current()),
       frontend_(frontend),
       client_(client) {
 
@@ -67,8 +63,9 @@ CrxInstaller::CrxInstaller(const FilePath& crx_path,
   unpacker_ = new SandboxedExtensionUnpacker(
       crx_path, g_browser_process->resource_dispatcher_host(), this);
 
-  file_loop->PostTask(FROM_HERE, NewRunnableMethod(unpacker_,
-      &SandboxedExtensionUnpacker::Start));
+  ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      NewRunnableMethod(unpacker_, &SandboxedExtensionUnpacker::Start));
 }
 
 CrxInstaller::~CrxInstaller() {
@@ -76,25 +73,27 @@ CrxInstaller::~CrxInstaller() {
   // destructor might be called on any thread, so we post a task to the file
   // thread to make sure the delete happens there.
   if (!temp_dir_.value().empty()) {
-    file_loop_->PostTask(FROM_HERE, NewRunnableFunction(&DeleteFileHelper,
-        temp_dir_, true));  // recursive delete
+    ChromeThread::PostTask(
+        ChromeThread::FILE, FROM_HERE,
+        NewRunnableFunction(&DeleteFileHelper, temp_dir_, true));
   }
 
   if (delete_crx_) {
-    file_loop_->PostTask(FROM_HERE, NewRunnableFunction(&DeleteFileHelper,
-        crx_path_, false));  // non-recursive delete
+    ChromeThread::PostTask(
+        ChromeThread::FILE, FROM_HERE,
+        NewRunnableFunction(&DeleteFileHelper, crx_path_, false));
   }
 }
 
 void CrxInstaller::OnUnpackFailure(const std::string& error_message) {
-  DCHECK(MessageLoop::current() == file_loop_);
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
   ReportFailureFromFileThread(error_message);
 }
 
 void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir,
                                    const FilePath& extension_dir,
                                    Extension* extension) {
-  DCHECK(MessageLoop::current() == file_loop_);
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
 
   // Note: We take ownership of |extension| and |temp_dir|.
   extension_.reset(extension);
@@ -128,8 +127,9 @@ void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir,
         extension_->GetIconPath(Extension::EXTENSION_ICON_LARGE).GetFilePath();
     DecodeInstallIcon(icon_path, &install_icon_);
   }
-  ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-      &CrxInstaller::ConfirmInstall));
+  ChromeThread::PostTask(
+      ChromeThread::UI, FROM_HERE,
+      NewRunnableMethod(this, &CrxInstaller::ConfirmInstall));
 }
 
 // static
@@ -168,7 +168,7 @@ void CrxInstaller::DecodeInstallIcon(const FilePath& large_icon_path,
 }
 
 void CrxInstaller::ConfirmInstall() {
-  DCHECK(MessageLoop::current() == ui_loop_);
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
   if (frontend_->extension_prefs()->IsExtensionBlacklisted(extension_->id())) {
     LOG(INFO) << "This extension: " << extension_->id()
       << " is blacklisted. Install failed.";
@@ -185,15 +185,17 @@ void CrxInstaller::ConfirmInstall() {
     AddRef();  // balanced in ContinueInstall() and AbortInstall().
     client_->ConfirmInstall(this, extension_.get(), install_icon_.get());
   } else {
-    file_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-      &CrxInstaller::CompleteInstall));
+    ChromeThread::PostTask(
+        ChromeThread::FILE, FROM_HERE,
+        NewRunnableMethod(this, &CrxInstaller::CompleteInstall));
   }
   return;
 }
 
 void CrxInstaller::ContinueInstall() {
-  file_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-      &CrxInstaller::CompleteInstall));
+  ChromeThread::PostTask(
+        ChromeThread::FILE, FROM_HERE,
+        NewRunnableMethod(this, &CrxInstaller::CompleteInstall));
 
   Release();  // balanced in ConfirmInstall().
 }
@@ -211,7 +213,7 @@ void CrxInstaller::AbortInstall() {
 }
 
 void CrxInstaller::CompleteInstall() {
-  DCHECK(MessageLoop::current() == file_loop_);
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
 
   FilePath version_dir;
   Extension::InstallType install_type =
@@ -252,13 +254,14 @@ void CrxInstaller::CompleteInstall() {
 }
 
 void CrxInstaller::ReportFailureFromFileThread(const std::string& error) {
-  DCHECK(MessageLoop::current() == file_loop_);
-  ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-      &CrxInstaller::ReportFailureFromUIThread, error));
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+  ChromeThread::PostTask(
+      ChromeThread::UI, FROM_HERE,
+      NewRunnableMethod(this, &CrxInstaller::ReportFailureFromUIThread, error));
 }
 
 void CrxInstaller::ReportFailureFromUIThread(const std::string& error) {
-  DCHECK(MessageLoop::current() == ui_loop_);
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
 
   NotificationService* service = NotificationService::current();
   service->Notify(NotificationType::EXTENSION_INSTALL_ERROR,
@@ -277,13 +280,14 @@ void CrxInstaller::ReportFailureFromUIThread(const std::string& error) {
 }
 
 void CrxInstaller::ReportOverinstallFromFileThread() {
-  DCHECK(MessageLoop::current() == file_loop_);
-  ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-      &CrxInstaller::ReportOverinstallFromUIThread));
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+  ChromeThread::PostTask(
+      ChromeThread::UI, FROM_HERE,
+      NewRunnableMethod(this, &CrxInstaller::ReportOverinstallFromUIThread));
 }
 
 void CrxInstaller::ReportOverinstallFromUIThread() {
-  DCHECK(MessageLoop::current() == ui_loop_);
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
 
   NotificationService* service = NotificationService::current();
   service->Notify(NotificationType::EXTENSION_OVERINSTALL_ERROR,
@@ -297,13 +301,14 @@ void CrxInstaller::ReportOverinstallFromUIThread() {
 }
 
 void CrxInstaller::ReportSuccessFromFileThread() {
-  DCHECK(MessageLoop::current() == file_loop_);
-  ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-      &CrxInstaller::ReportSuccessFromUIThread));
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+  ChromeThread::PostTask(
+      ChromeThread::UI, FROM_HERE,
+      NewRunnableMethod(this, &CrxInstaller::ReportSuccessFromUIThread));
 }
 
 void CrxInstaller::ReportSuccessFromUIThread() {
-  DCHECK(MessageLoop::current() == ui_loop_);
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
 
   // If there is a client, tell the client about installation.
   if (client_.get())
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h
index 23f5cda..a0e50ef 100644
--- a/chrome/browser/extensions/crx_installer.h
+++ b/chrome/browser/extensions/crx_installer.h
@@ -8,7 +8,6 @@
 #include <string>
 
 #include "base/file_path.h"
-#include "base/message_loop.h"
 #include "base/ref_counted.h"
 #include "base/task.h"
 #include "chrome/browser/extensions/extension_install_ui.h"
@@ -48,7 +47,6 @@ class CrxInstaller :
   //               should be after unpacking, it can be specified here as a
   //               sanity check.
   //  delete_crx: Whether the crx should be deleted on completion.
-  //  file_loop: The message loop to do file IO on.
   //  frontend: The ExtensionsService to report the successfully installed
   //            extension to.
   //  client: Optional. If specified, will be used to confirm installation and
@@ -60,7 +58,6 @@ class CrxInstaller :
                     const std::string& expected_id,
                     bool delete_crx,
                     bool allow_privilege_increase,
-                    MessageLoop* file_loop,
                     ExtensionsService* frontend,
                     ExtensionInstallUI* client);
 
@@ -80,7 +77,6 @@ class CrxInstaller :
                const std::string& expected_id,
                bool delete_crx,
                bool allow_privilege_increase,
-               MessageLoop* file_loop,
                ExtensionsService* frontend,
                ExtensionInstallUI* client);
   ~CrxInstaller();
@@ -134,12 +130,6 @@ class CrxInstaller :
   // previously installed version of the extension.
   bool allow_privilege_increase_;
 
-  // The message loop to use for file IO.
-  MessageLoop* file_loop_;
-
-  // The message loop the UI is running on.
-  MessageLoop* ui_loop_;
-
   // The extension we're installing. We own this and either pass it off to
   // ExtensionsService on success, or delete it on failure.
   scoped_ptr<Extension> extension_;
diff --git a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
index 64a1534..ea8de22 100644
--- a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
+++ b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
@@ -25,8 +25,7 @@ class ExtensionDisabledDialogDelegate
   ExtensionDisabledDialogDelegate(Profile* profile,
                                   ExtensionsService* service,
                                   Extension* extension)
-        : profile_(profile), service_(service), extension_(extension),
-          ui_loop_(MessageLoop::current()) {
+        : profile_(profile), service_(service), extension_(extension) {
     AddRef();  // balanced in ContinueInstall or AbortInstall.
 
     // Do this now because we can't touch extension on the file loop.
@@ -57,13 +56,14 @@ class ExtensionDisabledDialogDelegate
     FilePath install_icon_path = install_icon_resource_.GetFilePath();
     CrxInstaller::DecodeInstallIcon(install_icon_path, &install_icon_);
     // Then we display the UI on the UI thread.
-    ui_loop_->PostTask(FROM_HERE,
-        NewRunnableMethod(this,
-                          &ExtensionDisabledDialogDelegate::ConfirmInstall));
+    ChromeThread::PostTask(
+        ChromeThread::UI, FROM_HERE,
+        NewRunnableMethod(
+            this, &ExtensionDisabledDialogDelegate::ConfirmInstall));
   }
 
   void ConfirmInstall() {
-    DCHECK(MessageLoop::current() == ui_loop_);
+    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
     ExtensionInstallUI ui(profile_);
     ui.ConfirmInstall(this, extension_, install_icon_.get());
   }
@@ -73,7 +73,6 @@ class ExtensionDisabledDialogDelegate
   Extension* extension_;
   ExtensionResource install_icon_resource_;
   scoped_ptr<SkBitmap> install_icon_;
-  MessageLoop* ui_loop_;
 };
 
 class ExtensionDisabledInfobarDelegate
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index cd011f1..92c77a8 100644
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -112,12 +112,9 @@ const char ExtensionMessageService::kDispatchEvent[] =
     "Event.dispatchJSON";
 
 ExtensionMessageService::ExtensionMessageService(Profile* profile)
-    : ui_loop_(MessageLoop::current()),
-      profile_(profile),
+    : profile_(profile),
       extension_devtools_manager_(NULL),
       next_port_id_(0) {
-  DCHECK_EQ(ui_loop_->type(), MessageLoop::TYPE_UI);
-
   registrar_.Add(this, NotificationType::RENDERER_PROCESS_TERMINATED,
                  NotificationService::AllSources());
   registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSED,
@@ -132,8 +129,6 @@ ExtensionMessageService::~ExtensionMessageService() {
 }
 
 void ExtensionMessageService::ProfileDestroyed() {
-  DCHECK_EQ(ui_loop_->type(), MessageLoop::TYPE_UI);
-
   profile_ = NULL;
 
   // We remove notifications here because our destructor might be called on
@@ -207,9 +202,10 @@ int ExtensionMessageService::OpenChannelToExtension(
 
   // Each side of the port is given his own port ID.  When they send messages,
   // we convert to the opposite port ID.  See PostMessageFromRenderer.
-  ui_loop_->PostTask(FROM_HERE,
-      NewRunnableMethod(this,
-          &ExtensionMessageService::OpenChannelToExtensionOnUIThread,
+  ChromeThread::PostTask(
+      ChromeThread::UI, FROM_HERE,
+      NewRunnableMethod(
+          this, &ExtensionMessageService::OpenChannelToExtensionOnUIThread,
           source->id(), routing_id, port2_id, source_extension_id,
           target_extension_id, channel_name));
 
@@ -230,9 +226,10 @@ int ExtensionMessageService::OpenChannelToTab(int routing_id,
 
   // Each side of the port is given his own port ID.  When they send messages,
   // we convert to the opposite port ID.  See PostMessageFromRenderer.
-  ui_loop_->PostTask(FROM_HERE,
-      NewRunnableMethod(this,
-          &ExtensionMessageService::OpenChannelToTabOnUIThread,
+  ChromeThread::PostTask(
+      ChromeThread::UI, FROM_HERE,
+      NewRunnableMethod(
+          this, &ExtensionMessageService::OpenChannelToTabOnUIThread,
           source->id(), routing_id, port2_id, tab_id, extension_id,
           channel_name));
 
diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h
index eb66bb6..0164cd2 100644
--- a/chrome/browser/extensions/extension_message_service.h
+++ b/chrome/browser/extensions/extension_message_service.h
@@ -139,9 +139,6 @@ class ExtensionMessageService
   void CloseChannelImpl(MessageChannelMap::iterator channel_iter, int port_id,
                         bool notify_other_port);
 
-  // The UI message loop, used for posting tasks.
-  MessageLoop* ui_loop_;
-
   // --- UI thread only:
 
   // Handles channel creation and notifies the destinations that a channel was
diff --git a/chrome/browser/extensions/extension_updater.cc b/chrome/browser/extensions/extension_updater.cc
index d5db3e6..a546b23 100644
--- a/chrome/browser/extensions/extension_updater.cc
+++ b/chrome/browser/extensions/extension_updater.cc
@@ -60,15 +60,11 @@ static const int kMaxUpdateFrequencySeconds = 60 * 60 * 24 * 7;  // 7 days
 class ExtensionUpdaterFileHandler
     : public base::RefCountedThreadSafe<ExtensionUpdaterFileHandler> {
  public:
-  ExtensionUpdaterFileHandler(MessageLoop* updater_loop,
-                              MessageLoop* file_io_loop)
-      : updater_loop_(updater_loop), file_io_loop_(file_io_loop) {}
-
   // Writes crx file data into a tempfile, and calls back the updater.
   void WriteTempFile(const std::string& extension_id, const std::string& data,
                      scoped_refptr<ExtensionUpdater> updater) {
     // Make sure we're running in the right thread.
-    DCHECK(MessageLoop::current() == file_io_loop_);
+    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
 
     FilePath path;
     if (!file_util::CreateTemporaryFile(&path)) {
@@ -86,47 +82,32 @@ class ExtensionUpdaterFileHandler
 
     // The ExtensionUpdater is now responsible for cleaning up the temp file
     // from disk.
-    updater_loop_->PostTask(FROM_HERE, NewRunnableMethod(
-        updater.get(), &ExtensionUpdater::OnCRXFileWritten, extension_id,
-        path));
+    ChromeThread::PostTask(
+        ChromeThread::UI, FROM_HERE,
+        NewRunnableMethod(
+            updater.get(), &ExtensionUpdater::OnCRXFileWritten, extension_id,
+            path));
   }
 
   void DeleteFile(const FilePath& path) {
-    DCHECK(MessageLoop::current() == file_io_loop_);
+    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
     if (!file_util::Delete(path, false)) {
       LOG(WARNING) << "Failed to delete temp file " << path.value();
     }
   }
-
- private:
-  // The MessageLoop we use to call back the ExtensionUpdater.
-  MessageLoop* updater_loop_;
-
-  // The MessageLoop we should be operating on for file operations.
-  MessageLoop* file_io_loop_;
 };
 
 
 ExtensionUpdater::ExtensionUpdater(ExtensionUpdateService* service,
                                    PrefService* prefs,
-                                   int frequency_seconds,
-                                   MessageLoop* file_io_loop,
-                                   MessageLoop* io_loop)
+                                   int frequency_seconds)
     : service_(service), frequency_seconds_(frequency_seconds),
-      file_io_loop_(file_io_loop), io_loop_(io_loop), prefs_(prefs),
-      file_handler_(new ExtensionUpdaterFileHandler(MessageLoop::current(),
-                                                    file_io_loop_)),
+      prefs_(prefs), file_handler_(new ExtensionUpdaterFileHandler()),
       blacklist_checks_enabled_(true) {
   Init();
 }
 
 void ExtensionUpdater::Init() {
-  // Unless we're in a unit test, expect that the file_io_loop_ is on the
-  // browser file thread.
-  if (g_browser_process->file_thread() != NULL) {
-    DCHECK(file_io_loop_ == g_browser_process->file_thread()->message_loop());
-  }
-
   DCHECK_GE(frequency_seconds_, 5);
   DCHECK(frequency_seconds_ <= kMaxUpdateFrequencySeconds);
 #ifdef NDEBUG
@@ -225,10 +206,8 @@ void ExtensionUpdater::OnURLFetchComplete(
 // Utility class to handle doing xml parsing in a sandboxed utility process.
 class SafeManifestParser : public UtilityProcessHost::Client {
  public:
-  SafeManifestParser(const std::string& xml, ExtensionUpdater* updater,
-                     MessageLoop* updater_loop, MessageLoop* io_loop)
-      : xml_(xml), updater_loop_(updater_loop), io_loop_(io_loop),
-        updater_(updater) {
+  SafeManifestParser(const std::string& xml, ExtensionUpdater* updater)
+      : xml_(xml), updater_(updater) {
   }
 
   ~SafeManifestParser() {}
@@ -236,15 +215,17 @@ class SafeManifestParser : public UtilityProcessHost::Client {
   // Posts a task over to the IO loop to start the parsing of xml_ in a
   // utility process.
   void Start() {
-    DCHECK(MessageLoop::current() == updater_loop_);
-    io_loop_->PostTask(FROM_HERE,
-        NewRunnableMethod(this, &SafeManifestParser::ParseInSandbox,
+    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+    ChromeThread::PostTask(
+        ChromeThread::IO, FROM_HERE,
+        NewRunnableMethod(
+            this, &SafeManifestParser::ParseInSandbox,
             g_browser_process->resource_dispatcher_host()));
   }
 
   // Creates the sandboxed utility process and tells it to start parsing.
   void ParseInSandbox(ResourceDispatcherHost* rdh) {
-    DCHECK(MessageLoop::current() == io_loop_);
+    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
 
     // TODO(asargent) we shouldn't need to do this branch here - instead
     // UtilityProcessHost should handle it for us. (http://crbug.com/19192)
@@ -259,18 +240,22 @@ class SafeManifestParser : public UtilityProcessHost::Client {
 
     if (use_utility_process) {
       UtilityProcessHost* host = new UtilityProcessHost(
-          rdh, this, updater_loop_);
+          rdh, this, ChromeThread::UI);
       host->StartUpdateManifestParse(xml_);
     } else {
       UpdateManifest manifest;
       if (manifest.Parse(xml_)) {
-        updater_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-            &SafeManifestParser::OnParseUpdateManifestSucceeded,
-            manifest.results()));
+        ChromeThread::PostTask(
+            ChromeThread::UI, FROM_HERE,
+            NewRunnableMethod(
+                this, &SafeManifestParser::OnParseUpdateManifestSucceeded,
+                manifest.results()));
       } else {
-        updater_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-            &SafeManifestParser::OnParseUpdateManifestFailed,
-            manifest.errors()));
+        ChromeThread::PostTask(
+            ChromeThread::UI, FROM_HERE,
+            NewRunnableMethod(
+                this, &SafeManifestParser::OnParseUpdateManifestFailed,
+                manifest.errors()));
       }
     }
   }
@@ -278,25 +263,19 @@ class SafeManifestParser : public UtilityProcessHost::Client {
   // Callback from the utility process when parsing succeeded.
   virtual void OnParseUpdateManifestSucceeded(
       const UpdateManifest::ResultList& list) {
-    DCHECK(MessageLoop::current() == updater_loop_);
+    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
     updater_->HandleManifestResults(list);
   }
 
   // Callback from the utility process when parsing failed.
   virtual void OnParseUpdateManifestFailed(const std::string& error_message) {
-    DCHECK(MessageLoop::current() == updater_loop_);
+    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
     LOG(WARNING) << "Error parsing update manifest:\n" << error_message;
   }
 
  private:
   const std::string& xml_;
 
-  // The MessageLoop we use to call back the ExtensionUpdater.
-  MessageLoop* updater_loop_;
-
-  // The MessageLoop where we create the utility process.
-  MessageLoop* io_loop_;
-
   scoped_refptr<ExtensionUpdater> updater_;
 };
 
@@ -308,8 +287,8 @@ void ExtensionUpdater::OnManifestFetchComplete(const GURL& url,
   // We want to try parsing the manifest, and if it indicates updates are
   // available, we want to fire off requests to fetch those updates.
   if (status.status() == URLRequestStatus::SUCCESS && response_code == 200) {
-    scoped_refptr<SafeManifestParser>  safe_parser =
-        new SafeManifestParser(data, this, MessageLoop::current(), io_loop_);
+    scoped_refptr<SafeManifestParser> safe_parser =
+        new SafeManifestParser(data, this);
     safe_parser->Start();
   } else {
     // TODO(asargent) Do exponential backoff here. (http://crbug.com/12546).
@@ -375,9 +354,11 @@ void ExtensionUpdater::OnCRXFetchComplete(const GURL& url,
     } else {
       // Successfully fetched - now write crx to a file so we can have the
       // ExtensionsService install it.
-      file_io_loop_->PostTask(FROM_HERE, NewRunnableMethod(
-        file_handler_.get(), &ExtensionUpdaterFileHandler::WriteTempFile,
-        current_extension_fetch_.id, data, this));
+      ChromeThread::PostTask(
+          ChromeThread::FILE, FROM_HERE,
+          NewRunnableMethod(
+              file_handler_.get(), &ExtensionUpdaterFileHandler::WriteTempFile,
+              current_extension_fetch_.id, data, this));
     }
   } else {
     // TODO(asargent) do things like exponential backoff, handling
@@ -405,8 +386,10 @@ void ExtensionUpdater::OnCRXFileWritten(const std::string& id,
 void ExtensionUpdater::OnExtensionInstallFinished(const FilePath& path,
                                                   Extension* extension) {
   // Have the file_handler_ delete the temp file on the file I/O thread.
-  file_io_loop_->PostTask(FROM_HERE, NewRunnableMethod(
-    file_handler_.get(), &ExtensionUpdaterFileHandler::DeleteFile, path));
+  ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      NewRunnableMethod(
+          file_handler_.get(), &ExtensionUpdaterFileHandler::DeleteFile, path));
 }
 
 
diff --git a/chrome/browser/extensions/extension_updater.h b/chrome/browser/extensions/extension_updater.h
index 252bfeb..ed6ab2c 100644
--- a/chrome/browser/extensions/extension_updater.h
+++ b/chrome/browser/extensions/extension_updater.h
@@ -22,7 +22,6 @@
 
 class Extension;
 class ExtensionUpdaterTest;
-class MessageLoop;
 class ExtensionUpdaterFileHandler;
 class PrefService;
 
@@ -30,9 +29,7 @@ class PrefService;
 //
 // ExtensionUpdater* updater = new ExtensionUpdater(my_extensions_service,
 //                                                  pref_service,
-//                                                  update_frequency_secs,
-//                                                  file_io_loop,
-//                                                  io_loop);
+//                                                  update_frequency_secs);
 // updater.Start();
 // ....
 // updater.Stop();
@@ -45,9 +42,7 @@ class ExtensionUpdater
   // controls how often update checks are scheduled.
   ExtensionUpdater(ExtensionUpdateService* service,
                    PrefService* prefs,
-                   int frequency_seconds,
-                   MessageLoop* file_io_loop,
-                   MessageLoop* io_loop);
+                   int frequency_seconds);
 
   virtual ~ExtensionUpdater();
 
@@ -178,12 +173,6 @@ class ExtensionUpdater
   base::OneShotTimer<ExtensionUpdater> timer_;
   int frequency_seconds_;
 
-  // The MessageLoop where we should do file I/O.
-  MessageLoop* file_io_loop_;
-
-  // The IO loop for IPC.
-  MessageLoop* io_loop_;
-
   PrefService* prefs_;
 
   scoped_refptr<ExtensionUpdaterFileHandler> file_handler_;
diff --git a/chrome/browser/extensions/extension_updater_unittest.cc b/chrome/browser/extensions/extension_updater_unittest.cc
index a74bfbd..bcb9287 100644
--- a/chrome/browser/extensions/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/extension_updater_unittest.cc
@@ -252,7 +252,7 @@ class ExtensionUpdaterTest : public testing::Test {
     URLFetcher::set_factory(&factory);
     ScopedTempPrefService prefs;
     scoped_refptr<ExtensionUpdater> updater =
-      new ExtensionUpdater(&service, prefs.get(), 60*60*24, NULL, NULL);
+        new ExtensionUpdater(&service, prefs.get(), 60*60*24);
     updater->Start();
 
     // Tell the update that it's time to do update checks.
@@ -298,7 +298,7 @@ class ExtensionUpdaterTest : public testing::Test {
     URLFetcher::set_factory(&factory);
     ScopedTempPrefService prefs;
     scoped_refptr<ExtensionUpdater> updater =
-      new ExtensionUpdater(&service, prefs.get(), 60*60*24, NULL, NULL);
+        new ExtensionUpdater(&service, prefs.get(), 60*60*24);
     updater->Start();
 
     // Tell the updater that it's time to do update checks.
@@ -341,8 +341,7 @@ class ExtensionUpdaterTest : public testing::Test {
     MessageLoop message_loop;
     ScopedTempPrefService prefs;
     scoped_refptr<ExtensionUpdater> updater =
-      new ExtensionUpdater(&service, prefs.get(), kUpdateFrequencySecs,
-                           NULL, NULL);
+        new ExtensionUpdater(&service, prefs.get(), kUpdateFrequencySecs);
 
     // Check passing an empty list of parse results to DetermineUpdates
     std::vector<UpdateManifest::Result> updates;
@@ -366,6 +365,7 @@ class ExtensionUpdaterTest : public testing::Test {
 
   static void TestMultipleManifestDownloading() {
     MessageLoop ui_loop;
+    ChromeThread ui_thread(ChromeThread::UI, &ui_loop);
     ChromeThread file_thread(ChromeThread::FILE);
     file_thread.Start();
     ChromeThread io_thread(ChromeThread::IO);
@@ -377,9 +377,7 @@ class ExtensionUpdaterTest : public testing::Test {
     ServiceForDownloadTests service;
     ScopedTempPrefService prefs;
     scoped_refptr<ExtensionUpdater> updater =
-      new ExtensionUpdater(&service, prefs.get(), kUpdateFrequencySecs,
-                           file_thread.message_loop(),
-                           io_thread.message_loop());
+        new ExtensionUpdater(&service, prefs.get(), kUpdateFrequencySecs);
 
     GURL url1("http://localhost/manifest1");
     GURL url2("http://localhost/manifest2");
@@ -427,6 +425,7 @@ class ExtensionUpdaterTest : public testing::Test {
 
   static void TestSingleExtensionDownloading() {
     MessageLoop ui_loop;
+    ChromeThread ui_thread(ChromeThread::UI, &ui_loop);
     ChromeThread file_thread(ChromeThread::FILE);
     file_thread.Start();
     ChromeThread io_thread(ChromeThread::IO);
@@ -438,8 +437,7 @@ class ExtensionUpdaterTest : public testing::Test {
     ServiceForDownloadTests service;
     ScopedTempPrefService prefs;
     scoped_refptr<ExtensionUpdater> updater =
-      new ExtensionUpdater(&service, prefs.get(), kUpdateFrequencySecs,
-                           file_thread.message_loop(), NULL);
+        new ExtensionUpdater(&service, prefs.get(), kUpdateFrequencySecs);
 
     GURL test_url("http://localhost/extension.crx");
 
@@ -476,6 +474,7 @@ class ExtensionUpdaterTest : public testing::Test {
 
   static void TestBlacklistDownloading() {
     MessageLoop message_loop;
+    ChromeThread ui_thread(ChromeThread::UI, &message_loop);
     ChromeThread io_thread(ChromeThread::IO);
     io_thread.Start();
 
@@ -485,8 +484,7 @@ class ExtensionUpdaterTest : public testing::Test {
     ServiceForBlacklistTests service;
     ScopedTempPrefService prefs;
     scoped_refptr<ExtensionUpdater> updater =
-      new ExtensionUpdater(&service, prefs.get(), kUpdateFrequencySecs,
-                           NULL, NULL);
+        new ExtensionUpdater(&service, prefs.get(), kUpdateFrequencySecs);
     prefs.get()->
       RegisterStringPref(prefs::kExtensionBlacklistUpdateVersion, L"0");
     GURL test_url("http://localhost/extension.crx");
@@ -523,6 +521,8 @@ class ExtensionUpdaterTest : public testing::Test {
 
   static void TestMultipleExtensionDownloading() {
     MessageLoopForUI message_loop;
+    ChromeThread ui_thread(ChromeThread::UI, &message_loop);
+    ChromeThread file_thread(ChromeThread::FILE, &message_loop);
     ChromeThread io_thread(ChromeThread::IO);
     io_thread.Start();
 
@@ -532,8 +532,7 @@ class ExtensionUpdaterTest : public testing::Test {
     ServiceForDownloadTests service;
     ScopedTempPrefService prefs;
     scoped_refptr<ExtensionUpdater> updater =
-      new ExtensionUpdater(&service, prefs.get(), kUpdateFrequencySecs,
-                           &message_loop, NULL);
+        new ExtensionUpdater(&service, prefs.get(), kUpdateFrequencySecs);
 
     GURL url1("http://localhost/extension1.crx");
     GURL url2("http://localhost/extension2.crx");
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 0234ec5..9ff30a3 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -82,12 +82,9 @@ ExtensionsService::ExtensionsService(Profile* profile,
                                      const CommandLine* command_line,
                                      PrefService* prefs,
                                      const FilePath& install_directory,
-                                     MessageLoop* frontend_loop,
-                                     MessageLoop* backend_loop,
                                      bool autoupdate_enabled)
     : profile_(profile),
       extension_prefs_(new ExtensionPrefs(prefs, install_directory)),
-      backend_loop_(backend_loop),
       install_directory_(install_directory),
       extensions_enabled_(true),
       show_extensions_prompts_(true),
@@ -106,11 +103,10 @@ ExtensionsService::ExtensionsService(Profile* profile,
       update_frequency = StringToInt(WideToASCII(command_line->GetSwitchValue(
           switches::kExtensionsUpdateFrequency)));
     }
-    updater_ = new ExtensionUpdater(this, prefs, update_frequency,
-        backend_loop_, g_browser_process->io_thread()->message_loop());
+    updater_ = new ExtensionUpdater(this, prefs, update_frequency);
   }
 
-  backend_ = new ExtensionsServiceBackend(install_directory_, frontend_loop);
+  backend_ = new ExtensionsServiceBackend(install_directory_);
 }
 
 ExtensionsService::~ExtensionsService() {
@@ -143,7 +139,6 @@ void ExtensionsService::InstallExtension(const FilePath& extension_path) {
                       "",   // no expected id
                       false,  // don't delete crx when complete
                       true,  // allow privilege increase
-                      backend_loop_,
                       this,
                       NULL);  // no client (silent install)
 }
@@ -160,7 +155,6 @@ void ExtensionsService::UpdateExtension(const std::string& id,
                       id,
                       true,  // delete crx when complete
                       false,  // do not allow upgrade of privileges
-                      backend_loop_,
                       this,
                       NULL);  // no client (silent install)
 }
@@ -196,9 +190,11 @@ void ExtensionsService::UninstallExtension(const std::string& extension_id,
 
   // Tell the backend to start deleting installed extensions on the file thread.
   if (Extension::LOAD != extension->location()) {
-    backend_loop_->PostTask(FROM_HERE, NewRunnableFunction(
-      &extension_file_util::UninstallExtension, extension_id,
-      install_directory_));
+    ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      NewRunnableFunction(
+          &extension_file_util::UninstallExtension, extension_id,
+          install_directory_));
   }
 
   ExtensionDOMUI::UnregisterChromeURLOverrides(profile_,
@@ -256,9 +252,12 @@ void ExtensionsService::DisableExtension(const std::string& extension_id) {
 }
 
 void ExtensionsService::LoadExtension(const FilePath& extension_path) {
-  backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(),
-      &ExtensionsServiceBackend::LoadSingleExtension,
-      extension_path, scoped_refptr<ExtensionsService>(this)));
+  ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      NewRunnableMethod(
+          backend_.get(),
+          &ExtensionsServiceBackend::LoadSingleExtension,
+          extension_path, scoped_refptr<ExtensionsService>(this)));
 }
 
 void ExtensionsService::LoadAllExtensions() {
@@ -297,9 +296,12 @@ void ExtensionsService::LoadInstalledExtension(
 
   if (location == Extension::EXTERNAL_PREF ||
       location == Extension::EXTERNAL_REGISTRY) {
-    backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(),
-        &ExtensionsServiceBackend::CheckExternalUninstall,
-        scoped_refptr<ExtensionsService>(this), id, location));
+    ChromeThread::PostTask(
+        ChromeThread::FILE, FROM_HERE,
+        NewRunnableMethod(
+            backend_.get(),
+            &ExtensionsServiceBackend::CheckExternalUninstall,
+            scoped_refptr<ExtensionsService>(this), id, location));
   }
 }
 
@@ -315,11 +317,13 @@ void ExtensionsService::NotifyExtensionLoaded(Extension* extension) {
         static_cast<ChromeURLRequestContextGetter*>(
             profile_->GetRequestContext());
     if (context_getter) {
-      g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
-          NewRunnableMethod(context_getter,
-                            &ChromeURLRequestContextGetter::OnNewExtensions,
-                            extension->id(),
-                            extension->path()));
+      ChromeThread::PostTask(
+          ChromeThread::IO, FROM_HERE,
+          NewRunnableMethod(
+              context_getter,
+              &ChromeURLRequestContextGetter::OnNewExtensions,
+              extension->id(),
+              extension->path()));
     }
   }
 
@@ -342,7 +346,8 @@ void ExtensionsService::NotifyExtensionUnloaded(Extension* extension) {
         static_cast<ChromeURLRequestContextGetter*>(
             profile_->GetRequestContext());
     if (context_getter) {
-      g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
+      ChromeThread::PostTask(
+          ChromeThread::IO, FROM_HERE,
           NewRunnableMethod(
               context_getter,
               &ChromeURLRequestContextGetter::OnUnloadedExtension,
@@ -384,10 +389,11 @@ void ExtensionsService::CheckForExternalUpdates() {
   // later?
   std::set<std::string> killed_extensions;
   extension_prefs_->GetKilledExtensionIds(&killed_extensions);
-  backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(),
-      &ExtensionsServiceBackend::CheckForExternalUpdates,
-      killed_extensions,
-      scoped_refptr<ExtensionsService>(this)));
+  ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      NewRunnableMethod(
+          backend_.get(), &ExtensionsServiceBackend::CheckForExternalUpdates,
+          killed_extensions, scoped_refptr<ExtensionsService>(this)));
 }
 
 void ExtensionsService::UnloadExtension(const std::string& extension_id) {
@@ -439,9 +445,11 @@ void ExtensionsService::ReloadExtensions() {
 void ExtensionsService::GarbageCollectExtensions() {
   InstalledExtensionSet installed(
       new InstalledExtensions(extension_prefs_.get()));
-  backend_loop_->PostTask(FROM_HERE, NewRunnableFunction(
-      &extension_file_util::GarbageCollectExtensions, install_directory_,
-      installed.extensions()));
+  ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      NewRunnableFunction(
+          &extension_file_util::GarbageCollectExtensions, install_directory_,
+          installed.extensions()));
 }
 
 void ExtensionsService::OnLoadedInstalledExtensions() {
@@ -601,15 +609,19 @@ Extension* ExtensionsService::GetExtensionByURL(const GURL& url) {
 }
 
 void ExtensionsService::ClearProvidersForTesting() {
-  backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(),
-      &ExtensionsServiceBackend::ClearProvidersForTesting));
+  ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      NewRunnableMethod(
+          backend_.get(), &ExtensionsServiceBackend::ClearProvidersForTesting));
 }
 
 void ExtensionsService::SetProviderForTesting(
     Extension::Location location, ExternalExtensionProvider* test_provider) {
-  backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(),
-      &ExtensionsServiceBackend::SetProviderForTesting,
-      location, test_provider));
+  ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      NewRunnableMethod(
+          backend_.get(), &ExtensionsServiceBackend::SetProviderForTesting,
+          location, test_provider));
 }
 
 void ExtensionsService::OnExternalExtensionFound(const std::string& id,
@@ -639,7 +651,6 @@ void ExtensionsService::OnExternalExtensionFound(const std::string& id,
   CrxInstaller::Start(path, install_directory_, location, id,
                       false,  // don't delete crx when complete
                       true,  // allow privilege increase
-                      backend_loop_,
                       this,
                       NULL);  // no client (silent install)
 }
@@ -664,11 +675,10 @@ void ExtensionsService::ReportExtensionLoadError(
 // ExtensionsServicesBackend
 
 ExtensionsServiceBackend::ExtensionsServiceBackend(
-    const FilePath& install_directory, MessageLoop* frontend_loop)
+    const FilePath& install_directory)
         : frontend_(NULL),
           install_directory_(install_directory),
-          alert_on_error_(false),
-          frontend_loop_(frontend_loop) {
+          alert_on_error_(false) {
   // TODO(aa): This ends up doing blocking IO on the UI thread because it reads
   // pref data in the ctor and that is called on the UI thread. Would be better
   // to re-read data each time we list external extensions, anyway.
@@ -715,25 +725,19 @@ void ExtensionsServiceBackend::LoadSingleExtension(
 
 void ExtensionsServiceBackend::ReportExtensionLoadError(
     const FilePath& extension_path, const std::string &error) {
-  // In the unit tests, frontend_loop_ may be null.
-  if (frontend_loop_ == NULL) {
-    frontend_->ReportExtensionLoadError(
-        extension_path,
-        error,
-        NotificationType::EXTENSION_INSTALL_ERROR,
-        alert_on_error_);
-    return;
-  }
-
-  frontend_loop_->PostTask(FROM_HERE,
-      NewRunnableMethod(frontend_,
+  ChromeThread::PostTask(
+      ChromeThread::UI, FROM_HERE,
+      NewRunnableMethod(
+          frontend_,
           &ExtensionsService::ReportExtensionLoadError, extension_path,
           error, NotificationType::EXTENSION_INSTALL_ERROR, alert_on_error_));
 }
 
 void ExtensionsServiceBackend::ReportExtensionLoaded(Extension* extension) {
-  frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(
-      frontend_, &ExtensionsService::OnExtensionLoaded, extension, true));
+  ChromeThread::PostTask(
+      ChromeThread::UI, FROM_HERE,
+      NewRunnableMethod(
+          frontend_, &ExtensionsService::OnExtensionLoaded, extension, true));
 }
 
 bool ExtensionsServiceBackend::LookupExternalExtension(
@@ -795,9 +799,10 @@ void ExtensionsServiceBackend::CheckExternalUninstall(
     return;  // Yup, known extension, don't uninstall.
 
   // This is an external extension that we don't have registered.  Uninstall.
-  frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(
-      frontend.get(), &ExtensionsService::UninstallExtension,
-      id, true));
+  ChromeThread::PostTask(
+      ChromeThread::UI, FROM_HERE,
+      NewRunnableMethod(
+          frontend.get(), &ExtensionsService::UninstallExtension, id, true));
 }
 
 void ExtensionsServiceBackend::ClearProvidersForTesting() {
@@ -815,7 +820,9 @@ void ExtensionsServiceBackend::SetProviderForTesting(
 void ExtensionsServiceBackend::OnExternalExtensionFound(
     const std::string& id, const Version* version, const FilePath& path,
     Extension::Location location) {
-  frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(frontend_,
-      &ExtensionsService::OnExternalExtensionFound, id, version->GetString(),
-      path, location));
+  ChromeThread::PostTask(
+      ChromeThread::UI, FROM_HERE,
+      NewRunnableMethod(
+          frontend_, &ExtensionsService::OnExternalExtensionFound, id,
+          version->GetString(), path, location));
 }
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index ecd670d..6d525d7 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -29,7 +29,6 @@ class Extension;
 class ExtensionsServiceBackend;
 class ExtensionUpdater;
 class GURL;
-class MessageLoop;
 class PrefService;
 class Profile;
 class ResourceDispatcherHost;
@@ -81,8 +80,6 @@ class ExtensionsService
                     const CommandLine* command_line,
                     PrefService* prefs,
                     const FilePath& install_directory,
-                    MessageLoop* frontend_loop,
-                    MessageLoop* backend_loop,
                     bool autoupdate_enabled);
   virtual ~ExtensionsService();
 
@@ -247,9 +244,6 @@ class ExtensionsService
   // Preferences for the owning profile.
   scoped_ptr<ExtensionPrefs> extension_prefs_;
 
-  // The message loop to use with the backend.
-  MessageLoop* backend_loop_;
-
   // The current list of installed extensions.
   ExtensionList extensions_;
 
@@ -286,8 +280,7 @@ class ExtensionsServiceBackend
   // |rdh| can be NULL in the case of test environment.
   // |extension_prefs| contains a dictionary value that points to the extension
   // preferences.
-  ExtensionsServiceBackend(const FilePath& install_directory,
-                           MessageLoop* frontend_loop);
+  ExtensionsServiceBackend(const FilePath& install_directory);
 
   virtual ~ExtensionsServiceBackend();
 
@@ -366,9 +359,6 @@ class ExtensionsServiceBackend
   // Whether errors result in noisy alerts.
   bool alert_on_error_;
 
-  // The message loop to use to call the frontend.
-  MessageLoop* frontend_loop_;
-
   // A map of all external extension providers.
   typedef std::map<Extension::Location,
                    linked_ptr<ExternalExtensionProvider> > ProviderMap;
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index 8cd1af2..f31a298 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -194,7 +194,10 @@ class MockProviderVisitor : public ExternalExtensionProvider::Visitor {
 class ExtensionsServiceTest
   : public testing::Test, public NotificationObserver {
  public:
-  ExtensionsServiceTest() : installed_(NULL) {
+  ExtensionsServiceTest()
+      : ui_thread_(ChromeThread::UI, &loop_),
+        file_thread_(ChromeThread::FILE, &loop_),
+        installed_(NULL) {
     registrar_.Add(this, NotificationType::EXTENSION_LOADED,
                    NotificationService::AllSources());
     registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
@@ -213,8 +216,6 @@ class ExtensionsServiceTest
                                      CommandLine::ForCurrentProcess(),
                                      prefs_.get(),
                                      extensions_install_dir,
-                                     &loop_,
-                                     &loop_,
                                      false);
     service_->set_extensions_enabled(true);
     service_->set_show_extensions_prompts(false);
@@ -468,6 +469,8 @@ class ExtensionsServiceTest
   scoped_refptr<ExtensionsService> service_;
   size_t total_successes_;
   MessageLoop loop_;
+  ChromeThread ui_thread_;
+  ChromeThread file_thread_;
   ExtensionList loaded_;
   std::string unloaded_id_;
   Extension* installed_;
@@ -1527,6 +1530,8 @@ TEST(ExtensionsServiceTestSimple, Enabledness) {
   ExtensionsReadyRecorder recorder;
   TestingProfile profile;
   MessageLoop loop;
+  ChromeThread ui_thread(ChromeThread::UI, &loop);
+  ChromeThread file_thread(ChromeThread::FILE, &loop);
   scoped_ptr<CommandLine> command_line;
   scoped_refptr<ExtensionsService> service;
   FilePath install_dir = profile.GetPath()
@@ -1535,7 +1540,7 @@ TEST(ExtensionsServiceTestSimple, Enabledness) {
   // By default, we are enabled.
   command_line.reset(new CommandLine(CommandLine::ARGUMENTS_ONLY));
   service = new ExtensionsService(&profile, command_line.get(),
-      profile.GetPrefs(), install_dir, &loop, &loop, false);
+      profile.GetPrefs(), install_dir, false);
   EXPECT_TRUE(service->extensions_enabled());
   service->Init();
   loop.RunAllPending();
@@ -1545,7 +1550,7 @@ TEST(ExtensionsServiceTestSimple, Enabledness) {
   recorder.set_ready(false);
   command_line->AppendSwitch(switches::kDisableExtensions);
   service = new ExtensionsService(&profile, command_line.get(),
-      profile.GetPrefs(), install_dir, &loop, &loop, false);
+      profile.GetPrefs(), install_dir, false);
   EXPECT_FALSE(service->extensions_enabled());
   service->Init();
   loop.RunAllPending();
@@ -1554,7 +1559,7 @@ TEST(ExtensionsServiceTestSimple, Enabledness) {
   recorder.set_ready(false);
   profile.GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
   service = new ExtensionsService(&profile, command_line.get(),
-      profile.GetPrefs(), install_dir, &loop, &loop, false);
+      profile.GetPrefs(), install_dir, false);
   EXPECT_FALSE(service->extensions_enabled());
   service->Init();
   loop.RunAllPending();
@@ -1563,7 +1568,7 @@ TEST(ExtensionsServiceTestSimple, Enabledness) {
   recorder.set_ready(false);
   command_line.reset(new CommandLine(CommandLine::ARGUMENTS_ONLY));
   service = new ExtensionsService(&profile, command_line.get(),
-      profile.GetPrefs(), install_dir, &loop, &loop, false);
+      profile.GetPrefs(), install_dir, false);
   EXPECT_FALSE(service->extensions_enabled());
   service->Init();
   loop.RunAllPending();
diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc
index ea036a7..7ca742e 100644
--- a/chrome/browser/extensions/extensions_ui.cc
+++ b/chrome/browser/extensions/extensions_ui.cc
@@ -555,9 +555,11 @@ ExtensionsUI::ExtensionsUI(TabContents* contents) : DOMUI(contents) {
   ExtensionsUIHTMLSource* html_source = new ExtensionsUIHTMLSource();
 
   // Set up the chrome://extensions/ source.
-  g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
-      NewRunnableMethod(&chrome_url_data_manager,
-          &ChromeURLDataManager::AddDataSource, html_source));
+  ChromeThread::PostTask(
+      ChromeThread::IO, FROM_HERE,
+      NewRunnableMethod(
+          &chrome_url_data_manager, &ChromeURLDataManager::AddDataSource,
+          html_source));
 }
 
 // static
diff --git a/chrome/browser/extensions/image_loading_tracker.cc b/chrome/browser/extensions/image_loading_tracker.cc
index 10bbea3..8f2541c 100644
--- a/chrome/browser/extensions/image_loading_tracker.cc
+++ b/chrome/browser/extensions/image_loading_tracker.cc
@@ -11,7 +11,7 @@
 #include "base/scoped_ptr.h"
 #include "base/task.h"
 #include "base/thread.h"
-#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_thread.h"
 #include "chrome/common/extensions/extension_resource.h"
 #include "skia/ext/image_operations.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -22,7 +22,7 @@
 
 // The LoadImageTask is for asynchronously loading the image on the file thread.
 // If the image is successfully loaded and decoded it will report back on the
-// |callback_loop| to let the caller know the image is done loading.
+// calling thread to let the caller know the image is done loading.
 class ImageLoadingTracker::LoadImageTask : public Task {
  public:
   // Constructor for the LoadImageTask class. |tracker| is the object that
@@ -35,17 +35,18 @@ class ImageLoadingTracker::LoadImageTask : public Task {
                 const ExtensionResource& resource,
                 const gfx::Size& max_size,
                 size_t index)
-    : callback_loop_(MessageLoop::current()),
-      tracker_(tracker),
+    : tracker_(tracker),
       resource_(resource),
       max_size_(max_size),
-      index_(index) {}
+      index_(index) {
+    CHECK(ChromeThread::GetCurrentThreadIdentifier(&callback_thread_id_));
+  }
 
   void ReportBack(SkBitmap* image) {
-    callback_loop_->PostTask(FROM_HERE, NewRunnableMethod(tracker_,
-        &ImageLoadingTracker::OnImageLoaded,
-        image,
-        index_));
+    ChromeThread::PostTask(
+        callback_thread_id_, FROM_HERE,
+        NewRunnableMethod(
+            tracker_, &ImageLoadingTracker::OnImageLoaded, image, index_));
   }
 
   virtual void Run() {
@@ -80,8 +81,8 @@ class ImageLoadingTracker::LoadImageTask : public Task {
   }
 
  private:
-  // The message loop that we need to call back on to report that we are done.
-  MessageLoop* callback_loop_;
+  // The thread that we need to call back on to report that we are done.
+  ChromeThread::ID callback_thread_id_;
 
   // The object that is waiting for us to respond back.
   ImageLoadingTracker* tracker_;
@@ -101,9 +102,9 @@ class ImageLoadingTracker::LoadImageTask : public Task {
 
 void ImageLoadingTracker::PostLoadImageTask(const ExtensionResource& resource,
                                             const gfx::Size& max_size) {
-  MessageLoop* file_loop = g_browser_process->file_thread()->message_loop();
-  file_loop->PostTask(FROM_HERE, new LoadImageTask(this, resource, max_size,
-                                                   posted_count_++));
+  ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      new LoadImageTask(this, resource, max_size, posted_count_++));
 }
 
 void ImageLoadingTracker::OnImageLoaded(SkBitmap* image, size_t index) {
diff --git a/chrome/browser/extensions/pack_extension_job.cc b/chrome/browser/extensions/pack_extension_job.cc
index 497f1d1..9d370a1 100644
--- a/chrome/browser/extensions/pack_extension_job.cc
+++ b/chrome/browser/extensions/pack_extension_job.cc
@@ -7,14 +7,13 @@
 #include "base/message_loop.h"
 #include "base/string_util.h"
 #include "base/task.h"
-#include "chrome/browser/chrome_thread.h"
 #include "chrome/browser/extensions/extension_creator.h"
 
 PackExtensionJob::PackExtensionJob(Client* client,
                                    const FilePath& root_directory,
                                    const FilePath& key_file)
-    : ui_loop_(MessageLoop::current()), client_(client),
-      root_directory_(root_directory), key_file_(key_file) {
+    : client_(client), root_directory_(root_directory), key_file_(key_file) {
+  CHECK(ChromeThread::GetCurrentThreadIdentifier(&client_thread_id_));
   ChromeThread::PostTask(
       ChromeThread::FILE, FROM_HERE,
       NewRunnableMethod(this, &PackExtensionJob::RunOnFileThread));
@@ -34,11 +33,15 @@ void PackExtensionJob::RunOnFileThread() {
   // returns. See bug 20734.
   ExtensionCreator creator;
   if (creator.Run(root_directory_, crx_file_out_, key_file_, key_file_out_)) {
-    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-        &PackExtensionJob::ReportSuccessOnUIThread));
+    ChromeThread::PostTask(
+        client_thread_id_, FROM_HERE,
+        NewRunnableMethod(this, &PackExtensionJob::ReportSuccessOnUIThread));
   } else {
-    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-        &PackExtensionJob::ReportFailureOnUIThread, creator.error_message()));
+    ChromeThread::PostTask(
+        client_thread_id_, FROM_HERE,
+        NewRunnableMethod(
+            this, &PackExtensionJob::ReportFailureOnUIThread,
+            creator.error_message()));
   }
 }
 
diff --git a/chrome/browser/extensions/pack_extension_job.h b/chrome/browser/extensions/pack_extension_job.h
index b82e9d0..8a40692 100644
--- a/chrome/browser/extensions/pack_extension_job.h
+++ b/chrome/browser/extensions/pack_extension_job.h
@@ -9,8 +9,8 @@
 
 #include "base/file_path.h"
 #include "base/ref_counted.h"
+#include "chrome/browser/chrome_thread.h"
 
-class MessageLoop;
 
 // Manages packing an extension on the file thread and reporting the result
 // back to the UI.
@@ -38,7 +38,7 @@ class PackExtensionJob : public base::RefCountedThreadSafe<PackExtensionJob> {
   void ReportSuccessOnUIThread();
   void ReportFailureOnUIThread(const std::string& error);
 
-  MessageLoop* ui_loop_;
+  ChromeThread::ID client_thread_id_;
   Client* client_;
   FilePath root_directory_;
   FilePath key_file_;
diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.cc b/chrome/browser/extensions/sandboxed_extension_unpacker.cc
index d3d9f61..160a0de 100644
--- a/chrome/browser/extensions/sandboxed_extension_unpacker.cc
+++ b/chrome/browser/extensions/sandboxed_extension_unpacker.cc
@@ -29,14 +29,14 @@ const char SandboxedExtensionUnpacker::kExtensionHeaderMagic[] = "Cr24";
 SandboxedExtensionUnpacker::SandboxedExtensionUnpacker(
     const FilePath& crx_path, ResourceDispatcherHost* rdh,
     SandboxedExtensionUnpackerClient* client)
-      : crx_path_(crx_path), file_loop_(NULL), rdh_(rdh), client_(client),
-        got_response_(false) {
+      : crx_path_(crx_path), thread_identifier_(ChromeThread::ID_COUNT),
+        rdh_(rdh), client_(client), got_response_(false) {
 }
 
 void SandboxedExtensionUnpacker::Start() {
   // We assume that we are started on the thread that the client wants us to do
   // file IO on.
-  file_loop_ = MessageLoop::current();
+  CHECK(ChromeThread::GetCurrentThreadIdentifier(&thread_identifier_));
 
   // Create a temporary directory to work in.
   if (!temp_dir_.CreateUniqueTempDir()) {
@@ -91,13 +91,14 @@ void SandboxedExtensionUnpacker::Start() {
 
 void SandboxedExtensionUnpacker::StartProcessOnIOThread(
     const FilePath& temp_crx_path) {
-  UtilityProcessHost* host = new UtilityProcessHost(rdh_, this, file_loop_);
+  UtilityProcessHost* host = new UtilityProcessHost(
+      rdh_, this, thread_identifier_);
   host->StartExtensionUnpacker(temp_crx_path);
 }
 
 void SandboxedExtensionUnpacker::OnUnpackExtensionSucceeded(
     const DictionaryValue& manifest) {
-  DCHECK(file_loop_ == MessageLoop::current());
+  DCHECK(ChromeThread::CurrentlyOn(thread_identifier_));
   got_response_ = true;
 
   ExtensionUnpacker::DecodedImages images;
@@ -198,7 +199,7 @@ void SandboxedExtensionUnpacker::OnUnpackExtensionSucceeded(
 
 void SandboxedExtensionUnpacker::OnUnpackExtensionFailed(
     const std::string& error) {
-  DCHECK(file_loop_ == MessageLoop::current());
+  DCHECK(ChromeThread::CurrentlyOn(thread_identifier_));
   got_response_ = true;
   ReportFailure(error);
 }
diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.h b/chrome/browser/extensions/sandboxed_extension_unpacker.h
index 458ff29..91cd67f 100644
--- a/chrome/browser/extensions/sandboxed_extension_unpacker.h
+++ b/chrome/browser/extensions/sandboxed_extension_unpacker.h
@@ -124,7 +124,7 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client {
   void ReportSuccess();
 
   FilePath crx_path_;
-  MessageLoop* file_loop_;
+  ChromeThread::ID thread_identifier_;
   ResourceDispatcherHost* rdh_;
   scoped_refptr<SandboxedExtensionUnpackerClient> client_;
   ScopedTempDir temp_dir_;
diff --git a/chrome/browser/extensions/user_script_listener.cc b/chrome/browser/extensions/user_script_listener.cc
index cc77296..31f0971 100644
--- a/chrome/browser/extensions/user_script_listener.cc
+++ b/chrome/browser/extensions/user_script_listener.cc
@@ -4,28 +4,18 @@
 
 #include "chrome/browser/extensions/user_script_listener.h"
 
-#include "base/message_loop.h"
+#include "chrome/browser/chrome_thread.h"
 #include "chrome/browser/extensions/extensions_service.h"
 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/notification_service.h"
 #include "net/url_request/url_request.h"
 
-UserScriptListener::UserScriptListener(MessageLoop* ui_loop,
-                                       MessageLoop* io_loop,
-                                       ResourceDispatcherHost* rdh)
-    : ui_loop_(ui_loop),
-      io_loop_(io_loop),
-      resource_dispatcher_host_(rdh),
+UserScriptListener::UserScriptListener(ResourceDispatcherHost* rdh)
+    : resource_dispatcher_host_(rdh),
       user_scripts_ready_(false) {
-  DCHECK(ui_loop_);
-  DCHECK_EQ(ui_loop_, MessageLoop::current());
   DCHECK(resource_dispatcher_host_);
 
-  // IO loop can be NULL in unit tests.
-  if (!io_loop_)
-    io_loop_ = ui_loop;
-
   registrar_.Add(this, NotificationType::EXTENSION_LOADED,
                  NotificationService::AllSources());
   registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
@@ -35,7 +25,7 @@ UserScriptListener::UserScriptListener(MessageLoop* ui_loop,
 }
 
 bool UserScriptListener::ShouldStartRequest(URLRequest* request) {
-  DCHECK_EQ(io_loop_, MessageLoop::current());
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
 
   // If it's a frame load, then we need to check the URL against the list of
   // user scripts to see if we need to wait.
@@ -72,7 +62,7 @@ bool UserScriptListener::ShouldStartRequest(URLRequest* request) {
 }
 
 void UserScriptListener::StartDelayedRequests() {
-  DCHECK_EQ(io_loop_, MessageLoop::current());
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
 
   user_scripts_ready_ = true;
 
@@ -92,7 +82,7 @@ void UserScriptListener::StartDelayedRequests() {
 }
 
 void UserScriptListener::AppendNewURLPatterns(const URLPatterns& new_patterns) {
-  DCHECK_EQ(io_loop_, MessageLoop::current());
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
 
   user_scripts_ready_ = false;
   url_patterns_.insert(url_patterns_.end(),
@@ -100,13 +90,13 @@ void UserScriptListener::AppendNewURLPatterns(const URLPatterns& new_patterns) {
 }
 
 void UserScriptListener::ReplaceURLPatterns(const URLPatterns& patterns) {
-  DCHECK_EQ(io_loop_, MessageLoop::current());
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
   url_patterns_ = patterns;
 }
 
 void UserScriptListener::CollectURLPatterns(Extension* extension,
                                             URLPatterns* patterns) {
-  DCHECK_EQ(ui_loop_, MessageLoop::current());
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
 
   const UserScriptList& scripts = extension->content_scripts();
   for (UserScriptList::const_iterator iter = scripts.begin();
@@ -120,7 +110,7 @@ void UserScriptListener::CollectURLPatterns(Extension* extension,
 void UserScriptListener::Observe(NotificationType type,
                                  const NotificationSource& source,
                                  const NotificationDetails& details) {
-  DCHECK_EQ(ui_loop_, MessageLoop::current());
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
 
   switch (type.value) {
     case NotificationType::EXTENSION_LOADED: {
@@ -131,8 +121,10 @@ void UserScriptListener::Observe(NotificationType type,
       URLPatterns new_patterns;
       CollectURLPatterns(Details<Extension>(details).ptr(), &new_patterns);
       if (!new_patterns.empty()) {
-        io_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-            &UserScriptListener::AppendNewURLPatterns, new_patterns));
+        ChromeThread::PostTask(
+            ChromeThread::IO, FROM_HERE,
+            NewRunnableMethod(
+                this, &UserScriptListener::AppendNewURLPatterns, new_patterns));
       }
       break;
     }
@@ -150,13 +142,16 @@ void UserScriptListener::Observe(NotificationType type,
         if (*it != unloaded_extension)
           CollectURLPatterns(*it, &new_patterns);
       }
-      io_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
-          &UserScriptListener::ReplaceURLPatterns, new_patterns));
+      ChromeThread::PostTask(
+          ChromeThread::IO, FROM_HERE,
+          NewRunnableMethod(
+              this, &UserScriptListener::ReplaceURLPatterns, new_patterns));
       break;
     }
 
     case NotificationType::USER_SCRIPTS_UPDATED: {
-      io_loop_->PostTask(FROM_HERE,
+      ChromeThread::PostTask(
+          ChromeThread::IO, FROM_HERE,
           NewRunnableMethod(this, &UserScriptListener::StartDelayedRequests));
       break;
     }
diff --git a/chrome/browser/extensions/user_script_listener.h b/chrome/browser/extensions/user_script_listener.h
index a742d3a..303e354 100644
--- a/chrome/browser/extensions/user_script_listener.h
+++ b/chrome/browser/extensions/user_script_listener.h
@@ -13,7 +13,6 @@
 #include "chrome/common/notification_registrar.h"
 
 class Extension;
-class MessageLoop;
 class URLRequest;
 
 // This class handles delaying of resource loads that depend on unloaded user
@@ -27,9 +26,7 @@ class UserScriptListener
     : public base::RefCountedThreadSafe<UserScriptListener>,
       public NotificationObserver {
  public:
-  UserScriptListener(MessageLoop* ui_loop,
-                     MessageLoop* io_loop,
-                     ResourceDispatcherHost* rdh);
+  UserScriptListener(ResourceDispatcherHost* rdh);
 
   void OnResourceDispatcherHostGone() { resource_dispatcher_host_ = NULL; }
 
@@ -52,8 +49,6 @@ class UserScriptListener
   // deleted, so user_scripts_ready_ remains unchanged.
   void ReplaceURLPatterns(const URLPatterns& patterns);
 
-  MessageLoop* ui_loop_;
-  MessageLoop* io_loop_;
   ResourceDispatcherHost* resource_dispatcher_host_;
 
   // A list of every request that we delayed. Will be flushed when user scripts
diff --git a/chrome/browser/extensions/user_script_listener_unittest.cc b/chrome/browser/extensions/user_script_listener_unittest.cc
index 59357de..c644f1f 100644
--- a/chrome/browser/extensions/user_script_listener_unittest.cc
+++ b/chrome/browser/extensions/user_script_listener_unittest.cc
@@ -31,8 +31,8 @@ class SimpleTestJob : public URLRequestTestJob {
 
 class MockUserScriptMaster : public UserScriptMaster {
  public:
-  explicit MockUserScriptMaster(MessageLoop* worker, const FilePath& script_dir)
-      : UserScriptMaster(worker, script_dir) {}
+  explicit MockUserScriptMaster(const FilePath& script_dir)
+      : UserScriptMaster(script_dir) {}
 
   virtual void StartScan() {
     // Do nothing. We want to manually control when scans occur.
@@ -184,6 +184,8 @@ class ResourceDispatcherHostTester
 class UserScriptListenerTest : public testing::Test {
  public:
   virtual void SetUp() {
+    ui_thread_.reset(new ChromeThread(ChromeThread::UI, &loop_));
+    file_thread_.reset(new ChromeThread(ChromeThread::FILE, &loop_));
     io_thread_.reset(new MockIOThread());
     base::Thread::Options options(MessageLoop::TYPE_IO, 0);
     io_thread_->StartWithOptions(options);
@@ -196,14 +198,12 @@ class UserScriptListenerTest : public testing::Test {
     resource_tester_ =
         new ResourceDispatcherHostTester(io_thread_->message_loop());
 
-    master_ = new MockUserScriptMaster(&loop_, install_dir);
+    master_ = new MockUserScriptMaster(install_dir);
 
     service_ = new ExtensionsService(&profile_,
                                      CommandLine::ForCurrentProcess(),
                                      profile_.GetPrefs(),
                                      install_dir,
-                                     &loop_,
-                                     &loop_,
                                      false);
     service_->set_extensions_enabled(true);
     service_->set_show_extensions_prompts(false);
@@ -213,12 +213,16 @@ class UserScriptListenerTest : public testing::Test {
 
   virtual void TearDown() {
     io_thread_.reset();
+    file_thread_.reset();
+    ui_thread_.reset();
     resource_tester_ = NULL;
   }
 
  protected:
   TestingProfile profile_;
   MessageLoopForUI loop_;
+  scoped_ptr<ChromeThread> ui_thread_;
+  scoped_ptr<ChromeThread> file_thread_;
   scoped_ptr<MockIOThread> io_thread_;
   scoped_refptr<ResourceDispatcherHostTester> resource_tester_;
   scoped_refptr<MockUserScriptMaster> master_;
diff --git a/chrome/browser/extensions/user_script_master.cc b/chrome/browser/extensions/user_script_master.cc
index 024de80..b0552e0 100644
--- a/chrome/browser/extensions/user_script_master.cc
+++ b/chrome/browser/extensions/user_script_master.cc
@@ -36,8 +36,8 @@ static bool GetDeclarationValue(const base::StringPiece& line,
 }
 
 UserScriptMaster::ScriptReloader::ScriptReloader(UserScriptMaster* master)
-    : master_(master),
-      master_message_loop_(MessageLoop::current()) {
+    : master_(master) {
+  CHECK(ChromeThread::GetCurrentThreadIdentifier(&master_thread_id_));
 }
 
 // static
@@ -110,15 +110,15 @@ bool UserScriptMaster::ScriptReloader::ParseMetadataHeader(
 }
 
 void UserScriptMaster::ScriptReloader::StartScan(
-    MessageLoop* work_loop, const FilePath& script_dir,
-    const UserScriptList& lone_scripts) {
+    const FilePath& script_dir, const UserScriptList& lone_scripts) {
   // Add a reference to ourselves to keep ourselves alive while we're running.
   // Balanced by NotifyMaster().
   AddRef();
-  work_loop->PostTask(FROM_HERE,
-      NewRunnableMethod(this,
-                        &UserScriptMaster::ScriptReloader::RunScan,
-                        script_dir, lone_scripts));
+  ChromeThread::PostTask(
+      ChromeThread::FILE, FROM_HERE,
+      NewRunnableMethod(
+          this, &UserScriptMaster::ScriptReloader::RunScan, script_dir,
+          lone_scripts));
 }
 
 void UserScriptMaster::ScriptReloader::NotifyMaster(
@@ -252,17 +252,15 @@ void UserScriptMaster::ScriptReloader::RunScan(
   // Scripts now contains list of up-to-date scripts. Load the content in the
   // shared memory and let the master know it's ready. We need to post the task
   // back even if no scripts ware found to balance the AddRef/Release calls
-  master_message_loop_->PostTask(FROM_HERE,
-      NewRunnableMethod(this,
-                        &ScriptReloader::NotifyMaster,
-                        Serialize(scripts)));
+  ChromeThread::PostTask(
+      master_thread_id_, FROM_HERE,
+      NewRunnableMethod(
+          this, &ScriptReloader::NotifyMaster, Serialize(scripts)));
 }
 
 
-UserScriptMaster::UserScriptMaster(MessageLoop* worker_loop,
-                                   const FilePath& script_dir)
+UserScriptMaster::UserScriptMaster(const FilePath& script_dir)
     : user_script_dir_(script_dir),
-      worker_loop_(worker_loop),
       extensions_service_ready_(false),
       pending_scan_(false) {
   if (!user_script_dir_.value().empty())
@@ -383,5 +381,5 @@ void UserScriptMaster::StartScan() {
   if (!script_reloader_)
     script_reloader_ = new ScriptReloader(this);
 
-  script_reloader_->StartScan(worker_loop_, user_script_dir_, lone_scripts_);
+  script_reloader_->StartScan(user_script_dir_, lone_scripts_);
 }
diff --git a/chrome/browser/extensions/user_script_master.h b/chrome/browser/extensions/user_script_master.h
index c5a8803..a062448 100644
--- a/chrome/browser/extensions/user_script_master.h
+++ b/chrome/browser/extensions/user_script_master.h
@@ -11,11 +11,11 @@
 #include "base/file_path.h"
 #include "base/scoped_ptr.h"
 #include "base/shared_memory.h"
+#include "chrome/browser/chrome_thread.h"
 #include "chrome/common/extensions/user_script.h"
 #include "chrome/common/notification_registrar.h"
 #include "testing/gtest/include/gtest/gtest_prod.h"
 
-class MessageLoop;
 namespace base {
 class StringPiece;
 }
@@ -26,10 +26,9 @@ class UserScriptMaster : public base::RefCountedThreadSafe<UserScriptMaster>,
                          public DirectoryWatcher::Delegate,
                          public NotificationObserver {
  public:
-  // For testability, the constructor takes the MessageLoop to run the
-  // script-reloading worker on as well as the path the scripts live in.
-  // These are normally the file thread and a directory inside the profile.
-  UserScriptMaster(MessageLoop* worker, const FilePath& script_dir);
+  // For testability, the constructor takes the path the scripts live in.
+  // This is normally a directory inside the profile.
+  UserScriptMaster(const FilePath& script_dir);
   virtual ~UserScriptMaster();
 
   // Add a watched directory. All scripts will be reloaded when any file in
@@ -82,7 +81,7 @@ class UserScriptMaster : public base::RefCountedThreadSafe<UserScriptMaster>,
 
     // Start a scan for scripts.
     // Will always send a message to the master upon completion.
-    void StartScan(MessageLoop* work_loop, const FilePath& script_dir,
+    void StartScan(const FilePath& script_dir,
                    const UserScriptList& external_scripts);
 
     // The master is going away; don't call it back.
@@ -114,7 +113,7 @@ class UserScriptMaster : public base::RefCountedThreadSafe<UserScriptMaster>,
 
     // The message loop to call our master back on.
     // Expected to always outlive us.
-    MessageLoop* master_message_loop_;
+    ChromeThread::ID master_thread_id_;
 
     DISALLOW_COPY_AND_ASSIGN(ScriptReloader);
   };
@@ -136,10 +135,6 @@ class UserScriptMaster : public base::RefCountedThreadSafe<UserScriptMaster>,
   // The watcher watches the profile's user scripts directory for new scripts.
   std::vector<DirectoryWatcher*> dir_watchers_;
 
-  // The MessageLoop that the scanner worker runs on.
-  // Typically the file thread; configurable for testing.
-  MessageLoop* worker_loop_;
-
   // ScriptReloader (in another thread) reloads script off disk.
   // We hang on to our pointer to know if we've already got one running.
   scoped_refptr<ScriptReloader> script_reloader_;
diff --git a/chrome/browser/extensions/user_script_master_unittest.cc b/chrome/browser/extensions/user_script_master_unittest.cc
index e7c4206..840d8a3 100644
--- a/chrome/browser/extensions/user_script_master_unittest.cc
+++ b/chrome/browser/extensions/user_script_master_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/message_loop.h"
 #include "base/path_service.h"
 #include "base/string_util.h"
+#include "chrome/browser/chrome_thread.h"
 #include "chrome/common/notification_registrar.h"
 #include "chrome/common/notification_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -39,12 +40,18 @@ class UserScriptMasterTest : public testing::Test,
     // Register for all user script notifications.
     registrar_.Add(this, NotificationType::USER_SCRIPTS_UPDATED,
                    NotificationService::AllSources());
+
+    // UserScriptMaster posts tasks to the file thread so make the current
+    // thread look like one.
+    file_thread_.reset(new ChromeThread(
+        ChromeThread::FILE, MessageLoop::current()));
   }
 
   virtual void TearDown() {
     // Clean up test directory.
     ASSERT_TRUE(file_util::Delete(script_dir_, true));
     ASSERT_FALSE(file_util::PathExists(script_dir_));
+    file_thread_.reset();
   }
 
   virtual void Observe(NotificationType type,
@@ -62,6 +69,8 @@ class UserScriptMasterTest : public testing::Test,
   // MessageLoop used in tests.
   MessageLoop message_loop_;
 
+  scoped_ptr<ChromeThread> file_thread_;
+
   // Directory containing user scripts.
   FilePath script_dir_;
 
@@ -71,9 +80,7 @@ class UserScriptMasterTest : public testing::Test,
 
 // Test that we get notified even when there are no scripts.
 TEST_F(UserScriptMasterTest, NoScripts) {
-
-  scoped_refptr<UserScriptMaster> master(
-      new UserScriptMaster(MessageLoop::current(), script_dir_));
+  scoped_refptr<UserScriptMaster> master(new UserScriptMaster(script_dir_));
   master->StartScan();
   message_loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask);
   message_loop_.Run();
@@ -85,8 +92,7 @@ TEST_F(UserScriptMasterTest, NoScripts) {
 #if defined(OS_WIN) || defined(OS_MACOSX)
 // Test that we get notified about new scripts after they're added.
 TEST_F(UserScriptMasterTest, NewScripts) {
-  scoped_refptr<UserScriptMaster> master(
-      new UserScriptMaster(MessageLoop::current(), script_dir_));
+  scoped_refptr<UserScriptMaster> master(new UserScriptMaster(script_dir_));
 
   FilePath path = script_dir_.AppendASCII("script.user.js");
 
@@ -112,8 +118,7 @@ TEST_F(UserScriptMasterTest, ExistingScripts) {
   size_t written = file_util::WriteFile(path, content, sizeof(content));
   ASSERT_EQ(written, sizeof(content));
 
-  scoped_refptr<UserScriptMaster> master(
-      new UserScriptMaster(MessageLoop::current(), script_dir_));
+  scoped_refptr<UserScriptMaster> master(new UserScriptMaster(script_dir_));
   master->StartScan();
 
   message_loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask);
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index 43a5640..7d715f0 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -668,16 +668,12 @@ void ProfileImpl::InitExtensions() {
   }
 
   ExtensionErrorReporter::Init(true);  // allow noisy errors.
-  user_script_master_ = new UserScriptMaster(
-      g_browser_process->file_thread()->message_loop(),
-      script_dir);
+  user_script_master_ = new UserScriptMaster(script_dir);
   extensions_service_ = new ExtensionsService(
       this,
       CommandLine::ForCurrentProcess(),
       GetPrefs(),
       GetPath().AppendASCII(ExtensionsService::kInstallDirectoryName),
-      MessageLoop::current(),
-      g_browser_process->file_thread()->message_loop(),
       true);
 
   extensions_service_->Init();
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index 85935c3..b1c7129 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -259,7 +259,7 @@ ResourceDispatcherHost::ResourceDispatcherHost(MessageLoop* io_loop)
       ALLOW_THIS_IN_INITIALIZER_LIST(
           save_file_manager_(new SaveFileManager(ui_loop_, io_loop, this))),
       ALLOW_THIS_IN_INITIALIZER_LIST(user_script_listener_(
-          new UserScriptListener(ui_loop_, io_loop, this))),
+          new UserScriptListener(this))),
       safe_browsing_(new SafeBrowsingService),
       webkit_thread_(new WebKitThread),
       request_id_(-1),
diff --git a/chrome/browser/utility_process_host.cc b/chrome/browser/utility_process_host.cc
index 95729b0..0ba763b 100644
--- a/chrome/browser/utility_process_host.cc
+++ b/chrome/browser/utility_process_host.cc
@@ -26,10 +26,10 @@
 
 UtilityProcessHost::UtilityProcessHost(ResourceDispatcherHost* rdh,
                                        Client* client,
-                                       MessageLoop* client_loop)
+                                       ChromeThread::ID client_thread_id)
     : ChildProcessHost(UTILITY_PROCESS, rdh),
       client_(client),
-      client_loop_(client_loop) {
+      client_thread_id_(client_thread_id) {
 }
 
 UtilityProcessHost::~UtilityProcessHost() {
@@ -139,7 +139,8 @@ bool UtilityProcessHost::StartProcess(const FilePath& exposed_dir) {
 }
 
 void UtilityProcessHost::OnMessageReceived(const IPC::Message& message) {
-  client_loop_->PostTask(FROM_HERE,
+  ChromeThread::PostTask(
+      client_thread_id_, FROM_HERE,
       NewRunnableMethod(client_.get(), &Client::OnMessageReceived, message));
 }
 
@@ -147,7 +148,8 @@ void UtilityProcessHost::OnChannelError() {
   bool child_exited;
   bool did_crash = base::DidProcessCrash(&child_exited, handle());
   if (did_crash) {
-    client_loop_->PostTask(FROM_HERE,
+    ChromeThread::PostTask(
+        client_thread_id_, FROM_HERE,
         NewRunnableMethod(client_.get(), &Client::OnProcessCrashed));
   }
 }
diff --git a/chrome/browser/utility_process_host.h b/chrome/browser/utility_process_host.h
index d9e6d3f..25a8dd8 100644
--- a/chrome/browser/utility_process_host.h
+++ b/chrome/browser/utility_process_host.h
@@ -10,6 +10,7 @@
 #include "base/basictypes.h"
 #include "base/ref_counted.h"
 #include "base/task.h"
+#include "chrome/browser/chrome_thread.h"
 #include "chrome/common/child_process_host.h"
 #include "chrome/common/extensions/update_manifest.h"
 #include "ipc/ipc_channel.h"
@@ -17,7 +18,6 @@
 class CommandLine;
 class DictionaryValue;
 class ListValue;
-class MessageLoop;
 
 // This class acts as the browser-side host to a utility child process.  A
 // utility process is a short-lived sandboxed process that is created to run
@@ -72,7 +72,7 @@ class UtilityProcessHost : public ChildProcessHost {
   };
 
   UtilityProcessHost(ResourceDispatcherHost* rdh, Client* client,
-                     MessageLoop* client_loop);
+                     ChromeThread::ID client_thread_id);
   virtual ~UtilityProcessHost();
 
   // Start a process to unpack the extension at the given path.  The process
@@ -117,7 +117,7 @@ class UtilityProcessHost : public ChildProcessHost {
 
   // A pointer to our client interface, who will be informed of progress.
   scoped_refptr<Client> client_;
-  MessageLoop* client_loop_;
+  ChromeThread::ID client_thread_id_;
 
   DISALLOW_COPY_AND_ASSIGN(UtilityProcessHost);
 };
diff --git a/chrome/browser/utility_process_host_unittest.cc b/chrome/browser/utility_process_host_unittest.cc
index 96dded3..9647ca5 100644
--- a/chrome/browser/utility_process_host_unittest.cc
+++ b/chrome/browser/utility_process_host_unittest.cc
@@ -22,17 +22,17 @@ namespace {
 
 class UtilityProcessHostTest : public testing::Test {
  public:
-  UtilityProcessHostTest() {
+  UtilityProcessHostTest() : io_thread_(ChromeThread::IO, &message_loop_) {
   }
 
  protected:
   MessageLoopForIO message_loop_;
+  ChromeThread io_thread_;
 };
 
 class TestUtilityProcessHostClient : public UtilityProcessHost::Client {
  public:
-  explicit TestUtilityProcessHostClient(MessageLoop* message_loop)
-      : message_loop_(message_loop), success_(false) {
+  explicit TestUtilityProcessHostClient() : success_(false) {
   }
 
   // UtilityProcessHost::Client methods.
@@ -63,16 +63,14 @@ class TestUtilityProcessHostClient : public UtilityProcessHost::Client {
   }
 
  private:
-  MessageLoop* message_loop_;
   bool success_;
 };
 
 class TestUtilityProcessHost : public UtilityProcessHost {
  public:
   TestUtilityProcessHost(TestUtilityProcessHostClient* client,
-                         MessageLoop* loop_io,
                          ResourceDispatcherHost* rdh)
-      : UtilityProcessHost(rdh, client, loop_io) {
+      : UtilityProcessHost(rdh, client, ChromeThread::IO) {
   }
 
  protected:
@@ -140,10 +138,10 @@ TEST_F(UtilityProcessHostTest, ExtensionUnpacker) {
                                   temp_extension_dir.AppendASCII("theme.crx")));
 
   scoped_refptr<TestUtilityProcessHostClient> client(
-      new TestUtilityProcessHostClient(&message_loop_));
+      new TestUtilityProcessHostClient());
   ResourceDispatcherHost rdh(NULL);
   TestUtilityProcessHost* process_host =
-      new TestUtilityProcessHost(client.get(), &message_loop_, &rdh);
+      new TestUtilityProcessHost(client.get(), &rdh);
   // process_host will delete itself when it's done.
   ProcessClosedObserver observer(&message_loop_);
   process_host->StartExtensionUnpacker(
diff --git a/chrome/browser/web_resource/web_resource_service.cc b/chrome/browser/web_resource/web_resource_service.cc
index fc93f0d..4a6683c 100644
--- a/chrome/browser/web_resource/web_resource_service.cc
+++ b/chrome/browser/web_resource/web_resource_service.cc
@@ -118,11 +118,13 @@ class WebResourceService::UnpackerClient
 #endif
 
     if (use_utility_process) {
+      ChromeThread::ID thread_id;
+      CHECK(ChromeThread::GetCurrentThreadIdentifier(&thread_id));
       ChromeThread::PostTask(
           ChromeThread::IO, FROM_HERE,
           NewRunnableMethod(this, &UnpackerClient::StartProcessOnIOThread,
                             web_resource_service_->resource_dispatcher_host_,
-                            MessageLoop::current()));
+                            thread_id));
     } else {
       WebResourceUnpacker unpacker(json_data_);
       if (unpacker.Run()) {
@@ -164,8 +166,8 @@ class WebResourceService::UnpackerClient
   }
 
   void StartProcessOnIOThread(ResourceDispatcherHost* rdh,
-                              MessageLoop* file_loop) {
-    UtilityProcessHost* host = new UtilityProcessHost(rdh, this, file_loop);
+                              ChromeThread::ID thread_id) {
+    UtilityProcessHost* host = new UtilityProcessHost(rdh, this, thread_id);
     // TODO(mrc): get proper file path when we start using web resources
     // that need to be unpacked.
     host->StartWebResourceUnpacker(json_data_);
-- 
cgit v1.1