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