Convert extensions::LazyBackgroundTaskQueue from Profile to BrowserContext

To do this, introduce the concept of an ExtensionsBrowserClient that allows
the extensions module to ask Profile-like questions of the embedder. The
rest of the change is mostly mechanical.

Also, introduce some conventions around profile() vs. browser_context() and
GetForProfile() vs. GetForBrowserContext() so we can tell which pieces of
the system have been converted.

BUG=309909
TEST=browser_tests LazyBackgroundPageApiTest.* unit_tests LazyBackgroundTaskQueueTest.*

Review URL: https://codereview.chromium.org/46793003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231641 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/apps/DEPS b/apps/DEPS
index 0e66fcc4..1563676 100644
--- a/apps/DEPS
+++ b/apps/DEPS
@@ -41,7 +41,6 @@
   "+chrome/browser/extensions/extension_system.h",
   "+chrome/browser/extensions/extension_system_factory.h",
   "+chrome/browser/extensions/extension_web_contents_observer.h",
-  "+chrome/browser/extensions/lazy_background_task_queue.h",
   "+chrome/browser/extensions/suggest_permission_util.h",
   "+chrome/browser/extensions/unpacked_installer.h",
   "+chrome/common/extensions/api/app_runtime.h",
diff --git a/apps/launcher.cc b/apps/launcher.cc
index 731ff88..8e9b151b 100644
--- a/apps/launcher.cc
+++ b/apps/launcher.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/lazy_background_task_queue.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/extensions/api/app_runtime.h"
 #include "chrome/common/extensions/extension.h"
@@ -30,6 +29,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
+#include "extensions/browser/lazy_background_task_queue.h"
 #include "net/base/mime_util.h"
 #include "net/base/net_util.h"
 #include "url/gurl.h"
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 51abfe8..934e528 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -33,6 +33,7 @@
 #include "chrome/browser/devtools/remote_debugging_server.h"
 #include "chrome/browser/download/download_request_limiter.h"
 #include "chrome/browser/download/download_status_updater.h"
+#include "chrome/browser/extensions/chrome_extensions_browser_client.h"
 #include "chrome/browser/extensions/event_router_forwarder.h"
 #include "chrome/browser/extensions/extension_renderer_state.h"
 #include "chrome/browser/first_run/upgrade_util.h"
@@ -187,6 +188,8 @@
   apps::AppsClient::Set(ChromeAppsClient::GetInstance());
   extensions::ExtensionsClient::Set(
       extensions::ChromeExtensionsClient::GetInstance());
+  extensions::ExtensionsBrowserClient::Set(
+      extensions::ChromeExtensionsBrowserClient::GetInstance());
   extension_event_router_forwarder_ = new extensions::EventRouterForwarder;
   ExtensionRendererState::GetInstance()->Init();
 
diff --git a/chrome/browser/chromeos/file_manager/file_browser_handlers.cc b/chrome/browser/chromeos/file_manager/file_browser_handlers.cc
index 54ea3af..6d7956ffe 100644
--- a/chrome/browser/chromeos/file_manager/file_browser_handlers.cc
+++ b/chrome/browser/chromeos/file_manager/file_browser_handlers.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/extension_util.h"
-#include "chrome/browser/extensions/lazy_background_task_queue.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/common/extensions/api/file_browser_handlers/file_browser_handler.h"
@@ -28,6 +27,7 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/web_contents.h"
+#include "extensions/browser/lazy_background_task_queue.h"
 #include "net/base/escape.h"
 #include "webkit/browser/fileapi/file_system_context.h"
 #include "webkit/browser/fileapi/file_system_url.h"
diff --git a/chrome/browser/extensions/api/messaging/message_service.cc b/chrome/browser/extensions/api/messaging/message_service.cc
index cdf65278..d2951ecb 100644
--- a/chrome/browser/extensions/api/messaging/message_service.cc
+++ b/chrome/browser/extensions/api/messaging/message_service.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
 #include "chrome/browser/extensions/extension_util.h"
-#include "chrome/browser/extensions/lazy_background_task_queue.h"
 #include "chrome/browser/extensions/process_map.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/tab_contents/tab_util.h"
@@ -38,6 +37,7 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/web_contents.h"
+#include "extensions/browser/lazy_background_task_queue.h"
 #include "extensions/common/manifest_constants.h"
 #include "net/base/completion_callback.h"
 #include "url/gurl.h"
