Home | History | Annotate | Download | only in ui
      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)
     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 
    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.
    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