Chromium Code Reviews| Index: chrome/browser/ui/unload_controller.cc |
| diff --git a/chrome/browser/ui/unload_controller.cc b/chrome/browser/ui/unload_controller.cc |
| index 8da59883131c958fbd7a16fe9daa400225b43eb7..c5d4f011b1575693496d07907d6fadab77eb88ce 100644 |
| --- a/chrome/browser/ui/unload_controller.cc |
| +++ b/chrome/browser/ui/unload_controller.cc |
| @@ -12,6 +12,7 @@ |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_tabstrip.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| +#include "chrome/browser/ui/unload_controller_web_contents_delegate.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_source.h" |
| #include "content/public/browser/notification_types.h" |
| @@ -120,7 +121,7 @@ bool UnloadController::BeforeUnloadFired(content::WebContents* contents, |
| // Now that beforeunload has fired, put the tab on the queue to fire |
| // unload. |
| tabs_needing_unload_fired_.insert(contents); |
| - ProcessPendingTabs(); |
| + ProcessPendingTabs(false); |
| // We want to handle firing the unload event ourselves since we want to |
| // fire all the beforeunload events before attempting to fire the unload |
| // events should the user cancel closing the browser. |
| @@ -163,11 +164,12 @@ bool UnloadController::ShouldCloseWindow() { |
| // Cases 2 and 3. |
| on_close_confirmed_.Reset(); |
| - ProcessPendingTabs(); |
| + ProcessPendingTabs(false); |
| return false; |
| } |
| -bool UnloadController::CallBeforeUnloadHandlers( |
| +bool UnloadController::TryToCloseWindow( |
| + bool skip_before_unload_event, |
| const base::Callback<void(bool)>& on_close_confirmed) { |
| // The devtools browser gets its beforeunload events as the results of |
| // intercepting events from the inspected tab, so don't send them here as |
| @@ -179,11 +181,11 @@ bool UnloadController::CallBeforeUnloadHandlers( |
| is_attempting_to_close_browser_ = true; |
| on_close_confirmed_ = on_close_confirmed; |
| - ProcessPendingTabs(); |
| - return true; |
| + ProcessPendingTabs(skip_before_unload_event); |
| + return true && !skip_before_unload_event; |
| } |
| -void UnloadController::ResetBeforeUnloadHandlers() { |
| +void UnloadController::ResetTryToCloseWindow() { |
| if (!is_calling_before_unload_handlers()) |
| return; |
| CancelWindowClose(); |
| @@ -290,7 +292,7 @@ void UnloadController::TabDetachedImpl(content::WebContents* contents) { |
| content::Source<content::WebContents>(contents)); |
| } |
| -void UnloadController::ProcessPendingTabs() { |
| +void UnloadController::ProcessPendingTabs(bool skip_before_unload_event) { |
| if (!is_attempting_to_close_browser_) { |
| // Because we might invoke this after a delay it's possible for the value of |
| // is_attempting_to_close_browser_ to have changed since we scheduled the |
| @@ -305,6 +307,20 @@ void UnloadController::ProcessPendingTabs() { |
| return; |
| } |
| + if (skip_before_unload_event) { |
| + tabs_needing_unload_fired_.insert(tabs_needing_before_unload_fired_.begin(), |
| + tabs_needing_before_unload_fired_.end()); |
| + if (!web_contents_delegate_) |
| + web_contents_delegate_.reset(new UnloadControllerWebContentsDelegate()); |
| + for (UnloadListenerSet::iterator it = tabs_needing_unload_fired_.begin(); |
| + it != tabs_needing_unload_fired_.end(); ++it) { |
| + content::WebContents* contents = *it; |
| + if (contents->GetRenderViewHost()) |
|
Charlie Reis
2017/02/27 21:47:51
What's the purpose of this GetRenderViewHost() che
zmin
2017/03/06 23:58:08
I add the check here because FastUnloadController
|
| + contents->SetDelegate(web_contents_delegate_.get()); |
| + } |
| + tabs_needing_before_unload_fired_.clear(); |
| + } |
| + |
| // Process beforeunload tabs first. When that queue is empty, process |
| // unload tabs. |
| if (!tabs_needing_before_unload_fired_.empty()) { |
| @@ -329,7 +345,8 @@ void UnloadController::ProcessPendingTabs() { |
| // is complete. |
| if (tabs_needing_unload_fired_.empty()) |
| on_close_confirmed_.Reset(); |
| - on_close_confirmed.Run(true); |
| + if (!skip_before_unload_event) |
| + on_close_confirmed.Run(true); |
| } else if (!tabs_needing_unload_fired_.empty()) { |
| // We've finished firing all beforeunload events and can proceed with unload |
| // events. |
| @@ -377,11 +394,11 @@ void UnloadController::ClearUnloadState(content::WebContents* web_contents, |
| RemoveFromSet(&tabs_needing_before_unload_fired_, web_contents); |
| RemoveFromSet(&tabs_needing_unload_fired_, web_contents); |
| if (process_now) { |
| - ProcessPendingTabs(); |
| + ProcessPendingTabs(false); |
| } else { |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, base::Bind(&UnloadController::ProcessPendingTabs, |
| - weak_factory_.GetWeakPtr())); |
| + weak_factory_.GetWeakPtr(), false)); |
| } |
| } |
| } |