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

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: Removed unneeded friend decls and tweaked a comment. Created 9 years, 5 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
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/histogram.h" 18 #include "base/metrics/histogram.h"
19 #include "base/path_service.h" 19 #include "base/path_service.h"
20 #include "base/string_number_conversions.h"
20 #include "base/string_util.h" 21 #include "base/string_util.h"
21 #include "base/string_number_conversions.h"
22 #include "base/threading/thread.h" 22 #include "base/threading/thread.h"
23 #include "base/threading/thread_restrictions.h" 23 #include "base/threading/thread_restrictions.h"
24 #include "base/time.h" 24 #include "base/time.h"
25 #include "base/utf_string_conversions.h" 25 #include "base/utf_string_conversions.h"
26 #include "chrome/app/chrome_command_ids.h" 26 #include "chrome/app/chrome_command_ids.h"
27 #include "chrome/browser/autofill/autofill_manager.h" 27 #include "chrome/browser/autofill/autofill_manager.h"
28 #include "chrome/browser/background/background_contents_service.h" 28 #include "chrome/browser/background/background_contents_service.h"
29 #include "chrome/browser/bookmarks/bookmark_model.h" 29 #include "chrome/browser/bookmarks/bookmark_model.h"
30 #include "chrome/browser/bookmarks/bookmark_utils.h" 30 #include "chrome/browser/bookmarks/bookmark_utils.h"
31 #include "chrome/browser/browser_process.h" 31 #include "chrome/browser/browser_process.h"
(...skipping 19 matching lines...) Expand all
51 #include "chrome/browser/google/google_util.h" 51 #include "chrome/browser/google/google_util.h"
52 #include "chrome/browser/instant/instant_controller.h" 52 #include "chrome/browser/instant/instant_controller.h"
53 #include "chrome/browser/instant/instant_unload_handler.h" 53 #include "chrome/browser/instant/instant_unload_handler.h"
54 #include "chrome/browser/net/browser_url_util.h" 54 #include "chrome/browser/net/browser_url_util.h"
55 #include "chrome/browser/net/url_fixer_upper.h" 55 #include "chrome/browser/net/url_fixer_upper.h"
56 #include "chrome/browser/notifications/notification_ui_manager.h" 56 #include "chrome/browser/notifications/notification_ui_manager.h"
57 #include "chrome/browser/platform_util.h" 57 #include "chrome/browser/platform_util.h"
58 #include "chrome/browser/prefs/pref_service.h" 58 #include "chrome/browser/prefs/pref_service.h"
59 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" 59 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
60 #include "chrome/browser/profiles/profile.h" 60 #include "chrome/browser/profiles/profile.h"
61 #include "chrome/browser/profiles/profile_manager.h"
61 #include "chrome/browser/sessions/restore_tab_helper.h" 62 #include "chrome/browser/sessions/restore_tab_helper.h"
62 #include "chrome/browser/sessions/session_service.h" 63 #include "chrome/browser/sessions/session_service.h"
63 #include "chrome/browser/sessions/session_service_factory.h" 64 #include "chrome/browser/sessions/session_service_factory.h"
64 #include "chrome/browser/sessions/session_types.h" 65 #include "chrome/browser/sessions/session_types.h"
65 #include "chrome/browser/sessions/tab_restore_service.h" 66 #include "chrome/browser/sessions/tab_restore_service.h"
66 #include "chrome/browser/sessions/tab_restore_service_factory.h" 67 #include "chrome/browser/sessions/tab_restore_service_factory.h"
67 #include "chrome/browser/sync/profile_sync_service.h" 68 #include "chrome/browser/sync/profile_sync_service.h"
68 #include "chrome/browser/sync/sync_ui_util.h" 69 #include "chrome/browser/sync/sync_ui_util.h"
69 #include "chrome/browser/tab_closeable_state_watcher.h" 70 #include "chrome/browser/tab_closeable_state_watcher.h"
70 #include "chrome/browser/tab_contents/background_contents.h" 71 #include "chrome/browser/tab_contents/background_contents.h"
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 1036
1036 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to 1037 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
1037 // close again we'll show the warning again. 1038 // close again we'll show the warning again.
1038 cancel_download_confirmation_state_ = NOT_PROMPTED; 1039 cancel_download_confirmation_state_ = NOT_PROMPTED;
1039 1040
1040 // Show the download page so the user can figure-out what downloads are still 1041 // Show the download page so the user can figure-out what downloads are still
1041 // in-progress. 1042 // in-progress.
1042 ShowDownloadsTab(); 1043 ShowDownloadsTab();
1043 } 1044 }
1044 1045
1046 bool Browser::OkToCloseWithInProgressDownloads(
1047 DownloadClosePreventionType* type,
1048 int* num_downloads_blocking) const {
1049 DCHECK(type);
1050 DCHECK(num_downloads_blocking);
1051
1052 if (is_attempting_to_close_browser_)
1053 return true;
1054
1055 int total_download_count = 0;
1056 int profile_download_count = 0;
1057 CheckDownloadsInProgress(&total_download_count, &profile_download_count);
1058 if (total_download_count == 0)
1059 return true; // No downloads; can definitely close.
1060
1061 // Let's figure out if we are the last window for our profile, and
sky 2011/07/21 20:08:11 window -> tabbed window
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 Done.
1062 // the last window period.
1063 // Note that we cannot just use BrowserList::GetBrowserCount as browser
1064 // windows closing is delayed and the returned count might include windows
1065 // that are being closed.
1066 // The browser allowed to be closed only if:
1067 // 1. It is a regular browser and there are no regular downloads present or
1068 // this is not the last regular browser window.
1069 // 2. It is an incognito browser and there are no incognito downloads present
1070 // for this incognito profile or this is not the last incognito
1071 // browser window.
1072 // Note the lack of parallelism: regular profiles are kept around until
1073 // browser close, whereas incognito profiles are destroyed on last
1074 // associated window close.
1075 int profile_window_count = 0;
1076 int total_window_count = 0;
1077 for (BrowserList::const_iterator iter = BrowserList::begin();
1078 iter != BrowserList::end(); ++iter) {
1079 // Don't count this browser window or any other in the process of closing.
1080 // Only consider tabbed browser windows, not popups.
1081 Browser* const browser = *iter;
1082 if (browser == this
1083 || browser->is_attempting_to_close_browser_
sky 2011/07/21 20:08:11 nit: || on previous line
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 Done.
1084 || !browser->is_type_tabbed())
sky 2011/07/21 20:08:11 How come non-tabbed windows don't count?
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 That's an excellent question and I don't know the
sky 2011/07/22 03:00:40 Popups are the common case of a non-tabbed browser
Randy Smith (Not in Mondays) 2011/07/22 20:41:30 Ok, sounds like I shouldn't exclude non-tabbed stu
1085 continue;
1086
1087 if ((*iter)->profile() == profile())
1088 profile_window_count++;
1089 total_window_count++;
1090 }
1091
1092 // If there aren't any other windows, we're at browser shutdown.
1093 if (total_window_count == 0) {
1094 *type = BROWSER_SHUTDOWN;
sky 2011/07/21 20:08:11 Since this case just means there are no more tabbe
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 Profiles are only killed on browser shutdown, so i
sky 2011/07/22 03:00:40 non-tabbed windows definitely keep chrome running.
Randy Smith (Not in Mondays) 2011/07/22 20:41:30 Done.
1095 *num_downloads_blocking = total_download_count;
1096 return false;
1097 }
1098
1099 // If there aren't any other windows on our profile, we're an incognito
1100 // profile, and there are downloads associated with that profile,
1101 // indicate that.
1102 if (profile_window_count == 0 && profile_download_count > 0 &&
1103 profile()->IsOffTheRecord()) {
1104 *type = LAST_WINDOW_IN_INCOGNITO_PROFILE;
sky 2011/07/21 20:08:11 LAST_WINDOW -> LAST_TABBED_BROWSER
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 Holding off on this until we resolve the tabbed wi
1105 *num_downloads_blocking = profile_download_count;
1106 return false;
1107 }
1108
1109 // Those are the only conditions under which we will block shutdown.
1110 return true;
1111 }
1112
1045 //////////////////////////////////////////////////////////////////////////////// 1113 ////////////////////////////////////////////////////////////////////////////////
1046 // Browser, TabStripModel pass-thrus: 1114 // Browser, TabStripModel pass-thrus:
1047 1115
1048 int Browser::tab_count() const { 1116 int Browser::tab_count() const {
1049 return tab_handler_->GetTabStripModel()->count(); 1117 return tab_handler_->GetTabStripModel()->count();
1050 } 1118 }
1051 1119
1052 int Browser::active_index() const { 1120 int Browser::active_index() const {
1053 return tab_handler_->GetTabStripModel()->active_index(); 1121 return tab_handler_->GetTabStripModel()->active_index();
1054 } 1122 }
(...skipping 3337 matching lines...) Expand 10 before | Expand all | Expand 10 after
4392 MessageLoop::current()->PostTask( 4460 MessageLoop::current()->PostTask(
4393 FROM_HERE, 4461 FROM_HERE,
4394 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); 4462 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs));
4395 } 4463 }
4396 } 4464 }
4397 } 4465 }
4398 4466
4399 /////////////////////////////////////////////////////////////////////////////// 4467 ///////////////////////////////////////////////////////////////////////////////
4400 // Browser, In-progress download termination handling (private): 4468 // Browser, In-progress download termination handling (private):
4401 4469
4402 void Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present, 4470 void Browser::CheckDownloadsInProgress(int* total_download_count,
sky 2011/07/21 20:08:11 This method feels like it should be two methods. O
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 That makes sense, though I'm not sure where to put
4403 bool* incognito_downloads_are_present) { 4471 int* profile_download_count) const {
4404 *normal_downloads_are_present = false; 4472 // Downloads on the current profile are easy.
4405 *incognito_downloads_are_present = false; 4473 if (profile()->HasCreatedDownloadManager()) {
4406 4474 *profile_download_count =
4407 // If there are no download in-progress, our job is done. 4475 profile()->GetDownloadManager()->in_progress_count();
4408 DownloadManager* download_manager = NULL; 4476 } else {
4409 // But first we need to check for the existence of the download manager, as 4477 *profile_download_count = 0;
4410 // GetDownloadManager() will unnecessarily try to create one if it does not
4411 // exist.
4412 if (profile()->HasCreatedDownloadManager())
4413 download_manager = profile()->GetDownloadManager();
4414 if (profile()->IsOffTheRecord()) {
4415 // Browser is incognito and so download_manager if present is for incognito
4416 // downloads.
4417 *incognito_downloads_are_present =
4418 (download_manager && download_manager->in_progress_count() != 0);
4419 // Check original profile.
4420 if (profile()->GetOriginalProfile()->HasCreatedDownloadManager())
4421 download_manager = profile()->GetOriginalProfile()->GetDownloadManager();
4422 } 4478 }
4423 4479
4424 *normal_downloads_are_present = 4480 // Total downloads are a bit harder.
4425 (download_manager && download_manager->in_progress_count() != 0); 4481 std::vector<Profile*> profiles(
4482 g_browser_process->profile_manager()->GetLoadedProfiles());
4483 int count = 0;
4484 std::vector<Profile*>::const_iterator profile_it =
sky 2011/07/21 20:08:11 nit: move this into the for loop
Randy Smith (Not in Mondays) 2011/07/21 21:36:31 The loop now matches similar loops in profile_mana
4485 profiles.begin();
4486 for (; profile_it != profiles.end(); ++profile_it) {
4487 Profile* p = *profile_it;
4488 if (p->HasCreatedDownloadManager()) {
4489 count += p->GetDownloadManager()->in_progress_count();
4490 }
4491 if (p->HasOffTheRecordProfile() &&
4492 p->GetOffTheRecordProfile()->HasCreatedDownloadManager()) {
4493 count += p->GetOffTheRecordProfile()
4494 ->GetDownloadManager()->in_progress_count();
4495 }
4496 }
4497 *total_download_count = count;
4426 } 4498 }
4427 4499
4428 bool Browser::CanCloseWithInProgressDownloads() { 4500 bool Browser::CanCloseWithInProgressDownloads() {
4429 if (cancel_download_confirmation_state_ != NOT_PROMPTED) { 4501 if (cancel_download_confirmation_state_ != NOT_PROMPTED) {
4430 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) { 4502 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) {
4431 // We need to hear from the user before we can close. 4503 // We need to hear from the user before we can close.
4432 return false; 4504 return false;
4433 } 4505 }
4434 // RESPONSE_RECEIVED case, the user decided to go along with the closing. 4506 // RESPONSE_RECEIVED case, the user decided to go along with the closing.
4435 return true; 4507 return true;
4436 } 4508 }
4437 // Indicated that normal (non-incognito) downloads are pending. 4509
4438 bool normal_downloads_are_present = false; 4510 DownloadClosePreventionType type;
4439 bool incognito_downloads_are_present = false; 4511 int num_downloads_blocking;
4440 CheckDownloadsInProgress(&normal_downloads_are_present, 4512 if (OkToCloseWithInProgressDownloads(&type, &num_downloads_blocking))
4441 &incognito_downloads_are_present);
4442 if (!normal_downloads_are_present && !incognito_downloads_are_present)
4443 return true; 4513 return true;
4444 4514
4445 if (is_attempting_to_close_browser_) 4515 // Closing this window will kill some downloads; prompt to make sure
4446 return true; 4516 // that's ok.
4447
4448 if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) ||
4449 (!incognito_downloads_are_present && profile()->IsOffTheRecord()))
4450 return true;
4451
4452 // Let's figure out if we are the last window for our profile.
4453 // Note that we cannot just use BrowserList::GetBrowserCount as browser
4454 // windows closing is delayed and the returned count might include windows
4455 // that are being closed.
4456 // The browser allowed to be closed only if:
4457 // 1. It is a regular browser and there are no regular downloads present or
4458 // this is not the last regular browser window.
4459 // 2. It is an incognito browser and there are no incognito downloads present
4460 // or this is not the last incognito browser window.
4461 int count = 0;
4462 for (BrowserList::const_iterator iter = BrowserList::begin();
4463 iter != BrowserList::end(); ++iter) {
4464 // Don't count this browser window or any other in the process of closing.
4465 // Only consider tabbed browser windows, not popups.
4466 Browser* const browser = *iter;
4467 if (browser == this
4468 || browser->is_attempting_to_close_browser_
4469 || !browser->is_type_tabbed())
4470 continue;
4471
4472 // Verify that this is not the last non-incognito or incognito browser,
4473 // depending on the pending downloads.
4474 if (normal_downloads_are_present && !profile()->IsOffTheRecord() &&
4475 browser->profile()->IsOffTheRecord())
4476 continue;
4477 if (incognito_downloads_are_present && profile()->IsOffTheRecord() &&
4478 !browser->profile()->IsOffTheRecord())
4479 continue;
4480
4481 // We test the original profile, because an incognito browser window keeps
4482 // the original profile alive (and its DownloadManager).
4483 // We also need to test explicitly the profile directly so that 2 incognito
4484 // profiles count as a match.
4485 if ((*iter)->profile() == profile() ||
4486 (*iter)->profile()->GetOriginalProfile() == profile())
4487 count++;
4488 }
4489 if (count > 0)
4490 return true;
4491
4492 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; 4517 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
4493 window_->ConfirmBrowserCloseWithPendingDownloads(); 4518 window_->ConfirmBrowserCloseWithPendingDownloads();
4494 4519
4495 // Return false so the browser does not close. We'll close if the user 4520 // Return false so the browser does not close. We'll close if the user
4496 // confirms in the dialog. 4521 // confirms in the dialog.
4497 return false; 4522 return false;
4498 } 4523 }
4499 4524
4500 /////////////////////////////////////////////////////////////////////////////// 4525 ///////////////////////////////////////////////////////////////////////////////
4501 // Browser, Assorted utility functions (private): 4526 // Browser, Assorted utility functions (private):
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
4783 window_->BookmarkBarStateChanged(animate_type); 4808 window_->BookmarkBarStateChanged(animate_type);
4784 } 4809 }
4785 4810
4786 void Browser::ShowSyncSetup() { 4811 void Browser::ShowSyncSetup() {
4787 ProfileSyncService* service = profile()->GetProfileSyncService(); 4812 ProfileSyncService* service = profile()->GetProfileSyncService();
4788 if (service->HasSyncSetupCompleted()) 4813 if (service->HasSyncSetupCompleted())
4789 ShowOptionsTab(chrome::kSyncSetupSubPage); 4814 ShowOptionsTab(chrome::kSyncSetupSubPage);
4790 else 4815 else
4791 profile()->GetProfileSyncService()->ShowLoginDialog(); 4816 profile()->GetProfileSyncService()->ShowLoginDialog();
4792 } 4817 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698