Chromium Code Reviews| 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 969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1040 | 1041 |
| 1041 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to | 1042 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to |
| 1042 // close again we'll show the warning again. | 1043 // close again we'll show the warning again. |
| 1043 cancel_download_confirmation_state_ = NOT_PROMPTED; | 1044 cancel_download_confirmation_state_ = NOT_PROMPTED; |
| 1044 | 1045 |
| 1045 // Show the download page so the user can figure-out what downloads are still | 1046 // Show the download page so the user can figure-out what downloads are still |
| 1046 // in-progress. | 1047 // in-progress. |
| 1047 ShowDownloadsTab(); | 1048 ShowDownloadsTab(); |
| 1048 } | 1049 } |
| 1049 | 1050 |
| 1051 Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads( | |
| 1052 int* num_downloads_blocking) const { | |
| 1053 DCHECK(num_downloads_blocking); | |
| 1054 | |
| 1055 if (is_attempting_to_close_browser_) | |
| 1056 return DOWNLOAD_CLOSE_OK; | |
| 1057 | |
| 1058 // If we're not running a full browser process with a profile manager | |
| 1059 // (testing), it's ok to close the browser. | |
| 1060 if (!g_browser_process->profile_manager()) | |
| 1061 return DOWNLOAD_CLOSE_OK; | |
| 1062 | |
| 1063 int total_download_count = | |
| 1064 g_browser_process->profile_manager()->TotalDownloadCount(); | |
| 1065 if (total_download_count == 0) | |
| 1066 return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close. | |
| 1067 | |
| 1068 // Let's figure out if we are the last window for our profile, and | |
| 1069 // the last window period. | |
| 1070 // Note that we cannot just use BrowserList::GetBrowserCount as browser | |
| 1071 // windows closing is delayed and the returned count might include windows | |
| 1072 // that are being closed. | |
| 1073 // The browser allowed to be closed only if: | |
| 1074 // 1. It is a regular browser and there are no regular downloads present or | |
| 1075 // this is not the last regular browser window. | |
|
asanka
2011/08/04 19:07:10
As mentioned offline, a browser with regular downl
| |
| 1076 // 2. It is an incognito browser and there are no incognito downloads present | |
| 1077 // for this incognito profile or this is not the last incognito | |
| 1078 // browser window. | |
| 1079 // Note the lack of parallelism: regular profiles are kept around until | |
| 1080 // browser close, whereas incognito profiles are destroyed on last | |
| 1081 // associated window close. | |
| 1082 int profile_window_count = 0; | |
| 1083 int total_window_count = 0; | |
| 1084 for (BrowserList::const_iterator iter = BrowserList::begin(); | |
| 1085 iter != BrowserList::end(); ++iter) { | |
| 1086 // Don't count this browser window or any other in the process of closing. | |
| 1087 Browser* const browser = *iter; | |
| 1088 if (browser == this || | |
| 1089 browser->is_attempting_to_close_browser_) | |
| 1090 continue; | |
| 1091 | |
| 1092 if ((*iter)->profile() == profile()) | |
| 1093 profile_window_count++; | |
| 1094 total_window_count++; | |
| 1095 } | |
| 1096 | |
| 1097 // If there aren't any other windows, we're at browser shutdown. | |
| 1098 if (total_window_count == 0) { | |
| 1099 *num_downloads_blocking = total_download_count; | |
| 1100 return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN; | |
| 1101 } | |
| 1102 | |
| 1103 // If there aren't any other windows on our profile, we're an incognito | |
| 1104 // profile, and there are downloads associated with that profile, | |
| 1105 // indicate that. | |
| 1106 if (profile_window_count == 0 && profile()->DownloadCount() > 0 && | |
| 1107 profile()->IsOffTheRecord()) { | |
| 1108 *num_downloads_blocking = profile()->DownloadCount(); | |
| 1109 return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE; | |
| 1110 } | |
| 1111 | |
| 1112 // Those are the only conditions under which we will block shutdown. | |
| 1113 return DOWNLOAD_CLOSE_OK; | |
| 1114 } | |
| 1115 | |
| 1050 //////////////////////////////////////////////////////////////////////////////// | 1116 //////////////////////////////////////////////////////////////////////////////// |
| 1051 // Browser, TabStripModel pass-thrus: | 1117 // Browser, TabStripModel pass-thrus: |
| 1052 | 1118 |
| 1053 int Browser::tab_count() const { | 1119 int Browser::tab_count() const { |
| 1054 return tab_handler_->GetTabStripModel()->count(); | 1120 return tab_handler_->GetTabStripModel()->count(); |
| 1055 } | 1121 } |
| 1056 | 1122 |
| 1057 int Browser::active_index() const { | 1123 int Browser::active_index() const { |
| 1058 return tab_handler_->GetTabStripModel()->active_index(); | 1124 return tab_handler_->GetTabStripModel()->active_index(); |
| 1059 } | 1125 } |
| (...skipping 3362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4422 MessageLoop::current()->PostTask( | 4488 MessageLoop::current()->PostTask( |
| 4423 FROM_HERE, | 4489 FROM_HERE, |
| 4424 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); | 4490 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); |
| 4425 } | 4491 } |
| 4426 } | 4492 } |
| 4427 } | 4493 } |
| 4428 | 4494 |
| 4429 /////////////////////////////////////////////////////////////////////////////// | 4495 /////////////////////////////////////////////////////////////////////////////// |
| 4430 // Browser, In-progress download termination handling (private): | 4496 // Browser, In-progress download termination handling (private): |
| 4431 | 4497 |
| 4432 void Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present, | |
| 4433 bool* incognito_downloads_are_present) { | |
| 4434 *normal_downloads_are_present = false; | |
| 4435 *incognito_downloads_are_present = false; | |
| 4436 | |
| 4437 // If there are no download in-progress, our job is done. | |
| 4438 DownloadManager* download_manager = NULL; | |
| 4439 // But first we need to check for the existence of the download manager, as | |
| 4440 // GetDownloadManager() will unnecessarily try to create one if it does not | |
| 4441 // exist. | |
| 4442 if (profile()->HasCreatedDownloadManager()) | |
| 4443 download_manager = profile()->GetDownloadManager(); | |
| 4444 if (profile()->IsOffTheRecord()) { | |
| 4445 // Browser is incognito and so download_manager if present is for incognito | |
| 4446 // downloads. | |
| 4447 *incognito_downloads_are_present = | |
| 4448 (download_manager && download_manager->in_progress_count() != 0); | |
| 4449 // Check original profile. | |
| 4450 if (profile()->GetOriginalProfile()->HasCreatedDownloadManager()) | |
| 4451 download_manager = profile()->GetOriginalProfile()->GetDownloadManager(); | |
| 4452 } | |
| 4453 | |
| 4454 *normal_downloads_are_present = | |
| 4455 (download_manager && download_manager->in_progress_count() != 0); | |
| 4456 } | |
| 4457 | |
| 4458 bool Browser::CanCloseWithInProgressDownloads() { | 4498 bool Browser::CanCloseWithInProgressDownloads() { |
| 4459 if (cancel_download_confirmation_state_ != NOT_PROMPTED) { | 4499 if (cancel_download_confirmation_state_ != NOT_PROMPTED) { |
| 4460 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) { | 4500 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) { |
| 4461 // We need to hear from the user before we can close. | 4501 // We need to hear from the user before we can close. |
| 4462 return false; | 4502 return false; |
| 4463 } | 4503 } |
| 4464 // RESPONSE_RECEIVED case, the user decided to go along with the closing. | 4504 // RESPONSE_RECEIVED case, the user decided to go along with the closing. |
| 4465 return true; | 4505 return true; |
| 4466 } | 4506 } |
| 4467 // Indicated that normal (non-incognito) downloads are pending. | 4507 |
| 4468 bool normal_downloads_are_present = false; | 4508 int num_downloads_blocking; |
| 4469 bool incognito_downloads_are_present = false; | 4509 if (DOWNLOAD_CLOSE_OK == |
| 4470 CheckDownloadsInProgress(&normal_downloads_are_present, | 4510 OkToCloseWithInProgressDownloads(&num_downloads_blocking)) |
| 4471 &incognito_downloads_are_present); | |
| 4472 if (!normal_downloads_are_present && !incognito_downloads_are_present) | |
| 4473 return true; | 4511 return true; |
| 4474 | 4512 |
| 4475 if (is_attempting_to_close_browser_) | 4513 // Closing this window will kill some downloads; prompt to make sure |
| 4476 return true; | 4514 // that's ok. |
| 4477 | |
| 4478 if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) || | |
| 4479 (!incognito_downloads_are_present && profile()->IsOffTheRecord())) | |
| 4480 return true; | |
| 4481 | |
| 4482 // Let's figure out if we are the last window for our profile. | |
| 4483 // Note that we cannot just use BrowserList::GetBrowserCount as browser | |
| 4484 // windows closing is delayed and the returned count might include windows | |
| 4485 // that are being closed. | |
| 4486 // The browser allowed to be closed only if: | |
| 4487 // 1. It is a regular browser and there are no regular downloads present or | |
| 4488 // this is not the last regular browser window. | |
| 4489 // 2. It is an incognito browser and there are no incognito downloads present | |
| 4490 // or this is not the last incognito browser window. | |
| 4491 int count = 0; | |
| 4492 for (BrowserList::const_iterator iter = BrowserList::begin(); | |
| 4493 iter != BrowserList::end(); ++iter) { | |
| 4494 // Don't count this browser window or any other in the process of closing. | |
| 4495 // Only consider tabbed browser windows, not popups. | |
| 4496 Browser* const browser = *iter; | |
| 4497 if (browser == this | |
| 4498 || browser->is_attempting_to_close_browser_ | |
| 4499 || !browser->is_type_tabbed()) | |
| 4500 continue; | |
| 4501 | |
| 4502 // Verify that this is not the last non-incognito or incognito browser, | |
| 4503 // depending on the pending downloads. | |
| 4504 if (normal_downloads_are_present && !profile()->IsOffTheRecord() && | |
| 4505 browser->profile()->IsOffTheRecord()) | |
| 4506 continue; | |
| 4507 if (incognito_downloads_are_present && profile()->IsOffTheRecord() && | |
| 4508 !browser->profile()->IsOffTheRecord()) | |
| 4509 continue; | |
| 4510 | |
| 4511 // We test the original profile, because an incognito browser window keeps | |
| 4512 // the original profile alive (and its DownloadManager). | |
| 4513 // We also need to test explicitly the profile directly so that 2 incognito | |
| 4514 // profiles count as a match. | |
| 4515 if ((*iter)->profile() == profile() || | |
| 4516 (*iter)->profile()->GetOriginalProfile() == profile()) | |
| 4517 count++; | |
| 4518 } | |
| 4519 if (count > 0) | |
| 4520 return true; | |
| 4521 | |
| 4522 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; | 4515 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; |
| 4523 window_->ConfirmBrowserCloseWithPendingDownloads(); | 4516 window_->ConfirmBrowserCloseWithPendingDownloads(); |
| 4524 | 4517 |
| 4525 // Return false so the browser does not close. We'll close if the user | 4518 // Return false so the browser does not close. We'll close if the user |
| 4526 // confirms in the dialog. | 4519 // confirms in the dialog. |
| 4527 return false; | 4520 return false; |
| 4528 } | 4521 } |
| 4529 | 4522 |
| 4530 /////////////////////////////////////////////////////////////////////////////// | 4523 /////////////////////////////////////////////////////////////////////////////// |
| 4531 // Browser, Assorted utility functions (private): | 4524 // Browser, Assorted utility functions (private): |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4813 window_->BookmarkBarStateChanged(animate_type); | 4806 window_->BookmarkBarStateChanged(animate_type); |
| 4814 } | 4807 } |
| 4815 | 4808 |
| 4816 void Browser::ShowSyncSetup() { | 4809 void Browser::ShowSyncSetup() { |
| 4817 ProfileSyncService* service = profile()->GetProfileSyncService(); | 4810 ProfileSyncService* service = profile()->GetProfileSyncService(); |
| 4818 if (service->HasSyncSetupCompleted()) | 4811 if (service->HasSyncSetupCompleted()) |
| 4819 ShowOptionsTab(chrome::kSyncSetupSubPage); | 4812 ShowOptionsTab(chrome::kSyncSetupSubPage); |
| 4820 else | 4813 else |
| 4821 profile()->GetProfileSyncService()->ShowLoginDialog(); | 4814 profile()->GetProfileSyncService()->ShowLoginDialog(); |
| 4822 } | 4815 } |
| OLD | NEW |