15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/auto_reset.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_shutdown.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list_observer.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_service.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/user_metrics.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::LazyInstance<ObserverList<chrome::BrowserListObserver> >::Leaky
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserList::observers_ = LAZY_INSTANCE_INITIALIZER;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserList* BrowserList::native_instance_ = NULL;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserList* BrowserList::ash_instance_ = NULL;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// BrowserList, public:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Browser* BrowserList::GetLastActive() const {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!last_active_browsers_.empty())
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return *(last_active_browsers_.rbegin());
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserList* BrowserList::GetInstance(chrome::HostDesktopType type) {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserList** list = NULL;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type == chrome::HOST_DESKTOP_TYPE_NATIVE)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list = &native_instance_;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (type == chrome::HOST_DESKTOP_TYPE_ASH)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list = &ash_instance_;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!*list)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *list = new BrowserList;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return *list;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserList::AddBrowser(Browser* browser) {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(browser);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Push |browser| on the appropriate list instance.
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserList* browser_list = GetInstance(browser->host_desktop_type());
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_list->browsers_.push_back(browser);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  g_browser_process->AddRefModule();
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::NotificationService::current()->Notify(
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome::NOTIFICATION_BROWSER_OPENED,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::Source<Browser>(browser),
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::NotificationService::NoDetails());
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(chrome::BrowserListObserver, observers_.Get(),
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnBrowserAdded(browser));
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserList::RemoveBrowser(Browser* browser) {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove |browser| from the appropriate list instance.
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserList* browser_list = GetInstance(browser->host_desktop_type());
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RemoveBrowserFrom(browser, &browser_list->last_active_browsers_);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::NotificationService::current()->Notify(
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome::NOTIFICATION_BROWSER_CLOSED,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::Source<Browser>(browser),
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::NotificationService::NoDetails());
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RemoveBrowserFrom(browser, &browser_list->browsers_);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(chrome::BrowserListObserver, observers_.Get(),
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnBrowserRemoved(browser));
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  g_browser_process->ReleaseModule();
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we're exiting, send out the APP_TERMINATING notification to allow other
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // modules to shut themselves down.
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (chrome::GetTotalBrowserCount() == 0 &&
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (browser_shutdown::IsTryingToQuit() ||
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       g_browser_process->IsShuttingDown())) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Last browser has just closed, and this is a user-initiated quit or there
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // is no module keeping the app alive, so send out our notification. No need
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // to call ProfileManager::ShutdownSessionServices() as part of the
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // shutdown, because Browser::WindowClosing() already makes sure that the
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // SessionService is created and notified.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome::NotifyAppTerminating();
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome::OnAppExiting();
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserList::AddObserver(chrome::BrowserListObserver* observer) {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.Get().AddObserver(observer);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserList::RemoveObserver(chrome::BrowserListObserver* observer) {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.Get().RemoveObserver(observer);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserVector browsers_to_close;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile())
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browsers_to_close.push_back(*it);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (BrowserVector::const_iterator it = browsers_to_close.begin();
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != browsers_to_close.end(); ++it) {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*it)->window()->Close();
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BrowserList::CloseAllBrowsersWithProfile(Profile* profile,
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::Callback<void(const base::FilePath&)>& on_close_success) {
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BrowserVector browsers_to_close;
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile())
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      browsers_to_close.push_back(*it);
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TryToCloseBrowserList(browsers_to_close,
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        on_close_success,
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        profile->GetPath());
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BrowserList::TryToCloseBrowserList(const BrowserVector& browsers_to_close,
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::Callback<void(const base::FilePath&)>& on_close_success,
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::FilePath& profile_path) {
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (BrowserVector::const_iterator it = browsers_to_close.begin();
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != browsers_to_close.end(); ++it) {
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if ((*it)->CallBeforeUnloadHandlers(
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            base::Bind(&BrowserList::PostBeforeUnloadHandlers,
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       browsers_to_close,
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       on_close_success,
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       profile_path))) {
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return;
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  on_close_success.Run(profile_path);
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
16529b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  for (Browser* b : browsers_to_close) {
16629b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    // BeforeUnload handlers may close browser windows, so we need to explicitly
16729b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    // check whether they still exist.
16829b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    if (b->window())
16929b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch      b->window()->Close();
17029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch  }
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BrowserList::PostBeforeUnloadHandlers(
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const BrowserVector& browsers_to_close,
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::Callback<void(const base::FilePath&)>& on_close_success,
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::FilePath& profile_path,
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool tab_close_confirmed) {
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We need this bool to avoid infinite recursion when resetting the
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // BeforeUnload handlers, since doing that will trigger calls back to this
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // method for each affected window.
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static bool resetting_handlers = false;
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (tab_close_confirmed) {
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TryToCloseBrowserList(browsers_to_close, on_close_success, profile_path);
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (!resetting_handlers) {
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::AutoReset<bool> resetting_handlers_scoper(&resetting_handlers, true);
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (BrowserVector::const_iterator it = browsers_to_close.begin();
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         it != browsers_to_close.end(); ++it) {
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      (*it)->ResetBeforeUnloadHandlers();
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserList::SetLastActive(Browser* browser) {
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::RecordAction(UserMetricsAction("ActiveBrowserChanged"));
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserList* browser_list = GetInstance(browser->host_desktop_type());
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RemoveBrowserFrom(browser, &browser_list->last_active_browsers_);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_list->last_active_browsers_.push_back(browser);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(chrome::BrowserListObserver, observers_.Get(),
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnBrowserSetLastActive(browser));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserList::IsOffTheRecordSessionActive() {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (it->profile()->IsOffTheRecord())
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserList::IsOffTheRecordSessionActiveForProfile(Profile* profile) {
2180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (profile->IsGuestSession())
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (it->profile()->IsSameProfile(profile) &&
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        it->profile()->IsOffTheRecord()) {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// BrowserList, private:
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserList::BrowserList() {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserList::~BrowserList() {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserList::RemoveBrowserFrom(Browser* browser,
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    BrowserVector* browser_list) {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserVector::iterator remove_browser =
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::find(browser_list->begin(), browser_list->end(), browser);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (remove_browser != browser_list->end())
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser_list->erase(remove_browser);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
246