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

Side by Side Diff: chrome/browser/ui/browser_list.cc

Issue 471763008: Nicely handle OnBeforeUnloads with guest and lock mode. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: A couple of comments and compiler issues Created 6 years, 3 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
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 #include "chrome/browser/ui/browser_list.h" 5 #include "chrome/browser/ui/browser_list.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
(...skipping 14 matching lines...) Expand all
25 using content::WebContents; 25 using content::WebContents;
26 26
27 // static 27 // static
28 base::LazyInstance<ObserverList<chrome::BrowserListObserver> >::Leaky 28 base::LazyInstance<ObserverList<chrome::BrowserListObserver> >::Leaky
29 BrowserList::observers_ = LAZY_INSTANCE_INITIALIZER; 29 BrowserList::observers_ = LAZY_INSTANCE_INITIALIZER;
30 30
31 // static 31 // static
32 BrowserList* BrowserList::native_instance_ = NULL; 32 BrowserList* BrowserList::native_instance_ = NULL;
33 BrowserList* BrowserList::ash_instance_ = NULL; 33 BrowserList* BrowserList::ash_instance_ = NULL;
34 34
35 // static
36 // Whether the BrowserList is currently processing OnBeforeUnload events.
37 bool before_unload_callback_expected_;
38
35 //////////////////////////////////////////////////////////////////////////////// 39 ////////////////////////////////////////////////////////////////////////////////
36 // BrowserList, public: 40 // BrowserList, public:
37 41
38 Browser* BrowserList::GetLastActive() const { 42 Browser* BrowserList::GetLastActive() const {
39 if (!last_active_browsers_.empty()) 43 if (!last_active_browsers_.empty())
40 return *(last_active_browsers_.rbegin()); 44 return *(last_active_browsers_.rbegin());
41 return NULL; 45 return NULL;
42 } 46 }
43 47
44 // static 48 // static
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 // static 113 // static
110 void BrowserList::AddObserver(chrome::BrowserListObserver* observer) { 114 void BrowserList::AddObserver(chrome::BrowserListObserver* observer) {
111 observers_.Get().AddObserver(observer); 115 observers_.Get().AddObserver(observer);
112 } 116 }
113 117
114 // static 118 // static
115 void BrowserList::RemoveObserver(chrome::BrowserListObserver* observer) { 119 void BrowserList::RemoveObserver(chrome::BrowserListObserver* observer) {
116 observers_.Get().RemoveObserver(observer); 120 observers_.Get().RemoveObserver(observer);
117 } 121 }
118 122
123 // static
119 void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) { 124 void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) {
120 BrowserVector browsers_to_close; 125 BrowserVector browsers_to_close;
121 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 126 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
122 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile()) 127 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile())
123 browsers_to_close.push_back(*it); 128 browsers_to_close.push_back(*it);
124 } 129 }
125 130
126 for (BrowserVector::const_iterator it = browsers_to_close.begin(); 131 for (BrowserVector::const_iterator it = browsers_to_close.begin();
127 it != browsers_to_close.end(); ++it) { 132 it != browsers_to_close.end(); ++it) {
128 (*it)->window()->Close(); 133 (*it)->window()->Close();
129 } 134 }
130 } 135 }
131 136
132 // static 137 // static
138 void BrowserList::CloseAllBrowsersWithProfile(Profile* profile,
139 const base::Callback<void(const base::FilePath&)>& on_close_success) {
140 before_unload_callback_expected_ = false;
141 BrowserVector browsers_to_close;
142 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
143 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile())
144 browsers_to_close.push_back(*it);
145 }
146
147 TryToCloseBrowserList(browsers_to_close,
148 on_close_success,
149 profile->GetPath());
150 }
151
152 // static
153 void BrowserList::TryToCloseBrowserList(const BrowserVector& browsers_to_close,
154 const base::Callback<void(const base::FilePath&)>& on_close_success,
155 const base::FilePath& profile_path) {
156 for (BrowserVector::const_iterator it = browsers_to_close.begin();
157 it != browsers_to_close.end(); ++it) {
158 if ((*it)->CallBeforeUnloadHandlers(
159 base::Bind(&BrowserList::PostBeforeUnloadHandlers,
160 browsers_to_close,
161 on_close_success,
162 profile_path))) {
163 // Note that the UnloadController has been called to fire and handle one
164 // OnBeforeUnload event. We expect the callback to be called once.
165 before_unload_callback_expected_ = true;
166 return;
167 }
168 }
169
170 for (BrowserVector::const_iterator it = browsers_to_close.begin();
171 it != browsers_to_close.end(); ++it)
172 (*it)->window()->Close();
173
174 on_close_success.Run(profile_path);
175 }
176
177 // static
178 void BrowserList::PostBeforeUnloadHandlers(
179 const BrowserVector& browsers_to_close,
180 const base::Callback<void(const base::FilePath&)>& on_close_success,
181 const base::FilePath& profile_path,
182 bool tab_close_confirmed) {
183 // If multiple windows' OnBeforeUnload events have been handled when the user
184 // clicks "Stay on this page", then resetting the handlers will call each
185 // window's UnloadController's CancelWindowClose method, triggering the
186 // UnloadController's callback (this method). The following check ensures this
187 // callback only executes once.
Peter Kasting 2014/08/29 21:30:25 It seems like we can simplify this to avoid the me
Mike Lerman 2014/09/02 15:15:40 I like that AutoReset class! And done.
188 if (!before_unload_callback_expected_)
189 return;
190
191 // The UnloadController has called back for the processing of a
192 // particular OnBeforeUnload event. We expect no more callbacks.
193 before_unload_callback_expected_ = false;
194
195 if (tab_close_confirmed) {
196 TryToCloseBrowserList(browsers_to_close, on_close_success, profile_path);
197 } else {
198 for (BrowserVector::const_iterator it = browsers_to_close.begin();
199 it != browsers_to_close.end(); ++it) {
200 (*it)->ResetBeforeUnloadHandlers();
201 }
202 }
203 }
204
205 // static
133 void BrowserList::SetLastActive(Browser* browser) { 206 void BrowserList::SetLastActive(Browser* browser) {
134 content::RecordAction(UserMetricsAction("ActiveBrowserChanged")); 207 content::RecordAction(UserMetricsAction("ActiveBrowserChanged"));
135 BrowserList* browser_list = GetInstance(browser->host_desktop_type()); 208 BrowserList* browser_list = GetInstance(browser->host_desktop_type());
136 209
137 RemoveBrowserFrom(browser, &browser_list->last_active_browsers_); 210 RemoveBrowserFrom(browser, &browser_list->last_active_browsers_);
138 browser_list->last_active_browsers_.push_back(browser); 211 browser_list->last_active_browsers_.push_back(browser);
139 212
140 FOR_EACH_OBSERVER(chrome::BrowserListObserver, observers_.Get(), 213 FOR_EACH_OBSERVER(chrome::BrowserListObserver, observers_.Get(),
141 OnBrowserSetLastActive(browser)); 214 OnBrowserSetLastActive(browser));
142 } 215 }
(...skipping 30 matching lines...) Expand all
173 } 246 }
174 247
175 // static 248 // static
176 void BrowserList::RemoveBrowserFrom(Browser* browser, 249 void BrowserList::RemoveBrowserFrom(Browser* browser,
177 BrowserVector* browser_list) { 250 BrowserVector* browser_list) {
178 BrowserVector::iterator remove_browser = 251 BrowserVector::iterator remove_browser =
179 std::find(browser_list->begin(), browser_list->end(), browser); 252 std::find(browser_list->begin(), browser_list->end(), browser);
180 if (remove_browser != browser_list->end()) 253 if (remove_browser != browser_list->end())
181 browser_list->erase(remove_browser); 254 browser_list->erase(remove_browser);
182 } 255 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698