Chromium Code Reviews| Index: chrome/browser/ui/browser.cc |
| diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc |
| index 0187b1df5a251a52b720e293230a61992b418458..30814f6eb7e7031a2d4b61c8c003faf9e6ffca15 100644 |
| --- a/chrome/browser/ui/browser.cc |
| +++ b/chrome/browser/ui/browser.cc |
| @@ -17,8 +17,8 @@ |
| #include "base/logging.h" |
| #include "base/metrics/histogram.h" |
| #include "base/path_service.h" |
| -#include "base/string_util.h" |
| #include "base/string_number_conversions.h" |
| +#include "base/string_util.h" |
| #include "base/threading/thread.h" |
| #include "base/threading/thread_restrictions.h" |
| #include "base/time.h" |
| @@ -58,6 +58,7 @@ |
| #include "chrome/browser/prefs/pref_service.h" |
| #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/sessions/restore_tab_helper.h" |
| #include "chrome/browser/sessions/session_service.h" |
| #include "chrome/browser/sessions/session_service_factory.h" |
| @@ -1047,6 +1048,71 @@ void Browser::InProgressDownloadResponse(bool cancel_downloads) { |
| ShowDownloadsTab(); |
| } |
| +Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads( |
| + int* num_downloads_blocking) const { |
| + DCHECK(num_downloads_blocking); |
| + |
| + if (is_attempting_to_close_browser_) |
| + return DOWNLOAD_CLOSE_OK; |
| + |
| + // If we're not running a full browser process with a profile manager |
| + // (testing), it's ok to close the browser. |
| + if (!g_browser_process->profile_manager()) |
| + return DOWNLOAD_CLOSE_OK; |
| + |
| + int total_download_count = |
| + g_browser_process->profile_manager()->TotalDownloadCount(); |
| + if (total_download_count == 0) |
| + return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close. |
| + |
| + // Let's figure out if we are the last window for our profile, and |
| + // the last window period. |
| + // Note that we cannot just use BrowserList::GetBrowserCount as browser |
| + // windows closing is delayed and the returned count might include windows |
| + // that are being closed. |
| + // The browser allowed to be closed only if: |
| + // 1. It is a regular browser and there are no regular downloads present or |
| + // this is not the last regular browser window. |
|
asanka
2011/08/04 19:07:10
As mentioned offline, a browser with regular downl
|
| + // 2. It is an incognito browser and there are no incognito downloads present |
| + // for this incognito profile or this is not the last incognito |
| + // browser window. |
| + // Note the lack of parallelism: regular profiles are kept around until |
| + // browser close, whereas incognito profiles are destroyed on last |
| + // associated window close. |
| + int profile_window_count = 0; |
| + int total_window_count = 0; |
| + for (BrowserList::const_iterator iter = BrowserList::begin(); |
| + iter != BrowserList::end(); ++iter) { |
| + // Don't count this browser window or any other in the process of closing. |
| + Browser* const browser = *iter; |
| + if (browser == this || |
| + browser->is_attempting_to_close_browser_) |
| + continue; |
| + |
| + if ((*iter)->profile() == profile()) |
| + profile_window_count++; |
| + total_window_count++; |
| + } |
| + |
| + // If there aren't any other windows, we're at browser shutdown. |
| + if (total_window_count == 0) { |
| + *num_downloads_blocking = total_download_count; |
| + return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN; |
| + } |
| + |
| + // If there aren't any other windows on our profile, we're an incognito |
| + // profile, and there are downloads associated with that profile, |
| + // indicate that. |
| + if (profile_window_count == 0 && profile()->DownloadCount() > 0 && |
| + profile()->IsOffTheRecord()) { |
| + *num_downloads_blocking = profile()->DownloadCount(); |
| + return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE; |
| + } |
| + |
| + // Those are the only conditions under which we will block shutdown. |
| + return DOWNLOAD_CLOSE_OK; |
| +} |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // Browser, TabStripModel pass-thrus: |
| @@ -4429,32 +4495,6 @@ void Browser::ClearUnloadState(TabContents* tab, bool process_now) { |
| /////////////////////////////////////////////////////////////////////////////// |
| // Browser, In-progress download termination handling (private): |
| -void Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present, |
| - bool* incognito_downloads_are_present) { |
| - *normal_downloads_are_present = false; |
| - *incognito_downloads_are_present = false; |
| - |
| - // If there are no download in-progress, our job is done. |
| - DownloadManager* download_manager = NULL; |
| - // But first we need to check for the existence of the download manager, as |
| - // GetDownloadManager() will unnecessarily try to create one if it does not |
| - // exist. |
| - if (profile()->HasCreatedDownloadManager()) |
| - download_manager = profile()->GetDownloadManager(); |
| - if (profile()->IsOffTheRecord()) { |
| - // Browser is incognito and so download_manager if present is for incognito |
| - // downloads. |
| - *incognito_downloads_are_present = |
| - (download_manager && download_manager->in_progress_count() != 0); |
| - // Check original profile. |
| - if (profile()->GetOriginalProfile()->HasCreatedDownloadManager()) |
| - download_manager = profile()->GetOriginalProfile()->GetDownloadManager(); |
| - } |
| - |
| - *normal_downloads_are_present = |
| - (download_manager && download_manager->in_progress_count() != 0); |
| -} |
| - |
| bool Browser::CanCloseWithInProgressDownloads() { |
| if (cancel_download_confirmation_state_ != NOT_PROMPTED) { |
| if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) { |
| @@ -4464,61 +4504,14 @@ bool Browser::CanCloseWithInProgressDownloads() { |
| // RESPONSE_RECEIVED case, the user decided to go along with the closing. |
| return true; |
| } |
| - // Indicated that normal (non-incognito) downloads are pending. |
| - bool normal_downloads_are_present = false; |
| - bool incognito_downloads_are_present = false; |
| - CheckDownloadsInProgress(&normal_downloads_are_present, |
| - &incognito_downloads_are_present); |
| - if (!normal_downloads_are_present && !incognito_downloads_are_present) |
| - return true; |
| - |
| - if (is_attempting_to_close_browser_) |
| - return true; |
| - |
| - if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) || |
| - (!incognito_downloads_are_present && profile()->IsOffTheRecord())) |
| - return true; |
| - // Let's figure out if we are the last window for our profile. |
| - // Note that we cannot just use BrowserList::GetBrowserCount as browser |
| - // windows closing is delayed and the returned count might include windows |
| - // that are being closed. |
| - // The browser allowed to be closed only if: |
| - // 1. It is a regular browser and there are no regular downloads present or |
| - // this is not the last regular browser window. |
| - // 2. It is an incognito browser and there are no incognito downloads present |
| - // or this is not the last incognito browser window. |
| - int count = 0; |
| - for (BrowserList::const_iterator iter = BrowserList::begin(); |
| - iter != BrowserList::end(); ++iter) { |
| - // Don't count this browser window or any other in the process of closing. |
| - // Only consider tabbed browser windows, not popups. |
| - Browser* const browser = *iter; |
| - if (browser == this |
| - || browser->is_attempting_to_close_browser_ |
| - || !browser->is_type_tabbed()) |
| - continue; |
| - |
| - // Verify that this is not the last non-incognito or incognito browser, |
| - // depending on the pending downloads. |
| - if (normal_downloads_are_present && !profile()->IsOffTheRecord() && |
| - browser->profile()->IsOffTheRecord()) |
| - continue; |
| - if (incognito_downloads_are_present && profile()->IsOffTheRecord() && |
| - !browser->profile()->IsOffTheRecord()) |
| - continue; |
| - |
| - // We test the original profile, because an incognito browser window keeps |
| - // the original profile alive (and its DownloadManager). |
| - // We also need to test explicitly the profile directly so that 2 incognito |
| - // profiles count as a match. |
| - if ((*iter)->profile() == profile() || |
| - (*iter)->profile()->GetOriginalProfile() == profile()) |
| - count++; |
| - } |
| - if (count > 0) |
| + int num_downloads_blocking; |
| + if (DOWNLOAD_CLOSE_OK == |
| + OkToCloseWithInProgressDownloads(&num_downloads_blocking)) |
| return true; |
| + // Closing this window will kill some downloads; prompt to make sure |
| + // that's ok. |
| cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; |
| window_->ConfirmBrowserCloseWithPendingDownloads(); |