OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/browser_list.h" | 5 #include "chrome/browser/browser_list.h" |
6 | 6 |
7 #include "base/histogram.h" | 7 #include "base/histogram.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
11 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 profile_match; | 95 profile_match; |
96 } | 96 } |
97 | 97 |
98 // Finds a registered Browser object matching |profile| and |type|. This | 98 // Finds a registered Browser object matching |profile| and |type|. This |
99 // walks the list of Browsers that have ever been activated from most recently | 99 // walks the list of Browsers that have ever been activated from most recently |
100 // activated to least. If a Browser has never been activated, such as in a test | 100 // activated to least. If a Browser has never been activated, such as in a test |
101 // scenario, this function will _not_ find it. Fall back to | 101 // scenario, this function will _not_ find it. Fall back to |
102 // FindBrowserMatching() in that case. | 102 // FindBrowserMatching() in that case. |
103 Browser* FindInLastActiveMatching(Profile* profile, Browser::Type type, | 103 Browser* FindInLastActiveMatching(Profile* profile, Browser::Type type, |
104 bool match_incognito) { | 104 bool match_incognito) { |
105 for (BrowserList::list_type::const_reverse_iterator i = | 105 for (BrowserList::BrowserVector::const_reverse_iterator i = |
106 BrowserList::begin_last_active(); i != BrowserList::end_last_active(); | 106 BrowserList::begin_last_active(); i != BrowserList::end_last_active(); |
107 ++i) { | 107 ++i) { |
108 if (BrowserMatchesProfileAndType(*i, profile, type, match_incognito)) | 108 if (BrowserMatchesProfileAndType(*i, profile, type, match_incognito)) |
109 return *i; | 109 return *i; |
110 } | 110 } |
111 return NULL; | 111 return NULL; |
112 } | 112 } |
113 | 113 |
114 // Finds a registered Browser object matching |profile| and |type| even if that | 114 // Finds a registered Browser object matching |profile| and |type| even if that |
115 // Browser has never been activated. This is a forward walk, and intended as a | 115 // Browser has never been activated. This is a forward walk, and intended as a |
116 // last ditch fallback mostly to handle tests run on machines where no window is | 116 // last ditch fallback mostly to handle tests run on machines where no window is |
117 // ever activated. The user experience if this function is relied on is not good | 117 // ever activated. The user experience if this function is relied on is not good |
118 // since matching browsers will be returned in registration (creation) order. | 118 // since matching browsers will be returned in registration (creation) order. |
119 Browser* FindBrowserMatching(Profile* profile, Browser::Type type, | 119 Browser* FindBrowserMatching(Profile* profile, Browser::Type type, |
120 bool match_incognito) { | 120 bool match_incognito) { |
121 for (BrowserList::const_iterator i = BrowserList::begin(); | 121 for (BrowserList::const_iterator i = BrowserList::begin(); |
122 i != BrowserList::end(); ++i) { | 122 i != BrowserList::end(); ++i) { |
123 if (BrowserMatchesProfileAndType(*i, profile, type, match_incognito)) | 123 if (BrowserMatchesProfileAndType(*i, profile, type, match_incognito)) |
124 return *i; | 124 return *i; |
125 } | 125 } |
126 return NULL; | 126 return NULL; |
127 } | 127 } |
128 | 128 |
129 } // namespace | 129 } // namespace |
130 | 130 |
131 BrowserList::list_type BrowserList::browsers_; | 131 BrowserList::BrowserVector BrowserList::browsers_; |
132 std::vector<BrowserList::Observer*> BrowserList::observers_; | 132 ObserverList<BrowserList::Observer> BrowserList::observers_; |
133 | 133 |
134 // static | 134 // static |
135 void BrowserList::AddBrowser(Browser* browser) { | 135 void BrowserList::AddBrowser(Browser* browser) { |
136 DCHECK(browser); | 136 DCHECK(browser); |
137 browsers_.push_back(browser); | 137 browsers_.push_back(browser); |
138 | 138 |
139 g_browser_process->AddRefModule(); | 139 g_browser_process->AddRefModule(); |
140 | 140 |
141 if (!activity_observer) | 141 if (!activity_observer) |
142 activity_observer = new BrowserActivityObserver; | 142 activity_observer = new BrowserActivityObserver; |
143 | 143 |
144 NotificationService::current()->Notify( | 144 NotificationService::current()->Notify( |
145 NotificationType::BROWSER_OPENED, | 145 NotificationType::BROWSER_OPENED, |
146 Source<Browser>(browser), | 146 Source<Browser>(browser), |
147 NotificationService::NoDetails()); | 147 NotificationService::NoDetails()); |
148 | 148 |
149 // Send out notifications after add has occurred. Do some basic checking to | 149 // Send out notifications after add has occurred. Do some basic checking to |
150 // try to catch evil observers that change the list from under us. | 150 // try to catch evil observers that change the list from under us. |
151 size_t original_count = observers_.size(); | 151 size_t original_count = observers_.size(); |
152 for (size_t i = 0; i < observers_.size(); ++i) | 152 FOR_EACH_OBSERVER(Observer, observers_, OnBrowserAdded(browser)); |
153 observers_[i]->OnBrowserAdded(browser); | |
154 DCHECK_EQ(original_count, observers_.size()) | 153 DCHECK_EQ(original_count, observers_.size()) |
155 << "observer list modified during notification"; | 154 << "observer list modified during notification"; |
156 } | 155 } |
157 | 156 |
158 // static | 157 // static |
159 void BrowserList::RemoveBrowser(Browser* browser) { | 158 void BrowserList::RemoveBrowser(Browser* browser) { |
160 RemoveBrowserFrom(browser, &last_active_browsers_); | 159 RemoveBrowserFrom(browser, &last_active_browsers_); |
161 | 160 |
162 // Closing all windows does not indicate quitting the application on the Mac, | 161 // Closing all windows does not indicate quitting the application on the Mac, |
163 // however, many UI tests rely on this behavior so leave it be for now and | 162 // however, many UI tests rely on this behavior so leave it be for now and |
164 // simply ignore the behavior on the Mac outside of unit tests. | 163 // simply ignore the behavior on the Mac outside of unit tests. |
165 // TODO(andybons): Fix the UI tests to Do The Right Thing. | 164 // TODO(andybons): Fix the UI tests to Do The Right Thing. |
166 bool close_app_non_mac = (browsers_.size() == 1); | 165 bool close_app_non_mac = (browsers_.size() == 1); |
167 NotificationService::current()->Notify( | 166 NotificationService::current()->Notify( |
168 NotificationType::BROWSER_CLOSED, | 167 NotificationType::BROWSER_CLOSED, |
169 Source<Browser>(browser), Details<bool>(&close_app_non_mac)); | 168 Source<Browser>(browser), Details<bool>(&close_app_non_mac)); |
170 | 169 |
171 // Send out notifications before anything changes. Do some basic checking to | 170 // Send out notifications before anything changes. Do some basic checking to |
172 // try to catch evil observers that change the list from under us. | 171 // try to catch evil observers that change the list from under us. |
173 size_t original_count = observers_.size(); | 172 size_t original_count = observers_.size(); |
174 for (size_t i = 0; i < observers_.size(); ++i) | 173 FOR_EACH_OBSERVER(Observer, observers_, OnBrowserRemoving(browser)); |
175 observers_[i]->OnBrowserRemoving(browser); | |
176 DCHECK_EQ(original_count, observers_.size()) | 174 DCHECK_EQ(original_count, observers_.size()) |
177 << "observer list modified during notification"; | 175 << "observer list modified during notification"; |
178 | 176 |
179 RemoveBrowserFrom(browser, &browsers_); | 177 RemoveBrowserFrom(browser, &browsers_); |
180 | 178 |
181 // If the last Browser object was destroyed, make sure we try to close any | 179 // If the last Browser object was destroyed, make sure we try to close any |
182 // remaining dependent windows too. | 180 // remaining dependent windows too. |
183 if (browsers_.empty()) { | 181 if (browsers_.empty()) { |
184 AllBrowsersClosed(); | 182 AllBrowsersClosed(); |
185 | 183 |
186 delete activity_observer; | 184 delete activity_observer; |
187 activity_observer = NULL; | 185 activity_observer = NULL; |
188 } | 186 } |
189 | 187 |
190 g_browser_process->ReleaseModule(); | 188 g_browser_process->ReleaseModule(); |
191 } | 189 } |
192 | 190 |
193 // static | 191 // static |
194 void BrowserList::AddObserver(BrowserList::Observer* observer) { | 192 void BrowserList::AddObserver(BrowserList::Observer* observer) { |
195 DCHECK(std::find(observers_.begin(), observers_.end(), observer) | 193 observers_.AddObserver(observer); |
196 == observers_.end()) << "Adding an observer twice"; | |
197 observers_.push_back(observer); | |
198 } | 194 } |
199 | 195 |
200 // static | 196 // static |
201 void BrowserList::RemoveObserver(BrowserList::Observer* observer) { | 197 void BrowserList::RemoveObserver(BrowserList::Observer* observer) { |
202 std::vector<Observer*>::iterator i = | 198 observers_.RemoveObserver(observer); |
203 std::find(observers_.begin(), observers_.end(), observer); | |
204 if (i == observers_.end()) { | |
205 NOTREACHED() << "Removing an observer that isn't registered."; | |
206 return; | |
207 } | |
208 observers_.erase(i); | |
209 } | 199 } |
210 | 200 |
211 // static | 201 // static |
212 void BrowserList::CloseAllBrowsers(bool use_post) { | 202 void BrowserList::CloseAllBrowsers(bool use_post) { |
213 // Before we close the browsers shutdown all session services. That way an | 203 // Before we close the browsers shutdown all session services. That way an |
214 // exit can restore all browsers open before exiting. | 204 // exit can restore all browsers open before exiting. |
215 ProfileManager::ShutdownSessionServices(); | 205 ProfileManager::ShutdownSessionServices(); |
216 | 206 |
217 for (BrowserList::const_iterator i = BrowserList::begin(); | 207 for (BrowserList::const_iterator i = BrowserList::begin(); |
218 i != BrowserList::end();) { | 208 i != BrowserList::end();) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 } | 300 } |
311 | 301 |
312 // static | 302 // static |
313 bool BrowserList::IsInPersistentMode() { | 303 bool BrowserList::IsInPersistentMode() { |
314 // TODO(atwilson): check the boolean state variable that you will set for | 304 // TODO(atwilson): check the boolean state variable that you will set for |
315 // persisent instances. | 305 // persisent instances. |
316 return false; | 306 return false; |
317 } | 307 } |
318 | 308 |
319 // static | 309 // static |
320 BrowserList::list_type BrowserList::last_active_browsers_; | 310 BrowserList::BrowserVector BrowserList::last_active_browsers_; |
321 | 311 |
322 // static | 312 // static |
323 void BrowserList::SetLastActive(Browser* browser) { | 313 void BrowserList::SetLastActive(Browser* browser) { |
324 RemoveBrowserFrom(browser, &last_active_browsers_); | 314 RemoveBrowserFrom(browser, &last_active_browsers_); |
325 last_active_browsers_.push_back(browser); | 315 last_active_browsers_.push_back(browser); |
326 | 316 |
327 for (std::vector<Observer*>::const_iterator i = observers_.begin(); | 317 FOR_EACH_OBSERVER(Observer, observers_, OnBrowserSetLastActive(browser)); |
328 i != observers_.end(); ++i) { | |
329 (*i)->OnBrowserSetLastActive(browser); | |
330 } | |
331 } | 318 } |
332 | 319 |
333 // static | 320 // static |
334 Browser* BrowserList::GetLastActive() { | 321 Browser* BrowserList::GetLastActive() { |
335 if (!last_active_browsers_.empty()) | 322 if (!last_active_browsers_.empty()) |
336 return *(last_active_browsers_.rbegin()); | 323 return *(last_active_browsers_.rbegin()); |
337 | 324 |
338 return NULL; | 325 return NULL; |
339 } | 326 } |
340 | 327 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 bool BrowserList::IsOffTheRecordSessionActive() { | 381 bool BrowserList::IsOffTheRecordSessionActive() { |
395 for (BrowserList::const_iterator i = BrowserList::begin(); | 382 for (BrowserList::const_iterator i = BrowserList::begin(); |
396 i != BrowserList::end(); ++i) { | 383 i != BrowserList::end(); ++i) { |
397 if ((*i)->profile()->IsOffTheRecord()) | 384 if ((*i)->profile()->IsOffTheRecord()) |
398 return true; | 385 return true; |
399 } | 386 } |
400 return false; | 387 return false; |
401 } | 388 } |
402 | 389 |
403 // static | 390 // static |
404 void BrowserList::RemoveBrowserFrom(Browser* browser, list_type* browser_list) { | 391 void BrowserList::RemoveBrowserFrom(Browser* browser, |
| 392 BrowserVector* browser_list) { |
405 const iterator remove_browser = | 393 const iterator remove_browser = |
406 std::find(browser_list->begin(), browser_list->end(), browser); | 394 std::find(browser_list->begin(), browser_list->end(), browser); |
407 if (remove_browser != browser_list->end()) | 395 if (remove_browser != browser_list->end()) |
408 browser_list->erase(remove_browser); | 396 browser_list->erase(remove_browser); |
409 } | 397 } |
410 | 398 |
411 TabContentsIterator::TabContentsIterator() | 399 TabContentsIterator::TabContentsIterator() |
412 : browser_iterator_(BrowserList::begin()), | 400 : browser_iterator_(BrowserList::begin()), |
413 web_view_index_(-1), | 401 web_view_index_(-1), |
414 cur_(NULL) { | 402 cur_(NULL) { |
(...skipping 21 matching lines...) Expand all Loading... |
436 } | 424 } |
437 | 425 |
438 TabContents* next_tab = | 426 TabContents* next_tab = |
439 (*browser_iterator_)->GetTabContentsAt(web_view_index_); | 427 (*browser_iterator_)->GetTabContentsAt(web_view_index_); |
440 if (next_tab) { | 428 if (next_tab) { |
441 cur_ = next_tab; | 429 cur_ = next_tab; |
442 return; | 430 return; |
443 } | 431 } |
444 } | 432 } |
445 } | 433 } |
OLD | NEW |