1 // Copyright 2013 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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_TABS_TABS_EVENT_ROUTER_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_TABS_TABS_EVENT_ROUTER_H_
11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h"
13 #include "chrome/browser/extensions/api/tabs/tabs_api.h"
14 #include "chrome/browser/ui/browser_list_observer.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
16 #include "content/public/browser/notification_registrar.h"
17 #include "extensions/browser/event_router.h"
23 namespace extensions
{
25 // The TabsEventRouter listens to tab events and routes them to listeners inside
26 // extension process renderers.
27 // TabsEventRouter will only route events from windows/tabs within a profile to
28 // extension processes in the same profile.
29 class TabsEventRouter
: public TabStripModelObserver
,
30 public chrome::BrowserListObserver
,
31 public content::NotificationObserver
{
33 explicit TabsEventRouter(Profile
* profile
);
34 virtual ~TabsEventRouter();
36 // chrome::BrowserListObserver
37 virtual void OnBrowserAdded(Browser
* browser
) OVERRIDE
;
38 virtual void OnBrowserRemoved(Browser
* browser
) OVERRIDE
;
39 virtual void OnBrowserSetLastActive(Browser
* browser
) OVERRIDE
;
41 // TabStripModelObserver
42 virtual void TabInsertedAt(content::WebContents
* contents
, int index
,
43 bool active
) OVERRIDE
;
44 virtual void TabClosingAt(TabStripModel
* tab_strip_model
,
45 content::WebContents
* contents
,
47 virtual void TabDetachedAt(content::WebContents
* contents
,
49 virtual void ActiveTabChanged(content::WebContents
* old_contents
,
50 content::WebContents
* new_contents
,
53 virtual void TabSelectionChanged(
54 TabStripModel
* tab_strip_model
,
55 const ui::ListSelectionModel
& old_model
) OVERRIDE
;
56 virtual void TabMoved(content::WebContents
* contents
,
58 int to_index
) OVERRIDE
;
59 virtual void TabChangedAt(content::WebContents
* contents
,
61 TabChangeType change_type
) OVERRIDE
;
62 virtual void TabReplacedAt(TabStripModel
* tab_strip_model
,
63 content::WebContents
* old_contents
,
64 content::WebContents
* new_contents
,
66 virtual void TabPinnedStateChanged(content::WebContents
* contents
,
69 // content::NotificationObserver.
70 virtual void Observe(int type
,
71 const content::NotificationSource
& source
,
72 const content::NotificationDetails
& details
) OVERRIDE
;
74 // "Synthetic" event. Called from TabInsertedAt if new tab is detected.
75 void TabCreatedAt(content::WebContents
* contents
, int index
, bool active
);
77 // Internal processing of tab updated events. Is called by both TabChangedAt
78 // and Observe/NAV_ENTRY_COMMITTED.
79 void TabUpdated(content::WebContents
* contents
, bool did_navigate
);
81 // Triggers a tab updated event if the favicon URL changes.
82 void FaviconUrlUpdated(content::WebContents
* contents
);
84 // The DispatchEvent methods forward events to the |profile|'s event router.
85 // The TabsEventRouter listens to events for all profiles,
86 // so we avoid duplication by dropping events destined for other profiles.
87 void DispatchEvent(Profile
* profile
,
88 const std::string
& event_name
,
89 scoped_ptr
<base::ListValue
> args
,
90 EventRouter::UserGestureState user_gesture
);
92 void DispatchEventsAcrossIncognito(
94 const std::string
& event_name
,
95 scoped_ptr
<base::ListValue
> event_args
,
96 scoped_ptr
<base::ListValue
> cross_incognito_args
);
98 void DispatchSimpleBrowserEvent(Profile
* profile
,
100 const std::string
& event_name
);
102 // Packages |changed_properties| as a tab updated event for the tab |contents|
103 // and dispatches the event to the extension.
104 void DispatchTabUpdatedEvent(
105 content::WebContents
* contents
,
106 scoped_ptr
<base::DictionaryValue
> changed_properties
);
108 // Register ourselves to receive the various notifications we are interested
110 void RegisterForBrowserNotifications(Browser
* browser
);
112 // Register ourselves to receive the various notifications we are interested
114 void RegisterForTabNotifications(content::WebContents
* contents
);
116 // Removes notifications added in RegisterForTabNotifications.
117 void UnregisterForTabNotifications(content::WebContents
* contents
);
119 content::NotificationRegistrar registrar_
;
121 // Maintain some information about known tabs, so we can:
123 // - distinguish between tab creation and tab insertion
124 // - not send tab-detached after tab-removed
125 // - reduce the "noise" of TabChangedAt() when sending events to extensions
128 // Create a new tab entry whose initial state is TAB_COMPLETE. This
129 // constructor is required because TabEntry objects placed inside an
130 // std::map<> by value.
133 // Update the load state of the tab based on its WebContents. Returns true
134 // if the state changed, false otherwise. Whether the state has changed or
135 // not is used to determine if events needs to be sent to extensions during
136 // processing of TabChangedAt(). This method will "hold" a state-change
137 // to "loading", until the DidNavigate() method which should always follow
138 // it. Returns NULL if no updates should be sent.
139 base::DictionaryValue
* UpdateLoadState(
140 const content::WebContents
* contents
);
142 // Indicates that a tab load has resulted in a navigation and the
143 // destination url is available for inspection. Returns NULL if no updates
145 base::DictionaryValue
* DidNavigate(const content::WebContents
* contents
);
148 // Whether we are waiting to fire the 'complete' status change. This will
149 // occur the first time the WebContents stops loading after the
150 // NAV_ENTRY_COMMITTED was fired. The tab may go back into and out of the
151 // loading state subsequently, but we will ignore those changes.
152 bool complete_waiting_on_load_
;
157 // Gets the TabEntry for the given |contents|. Returns TabEntry* if
158 // found, NULL if not.
159 TabEntry
* GetTabEntry(const content::WebContents
* contents
);
161 std::map
<int, TabEntry
> tab_entries_
;
163 // The main profile that owns this event router.
166 DISALLOW_COPY_AND_ASSIGN(TabsEventRouter
);
169 } // namespace extensions
171 #endif // CHROME_BROWSER_EXTENSIONS_API_TABS_TABS_EVENT_ROUTER_H_