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