browser_list.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/browser_list.h" 6 7#include <algorithm> 8 9#include "base/logging.h" 10#include "chrome/browser/browser_process.h" 11#include "chrome/browser/browser_shutdown.h" 12#include "chrome/browser/chrome_notification_types.h" 13#include "chrome/browser/lifetime/application_lifetime.h" 14#include "chrome/browser/profiles/profile.h" 15#include "chrome/browser/ui/browser.h" 16#include "chrome/browser/ui/browser_finder.h" 17#include "chrome/browser/ui/browser_iterator.h" 18#include "chrome/browser/ui/browser_list_observer.h" 19#include "chrome/browser/ui/browser_window.h" 20#include "chrome/browser/ui/host_desktop.h" 21#include "content/public/browser/notification_service.h" 22#include "content/public/browser/user_metrics.h" 23 24#if defined(OS_CHROMEOS) 25#include "chrome/browser/chromeos/login/users/user_manager.h" 26#endif 27 28using base::UserMetricsAction; 29using content::WebContents; 30 31// static 32base::LazyInstance<ObserverList<chrome::BrowserListObserver> >::Leaky 33 BrowserList::observers_ = LAZY_INSTANCE_INITIALIZER; 34 35// static 36BrowserList* BrowserList::native_instance_ = NULL; 37BrowserList* BrowserList::ash_instance_ = NULL; 38 39//////////////////////////////////////////////////////////////////////////////// 40// BrowserList, public: 41 42Browser* BrowserList::GetLastActive() const { 43 if (!last_active_browsers_.empty()) 44 return *(last_active_browsers_.rbegin()); 45 return NULL; 46} 47 48// static 49BrowserList* BrowserList::GetInstance(chrome::HostDesktopType type) { 50 BrowserList** list = NULL; 51 if (type == chrome::HOST_DESKTOP_TYPE_NATIVE) 52 list = &native_instance_; 53 else if (type == chrome::HOST_DESKTOP_TYPE_ASH) 54 list = &ash_instance_; 55 else 56 NOTREACHED(); 57 if (!*list) 58 *list = new BrowserList; 59 return *list; 60} 61 62// static 63void BrowserList::AddBrowser(Browser* browser) { 64 DCHECK(browser); 65 // Push |browser| on the appropriate list instance. 66 BrowserList* browser_list = GetInstance(browser->host_desktop_type()); 67 browser_list->browsers_.push_back(browser); 68 69 g_browser_process->AddRefModule(); 70 71 content::NotificationService::current()->Notify( 72 chrome::NOTIFICATION_BROWSER_OPENED, 73 content::Source<Browser>(browser), 74 content::NotificationService::NoDetails()); 75 76 FOR_EACH_OBSERVER(chrome::BrowserListObserver, observers_.Get(), 77 OnBrowserAdded(browser)); 78} 79 80// static 81void BrowserList::RemoveBrowser(Browser* browser) { 82 // Remove |browser| from the appropriate list instance. 83 BrowserList* browser_list = GetInstance(browser->host_desktop_type()); 84 RemoveBrowserFrom(browser, &browser_list->last_active_browsers_); 85 86 content::NotificationService::current()->Notify( 87 chrome::NOTIFICATION_BROWSER_CLOSED, 88 content::Source<Browser>(browser), 89 content::NotificationService::NoDetails()); 90 91 RemoveBrowserFrom(browser, &browser_list->browsers_); 92 93 FOR_EACH_OBSERVER(chrome::BrowserListObserver, observers_.Get(), 94 OnBrowserRemoved(browser)); 95 96 g_browser_process->ReleaseModule(); 97 98 // If we're exiting, send out the APP_TERMINATING notification to allow other 99 // modules to shut themselves down. 100 if (chrome::GetTotalBrowserCount() == 0 && 101 (browser_shutdown::IsTryingToQuit() || 102 g_browser_process->IsShuttingDown())) { 103 // Last browser has just closed, and this is a user-initiated quit or there 104 // is no module keeping the app alive, so send out our notification. No need 105 // to call ProfileManager::ShutdownSessionServices() as part of the 106 // shutdown, because Browser::WindowClosing() already makes sure that the 107 // SessionService is created and notified. 108 chrome::NotifyAppTerminating(); 109 chrome::OnAppExiting(); 110 } 111} 112 113// static 114void BrowserList::AddObserver(chrome::BrowserListObserver* observer) { 115 observers_.Get().AddObserver(observer); 116} 117 118// static 119void BrowserList::RemoveObserver(chrome::BrowserListObserver* observer) { 120 observers_.Get().RemoveObserver(observer); 121} 122 123void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) { 124 BrowserVector browsers_to_close; 125 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 126 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile()) 127 browsers_to_close.push_back(*it); 128 } 129 130 for (BrowserVector::const_iterator it = browsers_to_close.begin(); 131 it != browsers_to_close.end(); ++it) { 132 (*it)->window()->Close(); 133 } 134} 135 136// static 137void BrowserList::SetLastActive(Browser* browser) { 138 content::RecordAction(UserMetricsAction("ActiveBrowserChanged")); 139 BrowserList* browser_list = GetInstance(browser->host_desktop_type()); 140 141 RemoveBrowserFrom(browser, &browser_list->last_active_browsers_); 142 browser_list->last_active_browsers_.push_back(browser); 143 144 FOR_EACH_OBSERVER(chrome::BrowserListObserver, observers_.Get(), 145 OnBrowserSetLastActive(browser)); 146} 147 148// static 149bool BrowserList::IsOffTheRecordSessionActive() { 150 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 151 if (it->profile()->IsOffTheRecord()) 152 return true; 153 } 154 return false; 155} 156 157// static 158bool BrowserList::IsOffTheRecordSessionActiveForProfile(Profile* profile) { 159 if (profile->IsGuestSession()) 160 return true; 161 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 162 if (it->profile()->IsSameProfile(profile) && 163 it->profile()->IsOffTheRecord()) { 164 return true; 165 } 166 } 167 return false; 168} 169 170//////////////////////////////////////////////////////////////////////////////// 171// BrowserList, private: 172 173BrowserList::BrowserList() { 174} 175 176BrowserList::~BrowserList() { 177} 178 179// static 180void BrowserList::RemoveBrowserFrom(Browser* browser, 181 BrowserVector* browser_list) { 182 BrowserVector::iterator remove_browser = 183 std::find(browser_list->begin(), browser_list->end(), browser); 184 if (remove_browser != browser_list->end()) 185 browser_list->erase(remove_browser); 186} 187