Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / browser_list.cc
index 66968ae..b9d6317 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 
+#include "base/auto_reset.h"
 #include "base/logging.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/user_metrics.h"
 
-#if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/login/user_manager.h"
-#endif
-
-using content::UserMetricsAction;
+using base::UserMetricsAction;
 using content::WebContents;
 
 // static
@@ -120,6 +117,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()) {
@@ -134,6 +132,67 @@ void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) {
 }
 
 // static
+void BrowserList::CloseAllBrowsersWithProfile(Profile* profile,
+    const base::Callback<void(const base::FilePath&)>& on_close_success) {
+  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))) {
+      return;
+    }
+  }
+
+  on_close_success.Run(profile_path);
+
+  for (Browser* b : browsers_to_close) {
+    // BeforeUnload handlers may close browser windows, so we need to explicitly
+    // check whether they still exist.
+    if (b->window())
+      b->window()->Close();
+  }
+}
+
+// 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) {
+  // We need this bool to avoid infinite recursion when resetting the
+  // BeforeUnload handlers, since doing that will trigger calls back to this
+  // method for each affected window.
+  static bool resetting_handlers = false;
+
+  if (tab_close_confirmed) {
+    TryToCloseBrowserList(browsers_to_close, on_close_success, profile_path);
+  } else if (!resetting_handlers) {
+    base::AutoReset<bool> resetting_handlers_scoper(&resetting_handlers, true);
+    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());
@@ -156,12 +215,8 @@ bool BrowserList::IsOffTheRecordSessionActive() {
 
 // static
 bool BrowserList::IsOffTheRecordSessionActiveForProfile(Profile* profile) {
-  #if defined(OS_CHROMEOS)
-  // In ChromeOS, we assume that the default profile is always valid, so if
-  // we are in guest mode, keep the OTR profile active so it won't be deleted.
-  if (chromeos::UserManager::Get()->IsLoggedInAsGuest())
+  if (profile->IsGuestSession())
     return true;
-#endif
   for (chrome::BrowserIterator it; !it.done(); it.Next()) {
     if (it->profile()->IsSameProfile(profile) &&
         it->profile()->IsOffTheRecord()) {