Commit 920d4f37 authored by Evan Stade's avatar Evan Stade Committed by Chromium LUCI CQ

Make UnloadController::on_close_confirmed_ explicitly RepeatingCallback

Unintuitively, it seems this can be called more than once if a close is
confirmed by the user but later aborted.

Bug: 1152284
Change-Id: I89d45ae0eadf3248fccd983406fe0dc5d050afd0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2570332Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Evan Stade <estade@chromium.org>
Cr-Commit-Position: refs/heads/master@{#833425}
parent ab6a4c33
...@@ -74,8 +74,8 @@ void BrowserCloseManager::TryToCloseBrowsers() { ...@@ -74,8 +74,8 @@ void BrowserCloseManager::TryToCloseBrowsers() {
// this will trigger TryToCloseBrowsers to try again. // this will trigger TryToCloseBrowsers to try again.
for (auto* browser : *BrowserList::GetInstance()) { for (auto* browser : *BrowserList::GetInstance()) {
if (browser->TryToCloseWindow( if (browser->TryToCloseWindow(
false, false, base::BindRepeating(
base::Bind(&BrowserCloseManager::OnBrowserReportCloseable, this))) { &BrowserCloseManager::OnBrowserReportCloseable, this))) {
current_browser_ = browser; current_browser_ = browser;
return; return;
} }
......
...@@ -861,7 +861,7 @@ bool Browser::ShouldCloseWindow() { ...@@ -861,7 +861,7 @@ bool Browser::ShouldCloseWindow() {
bool Browser::TryToCloseWindow( bool Browser::TryToCloseWindow(
bool skip_beforeunload, bool skip_beforeunload,
const base::Callback<void(bool)>& on_close_confirmed) { const base::RepeatingCallback<void(bool)>& on_close_confirmed) {
cancel_download_confirmation_state_ = RESPONSE_RECEIVED; cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
return unload_controller_.TryToCloseWindow(skip_beforeunload, return unload_controller_.TryToCloseWindow(skip_beforeunload,
on_close_confirmed); on_close_confirmed);
......
...@@ -460,8 +460,9 @@ class Browser : public TabStripModelObserver, ...@@ -460,8 +460,9 @@ class Browser : public TabStripModelObserver,
// Note that if the browser window has been used before, users should always // Note that if the browser window has been used before, users should always
// have a chance to save their work before the window is closed without // have a chance to save their work before the window is closed without
// triggering beforeunload event. // triggering beforeunload event.
bool TryToCloseWindow(bool skip_beforeunload, bool TryToCloseWindow(
const base::Callback<void(bool)>& on_close_confirmed); bool skip_beforeunload,
const base::RepeatingCallback<void(bool)>& on_close_confirmed);
// Clears the results of any beforeunload confirmation dialogs triggered by a // Clears the results of any beforeunload confirmation dialogs triggered by a
// TryToCloseWindow call. // TryToCloseWindow call.
......
...@@ -166,7 +166,7 @@ bool UnloadController::ShouldCloseWindow() { ...@@ -166,7 +166,7 @@ bool UnloadController::ShouldCloseWindow() {
bool UnloadController::TryToCloseWindow( bool UnloadController::TryToCloseWindow(
bool skip_beforeunload, bool skip_beforeunload,
const base::Callback<void(bool)>& on_close_confirmed) { const base::RepeatingCallback<void(bool)>& on_close_confirmed) {
// The devtools browser gets its beforeunload events as the results of // The devtools browser gets its beforeunload events as the results of
// intercepting events from the inspected tab, so don't send them here as // intercepting events from the inspected tab, so don't send them here as
// well. // well.
...@@ -215,11 +215,8 @@ void UnloadController::CancelWindowClose() { ...@@ -215,11 +215,8 @@ void UnloadController::CancelWindowClose() {
DevToolsWindow::OnPageCloseCanceled(*it); DevToolsWindow::OnPageCloseCanceled(*it);
} }
tabs_needing_unload_fired_.clear(); tabs_needing_unload_fired_.clear();
if (is_calling_before_unload_handlers()) { if (is_calling_before_unload_handlers())
base::Callback<void(bool)> on_close_confirmed = on_close_confirmed_; std::move(on_close_confirmed_).Run(false);
on_close_confirmed_.Reset();
on_close_confirmed.Run(false);
}
is_attempting_to_close_browser_ = false; is_attempting_to_close_browser_ = false;
content::NotificationService::current()->Notify( content::NotificationService::current()->Notify(
...@@ -334,7 +331,8 @@ void UnloadController::ProcessPendingTabs(bool skip_beforeunload) { ...@@ -334,7 +331,8 @@ void UnloadController::ProcessPendingTabs(bool skip_beforeunload) {
ClearUnloadState(web_contents, true); ClearUnloadState(web_contents, true);
} }
} else if (is_calling_before_unload_handlers()) { } else if (is_calling_before_unload_handlers()) {
base::Callback<void(bool)> on_close_confirmed = on_close_confirmed_; base::RepeatingCallback<void(bool)> on_close_confirmed =
on_close_confirmed_;
// Reset |on_close_confirmed_| in case the callback tests // Reset |on_close_confirmed_| in case the callback tests
// |is_calling_before_unload_handlers()|, we want to return that calling // |is_calling_before_unload_handlers()|, we want to return that calling
// is complete. // is complete.
......
...@@ -63,8 +63,9 @@ class UnloadController : public content::NotificationObserver, ...@@ -63,8 +63,9 @@ class UnloadController : public content::NotificationObserver,
// Begins the process of confirming whether the associated browser can be // Begins the process of confirming whether the associated browser can be
// closed. Beforeunload events won't be fired if |skip_beforeunload| // closed. Beforeunload events won't be fired if |skip_beforeunload|
// is true. // is true.
bool TryToCloseWindow(bool skip_beforeunload, bool TryToCloseWindow(
const base::Callback<void(bool)>& on_close_confirmed); bool skip_beforeunload,
const base::RepeatingCallback<void(bool)>& on_close_confirmed);
// Clears the results of any beforeunload confirmation dialogs triggered by a // Clears the results of any beforeunload confirmation dialogs triggered by a
// TryToCloseWindow call. // TryToCloseWindow call.
...@@ -147,8 +148,13 @@ class UnloadController : public content::NotificationObserver, ...@@ -147,8 +148,13 @@ class UnloadController : public content::NotificationObserver,
// A callback to call to report whether the user chose to close all tabs of // A callback to call to report whether the user chose to close all tabs of
// |browser_| that have beforeunload event handlers. This is set only if we // |browser_| that have beforeunload event handlers. This is set only if we
// are currently confirming that the browser is closable. // are currently confirming that the browser is closable. This can be called
base::Callback<void(bool)> on_close_confirmed_; // more than once if a user confirms all the beforeunload prompts (at which
// point it will be called with true) but the window close is later aborted
// (at which point it will be called with false). This can happen when
// multiple browser windows are being closed together. See
// BrowserList::TryToCloseBrowserList.
base::RepeatingCallback<void(bool)> on_close_confirmed_;
base::WeakPtrFactory<UnloadController> weak_factory_{this}; base::WeakPtrFactory<UnloadController> weak_factory_{this};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment