| 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/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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 #include "chrome/browser/notifications/notification_ui_manager.h" | 67 #include "chrome/browser/notifications/notification_ui_manager.h" |
| 68 #include "chrome/browser/platform_util.h" | 68 #include "chrome/browser/platform_util.h" |
| 69 #include "chrome/browser/prefs/incognito_mode_prefs.h" | 69 #include "chrome/browser/prefs/incognito_mode_prefs.h" |
| 70 #include "chrome/browser/prefs/pref_service.h" | 70 #include "chrome/browser/prefs/pref_service.h" |
| 71 #include "chrome/browser/prerender/prerender_tab_helper.h" | 71 #include "chrome/browser/prerender/prerender_tab_helper.h" |
| 72 #include "chrome/browser/printing/background_printing_manager.h" | 72 #include "chrome/browser/printing/background_printing_manager.h" |
| 73 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" | 73 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" |
| 74 #include "chrome/browser/printing/print_preview_tab_controller.h" | 74 #include "chrome/browser/printing/print_preview_tab_controller.h" |
| 75 #include "chrome/browser/printing/print_view_manager.h" | 75 #include "chrome/browser/printing/print_view_manager.h" |
| 76 #include "chrome/browser/profiles/profile.h" | 76 #include "chrome/browser/profiles/profile.h" |
| 77 #include "chrome/browser/profiles/profile_manager.h" |
| 77 #include "chrome/browser/sessions/restore_tab_helper.h" | 78 #include "chrome/browser/sessions/restore_tab_helper.h" |
| 78 #include "chrome/browser/sessions/session_service.h" | 79 #include "chrome/browser/sessions/session_service.h" |
| 79 #include "chrome/browser/sessions/session_service_factory.h" | 80 #include "chrome/browser/sessions/session_service_factory.h" |
| 80 #include "chrome/browser/sessions/session_types.h" | 81 #include "chrome/browser/sessions/session_types.h" |
| 81 #include "chrome/browser/sessions/tab_restore_service.h" | 82 #include "chrome/browser/sessions/tab_restore_service.h" |
| 82 #include "chrome/browser/sessions/tab_restore_service_factory.h" | 83 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
| 83 #include "chrome/browser/sync/profile_sync_service.h" | 84 #include "chrome/browser/sync/profile_sync_service.h" |
| 84 #include "chrome/browser/sync/sync_ui_util.h" | 85 #include "chrome/browser/sync/sync_ui_util.h" |
| 85 #include "chrome/browser/tab_closeable_state_watcher.h" | 86 #include "chrome/browser/tab_closeable_state_watcher.h" |
| 86 #include "chrome/browser/tab_contents/background_contents.h" | 87 #include "chrome/browser/tab_contents/background_contents.h" |
| (...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1030 | 1031 |
| 1031 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to | 1032 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to |
| 1032 // close again we'll show the warning again. | 1033 // close again we'll show the warning again. |
| 1033 cancel_download_confirmation_state_ = NOT_PROMPTED; | 1034 cancel_download_confirmation_state_ = NOT_PROMPTED; |
| 1034 | 1035 |
| 1035 // Show the download page so the user can figure-out what downloads are still | 1036 // Show the download page so the user can figure-out what downloads are still |
| 1036 // in-progress. | 1037 // in-progress. |
| 1037 ShowDownloadsTab(); | 1038 ShowDownloadsTab(); |
| 1038 } | 1039 } |
| 1039 | 1040 |
| 1041 Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads( |
| 1042 int* num_downloads_blocking) const { |
| 1043 DCHECK(num_downloads_blocking); |
| 1044 *num_downloads_blocking = 0; |
| 1045 |
| 1046 if (is_attempting_to_close_browser_) |
| 1047 return DOWNLOAD_CLOSE_OK; |
| 1048 |
| 1049 // If we're not running a full browser process with a profile manager |
| 1050 // (testing), it's ok to close the browser. |
| 1051 if (!g_browser_process->profile_manager()) |
| 1052 return DOWNLOAD_CLOSE_OK; |
| 1053 |
| 1054 int total_download_count = DownloadService::TotalDownloadCount(); |
| 1055 if (total_download_count == 0) |
| 1056 return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close. |
| 1057 |
| 1058 // Figure out how many windows are open total, and associated with this |
| 1059 // profile, that are relevant for the ok-to-close decision. |
| 1060 int profile_window_count = 0; |
| 1061 int total_window_count = 0; |
| 1062 for (BrowserList::const_iterator iter = BrowserList::begin(); |
| 1063 iter != BrowserList::end(); ++iter) { |
| 1064 // Don't count this browser window or any other in the process of closing. |
| 1065 Browser* const browser = *iter; |
| 1066 // Check is_attempting_to_close_browser_ as window closing may be |
| 1067 // delayed, and windows that are in the process of closing don't |
| 1068 // count against our totals. |
| 1069 if (browser == this || browser->is_attempting_to_close_browser_) |
| 1070 continue; |
| 1071 |
| 1072 if ((*iter)->profile() == profile()) |
| 1073 profile_window_count++; |
| 1074 total_window_count++; |
| 1075 } |
| 1076 |
| 1077 // If there aren't any other windows, we're at browser shutdown, |
| 1078 // which would cancel all current downloads. |
| 1079 if (total_window_count == 0) { |
| 1080 *num_downloads_blocking = total_download_count; |
| 1081 return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN; |
| 1082 } |
| 1083 |
| 1084 // If there aren't any other windows on our profile, and we're an incognito |
| 1085 // profile, and there are downloads associated with that profile, |
| 1086 // those downloads would be cancelled by our window (-> profile) close. |
| 1087 DownloadService* download_service = |
| 1088 DownloadServiceFactory::GetForProfile(profile()); |
| 1089 if (profile_window_count == 0 && download_service->DownloadCount() > 0 && |
| 1090 profile()->IsOffTheRecord()) { |
| 1091 *num_downloads_blocking = download_service->DownloadCount(); |
| 1092 return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE; |
| 1093 } |
| 1094 |
| 1095 // Those are the only conditions under which we will block shutdown. |
| 1096 return DOWNLOAD_CLOSE_OK; |
| 1097 } |
| 1098 |
| 1040 //////////////////////////////////////////////////////////////////////////////// | 1099 //////////////////////////////////////////////////////////////////////////////// |
| 1041 // Browser, TabStripModel pass-thrus: | 1100 // Browser, TabStripModel pass-thrus: |
| 1042 | 1101 |
| 1043 int Browser::tab_count() const { | 1102 int Browser::tab_count() const { |
| 1044 return tab_handler_->GetTabStripModel()->count(); | 1103 return tab_handler_->GetTabStripModel()->count(); |
| 1045 } | 1104 } |
| 1046 | 1105 |
| 1047 int Browser::active_index() const { | 1106 int Browser::active_index() const { |
| 1048 return tab_handler_->GetTabStripModel()->active_index(); | 1107 return tab_handler_->GetTabStripModel()->active_index(); |
| 1049 } | 1108 } |
| (...skipping 3795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4845 MessageLoop::current()->PostTask( | 4904 MessageLoop::current()->PostTask( |
| 4846 FROM_HERE, | 4905 FROM_HERE, |
| 4847 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); | 4906 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); |
| 4848 } | 4907 } |
| 4849 } | 4908 } |
| 4850 } | 4909 } |
| 4851 | 4910 |
| 4852 /////////////////////////////////////////////////////////////////////////////// | 4911 /////////////////////////////////////////////////////////////////////////////// |
| 4853 // Browser, In-progress download termination handling (private): | 4912 // Browser, In-progress download termination handling (private): |
| 4854 | 4913 |
| 4855 void Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present, | 4914 bool Browser::CanCloseWithInProgressDownloads() { |
| 4856 bool* incognito_downloads_are_present) { | 4915 // If we've prompted, we need to hear from the user before we |
| 4857 *normal_downloads_are_present = false; | 4916 // can close. |
| 4858 *incognito_downloads_are_present = false; | 4917 if (cancel_download_confirmation_state_ != NOT_PROMPTED) |
| 4918 return cancel_download_confirmation_state_ != WAITING_FOR_RESPONSE; |
| 4859 | 4919 |
| 4860 // If there are no download in-progress, our job is done. | 4920 int num_downloads_blocking; |
| 4861 DownloadManager* download_manager = NULL; | 4921 if (DOWNLOAD_CLOSE_OK == |
| 4862 DownloadService* download_service = | 4922 OkToCloseWithInProgressDownloads(&num_downloads_blocking)) |
| 4863 DownloadServiceFactory::GetForProfile(profile()); | |
| 4864 // But first we need to check for the existence of the download manager, as | |
| 4865 // GetDownloadManager() will unnecessarily try to create one if it does not | |
| 4866 // exist. | |
| 4867 if (download_service->HasCreatedDownloadManager()) | |
| 4868 download_manager = download_service->GetDownloadManager(); | |
| 4869 if (profile()->IsOffTheRecord()) { | |
| 4870 // Browser is incognito and so download_manager if present is for incognito | |
| 4871 // downloads. | |
| 4872 *incognito_downloads_are_present = | |
| 4873 (download_manager && download_manager->in_progress_count() != 0); | |
| 4874 // Check original profile. | |
| 4875 DownloadService* download_service = DownloadServiceFactory::GetForProfile( | |
| 4876 profile()->GetOriginalProfile()); | |
| 4877 if (download_service->HasCreatedDownloadManager()) | |
| 4878 download_manager = download_service->GetDownloadManager(); | |
| 4879 } | |
| 4880 | |
| 4881 *normal_downloads_are_present = | |
| 4882 (download_manager && download_manager->in_progress_count() != 0); | |
| 4883 } | |
| 4884 | |
| 4885 bool Browser::CanCloseWithInProgressDownloads() { | |
| 4886 if (cancel_download_confirmation_state_ != NOT_PROMPTED) { | |
| 4887 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) { | |
| 4888 // We need to hear from the user before we can close. | |
| 4889 return false; | |
| 4890 } | |
| 4891 // RESPONSE_RECEIVED case, the user decided to go along with the closing. | |
| 4892 return true; | |
| 4893 } | |
| 4894 // Indicated that normal (non-incognito) downloads are pending. | |
| 4895 bool normal_downloads_are_present = false; | |
| 4896 bool incognito_downloads_are_present = false; | |
| 4897 CheckDownloadsInProgress(&normal_downloads_are_present, | |
| 4898 &incognito_downloads_are_present); | |
| 4899 if (!normal_downloads_are_present && !incognito_downloads_are_present) | |
| 4900 return true; | 4923 return true; |
| 4901 | 4924 |
| 4902 if (is_attempting_to_close_browser_) | 4925 // Closing this window will kill some downloads; prompt to make sure |
| 4903 return true; | 4926 // that's ok. |
| 4904 | |
| 4905 if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) || | |
| 4906 (!incognito_downloads_are_present && profile()->IsOffTheRecord())) | |
| 4907 return true; | |
| 4908 | |
| 4909 // Let's figure out if we are the last window for our profile. | |
| 4910 // Note that we cannot just use BrowserList::GetBrowserCount as browser | |
| 4911 // windows closing is delayed and the returned count might include windows | |
| 4912 // that are being closed. | |
| 4913 // The browser allowed to be closed only if: | |
| 4914 // 1. It is a regular browser and there are no regular downloads present or | |
| 4915 // this is not the last regular browser window. | |
| 4916 // 2. It is an incognito browser and there are no incognito downloads present | |
| 4917 // or this is not the last incognito browser window. | |
| 4918 int count = 0; | |
| 4919 for (BrowserList::const_iterator iter = BrowserList::begin(); | |
| 4920 iter != BrowserList::end(); ++iter) { | |
| 4921 // Don't count this browser window or any other in the process of closing. | |
| 4922 // Only consider tabbed browser windows, not popups. | |
| 4923 Browser* const browser = *iter; | |
| 4924 if (browser == this | |
| 4925 || browser->is_attempting_to_close_browser_ | |
| 4926 || !browser->is_type_tabbed()) | |
| 4927 continue; | |
| 4928 | |
| 4929 // Verify that this is not the last non-incognito or incognito browser, | |
| 4930 // depending on the pending downloads. | |
| 4931 if (normal_downloads_are_present && !profile()->IsOffTheRecord() && | |
| 4932 browser->profile()->IsOffTheRecord()) | |
| 4933 continue; | |
| 4934 if (incognito_downloads_are_present && profile()->IsOffTheRecord() && | |
| 4935 !browser->profile()->IsOffTheRecord()) | |
| 4936 continue; | |
| 4937 | |
| 4938 // We test the original profile, because an incognito browser window keeps | |
| 4939 // the original profile alive (and its DownloadManager). | |
| 4940 // We also need to test explicitly the profile directly so that 2 incognito | |
| 4941 // profiles count as a match. | |
| 4942 if ((*iter)->profile() == profile() || | |
| 4943 (*iter)->profile()->GetOriginalProfile() == profile()) | |
| 4944 count++; | |
| 4945 } | |
| 4946 if (count > 0) | |
| 4947 return true; | |
| 4948 | |
| 4949 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; | 4927 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; |
| 4950 window_->ConfirmBrowserCloseWithPendingDownloads(); | 4928 window_->ConfirmBrowserCloseWithPendingDownloads(); |
| 4951 | 4929 |
| 4952 // Return false so the browser does not close. We'll close if the user | 4930 // Return false so the browser does not close. We'll close if the user |
| 4953 // confirms in the dialog. | 4931 // confirms in the dialog. |
| 4954 return false; | 4932 return false; |
| 4955 } | 4933 } |
| 4956 | 4934 |
| 4957 /////////////////////////////////////////////////////////////////////////////// | 4935 /////////////////////////////////////////////////////////////////////////////// |
| 4958 // Browser, Assorted utility functions (private): | 4936 // Browser, Assorted utility functions (private): |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5287 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type); | 5265 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type); |
| 5288 } else if (is_type_tabbed()) { | 5266 } else if (is_type_tabbed()) { |
| 5289 GlobalErrorService* service = | 5267 GlobalErrorService* service = |
| 5290 GlobalErrorServiceFactory::GetForProfile(profile()); | 5268 GlobalErrorServiceFactory::GetForProfile(profile()); |
| 5291 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView(); | 5269 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView(); |
| 5292 if (error) { | 5270 if (error) { |
| 5293 error->ShowBubbleView(this); | 5271 error->ShowBubbleView(this); |
| 5294 } | 5272 } |
| 5295 } | 5273 } |
| 5296 } | 5274 } |
| OLD | NEW |