Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / tabs / tabs_event_router.h
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.
4
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_TABS_TABS_EVENT_ROUTER_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_TABS_TABS_EVENT_ROUTER_H_
7
8 #include <map>
9 #include <string>
10
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"
18
19 namespace content {
20 class WebContents;
21 }
22
23 namespace extensions {
24
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 {
32  public:
33   explicit TabsEventRouter(Profile* profile);
34   virtual ~TabsEventRouter();
35
36   // chrome::BrowserListObserver
37   virtual void OnBrowserAdded(Browser* browser) OVERRIDE;
38   virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
39   virtual void OnBrowserSetLastActive(Browser* browser) OVERRIDE;
40
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,
46                             int index) OVERRIDE;
47   virtual void TabDetachedAt(content::WebContents* contents,
48                              int index) OVERRIDE;
49   virtual void ActiveTabChanged(content::WebContents* old_contents,
50                                 content::WebContents* new_contents,
51                                 int index,
52                                 int reason) OVERRIDE;
53   virtual void TabSelectionChanged(
54       TabStripModel* tab_strip_model,
55       const ui::ListSelectionModel& old_model) OVERRIDE;
56   virtual void TabMoved(content::WebContents* contents,
57                         int from_index,
58                         int to_index) OVERRIDE;
59   virtual void TabChangedAt(content::WebContents* contents,
60                             int index,
61                             TabChangeType change_type) OVERRIDE;
62   virtual void TabReplacedAt(TabStripModel* tab_strip_model,
63                              content::WebContents* old_contents,
64                              content::WebContents* new_contents,
65                              int index) OVERRIDE;
66   virtual void TabPinnedStateChanged(content::WebContents* contents,
67                                      int index) OVERRIDE;
68
69   // content::NotificationObserver.
70   virtual void Observe(int type,
71                        const content::NotificationSource& source,
72                        const content::NotificationDetails& details) OVERRIDE;
73  private:
74   // "Synthetic" event. Called from TabInsertedAt if new tab is detected.
75   void TabCreatedAt(content::WebContents* contents, int index, bool active);
76
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);
80
81   // Triggers a tab updated event if the favicon URL changes.
82   void FaviconUrlUpdated(content::WebContents* contents);
83
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);
91
92   void DispatchEventsAcrossIncognito(
93       Profile* profile,
94       const std::string& event_name,
95       scoped_ptr<base::ListValue> event_args,
96       scoped_ptr<base::ListValue> cross_incognito_args);
97
98   void DispatchSimpleBrowserEvent(Profile* profile,
99                                   const int window_id,
100                                   const std::string& event_name);
101
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);
107
108   // Register ourselves to receive the various notifications we are interested
109   // in for a browser.
110   void RegisterForBrowserNotifications(Browser* browser);
111
112   // Register ourselves to receive the various notifications we are interested
113   // in for a tab.
114   void RegisterForTabNotifications(content::WebContents* contents);
115
116   // Removes notifications added in RegisterForTabNotifications.
117   void UnregisterForTabNotifications(content::WebContents* contents);
118
119   content::NotificationRegistrar registrar_;
120
121   // Maintain some information about known tabs, so we can:
122   //
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
126   class TabEntry {
127    public:
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.
131     TabEntry();
132
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);
141
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
144     // should be sent.
145     base::DictionaryValue* DidNavigate(const content::WebContents* contents);
146
147    private:
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_;
153
154     GURL url_;
155   };
156
157   // Gets the TabEntry for the given |contents|. Returns TabEntry* if
158   // found, NULL if not.
159   TabEntry* GetTabEntry(content::WebContents* contents);
160
161   std::map<int, TabEntry> tab_entries_;
162
163   // The main profile that owns this event router.
164   Profile* profile_;
165
166   DISALLOW_COPY_AND_ASSIGN(TabsEventRouter);
167 };
168
169 }  // namespace extensions
170
171 #endif  // CHROME_BROWSER_EXTENSIONS_API_TABS_TABS_EVENT_ROUTER_H_