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/bind.h" | |
| 16 #include "base/command_line.h" | 17 #include "base/command_line.h" |
| 17 #include "base/logging.h" | 18 #include "base/logging.h" |
| 18 #include "base/metrics/field_trial.h" | 19 #include "base/metrics/field_trial.h" |
| 19 #include "base/metrics/histogram.h" | 20 #include "base/metrics/histogram.h" |
| 20 #include "base/path_service.h" | 21 #include "base/path_service.h" |
| 21 #include "base/string_number_conversions.h" | 22 #include "base/string_number_conversions.h" |
| 22 #include "base/string_util.h" | 23 #include "base/string_util.h" |
| 23 #include "base/stringprintf.h" | 24 #include "base/stringprintf.h" |
| 24 #include "base/threading/thread.h" | 25 #include "base/threading/thread.h" |
| 25 #include "base/threading/thread_restrictions.h" | 26 #include "base/threading/thread_restrictions.h" |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 299 window_(NULL), | 300 window_(NULL), |
| 300 ALLOW_THIS_IN_INITIALIZER_LIST( | 301 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 301 tab_handler_(TabHandler::CreateTabHandler(this))), | 302 tab_handler_(TabHandler::CreateTabHandler(this))), |
| 302 command_updater_(this), | 303 command_updater_(this), |
| 303 toolbar_model_(this), | 304 toolbar_model_(this), |
| 304 chrome_updater_factory_(this), | 305 chrome_updater_factory_(this), |
| 305 is_attempting_to_close_browser_(false), | 306 is_attempting_to_close_browser_(false), |
| 306 cancel_download_confirmation_state_(NOT_PROMPTED), | 307 cancel_download_confirmation_state_(NOT_PROMPTED), |
| 307 show_state_(ui::SHOW_STATE_DEFAULT), | 308 show_state_(ui::SHOW_STATE_DEFAULT), |
| 308 is_session_restore_(false), | 309 is_session_restore_(false), |
| 309 method_factory_(this), | 310 weak_factory_(this), |
| 310 block_command_execution_(false), | 311 block_command_execution_(false), |
| 311 last_blocked_command_id_(-1), | 312 last_blocked_command_id_(-1), |
| 312 last_blocked_command_disposition_(CURRENT_TAB), | 313 last_blocked_command_disposition_(CURRENT_TAB), |
| 313 pending_web_app_action_(NONE), | 314 pending_web_app_action_(NONE), |
| 314 ALLOW_THIS_IN_INITIALIZER_LIST( | 315 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 315 tab_restore_service_delegate_( | 316 tab_restore_service_delegate_( |
| 316 new BrowserTabRestoreServiceDelegate(this))), | 317 new BrowserTabRestoreServiceDelegate(this))), |
| 317 ALLOW_THIS_IN_INITIALIZER_LIST( | 318 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 318 synced_window_delegate_( | 319 synced_window_delegate_( |
| 319 new BrowserSyncedWindowDelegate(this))), | 320 new BrowserSyncedWindowDelegate(this))), |
| (...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1729 | 1730 |
| 1730 #if defined(OS_CHROMEOS) | 1731 #if defined(OS_CHROMEOS) |
| 1731 void Browser::Search() { | 1732 void Browser::Search() { |
| 1732 // Exit fullscreen to show omnibox. | 1733 // Exit fullscreen to show omnibox. |
| 1733 if (window_->IsFullscreen()) { | 1734 if (window_->IsFullscreen()) { |
| 1734 ToggleFullscreenMode(false); | 1735 ToggleFullscreenMode(false); |
| 1735 // ToggleFullscreenMode is asynchronous, so we don't have omnibox | 1736 // ToggleFullscreenMode is asynchronous, so we don't have omnibox |
| 1736 // visible at this point. Wait for next event cycle which toggles | 1737 // visible at this point. Wait for next event cycle which toggles |
| 1737 // the visibility of omnibox before creating new tab. | 1738 // the visibility of omnibox before creating new tab. |
| 1738 MessageLoop::current()->PostTask( | 1739 MessageLoop::current()->PostTask( |
| 1739 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::Search)); | 1740 FROM_HERE, base::Bind(&Browser::Search, weak_factory_.GetWeakPtr())); |
|
James Hawkins
2011/11/22 21:26:30
This extra space makes the indentation 5 spaces (I
csilv
2011/11/22 21:31:52
Done.
| |
| 1740 return; | 1741 return; |
| 1741 } | 1742 } |
| 1742 | 1743 |
| 1743 const GURL& url = GetSelectedTabContents()->GetURL(); | 1744 const GURL& url = GetSelectedTabContents()->GetURL(); |
| 1744 if (url.SchemeIs(chrome::kChromeUIScheme) && | 1745 if (url.SchemeIs(chrome::kChromeUIScheme) && |
| 1745 url.host() == chrome::kChromeUINewTabHost) { | 1746 url.host() == chrome::kChromeUINewTabHost) { |
| 1746 // If the NTP is showing, focus the omnibox. | 1747 // If the NTP is showing, focus the omnibox. |
| 1747 window_->SetFocusToLocationBar(true); | 1748 window_->SetFocusToLocationBar(true); |
| 1748 } else { | 1749 } else { |
| 1749 // Otherwise, open the NTP. | 1750 // Otherwise, open the NTP. |
| (...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3096 session_service->TabRestored(contents_dupe, pinned); | 3097 session_service->TabRestored(contents_dupe, pinned); |
| 3097 } | 3098 } |
| 3098 | 3099 |
| 3099 void Browser::CloseFrameAfterDragSession() { | 3100 void Browser::CloseFrameAfterDragSession() { |
| 3100 #if !defined(OS_MACOSX) | 3101 #if !defined(OS_MACOSX) |
| 3101 // This is scheduled to run after we return to the message loop because | 3102 // This is scheduled to run after we return to the message loop because |
| 3102 // otherwise the frame will think the drag session is still active and ignore | 3103 // otherwise the frame will think the drag session is still active and ignore |
| 3103 // the request. | 3104 // the request. |
| 3104 // TODO(port): figure out what is required here in a cross-platform world | 3105 // TODO(port): figure out what is required here in a cross-platform world |
| 3105 MessageLoop::current()->PostTask( | 3106 MessageLoop::current()->PostTask( |
| 3106 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame)); | 3107 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr())); |
| 3107 #endif | 3108 #endif |
| 3108 } | 3109 } |
| 3109 | 3110 |
| 3110 void Browser::CreateHistoricalTab(TabContentsWrapper* contents) { | 3111 void Browser::CreateHistoricalTab(TabContentsWrapper* contents) { |
| 3111 // We don't create historical tabs for incognito windows or windows without | 3112 // We don't create historical tabs for incognito windows or windows without |
| 3112 // profiles. | 3113 // profiles. |
| 3113 if (!profile() || profile()->IsOffTheRecord()) | 3114 if (!profile() || profile()->IsOffTheRecord()) |
| 3114 return; | 3115 return; |
| 3115 | 3116 |
| 3116 // We don't create historical tabs for print preview tabs. | 3117 // We don't create historical tabs for print preview tabs. |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3246 } | 3247 } |
| 3247 } | 3248 } |
| 3248 | 3249 |
| 3249 // Discarded tabs always get reloaded. | 3250 // Discarded tabs always get reloaded. |
| 3250 if (IsTabDiscarded(index)) { | 3251 if (IsTabDiscarded(index)) { |
| 3251 Reload(CURRENT_TAB); | 3252 Reload(CURRENT_TAB); |
| 3252 return; | 3253 return; |
| 3253 } | 3254 } |
| 3254 | 3255 |
| 3255 // If we have any update pending, do it now. | 3256 // If we have any update pending, do it now. |
| 3256 if (!chrome_updater_factory_.empty() && old_contents) | 3257 if (chrome_updater_factory_.HasWeakPtrs() && old_contents) |
| 3257 ProcessPendingUIUpdates(); | 3258 ProcessPendingUIUpdates(); |
| 3258 | 3259 |
| 3259 // Propagate the profile to the location bar. | 3260 // Propagate the profile to the location bar. |
| 3260 UpdateToolbar(true); | 3261 UpdateToolbar(true); |
| 3261 | 3262 |
| 3262 // Update reload/stop state. | 3263 // Update reload/stop state. |
| 3263 UpdateReloadStopState(new_contents->tab_contents()->IsLoading(), true); | 3264 UpdateReloadStopState(new_contents->tab_contents()->IsLoading(), true); |
| 3264 | 3265 |
| 3265 // Update commands to reflect current state. | 3266 // Update commands to reflect current state. |
| 3266 UpdateCommandsForTabState(); | 3267 UpdateCommandsForTabState(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3344 void Browser::TabStripEmpty() { | 3345 void Browser::TabStripEmpty() { |
| 3345 // Close the frame after we return to the message loop (not immediately, | 3346 // Close the frame after we return to the message loop (not immediately, |
| 3346 // otherwise it will destroy this object before the stack has a chance to | 3347 // otherwise it will destroy this object before the stack has a chance to |
| 3347 // cleanly unwind.) | 3348 // cleanly unwind.) |
| 3348 // Note: This will be called several times if TabStripEmpty is called several | 3349 // Note: This will be called several times if TabStripEmpty is called several |
| 3349 // times. This is because it does not close the window if tabs are | 3350 // times. This is because it does not close the window if tabs are |
| 3350 // still present. | 3351 // still present. |
| 3351 // NOTE: If you change to be immediate (no invokeLater) then you'll need to | 3352 // NOTE: If you change to be immediate (no invokeLater) then you'll need to |
| 3352 // update BrowserList::CloseAllBrowsers. | 3353 // update BrowserList::CloseAllBrowsers. |
| 3353 MessageLoop::current()->PostTask( | 3354 MessageLoop::current()->PostTask( |
| 3354 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame)); | 3355 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr())); |
| 3355 } | 3356 } |
| 3356 | 3357 |
| 3357 /////////////////////////////////////////////////////////////////////////////// | 3358 /////////////////////////////////////////////////////////////////////////////// |
| 3358 // Browser, TabContentsDelegate implementation: | 3359 // Browser, TabContentsDelegate implementation: |
| 3359 | 3360 |
| 3360 // TODO(adriansc): Remove this method once refactoring changed all call sites. | 3361 // TODO(adriansc): Remove this method once refactoring changed all call sites. |
| 3361 TabContents* Browser::OpenURLFromTab(TabContents* source, | 3362 TabContents* Browser::OpenURLFromTab(TabContents* source, |
| 3362 const GURL& url, | 3363 const GURL& url, |
| 3363 const GURL& referrer, | 3364 const GURL& referrer, |
| 3364 WindowOpenDisposition disposition, | 3365 WindowOpenDisposition disposition, |
| (...skipping 1357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4722 TabStripModelObserver::TITLE_NOT_LOADING); | 4723 TabStripModelObserver::TITLE_NOT_LOADING); |
| 4723 } | 4724 } |
| 4724 | 4725 |
| 4725 // If the only updates were synchronously handled above, we're done. | 4726 // If the only updates were synchronously handled above, we're done. |
| 4726 if (changed_flags == 0) | 4727 if (changed_flags == 0) |
| 4727 return; | 4728 return; |
| 4728 | 4729 |
| 4729 // Save the dirty bits. | 4730 // Save the dirty bits. |
| 4730 scheduled_updates_[source] |= changed_flags; | 4731 scheduled_updates_[source] |= changed_flags; |
| 4731 | 4732 |
| 4732 if (chrome_updater_factory_.empty()) { | 4733 if (!chrome_updater_factory_.HasWeakPtrs()) { |
| 4733 // No task currently scheduled, start another. | 4734 // No task currently scheduled, start another. |
| 4734 MessageLoop::current()->PostDelayedTask( | 4735 MessageLoop::current()->PostDelayedTask( |
| 4735 FROM_HERE, | 4736 FROM_HERE, |
| 4736 chrome_updater_factory_.NewRunnableMethod( | 4737 base::Bind(&Browser::ProcessPendingUIUpdates, |
| 4737 &Browser::ProcessPendingUIUpdates), | 4738 chrome_updater_factory_.GetWeakPtr()), |
| 4738 kUIUpdateCoalescingTimeMS); | 4739 kUIUpdateCoalescingTimeMS); |
| 4739 } | 4740 } |
| 4740 } | 4741 } |
| 4741 | 4742 |
| 4742 void Browser::ProcessPendingUIUpdates() { | 4743 void Browser::ProcessPendingUIUpdates() { |
| 4743 #ifndef NDEBUG | 4744 #ifndef NDEBUG |
| 4744 // Validate that all tabs we have pending updates for exist. This is scary | 4745 // Validate that all tabs we have pending updates for exist. This is scary |
| 4745 // because the pending list must be kept in sync with any detached or | 4746 // because the pending list must be kept in sync with any detached or |
| 4746 // deleted tabs. | 4747 // deleted tabs. |
| 4747 for (UpdateMap::const_iterator i = scheduled_updates_.begin(); | 4748 for (UpdateMap::const_iterator i = scheduled_updates_.begin(); |
| 4748 i != scheduled_updates_.end(); ++i) { | 4749 i != scheduled_updates_.end(); ++i) { |
| 4749 bool found = false; | 4750 bool found = false; |
| 4750 for (int tab = 0; tab < tab_count(); tab++) { | 4751 for (int tab = 0; tab < tab_count(); tab++) { |
| 4751 if (GetTabContentsAt(tab) == i->first) { | 4752 if (GetTabContentsAt(tab) == i->first) { |
| 4752 found = true; | 4753 found = true; |
| 4753 break; | 4754 break; |
| 4754 } | 4755 } |
| 4755 } | 4756 } |
| 4756 DCHECK(found); | 4757 DCHECK(found); |
| 4757 } | 4758 } |
| 4758 #endif | 4759 #endif |
| 4759 | 4760 |
| 4760 chrome_updater_factory_.RevokeAll(); | 4761 chrome_updater_factory_.InvalidateWeakPtrs(); |
| 4761 | 4762 |
| 4762 for (UpdateMap::const_iterator i = scheduled_updates_.begin(); | 4763 for (UpdateMap::const_iterator i = scheduled_updates_.begin(); |
| 4763 i != scheduled_updates_.end(); ++i) { | 4764 i != scheduled_updates_.end(); ++i) { |
| 4764 // Do not dereference |contents|, it may be out-of-date! | 4765 // Do not dereference |contents|, it may be out-of-date! |
| 4765 const TabContents* contents = i->first; | 4766 const TabContents* contents = i->first; |
| 4766 unsigned flags = i->second; | 4767 unsigned flags = i->second; |
| 4767 | 4768 |
| 4768 if (contents == GetSelectedTabContents()) { | 4769 if (contents == GetSelectedTabContents()) { |
| 4769 // Updates that only matter when the tab is selected go here. | 4770 // Updates that only matter when the tab is selected go here. |
| 4770 | 4771 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4936 // time when request was initiated and when this method is called, so check | 4937 // time when request was initiated and when this method is called, so check |
| 4937 // for is_attempting_to_close_browser_ flag before proceeding. | 4938 // for is_attempting_to_close_browser_ flag before proceeding. |
| 4938 if (is_attempting_to_close_browser_) { | 4939 if (is_attempting_to_close_browser_) { |
| 4939 RemoveFromSet(&tabs_needing_before_unload_fired_, tab); | 4940 RemoveFromSet(&tabs_needing_before_unload_fired_, tab); |
| 4940 RemoveFromSet(&tabs_needing_unload_fired_, tab); | 4941 RemoveFromSet(&tabs_needing_unload_fired_, tab); |
| 4941 if (process_now) { | 4942 if (process_now) { |
| 4942 ProcessPendingTabs(); | 4943 ProcessPendingTabs(); |
| 4943 } else { | 4944 } else { |
| 4944 MessageLoop::current()->PostTask( | 4945 MessageLoop::current()->PostTask( |
| 4945 FROM_HERE, | 4946 FROM_HERE, |
| 4946 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs)); | 4947 base::Bind(&Browser::ProcessPendingTabs, weak_factory_.GetWeakPtr())); |
| 4947 } | 4948 } |
| 4948 } | 4949 } |
| 4949 } | 4950 } |
| 4950 | 4951 |
| 4951 /////////////////////////////////////////////////////////////////////////////// | 4952 /////////////////////////////////////////////////////////////////////////////// |
| 4952 // Browser, In-progress download termination handling (private): | 4953 // Browser, In-progress download termination handling (private): |
| 4953 | 4954 |
| 4954 bool Browser::CanCloseWithInProgressDownloads() { | 4955 bool Browser::CanCloseWithInProgressDownloads() { |
| 4955 // If we've prompted, we need to hear from the user before we | 4956 // If we've prompted, we need to hear from the user before we |
| 4956 // can close. | 4957 // can close. |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5315 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type); | 5316 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type); |
| 5316 } else { | 5317 } else { |
| 5317 GlobalErrorService* service = | 5318 GlobalErrorService* service = |
| 5318 GlobalErrorServiceFactory::GetForProfile(profile()); | 5319 GlobalErrorServiceFactory::GetForProfile(profile()); |
| 5319 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView(); | 5320 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView(); |
| 5320 if (error) { | 5321 if (error) { |
| 5321 error->ShowBubbleView(this); | 5322 error->ShowBubbleView(this); |
| 5322 } | 5323 } |
| 5323 } | 5324 } |
| 5324 } | 5325 } |
| OLD | NEW |