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" |
34 #include "chrome/browser/browser_process.h" | 34 #include "chrome/browser/browser_process.h" |
35 #include "chrome/browser/browser_shutdown.h" | 35 #include "chrome/browser/browser_shutdown.h" |
36 #include "chrome/browser/character_encoding.h" | 36 #include "chrome/browser/character_encoding.h" |
37 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" | 37 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" |
38 #include "chrome/browser/custom_handlers/register_protocol_handler_infobar_deleg ate.h" | 38 #include "chrome/browser/custom_handlers/register_protocol_handler_infobar_deleg ate.h" |
39 #include "chrome/browser/debugger/devtools_toggle_action.h" | 39 #include "chrome/browser/debugger/devtools_toggle_action.h" |
40 #include "chrome/browser/debugger/devtools_window.h" | 40 #include "chrome/browser/debugger/devtools_window.h" |
41 #include "chrome/browser/download/chrome_download_manager_delegate.h" | 41 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
42 #include "chrome/browser/download/download_item_model.h" | 42 #include "chrome/browser/download/download_item_model.h" |
43 #include "chrome/browser/download/download_service.h" | 43 #include "chrome/browser/download/download_service.h" |
44 #include "chrome/browser/download/download_service.h" | |
44 #include "chrome/browser/download/download_service_factory.h" | 45 #include "chrome/browser/download/download_service_factory.h" |
45 #include "chrome/browser/download/download_started_animation.h" | 46 #include "chrome/browser/download/download_started_animation.h" |
46 #include "chrome/browser/extensions/crx_installer.h" | 47 #include "chrome/browser/extensions/crx_installer.h" |
47 #include "chrome/browser/extensions/default_apps_trial.h" | 48 #include "chrome/browser/extensions/default_apps_trial.h" |
48 #include "chrome/browser/extensions/extension_browser_event_router.h" | 49 #include "chrome/browser/extensions/extension_browser_event_router.h" |
49 #include "chrome/browser/extensions/extension_disabled_infobar_delegate.h" | 50 #include "chrome/browser/extensions/extension_disabled_infobar_delegate.h" |
50 #include "chrome/browser/extensions/extension_host.h" | 51 #include "chrome/browser/extensions/extension_host.h" |
51 #include "chrome/browser/extensions/extension_prefs.h" | 52 #include "chrome/browser/extensions/extension_prefs.h" |
52 #include "chrome/browser/extensions/extension_service.h" | 53 #include "chrome/browser/extensions/extension_service.h" |
53 #include "chrome/browser/extensions/extension_tab_helper.h" | 54 #include "chrome/browser/extensions/extension_tab_helper.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
67 #include "chrome/browser/notifications/notification_ui_manager.h" | 68 #include "chrome/browser/notifications/notification_ui_manager.h" |
68 #include "chrome/browser/platform_util.h" | 69 #include "chrome/browser/platform_util.h" |
69 #include "chrome/browser/prefs/incognito_mode_prefs.h" | 70 #include "chrome/browser/prefs/incognito_mode_prefs.h" |
70 #include "chrome/browser/prefs/pref_service.h" | 71 #include "chrome/browser/prefs/pref_service.h" |
71 #include "chrome/browser/prerender/prerender_tab_helper.h" | 72 #include "chrome/browser/prerender/prerender_tab_helper.h" |
72 #include "chrome/browser/printing/background_printing_manager.h" | 73 #include "chrome/browser/printing/background_printing_manager.h" |
73 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" | 74 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" |
74 #include "chrome/browser/printing/print_preview_tab_controller.h" | 75 #include "chrome/browser/printing/print_preview_tab_controller.h" |
75 #include "chrome/browser/printing/print_view_manager.h" | 76 #include "chrome/browser/printing/print_view_manager.h" |
76 #include "chrome/browser/profiles/profile.h" | 77 #include "chrome/browser/profiles/profile.h" |
78 #include "chrome/browser/profiles/profile_manager.h" | |
77 #include "chrome/browser/sessions/restore_tab_helper.h" | 79 #include "chrome/browser/sessions/restore_tab_helper.h" |
78 #include "chrome/browser/sessions/session_service.h" | 80 #include "chrome/browser/sessions/session_service.h" |
79 #include "chrome/browser/sessions/session_service_factory.h" | 81 #include "chrome/browser/sessions/session_service_factory.h" |
80 #include "chrome/browser/sessions/session_types.h" | 82 #include "chrome/browser/sessions/session_types.h" |
81 #include "chrome/browser/sessions/tab_restore_service.h" | 83 #include "chrome/browser/sessions/tab_restore_service.h" |
82 #include "chrome/browser/sessions/tab_restore_service_factory.h" | 84 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
83 #include "chrome/browser/sync/profile_sync_service.h" | 85 #include "chrome/browser/sync/profile_sync_service.h" |
84 #include "chrome/browser/sync/sync_ui_util.h" | 86 #include "chrome/browser/sync/sync_ui_util.h" |
85 #include "chrome/browser/tab_closeable_state_watcher.h" | 87 #include "chrome/browser/tab_closeable_state_watcher.h" |
86 #include "chrome/browser/tab_contents/background_contents.h" | 88 #include "chrome/browser/tab_contents/background_contents.h" |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1030 | 1032 |
1031 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to | 1033 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to |
1032 // close again we'll show the warning again. | 1034 // close again we'll show the warning again. |
1033 cancel_download_confirmation_state_ = NOT_PROMPTED; | 1035 cancel_download_confirmation_state_ = NOT_PROMPTED; |
1034 | 1036 |
1035 // Show the download page so the user can figure-out what downloads are still | 1037 // Show the download page so the user can figure-out what downloads are still |
1036 // in-progress. | 1038 // in-progress. |
1037 ShowDownloadsTab(); | 1039 ShowDownloadsTab(); |
1038 } | 1040 } |
1039 | 1041 |
1042 Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads( | |
1043 int* num_downloads_blocking) const { | |
1044 DCHECK(num_downloads_blocking); | |
1045 | |
achuithb
2011/10/13 23:05:08
I'd set *num_downloads_blocking to 0 here since an
Randy Smith (Not in Mondays)
2011/10/14 00:37:41
Done.
| |
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 | |
achuithb
2011/10/13 23:05:08
Have you considered combining the above 3 conditio
Randy Smith (Not in Mondays)
2011/10/14 00:37:41
My preference is for it being the way it is now; I
achuithb
2011/10/14 19:22:10
That's fine.
| |
1058 // Let's figure out if we are the last window for our profile, and | |
1059 // the last window period. | |
1060 // Note that we cannot just use BrowserList::GetBrowserCount as browser | |
1061 // windows closing is delayed and the returned count might include windows | |
1062 // that are being closed. | |
1063 // The browser allowed to be closed only if both of the following are true: | |
1064 // 1. There are no downloads present for any profile or it is not the | |
1065 // last Browser. | |
1066 // 2. (Incognito Browser) There are no incognito downloads associated with | |
1067 // the Browser's profile or it is not the last Browser associated with | |
1068 // that profile. | |
1069 // Note the lack of parallelism: regular profiles are kept around until | |
1070 // browser close, whereas incognito profiles are destroyed on last | |
1071 // associated window close. | |
1072 int profile_window_count = 0; | |
achuithb
2011/10/13 23:05:08
Does it make sense to move lines 1072-1085 into a
Randy Smith (Not in Mondays)
2011/10/14 00:37:41
Huh. I don't have that feeling about it. The *lo
achuithb
2011/10/14 19:22:10
Yup, definitely better since it fits on my 15" scr
| |
1073 int total_window_count = 0; | |
1074 for (BrowserList::const_iterator iter = BrowserList::begin(); | |
1075 iter != BrowserList::end(); ++iter) { | |
1076 // Don't count this browser window or any other in the process of closing. | |
1077 Browser* const browser = *iter; | |
1078 if (browser == this || | |
1079 browser->is_attempting_to_close_browser_) | |
sky
2011/10/13 20:23:43
nit: move this up to the previous line.
achuithb
2011/10/13 23:05:08
You lost the condition to guard against counting p
Randy Smith (Not in Mondays)
2011/10/14 00:37:41
Done.
Randy Smith (Not in Mondays)
2011/10/14 00:37:41
Yes. See earlier comment on this CL @
http://cod
| |
1080 continue; | |
1081 | |
1082 if ((*iter)->profile() == profile()) | |
1083 profile_window_count++; | |
1084 total_window_count++; | |
1085 } | |
1086 | |
1087 // If there aren't any other windows, we're at browser shutdown. | |
1088 if (total_window_count == 0) { | |
1089 *num_downloads_blocking = total_download_count; | |
1090 return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN; | |
1091 } | |
1092 | |
1093 // If there aren't any other windows on our profile, we're an incognito | |
1094 // profile, and there are downloads associated with that profile, | |
1095 // indicate that. | |
1096 DownloadService* download_service = | |
1097 DownloadServiceFactory::GetForProfile(profile()); | |
1098 if (profile_window_count == 0 && download_service->DownloadCount() > 0 && | |
1099 profile()->IsOffTheRecord()) { | |
1100 *num_downloads_blocking = download_service->DownloadCount(); | |
1101 return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE; | |
1102 } | |
1103 | |
1104 // Those are the only conditions under which we will block shutdown. | |
1105 return DOWNLOAD_CLOSE_OK; | |
1106 } | |
1107 | |
1040 //////////////////////////////////////////////////////////////////////////////// | 1108 //////////////////////////////////////////////////////////////////////////////// |
1041 // Browser, TabStripModel pass-thrus: | 1109 // Browser, TabStripModel pass-thrus: |
1042 | 1110 |
1043 int Browser::tab_count() const { | 1111 int Browser::tab_count() const { |
1044 return tab_handler_->GetTabStripModel()->count(); | 1112 return tab_handler_->GetTabStripModel()->count(); |
1045 } | 1113 } |
1046 | 1114 |
1047 int Browser::active_index() const { | 1115 int Browser::active_index() const { |
1048 return tab_handler_->GetTabStripModel()->active_index(); | 1116 return tab_handler_->GetTabStripModel()->active_index(); |
1049 } | 1117 } |
(...skipping 3795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4845 MessageLoop::current()->PostTask( | 4913 MessageLoop::current()->PostTask( |
4846 FROM_HERE, | 4914 FROM_HERE, |
4847 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); | 4915 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); |
4848 } | 4916 } |
4849 } | 4917 } |
4850 } | 4918 } |
4851 | 4919 |
4852 /////////////////////////////////////////////////////////////////////////////// | 4920 /////////////////////////////////////////////////////////////////////////////// |
4853 // Browser, In-progress download termination handling (private): | 4921 // Browser, In-progress download termination handling (private): |
4854 | 4922 |
4855 void Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present, | |
4856 bool* incognito_downloads_are_present) { | |
4857 *normal_downloads_are_present = false; | |
4858 *incognito_downloads_are_present = false; | |
4859 | |
4860 // If there are no download in-progress, our job is done. | |
4861 DownloadManager* download_manager = NULL; | |
4862 DownloadService* download_service = | |
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() { | 4923 bool Browser::CanCloseWithInProgressDownloads() { |
4886 if (cancel_download_confirmation_state_ != NOT_PROMPTED) { | 4924 if (cancel_download_confirmation_state_ != NOT_PROMPTED) { |
achuithb
2011/10/13 23:05:08
I know this is not your code, but do you think you
Randy Smith (Not in Mondays)
2011/10/14 00:37:41
I agree with you, but I'm reluctant to make a chan
Randy Smith (Not in Mondays)
2011/10/14 16:13:03
Done.
| |
4887 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) { | 4925 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) { |
4888 // We need to hear from the user before we can close. | 4926 // We need to hear from the user before we can close. |
4889 return false; | 4927 return false; |
4890 } | 4928 } |
4891 // RESPONSE_RECEIVED case, the user decided to go along with the closing. | 4929 // RESPONSE_RECEIVED case, the user decided to go along with the closing. |
4892 return true; | 4930 return true; |
4893 } | 4931 } |
4894 // Indicated that normal (non-incognito) downloads are pending. | 4932 |
4895 bool normal_downloads_are_present = false; | 4933 int num_downloads_blocking; |
4896 bool incognito_downloads_are_present = false; | 4934 if (DOWNLOAD_CLOSE_OK == |
4897 CheckDownloadsInProgress(&normal_downloads_are_present, | 4935 OkToCloseWithInProgressDownloads(&num_downloads_blocking)) |
4898 &incognito_downloads_are_present); | |
4899 if (!normal_downloads_are_present && !incognito_downloads_are_present) | |
4900 return true; | 4936 return true; |
4901 | 4937 |
4902 if (is_attempting_to_close_browser_) | 4938 // Closing this window will kill some downloads; prompt to make sure |
4903 return true; | 4939 // 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; | 4940 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; |
4950 window_->ConfirmBrowserCloseWithPendingDownloads(); | 4941 window_->ConfirmBrowserCloseWithPendingDownloads(); |
4951 | 4942 |
4952 // Return false so the browser does not close. We'll close if the user | 4943 // Return false so the browser does not close. We'll close if the user |
4953 // confirms in the dialog. | 4944 // confirms in the dialog. |
4954 return false; | 4945 return false; |
4955 } | 4946 } |
4956 | 4947 |
4957 /////////////////////////////////////////////////////////////////////////////// | 4948 /////////////////////////////////////////////////////////////////////////////// |
4958 // Browser, Assorted utility functions (private): | 4949 // Browser, Assorted utility functions (private): |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5287 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type); | 5278 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type); |
5288 } else if (is_type_tabbed()) { | 5279 } else if (is_type_tabbed()) { |
5289 GlobalErrorService* service = | 5280 GlobalErrorService* service = |
5290 GlobalErrorServiceFactory::GetForProfile(profile()); | 5281 GlobalErrorServiceFactory::GetForProfile(profile()); |
5291 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView(); | 5282 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView(); |
5292 if (error) { | 5283 if (error) { |
5293 error->ShowBubbleView(this); | 5284 error->ShowBubbleView(this); |
5294 } | 5285 } |
5295 } | 5286 } |
5296 } | 5287 } |
OLD | NEW |