File: browser_list.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (260 lines) | stat: -rw-r--r-- 11,083 bytes parent folder | download | duplicates (5)
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
// Copyright 2012 The Chromium Authors
// 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_

#include <stddef.h>

#include <vector>

#include "base/containers/flat_set.h"
#include "base/functional/callback_forward.h"
#include "base/functional/function_ref.h"
#include "base/lazy_instance.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/stack_allocated.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "build/build_config.h"

#if BUILDFLAG(IS_ANDROID)
#error This file should only be included on desktop.
#endif

enum class BrowserClosingStatus;

class Browser;
class Profile;

namespace base {
class FilePath;
}

class BrowserListObserver;

// Maintains a list of Browser objects.
class BrowserList {
 public:
  using BrowserSet = base::flat_set<raw_ptr<Browser, CtnExperimental>>;
  using BrowserVector = std::vector<raw_ptr<Browser, VectorExperimental>>;
  using BrowserWeakVector = std::vector<base::WeakPtr<Browser>>;
  using CloseCallback = base::RepeatingCallback<void(const base::FilePath&)>;
  using const_iterator = BrowserVector::const_iterator;
  using const_reverse_iterator = BrowserVector::const_reverse_iterator;

  struct BrowsersOrderedByActivationRange {
    const raw_ref<const BrowserList> browser_list;

    const_reverse_iterator begin() const {
      return browser_list->begin_browsers_ordered_by_activation();
    }
    const_reverse_iterator end() const {
      return browser_list->end_browsers_ordered_by_activation();
    }

   private:
    // Stack allocated only to reduce risk of out of bounds lifetime with
    // |browser_list|.
    STACK_ALLOCATED();
  };

  BrowserList(const BrowserList&) = delete;
  BrowserList& operator=(const BrowserList&) = delete;

  // Returns the last active browser for this list.
  Browser* GetLastActive() const;

  const_iterator begin() const { return browsers_.begin(); }
  const_iterator end() const { return browsers_.end(); }

  bool empty() const { return browsers_.empty(); }
  size_t size() const { return browsers_.size(); }

  Browser* get(size_t index) const { return browsers_[index]; }

  // Enumerate the current browser and the new browser in-order.
  void ForEachCurrentAndNewBrowser(
      base::FunctionRef<void(Browser*)> on_browser);

  // Enumerate the current browser in-order.
  void ForEachCurrentBrowser(base::FunctionRef<void(Browser*)> on_browser);

  // Returns iterated access to list of open browsers ordered by activation. The
  // underlying data structure is a vector and we push_back on recent access so
  // a reverse iterator gives the latest accessed browser first.
  const_reverse_iterator begin_browsers_ordered_by_activation() const {
    return browsers_ordered_by_activation_.rbegin();
  }
  const_reverse_iterator end_browsers_ordered_by_activation() const {
    return browsers_ordered_by_activation_.rend();
  }

  // Convenience method for iterating over browsers in activation order. I.e.
  // the most recently used browser will be at the front of the list.
  // Example:
  // for (Browser* browser : BrowserList::GetInstance()->OrderedByActivation())
  BrowsersOrderedByActivationRange OrderedByActivation() const {
    return {raw_ref(*this)};
  }

  // Returns the set of browsers that are currently in the closing state.
  const BrowserSet& currently_closing_browsers() const {
    return currently_closing_browsers_;
  }

  static BrowserList* GetInstance();

  // Adds or removes |browser| from the list it is associated with. 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);

  // Appends active browser windows to |browsers_ordered_by_activation_|.
  // Prepends inactive browser windows to |browsers_ordered_by_activation_|.
  static void AddBrowserToActiveList(Browser* browser);

  // Adds and removes |observer| from the observer list for all desktops.
  // Observers are responsible for making sure the notifying browser is relevant
  // to them (e.g., on the specific desktop they care about if any).
  static void AddObserver(BrowserListObserver* observer);
  static void RemoveObserver(BrowserListObserver* observer);

  // Moves all the browsers that show on workspace |new_workspace| to the end of
  // the browser list (i.e. the browsers that were "activated" most recently).
  static void MoveBrowsersInWorkspaceToFront(const std::string& new_workspace);

  // Called by Browser objects when their window is activated (focused).  This
  // allows us to determine what the last active Browser was on each desktop.
  static void SetLastActive(Browser* browser);

  // Notifies the observers when the current active browser becomes not active.
  static void NotifyBrowserNoLongerActive(Browser* browser);

  // Notifies the observers that the attempted closure of `browser` was
  // cancelled for a certain `reason`.
  static void NotifyBrowserCloseCancelled(Browser* browser,
                                          BrowserClosingStatus reason);

  // Notifies the observers when browser close was started. This may be called
  // more than once for a particular browser.
  static void NotifyBrowserCloseStarted(Browser* browser);

  // Closes all browsers for |profile| across all desktops.
  // TODO(mlerman): Move the Profile Deletion flow to use the overloaded
  // version of this method with a callback, then remove this method.
  static void CloseAllBrowsersWithProfile(Profile* profile);

  // Closes all browsers for |profile| across all desktops. Uses
  // TryToCloseBrowserList() to do the actual closing. Triggers any
  // OnBeforeUnload events unless |skip_beforeunload| is true. If all
  // OnBeforeUnload events are confirmed or |skip_beforeunload| is true,
  // |on_close_success| is called, otherwise |on_close_aborted| is called. Both
  // callbacks may be null.
  // Note that if there is any browser window that has been used before, the
  // user should always have a chance to save their work before closing windows
  // without triggering beforeunload events.
  static void CloseAllBrowsersWithProfile(Profile* profile,
                                          const CloseCallback& on_close_success,
                                          const CloseCallback& on_close_aborted,
                                          bool skip_beforeunload);

  // Similarly to CloseAllBrowsersWithProfile, but DCHECK's that profile is
  // Off-the-Record and doesn't close browsers with the original profile.
  static void CloseAllBrowsersWithIncognitoProfile(
      Profile* profile,
      const CloseCallback& on_close_success,
      const CloseCallback& on_close_aborted,
      bool skip_beforeunload);

  // Returns true if at least one off-the-record browser is active across all
  // desktops.
  static bool IsOffTheRecordBrowserActive();

  // Returns the number of active off-the-record browsers for |profile| across
  // all desktops. Note that this function does not count devtools windows
  // opened for off-the-record windows.
  static int GetOffTheRecordBrowsersActiveForProfile(Profile* profile);

  // Returns the number of active incognito browsers except devtools windows
  // across all desktops.
  static size_t GetIncognitoBrowserCount();

  // Returns the number of active guest browsers except devtools windows
  // across all desktops.
  static size_t GetGuestBrowserCount();

  // Returns true if the off-the-record browser for |profile| is in use in any
  // window across all desktops. This function considers devtools windows as
  // well.
  static bool IsOffTheRecordBrowserInUse(Profile* profile);

 private:
  BrowserList();
  ~BrowserList();

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

  // Attempts to close |browsers_to_close| while respecting OnBeforeUnload
  // events. If there are no OnBeforeUnload events to be called,
  // |on_close_success| will be called, with a parameter of |profile_path|,
  // and the Browsers will then be closed. If at least one unfired
  // OnBeforeUnload event is found, handle it with a callback to
  // PostTryToCloseBrowserWindow, which upon success will recursively call this
  // method to handle any other OnBeforeUnload events. If aborted in the
  // OnBeforeUnload event, PostTryToCloseBrowserWindow will call
  // |on_close_aborted| instead and reset all OnBeforeUnload event handlers.
  static void TryToCloseBrowserList(const BrowserWeakVector& browsers_to_close,
                                    const CloseCallback& on_close_success,
                                    const CloseCallback& on_close_aborted,
                                    const base::FilePath& profile_path,
                                    const bool skip_beforeunload);

  // Called after handling an OnBeforeUnload event. If |tab_close_confirmed| is
  // true, calls |TryToCloseBrowserList()|, passing the parameters
  // |browsers_to_close|, |on_close_success|, |on_close_aborted|, and
  // |profile_path|. Otherwise, resets all the OnBeforeUnload event handlers and
  // calls |on_close_aborted|.
  static void PostTryToCloseBrowserWindow(
      const BrowserWeakVector& browsers_to_close,
      const CloseCallback& on_close_success,
      const CloseCallback& on_close_aborted,
      const base::FilePath& profile_path,
      const bool skip_beforeunload,
      bool tab_close_confirmed);

  // A vector of the browsers in this list, in the order they were added.
  BrowserVector browsers_;
  // A vector of the browsers in this list, in reverse order of activation. I.e.
  // the most recently used browser will be at the end. Inactive browser
  // windows, (e.g., created by session restore) are inserted at the front of
  // the list.
  BrowserVector browsers_ordered_by_activation_;
  // A vector of the browsers that are currently in the closing state.
  BrowserSet currently_closing_browsers_;

  // If an observer is added while iterating over them and notifying, it should
  // not be notified as it probably already saw the Browser* being added/removed
  // in the BrowserList.
  struct ObserverListTraits : base::internal::LeakyLazyInstanceTraits<
                                  base::ObserverList<BrowserListObserver>> {
    static base::ObserverList<BrowserListObserver>* New(void* instance) {
      return new (instance) base::ObserverList<BrowserListObserver>(
          base::ObserverListPolicy::EXISTING_ONLY);
    }
  };

  // A list of observers which will be notified of every browser addition and
  // removal across all BrowserLists.
  static base::LazyInstance<base::ObserverList<BrowserListObserver>,
                            ObserverListTraits>
      observers_;

  static BrowserList* instance_;
};

#endif  // CHROME_BROWSER_UI_BROWSER_LIST_H_