1// Copyright (c) 2011 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#ifndef CHROME_BROWSER_UI_BROWSER_LIST_H_
6#define CHROME_BROWSER_UI_BROWSER_LIST_H_
7#pragma once
8
9#include <vector>
10
11#include "base/observer_list.h"
12#include "chrome/browser/ui/browser.h"
13
14// Stores a list of all Browser objects.
15class BrowserList {
16 public:
17  typedef std::vector<Browser*> BrowserVector;
18  typedef BrowserVector::iterator iterator;
19  typedef BrowserVector::const_iterator const_iterator;
20  typedef BrowserVector::const_reverse_iterator const_reverse_iterator;
21
22  // It is not allowed to change the global window list (add or remove any
23  // browser windows while handling observer callbacks.
24  class Observer {
25   public:
26    // Called immediately after a browser is added to the list
27    virtual void OnBrowserAdded(const Browser* browser) = 0;
28
29    // Called immediately after a browser is removed from the list
30    virtual void OnBrowserRemoved(const Browser* browser) = 0;
31
32    // Called immediately after a browser is set active (SetLastActive)
33    virtual void OnBrowserSetLastActive(const Browser* browser) {}
34
35   protected:
36    virtual ~Observer() {}
37  };
38
39  // Adds and removes browsers from the global list. The browser object should
40  // be valid BEFORE these calls (for the benefit of observers), so notify and
41  // THEN delete the object.
42  static void AddBrowser(Browser* browser);
43  static void RemoveBrowser(Browser* browser);
44
45  static void AddObserver(Observer* observer);
46  static void RemoveObserver(Observer* observer);
47
48  // Called by Browser objects when their window is activated (focused).  This
49  // allows us to determine what the last active Browser was.
50  static void SetLastActive(Browser* browser);
51
52  // Returns the Browser object whose window was most recently active.  If the
53  // most recently open Browser's window was closed, returns the first Browser
54  // in the list.  If no Browsers exist, returns NULL.
55  //
56  // WARNING: this is NULL until a browser becomes active. If during startup
57  // a browser does not become active (perhaps the user launches Chrome, then
58  // clicks on another app before the first browser window appears) then this
59  // returns NULL.
60  // WARNING #2: this will always be NULL in unit tests run on the bots.
61  static Browser* GetLastActive();
62
63  // Identical in behavior to GetLastActive(), except that the most recently
64  // open browser owned by |profile| is returned. If none exist, returns NULL.
65  // WARNING: see warnings in GetLastActive().
66  static Browser* GetLastActiveWithProfile(Profile *profile);
67
68  // Find an existing browser window with the provided type. Searches in the
69  // order of last activation. Only browsers that have been active can be
70  // returned. If |match_incognito| is true, will match a browser with either
71  // a regular or incognito profile that matches the given one. Returns NULL if
72  // no such browser currently exists.
73  static Browser* FindBrowserWithType(Profile* p, Browser::Type t,
74                                      bool match_incognito);
75
76  // Find an existing browser window that can provide the specified type (this
77  // uses Browser::CanSupportsWindowFeature, not
78  // Browser::SupportsWindowFeature). This searches in the order of last
79  // activation. Only browsers that have been active can be returned. Returns
80  // NULL if no such browser currently exists.
81  static Browser* FindBrowserWithFeature(Profile* p,
82                                         Browser::WindowFeature feature);
83
84  // Find an existing browser window with the provided profile. Searches in the
85  // order of last activation. Only browsers that have been active can be
86  // returned. Returns NULL if no such browser currently exists.
87  static Browser* FindBrowserWithProfile(Profile* p);
88
89  // Find an existing browser with the provided ID. Returns NULL if no such
90  // browser currently exists.
91  static Browser* FindBrowserWithID(SessionID::id_type desired_id);
92
93  // Checks if the browser can be automatically restarted to install upgrades
94  // The browser can be automatically restarted when:
95  // 1. It's in the background mode (no visible windows).
96  // 2. An update exe is present in the install folder.
97  static bool CanRestartForUpdate();
98
99  // Called from Browser::Exit.
100  static void Exit();
101
102  // Closes all browsers and exits.  This is equivalent to
103  // CloseAllBrowsers(true) on platforms where the application exits when no
104  // more windows are remaining.  On other platforms (the Mac), this will
105  // additionally exit the application.
106  static void CloseAllBrowsersAndExit();
107
108  // Closes all browsers. If the session is ending the windows are closed
109  // directly. Otherwise the windows are closed by way of posting a WM_CLOSE
110  // message.
111  static void CloseAllBrowsers();
112
113  // Begins shutdown of the application when the desktop session is ending.
114  static void SessionEnding();
115
116  // Returns true if there is at least one Browser with the specified profile.
117  static bool HasBrowserWithProfile(Profile* profile);
118
119  // Tells the BrowserList to keep the application alive after the last Browser
120  // closes. This is implemented as a count, so callers should pair their calls
121  // to StartKeepAlive() with matching calls to EndKeepAlive() when they no
122  // longer need to keep the application running.
123  static void StartKeepAlive();
124
125  // Stops keeping the application alive after the last Browser is closed.
126  // Should match a previous call to StartKeepAlive().
127  static void EndKeepAlive();
128
129  // Returns true if application will continue running after the last Browser
130  // closes.
131  static bool WillKeepAlive();
132
133  // Browsers are added to |browsers_| before they have constructed windows,
134  // so the |window()| member function may return NULL.
135  static const_iterator begin() { return browsers_.begin(); }
136  static const_iterator end() { return browsers_.end(); }
137
138  static bool empty() { return browsers_.empty(); }
139  static size_t size() { return browsers_.size(); }
140
141  // Returns iterated access to list of open browsers ordered by when
142  // they were last active. The underlying data structure is a vector
143  // and we push_back on recent access so a reverse iterator gives the
144  // latest accessed browser first.
145  static const_reverse_iterator begin_last_active() {
146    return last_active_browsers_.rbegin();
147  }
148
149  static const_reverse_iterator end_last_active() {
150    return last_active_browsers_.rend();
151  }
152
153  // Return the number of browsers with the following profile which are
154  // currently open.
155  static size_t GetBrowserCount(Profile* p);
156
157  // Return the number of browsers with the following profile and type which are
158  // currently open.
159  static size_t GetBrowserCountForType(Profile* p, Browser::Type type);
160
161  // Returns true if at least one incognito session is active.
162  static bool IsOffTheRecordSessionActive();
163
164  // Send out notifications.
165  // For ChromeOS, also request session manager to end the session.
166  static void NotifyAndTerminate(bool fast_path);
167
168  // Called once there are no more browsers open and the application is exiting.
169  static void AllBrowsersClosedAndAppExiting();
170
171 private:
172  // Helper method to remove a browser instance from a list of browsers
173  static void RemoveBrowserFrom(Browser* browser, BrowserVector* browser_list);
174  static void MarkAsCleanShutdown();
175#if defined(OS_CHROMEOS)
176  static bool NeedBeforeUnloadFired();
177  static bool PendingDownloads();
178  static void NotifyWindowManagerAboutSignout();
179
180  static bool signout_;
181#endif
182
183  static BrowserVector browsers_;
184  static BrowserVector last_active_browsers_;
185  static ObserverList<Observer> observers_;
186
187  // Counter of calls to StartKeepAlive(). If non-zero, the application will
188  // continue running after the last browser has exited.
189  static int keep_alive_count_;
190};
191
192class TabContentsWrapper;
193
194// Iterates through all web view hosts in all browser windows. Because the
195// renderers act asynchronously, getting a host through this interface does
196// not guarantee that the renderer is ready to go. Doing anything to affect
197// browser windows or tabs while iterating may cause incorrect behavior.
198//
199// Example:
200//   for (TabContentsIterator iterator; !iterator.done(); ++iterator) {
201//     TabContents* cur = *iterator;
202//     -or-
203//     iterator->operationOnTabContents();
204//     ...
205//   }
206class TabContentsIterator {
207 public:
208  TabContentsIterator();
209
210  // Returns true if we are past the last Browser.
211  bool done() const {
212    return cur_ == NULL;
213  }
214
215  // Returns the Browser instance associated with the current TabContents.
216  // Valid as long as !Done()
217  Browser* browser() const {
218    return *browser_iterator_;
219  }
220
221  // Returns the current TabContents, valid as long as !Done()
222  TabContentsWrapper* operator->() const {
223    return cur_;
224  }
225  TabContentsWrapper* operator*() const {
226    return cur_;
227  }
228
229  // Incrementing operators, valid as long as !Done()
230  TabContentsWrapper* operator++() {  // ++preincrement
231    Advance();
232    return cur_;
233  }
234  TabContentsWrapper* operator++(int) {  // postincrement++
235    TabContentsWrapper* tmp = cur_;
236    Advance();
237    return tmp;
238  }
239
240 private:
241  // Loads the next host into Cur. This is designed so that for the initial
242  // call when browser_iterator_ points to the first browser and
243  // web_view_index_ is -1, it will fill the first host.
244  void Advance();
245
246  // iterator over all the Browser objects
247  BrowserList::const_iterator browser_iterator_;
248
249  // tab index into the current Browser of the current web view
250  int web_view_index_;
251
252  // Current TabContents, or NULL if we're at the end of the list. This can
253  // be extracted given the browser iterator and index, but it's nice to cache
254  // this since the caller may access the current host many times.
255  TabContentsWrapper* cur_;
256};
257
258#endif  // CHROME_BROWSER_UI_BROWSER_LIST_H_
259