Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: trunk/src/chrome/browser/ui/unload_controller.h

Issue 14362028: Speculative Revert 195108 "Changes to closing contents with beforeunload/unl..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_UI_UNLOAD_CONTROLLER_H_ 5 #ifndef CHROME_BROWSER_UI_UNLOAD_CONTROLLER_H_
6 #define CHROME_BROWSER_UI_UNLOAD_CONTROLLER_H_ 6 #define CHROME_BROWSER_UI_UNLOAD_CONTROLLER_H_
7 7
8 #include <set> 8 #include <set>
9 9
10 #include "base/memory/scoped_ptr.h"
11 #include "base/memory/weak_ptr.h" 10 #include "base/memory/weak_ptr.h"
12 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" 11 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
13 #include "content/public/browser/notification_observer.h" 12 #include "content/public/browser/notification_observer.h"
14 #include "content/public/browser/notification_registrar.h" 13 #include "content/public/browser/notification_registrar.h"
15 14
16 class Browser; 15 class Browser;
17 class TabStripModel; 16 class TabStripModel;
18 17
19 namespace content { 18 namespace content {
20 class NotificationSource; 19 class NotificationSource;
21 class NotifictaionDetails; 20 class NotifictaionDetails;
22 class WebContents; 21 class WebContents;
23 } 22 }
24 23
25 namespace chrome { 24 namespace chrome {
26 class UnloadDetachedHandler;
27 25
28 // UnloadController manages closing tabs and windows -- especially in
29 // regards to beforeunload handlers (proceed/cancel dialogs) and
30 // unload handlers (no user interaction).
31 //
32 // Typical flow of closing a tab:
33 // 1. Browser calls |CanCloseContents()|.
34 // If true, browser calls contents::CloseWebContents().
35 // 2. WebContents notifies us via its delegate and BeforeUnloadFired()
36 // that the beforeunload handler was run. If the user allowed the
37 // close to continue, we hand-off running the unload handler to
38 // UnloadDetachedHandler. The tab is removed from the tab strip at
39 // this point.
40 //
41 // Typical flow of closing a window:
42 // 1. BrowserView::CanClose() calls TabsNeedBeforeUnloadFired().
43 // If beforeunload/unload handlers need to run, UnloadController returns
44 // true and calls ProcessPendingTabs() (private method).
45 // 2. For each tab with a beforeunload/unload handler, ProcessPendingTabs()
46 // calls |web_contents->OnCloseStarted()|
47 // and |web_contents->GetRenderViewHost()->FirePageBeforeUnload()|.
48 // 3. If the user allowed the close to continue, we hand-off all the tabs with
49 // unload handlers to UnloadDetachedHandler. All the tabs are removed
50 // from the tab strip.
51 // 4. The browser gets notified that the tab strip is empty and calls
52 // CloseFrame where the empty tab strip causes the window to hide.
53 // Once the detached tabs finish, the browser calls CloseFrame again and
54 // the window is finally closed.
55 //
56 class UnloadController : public content::NotificationObserver, 26 class UnloadController : public content::NotificationObserver,
57 public TabStripModelObserver { 27 public TabStripModelObserver {
58 public: 28 public:
59 explicit UnloadController(Browser* browser); 29 explicit UnloadController(Browser* browser);
60 virtual ~UnloadController(); 30 virtual ~UnloadController();
61 31
62 // Returns true if |contents| can be cleanly closed. When |browser_| is being 32 // Returns true if |contents| can be cleanly closed. When |browser_| is being
63 // closed, this function will return false to indicate |contents| should not 33 // closed, this function will return false to indicate |contents| should not
64 // be cleanly closed, since the fast shutdown path will just kill its 34 // be cleanly closed, since the fast shutdown path will just kill its
65 // renderer. 35 // renderer.
66 bool CanCloseContents(content::WebContents* contents); 36 bool CanCloseContents(content::WebContents* contents);
67 37
68 // Called when a BeforeUnload handler is fired for |contents|. |proceed| 38 // Called when a BeforeUnload handler is fired for |contents|. |proceed|
69 // indicates the user's response to the Y/N BeforeUnload handler dialog. If 39 // indicates the user's response to the Y/N BeforeUnload handler dialog. If
70 // this parameter is false, any pending attempt to close the whole browser 40 // this parameter is false, any pending attempt to close the whole browser
71 // will be canceled. Returns true if Unload handlers should be fired. When the 41 // will be canceled. Returns true if Unload handlers should be fired. When the
72 // |browser_| is being closed, Unload handlers for any particular WebContents 42 // |browser_| is being closed, Unload handlers for any particular WebContents
73 // will not be run until every WebContents being closed has a chance to run 43 // will not be run until every WebContents being closed has a chance to run
74 // its BeforeUnloadHandler. 44 // its BeforeUnloadHandler.
75 bool BeforeUnloadFired(content::WebContents* contents, bool proceed); 45 bool BeforeUnloadFired(content::WebContents* contents, bool proceed);
76 46
77 bool is_attempting_to_close_browser() const { 47 bool is_attempting_to_close_browser() const {
78 return is_attempting_to_close_browser_; 48 return is_attempting_to_close_browser_;
79 } 49 }
80 50
81 // Called in response to a request to close |browser_|'s window. Returns true 51 // Called in response to a request to close |browser_|'s window. Returns true
82 // when there are no remaining beforeunload handlers to be run. 52 // when there are no remaining unload handlers to be run.
83 bool ShouldCloseWindow(); 53 bool ShouldCloseWindow();
84 54
85 // Returns true if |browser_| has any tabs that have BeforeUnload handlers 55 // Returns true if |browser_| has any tabs that have BeforeUnload handlers
86 // that have not been fired. This method is non-const because it builds a list 56 // that have not been fired. This method is non-const because it builds a list
87 // of tabs that need their BeforeUnloadHandlers fired. 57 // of tabs that need their BeforeUnloadHandlers fired.
88 // TODO(beng): This seems like it could be private but it is used by 58 // TODO(beng): This seems like it could be private but it is used by
89 // AreAllBrowsersCloseable() in application_lifetime.cc. It seems 59 // AreAllBrowsersCloseable() in application_lifetime.cc. It seems
90 // very similar to ShouldCloseWindow() and some consolidation 60 // very similar to ShouldCloseWindow() and some consolidation
91 // could be pursued. 61 // could be pursued.
92 bool TabsNeedBeforeUnloadFired(); 62 bool TabsNeedBeforeUnloadFired();
93 63
94 // Returns true if all tabs' beforeunload/unload events have fired.
95 bool HasCompletedUnloadProcessing() const;
96
97 private: 64 private:
98 typedef std::set<content::WebContents*> UnloadListenerSet; 65 typedef std::set<content::WebContents*> UnloadListenerSet;
99 66
100 // Overridden from content::NotificationObserver: 67 // Overridden from content::NotificationObserver:
101 virtual void Observe(int type, 68 virtual void Observe(int type,
102 const content::NotificationSource& source, 69 const content::NotificationSource& source,
103 const content::NotificationDetails& details) OVERRIDE; 70 const content::NotificationDetails& details) OVERRIDE;
104 71
105 // Overridden from TabStripModelObserver: 72 // Overridden from TabStripModelObserver:
106 virtual void TabInsertedAt(content::WebContents* contents, 73 virtual void TabInsertedAt(content::WebContents* contents,
107 int index, 74 int index,
108 bool foreground) OVERRIDE; 75 bool foreground) OVERRIDE;
109 virtual void TabDetachedAt(content::WebContents* contents, 76 virtual void TabDetachedAt(content::WebContents* contents,
110 int index) OVERRIDE; 77 int index) OVERRIDE;
111 virtual void TabReplacedAt(TabStripModel* tab_strip_model, 78 virtual void TabReplacedAt(TabStripModel* tab_strip_model,
112 content::WebContents* old_contents, 79 content::WebContents* old_contents,
113 content::WebContents* new_contents, 80 content::WebContents* new_contents,
114 int index) OVERRIDE; 81 int index) OVERRIDE;
115 virtual void TabStripEmpty() OVERRIDE; 82 virtual void TabStripEmpty() OVERRIDE;
116 83
117 void TabAttachedImpl(content::WebContents* contents); 84 void TabAttachedImpl(content::WebContents* contents);
118 void TabDetachedImpl(content::WebContents* contents); 85 void TabDetachedImpl(content::WebContents* contents);
119 86
120 // Processes the next tab that needs it's beforeunload/unload event fired. 87 // Processes the next tab that needs it's beforeunload/unload event fired.
121 void ProcessPendingTabs(); 88 void ProcessPendingTabs();
122 89
90 // Whether we've completed firing all the tabs' beforeunload/unload events.
91 bool HasCompletedUnloadProcessing() const;
92
123 // Clears all the state associated with processing tabs' beforeunload/unload 93 // Clears all the state associated with processing tabs' beforeunload/unload
124 // events since the user cancelled closing the window. 94 // events since the user cancelled closing the window.
125 void CancelWindowClose(); 95 void CancelWindowClose();
126 96
127 // Removes |web_contents| from the passed |set|. 97 // Removes |web_contents| from the passed |set|.
128 // Returns whether the tab was in the set in the first place. 98 // Returns whether the tab was in the set in the first place.
129 bool RemoveFromSet(UnloadListenerSet* set, 99 bool RemoveFromSet(UnloadListenerSet* set,
130 content::WebContents* web_contents); 100 content::WebContents* web_contents);
131 101
132 // Cleans up state appropriately when we are trying to close the browser and 102 // Cleans up state appropriately when we are trying to close the browser and
133 // the tab has finished firing its unload handler. We also use this in the 103 // the tab has finished firing its unload handler. We also use this in the
134 // cases where a tab crashes or hangs even if the beforeunload/unload haven't 104 // cases where a tab crashes or hangs even if the beforeunload/unload haven't
135 // successfully fired. If |process_now| is true |ProcessPendingTabs| is 105 // successfully fired. If |process_now| is true |ProcessPendingTabs| is
136 // invoked immediately, otherwise it is invoked after a delay (PostTask). 106 // invoked immediately, otherwise it is invoked after a delay (PostTask).
137 // 107 //
138 // Typically you'll want to pass in true for |process_now|. Passing in true 108 // Typically you'll want to pass in true for |process_now|. Passing in true
139 // may result in deleting |tab|. If you know that shouldn't happen (because of 109 // may result in deleting |tab|. If you know that shouldn't happen (because of
140 // the state of the stack), pass in false. 110 // the state of the stack), pass in false.
141 void ClearUnloadState(content::WebContents* web_contents, bool process_now); 111 void ClearUnloadState(content::WebContents* web_contents, bool process_now);
142 112
143 Browser* browser_; 113 Browser* browser_;
144 114
145 content::NotificationRegistrar registrar_; 115 content::NotificationRegistrar registrar_;
146 116
147 // Tracks tabs that need their beforeunload event fired before we can 117 // Tracks tabs that need there beforeunload event fired before we can
148 // close the browser. Only gets populated when we try to close the browser. 118 // close the browser. Only gets populated when we try to close the browser.
149 UnloadListenerSet tabs_needing_before_unload_fired_; 119 UnloadListenerSet tabs_needing_before_unload_fired_;
150 120
151 // Tracks tabs that need their unload event fired before we can 121 // Tracks tabs that need there unload event fired before we can
152 // close the browser. Only gets populated when we try to close the browser. 122 // close the browser. Only gets populated when we try to close the browser.
153 UnloadListenerSet tabs_needing_unload_fired_; 123 UnloadListenerSet tabs_needing_unload_fired_;
154 124
155 // Whether we are processing the beforeunload and unload events of each tab 125 // Whether we are processing the beforeunload and unload events of each tab
156 // in preparation for closing the browser. UnloadController owns this state 126 // in preparation for closing the browser. UnloadController owns this state
157 // rather than Browser because unload handlers are the only reason that a 127 // rather than Browser because unload handlers are the only reason that a
158 // Browser window isn't just immediately closed. 128 // Browser window isn't just immediately closed.
159 bool is_attempting_to_close_browser_; 129 bool is_attempting_to_close_browser_;
160 130
161 // Allow unload handlers to run without holding up the UI.
162 scoped_ptr<UnloadDetachedHandler> unload_detached_handler_;
163
164 base::WeakPtrFactory<UnloadController> weak_factory_; 131 base::WeakPtrFactory<UnloadController> weak_factory_;
165 132
166 DISALLOW_COPY_AND_ASSIGN(UnloadController); 133 DISALLOW_COPY_AND_ASSIGN(UnloadController);
167 }; 134 };
168 135
169 } // namespace chrome 136 } // namespace chrome
170 137
171 #endif // CHROME_BROWSER_UI_UNLOAD_CONTROLLER_H_ 138 #endif // CHROME_BROWSER_UI_UNLOAD_CONTROLLER_H_
OLDNEW
« no previous file with comments | « trunk/src/chrome/browser/ui/gtk/browser_window_gtk.cc ('k') | trunk/src/chrome/browser/ui/unload_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698