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