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.
4 
5 #ifndef CHROME_BROWSER_SESSIONS_SESSION_RESTORE_H_
6 #define CHROME_BROWSER_SESSIONS_SESSION_RESTORE_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <vector>
12 
13 #include "base/callback_list.h"
14 #include "base/gtest_prod_util.h"
15 #include "base/macros.h"
16 #include "base/observer_list.h"
17 #include "chrome/browser/sessions/session_restore_observer.h"
18 #include "components/history/core/browser/history_service.h"
19 #include "components/sessions/core/session_types.h"
20 #include "ui/base/window_open_disposition.h"
21 
22 class Browser;
23 class Profile;
24 class SessionRestoreImpl;
25 
26 namespace content {
27 class WebContents;
28 }
29 
30 // SessionRestore handles restoring either the last or saved session. Session
31 // restore come in two variants, asynchronous or synchronous. The synchronous
32 // variety is meant for startup and blocks until restore is complete.
33 class SessionRestore {
34  public:
35   // Bitmask representing behaviors available when restoring a session. Populate
36   // using the values below.
37   using BehaviorBitmask = uint32_t;
38 
39   enum {
40     // Indicates the active tab of the supplied browser should be closed.
41     CLOBBER_CURRENT_TAB          = 1 << 0,
42 
43     // Indicates that if there is a problem restoring the last session then a
44     // new tabbed browser should be created.
45     ALWAYS_CREATE_TABBED_BROWSER = 1 << 1,
46 
47     // Restore blocks until complete. This is intended for use during startup
48     // when we want to block until restore is complete.
49     SYNCHRONOUS                  = 1 << 2,
50   };
51 
52   // Notification callback list.
53   using CallbackList = base::RepeatingCallbackList<void(int)>;
54 
55   // Used by objects calling RegisterOnSessionRestoredCallback() to de-register
56   // themselves when they are destroyed.
57   using CallbackSubscription =
58       std::unique_ptr<base::RepeatingCallbackList<void(int)>::Subscription>;
59 
60   // Restores the last session. |behavior| is a bitmask of Behaviors, see it
61   // for details. If |browser| is non-null the tabs for the first window are
62   // added to it. Returns the last active browser.
63   //
64   // If |urls_to_open| is non-empty, a tab is added for each of the URLs.
65   static Browser* RestoreSession(Profile* profile,
66                                  Browser* browser,
67                                  BehaviorBitmask behavior,
68                                  const std::vector<GURL>& urls_to_open);
69 
70   // Restores the last session when the last session crashed. It's a wrapper
71   // of function RestoreSession.
72   static void RestoreSessionAfterCrash(Browser* browser);
73 
74   // Opens the startup pages when the last session crashed.
75   static void OpenStartupPagesAfterCrash(Browser* browser);
76 
77   // Specifically used in the restoration of a foreign session.  This function
78   // restores the given session windows to multiple browsers. Returns the
79   // created Browsers.
80   static std::vector<Browser*> RestoreForeignSessionWindows(
81       Profile* profile,
82       std::vector<const sessions::SessionWindow*>::const_iterator begin,
83       std::vector<const sessions::SessionWindow*>::const_iterator end);
84 
85   // Specifically used in the restoration of a foreign session.  This method
86   // restores the given session tab to the browser of |source_web_contents| if
87   // the disposition is not NEW_WINDOW. Returns the WebContents corresponding
88   // to the restored tab. If |disposition| is CURRENT_TAB, |source_web_contents|
89   // may be destroyed.
90   static content::WebContents* RestoreForeignSessionTab(
91       content::WebContents* source_web_contents,
92       const sessions::SessionTab& tab,
93       WindowOpenDisposition disposition);
94 
95   // Returns true if we're in the process of restoring |profile|.
96   static bool IsRestoring(const Profile* profile);
97 
98   // Returns true if synchronously restoring a session.
99   static bool IsRestoringSynchronously();
100 
101   // Registers a callback that is notified every time session restore completes.
102   // Note that 'complete' means all the browsers and tabs have been created but
103   // have not necessarily finished loading. The integer supplied to the callback
104   // indicates the number of tabs that were created.
105   static CallbackSubscription RegisterOnSessionRestoredCallback(
106       const base::RepeatingCallback<void(int)>& callback);
107 
108   // Add/remove an observer to/from this session restore.
109   static void AddObserver(SessionRestoreObserver* observer);
110   static void RemoveObserver(SessionRestoreObserver* observer);
111 
112   // Get called when the tab loader finishes loading tabs in tab restore even
113   // without session restore started.
114   static void OnTabLoaderFinishedLoadingTabs();
115 
116   // Is called when session restore is going to restore a tab.
117   static void OnWillRestoreTab(content::WebContents* web_contents);
118 
119  private:
120   friend class SessionRestoreImpl;
121   FRIEND_TEST_ALL_PREFIXES(SessionRestoreObserverTest, SingleSessionRestore);
122   FRIEND_TEST_ALL_PREFIXES(SessionRestoreObserverTest,
123                            SequentialSessionRestores);
124   FRIEND_TEST_ALL_PREFIXES(SessionRestoreObserverTest,
125                            ConcurrentSessionRestores);
126   FRIEND_TEST_ALL_PREFIXES(SessionRestoreObserverTest,
127                            TabManagerShouldObserveSessionRestore);
128 
129   // Session restore observer list.
130   using SessionRestoreObserverList =
131       base::ObserverList<SessionRestoreObserver>::Unchecked;
132 
133   SessionRestore();
134 
135   // Accessor for |*on_session_restored_callbacks_|. Creates a new object the
136   // first time so that it always returns a valid object.
on_session_restored_callbacks()137   static CallbackList* on_session_restored_callbacks() {
138     if (!on_session_restored_callbacks_)
139       on_session_restored_callbacks_ = new CallbackList();
140     return on_session_restored_callbacks_;
141   }
142 
143   // Accessor for the observer list. Create the list the first time to always
144   // return a valid reference.
observers()145   static SessionRestoreObserverList* observers() {
146     if (!observers_)
147       observers_ = new SessionRestoreObserverList();
148     return observers_;
149   }
150 
151   // Contains all registered callbacks for session restore notifications.
152   static CallbackList* on_session_restored_callbacks_;
153 
154   // Notify SessionRestoreObservers session restore started. If there are
155   // multiple concurrent session restores, observers get notified only once in
156   // the first session restore.
157   static void NotifySessionRestoreStartedLoadingTabs();
158 
159   // Contains all registered observers for session restore events.
160   static SessionRestoreObserverList* observers_;
161 
162   // Whether session restore started or not.
163   static bool session_restore_started_;
164 
165   DISALLOW_COPY_AND_ASSIGN(SessionRestore);
166 };
167 
168 #endif  // CHROME_BROWSER_SESSIONS_SESSION_RESTORE_H_
169