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