diff --git a/chrome/browser/extensions/api/runtime/runtime_api.cc b/chrome/browser/extensions/api/runtime/runtime_api.cc
index a6670c0..185c2ce2 100644
--- a/chrome/browser/extensions/api/runtime/runtime_api.cc
+++ b/chrome/browser/extensions/api/runtime/runtime_api.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/lazy_background_task_queue.h"
 #include "chrome/browser/extensions/updater/extension_updater.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -31,6 +30,7 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
+#include "extensions/browser/lazy_background_task_queue.h"
 #include "extensions/common/error_utils.h"
 #include "url/gurl.h"
 #include "webkit/browser/fileapi/isolated_context.h"
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc
new file mode 100644
index 0000000..e2ba427a
--- /dev/null
+++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc
@@ -0,0 +1,49 @@
+// Copyright 2013 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 "chrome/browser/extensions/chrome_extensions_browser_client.h"
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile.h"
+
+namespace extensions {
+
+namespace {
+
+static base::LazyInstance<ChromeExtensionsBrowserClient> g_client =
+    LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
+ChromeExtensionsBrowserClient::ChromeExtensionsBrowserClient() {}
+
+ChromeExtensionsBrowserClient::~ChromeExtensionsBrowserClient() {}
+
+bool ChromeExtensionsBrowserClient::IsShuttingDown() {
+  return g_browser_process->IsShuttingDown();
+}
+
+bool ChromeExtensionsBrowserClient::IsSameContext(
+    content::BrowserContext* first,
+    content::BrowserContext* second) {
+  return static_cast<Profile*>(first)->IsSameProfile(
+      static_cast<Profile*>(second));
+}
+
+bool ChromeExtensionsBrowserClient::HasOffTheRecordContext(
+    content::BrowserContext* context) {
+  return static_cast<Profile*>(context)->HasOffTheRecordProfile();
+}
+
+content::BrowserContext* ChromeExtensionsBrowserClient::GetOffTheRecordContext(
+    content::BrowserContext* context) {
+  return static_cast<Profile*>(context)->GetOffTheRecordProfile();
+}
+
+// static
+ChromeExtensionsBrowserClient* ChromeExtensionsBrowserClient::GetInstance() {
+  return g_client.Pointer();
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.h b/chrome/browser/extensions/chrome_extensions_browser_client.h
new file mode 100644
index 0000000..ddcc4d78
--- /dev/null
+++ b/chrome/browser/extensions/chrome_extensions_browser_client.h
@@ -0,0 +1,50 @@
+// Copyright 2013 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 CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSIONS_BROWSER_CLIENT_H_
+#define CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSIONS_BROWSER_CLIENT_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/lazy_instance.h"
+#include "extensions/browser/extensions_browser_client.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace extensions {
+
+// Implementation of extensions::BrowserClient for Chrome, which includes
+// knowledge of Profiles, BrowserContexts and incognito.
+//
+// NOTE: Methods that do not require knowledge of browser concepts should be
+// implemented in ChromeExtensionsClient even if they are only used in the
+// browser process (see chrome/common/extensions/chrome_extensions_client.h).
+class ChromeExtensionsBrowserClient : public ExtensionsBrowserClient {
+ public:
+  ChromeExtensionsBrowserClient();
+  virtual ~ChromeExtensionsBrowserClient();
+
+  // BrowserClient overrides:
+  virtual bool IsShuttingDown() OVERRIDE;
+  virtual bool IsSameContext(content::BrowserContext* first,
+                             content::BrowserContext* second) OVERRIDE;
+  virtual bool HasOffTheRecordContext(
+      content::BrowserContext* context) OVERRIDE;
+  virtual content::BrowserContext* GetOffTheRecordContext(
+      content::BrowserContext* context) OVERRIDE;
+
+  // Get the LazyInstance for ChromeBrowserClient.
+  static ChromeExtensionsBrowserClient* GetInstance();
+
+ private:
+  friend struct base::DefaultLazyInstanceTraits<ChromeExtensionsBrowserClient>;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsBrowserClient);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSIONS_BROWSER_CLIENT_H_
diff --git a/chrome/browser/extensions/devtools_util.cc b/chrome/browser/extensions/devtools_util.cc
index b17530d..987fe9e 100644
--- a/chrome/browser/extensions/devtools_util.cc
+++ b/chrome/browser/extensions/devtools_util.cc
@@ -8,8 +8,9 @@
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/lazy_background_task_queue.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/common/extensions/extension.h"
+#include "extensions/browser/lazy_background_task_queue.h"
 
 namespace extensions {
 namespace devtools_util {
diff --git a/chrome/browser/extensions/event_router.cc b/chrome/browser/extensions/event_router.cc
index b5e88bf4..c1203f6 100644
--- a/chrome/browser/extensions/event_router.cc
+++ b/chrome/browser/extensions/event_router.cc
@@ -23,7 +23,6 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/extension_util.h"
-#include "chrome/browser/extensions/lazy_background_task_queue.h"
 #include "chrome/browser/extensions/process_map.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -37,6 +36,7 @@
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
+#include "extensions/browser/lazy_background_task_queue.h"
 #include "extensions/common/extension_urls.h"
 
 using base::DictionaryValue;
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index b859c417..e8da09d 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -258,6 +258,10 @@
       view()->browser()->extension_window_controller() : NULL;
 }
 
+content::BrowserContext* ExtensionHost::browser_context() {
+  return profile_;
+}
+
 const GURL& ExtensionHost::GetURL() const {
   return host_contents()->GetURL();
 }
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index 376d388..b5501a76 100644
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -39,6 +39,7 @@
 class PrefsTabHelper;
 
 namespace content {
+class BrowserContext;
 class RenderProcessHost;
 class RenderWidgetHostView;
 class SiteInstance;
@@ -115,6 +116,10 @@
 
   Profile* profile() const { return profile_; }
 
+  // Returns the same value as profile() but as a BrowserContext. Implemented
+  // in the .cc file to avoid including profile.h in this header.
+  content::BrowserContext* browser_context();
+
   ViewType extension_host_type() const { return extension_host_type_; }
   const GURL& GetURL() const;
 
diff --git a/chrome/browser/extensions/extension_system.cc b/chrome/browser/extensions/extension_system.cc
index 6ed7220..8bca0b8 100644
--- a/chrome/browser/extensions/extension_system.cc
+++ b/chrome/browser/extensions/extension_system.cc
@@ -27,7 +27,6 @@
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/extensions/extension_warning_badge_service.h"
 #include "chrome/browser/extensions/extension_warning_set.h"
-#include "chrome/browser/extensions/lazy_background_task_queue.h"
 #include "chrome/browser/extensions/management_policy.h"
 #include "chrome/browser/extensions/navigation_observer.h"
 #include "chrome/browser/extensions/standard_management_policy_provider.h"
@@ -44,6 +43,7 @@
 #include "chrome/common/extensions/features/feature_channel.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/url_data_source.h"
+#include "extensions/browser/lazy_background_task_queue.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/manifest.h"
 
@@ -79,6 +79,12 @@
   return ExtensionSystemFactory::GetForProfile(profile);
 }
 
+// static
+ExtensionSystem* ExtensionSystem::GetForBrowserContext(
+    content::BrowserContext* profile) {
+  return ExtensionSystemFactory::GetForProfile(static_cast<Profile*>(profile));
+}
+
 //
 // ExtensionSystemImpl::Shared
 //
diff --git a/chrome/browser/extensions/extension_system.h b/chrome/browser/extensions/extension_system.h
index 07cbfb6..663c176 100644
--- a/chrome/browser/extensions/extension_system.h
+++ b/chrome/browser/extensions/extension_system.h
@@ -24,6 +24,10 @@
 }
 #endif  // defined(OS_CHROMEOS)
 
+namespace content {
+class BrowserContext;
+}
+
 namespace extensions {
 class Blacklist;
 class ErrorConsole;
@@ -53,6 +57,10 @@
   // a convenience wrapper around ExtensionSystemFactory::GetForProfile.
   static ExtensionSystem* Get(Profile* profile);
 
+  // Returns the same instance as Get() above.
+  static ExtensionSystem* GetForBrowserContext(
+      content::BrowserContext* profile);
+
   // BrowserContextKeyedService implementation.
   virtual void Shutdown() OVERRIDE {}
 
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
index 32b6e3d..c4f1b7e 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
+++ b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
@@ -39,7 +39,6 @@
 #include "chrome/browser/extensions/extension_tab_util.h"
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/extensions/extension_warning_set.h"
-#include "chrome/browser/extensions/lazy_background_task_queue.h"
 #include "chrome/browser/extensions/management_policy.h"
 #include "chrome/browser/extensions/unpacked_installer.h"
 #include "chrome/browser/extensions/updater/extension_updater.h"
@@ -77,6 +76,7 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "extensions/browser/extension_error.h"
+#include "extensions/browser/lazy_background_task_queue.h"
 #include "extensions/browser/view_type_utils.h"
 #include "extensions/common/constants.h"
 #include "grit/browser_resources.h"
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index 36a3e6a..5303ad05 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -631,6 +631,8 @@
         'browser/extensions/bundle_installer.h',
         'browser/extensions/chrome_extension_function.cc',
         'browser/extensions/chrome_extension_function.h',
+        'browser/extensions/chrome_extensions_browser_client.cc',
+        'browser/extensions/chrome_extensions_browser_client.h',
         'browser/extensions/component_loader.cc',
         'browser/extensions/component_loader.h',
         'browser/extensions/context_menu_matcher.cc',
@@ -805,8 +807,6 @@
         'browser/extensions/install_tracker.h',
         'browser/extensions/install_tracker_factory.cc',
         'browser/extensions/install_tracker_factory.h',
-        'browser/extensions/lazy_background_task_queue.cc',
-        'browser/extensions/lazy_background_task_queue.h',
         'browser/extensions/location_bar_controller.h',
         'browser/extensions/management_policy.cc',
         'browser/extensions/management_policy.h',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 5d90dde4..f0d3358 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -512,6 +512,7 @@
         '../components/autofill/content/renderer/test_password_autofill_agent.h',
         '../extensions/browser/file_highlighter_unittest.cc',
         '../extensions/browser/file_reader_unittest.cc',
+        '../extensions/browser/lazy_background_task_queue_unittest.cc',
         '../extensions/common/event_filter_unittest.cc',
         '../extensions/common/extension_resource_unittest.cc',
         '../extensions/common/id_util_unittest.cc',
@@ -888,7 +889,6 @@
         'browser/extensions/external_policy_loader_unittest.cc',
         'browser/extensions/external_provider_impl_chromeos_unittest.cc',
         'browser/extensions/image_loader_unittest.cc',
-        'browser/extensions/lazy_background_task_queue_unittest.cc',
         'browser/extensions/management_policy_unittest.cc',
         'browser/extensions/menu_manager_unittest.cc',
         'browser/extensions/pack_extension_unittest.cc',
@@ -2131,7 +2131,6 @@
             'browser/extensions/extension_context_menu_model_unittest.cc',
             'browser/extensions/extension_protocols_unittest.cc',
             'browser/extensions/extension_ui_unittest.cc',
-            'browser/extensions/lazy_background_task_queue_unittest.cc',
             'browser/extensions/pack_extension_unittest.cc',
             'browser/extensions/permissions_updater_unittest.cc',
             'browser/extensions/sandboxed_unpacker_unittest.cc',
diff --git a/chrome/test/base/chrome_test_suite.cc b/chrome/test/base/chrome_test_suite.cc
index ad2967e..e010054 100644
--- a/chrome/test/base/chrome_test_suite.cc
+++ b/chrome/test/base/chrome_test_suite.cc
@@ -17,6 +17,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_content_browser_client.h"
+#include "chrome/browser/extensions/chrome_extensions_browser_client.h"
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_content_client.h"
@@ -171,6 +172,8 @@
 
   extensions::ExtensionsClient::Set(
       extensions::ChromeExtensionsClient::GetInstance());
+  extensions::ExtensionsBrowserClient::Set(
+      extensions::ChromeExtensionsBrowserClient::GetInstance());
 
   // Only want to do this for unit tests.
   if (!content::GetCurrentTestLauncherDelegate()) {
diff --git a/extensions/browser/DEPS b/extensions/browser/DEPS
index 1c35d9c..3c1ac11c 100644
--- a/extensions/browser/DEPS
+++ b/extensions/browser/DEPS
@@ -1,3 +1,30 @@
 include_rules = [
   "+content/public/browser",
+
+  # Temporarily allowed includes as part of the app shell/extensions refactor.
+  #
+  # NOTE: Please do not add includes without talking to the app shell team;
+  # see OWNERS for this directory.
+  #
+  # TODO(jamescook): Remove these. http://crbug.com/162530
+  "+chrome/browser/chrome_notification_types.h",
+  "+chrome/browser/extensions/extension_host.h",
+  "+chrome/browser/extensions/extension_process_manager.h",
+  "+chrome/browser/extensions/extension_service.h",
+  "+chrome/browser/extensions/extension_system.h",
+  "+chrome/browser/extensions/process_map.h",
+  "+chrome/common/extensions/background_info.h",
+  "+chrome/common/extensions/extension.h",
+  "+chrome/common/extensions/extension_messages.h",
 ]
+
+specific_include_rules = {
+  ".*test\.cc": [
+    # Temporarily allowed testing includes.  See above.
+    # TODO(jamescook): Remove these. http://crbug.com/159366
+    "+chrome/browser/extensions/extension_service_unittest.h",
+    "+chrome/browser/extensions/test_extension_system.h",
+    "+chrome/common/extensions/extension_builder.h",
+    "+chrome/test/base/testing_profile.h",
+  ]
+}
diff --git a/extensions/browser/OWNERS b/extensions/browser/OWNERS
new file mode 100644
index 0000000..b06f377
--- /dev/null
+++ b/extensions/browser/OWNERS
@@ -0,0 +1,7 @@
+# Please talk to the apps shell team before adding DEPS.
+per-file DEPS=set noparent
+per-file [email protected]
+per-file [email protected]
+per-file [email protected]
+per-file [email protected]
+per-file [email protected]
diff --git a/extensions/browser/extensions_browser_client.cc b/extensions/browser/extensions_browser_client.cc
new file mode 100644
index 0000000..2724d47
--- /dev/null
+++ b/extensions/browser/extensions_browser_client.cc
@@ -0,0 +1,28 @@
+// Copyright 2013 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 "extensions/browser/extensions_browser_client.h"
+
+#include "base/basictypes.h"
+
+namespace extensions {
+
+namespace {
+
+ExtensionsBrowserClient* g_client = NULL;
+
+}  // namespace
+
+ExtensionsBrowserClient* ExtensionsBrowserClient::Get() {
+  return g_client;
+}
+
+void ExtensionsBrowserClient::Set(ExtensionsBrowserClient* client) {
+  // This can happen in tests.
+  if (g_client)
+    return;
+  g_client = client;
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/extensions_browser_client.h b/extensions/browser/extensions_browser_client.h
new file mode 100644
index 0000000..4810836
--- /dev/null
+++ b/extensions/browser/extensions_browser_client.h
@@ -0,0 +1,51 @@
+// Copyright 2013 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 EXTENSIONS_BROWSER_EXTENSIONS_BROWSER_CLIENT_H_
+#define EXTENSIONS_BROWSER_EXTENSIONS_BROWSER_CLIENT_H_
+
+namespace content {
+class BrowserContext;
+}
+
+namespace extensions {
+
+// Interface to allow the extensions module to make browser-process-specific
+// queries of the embedder. Should be Set() once in the browser process.
+//
+// NOTE: Methods that do not require knowledge of browser concepts should be
+// added in ExtensionsClient (extensions/common/extensions_client.h) even if
+// they are only used in the browser process.
+class ExtensionsBrowserClient {
+ public:
+  virtual ~ExtensionsBrowserClient() {}
+
+  // Returns true if the embedder has started shutting down.
+  virtual bool IsShuttingDown() = 0;
+
+  // Returns true if the BrowserContexts could be considered equivalent, for
+  // example, if one is an off-the-record context owned by the other.
+  virtual bool IsSameContext(content::BrowserContext* first,
+                             content::BrowserContext* second) = 0;
+
+  // Returns true if |context| has an off-the-record content associated with it.
+  virtual bool HasOffTheRecordContext(content::BrowserContext* context) = 0;
+
+  // Returns the off-the-record context associated with |context|. If |context|
+  // is already off-the-record, returns |context|.
+  // WARNING: This may create a new off-the-record context. To avoid creating
+  // another context, check HasOffTheRecordContext() first.
+  virtual content::BrowserContext* GetOffTheRecordContext(
+      content::BrowserContext* context) = 0;
+
+  // Returns the single instance of |this|.
+  static ExtensionsBrowserClient* Get();
+
+  // Initialize the single instance.
+  static void Set(ExtensionsBrowserClient* client);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_EXTENSIONS_BROWSER_CLIENT_H_
diff --git a/chrome/browser/extensions/lazy_background_task_queue.cc b/extensions/browser/lazy_background_task_queue.cc
similarity index 70%
rename from chrome/browser/extensions/lazy_background_task_queue.cc
rename to extensions/browser/lazy_background_task_queue.cc
index dc0bf4a..584d897 100644
--- a/chrome/browser/extensions/lazy_background_task_queue.cc
+++ b/extensions/browser/lazy_background_task_queue.cc
@@ -1,49 +1,51 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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 "chrome/browser/extensions/lazy_background_task_queue.h"
+#include "extensions/browser/lazy_background_task_queue.h"
 
 #include "base/callback.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/process_map.h"
-#include "chrome/browser/profiles/profile.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_messages.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/web_contents.h"
+#include "extensions/browser/extensions_browser_client.h"
 #include "extensions/common/view_type.h"
 
 namespace extensions {
 
-LazyBackgroundTaskQueue::LazyBackgroundTaskQueue(Profile* profile)
-    : profile_(profile) {
+LazyBackgroundTaskQueue::LazyBackgroundTaskQueue(
+    content::BrowserContext* browser_context)
+    : browser_context_(browser_context) {
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
                  content::NotificationService::AllBrowserContextsAndSources());
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
                  content::NotificationService::AllBrowserContextsAndSources());
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
-                 content::Source<Profile>(profile));
+                 content::Source<content::BrowserContext>(browser_context));
 }
 
 LazyBackgroundTaskQueue::~LazyBackgroundTaskQueue() {
 }
 
 bool LazyBackgroundTaskQueue::ShouldEnqueueTask(
-    Profile* profile, const Extension* extension) {
+    content::BrowserContext* browser_context,
+    const Extension* extension) {
   DCHECK(extension);
   if (BackgroundInfo::HasBackgroundPage(extension)) {
-    ExtensionProcessManager* pm = ExtensionSystem::Get(profile)->
-        process_manager();
+    ExtensionProcessManager* pm = ExtensionSystem::GetForBrowserContext(
+        browser_context)->process_manager();
     DCHECK(pm);
     ExtensionHost* background_host =
         pm->GetBackgroundHostForExtension(extension->id());
@@ -57,30 +59,30 @@
 }
 
 void LazyBackgroundTaskQueue::AddPendingTask(
-    Profile* profile,
+    content::BrowserContext* browser_context,
     const std::string& extension_id,
     const PendingTask& task) {
-  if (g_browser_process->IsShuttingDown()) {
+  if (ExtensionsBrowserClient::Get()->IsShuttingDown()) {
     task.Run(NULL);
     return;
   }
   PendingTasksList* tasks_list = NULL;
-  PendingTasksKey key(profile, extension_id);
+  PendingTasksKey key(browser_context, extension_id);
   PendingTasksMap::iterator it = pending_tasks_.find(key);
   if (it == pending_tasks_.end()) {
     tasks_list = new PendingTasksList();
     pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list);
 
-    ExtensionService* extension_service =
-        ExtensionSystem::Get(profile)->extension_service();
+    ExtensionService* extension_service = ExtensionSystem::GetForBrowserContext(
+        browser_context)->extension_service();
     DCHECK(extension_service);
     const Extension* extension =
         extension_service->extensions()->GetByID(extension_id);
     if (extension && BackgroundInfo::HasLazyBackgroundPage(extension)) {
       // If this is the first enqueued task, and we're not waiting for the
       // background page to unload, ensure the background page is loaded.
-      ExtensionProcessManager* pm =
-          ExtensionSystem::Get(profile)->process_manager();
+      ExtensionProcessManager* pm = ExtensionSystem::GetForBrowserContext(
+          browser_context)->process_manager();
       pm->IncrementLazyKeepaliveCount(extension);
       // Creating the background host may fail, e.g. if |profile| is incognito
       // but the extension isn't enabled in incognito mode.
@@ -99,12 +101,13 @@
 
 void LazyBackgroundTaskQueue::ProcessPendingTasks(
     ExtensionHost* host,
-    Profile* profile,
+    content::BrowserContext* browser_context,
     const Extension* extension) {
-  if (!profile->IsSameProfile(profile_))
+  if (!ExtensionsBrowserClient::Get()->IsSameContext(browser_context,
+                                                     browser_context_))
     return;
 
-  PendingTasksKey key(profile, extension->id());
+  PendingTasksKey key(browser_context, extension->id());
   PendingTasksMap::iterator map_it = pending_tasks_.find(key);
   if (map_it == pending_tasks_.end()) {
     if (BackgroundInfo::HasLazyBackgroundPage(extension))
@@ -126,7 +129,7 @@
   // Balance the keepalive in AddPendingTask. Note we don't do this on a
   // failure to load, because the keepalive count is reset in that case.
   if (host && BackgroundInfo::HasLazyBackgroundPage(extension)) {
-    ExtensionSystem::Get(profile)->process_manager()->
+    ExtensionSystem::GetForBrowserContext(browser_context)->process_manager()->
         DecrementLazyKeepaliveCount(extension);
   }
 }
@@ -143,7 +146,7 @@
           content::Details<ExtensionHost>(details).ptr();
       if (host->extension_host_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
         CHECK(host->did_stop_loading());
-        ProcessPendingTasks(host, host->profile(), host->extension());
+        ProcessPendingTasks(host, host->browser_context(), host->extension());
       }
       break;
     }
@@ -152,23 +155,30 @@
       // This can happen if the extension crashes. This is not strictly
       // necessary, since we also unload the extension in that case (which
       // dispatches the tasks below), but is a good extra precaution.
-      Profile* profile = content::Source<Profile>(source).ptr();
+      content::BrowserContext* browser_context =
+          content::Source<content::BrowserContext>(source).ptr();
       ExtensionHost* host =
            content::Details<ExtensionHost>(details).ptr();
       if (host->extension_host_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
-        ProcessPendingTasks(NULL, profile, host->extension());
+        ProcessPendingTasks(NULL, browser_context, host->extension());
       }
       break;
     }
     case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
       // Notify consumers that the page failed to load.
-      Profile* profile = content::Source<Profile>(source).ptr();
+      content::BrowserContext* browser_context =
+          content::Source<content::BrowserContext>(source).ptr();
       UnloadedExtensionInfo* unloaded =
           content::Details<UnloadedExtensionInfo>(details).ptr();
-      ProcessPendingTasks(NULL, profile, unloaded->extension);
-      if (profile->HasOffTheRecordProfile()) {
-        ProcessPendingTasks(NULL, profile->GetOffTheRecordProfile(),
-                            unloaded->extension);
+      ProcessPendingTasks(NULL, browser_context, unloaded->extension);
+      // If this extension is also running in an off-the-record context,
+      // notify that task queue as well.
+      ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get();
+      if (browser_client->HasOffTheRecordContext(browser_context)) {
+        ProcessPendingTasks(
+            NULL,
+            browser_client->GetOffTheRecordContext(browser_context),
+            unloaded->extension);
       }
       break;
     }
diff --git a/chrome/browser/extensions/lazy_background_task_queue.h b/extensions/browser/lazy_background_task_queue.h
similarity index 76%
rename from chrome/browser/extensions/lazy_background_task_queue.h
rename to extensions/browser/lazy_background_task_queue.h
index d6419d5..a92ec7c3 100644
--- a/chrome/browser/extensions/lazy_background_task_queue.h
+++ b/extensions/browser/lazy_background_task_queue.h
@@ -1,21 +1,23 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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 CHROME_BROWSER_EXTENSIONS_LAZY_BACKGROUND_TASK_QUEUE_H_
-#define CHROME_BROWSER_EXTENSIONS_LAZY_BACKGROUND_TASK_QUEUE_H_
+#ifndef EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_
+#define EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_
 
 #include <map>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/callback_forward.h"
+#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/linked_ptr.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 
-class Profile;
+namespace content {
+class BrowserContext;
+}
 
 namespace extensions {
 class Extension;
@@ -31,7 +33,7 @@
  public:
   typedef base::Callback<void(ExtensionHost*)> PendingTask;
 
-  explicit LazyBackgroundTaskQueue(Profile* profile);
+  explicit LazyBackgroundTaskQueue(content::BrowserContext* browser_context);
   virtual ~LazyBackgroundTaskQueue();
 
   // Returns the number of extensions having pending tasks.
@@ -41,7 +43,8 @@
   // extension has a lazy background page that isn't ready yet). If the
   // extension has a lazy background page that is being suspended this method
   // cancels that suspension.
-  bool ShouldEnqueueTask(Profile* profile, const Extension* extension);
+  bool ShouldEnqueueTask(content::BrowserContext* context,
+                         const Extension* extension);
 
   // Adds a task to the queue for a given extension. If this is the first
   // task added for the extension, its lazy background page will be loaded.
@@ -49,17 +52,17 @@
   // page fails to load for some reason (e.g. a crash or browser
   // shutdown). In the latter case, the ExtensionHost parameter is NULL.
   void AddPendingTask(
-      Profile* profile,
+      content::BrowserContext* context,
       const std::string& extension_id,
       const PendingTask& task);
 
  private:
   FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest, ProcessPendingTasks);
 
-  // A map between an extension_id,Profile pair and the queue of tasks pending
-  // the load of its background page.
+  // A map between a BrowserContext/extension_id pair and the queue of tasks
+  // pending the load of its background page.
   typedef std::string ExtensionID;
-  typedef std::pair<Profile*, ExtensionID> PendingTasksKey;
+  typedef std::pair<content::BrowserContext*, ExtensionID> PendingTasksKey;
   typedef std::vector<PendingTask> PendingTasksList;
   typedef std::map<PendingTasksKey,
                    linked_ptr<PendingTasksList> > PendingTasksMap;
@@ -73,14 +76,14 @@
   // load (host is NULL in that case). All enqueued tasks are run in order.
   void ProcessPendingTasks(
       ExtensionHost* host,
-      Profile* profile,
+      content::BrowserContext* context,
       const Extension* extension);
 
-  Profile* profile_;
+  content::BrowserContext* browser_context_;
   content::NotificationRegistrar registrar_;
   PendingTasksMap pending_tasks_;
 };
 
 }  // namespace extensions
 
-#endif  // CHROME_BROWSER_EXTENSIONS_LAZY_BACKGROUND_TASK_QUEUE_H_
+#endif  // EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_
diff --git a/chrome/browser/extensions/lazy_background_task_queue_unittest.cc b/extensions/browser/lazy_background_task_queue_unittest.cc
similarity index 95%
rename from chrome/browser/extensions/lazy_background_task_queue_unittest.cc
rename to extensions/browser/lazy_background_task_queue_unittest.cc
index df68492b..27d84715 100644
--- a/chrome/browser/extensions/lazy_background_task_queue_unittest.cc
+++ b/extensions/browser/lazy_background_task_queue_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/extensions/lazy_background_task_queue.h"
+#include "extensions/browser/lazy_background_task_queue.h"
 
 #include "base/bind.h"
 #include "base/command_line.h"
@@ -179,6 +179,12 @@
   EXPECT_EQ(0, task_run_count());
   EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
 
+  // Trying to run tasks for an unrelated profile should do nothing.
+  TestingProfile profile2;
+  queue.ProcessPendingTasks(NULL, &profile2, extension);
+  EXPECT_EQ(0, task_run_count());
+  EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
+
   // Processing tasks when there is one pending runs the task and removes the
   // extension from the list of extensions with pending tasks.
   queue.ProcessPendingTasks(NULL, profile_.get(), extension);
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index 335eff9..e54d965 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -112,10 +112,14 @@
         'browser/extension_prefs_scope.h',
         'browser/extension_error.cc',
         'browser/extension_error.h',
+        'browser/extensions_browser_client.cc',
+        'browser/extensions_browser_client.h',
         'browser/file_highlighter.cc',
         'browser/file_highlighter.h',
         'browser/file_reader.cc',
         'browser/file_reader.h',
+        'browser/lazy_background_task_queue.cc',
+        'browser/lazy_background_task_queue.h',
         'browser/pref_names.cc',
         'browser/pref_names.h',
         'browser/view_type_utils.cc',