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

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

Powered by Google App Engine
This is Rietveld 408576698