summaryrefslogtreecommitdiffstats
path: root/chrome/browser/browser_list.h
blob: b690ba71e058e4cce41a68a740193a155ccd59e7 (plain)
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
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef CHROME_BROWSER_BROWSER_LIST_H__
#define CHROME_BROWSER_BROWSER_LIST_H__

#include <algorithm>
#include <vector>

#include "chrome/browser/browser.h"

namespace ChromeViews {
class Window;
};
class WebContents;

// Stores a list of all Browser objects.
class BrowserList {
 public:
  typedef std::vector<Browser*> list_type;
  typedef list_type::iterator iterator;
  typedef list_type::const_iterator const_iterator;
  typedef list_type::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 before a browser is removed from the list
    virtual void OnBrowserRemoving(const Browser* browser) = 0;
  };

  // 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);

  // Adds and removes non-browser dependent windows. These are windows that are
  // top level, but whose lifetime is associated wtih the existence of at least
  // one active Browser. When the last Browser is destroyed, all open dependent
  // windows are closed.
  static void AddDependentWindow(ChromeViews::Window* window);
  static void RemoveDependentWindow(ChromeViews::Window* window);

  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.
  static Browser* GetLastActive();

  // Find an existing browser window with the provided type. If the last active
  // has the right type, it is returned. Otherwise, the next available browser
  // is returned. Returns NULL if no such browser currently exists.
  static Browser* FindBrowserWithType(Profile* p, BrowserType::Type t);

  // Closes all browsers. If use_post is true the windows are closed by way of
  // posting a WM_CLOSE message, otherwise the windows are closed directly. In
  // almost all cases you'll want to use true, the one exception is ending
  // the session. use_post should only be false when invoked from end session.
  static void CloseAllBrowsers(bool use_post);

  // Returns true if there is at least one Browser with the specified profile.
  static bool HasBrowserWithProfile(Profile* profile);

  // Set whether the last active browser should be modal or not, if
  // |is_app_modal| is true, the last active browser window will be activated
  // and brought to the front whenever the user attempts to activate any other
  // browser window. If |is_app_modal| is false all window activation works as
  // normal. SetIsShowingAppModalDialog should not be called with |is_app_modal|
  // set to true if the last active browser is already modal.
  //
  // TODO(devint): http://b/issue?id=1123402 Application modal dialogs aren't
  // selected, just the last active browser. Therefore, to properly use this
  // function we have to set the modal dialog as a child of a browser,
  // activate that browser window, call SetIsShowingAppModalDialog(true), and
  // implement the modal dialog as window modal to its parent. This still isn't
  // perfect,however, because it just assures that the browser is activated, and
  // the dialog will be on top of that browser, but inactive. It will activate
  // if the users attempts to interact with its parent window (the browser).
  // Ideally we should activate the modal dialog, not just its parent browser.
  //
  // There is probably a less clunky way overall to implement application
  // modality. Currently, if IsShowingAppModalDialog returns true, we handle
  // messages right before the browser activates, and activate whatever
  // GetLastActive() returns instead of whatever was trying to be activated.
  // It'd be better if we could use built in OS modality handling to deal with
  // this, but Windows only supports system modal or parent window modal.
  static void SetIsShowingAppModalDialog(bool is_app_modal);

  // True if the last active browser is application modal, false otherwise. See
  // SetIsShowingAppModalDialog for more details.
  static bool IsShowingAppModalDialog();

  static const_iterator begin() {
    return browsers_.begin();
  }

  static const_iterator end() {
    return browsers_.end();
  }

  static size_t size() {
    return browsers_.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() {
    return last_active_browsers_.rbegin();
  }

  static const_reverse_iterator end_last_active() {
    return last_active_browsers_.rend();
  }

  // Return the number of browsers with the following profile which are
  // currently open.
  static size_t GetBrowserCount(Profile* p);

  // Return the number of browsers with the following profile and type which are
  // currently open.
  static size_t GetBrowserCountForType(Profile* p, BrowserType::Type type);

  // Returns true if at least one off the record session is active.
  static bool IsOffTheRecordSessionActive();

 private:
  // Closes all registered dependent windows.
  static void CloseAllDependentWindows();

  // Helper method to remove a browser instance from a list of browsers
  static void RemoveBrowserFrom(Browser* browser, list_type* browser_list);

  static list_type browsers_;
  static std::vector<Observer*> observers_;
  static list_type last_active_browsers_;
  typedef std::vector<ChromeViews::Window*> DependentWindowList;
  static DependentWindowList dependent_windows_;

  // True if last_active_ is app modal, false otherwise.
  static bool is_app_modal_;
};


// 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 (WebContentsIterator iterator; !iterator.done(); iterator++) {
//     WebContents* cur = *iterator;
//     -or-
//     iterator->operationOnWebContents();
//     ...
//   }
class WebContentsIterator {
 public:
  WebContentsIterator();

  // Returns true if we are past the last Browser.
  bool done() const {
    return cur_ == NULL;
  }

  // Returns the current WebContents, valid as long as !Done()
  WebContents* operator->() const {
    return cur_;
  }
  WebContents* operator*() const {
    return cur_;
  }

  // Incrementing operators, valid as long as !Done()
  WebContents* operator++() { // ++preincrement
    Advance();
    return cur_;
  }
  WebContents* operator++(int) { // postincrement++
    WebContents* 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_;

  // Current WebContents, 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.
  WebContents* cur_;
};

#endif  // CHROME_BROWSER_BROWSER_LIST_H__