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(); |