• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_id.h"
15 #include "chrome/browser/sessions/session_types.h"
16 #include "chrome/browser/sessions/tab_restore_service.h"
17 #include "chrome/browser/ui/host_desktop.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