summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.cc55
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.h8
-rw-r--r--chrome/browser/extensions/extensions_service.cc9
3 files changed, 59 insertions, 13 deletions
diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc
index ad0d701..4e9bab3 100644
--- a/chrome/browser/extensions/extension_browser_event_router.cc
+++ b/chrome/browser/extensions/extension_browser_event_router.cc
@@ -111,6 +111,23 @@ void ExtensionBrowserEventRouter::Init() {
BrowserList::AddObserver(this);
+ // Init() can happen after the browser is running, so catch up with any
+ // windows that already exist.
+ for (BrowserList::const_iterator iter = BrowserList::begin();
+ iter != BrowserList::end(); ++iter) {
+ RegisterForBrowserNotifications(*iter);
+
+ // Also catch up our internal bookkeeping of tab entries.
+ Browser* browser = *iter;
+ if (browser->tabstrip_model()) {
+ for (int i = 0; i < browser->tabstrip_model()->count(); ++i) {
+ TabContents* contents = browser->tabstrip_model()->GetTabContentsAt(i);
+ int tab_id = ExtensionTabUtil::GetTabId(contents);
+ tab_entries_[tab_id] = TabEntry(contents);
+ }
+ }
+ }
+
initialized_ = true;
}
@@ -118,12 +135,38 @@ ExtensionBrowserEventRouter::ExtensionBrowserEventRouter()
: initialized_(false) { }
void ExtensionBrowserEventRouter::OnBrowserAdded(const Browser* browser) {
+ RegisterForBrowserNotifications(browser);
+}
+
+void ExtensionBrowserEventRouter::RegisterForBrowserNotifications(
+ const Browser* browser) {
// Start listening to TabStripModel events for this browser.
browser->tabstrip_model()->AddObserver(this);
- // The window isn't ready at this point, so we defer until it is.
+ // If this is a new window, it isn't ready at this point, so we register to be
+ // notified when it is. If this is an existing window, this is a no-op that we
+ // just do to reduce code complexity.
registrar_.Add(this, NotificationType::BROWSER_WINDOW_READY,
Source<const Browser>(browser));
+
+ if (browser->tabstrip_model()) {
+ for (int i = 0; i < browser->tabstrip_model()->count(); ++i)
+ RegisterForTabNotifications(
+ browser->tabstrip_model()->GetTabContentsAt(i));
+ }
+}
+
+void ExtensionBrowserEventRouter::RegisterForTabNotifications(
+ TabContents* contents) {
+ registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(&contents->controller()));
+
+ // Observing TAB_CONTENTS_DESTROYED is necessary because it's
+ // possible for tabs to be created, detached and then destroyed without
+ // ever having been re-attached and closed. This happens in the case of
+ // a devtools TabContents that is opened in window, docked, then closed.
+ registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
+ Source<TabContents>(contents));
}
void ExtensionBrowserEventRouter::OnBrowserWindowReady(const Browser* browser) {
@@ -168,15 +211,7 @@ void ExtensionBrowserEventRouter::TabCreatedAt(TabContents* contents,
DispatchEvent(contents->profile(), events::kOnTabCreated, json_args);
- registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
- Source<NavigationController>(&contents->controller()));
-
- // Observing TAB_CONTENTS_DESTROYED is necessary because it's
- // possible for tabs to be created, detached and then destroyed without
- // ever having been re-attached and closed. This happens in the case of
- // a devtools TabContents that is opened in window, docked, then closed.
- registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
- Source<TabContents>(contents));
+ RegisterForTabNotifications(contents);
}
void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents,
diff --git a/chrome/browser/extensions/extension_browser_event_router.h b/chrome/browser/extensions/extension_browser_event_router.h
index 788229d..49d3351 100644
--- a/chrome/browser/extensions/extension_browser_event_router.h
+++ b/chrome/browser/extensions/extension_browser_event_router.h
@@ -77,6 +77,14 @@ class ExtensionBrowserEventRouter : public TabStripModelObserver,
// and Observe/NAV_ENTRY_COMMITTED.
void TabUpdated(TabContents* contents, bool did_navigate);
+ // Register ourselves to receive the various notifications we are interested
+ // in for a browser.
+ void RegisterForBrowserNotifications(const Browser* browser);
+
+ // Register ourselves to receive the various notifications we are interested
+ // in for a tab.
+ void RegisterForTabNotifications(TabContents* contents);
+
ExtensionBrowserEventRouter();
friend struct DefaultSingletonTraits<ExtensionBrowserEventRouter>;
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index ef6d9cd..d681e83d 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -127,9 +127,6 @@ void ExtensionsService::Init() {
// the first extension, because its members listen for loaded notifications.
g_browser_process->resource_dispatcher_host();
- // Start up the extension event routers.
- ExtensionBrowserEventRouter::GetInstance()->Init();
-
LoadAllExtensions();
// TODO(erikkay) this should probably be deferred to a future point
@@ -508,6 +505,12 @@ void ExtensionsService::OnExtensionLoaded(Extension* extension,
case Extension::ENABLED:
extensions_.push_back(scoped_extension.release());
+ // We delay starting up the browser event router until at least one
+ // extension that needs it is loaded.
+ if (extension->HasApiPermission(Extension::kTabPermission)) {
+ ExtensionBrowserEventRouter::GetInstance()->Init();
+ }
+
if (extension->location() != Extension::LOAD)
extension_prefs_->MigrateToPrefs(extension);