summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/unload_controller.h
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/ui/unload_controller.h')
-rw-r--r--chrome/browser/ui/unload_controller.h98
1 files changed, 28 insertions, 70 deletions
diff --git a/chrome/browser/ui/unload_controller.h b/chrome/browser/ui/unload_controller.h
index 47e50b0..4c13c67 100644
--- a/chrome/browser/ui/unload_controller.h
+++ b/chrome/browser/ui/unload_controller.h
@@ -7,9 +7,7 @@
#include <set>
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/strings/string_piece.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
@@ -24,33 +22,7 @@ class WebContents;
}
namespace chrome {
-// UnloadController manages closing tabs and windows -- especially in
-// regards to beforeunload handlers (have proceed/cancel dialogs) and
-// unload handlers (have no user interaction).
-//
-// Typical flow of closing a tab:
-// 1. Browser calls CanCloseContents().
-// If true, browser calls contents::CloseWebContents().
-// 2. WebContents notifies us via its delegate and BeforeUnloadFired()
-// that the beforeunload handler was run. If the user allowed the
-// close to continue, we detached the tab and hold onto it while the
-// close finishes.
-//
-// Typical flow of closing a window:
-// 1. BrowserView::CanClose() calls TabsNeedBeforeUnloadFired().
-// If beforeunload/unload handlers need to run, UnloadController returns
-// true and calls ProcessPendingTabs() (private method).
-// 2. For each tab with a beforeunload/unload handler, ProcessPendingTabs()
-// calls |CoreTabHelper::OnCloseStarted()|
-// and |web_contents->GetRenderViewHost()->FirePageBeforeUnload()|.
-// 3. If the user allowed the close to continue, we detach all the tabs with
-// unload handlers, remove them from the tab strip, and finish closing
-// the tabs in the background.
-// 4. The browser gets notified that the tab strip is empty and calls
-// CloseFrame where the empty tab strip causes the window to hide.
-// Once the detached tabs finish, the browser calls CloseFrame again and
-// the window is finally closed.
-//
+
class UnloadController : public content::NotificationObserver,
public TabStripModelObserver {
public:
@@ -77,7 +49,7 @@ class UnloadController : public content::NotificationObserver,
}
// Called in response to a request to close |browser_|'s window. Returns true
- // when there are no remaining beforeunload handlers to be run.
+ // when there are no remaining unload handlers to be run.
bool ShouldCloseWindow();
// Returns true if |browser_| has any tabs that have BeforeUnload handlers
@@ -89,10 +61,9 @@ class UnloadController : public content::NotificationObserver,
// could be pursued.
bool TabsNeedBeforeUnloadFired();
- // Returns true if all tabs' beforeunload/unload events have fired.
- bool HasCompletedUnloadProcessing() const;
-
private:
+ typedef std::set<content::WebContents*> UnloadListenerSet;
+
// Overridden from content::NotificationObserver:
virtual void Observe(int type,
const content::NotificationSource& source,
@@ -113,52 +84,43 @@ class UnloadController : public content::NotificationObserver,
void TabAttachedImpl(content::WebContents* contents);
void TabDetachedImpl(content::WebContents* contents);
- // Detach |contents| and wait for it to finish closing.
- // The close must be inititiated outside of this method.
- // Returns true if it succeeds.
- bool DetachWebContents(content::WebContents* contents);
-
// Processes the next tab that needs it's beforeunload/unload event fired.
void ProcessPendingTabs();
+ // Whether we've completed firing all the tabs' beforeunload/unload events.
+ bool HasCompletedUnloadProcessing() const;
+
// Clears all the state associated with processing tabs' beforeunload/unload
// events since the user cancelled closing the window.
void CancelWindowClose();
- // Cleans up state appropriately when we are trying to close the
- // browser or close a tab in the background. We also use this in the
- // cases where a tab crashes or hangs even if the
- // beforeunload/unload haven't successfully fired.
- void ClearUnloadState(content::WebContents* contents);
-
- // Helper for |ClearUnloadState| to unwind stack before proceeding.
- void PostTaskForProcessPendingTabs();
-
- // Log a step of the unload processing.
- void LogUnloadStep(const base::StringPiece& step_name,
- content::WebContents* contents) const;
+ // Removes |web_contents| from the passed |set|.
+ // Returns whether the tab was in the set in the first place.
+ bool RemoveFromSet(UnloadListenerSet* set,
+ content::WebContents* web_contents);
+
+ // Cleans up state appropriately when we are trying to close the browser and
+ // the tab has finished firing its unload handler. We also use this in the
+ // cases where a tab crashes or hangs even if the beforeunload/unload haven't
+ // successfully fired. If |process_now| is true |ProcessPendingTabs| is
+ // invoked immediately, otherwise it is invoked after a delay (PostTask).
+ //
+ // Typically you'll want to pass in true for |process_now|. Passing in true
+ // may result in deleting |tab|. If you know that shouldn't happen (because of
+ // the state of the stack), pass in false.
+ void ClearUnloadState(content::WebContents* web_contents, bool process_now);
Browser* browser_;
content::NotificationRegistrar registrar_;
- typedef std::set<content::WebContents*> WebContentsSet;
-
- // Tracks tabs that need their beforeunload event started.
- // Only gets populated when we try to close the browser.
- WebContentsSet tabs_needing_before_unload_;
+ // Tracks tabs that need there beforeunload event fired before we can
+ // close the browser. Only gets populated when we try to close the browser.
+ UnloadListenerSet tabs_needing_before_unload_fired_;
- // Tracks the tab that needs its beforeunload event result.
- // Only gets populated when we try to close the browser.
- content::WebContents* tab_needing_before_unload_ack_;
-
- // Tracks tabs that need their unload event started.
- // Only gets populated when we try to close the browser.
- WebContentsSet tabs_needing_unload_;
-
- // Tracks tabs that need to finish running their unload event.
- // Populated both when closing individual tabs and when closing the browser.
- WebContentsSet tabs_needing_unload_ack_;
+ // Tracks tabs that need there unload event fired before we can
+ // close the browser. Only gets populated when we try to close the browser.
+ UnloadListenerSet tabs_needing_unload_fired_;
// Whether we are processing the beforeunload and unload events of each tab
// in preparation for closing the browser. UnloadController owns this state
@@ -166,10 +128,6 @@ class UnloadController : public content::NotificationObserver,
// Browser window isn't just immediately closed.
bool is_attempting_to_close_browser_;
- // Manage tabs with beforeunload/unload handlers that close detached.
- class DetachedWebContentsDelegate;
- scoped_ptr<DetachedWebContentsDelegate> detached_delegate_;
-
base::WeakPtrFactory<UnloadController> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(UnloadController);