| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/api/tabs/tabs_event_router.h" | 5 #include "chrome/browser/extensions/api/tabs/tabs_event_router.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "chrome/browser/chrome_notification_types.h" | 10 #include "chrome/browser/chrome_notification_types.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 } | 111 } |
| 112 | 112 |
| 113 bool TabsEventRouter::TabEntry::SetMuted(bool new_val) { | 113 bool TabsEventRouter::TabEntry::SetMuted(bool new_val) { |
| 114 if (was_muted_ == new_val) | 114 if (was_muted_ == new_val) |
| 115 return false; | 115 return false; |
| 116 was_muted_ = new_val; | 116 was_muted_ = new_val; |
| 117 return true; | 117 return true; |
| 118 } | 118 } |
| 119 | 119 |
| 120 TabsEventRouter::TabsEventRouter(Profile* profile) | 120 TabsEventRouter::TabsEventRouter(Profile* profile) |
| 121 : profile_(profile), favicon_scoped_observer_(this) { | 121 : profile_(profile), |
| 122 favicon_scoped_observer_(this), |
| 123 browser_tab_strip_tracker_(this, this, this) { |
| 122 DCHECK(!profile->IsOffTheRecord()); | 124 DCHECK(!profile->IsOffTheRecord()); |
| 123 | 125 |
| 124 BrowserList::AddObserver(this); | 126 browser_tab_strip_tracker_.Init( |
| 125 | 127 BrowserTabStripTracker::InitWith::ALL_BROWERS); |
| 126 // Init() can happen after the browser is running, so catch up with any | |
| 127 // windows that already exist. | |
| 128 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | |
| 129 RegisterForBrowserNotifications(*it); | |
| 130 | |
| 131 // Also catch up our internal bookkeeping of tab entries. | |
| 132 Browser* browser = *it; | |
| 133 if (ExtensionTabUtil::BrowserSupportsTabs(browser)) { | |
| 134 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { | |
| 135 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(i); | |
| 136 int tab_id = ExtensionTabUtil::GetTabId(contents); | |
| 137 tab_entries_[tab_id] = make_linked_ptr(new TabEntry(contents)); | |
| 138 } | |
| 139 } | |
| 140 } | |
| 141 } | 128 } |
| 142 | 129 |
| 143 TabsEventRouter::~TabsEventRouter() { | 130 TabsEventRouter::~TabsEventRouter() { |
| 144 BrowserList::RemoveObserver(this); | |
| 145 } | 131 } |
| 146 | 132 |
| 147 void TabsEventRouter::OnBrowserAdded(Browser* browser) { | 133 bool TabsEventRouter::ShouldTrackBrowser(Browser* browser) { |
| 148 RegisterForBrowserNotifications(browser); | 134 return profile_->IsSameProfile(browser->profile()) && |
| 149 } | 135 ExtensionTabUtil::BrowserSupportsTabs(browser); |
| 150 | |
| 151 void TabsEventRouter::RegisterForBrowserNotifications(Browser* browser) { | |
| 152 if (!profile_->IsSameProfile(browser->profile()) || | |
| 153 !ExtensionTabUtil::BrowserSupportsTabs(browser)) | |
| 154 return; | |
| 155 // Start listening to TabStripModel events for this browser. | |
| 156 TabStripModel* tab_strip = browser->tab_strip_model(); | |
| 157 tab_strip->AddObserver(this); | |
| 158 | |
| 159 for (int i = 0; i < tab_strip->count(); ++i) { | |
| 160 RegisterForTabNotifications(tab_strip->GetWebContentsAt(i)); | |
| 161 } | |
| 162 } | 136 } |
| 163 | 137 |
| 164 void TabsEventRouter::RegisterForTabNotifications(WebContents* contents) { | 138 void TabsEventRouter::RegisterForTabNotifications(WebContents* contents) { |
| 165 registrar_.Add( | 139 registrar_.Add( |
| 166 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 140 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| 167 content::Source<NavigationController>(&contents->GetController())); | 141 content::Source<NavigationController>(&contents->GetController())); |
| 168 | 142 |
| 169 // Observing NOTIFICATION_WEB_CONTENTS_DESTROYED is necessary because it's | 143 // Observing NOTIFICATION_WEB_CONTENTS_DESTROYED is necessary because it's |
| 170 // possible for tabs to be created, detached and then destroyed without | 144 // possible for tabs to be created, detached and then destroyed without |
| 171 // ever having been re-attached and closed. This happens in the case of | 145 // ever having been re-attached and closed. This happens in the case of |
| (...skipping 11 matching lines...) Expand all Loading... |
| 183 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 157 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| 184 content::Source<NavigationController>(&contents->GetController())); | 158 content::Source<NavigationController>(&contents->GetController())); |
| 185 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 159 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| 186 content::Source<WebContents>(contents)); | 160 content::Source<WebContents>(contents)); |
| 187 favicon_scoped_observer_.Remove( | 161 favicon_scoped_observer_.Remove( |
| 188 favicon::ContentFaviconDriver::FromWebContents(contents)); | 162 favicon::ContentFaviconDriver::FromWebContents(contents)); |
| 189 | 163 |
| 190 ZoomController::FromWebContents(contents)->RemoveObserver(this); | 164 ZoomController::FromWebContents(contents)->RemoveObserver(this); |
| 191 } | 165 } |
| 192 | 166 |
| 193 void TabsEventRouter::OnBrowserRemoved(Browser* browser) { | |
| 194 if (!profile_->IsSameProfile(browser->profile())) | |
| 195 return; | |
| 196 | |
| 197 // Stop listening to TabStripModel events for this browser. | |
| 198 browser->tab_strip_model()->RemoveObserver(this); | |
| 199 } | |
| 200 | |
| 201 void TabsEventRouter::OnBrowserSetLastActive(Browser* browser) { | 167 void TabsEventRouter::OnBrowserSetLastActive(Browser* browser) { |
| 202 TabsWindowsAPI* tabs_window_api = TabsWindowsAPI::Get(profile_); | 168 TabsWindowsAPI* tabs_window_api = TabsWindowsAPI::Get(profile_); |
| 203 if (tabs_window_api) { | 169 if (tabs_window_api) { |
| 204 tabs_window_api->windows_event_router()->OnActiveWindowChanged( | 170 tabs_window_api->windows_event_router()->OnActiveWindowChanged( |
| 205 browser ? browser->extension_window_controller() : NULL); | 171 browser ? browser->extension_window_controller() : NULL); |
| 206 } | 172 } |
| 207 } | 173 } |
| 208 | 174 |
| 209 static bool WillDispatchTabCreatedEvent( | 175 static bool WillDispatchTabCreatedEvent( |
| 210 WebContents* contents, | 176 WebContents* contents, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 233 event->will_dispatch_callback = | 199 event->will_dispatch_callback = |
| 234 base::Bind(&WillDispatchTabCreatedEvent, contents, active); | 200 base::Bind(&WillDispatchTabCreatedEvent, contents, active); |
| 235 EventRouter::Get(profile)->BroadcastEvent(event.Pass()); | 201 EventRouter::Get(profile)->BroadcastEvent(event.Pass()); |
| 236 | 202 |
| 237 RegisterForTabNotifications(contents); | 203 RegisterForTabNotifications(contents); |
| 238 } | 204 } |
| 239 | 205 |
| 240 void TabsEventRouter::TabInsertedAt(WebContents* contents, | 206 void TabsEventRouter::TabInsertedAt(WebContents* contents, |
| 241 int index, | 207 int index, |
| 242 bool active) { | 208 bool active) { |
| 243 // If tab is new, send created event. | |
| 244 int tab_id = ExtensionTabUtil::GetTabId(contents); | 209 int tab_id = ExtensionTabUtil::GetTabId(contents); |
| 245 if (GetTabEntry(contents).get() == NULL) { | 210 if (GetTabEntry(contents).get() == NULL) { |
| 246 tab_entries_[tab_id] = make_linked_ptr(new TabEntry(contents)); | 211 tab_entries_[tab_id] = make_linked_ptr(new TabEntry(contents)); |
| 247 | 212 |
| 248 TabCreatedAt(contents, index, active); | 213 // We've never seen this tab, send create event as long as we're not in the |
| 214 // constructor. |
| 215 if (browser_tab_strip_tracker_.is_processing_initial_browsers()) |
| 216 RegisterForTabNotifications(contents); |
| 217 else |
| 218 TabCreatedAt(contents, index, active); |
| 249 return; | 219 return; |
| 250 } | 220 } |
| 251 | 221 |
| 252 scoped_ptr<base::ListValue> args(new base::ListValue); | 222 scoped_ptr<base::ListValue> args(new base::ListValue); |
| 253 args->Append(new FundamentalValue(tab_id)); | 223 args->Append(new FundamentalValue(tab_id)); |
| 254 | 224 |
| 255 base::DictionaryValue* object_args = new base::DictionaryValue(); | 225 base::DictionaryValue* object_args = new base::DictionaryValue(); |
| 256 object_args->Set(tabs_constants::kNewWindowIdKey, | 226 object_args->Set(tabs_constants::kNewWindowIdKey, |
| 257 new FundamentalValue( | 227 new FundamentalValue( |
| 258 ExtensionTabUtil::GetWindowIdOfTab(contents))); | 228 ExtensionTabUtil::GetWindowIdOfTab(contents))); |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 void TabsEventRouter::OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, | 577 void TabsEventRouter::OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, |
| 608 bool icon_url_changed) { | 578 bool icon_url_changed) { |
| 609 if (icon_url_changed) { | 579 if (icon_url_changed) { |
| 610 favicon::ContentFaviconDriver* content_favicon_driver = | 580 favicon::ContentFaviconDriver* content_favicon_driver = |
| 611 static_cast<favicon::ContentFaviconDriver*>(favicon_driver); | 581 static_cast<favicon::ContentFaviconDriver*>(favicon_driver); |
| 612 FaviconUrlUpdated(content_favicon_driver->web_contents()); | 582 FaviconUrlUpdated(content_favicon_driver->web_contents()); |
| 613 } | 583 } |
| 614 } | 584 } |
| 615 | 585 |
| 616 } // namespace extensions | 586 } // namespace extensions |
| OLD | NEW |