Chromium Code Reviews| 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()); |