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

Unified 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, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/browser_list.cc
diff --git a/chrome/browser/ui/browser_list.cc b/chrome/browser/ui/browser_list.cc
index 000c4c6210db311e0600ad9cac30d7a454e833c8..f21e37e32e557ee2a963533c18271ac636eb36c3 100644
--- a/chrome/browser/ui/browser_list.cc
+++ b/chrome/browser/ui/browser_list.cc
@@ -32,6 +32,10 @@ base::LazyInstance<ObserverList<chrome::BrowserListObserver> >::Leaky
BrowserList* BrowserList::native_instance_ = NULL;
BrowserList* BrowserList::ash_instance_ = NULL;
+// static
+// Whether the BrowserList is currently processing OnBeforeUnload events.
+bool before_unload_callback_expected_;
+
////////////////////////////////////////////////////////////////////////////////
// BrowserList, public:
@@ -116,6 +120,7 @@ void BrowserList::RemoveObserver(chrome::BrowserListObserver* observer) {
observers_.Get().RemoveObserver(observer);
}
+// static
void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) {
BrowserVector browsers_to_close;
for (chrome::BrowserIterator it; !it.done(); it.Next()) {
@@ -130,6 +135,74 @@ void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) {
}
// static
+void BrowserList::CloseAllBrowsersWithProfile(Profile* profile,
+ const base::Callback<void(const base::FilePath&)>& on_close_success) {
+ before_unload_callback_expected_ = false;
+ BrowserVector browsers_to_close;
+ for (chrome::BrowserIterator it; !it.done(); it.Next()) {
+ if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile())
+ browsers_to_close.push_back(*it);
+ }
+
+ TryToCloseBrowserList(browsers_to_close,
+ on_close_success,
+ profile->GetPath());
+}
+
+// static
+void BrowserList::TryToCloseBrowserList(const BrowserVector& browsers_to_close,
+ const base::Callback<void(const base::FilePath&)>& on_close_success,
+ const base::FilePath& profile_path) {
+ for (BrowserVector::const_iterator it = browsers_to_close.begin();
+ it != browsers_to_close.end(); ++it) {
+ if ((*it)->CallBeforeUnloadHandlers(
+ base::Bind(&BrowserList::PostBeforeUnloadHandlers,
+ browsers_to_close,
+ on_close_success,
+ profile_path))) {
+ // Note that the UnloadController has been called to fire and handle one
+ // OnBeforeUnload event. We expect the callback to be called once.
+ before_unload_callback_expected_ = true;
+ return;
+ }
+ }
+
+ for (BrowserVector::const_iterator it = browsers_to_close.begin();
+ it != browsers_to_close.end(); ++it)
+ (*it)->window()->Close();
+
+ on_close_success.Run(profile_path);
+}
+
+// static
+void BrowserList::PostBeforeUnloadHandlers(
+ const BrowserVector& browsers_to_close,
+ const base::Callback<void(const base::FilePath&)>& on_close_success,
+ const base::FilePath& profile_path,
+ bool tab_close_confirmed) {
+ // If multiple windows' OnBeforeUnload events have been handled when the user
+ // clicks "Stay on this page", then resetting the handlers will call each
+ // window's UnloadController's CancelWindowClose method, triggering the
+ // UnloadController's callback (this method). The following check ensures this
+ // 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.
+ if (!before_unload_callback_expected_)
+ return;
+
+ // The UnloadController has called back for the processing of a
+ // particular OnBeforeUnload event. We expect no more callbacks.
+ before_unload_callback_expected_ = false;
+
+ if (tab_close_confirmed) {
+ TryToCloseBrowserList(browsers_to_close, on_close_success, profile_path);
+ } else {
+ for (BrowserVector::const_iterator it = browsers_to_close.begin();
+ it != browsers_to_close.end(); ++it) {
+ (*it)->ResetBeforeUnloadHandlers();
+ }
+ }
+}
+
+// static
void BrowserList::SetLastActive(Browser* browser) {
content::RecordAction(UserMetricsAction("ActiveBrowserChanged"));
BrowserList* browser_list = GetInstance(browser->host_desktop_type());

Powered by Google App Engine
This is Rietveld 408576698