OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |