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. 15 class 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) OnBrowserSetLastActive(const Browser * browser)33 virtual void OnBrowserSetLastActive(const Browser* browser) {} 34 35 protected: ~Observer()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. begin()135 static const_iterator begin() { return browsers_.begin(); } end()136 static const_iterator end() { return browsers_.end(); } 137 empty()138 static bool empty() { return browsers_.empty(); } size()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. begin_last_active()145 static const_reverse_iterator begin_last_active() { 146 return last_active_browsers_.rbegin(); 147 } 148 end_last_active()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 192 class 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 // } 206 class TabContentsIterator { 207 public: 208 TabContentsIterator(); 209 210 // Returns true if we are past the last Browser. done()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() browser()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