Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / sessions / session_service.h
blob0b5212d293ce1a3e40e6eaddc3fc754b1dcdef18
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
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_SESSIONS_SESSION_SERVICE_H_
6 #define CHROME_BROWSER_SESSIONS_SESSION_SERVICE_H_
8 #include <map>
9 #include <string>
11 #include "base/basictypes.h"
12 #include "base/callback.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/task/cancelable_task_tracker.h"
16 #include "base/time/time.h"
17 #include "chrome/browser/defaults.h"
18 #include "chrome/browser/sessions/base_session_service_delegate_impl.h"
19 #include "chrome/browser/sessions/session_service_utils.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_finder.h"
22 #include "chrome/browser/ui/browser_list_observer.h"
23 #include "components/keyed_service/core/keyed_service.h"
24 #include "components/sessions/session_service_commands.h"
25 #include "content/public/browser/notification_observer.h"
26 #include "content/public/browser/notification_registrar.h"
27 #include "ui/base/ui_base_types.h"
29 class Profile;
31 namespace content {
32 class NavigationEntry;
33 class WebContents;
34 } // namespace content
36 namespace sessions {
37 class SessionCommand;
38 struct SessionTab;
39 struct SessionWindow;
40 } // namespace sessions
42 // SessionService ------------------------------------------------------------
44 // SessionService is responsible for maintaining the state of open windows
45 // and tabs so that they can be restored at a later date. The state of the
46 // currently open browsers is referred to as the current session.
48 // SessionService supports restoring from the last session. The last session
49 // typically corresponds to the last run of the browser, but not always. For
50 // example, if the user has a tabbed browser and app window running, closes the
51 // tabbed browser, then creates a new tabbed browser the current session is made
52 // the last session and the current session reset. This is done to provide the
53 // illusion that app windows run in separate processes. Similar behavior occurs
54 // with incognito windows.
56 // SessionService itself uses functions from session_service_commands to store
57 // commands which can rebuild the open state of the browser (as |SessionWindow|,
58 // |SessionTab| and |SerializedNavigationEntry|). The commands are periodically
59 // flushed to |SessionBackend| and written to a file. Every so often
60 // |SessionService| rebuilds the contents of the file from the open state of the
61 // browser.
62 class SessionService : public BaseSessionServiceDelegateImpl,
63 public KeyedService,
64 public content::NotificationObserver,
65 public chrome::BrowserListObserver {
66 friend class SessionServiceTestHelper;
67 public:
68 // Used to distinguish an application from a ordinary content window.
69 enum AppType {
70 TYPE_APP,
71 TYPE_NORMAL
74 // Creates a SessionService for the specified profile.
75 explicit SessionService(Profile* profile);
76 // For testing.
77 explicit SessionService(const base::FilePath& save_path);
79 ~SessionService() override;
81 // This may be NULL during testing.
82 Profile* profile() const { return profile_; }
84 // Returns true if a new window opening should really be treated like the
85 // start of a session (with potential session restore, startup URLs, etc.).
86 // In particular, this is true if there are no tabbed browsers running
87 // currently (eg. because only background or other app pages are running).
88 bool ShouldNewWindowStartSession();
90 // Invoke at a point when you think session restore might occur. For example,
91 // during startup and window creation this is invoked to see if a session
92 // needs to be restored. If a session needs to be restored it is done so
93 // asynchronously and true is returned. If false is returned the session was
94 // not restored and the caller needs to create a new window.
95 bool RestoreIfNecessary(const std::vector<GURL>& urls_to_open);
97 // Resets the contents of the file from the current state of all open
98 // browsers whose profile matches our profile.
99 void ResetFromCurrentBrowsers();
101 // Moves the current session to the last session. This is useful when a
102 // checkpoint occurs, such as when the user launches the app and no tabbed
103 // browsers are running.
104 void MoveCurrentSessionToLastSession();
106 // Deletes the last session.
107 void DeleteLastSession();
109 // Associates a tab with a window.
110 void SetTabWindow(const SessionID& window_id,
111 const SessionID& tab_id);
113 // Sets the bounds of a window.
114 void SetWindowBounds(const SessionID& window_id,
115 const gfx::Rect& bounds,
116 ui::WindowShowState show_state);
118 // Sets the visual index of the tab in its parent window.
119 void SetTabIndexInWindow(const SessionID& window_id,
120 const SessionID& tab_id,
121 int new_index);
123 // Sets the pinned state of the tab.
124 void SetPinnedState(const SessionID& window_id,
125 const SessionID& tab_id,
126 bool is_pinned);
128 // Notification that a tab has been closed. |closed_by_user_gesture| comes
129 // from |WebContents::closed_by_user_gesture|; see it for details.
131 // Note: this is invoked from the NavigationController's destructor, which is
132 // after the actual tab has been removed.
133 void TabClosed(const SessionID& window_id,
134 const SessionID& tab_id,
135 bool closed_by_user_gesture);
137 // Notification a window has opened.
138 void WindowOpened(Browser* browser);
140 // Notification the window is about to close.
141 void WindowClosing(const SessionID& window_id);
143 // Notification a window has finished closing.
144 void WindowClosed(const SessionID& window_id);
146 // Called when a tab is inserted.
147 void TabInserted(content::WebContents* contents);
149 // Called when a tab is closing.
150 void TabClosing(content::WebContents* contents);
152 // Sets the type of window. In order for the contents of a window to be
153 // tracked SetWindowType must be invoked with a type we track
154 // (ShouldRestoreOfWindowType returns true).
155 void SetWindowType(const SessionID& window_id,
156 Browser::Type type,
157 AppType app_type);
159 // Sets the application name of the specified window.
160 void SetWindowAppName(const SessionID& window_id,
161 const std::string& app_name);
163 // Invoked when the NavigationController has removed entries from the back of
164 // the list. |count| gives the number of entries in the navigation controller.
165 void TabNavigationPathPrunedFromBack(const SessionID& window_id,
166 const SessionID& tab_id,
167 int count);
169 // Invoked when the NavigationController has removed entries from the front of
170 // the list. |count| gives the number of entries that were removed.
171 void TabNavigationPathPrunedFromFront(const SessionID& window_id,
172 const SessionID& tab_id,
173 int count);
175 // Updates the navigation entry for the specified tab.
176 void UpdateTabNavigation(
177 const SessionID& window_id,
178 const SessionID& tab_id,
179 const sessions::SerializedNavigationEntry& navigation);
181 // Notification that a tab has restored its entries or a closed tab is being
182 // reused.
183 void TabRestored(content::WebContents* tab, bool pinned);
185 // Sets the index of the selected entry in the navigation controller for the
186 // specified tab.
187 void SetSelectedNavigationIndex(const SessionID& window_id,
188 const SessionID& tab_id,
189 int index);
191 // Sets the index of the selected tab in the specified window.
192 void SetSelectedTabInWindow(const SessionID& window_id, int index);
194 // Sets the user agent override of the specified tab.
195 void SetTabUserAgentOverride(const SessionID& window_id,
196 const SessionID& tab_id,
197 const std::string& user_agent_override);
199 // Sets the application extension id of the specified tab.
200 void SetTabExtensionAppID(const SessionID& window_id,
201 const SessionID& tab_id,
202 const std::string& extension_app_id);
204 // Sets the last active time of the tab.
205 void SetLastActiveTime(const SessionID& window_id,
206 const SessionID& tab_id,
207 base::TimeTicks last_active_time);
209 // Callback from GetLastSession.
210 // The second parameter is the id of the window that was last active.
211 typedef base::Callback<void(ScopedVector<sessions::SessionWindow>,
212 SessionID::id_type)> SessionCallback;
214 // Fetches the contents of the last session, notifying the callback when
215 // done. If the callback is supplied an empty vector of SessionWindows
216 // it means the session could not be restored.
217 base::CancelableTaskTracker::TaskId GetLastSession(
218 const SessionCallback& callback,
219 base::CancelableTaskTracker* tracker);
221 // BaseSessionServiceDelegateImpl:
222 void OnSavedCommands() override;
224 private:
225 // Allow tests to access our innards for testing purposes.
226 FRIEND_TEST_ALL_PREFIXES(SessionServiceTest, SavedSessionNotification);
227 FRIEND_TEST_ALL_PREFIXES(SessionServiceTest, RestoreActivation1);
228 FRIEND_TEST_ALL_PREFIXES(SessionServiceTest, RestoreActivation2);
229 FRIEND_TEST_ALL_PREFIXES(SessionServiceTest, RemoveUnusedRestoreWindowsTest);
230 FRIEND_TEST_ALL_PREFIXES(NoStartupWindowTest, DontInitSessionServiceForApps);
232 typedef std::map<SessionID::id_type, std::pair<int, int> > IdToRange;
234 void Init();
236 // Returns true if a window of given |window_type| and |app_type| should get
237 // restored upon session restore.
238 bool ShouldRestoreWindowOfType(sessions::SessionWindow::WindowType type,
239 AppType app_type) const;
241 // Removes unrestorable windows from the previous windows list.
242 void RemoveUnusedRestoreWindows(
243 std::vector<sessions::SessionWindow*>* window_list);
245 // Implementation of RestoreIfNecessary. If |browser| is non-null and we need
246 // to restore, the tabs are added to it, otherwise a new browser is created.
247 bool RestoreIfNecessary(const std::vector<GURL>& urls_to_open,
248 Browser* browser);
250 void Observe(int type,
251 const content::NotificationSource& source,
252 const content::NotificationDetails& details) override;
254 // chrome::BrowserListObserver
255 void OnBrowserAdded(Browser* browser) override {}
256 void OnBrowserRemoved(Browser* browser) override {}
257 void OnBrowserSetLastActive(Browser* browser) override;
259 // Converts |commands| to SessionWindows and notifies the callback.
260 void OnGotSessionCommands(const SessionCallback& callback,
261 ScopedVector<sessions::SessionCommand> commands);
263 // Adds commands to commands that will recreate the state of the specified
264 // tab. This adds at most kMaxNavigationCountToPersist navigations (in each
265 // direction from the current navigation index).
266 // 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,
270 content::WebContents* tab,
271 int index_in_window,
272 bool is_pinned,
273 IdToRange* tab_to_available_range);
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,
280 IdToRange* tab_to_available_range,
281 std::set<SessionID::id_type>* windows_to_track);
283 // Iterates over all the known browsers invoking BuildCommandsForBrowser.
284 // 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).
287 void BuildCommandsFromBrowsers(
288 IdToRange* tab_to_available_range,
289 std::set<SessionID::id_type>* windows_to_track);
291 // 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();
295 // Schedules the specified command.
296 void ScheduleCommand(scoped_ptr<sessions::SessionCommand> command);
298 // Converts all pending tab/window closes to commands and schedules them.
299 void CommitPendingCloses();
301 // Returns true if there is only one window open with a single tab that shares
302 // our profile.
303 bool IsOnlyOneTabLeft() const;
305 // 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
307 // which |ShouldRestoreWindowOfType| returns true. See
308 // |ShouldRestoreWindowOfType| for details.
309 bool HasOpenTrackableBrowsers(const SessionID& window_id) const;
311 // Returns true if changes to tabs in the specified window should be tracked.
312 bool ShouldTrackChangesToWindow(const SessionID& window_id) const;
314 // Returns true if we track changes to the specified browser.
315 bool ShouldTrackBrowser(Browser* browser) const;
317 // Call when certain session relevant notifications
318 // (tab_closed, nav_list_pruned) occur. In addition, this is
319 // currently called when Save() is called to compare how often the
320 // session data is currently saved verses when we may want to save it.
321 // It records the data in UMA stats.
322 void RecordSessionUpdateHistogramData(int type,
323 base::TimeTicks* last_updated_time);
325 // Helper methods to record the histogram data
326 void RecordUpdatedTabClosed(base::TimeDelta delta, bool use_long_period);
327 void RecordUpdatedNavListPruned(base::TimeDelta delta, bool use_long_period);
328 void RecordUpdatedNavEntryCommit(base::TimeDelta delta, bool use_long_period);
329 void RecordUpdatedSaveTime(base::TimeDelta delta, bool use_long_period);
330 void RecordUpdatedSessionNavigationOrTab(base::TimeDelta delta,
331 bool use_long_period);
333 // Deletes session data if no windows are open for the current profile.
334 void MaybeDeleteSessionOnlyData();
336 // Unit test accessors.
337 sessions::BaseSessionService* GetBaseSessionServiceForTest();
339 // The profile. This may be null during testing.
340 Profile* profile_;
342 // The owned BaseSessionService.
343 scoped_ptr<sessions::BaseSessionService> base_session_service_;
345 content::NotificationRegistrar registrar_;
347 // Maps from session tab id to the range of navigation entries that has
348 // been written to disk.
350 // This is only used if not all the navigation entries have been
351 // written.
352 IdToRange tab_to_available_range_;
354 // When the user closes the last window, where the last window is the
355 // last tabbed browser and no more tabbed browsers are open with the same
356 // profile, the window ID is added here. These IDs are only committed (which
357 // marks them as closed) if the user creates a new tabbed browser.
358 typedef std::set<SessionID::id_type> PendingWindowCloseIDs;
359 PendingWindowCloseIDs pending_window_close_ids_;
361 // Set of tabs that have been closed by way of the last window or last tab
362 // closing, but not yet committed.
363 typedef std::set<SessionID::id_type> PendingTabCloseIDs;
364 PendingTabCloseIDs pending_tab_close_ids_;
366 // When a window other than the last window (see description of
367 // pending_window_close_ids) is closed, the id is added to this set.
368 typedef std::set<SessionID::id_type> WindowClosingIDs;
369 WindowClosingIDs window_closing_ids_;
371 // Set of windows we're tracking changes to. This is only browsers that
372 // return true from |ShouldRestoreWindowOfType|.
373 typedef std::set<SessionID::id_type> WindowsTracking;
374 WindowsTracking windows_tracking_;
376 // Are there any open trackable browsers?
377 bool has_open_trackable_browsers_;
379 // If true and a new tabbed browser is created and there are no opened tabbed
380 // browser (has_open_trackable_browsers_ is false), then the current session
381 // is made the last session. See description above class for details on
382 // current/last session.
383 bool move_on_new_browser_;
385 // Used for reporting frequency of session altering operations.
386 base::TimeTicks last_updated_tab_closed_time_;
387 base::TimeTicks last_updated_nav_list_pruned_time_;
388 base::TimeTicks last_updated_nav_entry_commit_time_;
389 base::TimeTicks last_updated_save_time_;
391 // Constants used in calculating histogram data.
392 const base::TimeDelta save_delay_in_millis_;
393 const base::TimeDelta save_delay_in_mins_;
394 const base::TimeDelta save_delay_in_hrs_;
396 // For browser_tests, since we want to simulate the browser shutting down
397 // without quitting.
398 bool force_browser_not_alive_with_no_windows_;
400 base::WeakPtrFactory<SessionService> weak_factory_;
402 DISALLOW_COPY_AND_ASSIGN(SessionService);
405 #endif // CHROME_BROWSER_SESSIONS_SESSION_SERVICE_H_