Make the inspector for the background page stay open when
reloading an extension.

BUG=25287
TEST=Load an extension that has a background page and reload it. Inspector should stay open and continue
working.

Review URL: http://codereview.chromium.org/371040

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31335 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index a2193ef..2323e6dd9 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -12,11 +12,13 @@
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/debugger/devtools_manager.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_browser_event_router.h"
 #include "chrome/browser/extensions/extension_dom_ui.h"
 #include "chrome/browser/extensions/extension_file_util.h"
 #include "chrome/browser/extensions/extension_history_api.h"
+#include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_updater.h"
 #include "chrome/browser/extensions/external_extension_provider.h"
 #include "chrome/browser/extensions/external_pref_extension_provider.h"
@@ -27,6 +29,7 @@
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_error_reporter.h"
 #include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/pref_service.h"
 #include "chrome/common/url_constants.h"
@@ -99,6 +102,9 @@
     extensions_enabled_ = false;
   }
 
+  registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
+                 NotificationService::AllSources());
+
   // Set up the ExtensionUpdater
   if (autoupdate_enabled) {
     int update_frequency = kDefaultUpdateFrequencySeconds;
@@ -171,6 +177,20 @@
 
   // Unload the extension if it's loaded. It might not be loaded if it crashed.
   if (current_extension) {
+    // If the extension has an inspector open for its background page, detach
+    // the inspector and hang onto a cookie for it, so that we can reattach
+    // later.
+    ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
+    ExtensionHost* host = manager->GetBackgroundHostForExtension(
+        current_extension);
+    if (host) {
+      // Look for an open inspector for the background page.
+      int devtools_cookie = DevToolsManager::GetInstance()->DetachClientHost(
+          host->render_view_host());
+      if (devtools_cookie >= 0)
+        orphaned_dev_tools_[extension_id] = devtools_cookie;
+    }
+
     path = current_extension->path();
     UnloadExtension(extension_id);
   }
@@ -757,6 +777,29 @@
   return result;
 }
 
+void ExtensionsService::Observe(NotificationType type,
+                                const NotificationSource& source,
+                                const NotificationDetails& details) {
+  switch (type.value) {
+    case NotificationType::EXTENSION_HOST_DID_STOP_LOADING: {
+      ExtensionHost* host = Details<ExtensionHost>(details).ptr();
+      OrphanedDevTools::iterator iter =
+          orphaned_dev_tools_.find(host->extension()->id());
+      if (iter == orphaned_dev_tools_.end())
+        return;
+
+      DevToolsManager::GetInstance()->AttachClientHost(
+          iter->second, host->render_view_host());
+      orphaned_dev_tools_.erase(iter);
+      break;
+    }
+
+    default:
+      NOTREACHED() << "Unexpected notification type.";
+  }
+}
+
+
 // ExtensionsServicesBackend
 
 ExtensionsServiceBackend::ExtensionsServiceBackend(