Unrevert again r119770 - "Event pages: remember events that the page registered for,""

Original CL:
Add support for broadcasted events.

Add an extension.onInstalled event that is run when the event page first
starts."

Fixed ASAN bug with previous incarnation.

Previous revert did not fix failing tests, so it's going back in.

TBR=aa
BUG=81752, 112391
TEST=no

Review URL: https://chromiumcodereview.appspot.com/9350006

Review URL: https://chromiumcodereview.appspot.com/9350024

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120808 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_event_router.h b/chrome/browser/extensions/extension_event_router.h
index 6624d98..b142198 100644
--- a/chrome/browser/extensions/extension_event_router.h
+++ b/chrome/browser/extensions/extension_event_router.h
@@ -50,6 +50,15 @@
                            content::RenderProcessHost* process,
                            const std::string& extension_id);
 
+  // Add or remove the extension as having a lazy background page that listens
+  // to the event. The difference from the above methods is that these will be
+  // remembered even after the process goes away. We use this list to decide
+  // which extension pages to load when dispatching an event.
+  void AddLazyEventListener(const std::string& event_name,
+                            const std::string& extension_id);
+  void RemoveLazyEventListener(const std::string& event_name,
+                               const std::string& extension_id);
+
   // Returns true if there is at least one listener for the given event.
   bool HasEventListener(const std::string& event_name);
 
@@ -105,15 +114,25 @@
   // Shared by DispatchEvent*. If |extension_id| is empty, the event is
   // broadcast.
   // An event that just came off the pending list may not be delayed again.
-  void DispatchEventImpl(const linked_ptr<ExtensionEvent>& event,
+  void DispatchEventImpl(const std::string& extension_id,
+                         const linked_ptr<ExtensionEvent>& event,
                          bool was_pending);
 
+  // Ensures that all non-persistent background pages that are interested in the
+  // given event are loaded, and queues the event if the page is not ready yet.
+  // If |extension_id| is non-empty, we load only that extension's page
+  // (assuming it is interested in the event).
+  void LoadLazyBackgroundPagesForEvent(
+      const std::string& extension_id,
+      const linked_ptr<ExtensionEvent>& event);
+
   // Dispatch may be delayed if the extension has a lazy background page.
-  bool CanDispatchEventNow(const std::string& extension_id);
+  bool CanDispatchEventNow(const Extension* extension);
 
   // Store the event so that it can be dispatched (in order received)
   // when the background page is done loading.
-  void AppendEvent(const linked_ptr<ExtensionEvent>& event);
+  void AppendEvent(const std::string& extension_id,
+                   const linked_ptr<ExtensionEvent>& event);
   void DispatchPendingEvents(const std::string& extension_id);
 
  private:
@@ -135,6 +154,11 @@
   typedef std::map<std::string, std::set<EventListener> > ListenerMap;
   ListenerMap listeners_;
 
+  // Keeps track of all the non-persistent background pages that are listening
+  // to events.
+  // TODO(mpcomplete): save to disk.
+  ListenerMap lazy_listeners_;
+
   // A map between an extension id and the queue of events pending
   // the load of it's background page.
   typedef std::vector<linked_ptr<ExtensionEvent> > PendingEventsList;