Home | History | Annotate | Download | only in sessions
      1 // Copyright (c) 2012 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_SESSIONS_TAB_RESTORE_SERVICE_HELPER_H_
      6 #define CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_HELPER_H_
      7 
      8 #include <set>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/observer_list.h"
     13 #include "base/time/time.h"
     14 #include "chrome/browser/sessions/session_types.h"
     15 #include "chrome/browser/sessions/tab_restore_service.h"
     16 #include "chrome/browser/ui/host_desktop.h"
     17 #include "components/sessions/session_id.h"
     18 
     19 class Profile;
     20 class TabRestoreService;
     21 class TabRestoreServiceDelegate;
     22 class TabRestoreServiceObserver;
     23 class TimeFactory;
     24 
     25 namespace content {
     26 class NavigationController;
     27 class WebContents;
     28 }
     29 
     30 // Helper class used to implement InMemoryTabRestoreService and
     31 // PersistentTabRestoreService. See tab_restore_service.h for method-level
     32 // comments.
     33 class TabRestoreServiceHelper {
     34  public:
     35   typedef TabRestoreService::Entries Entries;
     36   typedef TabRestoreService::Entry Entry;
     37   typedef TabRestoreService::Tab Tab;
     38   typedef TabRestoreService::TimeFactory TimeFactory;
     39   typedef TabRestoreService::Window Window;
     40 
     41   // Provides a way for the client to add behavior to the tab restore service
     42   // helper (e.g. implementing tabs persistence).
     43   class Observer {
     44    public:
     45     // Invoked before the entries are cleared.
     46     virtual void OnClearEntries();
     47 
     48     // Invoked before the entry is restored. |entry_iterator| points to the
     49     // entry corresponding to the session identified by |id|.
     50     virtual void OnRestoreEntryById(SessionID::id_type id,
     51                                     Entries::const_iterator entry_iterator);
     52 
     53     // Invoked after an entry was added.
     54     virtual void OnAddEntry();
     55 
     56    protected:
     57     virtual ~Observer();
     58   };
     59 
     60   enum {
     61     // Max number of entries we'll keep around.
     62     kMaxEntries = 25,
     63   };
     64 
     65   // Creates a new TabRestoreServiceHelper and provides an object that provides
     66   // the current time. The TabRestoreServiceHelper does not take ownership of
     67   // |time_factory| and |observer|. Note that |observer| can also be NULL.
     68   TabRestoreServiceHelper(TabRestoreService* tab_restore_service,
     69                           Observer* observer,
     70                           Profile* profile,
     71                           TimeFactory* time_factory);
     72 
     73   ~TabRestoreServiceHelper();
     74 
     75   // Helper methods used to implement TabRestoreService.
     76   void AddObserver(TabRestoreServiceObserver* observer);
     77   void RemoveObserver(TabRestoreServiceObserver* observer);
     78   void CreateHistoricalTab(content::WebContents* contents, int index);
     79   void BrowserClosing(TabRestoreServiceDelegate* delegate);
     80   void BrowserClosed(TabRestoreServiceDelegate* delegate);
     81   void ClearEntries();
     82   const Entries& entries() const;
     83   std::vector<content::WebContents*> RestoreMostRecentEntry(
     84       TabRestoreServiceDelegate* delegate,
     85       chrome::HostDesktopType host_desktop_type);
     86   Tab* RemoveTabEntryById(SessionID::id_type id);
     87   std::vector<content::WebContents*> RestoreEntryById(
     88       TabRestoreServiceDelegate* delegate,
     89       SessionID::id_type id,
     90       chrome::HostDesktopType host_desktop_type,
     91       WindowOpenDisposition disposition);
     92 
     93   // Notifies observers the tabs have changed.
     94   void NotifyTabsChanged();
     95 
     96   // Notifies observers the service has loaded.
     97   void NotifyLoaded();
     98 
     99   // Adds |entry| to the list of entries and takes ownership. If |prune| is true
    100   // |PruneAndNotify| is invoked. If |to_front| is true the entry is added to
    101   // the front, otherwise the back. Normal closes go to the front, but
    102   // tab/window closes from the previous session are added to the back.
    103   void AddEntry(Entry* entry, bool prune, bool to_front);
    104 
    105   // Prunes |entries_| to contain only kMaxEntries, and removes uninteresting
    106   // entries.
    107   void PruneEntries();
    108 
    109   // Returns an iterator into |entries_| whose id matches |id|. If |id|
    110   // identifies a Window, then its iterator position will be returned. If it
    111   // identifies a tab, then the iterator position of the Window in which the Tab
    112   // resides is returned.
    113   Entries::iterator GetEntryIteratorById(SessionID::id_type id);
    114 
    115   // Calls either ValidateTab or ValidateWindow as appropriate.
    116   static bool ValidateEntry(Entry* entry);
    117 
    118  private:
    119   friend class PersistentTabRestoreService;
    120 
    121   // Populates the tab's navigations from the NavigationController, and its
    122   // browser_id and pinned state from the browser.
    123   void PopulateTab(Tab* tab,
    124                    int index,
    125                    TabRestoreServiceDelegate* delegate,
    126                    content::NavigationController* controller);
    127 
    128   // This is a helper function for RestoreEntryById() for restoring a single
    129   // tab. If |delegate| is NULL, this creates a new window for the entry. This
    130   // returns the TabRestoreServiceDelegate into which the tab was restored.
    131   // |disposition| will be respected, but if it is UNKNOWN then the tab's
    132   // original attributes will be respected instead. If a new browser needs to be
    133   // created for this tab, it will be created on the desktop specified by
    134   // |host_desktop_type|. If present, |contents| will be populated with the
    135   // WebContents of the restored tab.
    136   TabRestoreServiceDelegate* RestoreTab(
    137       const Tab& tab,
    138       TabRestoreServiceDelegate* delegate,
    139       chrome::HostDesktopType host_desktop_type,
    140       WindowOpenDisposition disposition,
    141       content::WebContents** contents);
    142 
    143   // Returns true if |tab| has more than one navigation. If |tab| has more
    144   // than one navigation |tab->current_navigation_index| is constrained based
    145   // on the number of navigations.
    146   static bool ValidateTab(Tab* tab);
    147 
    148   // Validates all the tabs in a window, plus the window's active tab index.
    149   static bool ValidateWindow(Window* window);
    150 
    151   // Returns true if |tab| is one we care about restoring.
    152   static bool IsTabInteresting(const Tab* tab);
    153 
    154   // Checks whether |window| is interesting --- if it only contains a single,
    155   // uninteresting tab, it's not interesting.
    156   static bool IsWindowInteresting(const Window* window);
    157 
    158   // Validates and checks |entry| for interesting.
    159   static bool FilterEntry(Entry* entry);
    160 
    161   // Finds tab entries with the old browser_id and sets it to the new one.
    162   void UpdateTabBrowserIDs(SessionID::id_type old_id,
    163                            SessionID::id_type new_id);
    164 
    165   // Gets the current time. This uses the time_factory_ if there is one.
    166   base::Time TimeNow() const;
    167 
    168   TabRestoreService* const tab_restore_service_;
    169 
    170   Observer* const observer_;
    171 
    172   Profile* const profile_;
    173 
    174   // Set of entries. They are ordered from most to least recent.
    175   Entries entries_;
    176 
    177   // Are we restoring a tab? If this is true we ignore requests to create a
    178   // historical tab.
    179   bool restoring_;
    180 
    181   ObserverList<TabRestoreServiceObserver> observer_list_;
    182 
    183   // Set of delegates that we've received a BrowserClosing method for but no
    184   // corresponding BrowserClosed. We cache the set of delegates closing to
    185   // avoid creating historical tabs for them.
    186   std::set<TabRestoreServiceDelegate*> closing_delegates_;
    187 
    188   TimeFactory* const time_factory_;
    189 
    190   DISALLOW_COPY_AND_ASSIGN(TabRestoreServiceHelper);
    191 };
    192 
    193 #endif  // CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_HELPER_H_
    194