Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(547)

Side by Side Diff: chrome/browser/sessions/tab_restore_service_helper.h

Issue 10989027: Split TabRestoreService into InMemoryTRS and PersistentTRS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Scott's comments Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_H_ 5 #ifndef CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_HELPER_H_
6 #define CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_H_ 6 #define CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_HELPER_H_
7 7
8 #include <list>
9 #include <set> 8 #include <set>
10 #include <vector>
11 9
12 #include "base/gtest_prod_util.h" 10 #include "base/basictypes.h"
13 #include "base/observer_list.h" 11 #include "base/observer_list.h"
14 #include "base/time.h" 12 #include "base/time.h"
15 #include "chrome/browser/sessions/base_session_service.h"
16 #include "chrome/browser/sessions/session_id.h" 13 #include "chrome/browser/sessions/session_id.h"
17 #include "chrome/browser/sessions/session_types.h" 14 #include "chrome/browser/sessions/session_types.h"
18 #include "content/public/browser/session_storage_namespace.h" 15 #include "chrome/browser/sessions/tab_restore_service.h"
19 #include "webkit/glue/window_open_disposition.h"
20 16
21 class Profile; 17 class Profile;
18 class TabRestoreService;
22 class TabRestoreServiceDelegate; 19 class TabRestoreServiceDelegate;
23 class TabRestoreServiceObserver; 20 class TabRestoreServiceObserver;
24 struct SessionWindow; 21 class TimeFactory;
25 22
26 namespace content { 23 namespace content {
27 class NavigationController; 24 class NavigationController;
28 class SessionStorageNamespace;
29 class WebContents; 25 class WebContents;
30 } 26 }
31 27
32 // TabRestoreService is responsible for maintaining the most recently closed 28 // Helper class used to implement InMemoryTabRestoreService and
33 // tabs and windows. When a tab is closed 29 // PersistentTabRestoreService. See tab_restore_service.h for method-level
34 // TabRestoreService::CreateHistoricalTab is invoked and a Tab is created to 30 // comments.
35 // represent the tab. Similarly, when a browser is closed, BrowserClosing is 31 class TabRestoreServiceHelper {
36 // invoked and a Window is created to represent the window.
37 //
38 // To restore a tab/window from the TabRestoreService invoke RestoreEntryById
39 // or RestoreMostRecentEntry.
40 //
41 // To listen for changes to the set of entries managed by the TabRestoreService
42 // add an observer.
43 class TabRestoreService : public BaseSessionService {
44 public: 32 public:
45 // Interface used to allow the test to provide a custom time. 33 typedef TabRestoreService::Entries Entries;
46 class TimeFactory { 34 typedef TabRestoreService::Entry Entry;
35 typedef TabRestoreService::Tab Tab;
36 typedef TabRestoreService::TimeFactory TimeFactory;
37 typedef TabRestoreService::Window Window;
38
39 // Provides a way to the client to add some behavior to the tab restore
sky 2012/10/25 00:45:44 to -> for remove some
Philippe 2012/10/25 15:37:07 Done.
40 // service helper (e.g. implementing tabs persistence).
41 class Observer {
47 public: 42 public:
48 virtual ~TimeFactory(); 43 virtual ~Observer();
sky 2012/10/25 00:45:44 Move this to protected section since you don't del
Philippe 2012/10/25 15:37:07 Good point.
49 virtual base::Time TimeNow() = 0; 44
45 virtual void OnClearEntries();
sky 2012/10/25 00:45:44 Can you better document when these are invoked. Ad
Philippe 2012/10/25 15:37:07 Done. These methods are actually not called at so
sky 2012/10/25 16:21:01 If that is the case can we nuke this entirely and
46
47 virtual void OnRestoreEntryById(SessionID::id_type id,
48 Entries::const_iterator entry_iterator);
49 virtual void OnAddEntry();
50 }; 50 };
51 51
52 // The type of entry. 52 // Max number of entries we'll keep around.
53 enum Type { 53 static const size_t kMaxEntries;
54 TAB,
55 WINDOW
56 };
57
58 struct Entry {
59 Entry();
60 explicit Entry(Type type);
61 virtual ~Entry();
62
63 // Unique id for this entry. The id is guaranteed to be unique for a
64 // session.
65 SessionID::id_type id;
66
67 // The type of the entry.
68 Type type;
69
70 // The time when the window or tab was closed.
71 base::Time timestamp;
72
73 // Is this entry from the last session? This is set to true for entries that
74 // were closed during the last session, and false for entries that were
75 // closed during this session.
76 bool from_last_session;
77 };
78
79 // Represents a previously open tab.
80 struct Tab : public Entry {
81 Tab();
82 virtual ~Tab();
83
84 bool has_browser() const { return browser_id > 0; }
85
86 // The navigations.
87 std::vector<TabNavigation> navigations;
88
89 // Index of the selected navigation in navigations.
90 int current_navigation_index;
91
92 // The ID of the browser to which this tab belonged, so it can be restored
93 // there. May be 0 (an invalid SessionID) when restoring an entire session.
94 SessionID::id_type browser_id;
95
96 // Index within the tab strip. May be -1 for an unknown index.
97 int tabstrip_index;
98
99 // True if the tab was pinned.
100 bool pinned;
101
102 // If non-empty gives the id of the extension for the tab.
103 std::string extension_app_id;
104
105 // The associated session storage namespace (if any).
106 scoped_refptr<content::SessionStorageNamespace> session_storage_namespace;
107
108 // The user agent override used for the tab's navigations (if applicable).
109 std::string user_agent_override;
110 };
111
112 // Represents a previously open window.
113 struct Window : public Entry {
114 Window();
115 virtual ~Window();
116
117 // The tabs that comprised the window, in order.
118 std::vector<Tab> tabs;
119
120 // Index of the selected tab.
121 int selected_tab_index;
122
123 // If an application window, the name of the app.
124 std::string app_name;
125 };
126
127 typedef std::list<Entry*> Entries;
128 54
129 // Creates a new TabRestoreService and provides an object that provides the 55 // Creates a new TabRestoreService and provides an object that provides the
130 // current time. The TabRestoreService does not take ownership of the 56 // current time. The TabRestoreService does not take ownership of
131 // |time_factory_|. 57 // |time_factory_| and |observer|. Note that |observer| can also be NULL.
132 TabRestoreService(Profile* profile, TimeFactory* time_factory_ = NULL); 58 TabRestoreServiceHelper(TabRestoreService* tab_restore_service,
59 Observer* observer,
60 Profile* profile,
61 TimeFactory* time_factory);
133 62
134 virtual ~TabRestoreService(); 63 ~TabRestoreServiceHelper();
135 64
136 // Adds/removes an observer. TabRestoreService does not take ownership of 65 // Helper methods used to implement TabRestoreService.
137 // the observer.
138 void AddObserver(TabRestoreServiceObserver* observer); 66 void AddObserver(TabRestoreServiceObserver* observer);
139 void RemoveObserver(TabRestoreServiceObserver* observer); 67 void RemoveObserver(TabRestoreServiceObserver* observer);
140
141 // Creates a Tab to represent |contents| and notifies observers the list of
142 // entries has changed.
143 void CreateHistoricalTab(content::WebContents* contents, int index); 68 void CreateHistoricalTab(content::WebContents* contents, int index);
144
145 // Invoked when a browser is closing. If |delegate| is a tabbed browser with
146 // at least one tab, a Window is created, added to entries and observers are
147 // notified.
148 void BrowserClosing(TabRestoreServiceDelegate* delegate); 69 void BrowserClosing(TabRestoreServiceDelegate* delegate);
149
150 // Invoked when the browser is done closing.
151 void BrowserClosed(TabRestoreServiceDelegate* delegate); 70 void BrowserClosed(TabRestoreServiceDelegate* delegate);
152
153 // Removes all entries from the list and notifies observers the list
154 // of tabs has changed.
155 void ClearEntries(); 71 void ClearEntries();
156 72 const Entries& entries() const;
157 // Returns the entries, ordered with most recently closed entries at the
158 // front.
159 virtual const Entries& entries() const;
160
161 // Restores the most recently closed entry. Does nothing if there are no
162 // entries to restore. If the most recently restored entry is a tab, it is
163 // added to |delegate|.
164 void RestoreMostRecentEntry(TabRestoreServiceDelegate* delegate); 73 void RestoreMostRecentEntry(TabRestoreServiceDelegate* delegate);
165
166 // Removes the Tab with id |id| from the list and returns it; ownership is
167 // passed to the caller.
168 Tab* RemoveTabEntryById(SessionID::id_type id); 74 Tab* RemoveTabEntryById(SessionID::id_type id);
169
170 // Restores an entry by id. If there is no entry with an id matching |id|,
171 // this does nothing. If |delegate| is NULL, this creates a new window for the
172 // entry. |disposition| is respected, but the attributes (tabstrip index,
173 // browser window) of the tab when it was closed will be respected if
174 // disposition is UNKNOWN.
175 void RestoreEntryById(TabRestoreServiceDelegate* delegate, 75 void RestoreEntryById(TabRestoreServiceDelegate* delegate,
176 SessionID::id_type id, 76 SessionID::id_type id,
177 WindowOpenDisposition disposition); 77 WindowOpenDisposition disposition);
178 78
179 // Loads the tabs and previous session. This does nothing if the tabs
180 // from the previous session have already been loaded.
181 void LoadTabsFromLastSession();
182
183 // Returns true if the tab entries have been loaded.
184 bool IsLoaded() const;
185
186 // Max number of entries we'll keep around.
187 static const size_t kMaxEntries;
188
189 // Creates and add entries to |entries| for each of the windows in |windows|.
190 void CreateEntriesFromWindows(std::vector<SessionWindow*>* windows,
191 std::vector<Entry*>* entries);
192
193 protected:
194 // ProfileKeyedService:
195 virtual void Shutdown() OVERRIDE;
196
197 // BaseSessionService:
198 virtual void Save() OVERRIDE;
199
200 private:
201 friend class TabRestoreServiceTest;
202 FRIEND_TEST_ALL_PREFIXES(TabRestoreServiceTest, PruneEntries);
203 FRIEND_TEST_ALL_PREFIXES(TabRestoreServiceTest, PruneIsCalled);
204
205 // Used to indicate what has loaded.
206 enum LoadState {
207 // Indicates we haven't loaded anything.
208 NOT_LOADED = 1 << 0,
209
210 // Indicates we've asked for the last sessions and tabs but haven't gotten
211 // the result back yet.
212 LOADING = 1 << 2,
213
214 // Indicates we finished loading the last tabs (but not necessarily the
215 // last session).
216 LOADED_LAST_TABS = 1 << 3,
217
218 // Indicates we finished loading the last session (but not necessarily the
219 // last tabs).
220 LOADED_LAST_SESSION = 1 << 4
221 };
222
223 // Populates the tab's navigations from the NavigationController, and its
224 // browser_id and pinned state from the browser.
225 void PopulateTab(Tab* tab,
226 int index,
227 TabRestoreServiceDelegate* delegate,
228 content::NavigationController* controller);
229
230 // Notifies observers the tabs have changed. 79 // Notifies observers the tabs have changed.
231 void NotifyTabsChanged(); 80 void NotifyTabsChanged();
232 81
233 // Adds |entry| to the list of entries and takes ownership. If |prune| is true 82 // Adds |entry| to the list of entries and takes ownership. If |prune| is true
234 // |PruneAndNotify| is invoked. If |to_front| is true the entry is added to 83 // |PruneAndNotify| is invoked. If |to_front| is true the entry is added to
235 // the front, otherwise the back. Normal closes go to the front, but 84 // the front, otherwise the back. Normal closes go to the front, but
236 // tab/window closes from the previous session are added to the back. 85 // tab/window closes from the previous session are added to the back.
237 void AddEntry(Entry* entry, bool prune, bool to_front); 86 void AddEntry(Entry* entry, bool prune, bool to_front);
238 87
239 // Prunes entries_ to contain only kMaxEntries, and removes uninteresting 88 // Prunes |entries_| to contain only kMaxEntries, and removes uninteresting
240 // entries. 89 // entries.
241 void PruneEntries(); 90 void PruneEntries();
242 91
243 // Returns an iterator into entries_ whose id matches |id|. If |id| identifies 92 // Returns an iterator into |entries_| whose id matches |id|. If |id|
244 // a Window, then its iterator position will be returned. If it identifies a 93 // identifies a Window, then its iterator position will be returned. If it
245 // tab, then the iterator position of the Window in which the Tab resides is 94 // identifies a tab, then the iterator position of the Window in which the Tab
246 // returned. 95 // resides is returned.
247 Entries::iterator GetEntryIteratorById(SessionID::id_type id); 96 Entries::iterator GetEntryIteratorById(SessionID::id_type id);
248 97
249 // Schedules the commands for a window close. 98 // Calls either ValidateTab or ValidateWindow as appropriate.
250 void ScheduleCommandsForWindow(const Window& window); 99 static bool ValidateEntry(Entry* entry);
251 100
252 // Schedules the commands for a tab close. |selected_index| gives the 101 private:
253 // index of the selected navigation. 102 friend class PersistentTabRestoreService;
254 void ScheduleCommandsForTab(const Tab& tab, int selected_index);
255 103
256 // Creates a window close command. 104 // Populates the tab's navigations from the NavigationController, and its
257 SessionCommand* CreateWindowCommand(SessionID::id_type id, 105 // browser_id and pinned state from the browser.
258 int selected_tab_index, 106 void PopulateTab(Tab* tab,
259 int num_tabs, 107 int index,
260 base::Time timestamp); 108 TabRestoreServiceDelegate* delegate,
261 109 content::NavigationController* controller);
262 // Creates a tab close command.
263 SessionCommand* CreateSelectedNavigationInTabCommand(
264 SessionID::id_type tab_id,
265 int32 index,
266 base::Time timestamp);
267
268 // Creates a restore command.
269 SessionCommand* CreateRestoredEntryCommand(SessionID::id_type entry_id);
270
271 // Returns the index to persist as the selected index. This is the same
272 // as |tab.current_navigation_index| unless the entry at
273 // |tab.current_navigation_index| shouldn't be persisted. Returns -1 if
274 // no valid navigation to persist.
275 int GetSelectedNavigationIndexToPersist(const Tab& tab);
276
277 // Invoked when we've loaded the session commands that identify the
278 // previously closed tabs. This creates entries, adds them to
279 // staging_entries_, and invokes LoadState.
280 void OnGotLastSessionCommands(
281 Handle handle,
282 scoped_refptr<InternalGetCommandsRequest> request);
283
284 // Populates |loaded_entries| with Entries from |request|.
285 void CreateEntriesFromCommands(
286 scoped_refptr<InternalGetCommandsRequest> request,
287 std::vector<Entry*>* loaded_entries);
288 110
289 // This is a helper function for RestoreEntryById() for restoring a single 111 // This is a helper function for RestoreEntryById() for restoring a single
290 // tab. If |delegate| is NULL, this creates a new window for the entry. This 112 // tab. If |delegate| is NULL, this creates a new window for the entry. This
291 // returns the TabRestoreServiceDelegate into which the tab was restored. 113 // returns the TabRestoreServiceDelegate into which the tab was restored.
292 // |disposition| will be respected, but if it is UNKNOWN then the tab's 114 // |disposition| will be respected, but if it is UNKNOWN then the tab's
293 // original attributes will be respected instead. 115 // original attributes will be respected instead.
294 TabRestoreServiceDelegate* RestoreTab(const Tab& tab, 116 TabRestoreServiceDelegate* RestoreTab(const Tab& tab,
295 TabRestoreServiceDelegate* delegate, 117 TabRestoreServiceDelegate* delegate,
296 WindowOpenDisposition disposition); 118 WindowOpenDisposition disposition);
297 119
298 // Returns true if |tab| has more than one navigation. If |tab| has more 120 // Returns true if |tab| has more than one navigation. If |tab| has more
299 // than one navigation |tab->current_navigation_index| is constrained based 121 // than one navigation |tab->current_navigation_index| is constrained based
300 // on the number of navigations. 122 // on the number of navigations.
301 static bool ValidateTab(Tab* tab); 123 static bool ValidateTab(Tab* tab);
302 124
303 // Validates all the tabs in a window, plus the window's active tab index. 125 // Validates all the tabs in a window, plus the window's active tab index.
304 static bool ValidateWindow(Window* window); 126 static bool ValidateWindow(Window* window);
305 127
306 // Calls either ValidateTab or ValidateWindow as appropriate.
307 static bool ValidateEntry(Entry* entry);
308
309 // Returns true if |tab| is one we care about restoring. 128 // Returns true if |tab| is one we care about restoring.
310 static bool IsTabInteresting(const Tab* tab); 129 static bool IsTabInteresting(const Tab* tab);
311 130
312 // Checks whether |window| is interesting --- if it only contains a single, 131 // Checks whether |window| is interesting --- if it only contains a single,
313 // uninteresting tab, it's not interesting. 132 // uninteresting tab, it's not interesting.
314 static bool IsWindowInteresting(const Window* window); 133 static bool IsWindowInteresting(const Window* window);
315 134
316 // Validates and checks |entry| for interesting. 135 // Validates and checks |entry| for interesting.
317 static bool FilterEntry(Entry* entry); 136 static bool FilterEntry(Entry* entry);
318 137
319 // Validates all entries in |entries|, deleting any with no navigations.
320 // This also deletes any entries beyond the max number of entries we can
321 // hold.
322 void ValidateAndDeleteEmptyEntries(std::vector<Entry*>* entries);
323
324 // Finds tab entries with the old browser_id and sets it to the new one. 138 // Finds tab entries with the old browser_id and sets it to the new one.
325 void UpdateTabBrowserIDs(SessionID::id_type old_id, 139 void UpdateTabBrowserIDs(SessionID::id_type old_id,
326 SessionID::id_type new_id); 140 SessionID::id_type new_id);
327 141
328 // Callback from SessionService when we've received the windows from the
329 // previous session. This creates and add entries to |staging_entries_|
330 // and invokes LoadStateChanged. |ignored_active_window| is ignored because
331 // we don't need to restore activation.
332 void OnGotPreviousSession(Handle handle,
333 std::vector<SessionWindow*>* windows,
334 SessionID::id_type ignored_active_window);
335
336 // Converts a SessionWindow into a Window, returning true on success. We use 0
337 // as the timestamp here since we do not know when the window/tab was closed.
338 bool ConvertSessionWindowToWindow(
339 SessionWindow* session_window,
340 Window* window);
341
342 // Invoked when previous tabs or session is loaded. If both have finished
343 // loading the entries in staging_entries_ are added to entries_ and
344 // observers are notified.
345 void LoadStateChanged();
346
347 // Gets the current time. This uses the time_factory_ if there is one. 142 // Gets the current time. This uses the time_factory_ if there is one.
348 base::Time TimeNow() const; 143 base::Time TimeNow() const;
349 144
145 TabRestoreService* const tab_restore_service_;
146
147 Observer* const observer_;
148
149 Profile* const profile_;
150
350 // Set of entries. They are ordered from most to least recent. 151 // Set of entries. They are ordered from most to least recent.
351 Entries entries_; 152 Entries entries_;
352 153
353 // Whether we've loaded the last session.
354 int load_state_;
355
356 // Are we restoring a tab? If this is true we ignore requests to create a 154 // Are we restoring a tab? If this is true we ignore requests to create a
357 // historical tab. 155 // historical tab.
358 bool restoring_; 156 bool restoring_;
359 157
360 // The number of entries to write.
361 int entries_to_write_;
362
363 // Number of entries we've written.
364 int entries_written_;
365
366 ObserverList<TabRestoreServiceObserver> observer_list_; 158 ObserverList<TabRestoreServiceObserver> observer_list_;
367 159
368 // Set of delegates that we've received a BrowserClosing method for but no 160 // Set of delegates that we've received a BrowserClosing method for but no
369 // corresponding BrowserClosed. We cache the set of delegates closing to 161 // corresponding BrowserClosed. We cache the set of delegates closing to
370 // avoid creating historical tabs for them. 162 // avoid creating historical tabs for them.
371 std::set<TabRestoreServiceDelegate*> closing_delegates_; 163 std::set<TabRestoreServiceDelegate*> closing_delegates_;
372 164
373 // Used when loading open tabs/session when recovering from a crash. 165 TimeFactory* const time_factory_;
374 CancelableRequestConsumer crash_consumer_;
375 166
376 // Used when loading previous tabs/session. 167 DISALLOW_COPY_AND_ASSIGN(TabRestoreServiceHelper);
377 CancelableRequestConsumer load_consumer_;
378
379 // Results from previously closed tabs/sessions is first added here. When
380 // the results from both us and the session restore service have finished
381 // loading LoadStateChanged is invoked, which adds these entries to
382 // entries_.
383 std::vector<Entry*> staging_entries_;
384
385 TimeFactory* time_factory_;
386
387 DISALLOW_COPY_AND_ASSIGN(TabRestoreService);
388 }; 168 };
389 169
390 #endif // CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_H_ 170 #endif // CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_HELPER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698