blob: 4961a2bfaecb370f5fa438f475bbec3eb26ce8eb [file] [log] [blame]
[email protected]a636d8e52012-02-28 15:40:411// Copyright (c) 2012 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_
initial.commit09911bf2008-07-26 23:55:297
8#include <map>
[email protected]23da84e152010-07-14 01:29:059#include <string>
initial.commit09911bf2008-07-26 23:55:2910
[email protected]f9ffb892011-11-28 18:57:3111#include "base/callback.h"
thestiga0e18cd2015-09-25 04:58:3612#include "base/gtest_prod_util.h"
avib896c712015-12-26 02:10:4313#include "base/macros.h"
sky1a14f492014-08-26 21:44:2614#include "base/memory/weak_ptr.h"
[email protected]e95b717f2014-02-06 13:47:1315#include "base/task/cancelable_task_tracker.h"
[email protected]cc86ccfe2013-06-28 00:10:5016#include "base/time/time.h"
[email protected]982921f12009-10-27 21:43:5317#include "chrome/browser/defaults.h"
blundell6d34c342015-09-11 09:09:1018#include "chrome/browser/sessions/session_common_utils.h"
skuhnec3aa8cf2014-10-30 06:02:4519#include "chrome/browser/sessions/session_service_utils.h"
[email protected]2ad4a902010-11-17 06:05:1320#include "chrome/browser/ui/browser.h"
[email protected]0665ebe2013-02-13 09:53:1921#include "chrome/browser/ui/browser_finder.h"
[email protected]bf219e9eb2012-10-10 15:20:3822#include "chrome/browser/ui/browser_list_observer.h"
[email protected]540380fc2014-03-14 10:10:3423#include "components/keyed_service/core/keyed_service.h"
blundell47c6d8a2015-09-24 11:06:4024#include "components/sessions/core/base_session_service_delegate.h"
25#include "components/sessions/core/session_service_commands.h"
blundell56789fe2015-09-10 05:11:1626#include "components/sessions/core/tab_restore_service_client.h"
[email protected]400eaf82011-08-22 15:47:3927#include "ui/base/ui_base_types.h"
initial.commit09911bf2008-07-26 23:55:2928
initial.commit09911bf2008-07-26 23:55:2929class Profile;
[email protected]ad23a092011-12-28 07:02:0430
31namespace content {
[email protected]40600152012-09-26 10:04:3132class WebContents;
skuhneb7409dcf2014-11-14 04:06:5533} // namespace content
34
35namespace sessions {
36class SessionCommand;
37struct SessionTab;
38struct SessionWindow;
39} // namespace sessions
initial.commit09911bf2008-07-26 23:55:2940
41// SessionService ------------------------------------------------------------
42
43// SessionService is responsible for maintaining the state of open windows
[email protected]6ea265a2008-10-30 02:58:3644// and tabs so that they can be restored at a later date. The state of the
45// currently open browsers is referred to as the current session.
initial.commit09911bf2008-07-26 23:55:2946//
[email protected]668cd422011-04-06 21:00:0147// SessionService supports restoring from the last session. The last session
48// typically corresponds to the last run of the browser, but not always. For
49// example, if the user has a tabbed browser and app window running, closes the
50// tabbed browser, then creates a new tabbed browser the current session is made
51// the last session and the current session reset. This is done to provide the
52// illusion that app windows run in separate processes. Similar behavior occurs
53// with incognito windows.
initial.commit09911bf2008-07-26 23:55:2954//
skuhnec3aa8cf2014-10-30 06:02:4555// SessionService itself uses functions from session_service_commands to store
56// commands which can rebuild the open state of the browser (as |SessionWindow|,
57// |SessionTab| and |SerializedNavigationEntry|). The commands are periodically
58// flushed to |SessionBackend| and written to a file. Every so often
59// |SessionService| rebuilds the contents of the file from the open state of the
[email protected]40a7e412013-04-29 18:13:0160// browser.
blundell6d34c342015-09-11 09:09:1061class SessionService : public sessions::BaseSessionServiceDelegate,
[email protected]540380fc2014-03-14 10:10:3462 public KeyedService,
cm.sanchia0d6add2017-12-13 04:59:3363 public BrowserListObserver {
[email protected]86ef6a392012-05-11 22:03:1164 friend class SessionServiceTestHelper;
initial.commit09911bf2008-07-26 23:55:2965 public:
skuhnec3aa8cf2014-10-30 06:02:4566 // Used to distinguish an application from a ordinary content window.
[email protected]a636d8e52012-02-28 15:40:4167 enum AppType {
68 TYPE_APP,
69 TYPE_NORMAL
70 };
71
initial.commit09911bf2008-07-26 23:55:2972 // Creates a SessionService for the specified profile.
73 explicit SessionService(Profile* profile);
74 // For testing.
[email protected]650b2d52013-02-10 03:41:4575 explicit SessionService(const base::FilePath& save_path);
initial.commit09911bf2008-07-26 23:55:2976
Daniel Chenga542fca2014-10-21 09:51:2977 ~SessionService() override;
[email protected]f0a58a382011-04-26 16:09:2978
skuhned58ab122014-10-22 20:23:0279 // This may be NULL during testing.
80 Profile* profile() const { return profile_; }
81
[email protected]8ddbb642011-09-01 02:52:2082 // Returns true if a new window opening should really be treated like the
83 // start of a session (with potential session restore, startup URLs, etc.).
84 // In particular, this is true if there are no tabbed browsers running
85 // currently (eg. because only background or other app pages are running).
86 bool ShouldNewWindowStartSession();
87
[email protected]c9b19942010-03-26 15:58:0888 // Invoke at a point when you think session restore might occur. For example,
89 // during startup and window creation this is invoked to see if a session
90 // needs to be restored. If a session needs to be restored it is done so
91 // asynchronously and true is returned. If false is returned the session was
92 // not restored and the caller needs to create a new window.
93 bool RestoreIfNecessary(const std::vector<GURL>& urls_to_open);
94
initial.commit09911bf2008-07-26 23:55:2995 // Resets the contents of the file from the current state of all open
96 // browsers whose profile matches our profile.
97 void ResetFromCurrentBrowsers();
98
99 // Moves the current session to the last session. This is useful when a
100 // checkpoint occurs, such as when the user launches the app and no tabbed
101 // browsers are running.
102 void MoveCurrentSessionToLastSession();
103
skuhned1e250b2014-11-05 15:26:50104 // Deletes the last session.
105 void DeleteLastSession();
106
initial.commit09911bf2008-07-26 23:55:29107 // Associates a tab with a window.
108 void SetTabWindow(const SessionID& window_id,
109 const SessionID& tab_id);
110
111 // Sets the bounds of a window.
112 void SetWindowBounds(const SessionID& window_id,
113 const gfx::Rect& bounds,
[email protected]400eaf82011-08-22 15:47:39114 ui::WindowShowState show_state);
initial.commit09911bf2008-07-26 23:55:29115
thomasanderson06405c52016-05-03 22:52:22116 // Sets the workspace the window resides in.
117 void SetWindowWorkspace(const SessionID& window_id,
118 const std::string& workspace);
119
initial.commit09911bf2008-07-26 23:55:29120 // Sets the visual index of the tab in its parent window.
121 void SetTabIndexInWindow(const SessionID& window_id,
122 const SessionID& tab_id,
123 int new_index);
124
[email protected]5c0e6482009-07-14 20:20:09125 // Sets the pinned state of the tab.
126 void SetPinnedState(const SessionID& window_id,
127 const SessionID& tab_id,
128 bool is_pinned);
129
[email protected]c0e3ee42010-05-26 22:11:07130 // Notification that a tab has been closed. |closed_by_user_gesture| comes
[email protected]e6ff1d52012-04-17 20:00:40131 // from |WebContents::closed_by_user_gesture|; see it for details.
initial.commit09911bf2008-07-26 23:55:29132 //
133 // Note: this is invoked from the NavigationController's destructor, which is
134 // after the actual tab has been removed.
[email protected]c0e3ee42010-05-26 22:11:07135 void TabClosed(const SessionID& window_id,
136 const SessionID& tab_id,
137 bool closed_by_user_gesture);
initial.commit09911bf2008-07-26 23:55:29138
[email protected]7d52ea4c62013-11-13 03:52:14139 // Notification a window has opened.
140 void WindowOpened(Browser* browser);
141
initial.commit09911bf2008-07-26 23:55:29142 // Notification the window is about to close.
143 void WindowClosing(const SessionID& window_id);
144
145 // Notification a window has finished closing.
146 void WindowClosed(const SessionID& window_id);
147
[email protected]40600152012-09-26 10:04:31148 // Called when a tab is inserted.
149 void TabInserted(content::WebContents* contents);
150
151 // Called when a tab is closing.
152 void TabClosing(content::WebContents* contents);
153
initial.commit09911bf2008-07-26 23:55:29154 // Sets the type of window. In order for the contents of a window to be
155 // tracked SetWindowType must be invoked with a type we track
skuhnec3aa8cf2014-10-30 06:02:45156 // (ShouldRestoreOfWindowType returns true).
[email protected]a636d8e52012-02-28 15:40:41157 void SetWindowType(const SessionID& window_id,
158 Browser::Type type,
159 AppType app_type);
160
[email protected]18ab5152013-03-28 23:14:05161 // Sets the application name of the specified window.
162 void SetWindowAppName(const SessionID& window_id,
163 const std::string& app_name);
initial.commit09911bf2008-07-26 23:55:29164
[email protected]c12bf1a12008-09-17 16:28:49165 // Invoked when the NavigationController has removed entries from the back of
166 // the list. |count| gives the number of entries in the navigation controller.
167 void TabNavigationPathPrunedFromBack(const SessionID& window_id,
168 const SessionID& tab_id,
169 int count);
170
171 // Invoked when the NavigationController has removed entries from the front of
172 // the list. |count| gives the number of entries that were removed.
173 void TabNavigationPathPrunedFromFront(const SessionID& window_id,
174 const SessionID& tab_id,
175 int count);
initial.commit09911bf2008-07-26 23:55:29176
Christian Dullweberb13ffda2018-02-23 11:42:14177 // Invoked when the NavigationController has deleted entries because of a
178 // history deletion.
179 void TabNavigationPathEntriesDeleted(const SessionID& window_id,
180 const SessionID& tab_id);
181
initial.commit09911bf2008-07-26 23:55:29182 // Updates the navigation entry for the specified tab.
[email protected]40a7e412013-04-29 18:13:01183 void UpdateTabNavigation(
184 const SessionID& window_id,
185 const SessionID& tab_id,
186 const sessions::SerializedNavigationEntry& navigation);
initial.commit09911bf2008-07-26 23:55:29187
188 // Notification that a tab has restored its entries or a closed tab is being
189 // reused.
[email protected]b624ddc2012-11-15 18:04:13190 void TabRestored(content::WebContents* tab, bool pinned);
initial.commit09911bf2008-07-26 23:55:29191
192 // Sets the index of the selected entry in the navigation controller for the
193 // specified tab.
194 void SetSelectedNavigationIndex(const SessionID& window_id,
195 const SessionID& tab_id,
196 int index);
197
198 // Sets the index of the selected tab in the specified window.
199 void SetSelectedTabInWindow(const SessionID& window_id, int index);
200
[email protected]8d0f3312012-08-18 01:47:53201 // Sets the user agent override of the specified tab.
202 void SetTabUserAgentOverride(const SessionID& window_id,
203 const SessionID& tab_id,
204 const std::string& user_agent_override);
205
skuhnec3aa8cf2014-10-30 06:02:45206 // Sets the application extension id of the specified tab.
207 void SetTabExtensionAppID(const SessionID& window_id,
208 const SessionID& tab_id,
209 const std::string& extension_app_id);
210
georgesak5582cbe2015-05-22 22:08:07211 // Sets the last active time of the tab.
212 void SetLastActiveTime(const SessionID& window_id,
213 const SessionID& tab_id,
214 base::TimeTicks last_active_time);
215
initial.commit09911bf2008-07-26 23:55:29216 // Fetches the contents of the last session, notifying the callback when
217 // done. If the callback is supplied an empty vector of SessionWindows
218 // it means the session could not be restored.
[email protected]e95b717f2014-02-06 13:47:13219 base::CancelableTaskTracker::TaskId GetLastSession(
blundell56789fe2015-09-10 05:11:16220 const sessions::GetLastSessionCallback& callback,
[email protected]e95b717f2014-02-06 13:47:13221 base::CancelableTaskTracker* tracker);
[email protected]3acb70ef2010-03-01 18:44:38222
blundell74001adc2015-09-18 11:04:25223 // BaseSessionServiceDelegate:
blundell6d34c342015-09-11 09:09:10224 bool ShouldUseDelayedSave() override;
Christian Dullweberb13ffda2018-02-23 11:42:14225 void OnWillSaveCommands() override;
[email protected]70eb8ed92010-06-10 18:13:12226
initial.commit09911bf2008-07-26 23:55:29227 private:
[email protected]bf219e9eb2012-10-10 15:20:38228 // Allow tests to access our innards for testing purposes.
skuhned1e250b2014-11-05 15:26:50229 FRIEND_TEST_ALL_PREFIXES(SessionServiceTest, SavedSessionNotification);
[email protected]bf219e9eb2012-10-10 15:20:38230 FRIEND_TEST_ALL_PREFIXES(SessionServiceTest, RestoreActivation1);
231 FRIEND_TEST_ALL_PREFIXES(SessionServiceTest, RestoreActivation2);
aseren748ab62e2015-01-12 13:33:02232 FRIEND_TEST_ALL_PREFIXES(SessionServiceTest, RemoveUnusedRestoreWindowsTest);
[email protected]51e5bdc2012-12-06 06:12:56233 FRIEND_TEST_ALL_PREFIXES(NoStartupWindowTest, DontInitSessionServiceForApps);
[email protected]bf219e9eb2012-10-10 15:20:38234
[email protected]23da84e152010-07-14 01:29:05235 typedef std::map<SessionID::id_type, std::pair<int, int> > IdToRange;
[email protected]97d2c1e2009-11-05 03:55:05236
[email protected]169627b2008-12-06 19:30:19237 void Init();
initial.commit09911bf2008-07-26 23:55:29238
skuhnec3aa8cf2014-10-30 06:02:45239 // Returns true if a window of given |window_type| and |app_type| should get
240 // restored upon session restore.
skuhneb7409dcf2014-11-14 04:06:55241 bool ShouldRestoreWindowOfType(sessions::SessionWindow::WindowType type,
skuhnec3aa8cf2014-10-30 06:02:45242 AppType app_type) const;
243
244 // Removes unrestorable windows from the previous windows list.
skuhneb7409dcf2014-11-14 04:06:55245 void RemoveUnusedRestoreWindows(
avi498cabca2016-09-21 19:03:50246 std::vector<std::unique_ptr<sessions::SessionWindow>>* window_list);
skuhnec3aa8cf2014-10-30 06:02:45247
[email protected]c9b19942010-03-26 15:58:08248 // Implementation of RestoreIfNecessary. If |browser| is non-null and we need
249 // to restore, the tabs are added to it, otherwise a new browser is created.
250 bool RestoreIfNecessary(const std::vector<GURL>& urls_to_open,
251 Browser* browser);
252
cm.sanchia0d6add2017-12-13 04:59:33253 // BrowserListObserver
Daniel Chenga542fca2014-10-21 09:51:29254 void OnBrowserAdded(Browser* browser) override {}
255 void OnBrowserRemoved(Browser* browser) override {}
256 void OnBrowserSetLastActive(Browser* browser) override;
[email protected]bf219e9eb2012-10-10 15:20:38257
[email protected]4c7f9c52012-12-11 21:51:30258 // Converts |commands| to SessionWindows and notifies the callback.
avi51f1cd92017-01-03 18:23:38259 void OnGotSessionCommands(
260 const sessions::GetLastSessionCallback& callback,
261 std::vector<std::unique_ptr<sessions::SessionCommand>> commands);
initial.commit09911bf2008-07-26 23:55:29262
initial.commit09911bf2008-07-26 23:55:29263 // Adds commands to commands that will recreate the state of the specified
[email protected]81898992011-06-14 22:15:00264 // tab. This adds at most kMaxNavigationCountToPersist navigations (in each
265 // direction from the current navigation index).
initial.commit09911bf2008-07-26 23:55:29266 // A pair is added to tab_to_available_range indicating the range of
267 // indices that were written.
268 void BuildCommandsForTab(
269 const SessionID& window_id,
[email protected]b624ddc2012-11-15 18:04:13270 content::WebContents* tab,
initial.commit09911bf2008-07-26 23:55:29271 int index_in_window,
[email protected]5c0e6482009-07-14 20:20:09272 bool is_pinned,
initial.commit09911bf2008-07-26 23:55:29273 IdToRange* tab_to_available_range);
274
275 // Adds commands to create the specified browser, and invokes
276 // BuildCommandsForTab for each of the tabs in the browser. This ignores
277 // any tabs not in the profile we were created with.
278 void BuildCommandsForBrowser(
279 Browser* browser,
initial.commit09911bf2008-07-26 23:55:29280 IdToRange* tab_to_available_range,
281 std::set<SessionID::id_type>* windows_to_track);
282
283 // Iterates over all the known browsers invoking BuildCommandsForBrowser.
skuhnec3aa8cf2014-10-30 06:02:45284 // This only adds browsers that should be tracked (|ShouldRestoreWindowOfType|
285 // returns true). All browsers that are tracked are added to windows_to_track
286 // (as long as it is non-null).
initial.commit09911bf2008-07-26 23:55:29287 void BuildCommandsFromBrowsers(
initial.commit09911bf2008-07-26 23:55:29288 IdToRange* tab_to_available_range,
289 std::set<SessionID::id_type>* windows_to_track);
290
skuhnec3aa8cf2014-10-30 06:02:45291 // Schedules a reset of the existing commands. A reset means the contents
292 // of the file are recreated from the state of the browser.
293 void ScheduleResetCommands();
initial.commit09911bf2008-07-26 23:55:29294
skuhne57b5b03f2014-10-31 03:59:55295 // Schedules the specified command.
dcheng4af48582016-04-19 00:29:35296 void ScheduleCommand(std::unique_ptr<sessions::SessionCommand> command);
initial.commit09911bf2008-07-26 23:55:29297
298 // Converts all pending tab/window closes to commands and schedules them.
299 void CommitPendingCloses();
300
initial.commit09911bf2008-07-26 23:55:29301 // Returns true if there is only one window open with a single tab that shares
302 // our profile.
[email protected]bf219e9eb2012-10-10 15:20:38303 bool IsOnlyOneTabLeft() const;
initial.commit09911bf2008-07-26 23:55:29304
[email protected]982921f12009-10-27 21:43:53305 // Returns true if there are open trackable browser windows whose ids do
306 // match |window_id| with our profile. A trackable window is a window from
skuhnec3aa8cf2014-10-30 06:02:45307 // which |ShouldRestoreWindowOfType| returns true. See
308 // |ShouldRestoreWindowOfType| for details.
[email protected]bf219e9eb2012-10-10 15:20:38309 bool HasOpenTrackableBrowsers(const SessionID& window_id) const;
initial.commit09911bf2008-07-26 23:55:29310
311 // Returns true if changes to tabs in the specified window should be tracked.
[email protected]bf219e9eb2012-10-10 15:20:38312 bool ShouldTrackChangesToWindow(const SessionID& window_id) const;
313
314 // Returns true if we track changes to the specified browser.
315 bool ShouldTrackBrowser(Browser* browser) const;
initial.commit09911bf2008-07-26 23:55:29316
Christian Dullweberb13ffda2018-02-23 11:42:14317 // Will rebuild session commands if rebuild_on_next_save_ is true.
318 void RebuildCommandsIfRequired();
319
[email protected]23da84e152010-07-14 01:29:05320 // Call when certain session relevant notifications
321 // (tab_closed, nav_list_pruned) occur. In addition, this is
322 // currently called when Save() is called to compare how often the
323 // session data is currently saved verses when we may want to save it.
324 // It records the data in UMA stats.
[email protected]432115822011-07-10 15:52:27325 void RecordSessionUpdateHistogramData(int type,
[email protected]23da84e152010-07-14 01:29:05326 base::TimeTicks* last_updated_time);
327
[email protected]3efee4172014-01-23 13:53:36328 // Deletes session data if no windows are open for the current profile.
329 void MaybeDeleteSessionOnlyData();
330
skuhned1e250b2014-11-05 15:26:50331 // Unit test accessors.
skuhneb7409dcf2014-11-14 04:06:55332 sessions::BaseSessionService* GetBaseSessionServiceForTest();
skuhned1e250b2014-11-05 15:26:50333
skuhned58ab122014-10-22 20:23:02334 // The profile. This may be null during testing.
335 Profile* profile_;
336
blundell6d34c342015-09-11 09:09:10337 // Whether to use delayed save. Set to false when constructed with a FilePath
338 // (which should only be used for testing).
339 bool should_use_delayed_save_;
340
skuhned1e250b2014-11-05 15:26:50341 // The owned BaseSessionService.
dcheng4af48582016-04-19 00:29:35342 std::unique_ptr<sessions::BaseSessionService> base_session_service_;
skuhned1e250b2014-11-05 15:26:50343
initial.commit09911bf2008-07-26 23:55:29344 // Maps from session tab id to the range of navigation entries that has
345 // been written to disk.
346 //
347 // This is only used if not all the navigation entries have been
348 // written.
349 IdToRange tab_to_available_range_;
350
[email protected]6ea265a2008-10-30 02:58:36351 // When the user closes the last window, where the last window is the
initial.commit09911bf2008-07-26 23:55:29352 // last tabbed browser and no more tabbed browsers are open with the same
353 // profile, the window ID is added here. These IDs are only committed (which
354 // marks them as closed) if the user creates a new tabbed browser.
355 typedef std::set<SessionID::id_type> PendingWindowCloseIDs;
356 PendingWindowCloseIDs pending_window_close_ids_;
357
358 // Set of tabs that have been closed by way of the last window or last tab
359 // closing, but not yet committed.
360 typedef std::set<SessionID::id_type> PendingTabCloseIDs;
361 PendingTabCloseIDs pending_tab_close_ids_;
362
363 // When a window other than the last window (see description of
364 // pending_window_close_ids) is closed, the id is added to this set.
365 typedef std::set<SessionID::id_type> WindowClosingIDs;
366 WindowClosingIDs window_closing_ids_;
367
368 // Set of windows we're tracking changes to. This is only browsers that
skuhnec3aa8cf2014-10-30 06:02:45369 // return true from |ShouldRestoreWindowOfType|.
initial.commit09911bf2008-07-26 23:55:29370 typedef std::set<SessionID::id_type> WindowsTracking;
371 WindowsTracking windows_tracking_;
372
[email protected]982921f12009-10-27 21:43:53373 // Are there any open trackable browsers?
374 bool has_open_trackable_browsers_;
initial.commit09911bf2008-07-26 23:55:29375
[email protected]6ea265a2008-10-30 02:58:36376 // If true and a new tabbed browser is created and there are no opened tabbed
[email protected]982921f12009-10-27 21:43:53377 // browser (has_open_trackable_browsers_ is false), then the current session
[email protected]668cd422011-04-06 21:00:01378 // is made the last session. See description above class for details on
379 // current/last session.
[email protected]6ea265a2008-10-30 02:58:36380 bool move_on_new_browser_;
[email protected]169627b2008-12-06 19:30:19381
[email protected]c4340bc02012-04-25 02:49:38382 // For browser_tests, since we want to simulate the browser shutting down
383 // without quitting.
384 bool force_browser_not_alive_with_no_windows_;
385
Christian Dullweberb13ffda2018-02-23 11:42:14386 // Force session commands to be rebuild before next save event.
387 bool rebuild_on_next_save_;
388
sky1a14f492014-08-26 21:44:26389 base::WeakPtrFactory<SessionService> weak_factory_;
390
[email protected]169627b2008-12-06 19:30:19391 DISALLOW_COPY_AND_ASSIGN(SessionService);
initial.commit09911bf2008-07-26 23:55:29392};
393
[email protected]169627b2008-12-06 19:30:19394#endif // CHROME_BROWSER_SESSIONS_SESSION_SERVICE_H_