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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 #include "chrome/browser/notifications/notification_ui_manager.h" | 68 #include "chrome/browser/notifications/notification_ui_manager.h" |
69 #include "chrome/browser/platform_util.h" | 69 #include "chrome/browser/platform_util.h" |
70 #include "chrome/browser/prefs/incognito_mode_prefs.h" | 70 #include "chrome/browser/prefs/incognito_mode_prefs.h" |
71 #include "chrome/browser/prefs/pref_service.h" | 71 #include "chrome/browser/prefs/pref_service.h" |
72 #include "chrome/browser/prerender/prerender_tab_helper.h" | 72 #include "chrome/browser/prerender/prerender_tab_helper.h" |
73 #include "chrome/browser/printing/background_printing_manager.h" | 73 #include "chrome/browser/printing/background_printing_manager.h" |
74 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" | 74 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" |
75 #include "chrome/browser/printing/print_preview_tab_controller.h" | 75 #include "chrome/browser/printing/print_preview_tab_controller.h" |
76 #include "chrome/browser/printing/print_view_manager.h" | 76 #include "chrome/browser/printing/print_view_manager.h" |
77 #include "chrome/browser/profiles/profile.h" | 77 #include "chrome/browser/profiles/profile.h" |
| 78 #include "chrome/browser/profiles/profile_manager.h" |
78 #include "chrome/browser/sessions/restore_tab_helper.h" | 79 #include "chrome/browser/sessions/restore_tab_helper.h" |
79 #include "chrome/browser/sessions/session_service.h" | 80 #include "chrome/browser/sessions/session_service.h" |
80 #include "chrome/browser/sessions/session_service_factory.h" | 81 #include "chrome/browser/sessions/session_service_factory.h" |
81 #include "chrome/browser/sessions/session_types.h" | 82 #include "chrome/browser/sessions/session_types.h" |
82 #include "chrome/browser/sessions/tab_restore_service.h" | 83 #include "chrome/browser/sessions/tab_restore_service.h" |
83 #include "chrome/browser/sessions/tab_restore_service_factory.h" | 84 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
84 #include "chrome/browser/sync/profile_sync_service.h" | 85 #include "chrome/browser/sync/profile_sync_service.h" |
85 #include "chrome/browser/sync/sync_ui_util.h" | 86 #include "chrome/browser/sync/sync_ui_util.h" |
86 #include "chrome/browser/tab_closeable_state_watcher.h" | 87 #include "chrome/browser/tab_closeable_state_watcher.h" |
87 #include "chrome/browser/tab_contents/background_contents.h" | 88 #include "chrome/browser/tab_contents/background_contents.h" |
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 | 1047 |
1047 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to | 1048 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to |
1048 // close again we'll show the warning again. | 1049 // close again we'll show the warning again. |
1049 cancel_download_confirmation_state_ = NOT_PROMPTED; | 1050 cancel_download_confirmation_state_ = NOT_PROMPTED; |
1050 | 1051 |
1051 // Show the download page so the user can figure-out what downloads are still | 1052 // Show the download page so the user can figure-out what downloads are still |
1052 // in-progress. | 1053 // in-progress. |
1053 ShowDownloadsTab(); | 1054 ShowDownloadsTab(); |
1054 } | 1055 } |
1055 | 1056 |
| 1057 Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads( |
| 1058 int* num_downloads_blocking) const { |
| 1059 DCHECK(num_downloads_blocking); |
| 1060 *num_downloads_blocking = 0; |
| 1061 |
| 1062 if (is_attempting_to_close_browser_) |
| 1063 return DOWNLOAD_CLOSE_OK; |
| 1064 |
| 1065 // If we're not running a full browser process with a profile manager |
| 1066 // (testing), it's ok to close the browser. |
| 1067 if (!g_browser_process->profile_manager()) |
| 1068 return DOWNLOAD_CLOSE_OK; |
| 1069 |
| 1070 int total_download_count = DownloadService::DownloadCountAllProfiles(); |
| 1071 if (total_download_count == 0) |
| 1072 return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close. |
| 1073 |
| 1074 // Figure out how many windows are open total, and associated with this |
| 1075 // profile, that are relevant for the ok-to-close decision. |
| 1076 int profile_window_count = 0; |
| 1077 int total_window_count = 0; |
| 1078 for (BrowserList::const_iterator iter = BrowserList::begin(); |
| 1079 iter != BrowserList::end(); ++iter) { |
| 1080 // Don't count this browser window or any other in the process of closing. |
| 1081 Browser* const browser = *iter; |
| 1082 // Check is_attempting_to_close_browser_ as window closing may be |
| 1083 // delayed, and windows that are in the process of closing don't |
| 1084 // count against our totals. |
| 1085 if (browser == this || browser->is_attempting_to_close_browser_) |
| 1086 continue; |
| 1087 |
| 1088 if ((*iter)->profile() == profile()) |
| 1089 profile_window_count++; |
| 1090 total_window_count++; |
| 1091 } |
| 1092 |
| 1093 // If there aren't any other windows, we're at browser shutdown, |
| 1094 // which would cancel all current downloads. |
| 1095 if (total_window_count == 0) { |
| 1096 *num_downloads_blocking = total_download_count; |
| 1097 return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN; |
| 1098 } |
| 1099 |
| 1100 // If there aren't any other windows on our profile, and we're an incognito |
| 1101 // profile, and there are downloads associated with that profile, |
| 1102 // those downloads would be cancelled by our window (-> profile) close. |
| 1103 DownloadService* download_service = |
| 1104 DownloadServiceFactory::GetForProfile(profile()); |
| 1105 if (profile_window_count == 0 && download_service->DownloadCount() > 0 && |
| 1106 profile()->IsOffTheRecord()) { |
| 1107 *num_downloads_blocking = download_service->DownloadCount(); |
| 1108 return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE; |
| 1109 } |
| 1110 |
| 1111 // Those are the only conditions under which we will block shutdown. |
| 1112 return DOWNLOAD_CLOSE_OK; |
| 1113 } |
| 1114 |
1056 //////////////////////////////////////////////////////////////////////////////// | 1115 //////////////////////////////////////////////////////////////////////////////// |
1057 // Browser, TabStripModel pass-thrus: | 1116 // Browser, TabStripModel pass-thrus: |
1058 | 1117 |
1059 int Browser::tab_count() const { | 1118 int Browser::tab_count() const { |
1060 return tab_handler_->GetTabStripModel()->count(); | 1119 return tab_handler_->GetTabStripModel()->count(); |
1061 } | 1120 } |
1062 | 1121 |
1063 int Browser::active_index() const { | 1122 int Browser::active_index() const { |
1064 return tab_handler_->GetTabStripModel()->active_index(); | 1123 return tab_handler_->GetTabStripModel()->active_index(); |
1065 } | 1124 } |
(...skipping 3958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5024 MessageLoop::current()->PostTask( | 5083 MessageLoop::current()->PostTask( |
5025 FROM_HERE, | 5084 FROM_HERE, |
5026 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); | 5085 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); |
5027 } | 5086 } |
5028 } | 5087 } |
5029 } | 5088 } |
5030 | 5089 |
5031 /////////////////////////////////////////////////////////////////////////////// | 5090 /////////////////////////////////////////////////////////////////////////////// |
5032 // Browser, In-progress download termination handling (private): | 5091 // Browser, In-progress download termination handling (private): |
5033 | 5092 |
5034 void Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present, | 5093 bool Browser::CanCloseWithInProgressDownloads() { |
5035 bool* incognito_downloads_are_present) { | 5094 // If we've prompted, we need to hear from the user before we |
5036 *normal_downloads_are_present = false; | 5095 // can close. |
5037 *incognito_downloads_are_present = false; | 5096 if (cancel_download_confirmation_state_ != NOT_PROMPTED) |
| 5097 return cancel_download_confirmation_state_ != WAITING_FOR_RESPONSE; |
5038 | 5098 |
5039 // If there are no download in-progress, our job is done. | 5099 int num_downloads_blocking; |
5040 DownloadManager* download_manager = NULL; | 5100 if (DOWNLOAD_CLOSE_OK == |
5041 DownloadService* download_service = | 5101 OkToCloseWithInProgressDownloads(&num_downloads_blocking)) |
5042 DownloadServiceFactory::GetForProfile(profile()); | |
5043 // But first we need to check for the existence of the download manager, as | |
5044 // GetDownloadManager() will unnecessarily try to create one if it does not | |
5045 // exist. | |
5046 if (download_service->HasCreatedDownloadManager()) | |
5047 download_manager = download_service->GetDownloadManager(); | |
5048 if (profile()->IsOffTheRecord()) { | |
5049 // Browser is incognito and so download_manager if present is for incognito | |
5050 // downloads. | |
5051 *incognito_downloads_are_present = | |
5052 (download_manager && download_manager->in_progress_count() != 0); | |
5053 // Check original profile. | |
5054 DownloadService* download_service = DownloadServiceFactory::GetForProfile( | |
5055 profile()->GetOriginalProfile()); | |
5056 if (download_service->HasCreatedDownloadManager()) | |
5057 download_manager = download_service->GetDownloadManager(); | |
5058 } | |
5059 | |
5060 *normal_downloads_are_present = | |
5061 (download_manager && download_manager->in_progress_count() != 0); | |
5062 } | |
5063 | |
5064 bool Browser::CanCloseWithInProgressDownloads() { | |
5065 if (cancel_download_confirmation_state_ != NOT_PROMPTED) { | |
5066 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) { | |
5067 // We need to hear from the user before we can close. | |
5068 return false; | |
5069 } | |
5070 // RESPONSE_RECEIVED case, the user decided to go along with the closing. | |
5071 return true; | |
5072 } | |
5073 // Indicated that normal (non-incognito) downloads are pending. | |
5074 bool normal_downloads_are_present = false; | |
5075 bool incognito_downloads_are_present = false; | |
5076 CheckDownloadsInProgress(&normal_downloads_are_present, | |
5077 &incognito_downloads_are_present); | |
5078 if (!normal_downloads_are_present && !incognito_downloads_are_present) | |
5079 return true; | 5102 return true; |
5080 | 5103 |
5081 if (is_attempting_to_close_browser_) | 5104 // Closing this window will kill some downloads; prompt to make sure |
5082 return true; | 5105 // that's ok. |
5083 | |
5084 if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) || | |
5085 (!incognito_downloads_are_present && profile()->IsOffTheRecord())) | |
5086 return true; | |
5087 | |
5088 // Let's figure out if we are the last window for our profile. | |
5089 // Note that we cannot just use BrowserList::GetBrowserCount as browser | |
5090 // windows closing is delayed and the returned count might include windows | |
5091 // that are being closed. | |
5092 // The browser allowed to be closed only if: | |
5093 // 1. It is a regular browser and there are no regular downloads present or | |
5094 // this is not the last regular browser window. | |
5095 // 2. It is an incognito browser and there are no incognito downloads present | |
5096 // or this is not the last incognito browser window. | |
5097 int count = 0; | |
5098 for (BrowserList::const_iterator iter = BrowserList::begin(); | |
5099 iter != BrowserList::end(); ++iter) { | |
5100 // Don't count this browser window or any other in the process of closing. | |
5101 // Only consider tabbed browser windows, not popups. | |
5102 Browser* const browser = *iter; | |
5103 if (browser == this | |
5104 || browser->is_attempting_to_close_browser_ | |
5105 || !browser->is_type_tabbed()) | |
5106 continue; | |
5107 | |
5108 // Verify that this is not the last non-incognito or incognito browser, | |
5109 // depending on the pending downloads. | |
5110 if (normal_downloads_are_present && !profile()->IsOffTheRecord() && | |
5111 browser->profile()->IsOffTheRecord()) | |
5112 continue; | |
5113 if (incognito_downloads_are_present && profile()->IsOffTheRecord() && | |
5114 !browser->profile()->IsOffTheRecord()) | |
5115 continue; | |
5116 | |
5117 // We test the original profile, because an incognito browser window keeps | |
5118 // the original profile alive (and its DownloadManager). | |
5119 // We also need to test explicitly the profile directly so that 2 incognito | |
5120 // profiles count as a match. | |
5121 if ((*iter)->profile() == profile() || | |
5122 (*iter)->profile()->GetOriginalProfile() == profile()) | |
5123 count++; | |
5124 } | |
5125 if (count > 0) | |
5126 return true; | |
5127 | |
5128 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; | 5106 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; |
5129 window_->ConfirmBrowserCloseWithPendingDownloads(); | 5107 window_->ConfirmBrowserCloseWithPendingDownloads(); |
5130 | 5108 |
5131 // Return false so the browser does not close. We'll close if the user | 5109 // Return false so the browser does not close. We'll close if the user |
5132 // confirms in the dialog. | 5110 // confirms in the dialog. |
5133 return false; | 5111 return false; |
5134 } | 5112 } |
5135 | 5113 |
5136 /////////////////////////////////////////////////////////////////////////////// | 5114 /////////////////////////////////////////////////////////////////////////////// |
5137 // Browser, Assorted utility functions (private): | 5115 // Browser, Assorted utility functions (private): |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5499 } | 5477 } |
5500 | 5478 |
5501 void Browser::UpdateFullscreenExitBubbleContent() { | 5479 void Browser::UpdateFullscreenExitBubbleContent() { |
5502 GURL url; | 5480 GURL url; |
5503 if (fullscreened_tab_) | 5481 if (fullscreened_tab_) |
5504 url = fullscreened_tab_->tab_contents()->GetURL(); | 5482 url = fullscreened_tab_->tab_contents()->GetURL(); |
5505 | 5483 |
5506 window_->UpdateFullscreenExitBubbleContent( | 5484 window_->UpdateFullscreenExitBubbleContent( |
5507 url, GetFullscreenExitBubbleType()); | 5485 url, GetFullscreenExitBubbleType()); |
5508 } | 5486 } |
OLD | NEW |