OLD | NEW |
1 // Copyright (c) 2010 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" |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 void BrowserList::AddObserver(BrowserList::Observer* observer) { | 216 void BrowserList::AddObserver(BrowserList::Observer* observer) { |
217 observers_.AddObserver(observer); | 217 observers_.AddObserver(observer); |
218 } | 218 } |
219 | 219 |
220 // static | 220 // static |
221 void BrowserList::RemoveObserver(BrowserList::Observer* observer) { | 221 void BrowserList::RemoveObserver(BrowserList::Observer* observer) { |
222 observers_.RemoveObserver(observer); | 222 observers_.RemoveObserver(observer); |
223 } | 223 } |
224 | 224 |
225 // static | 225 // static |
226 void BrowserList::CloseAllBrowsers(bool use_post) { | 226 void BrowserList::CloseAllBrowsers() { |
| 227 bool session_ending = |
| 228 browser_shutdown::GetShutdownType() == browser_shutdown::END_SESSION; |
| 229 bool use_post = !session_ending; |
| 230 bool force_exit = false; |
| 231 #if defined(USE_X11) |
| 232 if (session_ending) |
| 233 force_exit = true; |
| 234 #endif |
227 // Tell everyone that we are shutting down. | 235 // Tell everyone that we are shutting down. |
228 browser_shutdown::SetTryingToQuit(true); | 236 browser_shutdown::SetTryingToQuit(true); |
229 | 237 |
230 // Before we close the browsers shutdown all session services. That way an | 238 // Before we close the browsers shutdown all session services. That way an |
231 // exit can restore all browsers open before exiting. | 239 // exit can restore all browsers open before exiting. |
232 ProfileManager::ShutdownSessionServices(); | 240 ProfileManager::ShutdownSessionServices(); |
233 | 241 |
234 // If there are no browsers, send the APP_TERMINATING action here. Otherwise, | 242 // If there are no browsers, send the APP_TERMINATING action here. Otherwise, |
235 // it will be sent by RemoveBrowser() when the last browser has closed. | 243 // it will be sent by RemoveBrowser() when the last browser has closed. |
236 if (browsers_.empty()) { | 244 if (force_exit || browsers_.empty()) { |
237 NotificationService::current()->Notify(NotificationType::APP_TERMINATING, | 245 NotificationService::current()->Notify(NotificationType::APP_TERMINATING, |
238 NotificationService::AllSources(), | 246 NotificationService::AllSources(), |
239 NotificationService::NoDetails()); | 247 NotificationService::NoDetails()); |
240 AllBrowsersClosedAndAppExiting(); | 248 AllBrowsersClosedAndAppExiting(); |
241 return; | 249 return; |
242 } | 250 } |
243 for (BrowserList::const_iterator i = BrowserList::begin(); | 251 for (BrowserList::const_iterator i = BrowserList::begin(); |
244 i != BrowserList::end();) { | 252 i != BrowserList::end();) { |
245 if (use_post) { | 253 if (use_post) { |
246 (*i)->window()->Close(); | 254 (*i)->window()->Close(); |
(...skipping 22 matching lines...) Expand all Loading... |
269 | 277 |
270 // static | 278 // static |
271 void BrowserList::CloseAllBrowsersAndExit() { | 279 void BrowserList::CloseAllBrowsersAndExit() { |
272 NotificationService::current()->Notify( | 280 NotificationService::current()->Notify( |
273 NotificationType::APP_EXITING, | 281 NotificationType::APP_EXITING, |
274 NotificationService::AllSources(), | 282 NotificationService::AllSources(), |
275 NotificationService::NoDetails()); | 283 NotificationService::NoDetails()); |
276 | 284 |
277 #if !defined(OS_MACOSX) | 285 #if !defined(OS_MACOSX) |
278 // On most platforms, closing all windows causes the application to exit. | 286 // On most platforms, closing all windows causes the application to exit. |
279 CloseAllBrowsers(true); | 287 CloseAllBrowsers(); |
280 #else | 288 #else |
281 // On the Mac, the application continues to run once all windows are closed. | 289 // On the Mac, the application continues to run once all windows are closed. |
282 // Terminate will result in a CloseAllBrowsers(true) call, and once (and if) | 290 // Terminate will result in a CloseAllBrowsers() call, and once (and if) |
283 // that is done, will cause the application to exit cleanly. | 291 // that is done, will cause the application to exit cleanly. |
284 chrome_browser_application_mac::Terminate(); | 292 chrome_browser_application_mac::Terminate(); |
285 #endif | 293 #endif |
286 } | 294 } |
287 | 295 |
288 // static | 296 // static |
289 void BrowserList::WindowsSessionEnding() { | 297 void BrowserList::WindowsSessionEnding() { |
290 // EndSession is invoked once per frame. Only do something the first time. | 298 // EndSession is invoked once per frame. Only do something the first time. |
291 static bool already_ended = false; | 299 static bool already_ended = false; |
292 if (already_ended) | 300 if (already_ended) |
293 return; | 301 return; |
294 already_ended = true; | 302 already_ended = true; |
295 | 303 |
296 browser_shutdown::OnShutdownStarting(browser_shutdown::END_SESSION); | 304 browser_shutdown::OnShutdownStarting(browser_shutdown::END_SESSION); |
297 | 305 |
298 NotificationService::current()->Notify( | 306 NotificationService::current()->Notify( |
299 NotificationType::APP_EXITING, | 307 NotificationType::APP_EXITING, |
300 NotificationService::AllSources(), | 308 NotificationService::AllSources(), |
301 NotificationService::NoDetails()); | 309 NotificationService::NoDetails()); |
302 | 310 |
303 // Write important data first. | 311 // Write important data first. |
304 g_browser_process->EndSession(); | 312 g_browser_process->EndSession(); |
305 | 313 |
306 // Close all the browsers. | 314 BrowserList::CloseAllBrowsers(); |
307 BrowserList::CloseAllBrowsers(false); | |
308 | 315 |
309 // Send out notification. This is used during testing so that the test harness | 316 // Send out notification. This is used during testing so that the test harness |
310 // can properly shutdown before we exit. | 317 // can properly shutdown before we exit. |
311 NotificationService::current()->Notify( | 318 NotificationService::current()->Notify( |
312 NotificationType::SESSION_END, | 319 NotificationType::SESSION_END, |
313 NotificationService::AllSources(), | 320 NotificationService::AllSources(), |
314 NotificationService::NoDetails()); | 321 NotificationService::NoDetails()); |
315 | 322 |
316 // And shutdown. | 323 // And shutdown. |
317 browser_shutdown::Shutdown(); | 324 browser_shutdown::Shutdown(); |
318 | 325 |
319 #if defined(OS_WIN) | 326 #if defined(OS_WIN) |
320 // At this point the message loop is still running yet we've shut everything | 327 // At this point the message loop is still running yet we've shut everything |
321 // down. If any messages are processed we'll likely crash. Exit now. | 328 // down. If any messages are processed we'll likely crash. Exit now. |
322 ExitProcess(ResultCodes::NORMAL_EXIT); | 329 ExitProcess(ResultCodes::NORMAL_EXIT); |
| 330 #elif defined(OS_LINUX) |
| 331 _exit(ResultCodes::NORMAL_EXIT); |
323 #else | 332 #else |
324 NOTIMPLEMENTED(); | 333 NOTIMPLEMENTED(); |
325 #endif | 334 #endif |
326 } | 335 } |
327 | 336 |
328 // static | 337 // static |
329 bool BrowserList::HasBrowserWithProfile(Profile* profile) { | 338 bool BrowserList::HasBrowserWithProfile(Profile* profile) { |
330 return FindBrowserMatching(BrowserList::begin(), | 339 return FindBrowserMatching(BrowserList::begin(), |
331 BrowserList::end(), | 340 BrowserList::end(), |
332 profile, Browser::TYPE_ANY, | 341 profile, Browser::TYPE_ANY, |
(...skipping 18 matching lines...) Expand all Loading... |
351 DCHECK(keep_alive_count_ > 0); | 360 DCHECK(keep_alive_count_ > 0); |
352 keep_alive_count_--; | 361 keep_alive_count_--; |
353 // Allow the app to shutdown again. | 362 // Allow the app to shutdown again. |
354 if (!WillKeepAlive()) { | 363 if (!WillKeepAlive()) { |
355 g_browser_process->ReleaseModule(); | 364 g_browser_process->ReleaseModule(); |
356 // If there are no browsers open and we aren't already shutting down, | 365 // If there are no browsers open and we aren't already shutting down, |
357 // initiate a shutdown. Also skips shutdown if this is a unit test | 366 // initiate a shutdown. Also skips shutdown if this is a unit test |
358 // (MessageLoop::current() == null). | 367 // (MessageLoop::current() == null). |
359 if (browsers_.empty() && !browser_shutdown::IsTryingToQuit() && | 368 if (browsers_.empty() && !browser_shutdown::IsTryingToQuit() && |
360 MessageLoop::current()) | 369 MessageLoop::current()) |
361 CloseAllBrowsers(true); | 370 CloseAllBrowsers(); |
362 } | 371 } |
363 } | 372 } |
364 | 373 |
365 // static | 374 // static |
366 bool BrowserList::WillKeepAlive() { | 375 bool BrowserList::WillKeepAlive() { |
367 return keep_alive_count_ > 0; | 376 return keep_alive_count_ > 0; |
368 } | 377 } |
369 | 378 |
370 // static | 379 // static |
371 BrowserList::BrowserVector BrowserList::last_active_browsers_; | 380 BrowserList::BrowserVector BrowserList::last_active_browsers_; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 } | 516 } |
508 | 517 |
509 TabContents* next_tab = | 518 TabContents* next_tab = |
510 (*browser_iterator_)->GetTabContentsAt(web_view_index_); | 519 (*browser_iterator_)->GetTabContentsAt(web_view_index_); |
511 if (next_tab) { | 520 if (next_tab) { |
512 cur_ = next_tab; | 521 cur_ = next_tab; |
513 return; | 522 return; |
514 } | 523 } |
515 } | 524 } |
516 } | 525 } |
OLD | NEW |