blob: 6e49c2d86cc0b29ed5241239e2a40c716b344c22 [file] [log] [blame]
[email protected]ebbbb9f2011-03-09 13:16:141// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]169627b2008-12-06 19:30:195#ifndef CHROME_BROWSER_SESSIONS_SESSION_SERVICE_H_
6#define CHROME_BROWSER_SESSIONS_SESSION_SERVICE_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
initial.commit09911bf2008-07-26 23:55:298
9#include <map>
[email protected]23da84e152010-07-14 01:29:0510#include <string>
initial.commit09911bf2008-07-26 23:55:2911
12#include "base/basictypes.h"
[email protected]2041cf342010-02-19 03:15:5913#include "base/callback.h"
[email protected]70eb8ed92010-06-10 18:13:1214#include "base/time.h"
[email protected]982921f12009-10-27 21:43:5315#include "chrome/browser/defaults.h"
[email protected]926bfeb2009-02-14 23:19:4716#include "chrome/browser/sessions/base_session_service.h"
[email protected]169627b2008-12-06 19:30:1917#include "chrome/browser/sessions/session_id.h"
[email protected]2ad4a902010-11-17 06:05:1318#include "chrome/browser/ui/browser.h"
19#include "chrome/browser/ui/browser_list.h"
[email protected]ebbbb9f2011-03-09 13:16:1420#include "content/common/notification_observer.h"
21#include "content/common/notification_registrar.h"
[email protected]400eaf82011-08-22 15:47:3922#include "ui/base/ui_base_types.h"
initial.commit09911bf2008-07-26 23:55:2923
initial.commit09911bf2008-07-26 23:55:2924class NavigationEntry;
25class Profile;
initial.commit09911bf2008-07-26 23:55:2926class SessionCommand;
[email protected]169627b2008-12-06 19:30:1927struct SessionTab;
28struct SessionWindow;
[email protected]81898992011-06-14 22:15:0029class TabContentsWrapper;
initial.commit09911bf2008-07-26 23:55:2930
31// SessionService ------------------------------------------------------------
32
33// SessionService is responsible for maintaining the state of open windows
[email protected]6ea265a2008-10-30 02:58:3634// and tabs so that they can be restored at a later date. The state of the
35// currently open browsers is referred to as the current session.
initial.commit09911bf2008-07-26 23:55:2936//
[email protected]668cd422011-04-06 21:00:0137// SessionService supports restoring from the last session. The last session
38// typically corresponds to the last run of the browser, but not always. For
39// example, if the user has a tabbed browser and app window running, closes the
40// tabbed browser, then creates a new tabbed browser the current session is made
41// the last session and the current session reset. This is done to provide the
42// illusion that app windows run in separate processes. Similar behavior occurs
43// with incognito windows.
initial.commit09911bf2008-07-26 23:55:2944//
45// SessionService itself maintains a set of SessionCommands that allow
46// SessionService to rebuild the open state of the browser (as
47// SessionWindow, SessionTab and TabNavigation). The commands are periodically
48// flushed to SessionBackend and written to a file. Every so often
49// SessionService rebuilds the contents of the file from the open state
50// of the browser.
[email protected]169627b2008-12-06 19:30:1951class SessionService : public BaseSessionService,
52 public NotificationObserver {
initial.commit09911bf2008-07-26 23:55:2953 friend class SessionServiceTestHelper;
54 public:
55 // Creates a SessionService for the specified profile.
56 explicit SessionService(Profile* profile);
57 // For testing.
[email protected]5a82010a2009-02-14 01:33:0258 explicit SessionService(const FilePath& save_path);
initial.commit09911bf2008-07-26 23:55:2959
[email protected]f0a58a382011-04-26 16:09:2960 virtual ~SessionService();
61
[email protected]c9b19942010-03-26 15:58:0862 // Invoke at a point when you think session restore might occur. For example,
63 // during startup and window creation this is invoked to see if a session
64 // needs to be restored. If a session needs to be restored it is done so
65 // asynchronously and true is returned. If false is returned the session was
66 // not restored and the caller needs to create a new window.
67 bool RestoreIfNecessary(const std::vector<GURL>& urls_to_open);
68
initial.commit09911bf2008-07-26 23:55:2969 // Resets the contents of the file from the current state of all open
70 // browsers whose profile matches our profile.
71 void ResetFromCurrentBrowsers();
72
73 // Moves the current session to the last session. This is useful when a
74 // checkpoint occurs, such as when the user launches the app and no tabbed
75 // browsers are running.
76 void MoveCurrentSessionToLastSession();
77
78 // Associates a tab with a window.
79 void SetTabWindow(const SessionID& window_id,
80 const SessionID& tab_id);
81
82 // Sets the bounds of a window.
83 void SetWindowBounds(const SessionID& window_id,
84 const gfx::Rect& bounds,
[email protected]400eaf82011-08-22 15:47:3985 ui::WindowShowState show_state);
initial.commit09911bf2008-07-26 23:55:2986
87 // Sets the visual index of the tab in its parent window.
88 void SetTabIndexInWindow(const SessionID& window_id,
89 const SessionID& tab_id,
90 int new_index);
91
[email protected]5c0e6482009-07-14 20:20:0992 // Sets the pinned state of the tab.
93 void SetPinnedState(const SessionID& window_id,
94 const SessionID& tab_id,
95 bool is_pinned);
96
[email protected]c0e3ee42010-05-26 22:11:0797 // Notification that a tab has been closed. |closed_by_user_gesture| comes
98 // from |TabContents::closed_by_user_gesture|; see it for details.
initial.commit09911bf2008-07-26 23:55:2999 //
100 // Note: this is invoked from the NavigationController's destructor, which is
101 // after the actual tab has been removed.
[email protected]c0e3ee42010-05-26 22:11:07102 void TabClosed(const SessionID& window_id,
103 const SessionID& tab_id,
104 bool closed_by_user_gesture);
initial.commit09911bf2008-07-26 23:55:29105
106 // Notification the window is about to close.
107 void WindowClosing(const SessionID& window_id);
108
109 // Notification a window has finished closing.
110 void WindowClosed(const SessionID& window_id);
111
112 // Sets the type of window. In order for the contents of a window to be
113 // tracked SetWindowType must be invoked with a type we track
114 // (should_track_changes_for_browser_type returns true).
[email protected]299dabd2008-11-19 02:27:16115 void SetWindowType(const SessionID& window_id, Browser::Type type);
initial.commit09911bf2008-07-26 23:55:29116
[email protected]c12bf1a12008-09-17 16:28:49117 // Invoked when the NavigationController has removed entries from the back of
118 // the list. |count| gives the number of entries in the navigation controller.
119 void TabNavigationPathPrunedFromBack(const SessionID& window_id,
120 const SessionID& tab_id,
121 int count);
122
123 // Invoked when the NavigationController has removed entries from the front of
124 // the list. |count| gives the number of entries that were removed.
125 void TabNavigationPathPrunedFromFront(const SessionID& window_id,
126 const SessionID& tab_id,
127 int count);
initial.commit09911bf2008-07-26 23:55:29128
129 // Updates the navigation entry for the specified tab.
130 void UpdateTabNavigation(const SessionID& window_id,
131 const SessionID& tab_id,
132 int index,
133 const NavigationEntry& entry);
134
135 // Notification that a tab has restored its entries or a closed tab is being
136 // reused.
[email protected]81898992011-06-14 22:15:00137 void TabRestored(TabContentsWrapper* tab, bool pinned);
initial.commit09911bf2008-07-26 23:55:29138
139 // Sets the index of the selected entry in the navigation controller for the
140 // specified tab.
141 void SetSelectedNavigationIndex(const SessionID& window_id,
142 const SessionID& tab_id,
143 int index);
144
145 // Sets the index of the selected tab in the specified window.
146 void SetSelectedTabInWindow(const SessionID& window_id, int index);
147
148 // Callback from GetSavedSession of GetLastSession.
149 //
150 // The contents of the supplied vector are deleted after the callback is
151 // notified. To take ownership of the vector clear it before returning.
152 //
153 // The time gives the time the session was closed.
154 typedef Callback2<Handle, std::vector<SessionWindow*>*>::Type
[email protected]3acb70ef2010-03-01 18:44:38155 SessionCallback;
initial.commit09911bf2008-07-26 23:55:29156
157 // Fetches the contents of the last session, notifying the callback when
158 // done. If the callback is supplied an empty vector of SessionWindows
159 // it means the session could not be restored.
[email protected]169627b2008-12-06 19:30:19160 //
161 // The created request does NOT directly invoke the callback, rather the
162 // callback invokes OnGotSessionCommands from which we map the
163 // SessionCommands to browser state, then notify the callback.
initial.commit09911bf2008-07-26 23:55:29164 Handle GetLastSession(CancelableRequestConsumerBase* consumer,
[email protected]3acb70ef2010-03-01 18:44:38165 SessionCallback* callback);
166
167 // Fetches the contents of the current session, notifying the callback when
168 // done. If the callback is supplied an empty vector of SessionWindows
169 // it means the session could not be restored.
170 //
171 // The created request does NOT directly invoke the callback, rather the
172 // callback invokes OnGotSessionCommands from which we map the
173 // SessionCommands to browser state, then notify the callback.
174 Handle GetCurrentSession(CancelableRequestConsumerBase* consumer,
175 SessionCallback* callback);
initial.commit09911bf2008-07-26 23:55:29176
[email protected]70eb8ed92010-06-10 18:13:12177 // Overridden from BaseSessionService because we want some UMA reporting on
178 // session update activities.
179 virtual void Save();
180
initial.commit09911bf2008-07-26 23:55:29181 private:
[email protected]23da84e152010-07-14 01:29:05182 typedef std::map<SessionID::id_type, std::pair<int, int> > IdToRange;
183 typedef std::map<SessionID::id_type, SessionTab*> IdToSessionTab;
184 typedef std::map<SessionID::id_type, SessionWindow*> IdToSessionWindow;
185
initial.commit09911bf2008-07-26 23:55:29186
[email protected]97d2c1e2009-11-05 03:55:05187 // These types mirror Browser::Type, but are re-defined here because these
188 // specific enumeration _values_ are written into the session database and
189 // are needed to maintain forward compatibility.
[email protected]b35b26b32011-05-05 20:35:14190 // Note that we only store browsers of type TYPE_TABBED and TYPE_POPUP.
[email protected]97d2c1e2009-11-05 03:55:05191 enum WindowType {
[email protected]b35b26b32011-05-05 20:35:14192 TYPE_TABBED = 0,
193 TYPE_POPUP = 1
[email protected]97d2c1e2009-11-05 03:55:05194 };
195
[email protected]169627b2008-12-06 19:30:19196 void Init();
initial.commit09911bf2008-07-26 23:55:29197
[email protected]c9b19942010-03-26 15:58:08198 // Implementation of RestoreIfNecessary. If |browser| is non-null and we need
199 // to restore, the tabs are added to it, otherwise a new browser is created.
200 bool RestoreIfNecessary(const std::vector<GURL>& urls_to_open,
201 Browser* browser);
202
[email protected]432115822011-07-10 15:52:27203 virtual void Observe(int type,
[email protected]534e54b2008-08-13 15:40:09204 const NotificationSource& source,
205 const NotificationDetails& details);
206
[email protected]fca656c2010-02-10 20:30:10207 // Sets the application extension id of the specified tab.
[email protected]98aa0b52010-05-06 17:03:08208 void SetTabExtensionAppID(const SessionID& window_id,
[email protected]fca656c2010-02-10 20:30:10209 const SessionID& tab_id,
[email protected]98aa0b52010-05-06 17:03:08210 const std::string& extension_app_id);
[email protected]fca656c2010-02-10 20:30:10211
initial.commit09911bf2008-07-26 23:55:29212 // Methods to create the various commands. It is up to the caller to delete
213 // the returned the SessionCommand* object.
214 SessionCommand* CreateSetSelectedTabInWindow(const SessionID& window_id,
215 int index);
216
217 SessionCommand* CreateSetTabWindowCommand(const SessionID& window_id,
218 const SessionID& tab_id);
219
220 SessionCommand* CreateSetWindowBoundsCommand(const SessionID& window_id,
221 const gfx::Rect& bounds,
[email protected]400eaf82011-08-22 15:47:39222 ui::WindowShowState show_state);
initial.commit09911bf2008-07-26 23:55:29223
224 SessionCommand* CreateSetTabIndexInWindowCommand(const SessionID& tab_id,
225 int new_index);
226
227 SessionCommand* CreateTabClosedCommand(SessionID::id_type tab_id);
228
229 SessionCommand* CreateWindowClosedCommand(SessionID::id_type tab_id);
230
initial.commit09911bf2008-07-26 23:55:29231 SessionCommand* CreateSetSelectedNavigationIndexCommand(
232 const SessionID& tab_id,
233 int index);
234
235 SessionCommand* CreateSetWindowTypeCommand(const SessionID& window_id,
[email protected]97d2c1e2009-11-05 03:55:05236 WindowType type);
initial.commit09911bf2008-07-26 23:55:29237
[email protected]5c0e6482009-07-14 20:20:09238 SessionCommand* CreatePinnedStateCommand(const SessionID& tab_id,
239 bool is_pinned);
240
[email protected]668cd422011-04-06 21:00:01241 // Callback from the backend for getting the commands from the save file.
242 // Converts the commands in SessionWindows and notifies the real callback.
[email protected]3acb70ef2010-03-01 18:44:38243 void OnGotSessionCommands(
initial.commit09911bf2008-07-26 23:55:29244 Handle handle,
[email protected]169627b2008-12-06 19:30:19245 scoped_refptr<InternalGetCommandsRequest> request);
initial.commit09911bf2008-07-26 23:55:29246
247 // Converts the commands into SessionWindows. On return any valid
248 // windows are added to valid_windows. It is up to the caller to delete
249 // the windows added to valid_windows.
250 //
251 // If ignore_recent_closes is true, any window/tab closes within in a certain
252 // time frame are ignored.
253 void RestoreSessionFromCommands(const std::vector<SessionCommand*>& commands,
254 std::vector<SessionWindow*>* valid_windows);
255
256 // Iterates through the vector updating the selected_tab_index of each
257 // SessionWindow based on the actual tabs that were restored.
258 void UpdateSelectedTabIndex(std::vector<SessionWindow*>* windows);
259
260 // Returns the window in windows with the specified id. If a window does
261 // not exist, one is created.
262 SessionWindow* GetWindow(SessionID::id_type window_id,
263 IdToSessionWindow* windows);
264
265 // Returns the tab with the specified id in tabs. If a tab does not exist,
266 // it is created.
267 SessionTab* GetTab(SessionID::id_type tab_id,
268 IdToSessionTab* tabs);
269
270 // Returns an iterator into navigations pointing to the navigation whose
271 // index matches |index|. If no navigation index matches |index|, the first
272 // navigation with an index > |index| is returned.
273 //
274 // This assumes the navigations are ordered by index in ascending order.
275 std::vector<TabNavigation>::iterator FindClosestNavigationWithIndex(
276 std::vector<TabNavigation>* navigations,
277 int index);
278
279 // Does the following:
280 // . Deletes and removes any windows with no tabs or windows with types other
281 // than tabbed_browser or browser. NOTE: constrained windows that have
282 // been dragged out are of type browser. As such, this preserves any dragged
283 // out constrained windows (aka popups that have been dragged out).
284 // . Sorts the tabs in windows with valid tabs based on the tabs
285 // visual order, and adds the valid windows to windows.
286 void SortTabsBasedOnVisualOrderAndPrune(
[email protected]23da84e152010-07-14 01:29:05287 std::map<int, SessionWindow*>* windows,
initial.commit09911bf2008-07-26 23:55:29288 std::vector<SessionWindow*>* valid_windows);
289
290 // Adds tabs to their parent window based on the tab's window_id. This
291 // ignores tabs with no navigations.
[email protected]23da84e152010-07-14 01:29:05292 void AddTabsToWindows(std::map<int, SessionTab*>* tabs,
293 std::map<int, SessionWindow*>* windows);
initial.commit09911bf2008-07-26 23:55:29294
295 // Creates tabs and windows from the specified commands. The created tabs
296 // and windows are added to |tabs| and |windows| respectively. It is up to
297 // the caller to delete the tabs and windows added to |tabs| and |windows|.
298 //
299 // This does NOT add any created SessionTabs to SessionWindow.tabs, that is
300 // done by AddTabsToWindows.
301 bool CreateTabsAndWindows(const std::vector<SessionCommand*>& data,
[email protected]23da84e152010-07-14 01:29:05302 std::map<int, SessionTab*>* tabs,
303 std::map<int, SessionWindow*>* windows);
initial.commit09911bf2008-07-26 23:55:29304
305 // Adds commands to commands that will recreate the state of the specified
[email protected]81898992011-06-14 22:15:00306 // tab. This adds at most kMaxNavigationCountToPersist navigations (in each
307 // direction from the current navigation index).
initial.commit09911bf2008-07-26 23:55:29308 // A pair is added to tab_to_available_range indicating the range of
309 // indices that were written.
310 void BuildCommandsForTab(
311 const SessionID& window_id,
[email protected]81898992011-06-14 22:15:00312 TabContentsWrapper* tab,
initial.commit09911bf2008-07-26 23:55:29313 int index_in_window,
[email protected]5c0e6482009-07-14 20:20:09314 bool is_pinned,
initial.commit09911bf2008-07-26 23:55:29315 std::vector<SessionCommand*>* commands,
316 IdToRange* tab_to_available_range);
317
318 // Adds commands to create the specified browser, and invokes
319 // BuildCommandsForTab for each of the tabs in the browser. This ignores
320 // any tabs not in the profile we were created with.
321 void BuildCommandsForBrowser(
322 Browser* browser,
323 std::vector<SessionCommand*>* commands,
324 IdToRange* tab_to_available_range,
325 std::set<SessionID::id_type>* windows_to_track);
326
327 // Iterates over all the known browsers invoking BuildCommandsForBrowser.
328 // This only adds browsers that should be tracked
329 // (should_track_changes_for_browser_type returns true). All browsers that
330 // are tracked are added to windows_to_track (as long as it is non-null).
331 void BuildCommandsFromBrowsers(
332 std::vector<SessionCommand*>* commands,
333 IdToRange* tab_to_available_range,
334 std::set<SessionID::id_type>* windows_to_track);
335
336 // Schedules a reset. A reset means the contents of the file are recreated
337 // from the state of the browser.
338 void ScheduleReset();
339
340 // Searches for a pending command that can be replaced with command.
341 // If one is found, pending command is removed, command is added to
342 // the pending commands and true is returned.
343 bool ReplacePendingCommand(SessionCommand* command);
344
345 // Schedules the specified command. This method takes ownership of the
346 // command.
[email protected]78994ab02010-12-08 18:06:44347 virtual void ScheduleCommand(SessionCommand* command);
initial.commit09911bf2008-07-26 23:55:29348
349 // Converts all pending tab/window closes to commands and schedules them.
350 void CommitPendingCloses();
351
initial.commit09911bf2008-07-26 23:55:29352 // Returns true if there is only one window open with a single tab that shares
353 // our profile.
354 bool IsOnlyOneTabLeft();
355
[email protected]982921f12009-10-27 21:43:53356 // Returns true if there are open trackable browser windows whose ids do
357 // match |window_id| with our profile. A trackable window is a window from
358 // which |should_track_changes_for_browser_type| returns true. See
359 // |should_track_changes_for_browser_type| for details.
360 bool HasOpenTrackableBrowsers(const SessionID& window_id);
initial.commit09911bf2008-07-26 23:55:29361
362 // Returns true if changes to tabs in the specified window should be tracked.
363 bool ShouldTrackChangesToWindow(const SessionID& window_id);
364
365 // Returns true if we track changes to the specified browser type.
[email protected]b35b26b32011-05-05 20:35:14366 static bool should_track_changes_for_browser_type(Browser::Type type);
initial.commit09911bf2008-07-26 23:55:29367
[email protected]4070a6b2009-11-05 23:33:55368 // Returns true if we should record a window close as pending.
369 // |has_open_trackable_browsers_| must be up-to-date before calling this.
370 bool should_record_close_as_pending() const {
371 // When this is called, the browser window being closed is still open, hence
372 // still in the browser list. If there is a browser window other than the
373 // one being closed but no trackable windows, then the others must be App
374 // windows or similar. In this case, we record the close as pending.
375 return !has_open_trackable_browsers_ &&
376 (!browser_defaults::kBrowserAliveWithNoWindows ||
377 BrowserList::size() > 1);
[email protected]70eb8ed92010-06-10 18:13:12378 }
379
[email protected]23da84e152010-07-14 01:29:05380 // Call when certain session relevant notifications
381 // (tab_closed, nav_list_pruned) occur. In addition, this is
382 // currently called when Save() is called to compare how often the
383 // session data is currently saved verses when we may want to save it.
384 // It records the data in UMA stats.
[email protected]432115822011-07-10 15:52:27385 void RecordSessionUpdateHistogramData(int type,
[email protected]23da84e152010-07-14 01:29:05386 base::TimeTicks* last_updated_time);
387
388 // Helper methods to record the histogram data
389 void RecordUpdatedTabClosed(base::TimeDelta delta, bool use_long_period);
390 void RecordUpdatedNavListPruned(base::TimeDelta delta, bool use_long_period);
391 void RecordUpdatedNavEntryCommit(base::TimeDelta delta, bool use_long_period);
392 void RecordUpdatedSaveTime(base::TimeDelta delta, bool use_long_period);
393 void RecordUpdatedSessionNavigationOrTab(base::TimeDelta delta,
394 bool use_long_period);
[email protected]4070a6b2009-11-05 23:33:55395
[email protected]97d2c1e2009-11-05 03:55:05396 // Convert back/forward between the Browser and SessionService DB window
397 // types.
398 static WindowType WindowTypeForBrowserType(Browser::Type type);
399 static Browser::Type BrowserTypeForWindowType(WindowType type);
400
[email protected]6a02963e2009-01-06 16:58:03401 NotificationRegistrar registrar_;
402
initial.commit09911bf2008-07-26 23:55:29403 // Maps from session tab id to the range of navigation entries that has
404 // been written to disk.
405 //
406 // This is only used if not all the navigation entries have been
407 // written.
408 IdToRange tab_to_available_range_;
409
[email protected]6ea265a2008-10-30 02:58:36410 // When the user closes the last window, where the last window is the
initial.commit09911bf2008-07-26 23:55:29411 // last tabbed browser and no more tabbed browsers are open with the same
412 // profile, the window ID is added here. These IDs are only committed (which
413 // marks them as closed) if the user creates a new tabbed browser.
414 typedef std::set<SessionID::id_type> PendingWindowCloseIDs;
415 PendingWindowCloseIDs pending_window_close_ids_;
416
417 // Set of tabs that have been closed by way of the last window or last tab
418 // closing, but not yet committed.
419 typedef std::set<SessionID::id_type> PendingTabCloseIDs;
420 PendingTabCloseIDs pending_tab_close_ids_;
421
422 // When a window other than the last window (see description of
423 // pending_window_close_ids) is closed, the id is added to this set.
424 typedef std::set<SessionID::id_type> WindowClosingIDs;
425 WindowClosingIDs window_closing_ids_;
426
427 // Set of windows we're tracking changes to. This is only browsers that
428 // return true from should_track_changes_for_browser_type.
429 typedef std::set<SessionID::id_type> WindowsTracking;
430 WindowsTracking windows_tracking_;
431
[email protected]982921f12009-10-27 21:43:53432 // Are there any open trackable browsers?
433 bool has_open_trackable_browsers_;
initial.commit09911bf2008-07-26 23:55:29434
[email protected]6ea265a2008-10-30 02:58:36435 // If true and a new tabbed browser is created and there are no opened tabbed
[email protected]982921f12009-10-27 21:43:53436 // browser (has_open_trackable_browsers_ is false), then the current session
[email protected]668cd422011-04-06 21:00:01437 // is made the last session. See description above class for details on
438 // current/last session.
[email protected]6ea265a2008-10-30 02:58:36439 bool move_on_new_browser_;
[email protected]169627b2008-12-06 19:30:19440
[email protected]47db9a92011-01-24 20:10:13441 // Used for reporting frequency of session altering operations.
[email protected]23da84e152010-07-14 01:29:05442 base::TimeTicks last_updated_tab_closed_time_;
443 base::TimeTicks last_updated_nav_list_pruned_time_;
444 base::TimeTicks last_updated_nav_entry_commit_time_;
445 base::TimeTicks last_updated_save_time_;
446
447 // Constants used in calculating histogram data.
448 const base::TimeDelta save_delay_in_millis_;
449 const base::TimeDelta save_delay_in_mins_;
450 const base::TimeDelta save_delay_in_hrs_;
[email protected]70eb8ed92010-06-10 18:13:12451
[email protected]169627b2008-12-06 19:30:19452 DISALLOW_COPY_AND_ASSIGN(SessionService);
initial.commit09911bf2008-07-26 23:55:29453};
454
[email protected]169627b2008-12-06 19:30:19455#endif // CHROME_BROWSER_SESSIONS_SESSION_SERVICE_H_