Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(439)

Side by Side Diff: chrome/browser/extensions/api/tabs/tabs_event_router.cc

Issue 23724026: BrowserEventRouter -> TabsEventRouter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Yoyo's nits Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/browser_event_router.h" 5 #include "chrome/browser/extensions/api/tabs/tabs_event_router.h"
6 6
7 #include "base/json/json_writer.h" 7 #include "base/json/json_writer.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 #include "chrome/browser/chrome_notification_types.h" 9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" 10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
11 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h" 11 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
12 #include "chrome/browser/extensions/api/tabs/windows_event_router.h" 12 #include "chrome/browser/extensions/api/tabs/windows_event_router.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/extension_system.h" 13 #include "chrome/browser/extensions/extension_system.h"
15 #include "chrome/browser/extensions/extension_tab_util.h" 14 #include "chrome/browser/extensions/extension_tab_util.h"
16 #include "chrome/browser/extensions/window_controller.h"
17 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser.h" 16 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_iterator.h" 17 #include "chrome/browser/ui/browser_iterator.h"
20 #include "chrome/browser/ui/browser_list.h" 18 #include "chrome/browser/ui/browser_list.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h" 19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/extensions/extension_constants.h" 20 #include "chrome/common/extensions/extension_constants.h"
23 #include "content/public/browser/favicon_status.h" 21 #include "content/public/browser/favicon_status.h"
24 #include "content/public/browser/navigation_controller.h" 22 #include "content/public/browser/navigation_controller.h"
25 #include "content/public/browser/navigation_entry.h" 23 #include "content/public/browser/navigation_entry.h"
26 #include "content/public/browser/notification_service.h" 24 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/notification_types.h" 25 #include "content/public/browser/notification_types.h"
28 #include "content/public/browser/web_contents.h" 26 #include "content/public/browser/web_contents.h"
29 27
30 namespace tab_keys = extensions::tabs_constants; 28 using base::DictionaryValue;
31 29 using base::ListValue;
30 using base::FundamentalValue;
32 using content::NavigationController; 31 using content::NavigationController;
33 using content::WebContents; 32 using content::WebContents;
34 33
35 namespace extensions { 34 namespace extensions {
36 35
36 namespace {
37
37 namespace tabs = api::tabs; 38 namespace tabs = api::tabs;
38 39
39 BrowserEventRouter::TabEntry::TabEntry() 40 void WillDispatchTabUpdatedEvent(WebContents* contents,
40 : complete_waiting_on_load_(false), 41 const DictionaryValue* changed_properties,
41 url_() { 42 Profile* profile,
43 const Extension* extension,
44 ListValue* event_args) {
45 // Overwrite the second argument with the appropriate properties dictionary,
46 // depending on extension permissions.
47 DictionaryValue* properties_value = changed_properties->DeepCopy();
48 ExtensionTabUtil::ScrubTabValueForExtension(contents,
49 extension,
50 properties_value);
51 event_args->Set(1, properties_value);
52
53 // Overwrite the third arg with our tab value as seen by this extension.
54 event_args->Set(2, ExtensionTabUtil::CreateTabValue(contents, extension));
42 } 55 }
43 56
44 DictionaryValue* BrowserEventRouter::TabEntry::UpdateLoadState( 57 } // namespace
58
59 TabsEventRouter::TabEntry::TabEntry() : complete_waiting_on_load_(false),
60 url_() {
61 }
62
63 DictionaryValue* TabsEventRouter::TabEntry::UpdateLoadState(
45 const WebContents* contents) { 64 const WebContents* contents) {
46 // The tab may go in & out of loading (for instance if iframes navigate). 65 // The tab may go in & out of loading (for instance if iframes navigate).
47 // We only want to respond to the first change from loading to !loading after 66 // We only want to respond to the first change from loading to !loading after
48 // the NAV_ENTRY_COMMITTED was fired. 67 // the NAV_ENTRY_COMMITTED was fired.
49 if (!complete_waiting_on_load_ || contents->IsLoading()) 68 if (!complete_waiting_on_load_ || contents->IsLoading())
50 return NULL; 69 return NULL;
51 70
52 // Send "complete" state change. 71 // Send "complete" state change.
53 complete_waiting_on_load_ = false; 72 complete_waiting_on_load_ = false;
54 DictionaryValue* changed_properties = new DictionaryValue(); 73 DictionaryValue* changed_properties = new DictionaryValue();
55 changed_properties->SetString(tab_keys::kStatusKey, 74 changed_properties->SetString(tabs_constants::kStatusKey,
56 tab_keys::kStatusValueComplete); 75 tabs_constants::kStatusValueComplete);
57 return changed_properties; 76 return changed_properties;
58 } 77 }
59 78
60 DictionaryValue* BrowserEventRouter::TabEntry::DidNavigate( 79 DictionaryValue* TabsEventRouter::TabEntry::DidNavigate(
61 const WebContents* contents) { 80 const WebContents* contents) {
62 // Send "loading" state change. 81 // Send "loading" state change.
63 complete_waiting_on_load_ = true; 82 complete_waiting_on_load_ = true;
64 DictionaryValue* changed_properties = new DictionaryValue(); 83 DictionaryValue* changed_properties = new DictionaryValue();
65 changed_properties->SetString(tab_keys::kStatusKey, 84 changed_properties->SetString(tabs_constants::kStatusKey,
66 tab_keys::kStatusValueLoading); 85 tabs_constants::kStatusValueLoading);
67 86
68 if (contents->GetURL() != url_) { 87 if (contents->GetURL() != url_) {
69 url_ = contents->GetURL(); 88 url_ = contents->GetURL();
70 changed_properties->SetString(tab_keys::kUrlKey, url_.spec()); 89 changed_properties->SetString(tabs_constants::kUrlKey, url_.spec());
71 } 90 }
72 91
73 return changed_properties; 92 return changed_properties;
74 } 93 }
75 94
76 BrowserEventRouter::BrowserEventRouter(Profile* profile) 95 TabsEventRouter::TabsEventRouter(Profile* profile) : profile_(profile) {
77 : profile_(profile) {
78 DCHECK(!profile->IsOffTheRecord()); 96 DCHECK(!profile->IsOffTheRecord());
79 97
80 BrowserList::AddObserver(this); 98 BrowserList::AddObserver(this);
81 99
82 // Init() can happen after the browser is running, so catch up with any 100 // Init() can happen after the browser is running, so catch up with any
83 // windows that already exist. 101 // windows that already exist.
84 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 102 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
85 RegisterForBrowserNotifications(*it); 103 RegisterForBrowserNotifications(*it);
86 104
87 // Also catch up our internal bookkeeping of tab entries. 105 // Also catch up our internal bookkeeping of tab entries.
88 Browser* browser = *it; 106 Browser* browser = *it;
89 if (browser->tab_strip_model()) { 107 if (browser->tab_strip_model()) {
90 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { 108 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
91 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(i); 109 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(i);
92 int tab_id = ExtensionTabUtil::GetTabId(contents); 110 int tab_id = ExtensionTabUtil::GetTabId(contents);
93 tab_entries_[tab_id] = TabEntry(); 111 tab_entries_[tab_id] = TabEntry();
94 } 112 }
95 } 113 }
96 } 114 }
97 } 115 }
98 116
99 BrowserEventRouter::~BrowserEventRouter() { 117 TabsEventRouter::~TabsEventRouter() {
100 BrowserList::RemoveObserver(this); 118 BrowserList::RemoveObserver(this);
101 } 119 }
102 120
103 void BrowserEventRouter::OnBrowserAdded(Browser* browser) { 121 void TabsEventRouter::OnBrowserAdded(Browser* browser) {
104 RegisterForBrowserNotifications(browser); 122 RegisterForBrowserNotifications(browser);
105 } 123 }
106 124
107 void BrowserEventRouter::RegisterForBrowserNotifications(Browser* browser) { 125 void TabsEventRouter::RegisterForBrowserNotifications(Browser* browser) {
108 if (!profile_->IsSameProfile(browser->profile())) 126 if (!profile_->IsSameProfile(browser->profile()))
109 return; 127 return;
110 // Start listening to TabStripModel events for this browser. 128 // Start listening to TabStripModel events for this browser.
111 TabStripModel* tab_strip = browser->tab_strip_model(); 129 TabStripModel* tab_strip = browser->tab_strip_model();
112 tab_strip->AddObserver(this); 130 tab_strip->AddObserver(this);
113 131
114 for (int i = 0; i < tab_strip->count(); ++i) { 132 for (int i = 0; i < tab_strip->count(); ++i) {
115 RegisterForTabNotifications(tab_strip->GetWebContentsAt(i)); 133 RegisterForTabNotifications(tab_strip->GetWebContentsAt(i));
116 } 134 }
117 } 135 }
118 136
119 void BrowserEventRouter::RegisterForTabNotifications(WebContents* contents) { 137 void TabsEventRouter::RegisterForTabNotifications(WebContents* contents) {
120 registrar_.Add( 138 registrar_.Add(
121 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 139 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
122 content::Source<NavigationController>(&contents->GetController())); 140 content::Source<NavigationController>(&contents->GetController()));
123 141
124 // Observing NOTIFICATION_WEB_CONTENTS_DESTROYED is necessary because it's 142 // Observing NOTIFICATION_WEB_CONTENTS_DESTROYED is necessary because it's
125 // possible for tabs to be created, detached and then destroyed without 143 // possible for tabs to be created, detached and then destroyed without
126 // ever having been re-attached and closed. This happens in the case of 144 // ever having been re-attached and closed. This happens in the case of
127 // a devtools WebContents that is opened in window, docked, then closed. 145 // a devtools WebContents that is opened in window, docked, then closed.
128 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 146 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
129 content::Source<WebContents>(contents)); 147 content::Source<WebContents>(contents));
130 148
131 registrar_.Add(this, chrome::NOTIFICATION_FAVICON_UPDATED, 149 registrar_.Add(this, chrome::NOTIFICATION_FAVICON_UPDATED,
132 content::Source<WebContents>(contents)); 150 content::Source<WebContents>(contents));
133 } 151 }
134 152
135 void BrowserEventRouter::UnregisterForTabNotifications(WebContents* contents) { 153 void TabsEventRouter::UnregisterForTabNotifications(WebContents* contents) {
136 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 154 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
137 content::Source<NavigationController>(&contents->GetController())); 155 content::Source<NavigationController>(&contents->GetController()));
138 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 156 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
139 content::Source<WebContents>(contents)); 157 content::Source<WebContents>(contents));
140 registrar_.Remove(this, chrome::NOTIFICATION_FAVICON_UPDATED, 158 registrar_.Remove(this, chrome::NOTIFICATION_FAVICON_UPDATED,
141 content::Source<WebContents>(contents)); 159 content::Source<WebContents>(contents));
142 } 160 }
143 161
144 void BrowserEventRouter::OnBrowserRemoved(Browser* browser) { 162 void TabsEventRouter::OnBrowserRemoved(Browser* browser) {
145 if (!profile_->IsSameProfile(browser->profile())) 163 if (!profile_->IsSameProfile(browser->profile()))
146 return; 164 return;
147 165
148 // Stop listening to TabStripModel events for this browser. 166 // Stop listening to TabStripModel events for this browser.
149 browser->tab_strip_model()->RemoveObserver(this); 167 browser->tab_strip_model()->RemoveObserver(this);
150 } 168 }
151 169
152 void BrowserEventRouter::OnBrowserSetLastActive(Browser* browser) { 170 void TabsEventRouter::OnBrowserSetLastActive(Browser* browser) {
153 TabsWindowsAPI* tabs_window_api = TabsWindowsAPI::Get(profile_); 171 TabsWindowsAPI* tabs_window_api = TabsWindowsAPI::Get(profile_);
154 if (tabs_window_api) { 172 if (tabs_window_api) {
155 tabs_window_api->windows_event_router()->OnActiveWindowChanged( 173 tabs_window_api->windows_event_router()->OnActiveWindowChanged(
156 browser ? browser->extension_window_controller() : NULL); 174 browser ? browser->extension_window_controller() : NULL);
157 } 175 }
158 } 176 }
159 177
160 static void WillDispatchTabCreatedEvent(WebContents* contents, 178 static void WillDispatchTabCreatedEvent(WebContents* contents,
161 bool active, 179 bool active,
162 Profile* profile, 180 Profile* profile,
163 const Extension* extension, 181 const Extension* extension,
164 base::ListValue* event_args) { 182 ListValue* event_args) {
165 DictionaryValue* tab_value = ExtensionTabUtil::CreateTabValue( 183 DictionaryValue* tab_value = ExtensionTabUtil::CreateTabValue(
166 contents, extension); 184 contents, extension);
167 event_args->Clear(); 185 event_args->Clear();
168 event_args->Append(tab_value); 186 event_args->Append(tab_value);
169 tab_value->SetBoolean(tab_keys::kSelectedKey, active); 187 tab_value->SetBoolean(tabs_constants::kSelectedKey, active);
170 } 188 }
171 189
172 void BrowserEventRouter::TabCreatedAt(WebContents* contents, 190 void TabsEventRouter::TabCreatedAt(WebContents* contents,
173 int index, 191 int index,
174 bool active) { 192 bool active) {
175 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 193 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
176 scoped_ptr<base::ListValue> args(new base::ListValue()); 194 scoped_ptr<ListValue> args(new ListValue);
177 scoped_ptr<Event> event(new Event(tabs::OnCreated::kEventName, args.Pass())); 195 scoped_ptr<Event> event(new Event(tabs::OnCreated::kEventName, args.Pass()));
178 event->restrict_to_profile = profile; 196 event->restrict_to_profile = profile;
179 event->user_gesture = EventRouter::USER_GESTURE_NOT_ENABLED; 197 event->user_gesture = EventRouter::USER_GESTURE_NOT_ENABLED;
180 event->will_dispatch_callback = 198 event->will_dispatch_callback =
181 base::Bind(&WillDispatchTabCreatedEvent, contents, active); 199 base::Bind(&WillDispatchTabCreatedEvent, contents, active);
182 ExtensionSystem::Get(profile)->event_router()->BroadcastEvent(event.Pass()); 200 ExtensionSystem::Get(profile)->event_router()->BroadcastEvent(event.Pass());
183 201
184 RegisterForTabNotifications(contents); 202 RegisterForTabNotifications(contents);
185 } 203 }
186 204
187 void BrowserEventRouter::TabInsertedAt(WebContents* contents, 205 void TabsEventRouter::TabInsertedAt(WebContents* contents,
188 int index, 206 int index,
189 bool active) { 207 bool active) {
190 // If tab is new, send created event. 208 // If tab is new, send created event.
191 int tab_id = ExtensionTabUtil::GetTabId(contents); 209 int tab_id = ExtensionTabUtil::GetTabId(contents);
192 if (!GetTabEntry(contents)) { 210 if (!GetTabEntry(contents)) {
193 tab_entries_[tab_id] = TabEntry(); 211 tab_entries_[tab_id] = TabEntry();
194 212
195 TabCreatedAt(contents, index, active); 213 TabCreatedAt(contents, index, active);
196 return; 214 return;
197 } 215 }
198 216
199 scoped_ptr<base::ListValue> args(new base::ListValue()); 217 scoped_ptr<ListValue> args(new ListValue);
200 args->Append(new base::FundamentalValue(tab_id)); 218 args->Append(new FundamentalValue(tab_id));
201 219
202 DictionaryValue* object_args = new DictionaryValue(); 220 DictionaryValue* object_args = new DictionaryValue();
203 object_args->Set(tab_keys::kNewWindowIdKey, new base::FundamentalValue( 221 object_args->Set(tabs_constants::kNewWindowIdKey,
204 ExtensionTabUtil::GetWindowIdOfTab(contents))); 222 new FundamentalValue(
205 object_args->Set(tab_keys::kNewPositionKey, new base::FundamentalValue( 223 ExtensionTabUtil::GetWindowIdOfTab(contents)));
206 index)); 224 object_args->Set(tabs_constants::kNewPositionKey,
225 new FundamentalValue(index));
207 args->Append(object_args); 226 args->Append(object_args);
208 227
209 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 228 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
210 DispatchEvent(profile, tabs::OnAttached::kEventName, args.Pass(), 229 DispatchEvent(profile, tabs::OnAttached::kEventName, args.Pass(),
211 EventRouter::USER_GESTURE_UNKNOWN); 230 EventRouter::USER_GESTURE_UNKNOWN);
212 } 231 }
213 232
214 void BrowserEventRouter::TabDetachedAt(WebContents* contents, int index) { 233 void TabsEventRouter::TabDetachedAt(WebContents* contents, int index) {
215 if (!GetTabEntry(contents)) { 234 if (!GetTabEntry(contents)) {
216 // The tab was removed. Don't send detach event. 235 // The tab was removed. Don't send detach event.
217 return; 236 return;
218 } 237 }
219 238
220 scoped_ptr<base::ListValue> args(new base::ListValue()); 239 scoped_ptr<ListValue> args(new ListValue);
221 args->Append( 240 args->Append(
222 new base::FundamentalValue(ExtensionTabUtil::GetTabId(contents))); 241 new FundamentalValue(ExtensionTabUtil::GetTabId(contents)));
223 242
224 DictionaryValue* object_args = new DictionaryValue(); 243 DictionaryValue* object_args = new DictionaryValue();
225 object_args->Set(tab_keys::kOldWindowIdKey, new base::FundamentalValue( 244 object_args->Set(tabs_constants::kOldWindowIdKey,
226 ExtensionTabUtil::GetWindowIdOfTab(contents))); 245 new FundamentalValue(
227 object_args->Set(tab_keys::kOldPositionKey, new base::FundamentalValue( 246 ExtensionTabUtil::GetWindowIdOfTab(contents)));
228 index)); 247 object_args->Set(tabs_constants::kOldPositionKey,
248 new FundamentalValue(index));
229 args->Append(object_args); 249 args->Append(object_args);
230 250
231 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 251 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
232 DispatchEvent(profile, tabs::OnDetached::kEventName, args.Pass(), 252 DispatchEvent(profile,
253 tabs::OnDetached::kEventName,
254 args.Pass(),
233 EventRouter::USER_GESTURE_UNKNOWN); 255 EventRouter::USER_GESTURE_UNKNOWN);
234 } 256 }
235 257
236 void BrowserEventRouter::TabClosingAt(TabStripModel* tab_strip_model, 258 void TabsEventRouter::TabClosingAt(TabStripModel* tab_strip_model,
237 WebContents* contents, 259 WebContents* contents,
238 int index) { 260 int index) {
239 int tab_id = ExtensionTabUtil::GetTabId(contents); 261 int tab_id = ExtensionTabUtil::GetTabId(contents);
240 262
241 scoped_ptr<base::ListValue> args(new base::ListValue()); 263 scoped_ptr<ListValue> args(new ListValue);
242 args->Append(new base::FundamentalValue(tab_id)); 264 args->Append(new FundamentalValue(tab_id));
243 265
244 DictionaryValue* object_args = new DictionaryValue(); 266 DictionaryValue* object_args = new DictionaryValue();
245 object_args->SetInteger(tab_keys::kWindowIdKey, 267 object_args->SetInteger(tabs_constants::kWindowIdKey,
246 ExtensionTabUtil::GetWindowIdOfTab(contents)); 268 ExtensionTabUtil::GetWindowIdOfTab(contents));
247 object_args->SetBoolean(tab_keys::kWindowClosing, 269 object_args->SetBoolean(tabs_constants::kWindowClosing,
248 tab_strip_model->closing_all()); 270 tab_strip_model->closing_all());
249 args->Append(object_args); 271 args->Append(object_args);
250 272
251 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 273 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
252 DispatchEvent(profile, tabs::OnRemoved::kEventName, args.Pass(), 274 DispatchEvent(profile,
275 tabs::OnRemoved::kEventName,
276 args.Pass(),
253 EventRouter::USER_GESTURE_UNKNOWN); 277 EventRouter::USER_GESTURE_UNKNOWN);
254 278
255 int removed_count = tab_entries_.erase(tab_id); 279 int removed_count = tab_entries_.erase(tab_id);
256 DCHECK_GT(removed_count, 0); 280 DCHECK_GT(removed_count, 0);
257 281
258 UnregisterForTabNotifications(contents); 282 UnregisterForTabNotifications(contents);
259 } 283 }
260 284
261 void BrowserEventRouter::ActiveTabChanged(WebContents* old_contents, 285 void TabsEventRouter::ActiveTabChanged(WebContents* old_contents,
262 WebContents* new_contents, 286 WebContents* new_contents,
263 int index, 287 int index,
264 int reason) { 288 int reason) {
265 scoped_ptr<base::ListValue> args(new base::ListValue()); 289 scoped_ptr<ListValue> args(new ListValue);
266 int tab_id = ExtensionTabUtil::GetTabId(new_contents); 290 int tab_id = ExtensionTabUtil::GetTabId(new_contents);
267 args->Append(new base::FundamentalValue(tab_id)); 291 args->Append(new FundamentalValue(tab_id));
268 292
269 DictionaryValue* object_args = new DictionaryValue(); 293 DictionaryValue* object_args = new DictionaryValue();
270 object_args->Set(tab_keys::kWindowIdKey, new base::FundamentalValue( 294 object_args->Set(tabs_constants::kWindowIdKey,
271 ExtensionTabUtil::GetWindowIdOfTab(new_contents))); 295 new FundamentalValue(
296 ExtensionTabUtil::GetWindowIdOfTab(new_contents)));
272 args->Append(object_args); 297 args->Append(object_args);
273 298
274 // The onActivated event replaced onActiveChanged and onSelectionChanged. The 299 // The onActivated event replaced onActiveChanged and onSelectionChanged. The
275 // deprecated events take two arguments: tabId, {windowId}. 300 // deprecated events take two arguments: tabId, {windowId}.
276 Profile* profile = 301 Profile* profile =
277 Profile::FromBrowserContext(new_contents->GetBrowserContext()); 302 Profile::FromBrowserContext(new_contents->GetBrowserContext());
278 EventRouter::UserGestureState gesture = 303 EventRouter::UserGestureState gesture =
279 reason & CHANGE_REASON_USER_GESTURE 304 reason & CHANGE_REASON_USER_GESTURE
280 ? EventRouter::USER_GESTURE_ENABLED 305 ? EventRouter::USER_GESTURE_ENABLED
281 : EventRouter::USER_GESTURE_NOT_ENABLED; 306 : EventRouter::USER_GESTURE_NOT_ENABLED;
282 DispatchEvent(profile, tabs::OnSelectionChanged::kEventName, 307 DispatchEvent(profile,
283 scoped_ptr<base::ListValue>(args->DeepCopy()), gesture); 308 tabs::OnSelectionChanged::kEventName,
284 DispatchEvent(profile, tabs::OnActiveChanged::kEventName, 309 scoped_ptr<ListValue>(args->DeepCopy()),
285 scoped_ptr<base::ListValue>(args->DeepCopy()), gesture); 310 gesture);
311 DispatchEvent(profile,
312 tabs::OnActiveChanged::kEventName,
313 scoped_ptr<ListValue>(args->DeepCopy()),
314 gesture);
286 315
287 // The onActivated event takes one argument: {windowId, tabId}. 316 // The onActivated event takes one argument: {windowId, tabId}.
288 args->Remove(0, NULL); 317 args->Remove(0, NULL);
289 object_args->Set(tab_keys::kTabIdKey, new base::FundamentalValue(tab_id)); 318 object_args->Set(tabs_constants::kTabIdKey,
319 new FundamentalValue(tab_id));
290 DispatchEvent(profile, tabs::OnActivated::kEventName, args.Pass(), gesture); 320 DispatchEvent(profile, tabs::OnActivated::kEventName, args.Pass(), gesture);
291 } 321 }
292 322
293 void BrowserEventRouter::TabSelectionChanged( 323 void TabsEventRouter::TabSelectionChanged(
294 TabStripModel* tab_strip_model, 324 TabStripModel* tab_strip_model,
295 const ui::ListSelectionModel& old_model) { 325 const ui::ListSelectionModel& old_model) {
296 ui::ListSelectionModel::SelectedIndices new_selection = 326 ui::ListSelectionModel::SelectedIndices new_selection =
297 tab_strip_model->selection_model().selected_indices(); 327 tab_strip_model->selection_model().selected_indices();
298 base::ListValue* all = new base::ListValue(); 328 scoped_ptr<ListValue> all_tabs(new ListValue);
299 329
300 for (size_t i = 0; i < new_selection.size(); ++i) { 330 for (size_t i = 0; i < new_selection.size(); ++i) {
301 int index = new_selection[i]; 331 int index = new_selection[i];
302 WebContents* contents = tab_strip_model->GetWebContentsAt(index); 332 WebContents* contents = tab_strip_model->GetWebContentsAt(index);
303 if (!contents) 333 if (!contents)
304 break; 334 break;
305 int tab_id = ExtensionTabUtil::GetTabId(contents); 335 int tab_id = ExtensionTabUtil::GetTabId(contents);
306 all->Append(new base::FundamentalValue(tab_id)); 336 all_tabs->Append(new FundamentalValue(tab_id));
307 } 337 }
308 338
309 scoped_ptr<base::ListValue> args(new base::ListValue()); 339 scoped_ptr<ListValue> args(new ListValue);
310 DictionaryValue* select_info = new DictionaryValue(); 340 scoped_ptr<DictionaryValue> select_info(new DictionaryValue);
311 341
312 select_info->Set(tab_keys::kWindowIdKey, new base::FundamentalValue( 342 select_info->Set(
313 ExtensionTabUtil::GetWindowIdOfTabStripModel(tab_strip_model))); 343 tabs_constants::kWindowIdKey,
344 new FundamentalValue(
345 ExtensionTabUtil::GetWindowIdOfTabStripModel(tab_strip_model)));
314 346
315 select_info->Set(tab_keys::kTabIdsKey, all); 347 select_info->Set(tabs_constants::kTabIdsKey, all_tabs.release());
316 args->Append(select_info); 348 args->Append(select_info.release());
317 349
318 // The onHighlighted event replaced onHighlightChanged. 350 // The onHighlighted event replaced onHighlightChanged.
319 Profile* profile = tab_strip_model->profile(); 351 Profile* profile = tab_strip_model->profile();
320 DispatchEvent(profile, tabs::OnHighlightChanged::kEventName, 352 DispatchEvent(profile,
321 scoped_ptr<base::ListValue>(args->DeepCopy()), 353 tabs::OnHighlightChanged::kEventName,
354 scoped_ptr<ListValue>(args->DeepCopy()),
322 EventRouter::USER_GESTURE_UNKNOWN); 355 EventRouter::USER_GESTURE_UNKNOWN);
323 DispatchEvent(profile, tabs::OnHighlighted::kEventName, args.Pass(), 356 DispatchEvent(profile,
357 tabs::OnHighlighted::kEventName,
358 args.Pass(),
324 EventRouter::USER_GESTURE_UNKNOWN); 359 EventRouter::USER_GESTURE_UNKNOWN);
325 } 360 }
326 361
327 void BrowserEventRouter::TabMoved(WebContents* contents, 362 void TabsEventRouter::TabMoved(WebContents* contents,
328 int from_index, 363 int from_index,
329 int to_index) { 364 int to_index) {
330 scoped_ptr<base::ListValue> args(new base::ListValue()); 365 scoped_ptr<ListValue> args(new ListValue);
331 args->Append( 366 args->Append(
332 new base::FundamentalValue(ExtensionTabUtil::GetTabId(contents))); 367 new FundamentalValue(ExtensionTabUtil::GetTabId(contents)));
333 368
334 DictionaryValue* object_args = new DictionaryValue(); 369 DictionaryValue* object_args = new DictionaryValue();
335 object_args->Set(tab_keys::kWindowIdKey, new base::FundamentalValue( 370 object_args->Set(tabs_constants::kWindowIdKey,
336 ExtensionTabUtil::GetWindowIdOfTab(contents))); 371 new FundamentalValue(
337 object_args->Set(tab_keys::kFromIndexKey, new base::FundamentalValue( 372 ExtensionTabUtil::GetWindowIdOfTab(contents)));
338 from_index)); 373 object_args->Set(tabs_constants::kFromIndexKey,
339 object_args->Set(tab_keys::kToIndexKey, new base::FundamentalValue( 374 new FundamentalValue(from_index));
340 to_index)); 375 object_args->Set(tabs_constants::kToIndexKey,
376 new FundamentalValue(to_index));
341 args->Append(object_args); 377 args->Append(object_args);
342 378
343 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 379 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
344 DispatchEvent(profile, tabs::OnMoved::kEventName, args.Pass(), 380 DispatchEvent(profile,
381 tabs::OnMoved::kEventName,
382 args.Pass(),
345 EventRouter::USER_GESTURE_UNKNOWN); 383 EventRouter::USER_GESTURE_UNKNOWN);
346 } 384 }
347 385
348 void BrowserEventRouter::TabUpdated(WebContents* contents, bool did_navigate) { 386 void TabsEventRouter::TabUpdated(WebContents* contents, bool did_navigate) {
349 TabEntry* entry = GetTabEntry(contents); 387 TabEntry* entry = GetTabEntry(contents);
350 scoped_ptr<DictionaryValue> changed_properties; 388 scoped_ptr<DictionaryValue> changed_properties;
351 389
352 DCHECK(entry); 390 CHECK(entry);
353 391
354 if (did_navigate) 392 if (did_navigate)
355 changed_properties.reset(entry->DidNavigate(contents)); 393 changed_properties.reset(entry->DidNavigate(contents));
356 else 394 else
357 changed_properties.reset(entry->UpdateLoadState(contents)); 395 changed_properties.reset(entry->UpdateLoadState(contents));
358 396
359 if (changed_properties) 397 if (changed_properties)
360 DispatchTabUpdatedEvent(contents, changed_properties.Pass()); 398 DispatchTabUpdatedEvent(contents, changed_properties.Pass());
361 } 399 }
362 400
363 void BrowserEventRouter::FaviconUrlUpdated(WebContents* contents, 401 void TabsEventRouter::FaviconUrlUpdated(WebContents* contents) {
364 const bool* icon_url_changed) {
365 if (!icon_url_changed || !*icon_url_changed)
366 return;
367 content::NavigationEntry* entry = 402 content::NavigationEntry* entry =
368 contents->GetController().GetVisibleEntry(); 403 contents->GetController().GetVisibleEntry();
369 if (!entry || !entry->GetFavicon().valid) 404 if (!entry || !entry->GetFavicon().valid)
370 return; 405 return;
371 scoped_ptr<DictionaryValue> changed_properties(new DictionaryValue()); 406 scoped_ptr<DictionaryValue> changed_properties(new DictionaryValue);
372 changed_properties->SetString( 407 changed_properties->SetString(
373 tab_keys::kFaviconUrlKey, 408 tabs_constants::kFaviconUrlKey,
374 entry->GetFavicon().url.possibly_invalid_spec()); 409 entry->GetFavicon().url.possibly_invalid_spec());
375 DispatchTabUpdatedEvent(contents, changed_properties.Pass()); 410 DispatchTabUpdatedEvent(contents, changed_properties.Pass());
376 } 411 }
377 412
378 void BrowserEventRouter::DispatchEvent( 413 void TabsEventRouter::DispatchEvent(
379 Profile* profile, 414 Profile* profile,
380 const char* event_name, 415 const char* event_name,
381 scoped_ptr<base::ListValue> args, 416 scoped_ptr<ListValue> args,
382 EventRouter::UserGestureState user_gesture) { 417 EventRouter::UserGestureState user_gesture) {
383 if (!profile_->IsSameProfile(profile) || 418 if (!profile_->IsSameProfile(profile) ||
384 !extensions::ExtensionSystem::Get(profile)->event_router()) 419 !ExtensionSystem::Get(profile)->event_router())
385 return; 420 return;
386 421
387 scoped_ptr<Event> event(new Event(event_name, args.Pass())); 422 scoped_ptr<Event> event(new Event(event_name, args.Pass()));
388 event->restrict_to_profile = profile; 423 event->restrict_to_profile = profile;
389 event->user_gesture = user_gesture; 424 event->user_gesture = user_gesture;
390 ExtensionSystem::Get(profile)->event_router()->BroadcastEvent(event.Pass()); 425 ExtensionSystem::Get(profile)->event_router()->BroadcastEvent(event.Pass());
391 } 426 }
392 427
393 void BrowserEventRouter::DispatchSimpleBrowserEvent( 428 void TabsEventRouter::DispatchSimpleBrowserEvent(
394 Profile* profile, const int window_id, const char* event_name) { 429 Profile* profile, const int window_id, const char* event_name) {
395 if (!profile_->IsSameProfile(profile)) 430 if (!profile_->IsSameProfile(profile))
396 return; 431 return;
397 432
398 scoped_ptr<base::ListValue> args(new base::ListValue()); 433 scoped_ptr<ListValue> args(new ListValue);
399 args->Append(new base::FundamentalValue(window_id)); 434 args->Append(new FundamentalValue(window_id));
400 435
401 DispatchEvent(profile, event_name, args.Pass(), 436 DispatchEvent(profile,
437 event_name,
438 args.Pass(),
402 EventRouter::USER_GESTURE_UNKNOWN); 439 EventRouter::USER_GESTURE_UNKNOWN);
403 } 440 }
404 441
405 static void WillDispatchTabUpdatedEvent( 442 void TabsEventRouter::DispatchTabUpdatedEvent(
406 WebContents* contents,
407 const DictionaryValue* changed_properties,
408 Profile* profile,
409 const Extension* extension,
410 base::ListValue* event_args) {
411 // Overwrite the second argument with the appropriate properties dictionary,
412 // depending on extension permissions.
413 DictionaryValue* properties_value = changed_properties->DeepCopy();
414 ExtensionTabUtil::ScrubTabValueForExtension(contents, extension,
415 properties_value);
416 event_args->Set(1, properties_value);
417
418 // Overwrite the third arg with our tab value as seen by this extension.
419 DictionaryValue* tab_value = ExtensionTabUtil::CreateTabValue(
420 contents, extension);
421 event_args->Set(2, tab_value);
422 }
423
424 void BrowserEventRouter::DispatchTabUpdatedEvent(
425 WebContents* contents, scoped_ptr<DictionaryValue> changed_properties) { 443 WebContents* contents, scoped_ptr<DictionaryValue> changed_properties) {
426 DCHECK(changed_properties); 444 DCHECK(changed_properties);
427 DCHECK(contents); 445 DCHECK(contents);
428 446
429 // The state of the tab (as seen from the extension point of view) has 447 // The state of the tab (as seen from the extension point of view) has
430 // changed. Send a notification to the extension. 448 // changed. Send a notification to the extension.
431 scoped_ptr<base::ListValue> args_base(new base::ListValue()); 449 scoped_ptr<ListValue> args_base(new ListValue);
432 450
433 // First arg: The id of the tab that changed. 451 // First arg: The id of the tab that changed.
434 args_base->AppendInteger(ExtensionTabUtil::GetTabId(contents)); 452 args_base->AppendInteger(ExtensionTabUtil::GetTabId(contents));
435 453
436 // Second arg: An object containing the changes to the tab state. Filled in 454 // Second arg: An object containing the changes to the tab state. Filled in
437 // by WillDispatchTabUpdatedEvent as a copy of changed_properties, if the 455 // by WillDispatchTabUpdatedEvent as a copy of changed_properties, if the
438 // extension has the tabs permission. 456 // extension has the tabs permission.
439 457
440 // Third arg: An object containing the state of the tab. Filled in by 458 // Third arg: An object containing the state of the tab. Filled in by
441 // WillDispatchTabUpdatedEvent. 459 // WillDispatchTabUpdatedEvent.
442 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 460 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
443 461
444 scoped_ptr<Event> event(new Event(tabs::OnUpdated::kEventName, 462 scoped_ptr<Event> event(
445 args_base.Pass())); 463 new Event(tabs::OnUpdated::kEventName, args_base.Pass()));
446 event->restrict_to_profile = profile; 464 event->restrict_to_profile = profile;
447 event->user_gesture = EventRouter::USER_GESTURE_NOT_ENABLED; 465 event->user_gesture = EventRouter::USER_GESTURE_NOT_ENABLED;
448 event->will_dispatch_callback = 466 event->will_dispatch_callback =
449 base::Bind(&WillDispatchTabUpdatedEvent, 467 base::Bind(&WillDispatchTabUpdatedEvent,
450 contents, changed_properties.get()); 468 contents,
469 changed_properties.get());
451 ExtensionSystem::Get(profile)->event_router()->BroadcastEvent(event.Pass()); 470 ExtensionSystem::Get(profile)->event_router()->BroadcastEvent(event.Pass());
452 } 471 }
453 472
454 BrowserEventRouter::TabEntry* BrowserEventRouter::GetTabEntry( 473 TabsEventRouter::TabEntry* TabsEventRouter::GetTabEntry(
455 const WebContents* contents) { 474 const WebContents* contents) {
456 int tab_id = ExtensionTabUtil::GetTabId(contents); 475 int tab_id = ExtensionTabUtil::GetTabId(contents);
457 std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id); 476 std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id);
458 if (tab_entries_.end() == i) 477 if (tab_entries_.end() == i)
459 return NULL; 478 return NULL;
460 return &i->second; 479 return &i->second;
461 } 480 }
462 481
463 void BrowserEventRouter::Observe(int type, 482 void TabsEventRouter::Observe(int type,
464 const content::NotificationSource& source, 483 const content::NotificationSource& source,
465 const content::NotificationDetails& details) { 484 const content::NotificationDetails& details) {
466 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { 485 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
467 NavigationController* source_controller = 486 NavigationController* source_controller =
468 content::Source<NavigationController>(source).ptr(); 487 content::Source<NavigationController>(source).ptr();
469 TabUpdated(source_controller->GetWebContents(), true); 488 TabUpdated(source_controller->GetWebContents(), true);
470 } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { 489 } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) {
471 // Tab was destroyed after being detached (without being re-attached). 490 // Tab was destroyed after being detached (without being re-attached).
472 WebContents* contents = content::Source<WebContents>(source).ptr(); 491 WebContents* contents = content::Source<WebContents>(source).ptr();
473 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 492 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
474 content::Source<NavigationController>(&contents->GetController())); 493 content::Source<NavigationController>(&contents->GetController()));
475 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 494 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
476 content::Source<WebContents>(contents)); 495 content::Source<WebContents>(contents));
477 registrar_.Remove(this, chrome::NOTIFICATION_FAVICON_UPDATED, 496 registrar_.Remove(this, chrome::NOTIFICATION_FAVICON_UPDATED,
478 content::Source<WebContents>(contents)); 497 content::Source<WebContents>(contents));
479 } else if (type == chrome::NOTIFICATION_FAVICON_UPDATED) { 498 } else if (type == chrome::NOTIFICATION_FAVICON_UPDATED) {
480 WebContents* contents = content::Source<WebContents>(source).ptr(); 499 bool icon_url_changed = *content::Details<bool>(details).ptr();
481 const bool* icon_url_changed = content::Details<bool>(details).ptr(); 500 if (icon_url_changed)
482 FaviconUrlUpdated(contents, icon_url_changed); 501 FaviconUrlUpdated(content::Source<WebContents>(source).ptr());
483 } else { 502 } else {
484 NOTREACHED(); 503 NOTREACHED();
485 } 504 }
486 } 505 }
487 506
488 void BrowserEventRouter::TabChangedAt(WebContents* contents, 507 void TabsEventRouter::TabChangedAt(WebContents* contents,
489 int index, 508 int index,
490 TabChangeType change_type) { 509 TabChangeType change_type) {
491 TabUpdated(contents, false); 510 TabUpdated(contents, false);
492 } 511 }
493 512
494 void BrowserEventRouter::TabReplacedAt(TabStripModel* tab_strip_model, 513 void TabsEventRouter::TabReplacedAt(TabStripModel* tab_strip_model,
495 WebContents* old_contents, 514 WebContents* old_contents,
496 WebContents* new_contents, 515 WebContents* new_contents,
497 int index) { 516 int index) {
498 // Notify listeners that the next tabs closing or being added are due to 517 // Notify listeners that the next tabs closing or being added are due to
499 // WebContents being swapped. 518 // WebContents being swapped.
500 const int new_tab_id = ExtensionTabUtil::GetTabId(new_contents); 519 const int new_tab_id = ExtensionTabUtil::GetTabId(new_contents);
501 const int old_tab_id = ExtensionTabUtil::GetTabId(old_contents); 520 const int old_tab_id = ExtensionTabUtil::GetTabId(old_contents);
502 scoped_ptr<base::ListValue> args(new base::ListValue()); 521 scoped_ptr<ListValue> args(new ListValue);
503 args->Append(new base::FundamentalValue(new_tab_id)); 522 args->Append(new FundamentalValue(new_tab_id));
504 args->Append(new base::FundamentalValue(old_tab_id)); 523 args->Append(new FundamentalValue(old_tab_id));
505 524
506 DispatchEvent(Profile::FromBrowserContext(new_contents->GetBrowserContext()), 525 DispatchEvent(Profile::FromBrowserContext(new_contents->GetBrowserContext()),
507 tabs::OnReplaced::kEventName, 526 tabs::OnReplaced::kEventName,
508 args.Pass(), 527 args.Pass(),
509 EventRouter::USER_GESTURE_UNKNOWN); 528 EventRouter::USER_GESTURE_UNKNOWN);
510 529
511 // Update tab_entries_. 530 // Update tab_entries_.
512 const int removed_count = tab_entries_.erase(old_tab_id); 531 const int removed_count = tab_entries_.erase(old_tab_id);
513 DCHECK_GT(removed_count, 0); 532 DCHECK_GT(removed_count, 0);
514 UnregisterForTabNotifications(old_contents); 533 UnregisterForTabNotifications(old_contents);
515 534
516 if (!GetTabEntry(new_contents)) { 535 if (!GetTabEntry(new_contents)) {
517 tab_entries_[new_tab_id] = TabEntry(); 536 tab_entries_[new_tab_id] = TabEntry();
518 RegisterForTabNotifications(new_contents); 537 RegisterForTabNotifications(new_contents);
519 } 538 }
520 } 539 }
521 540
522 void BrowserEventRouter::TabPinnedStateChanged(WebContents* contents, 541 void TabsEventRouter::TabPinnedStateChanged(WebContents* contents, int index) {
523 int index) {
524 TabStripModel* tab_strip = NULL; 542 TabStripModel* tab_strip = NULL;
525 int tab_index; 543 int tab_index;
526 544
527 if (ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index)) { 545 if (ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index)) {
528 scoped_ptr<DictionaryValue> changed_properties(new DictionaryValue()); 546 scoped_ptr<DictionaryValue> changed_properties(new DictionaryValue());
529 changed_properties->SetBoolean(tab_keys::kPinnedKey, 547 changed_properties->SetBoolean(tabs_constants::kPinnedKey,
530 tab_strip->IsTabPinned(tab_index)); 548 tab_strip->IsTabPinned(tab_index));
531 DispatchTabUpdatedEvent(contents, changed_properties.Pass()); 549 DispatchTabUpdatedEvent(contents, changed_properties.Pass());
532 } 550 }
533 } 551 }
534 552
535 void BrowserEventRouter::TabStripEmpty() {}
536
537 } // namespace extensions 553 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/tabs/tabs_event_router.h ('k') | chrome/browser/extensions/api/tabs/tabs_windows_api.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698