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

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

Issue 10989027: Split TabRestoreService into InMemoryTRS and PersistentTRS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix build on Mac (not tested locally) Created 8 years, 2 months 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_IN_MEMORY_TAB_RESTORE_SERVICE_H_
6 #define CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_H_ 6 #define CHROME_BROWSER_SESSIONS_IN_MEMORY_TAB_RESTORE_SERVICE_H_
7 7
8 #include <list> 8 #include <map>
9 #include <set> 9 #include <set>
10 #include <vector>
11 10
12 #include "base/gtest_prod_util.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;
22 class TabRestoreServiceDelegate; 18 class TabRestoreServiceDelegate;
23 class TabRestoreServiceObserver; 19 class TabRestoreServiceObserver;
24 struct SessionWindow;
25 20
26 namespace content { 21 namespace content {
27 class NavigationController; 22 class NavigationController;
28 class SessionStorageNamespace;
29 class WebContents; 23 class WebContents;
30 } 24 }
31 25
32 // TabRestoreService is responsible for maintaining the most recently closed 26 // Tab restore service that doesn't persist tabs on disk. This is mainly used on
sky 2012/10/22 13:51:35 removed mainly.
Philippe 2012/10/23 15:07:36 Done.
33 // tabs and windows. When a tab is closed 27 // Android where tabs persistence is implemented on the application side in
34 // TabRestoreService::CreateHistoricalTab is invoked and a Tab is created to 28 // Java. Other platforms should use PersistentTabRestoreService which can be
35 // represent the tab. Similarly, when a browser is closed, BrowserClosing is 29 // instantiated through the TabRestoreServiceFactory.
36 // invoked and a Window is created to represent the window. 30 class InMemoryTabRestoreService : public TabRestoreService {
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: 31 public:
45 // Interface used to allow the test to provide a custom time. 32 enum {
46 class TimeFactory { 33 // Max number of entries we'll keep around.
47 public: 34 kMaxEntries = 25,
sky 2012/10/22 13:51:35 Why is this in an enum and not a static const?
Philippe 2012/10/23 15:07:36 Done. This moved to TabRestoreServiceHelper (as a
48 virtual ~TimeFactory();
49 virtual base::Time TimeNow() = 0;
50 }; 35 };
51 36
52 // The type of entry.
53 enum Type {
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
129 // Creates a new TabRestoreService and provides an object that provides the 37 // Creates a new TabRestoreService and provides an object that provides the
130 // current time. The TabRestoreService does not take ownership of the 38 // current time. The TabRestoreService does not take ownership of the
131 // |time_factory_|. 39 // |time_factory_|.
132 TabRestoreService(Profile* profile, TimeFactory* time_factory_ = NULL); 40 InMemoryTabRestoreService(Profile* profile,
41 TimeFactory* time_factory_ = NULL);
133 42
134 virtual ~TabRestoreService(); 43 virtual ~InMemoryTabRestoreService();
135 44
136 // Adds/removes an observer. TabRestoreService does not take ownership of 45 // TabRestoreService:
137 // the observer. 46 virtual void AddObserver(TabRestoreServiceObserver* observer) OVERRIDE;
138 void AddObserver(TabRestoreServiceObserver* observer); 47 virtual void RemoveObserver(TabRestoreServiceObserver* observer) OVERRIDE;
139 void RemoveObserver(TabRestoreServiceObserver* observer); 48 virtual void CreateHistoricalTab(content::WebContents* contents,
140 49 int index) OVERRIDE;
141 // Creates a Tab to represent |contents| and notifies observers the list of 50 virtual void BrowserClosing(TabRestoreServiceDelegate* delegate) OVERRIDE;
142 // entries has changed. 51 virtual void BrowserClosed(TabRestoreServiceDelegate* delegate) OVERRIDE;
143 void CreateHistoricalTab(content::WebContents* contents, int index); 52 virtual void ClearEntries() OVERRIDE;
144 53 virtual const Entries& entries() const OVERRIDE;
145 // Invoked when a browser is closing. If |delegate| is a tabbed browser with 54 virtual void RestoreMostRecentEntry(
146 // at least one tab, a Window is created, added to entries and observers are 55 TabRestoreServiceDelegate* delegate) OVERRIDE;
147 // notified. 56 virtual Tab* RemoveTabEntryById(SessionID::id_type id) OVERRIDE;
148 void BrowserClosing(TabRestoreServiceDelegate* delegate); 57 virtual void RestoreEntryById(TabRestoreServiceDelegate* delegate,
149 58 SessionID::id_type id,
150 // Invoked when the browser is done closing. 59 WindowOpenDisposition disposition) OVERRIDE;
151 void BrowserClosed(TabRestoreServiceDelegate* delegate); 60 virtual void LoadTabsFromLastSession() OVERRIDE;
152 61 virtual bool IsLoaded() const OVERRIDE;
153 // Removes all entries from the list and notifies observers the list 62 virtual void DeleteLastSession() OVERRIDE;
154 // of tabs has changed. 63 virtual void Shutdown() OVERRIDE;
155 void ClearEntries();
156
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);
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);
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,
176 SessionID::id_type id,
177 WindowOpenDisposition disposition);
178
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 64
193 protected: 65 protected:
194 // ProfileKeyedService: 66 typedef std::map<SessionID::id_type, TabRestoreService::Entry*> IDToEntry;
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 67
230 // Notifies observers the tabs have changed. 68 // Notifies observers the tabs have changed.
231 void NotifyTabsChanged(); 69 void NotifyTabsChanged();
232 70
233 // Adds |entry| to the list of entries and takes ownership. If |prune| is true 71 // 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 72 // |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 73 // 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. 74 // tab/window closes from the previous session are added to the back.
237 void AddEntry(Entry* entry, bool prune, bool to_front); 75 void AddEntry(Entry* entry, bool prune, bool to_front);
238 76
239 // Prunes entries_ to contain only kMaxEntries, and removes uninteresting 77 // Prunes entries_ to contain only kMaxEntries, and removes uninteresting
240 // entries. 78 // entries.
241 void PruneEntries(); 79 void PruneEntries();
242 80
243 // Returns an iterator into entries_ whose id matches |id|. If |id| identifies 81 // Returns an iterator into entries_ whose id matches |id|. If |id| identifies
244 // a Window, then its iterator position will be returned. If it identifies a 82 // a Window, then its iterator position will be returned. If it identifies a
245 // tab, then the iterator position of the Window in which the Tab resides is 83 // tab, then the iterator position of the Window in which the Tab resides is
246 // returned. 84 // returned.
247 Entries::iterator GetEntryIteratorById(SessionID::id_type id); 85 Entries::iterator GetEntryIteratorById(SessionID::id_type id);
248 86
249 // Schedules the commands for a window close. 87 // Calls either ValidateTab or ValidateWindow as appropriate.
250 void ScheduleCommandsForWindow(const Window& window); 88 static bool ValidateEntry(Entry* entry);
251 89
252 // Schedules the commands for a tab close. |selected_index| gives the 90 // Methods than can be overridden by subclasses to add some behavior (e.g.
253 // index of the selected navigation. 91 // persistence).
254 void ScheduleCommandsForTab(const Tab& tab, int selected_index); 92 virtual void OnClearEntries();
93 virtual void OnRestoreEntryById(SessionID::id_type id,
94 Entries::const_iterator entry_iterator);
95 virtual void OnAddEntry();
255 96
256 // Creates a window close command. 97 private:
257 SessionCommand* CreateWindowCommand(SessionID::id_type id, 98 friend class TabRestoreServiceTest;
258 int selected_tab_index,
259 int num_tabs,
260 base::Time timestamp);
261 99
262 // Creates a tab close command. 100 // Populates the tab's navigations from the NavigationController, and its
263 SessionCommand* CreateSelectedNavigationInTabCommand( 101 // browser_id and pinned state from the browser.
264 SessionID::id_type tab_id, 102 void PopulateTab(Tab* tab,
265 int32 index, 103 int index,
266 base::Time timestamp); 104 TabRestoreServiceDelegate* delegate,
267 105 content::NavigationController* controller);
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 106
289 // This is a helper function for RestoreEntryById() for restoring a single 107 // 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 108 // tab. If |delegate| is NULL, this creates a new window for the entry. This
291 // returns the TabRestoreServiceDelegate into which the tab was restored. 109 // returns the TabRestoreServiceDelegate into which the tab was restored.
292 // |disposition| will be respected, but if it is UNKNOWN then the tab's 110 // |disposition| will be respected, but if it is UNKNOWN then the tab's
293 // original attributes will be respected instead. 111 // original attributes will be respected instead.
294 TabRestoreServiceDelegate* RestoreTab(const Tab& tab, 112 TabRestoreServiceDelegate* RestoreTab(const Tab& tab,
295 TabRestoreServiceDelegate* delegate, 113 TabRestoreServiceDelegate* delegate,
296 WindowOpenDisposition disposition); 114 WindowOpenDisposition disposition);
297 115
298 // Returns true if |tab| has more than one navigation. If |tab| has more 116 // Returns true if |tab| has more than one navigation. If |tab| has more
299 // than one navigation |tab->current_navigation_index| is constrained based 117 // than one navigation |tab->current_navigation_index| is constrained based
300 // on the number of navigations. 118 // on the number of navigations.
301 static bool ValidateTab(Tab* tab); 119 static bool ValidateTab(Tab* tab);
302 120
303 // Validates all the tabs in a window, plus the window's active tab index. 121 // Validates all the tabs in a window, plus the window's active tab index.
304 static bool ValidateWindow(Window* window); 122 static bool ValidateWindow(Window* window);
305 123
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. 124 // Returns true if |tab| is one we care about restoring.
310 static bool IsTabInteresting(const Tab* tab); 125 static bool IsTabInteresting(const Tab* tab);
311 126
312 // Checks whether |window| is interesting --- if it only contains a single, 127 // Checks whether |window| is interesting --- if it only contains a single,
313 // uninteresting tab, it's not interesting. 128 // uninteresting tab, it's not interesting.
314 static bool IsWindowInteresting(const Window* window); 129 static bool IsWindowInteresting(const Window* window);
315 130
316 // Validates and checks |entry| for interesting. 131 // Validates and checks |entry| for interesting.
317 static bool FilterEntry(Entry* entry); 132 static bool FilterEntry(Entry* entry);
318 133
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. 134 // Finds tab entries with the old browser_id and sets it to the new one.
325 void UpdateTabBrowserIDs(SessionID::id_type old_id, 135 void UpdateTabBrowserIDs(SessionID::id_type old_id,
326 SessionID::id_type new_id); 136 SessionID::id_type new_id);
327 137
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. 138 // Gets the current time. This uses the time_factory_ if there is one.
348 base::Time TimeNow() const; 139 base::Time TimeNow() const;
349 140
141 Profile* const profile_;
142
350 // Set of entries. They are ordered from most to least recent. 143 // Set of entries. They are ordered from most to least recent.
351 Entries entries_; 144 Entries entries_;
352 145
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 146 // Are we restoring a tab? If this is true we ignore requests to create a
357 // historical tab. 147 // historical tab.
358 bool restoring_; 148 bool restoring_;
359 149
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_; 150 ObserverList<TabRestoreServiceObserver> observer_list_;
367 151
368 // Set of delegates that we've received a BrowserClosing method for but no 152 // Set of delegates that we've received a BrowserClosing method for but no
369 // corresponding BrowserClosed. We cache the set of delegates closing to 153 // corresponding BrowserClosed. We cache the set of delegates closing to
370 // avoid creating historical tabs for them. 154 // avoid creating historical tabs for them.
371 std::set<TabRestoreServiceDelegate*> closing_delegates_; 155 std::set<TabRestoreServiceDelegate*> closing_delegates_;
372 156
373 // Used when loading open tabs/session when recovering from a crash. 157 TimeFactory* const time_factory_;
374 CancelableRequestConsumer crash_consumer_;
375 158
376 // Used when loading previous tabs/session. 159 DISALLOW_COPY_AND_ASSIGN(InMemoryTabRestoreService);
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 }; 160 };
389 161
390 #endif // CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_H_ 162 #endif // CHROME_BROWSER_SESSIONS_IN_MEMORY_TAB_RESTORE_SERVICE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698