Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: chrome/browser/ui/browser.cc

Issue 7466033: Fix warning prompting on closing a window that will cancel downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make sure to use temporary download directory Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/browser.h ('k') | chrome/browser/ui/browser_close_browsertest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/ui/browser.h" 5 #include "chrome/browser/ui/browser.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <windows.h> 8 #include <windows.h>
9 #include <shellapi.h> 9 #include <shellapi.h>
10 #endif // OS_WIN 10 #endif // OS_WIN
11 11
12 #include <algorithm> 12 #include <algorithm>
13 #include <string> 13 #include <string>
14 14
15 #include "base/base_paths.h" 15 #include "base/base_paths.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/metrics/field_trial.h" 18 #include "base/metrics/field_trial.h"
19 #include "base/metrics/histogram.h" 19 #include "base/metrics/histogram.h"
20 #include "base/path_service.h" 20 #include "base/path_service.h"
21 #include "base/string_number_conversions.h" 21 #include "base/string_number_conversions.h"
22 #include "base/string_util.h"
22 #include "base/stringprintf.h" 23 #include "base/stringprintf.h"
23 #include "base/string_util.h"
24 #include "base/threading/thread.h" 24 #include "base/threading/thread.h"
25 #include "base/threading/thread_restrictions.h" 25 #include "base/threading/thread_restrictions.h"
26 #include "base/time.h" 26 #include "base/time.h"
27 #include "base/utf_string_conversions.h" 27 #include "base/utf_string_conversions.h"
28 #include "chrome/app/chrome_command_ids.h" 28 #include "chrome/app/chrome_command_ids.h"
29 #include "chrome/browser/autofill/autofill_manager.h" 29 #include "chrome/browser/autofill/autofill_manager.h"
30 #include "chrome/browser/autofill/personal_data_manager_factory.h" 30 #include "chrome/browser/autofill/personal_data_manager_factory.h"
31 #include "chrome/browser/background/background_contents_service.h" 31 #include "chrome/browser/background/background_contents_service.h"
32 #include "chrome/browser/bookmarks/bookmark_model.h" 32 #include "chrome/browser/bookmarks/bookmark_model.h"
33 #include "chrome/browser/bookmarks/bookmark_utils.h" 33 #include "chrome/browser/bookmarks/bookmark_utils.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 #include "chrome/browser/notifications/notification_ui_manager.h" 68 #include "chrome/browser/notifications/notification_ui_manager.h"
69 #include "chrome/browser/platform_util.h" 69 #include "chrome/browser/platform_util.h"
70 #include "chrome/browser/prefs/incognito_mode_prefs.h" 70 #include "chrome/browser/prefs/incognito_mode_prefs.h"
71 #include "chrome/browser/prefs/pref_service.h" 71 #include "chrome/browser/prefs/pref_service.h"
72 #include "chrome/browser/prerender/prerender_tab_helper.h" 72 #include "chrome/browser/prerender/prerender_tab_helper.h"
73 #include "chrome/browser/printing/background_printing_manager.h" 73 #include "chrome/browser/printing/background_printing_manager.h"
74 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" 74 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
75 #include "chrome/browser/printing/print_preview_tab_controller.h" 75 #include "chrome/browser/printing/print_preview_tab_controller.h"
76 #include "chrome/browser/printing/print_view_manager.h" 76 #include "chrome/browser/printing/print_view_manager.h"
77 #include "chrome/browser/profiles/profile.h" 77 #include "chrome/browser/profiles/profile.h"
78 #include "chrome/browser/profiles/profile_manager.h"
78 #include "chrome/browser/sessions/restore_tab_helper.h" 79 #include "chrome/browser/sessions/restore_tab_helper.h"
79 #include "chrome/browser/sessions/session_service.h" 80 #include "chrome/browser/sessions/session_service.h"
80 #include "chrome/browser/sessions/session_service_factory.h" 81 #include "chrome/browser/sessions/session_service_factory.h"
81 #include "chrome/browser/sessions/session_types.h" 82 #include "chrome/browser/sessions/session_types.h"
82 #include "chrome/browser/sessions/tab_restore_service.h" 83 #include "chrome/browser/sessions/tab_restore_service.h"
83 #include "chrome/browser/sessions/tab_restore_service_factory.h" 84 #include "chrome/browser/sessions/tab_restore_service_factory.h"
84 #include "chrome/browser/sync/profile_sync_service.h" 85 #include "chrome/browser/sync/profile_sync_service.h"
85 #include "chrome/browser/sync/sync_ui_util.h" 86 #include "chrome/browser/sync/sync_ui_util.h"
86 #include "chrome/browser/tab_closeable_state_watcher.h" 87 #include "chrome/browser/tab_closeable_state_watcher.h"
87 #include "chrome/browser/tab_contents/background_contents.h" 88 #include "chrome/browser/tab_contents/background_contents.h"
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 1047
1047 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to 1048 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
1048 // close again we'll show the warning again. 1049 // close again we'll show the warning again.
1049 cancel_download_confirmation_state_ = NOT_PROMPTED; 1050 cancel_download_confirmation_state_ = NOT_PROMPTED;
1050 1051
1051 // Show the download page so the user can figure-out what downloads are still 1052 // Show the download page so the user can figure-out what downloads are still
1052 // in-progress. 1053 // in-progress.
1053 ShowDownloadsTab(); 1054 ShowDownloadsTab();
1054 } 1055 }
1055 1056
1057 Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads(
1058 int* num_downloads_blocking) const {
1059 DCHECK(num_downloads_blocking);
1060 *num_downloads_blocking = 0;
1061
1062 if (is_attempting_to_close_browser_)
1063 return DOWNLOAD_CLOSE_OK;
1064
1065 // If we're not running a full browser process with a profile manager
1066 // (testing), it's ok to close the browser.
1067 if (!g_browser_process->profile_manager())
1068 return DOWNLOAD_CLOSE_OK;
1069
1070 int total_download_count = DownloadService::DownloadCountAllProfiles();
1071 if (total_download_count == 0)
1072 return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close.
1073
1074 // Figure out how many windows are open total, and associated with this
1075 // profile, that are relevant for the ok-to-close decision.
1076 int profile_window_count = 0;
1077 int total_window_count = 0;
1078 for (BrowserList::const_iterator iter = BrowserList::begin();
1079 iter != BrowserList::end(); ++iter) {
1080 // Don't count this browser window or any other in the process of closing.
1081 Browser* const browser = *iter;
1082 // Check is_attempting_to_close_browser_ as window closing may be
1083 // delayed, and windows that are in the process of closing don't
1084 // count against our totals.
1085 if (browser == this || browser->is_attempting_to_close_browser_)
1086 continue;
1087
1088 if ((*iter)->profile() == profile())
1089 profile_window_count++;
1090 total_window_count++;
1091 }
1092
1093 // If there aren't any other windows, we're at browser shutdown,
1094 // which would cancel all current downloads.
1095 if (total_window_count == 0) {
1096 *num_downloads_blocking = total_download_count;
1097 return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN;
1098 }
1099
1100 // If there aren't any other windows on our profile, and we're an incognito
1101 // profile, and there are downloads associated with that profile,
1102 // those downloads would be cancelled by our window (-> profile) close.
1103 DownloadService* download_service =
1104 DownloadServiceFactory::GetForProfile(profile());
1105 if (profile_window_count == 0 && download_service->DownloadCount() > 0 &&
1106 profile()->IsOffTheRecord()) {
1107 *num_downloads_blocking = download_service->DownloadCount();
1108 return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE;
1109 }
1110
1111 // Those are the only conditions under which we will block shutdown.
1112 return DOWNLOAD_CLOSE_OK;
1113 }
1114
1056 //////////////////////////////////////////////////////////////////////////////// 1115 ////////////////////////////////////////////////////////////////////////////////
1057 // Browser, TabStripModel pass-thrus: 1116 // Browser, TabStripModel pass-thrus:
1058 1117
1059 int Browser::tab_count() const { 1118 int Browser::tab_count() const {
1060 return tab_handler_->GetTabStripModel()->count(); 1119 return tab_handler_->GetTabStripModel()->count();
1061 } 1120 }
1062 1121
1063 int Browser::active_index() const { 1122 int Browser::active_index() const {
1064 return tab_handler_->GetTabStripModel()->active_index(); 1123 return tab_handler_->GetTabStripModel()->active_index();
1065 } 1124 }
(...skipping 3958 matching lines...) Expand 10 before | Expand all | Expand 10 after
5024 MessageLoop::current()->PostTask( 5083 MessageLoop::current()->PostTask(
5025 FROM_HERE, 5084 FROM_HERE,
5026 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); 5085 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs));
5027 } 5086 }
5028 } 5087 }
5029 } 5088 }
5030 5089
5031 /////////////////////////////////////////////////////////////////////////////// 5090 ///////////////////////////////////////////////////////////////////////////////
5032 // Browser, In-progress download termination handling (private): 5091 // Browser, In-progress download termination handling (private):
5033 5092
5034 void Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present, 5093 bool Browser::CanCloseWithInProgressDownloads() {
5035 bool* incognito_downloads_are_present) { 5094 // If we've prompted, we need to hear from the user before we
5036 *normal_downloads_are_present = false; 5095 // can close.
5037 *incognito_downloads_are_present = false; 5096 if (cancel_download_confirmation_state_ != NOT_PROMPTED)
5097 return cancel_download_confirmation_state_ != WAITING_FOR_RESPONSE;
5038 5098
5039 // If there are no download in-progress, our job is done. 5099 int num_downloads_blocking;
5040 DownloadManager* download_manager = NULL; 5100 if (DOWNLOAD_CLOSE_OK ==
5041 DownloadService* download_service = 5101 OkToCloseWithInProgressDownloads(&num_downloads_blocking))
5042 DownloadServiceFactory::GetForProfile(profile());
5043 // But first we need to check for the existence of the download manager, as
5044 // GetDownloadManager() will unnecessarily try to create one if it does not
5045 // exist.
5046 if (download_service->HasCreatedDownloadManager())
5047 download_manager = download_service->GetDownloadManager();
5048 if (profile()->IsOffTheRecord()) {
5049 // Browser is incognito and so download_manager if present is for incognito
5050 // downloads.
5051 *incognito_downloads_are_present =
5052 (download_manager && download_manager->in_progress_count() != 0);
5053 // Check original profile.
5054 DownloadService* download_service = DownloadServiceFactory::GetForProfile(
5055 profile()->GetOriginalProfile());
5056 if (download_service->HasCreatedDownloadManager())
5057 download_manager = download_service->GetDownloadManager();
5058 }
5059
5060 *normal_downloads_are_present =
5061 (download_manager && download_manager->in_progress_count() != 0);
5062 }
5063
5064 bool Browser::CanCloseWithInProgressDownloads() {
5065 if (cancel_download_confirmation_state_ != NOT_PROMPTED) {
5066 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) {
5067 // We need to hear from the user before we can close.
5068 return false;
5069 }
5070 // RESPONSE_RECEIVED case, the user decided to go along with the closing.
5071 return true;
5072 }
5073 // Indicated that normal (non-incognito) downloads are pending.
5074 bool normal_downloads_are_present = false;
5075 bool incognito_downloads_are_present = false;
5076 CheckDownloadsInProgress(&normal_downloads_are_present,
5077 &incognito_downloads_are_present);
5078 if (!normal_downloads_are_present && !incognito_downloads_are_present)
5079 return true; 5102 return true;
5080 5103
5081 if (is_attempting_to_close_browser_) 5104 // Closing this window will kill some downloads; prompt to make sure
5082 return true; 5105 // that's ok.
5083
5084 if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) ||
5085 (!incognito_downloads_are_present && profile()->IsOffTheRecord()))
5086 return true;
5087
5088 // Let's figure out if we are the last window for our profile.
5089 // Note that we cannot just use BrowserList::GetBrowserCount as browser
5090 // windows closing is delayed and the returned count might include windows
5091 // that are being closed.
5092 // The browser allowed to be closed only if:
5093 // 1. It is a regular browser and there are no regular downloads present or
5094 // this is not the last regular browser window.
5095 // 2. It is an incognito browser and there are no incognito downloads present
5096 // or this is not the last incognito browser window.
5097 int count = 0;
5098 for (BrowserList::const_iterator iter = BrowserList::begin();
5099 iter != BrowserList::end(); ++iter) {
5100 // Don't count this browser window or any other in the process of closing.
5101 // Only consider tabbed browser windows, not popups.
5102 Browser* const browser = *iter;
5103 if (browser == this
5104 || browser->is_attempting_to_close_browser_
5105 || !browser->is_type_tabbed())
5106 continue;
5107
5108 // Verify that this is not the last non-incognito or incognito browser,
5109 // depending on the pending downloads.
5110 if (normal_downloads_are_present && !profile()->IsOffTheRecord() &&
5111 browser->profile()->IsOffTheRecord())
5112 continue;
5113 if (incognito_downloads_are_present && profile()->IsOffTheRecord() &&
5114 !browser->profile()->IsOffTheRecord())
5115 continue;
5116
5117 // We test the original profile, because an incognito browser window keeps
5118 // the original profile alive (and its DownloadManager).
5119 // We also need to test explicitly the profile directly so that 2 incognito
5120 // profiles count as a match.
5121 if ((*iter)->profile() == profile() ||
5122 (*iter)->profile()->GetOriginalProfile() == profile())
5123 count++;
5124 }
5125 if (count > 0)
5126 return true;
5127
5128 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; 5106 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
5129 window_->ConfirmBrowserCloseWithPendingDownloads(); 5107 window_->ConfirmBrowserCloseWithPendingDownloads();
5130 5108
5131 // Return false so the browser does not close. We'll close if the user 5109 // Return false so the browser does not close. We'll close if the user
5132 // confirms in the dialog. 5110 // confirms in the dialog.
5133 return false; 5111 return false;
5134 } 5112 }
5135 5113
5136 /////////////////////////////////////////////////////////////////////////////// 5114 ///////////////////////////////////////////////////////////////////////////////
5137 // Browser, Assorted utility functions (private): 5115 // Browser, Assorted utility functions (private):
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
5499 } 5477 }
5500 5478
5501 void Browser::UpdateFullscreenExitBubbleContent() { 5479 void Browser::UpdateFullscreenExitBubbleContent() {
5502 GURL url; 5480 GURL url;
5503 if (fullscreened_tab_) 5481 if (fullscreened_tab_)
5504 url = fullscreened_tab_->tab_contents()->GetURL(); 5482 url = fullscreened_tab_->tab_contents()->GetURL();
5505 5483
5506 window_->UpdateFullscreenExitBubbleContent( 5484 window_->UpdateFullscreenExitBubbleContent(
5507 url, GetFullscreenExitBubbleType()); 5485 url, GetFullscreenExitBubbleType());
5508 } 5486 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/browser.h ('k') | chrome/browser/ui/browser_close_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698