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

Side by Side Diff: chrome/browser/sessions/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_TAB_RESTORE_SERVICE_H_
6 #define CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_H_ 6 #define CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_H_
7 7
8 #include <list> 8 #include <list>
9 #include <set> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/gtest_prod_util.h" 12 #include "base/memory/ref_counted.h"
13 #include "base/observer_list.h"
14 #include "base/time.h" 13 #include "base/time.h"
15 #include "chrome/browser/sessions/base_session_service.h" 14 #include "chrome/browser/profiles/profile_keyed_service.h"
16 #include "chrome/browser/sessions/session_id.h" 15 #include "chrome/browser/sessions/session_id.h"
17 #include "chrome/browser/sessions/session_types.h" 16 #include "chrome/browser/sessions/session_types.h"
18 #include "content/public/browser/session_storage_namespace.h" 17 #include "content/public/browser/session_storage_namespace.h"
19 #include "webkit/glue/window_open_disposition.h" 18 #include "webkit/glue/window_open_disposition.h"
20 19
21 class Profile;
22 class TabRestoreServiceDelegate; 20 class TabRestoreServiceDelegate;
23 class TabRestoreServiceObserver; 21 class TabRestoreServiceObserver;
24 struct SessionWindow;
25 22
26 namespace content { 23 namespace content {
27 class NavigationController;
28 class SessionStorageNamespace; 24 class SessionStorageNamespace;
29 class WebContents; 25 class WebContents;
30 } 26 }
31 27
32 // TabRestoreService is responsible for maintaining the most recently closed 28 // TabRestoreService is responsible for maintaining the most recently closed
33 // tabs and windows. When a tab is closed 29 // tabs and windows. When a tab is closed
34 // TabRestoreService::CreateHistoricalTab is invoked and a Tab is created to 30 // TabRestoreService::CreateHistoricalTab is invoked and a Tab is created to
35 // represent the tab. Similarly, when a browser is closed, BrowserClosing is 31 // represent the tab. Similarly, when a browser is closed, BrowserClosing is
36 // invoked and a Window is created to represent the window. 32 // invoked and a Window is created to represent the window.
37 // 33 //
38 // To restore a tab/window from the TabRestoreService invoke RestoreEntryById 34 // To restore a tab/window from the TabRestoreService invoke RestoreEntryById
39 // or RestoreMostRecentEntry. 35 // or RestoreMostRecentEntry.
40 // 36 //
41 // To listen for changes to the set of entries managed by the TabRestoreService 37 // To listen for changes to the set of entries managed by the TabRestoreService
42 // add an observer. 38 // add an observer.
43 class TabRestoreService : public BaseSessionService { 39 class TabRestoreService : public ProfileKeyedService {
44 public: 40 public:
45 // Interface used to allow the test to provide a custom time. 41 // Interface used to allow the test to provide a custom time.
46 class TimeFactory { 42 class TimeFactory {
47 public: 43 public:
48 virtual ~TimeFactory(); 44 virtual ~TimeFactory();
49 virtual base::Time TimeNow() = 0; 45 virtual base::Time TimeNow() = 0;
50 }; 46 };
51 47
52 // The type of entry. 48 // The type of entry.
53 enum Type { 49 enum Type {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 115
120 // Index of the selected tab. 116 // Index of the selected tab.
121 int selected_tab_index; 117 int selected_tab_index;
122 118
123 // If an application window, the name of the app. 119 // If an application window, the name of the app.
124 std::string app_name; 120 std::string app_name;
125 }; 121 };
126 122
127 typedef std::list<Entry*> Entries; 123 typedef std::list<Entry*> Entries;
128 124
129 // Creates a new TabRestoreService and provides an object that provides the
130 // current time. The TabRestoreService does not take ownership of the
131 // |time_factory_|.
132 TabRestoreService(Profile* profile, TimeFactory* time_factory_ = NULL);
133
134 virtual ~TabRestoreService(); 125 virtual ~TabRestoreService();
135 126
136 // Adds/removes an observer. TabRestoreService does not take ownership of 127 // Adds/removes an observer. TabRestoreService does not take ownership of
137 // the observer. 128 // the observer.
138 void AddObserver(TabRestoreServiceObserver* observer); 129 virtual void AddObserver(TabRestoreServiceObserver* observer) = 0;
139 void RemoveObserver(TabRestoreServiceObserver* observer); 130 virtual void RemoveObserver(TabRestoreServiceObserver* observer) = 0;
140 131
141 // Creates a Tab to represent |contents| and notifies observers the list of 132 // Creates a Tab to represent |contents| and notifies observers the list of
142 // entries has changed. 133 // entries has changed.
143 void CreateHistoricalTab(content::WebContents* contents, int index); 134 virtual void CreateHistoricalTab(content::WebContents* contents,
135 int index) = 0;
144 136
145 // Invoked when a browser is closing. If |delegate| is a tabbed browser with 137 // 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 138 // at least one tab, a Window is created, added to entries and observers are
147 // notified. 139 // notified.
148 void BrowserClosing(TabRestoreServiceDelegate* delegate); 140 virtual void BrowserClosing(TabRestoreServiceDelegate* delegate) = 0;
149 141
150 // Invoked when the browser is done closing. 142 // Invoked when the browser is done closing.
151 void BrowserClosed(TabRestoreServiceDelegate* delegate); 143 virtual void BrowserClosed(TabRestoreServiceDelegate* delegate) = 0;
152 144
153 // Removes all entries from the list and notifies observers the list 145 // Removes all entries from the list and notifies observers the list
154 // of tabs has changed. 146 // of tabs has changed.
155 void ClearEntries(); 147 virtual void ClearEntries() = 0;
156 148
157 // Returns the entries, ordered with most recently closed entries at the 149 // Returns the entries, ordered with most recently closed entries at the
158 // front. 150 // front.
159 virtual const Entries& entries() const; 151 virtual const Entries& entries() const = 0;
160 152
161 // Restores the most recently closed entry. Does nothing if there are no 153 // 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 154 // entries to restore. If the most recently restored entry is a tab, it is
163 // added to |delegate|. 155 // added to |delegate|.
164 void RestoreMostRecentEntry(TabRestoreServiceDelegate* delegate); 156 virtual void RestoreMostRecentEntry(TabRestoreServiceDelegate* delegate) = 0;
165 157
166 // Removes the Tab with id |id| from the list and returns it; ownership is 158 // Removes the Tab with id |id| from the list and returns it; ownership is
167 // passed to the caller. 159 // passed to the caller.
168 Tab* RemoveTabEntryById(SessionID::id_type id); 160 virtual Tab* RemoveTabEntryById(SessionID::id_type id) = 0;
169 161
170 // Restores an entry by id. If there is no entry with an id matching |id|, 162 // 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 163 // this does nothing. If |delegate| is NULL, this creates a new window for the
172 // entry. |disposition| is respected, but the attributes (tabstrip index, 164 // entry. |disposition| is respected, but the attributes (tabstrip index,
173 // browser window) of the tab when it was closed will be respected if 165 // browser window) of the tab when it was closed will be respected if
174 // disposition is UNKNOWN. 166 // disposition is UNKNOWN.
175 void RestoreEntryById(TabRestoreServiceDelegate* delegate, 167 virtual void RestoreEntryById(TabRestoreServiceDelegate* delegate,
176 SessionID::id_type id, 168 SessionID::id_type id,
177 WindowOpenDisposition disposition); 169 WindowOpenDisposition disposition) = 0;
178 170
179 // Loads the tabs and previous session. This does nothing if the tabs 171 // Loads the tabs and previous session. This does nothing if the tabs
180 // from the previous session have already been loaded. 172 // from the previous session have already been loaded.
181 void LoadTabsFromLastSession(); 173 virtual void LoadTabsFromLastSession() = 0;
182 174
183 // Returns true if the tab entries have been loaded. 175 // Returns true if the tab entries have been loaded.
184 bool IsLoaded() const; 176 virtual bool IsLoaded() const = 0;
185 177
186 // Max number of entries we'll keep around. 178 virtual void DeleteLastSession() = 0;
sky 2012/10/22 13:51:35 Add a comment.
Philippe 2012/10/23 15:07:36 Done. Let me know if you have a more useful commen
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.
231 void NotifyTabsChanged();
232
233 // 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
235 // 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.
237 void AddEntry(Entry* entry, bool prune, bool to_front);
238
239 // Prunes entries_ to contain only kMaxEntries, and removes uninteresting
240 // entries.
241 void PruneEntries();
242
243 // 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
245 // tab, then the iterator position of the Window in which the Tab resides is
246 // returned.
247 Entries::iterator GetEntryIteratorById(SessionID::id_type id);
248
249 // Schedules the commands for a window close.
250 void ScheduleCommandsForWindow(const Window& window);
251
252 // Schedules the commands for a tab close. |selected_index| gives the
253 // index of the selected navigation.
254 void ScheduleCommandsForTab(const Tab& tab, int selected_index);
255
256 // Creates a window close command.
257 SessionCommand* CreateWindowCommand(SessionID::id_type id,
258 int selected_tab_index,
259 int num_tabs,
260 base::Time timestamp);
261
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
289 // 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
291 // returns the TabRestoreServiceDelegate into which the tab was restored.
292 // |disposition| will be respected, but if it is UNKNOWN then the tab's
293 // original attributes will be respected instead.
294 TabRestoreServiceDelegate* RestoreTab(const Tab& tab,
295 TabRestoreServiceDelegate* delegate,
296 WindowOpenDisposition disposition);
297
298 // Returns true if |tab| has more than one navigation. If |tab| has more
299 // than one navigation |tab->current_navigation_index| is constrained based
300 // on the number of navigations.
301 static bool ValidateTab(Tab* tab);
302
303 // Validates all the tabs in a window, plus the window's active tab index.
304 static bool ValidateWindow(Window* window);
305
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.
310 static bool IsTabInteresting(const Tab* tab);
311
312 // Checks whether |window| is interesting --- if it only contains a single,
313 // uninteresting tab, it's not interesting.
314 static bool IsWindowInteresting(const Window* window);
315
316 // Validates and checks |entry| for interesting.
317 static bool FilterEntry(Entry* entry);
318
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.
325 void UpdateTabBrowserIDs(SessionID::id_type old_id,
326 SessionID::id_type new_id);
327
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.
348 base::Time TimeNow() const;
349
350 // Set of entries. They are ordered from most to least recent.
351 Entries entries_;
352
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
357 // historical tab.
358 bool restoring_;
359
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_;
367
368 // Set of delegates that we've received a BrowserClosing method for but no
369 // corresponding BrowserClosed. We cache the set of delegates closing to
370 // avoid creating historical tabs for them.
371 std::set<TabRestoreServiceDelegate*> closing_delegates_;
372
373 // Used when loading open tabs/session when recovering from a crash.
374 CancelableRequestConsumer crash_consumer_;
375
376 // Used when loading previous tabs/session.
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 }; 179 };
389 180
390 #endif // CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_H_ 181 #endif // CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698