1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
#include <map>
#include <string>
#include "base/basictypes.h"
#include "base/singleton.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/common/notification_registrar.h"
// The ExtensionBrowserEventRouter listens to Browser window & tab events
// and routes them to listeners inside extension process renderers.
// ExtensionBrowserEventRouter listens to *all* events, but will only route
// events from windows/tabs within a profile to extension processes in the same
// profile.
class ExtensionBrowserEventRouter : public TabStripModelObserver,
public BrowserList::Observer,
public NotificationObserver {
public:
// Get Browser-Global instance.
static ExtensionBrowserEventRouter* GetInstance();
// Must be called once. Subsequent calls have no effect.
void Init();
// BrowserList::Observer
virtual void OnBrowserAdded(const Browser* browser);
virtual void OnBrowserRemoving(const Browser* browser);
virtual void OnBrowserSetLastActive(const Browser* browser);
// Called from Observe() on BROWSER_WINDOW_READY (not a part of
// BrowserList::Observer).
void OnBrowserWindowReady(const Browser* browser);
// TabStripModelObserver
void TabInsertedAt(TabContents* contents, int index, bool foreground);
void TabClosingAt(TabContents* contents, int index);
void TabDetachedAt(TabContents* contents, int index);
void TabSelectedAt(TabContents* old_contents,
TabContents* new_contents,
int index,
bool user_gesture);
void TabMoved(TabContents* contents, int from_index, int to_index,
bool pinned_state_changed);
void TabChangedAt(TabContents* contents, int index, bool loading_only);
void TabStripEmpty();
// Page Action execute event.
void PageActionExecuted(Profile* profile,
const std::string& extension_id,
const std::string& page_action_id,
int tab_id,
const std::string& url,
int button);
// Browser Actions execute event.
void BrowserActionExecuted(Profile* profile,
const std::string& extension_id,
int window_id);
// NotificationObserver.
void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details);
private:
// "Synthetic" event. Called from TabInsertedAt if new tab is detected.
void TabCreatedAt(TabContents* contents, int index, bool foreground);
// Internal processing of tab updated events. Is called by both TabChangedAt
// and Observe/NAV_ENTRY_COMMITTED.
void TabUpdated(TabContents* contents, bool did_navigate);
ExtensionBrowserEventRouter();
friend struct DefaultSingletonTraits<ExtensionBrowserEventRouter>;
NotificationRegistrar registrar_;
bool initialized_;
// Maintain some information about known tabs, so we can:
//
// - distinguish between tab creation and tab insertion
// - not send tab-detached after tab-removed
// - reduce the "noise" of TabChangedAt() when sending events to extensions
class TabEntry {
public:
// Create a new tab entry whose initial state is TAB_COMPLETE. This
// constructor is required because TabEntry objects placed inside an
// std::map<> by value.
TabEntry();
// Create a new tab entry whose initial state is derived from the given
// tab contents.
explicit TabEntry(const TabContents* contents);
// Returns the current state of the tab.
ExtensionTabUtil::TabStatus state() const { return state_; }
// Update the load state of the tab based on its TabContents. Returns true
// if the state changed, false otherwise. Whether the state has changed or
// not is used to determine if events needs to be sent to extensions during
// processing of TabChangedAt(). This method will "hold" a state-change
// to "loading", until the DidNavigate() method which should always follow
// it. Returns NULL if no updates should be sent.
DictionaryValue* UpdateLoadState(const TabContents* contents);
// Indicates that a tab load has resulted in a navigation and the
// destination url is available for inspection. Returns NULL if no updates
// should be sent.
DictionaryValue* DidNavigate(const TabContents* contents);
private:
// Tab state used for last notification to extensions.
ExtensionTabUtil::TabStatus state_;
// Remember that the LOADING state has been captured, but not yet reported
// because it is waiting on the navigation event to know what the
// destination url is.
bool pending_navigate_;
GURL url_;
};
std::map<int, TabEntry> tab_entries_;
DISALLOW_COPY_AND_ASSIGN(ExtensionBrowserEventRouter);
};
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
|