Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
      6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
      7 #pragma once
      8 
      9 #include <map>
     10 #include <string>
     11 
     12 #include "base/basictypes.h"
     13 #include "chrome/browser/extensions/extension_tabs_module.h"
     14 #include "chrome/browser/tabs/tab_strip_model_observer.h"
     15 #include "chrome/browser/ui/browser_list.h"
     16 #include "content/common/notification_registrar.h"
     17 #if defined(TOOLKIT_VIEWS)
     18 #include "views/focus/focus_manager.h"
     19 #include "views/view.h"
     20 #elif defined(TOOLKIT_GTK)
     21 #include "ui/base/x/active_window_watcher_x.h"
     22 #endif
     23 
     24 // The ExtensionBrowserEventRouter listens to Browser window & tab events
     25 // and routes them to listeners inside extension process renderers.
     26 // ExtensionBrowserEventRouter listens to *all* events, but will only route
     27 // events from windows/tabs within a profile to extension processes in the same
     28 // profile.
     29 class ExtensionBrowserEventRouter : public TabStripModelObserver,
     30 #if defined(TOOLKIT_VIEWS)
     31                                     public views::WidgetFocusChangeListener,
     32 #elif defined(TOOLKIT_GTK)
     33                                     public ui::ActiveWindowWatcherX::Observer,
     34 #endif
     35                                     public BrowserList::Observer,
     36                                     public NotificationObserver {
     37  public:
     38   explicit ExtensionBrowserEventRouter(Profile* profile);
     39   ~ExtensionBrowserEventRouter();
     40 
     41   // Must be called once. Subsequent calls have no effect.
     42   void Init();
     43 
     44   // BrowserList::Observer
     45   virtual void OnBrowserAdded(const Browser* browser);
     46   virtual void OnBrowserRemoved(const Browser* browser);
     47   virtual void OnBrowserSetLastActive(const Browser* browser);
     48 
     49 #if defined(TOOLKIT_VIEWS)
     50   virtual void NativeFocusWillChange(gfx::NativeView focused_before,
     51                                      gfx::NativeView focused_now);
     52 #elif defined(TOOLKIT_GTK)
     53   virtual void ActiveWindowChanged(GdkWindow* active_window);
     54 #endif
     55 
     56   // Called from Observe() on BROWSER_WINDOW_READY (not a part of
     57   // BrowserList::Observer).
     58   void OnBrowserWindowReady(const Browser* browser);
     59 
     60   // TabStripModelObserver
     61   virtual void TabInsertedAt(TabContentsWrapper* contents, int index,
     62                              bool foreground);
     63   virtual void TabClosingAt(TabStripModel* tab_strip_model,
     64                             TabContentsWrapper* contents,
     65                             int index);
     66   virtual void TabDetachedAt(TabContentsWrapper* contents, int index);
     67   virtual void TabSelectedAt(TabContentsWrapper* old_contents,
     68                              TabContentsWrapper* new_contents,
     69                              int index,
     70                              bool user_gesture);
     71   virtual void TabMoved(TabContentsWrapper* contents, int from_index,
     72                         int to_index);
     73   virtual void TabChangedAt(TabContentsWrapper* contents, int index,
     74                             TabChangeType change_type);
     75   virtual void TabReplacedAt(TabStripModel* tab_strip_model,
     76                              TabContentsWrapper* old_contents,
     77                              TabContentsWrapper* new_contents,
     78                              int index);
     79   virtual void TabPinnedStateChanged(TabContentsWrapper* contents, int index);
     80   virtual void TabStripEmpty();
     81 
     82   // Page Action execute event.
     83   void PageActionExecuted(Profile* profile,
     84                           const std::string& extension_id,
     85                           const std::string& page_action_id,
     86                           int tab_id,
     87                           const std::string& url,
     88                           int button);
     89   // Browser Actions execute event.
     90   void BrowserActionExecuted(Profile* profile,
     91                              const std::string& extension_id,
     92                              Browser* browser);
     93 
     94   // NotificationObserver.
     95   virtual void Observe(NotificationType type,
     96                        const NotificationSource& source,
     97                        const NotificationDetails& details);
     98  private:
     99   // "Synthetic" event. Called from TabInsertedAt if new tab is detected.
    100   void TabCreatedAt(TabContents* contents, int index, bool foreground);
    101 
    102   // Internal processing of tab updated events. Is called by both TabChangedAt
    103   // and Observe/NAV_ENTRY_COMMITTED.
    104   void TabUpdated(TabContents* contents, bool did_navigate);
    105 
    106   // Packages |changed_properties| as a tab updated event for the tab |contents|
    107   // and dispatches the event to the extension.
    108   void DispatchTabUpdatedEvent(TabContents* contents,
    109                                DictionaryValue* changed_properties);
    110 
    111   // Called to dispatch a deprecated style page action click event that was
    112   // registered like:
    113   //   chrome.pageActions["name"].addListener(function(actionId, info){})
    114   void DispatchOldPageActionEvent(Profile* profile,
    115     const std::string& extension_id,
    116     const std::string& page_action_id,
    117     int tab_id,
    118     const std::string& url,
    119     int button);
    120 
    121   // Register ourselves to receive the various notifications we are interested
    122   // in for a browser.
    123   void RegisterForBrowserNotifications(const Browser* browser);
    124 
    125   // Register ourselves to receive the various notifications we are interested
    126   // in for a tab.
    127   void RegisterForTabNotifications(TabContents* contents);
    128 
    129   // Removes notifications added in RegisterForTabNotifications.
    130   void UnregisterForTabNotifications(TabContents* contents);
    131 
    132   NotificationRegistrar registrar_;
    133 
    134   bool initialized_;
    135 
    136   // Maintain some information about known tabs, so we can:
    137   //
    138   //  - distinguish between tab creation and tab insertion
    139   //  - not send tab-detached after tab-removed
    140   //  - reduce the "noise" of TabChangedAt() when sending events to extensions
    141   class TabEntry {
    142    public:
    143     // Create a new tab entry whose initial state is TAB_COMPLETE.  This
    144     // constructor is required because TabEntry objects placed inside an
    145     // std::map<> by value.
    146     TabEntry();
    147 
    148     // Update the load state of the tab based on its TabContents.  Returns true
    149     // if the state changed, false otherwise.  Whether the state has changed or
    150     // not is used to determine if events needs to be sent to extensions during
    151     // processing of TabChangedAt(). This method will "hold" a state-change
    152     // to "loading", until the DidNavigate() method which should always follow
    153     // it. Returns NULL if no updates should be sent.
    154     DictionaryValue* UpdateLoadState(const TabContents* contents);
    155 
    156     // Indicates that a tab load has resulted in a navigation and the
    157     // destination url is available for inspection. Returns NULL if no updates
    158     // should be sent.
    159     DictionaryValue* DidNavigate(const TabContents* contents);
    160 
    161    private:
    162     // Whether we are waiting to fire the 'complete' status change. This will
    163     // occur the first time the TabContents stops loading after the
    164     // NAV_ENTRY_COMMITTED was fired. The tab may go back into and out of the
    165     // loading state subsequently, but we will ignore those changes.
    166     bool complete_waiting_on_load_;
    167 
    168     GURL url_;
    169   };
    170 
    171   // Gets the TabEntry for the given |contents|. Returns TabEntry* if
    172   // found, NULL if not.
    173   TabEntry* GetTabEntry(const TabContents* contents);
    174 
    175   std::map<int, TabEntry> tab_entries_;
    176 
    177   // The currently focused window. We keep this so as to avoid sending multiple
    178   // windows.onFocusChanged events with the same windowId.
    179   int focused_window_id_;
    180 
    181   // The main profile (non-OTR) profile which will be used to send events not
    182   // associated with any browser.
    183   Profile* profile_;
    184 
    185   DISALLOW_COPY_AND_ASSIGN(ExtensionBrowserEventRouter);
    186 };
    187 
    188 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
    189