[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / lifetime / browser_close_manager.cc
blob13982f1d77a019121f3b8170631caac25894e6bd
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
3 // found in the LICENSE file.
5 #include "chrome/browser/lifetime/browser_close_manager.h"
7 #include "chrome/browser/background/background_mode_manager.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/browser_shutdown.h"
10 #include "chrome/browser/download/download_service.h"
11 #include "chrome/browser/download/download_service_factory.h"
12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_iterator.h"
15 #include "chrome/browser/ui/browser_list.h"
16 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/browser/ui/chrome_pages.h"
18 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "content/public/browser/web_contents.h"
22 BrowserCloseManager::BrowserCloseManager() : current_browser_(NULL) {}
24 BrowserCloseManager::~BrowserCloseManager() {}
26 void BrowserCloseManager::StartClosingBrowsers() {
27 // If the session is ending, skip straight to closing the browsers. There's no
28 // time to wait for beforeunload dialogs.
29 if (browser_shutdown::GetShutdownType() == browser_shutdown::END_SESSION) {
30 // Tell everyone that we are shutting down.
31 browser_shutdown::SetTryingToQuit(true);
32 CloseBrowsers();
33 return;
35 TryToCloseBrowsers();
38 void BrowserCloseManager::CancelBrowserClose() {
39 browser_shutdown::SetTryingToQuit(false);
40 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
41 it->ResetBeforeUnloadHandlers();
45 void BrowserCloseManager::TryToCloseBrowsers() {
46 // If all browser windows can immediately be closed, fall out of this loop and
47 // close the browsers. If any browser window cannot be closed, temporarily
48 // stop closing. CallBeforeUnloadHandlers prompts the user and calls
49 // OnBrowserReportCloseable with the result. If the user confirms the close,
50 // this will trigger TryToCloseBrowsers to try again.
51 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
52 if (it->CallBeforeUnloadHandlers(
53 base::Bind(&BrowserCloseManager::OnBrowserReportCloseable, this))) {
54 current_browser_ = *it;
55 return;
58 CheckForDownloadsInProgress();
61 void BrowserCloseManager::OnBrowserReportCloseable(bool proceed) {
62 if (!current_browser_)
63 return;
65 current_browser_ = NULL;
67 if (proceed)
68 TryToCloseBrowsers();
69 else
70 CancelBrowserClose();
73 void BrowserCloseManager::CheckForDownloadsInProgress() {
74 int download_count = DownloadService::NonMaliciousDownloadCountAllProfiles();
75 if (download_count == 0) {
76 CloseBrowsers();
77 return;
79 ConfirmCloseWithPendingDownloads(
80 download_count,
81 base::Bind(&BrowserCloseManager::OnReportDownloadsCancellable, this));
84 void BrowserCloseManager::ConfirmCloseWithPendingDownloads(
85 int download_count,
86 const base::Callback<void(bool)>& callback) {
87 Browser* browser =
88 BrowserList::GetInstance(chrome::GetActiveDesktop())->GetLastActive();
89 DCHECK(browser);
90 browser->window()->ConfirmBrowserCloseWithPendingDownloads(
91 download_count,
92 Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN,
93 true,
94 callback);
97 void BrowserCloseManager::OnReportDownloadsCancellable(bool proceed) {
98 if (proceed) {
99 CloseBrowsers();
100 return;
103 CancelBrowserClose();
105 // Open the downloads page for each profile with downloads in progress.
106 std::vector<Profile*> profiles(
107 g_browser_process->profile_manager()->GetLoadedProfiles());
108 for (std::vector<Profile*>::iterator it = profiles.begin();
109 it != profiles.end();
110 ++it) {
111 DownloadService* download_service =
112 DownloadServiceFactory::GetForBrowserContext(*it);
113 if (download_service->NonMaliciousDownloadCount() > 0) {
114 chrome::ScopedTabbedBrowserDisplayer displayer(
115 *it, chrome::GetActiveDesktop());
116 chrome::ShowDownloads(displayer.browser());
121 void BrowserCloseManager::CloseBrowsers() {
122 #if defined(ENABLE_SESSION_SERVICE)
123 // Before we close the browsers shutdown all session services. That way an
124 // exit can restore all browsers open before exiting.
125 ProfileManager::ShutdownSessionServices();
126 #endif
127 if (!browser_shutdown::IsTryingToQuit()) {
128 BackgroundModeManager* background_mode_manager =
129 g_browser_process->background_mode_manager();
130 if (background_mode_manager)
131 background_mode_manager->SuspendBackgroundMode();
134 bool session_ending =
135 browser_shutdown::GetShutdownType() == browser_shutdown::END_SESSION;
136 for (scoped_ptr<chrome::BrowserIterator> it_ptr(
137 new chrome::BrowserIterator());
138 !it_ptr->done();) {
139 Browser* browser = **it_ptr;
140 browser->window()->Close();
141 if (!session_ending) {
142 it_ptr->Next();
143 } else {
144 // This path is hit during logoff/power-down. In this case we won't get
145 // a final message and so we force the browser to be deleted.
146 // Close doesn't immediately destroy the browser
147 // (Browser::TabStripEmpty() uses invoke later) but when we're ending the
148 // session we need to make sure the browser is destroyed now. So, invoke
149 // DestroyBrowser to make sure the browser is deleted and cleanup can
150 // happen.
151 while (browser->tab_strip_model()->count())
152 delete browser->tab_strip_model()->GetWebContentsAt(0);
153 browser->window()->DestroyBrowser();
154 it_ptr.reset(new chrome::BrowserIterator());
155 if (!it_ptr->done() && browser == **it_ptr) {
156 // Destroying the browser should have removed it from the browser list.
157 // We should never get here.
158 NOTREACHED();
159 return;