OLD | NEW |
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 |
OLD | NEW |