1 // Copyright (c) 2011 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_BASE_SESSION_SERVICE_H_ 6 #define CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_H_ 7 #pragma once 8 9 #include "base/basictypes.h" 10 #include "base/callback.h" 11 #include "base/file_path.h" 12 #include "base/memory/ref_counted.h" 13 #include "chrome/browser/sessions/session_id.h" 14 #include "content/browser/cancelable_request.h" 15 16 class NavigationEntry; 17 class Profile; 18 class SessionBackend; 19 class SessionCommand; 20 class TabNavigation; 21 22 namespace base { 23 class Thread; 24 } 25 26 // BaseSessionService is the super class of both tab restore service and 27 // session service. It contains commonality needed by both, in particular 28 // it manages a set of SessionCommands that are periodically sent to a 29 // SessionBackend. 30 class BaseSessionService : public CancelableRequestProvider, 31 public base::RefCountedThreadSafe<BaseSessionService> { 32 public: 33 // Identifies the type of session service this is. This is used by the 34 // backend to determine the name of the files. 35 enum SessionType { 36 SESSION_RESTORE, 37 TAB_RESTORE 38 }; 39 40 // Creates a new BaseSessionService. After creation you need to invoke 41 // Init. 42 // |type| gives the type of session service, |profile| the profile and 43 // |path| the path to save files to. If |profile| is non-NULL, |path| is 44 // ignored and instead the path comes from the profile. 45 BaseSessionService(SessionType type, 46 Profile* profile, 47 const FilePath& path); 48 49 Profile* profile() const { return profile_; } 50 51 // Deletes the last session. 52 void DeleteLastSession(); 53 54 class InternalGetCommandsRequest; 55 56 typedef Callback2<Handle, scoped_refptr<InternalGetCommandsRequest> >::Type 57 InternalGetCommandsCallback; 58 59 // Callback used when fetching the last session. The last session consists 60 // of a vector of SessionCommands. 61 class InternalGetCommandsRequest : 62 public CancelableRequest<InternalGetCommandsCallback> { 63 public: 64 explicit InternalGetCommandsRequest(CallbackType* callback) 65 : CancelableRequest<InternalGetCommandsCallback>(callback) { 66 } 67 68 // The commands. The backend fills this in for us. 69 std::vector<SessionCommand*> commands; 70 71 protected: 72 virtual ~InternalGetCommandsRequest(); 73 74 private: 75 DISALLOW_COPY_AND_ASSIGN(InternalGetCommandsRequest); 76 }; 77 78 protected: 79 friend class base::RefCountedThreadSafe<BaseSessionService>; 80 81 virtual ~BaseSessionService(); 82 83 // Returns the backend. 84 SessionBackend* backend() const { return backend_; } 85 86 // Returns the thread the backend runs on. This returns NULL during testing. 87 base::Thread* backend_thread() const { return backend_thread_; } 88 89 // Returns the set of commands that needed to be scheduled. The commands 90 // in the vector are owned by BaseSessionService, until they are scheduled 91 // on the backend at which point the backend owns the commands. 92 std::vector<SessionCommand*>& pending_commands() { 93 return pending_commands_; 94 } 95 96 // Whether the next save resets the file before writing to it. 97 void set_pending_reset(bool value) { pending_reset_ = value; } 98 bool pending_reset() const { return pending_reset_; } 99 100 // Returns the number of commands sent down since the last reset. 101 int commands_since_reset() const { return commands_since_reset_; } 102 103 // Schedules a command. This adds |command| to pending_commands_ and 104 // invokes StartSaveTimer to start a timer that invokes Save at a later 105 // time. 106 virtual void ScheduleCommand(SessionCommand* command); 107 108 // Starts the timer that invokes Save (if timer isn't already running). 109 void StartSaveTimer(); 110 111 // Saves pending commands to the backend. This is invoked from the timer 112 // scheduled by StartSaveTimer. 113 virtual void Save(); 114 115 // Creates a SessionCommand that represents a navigation. 116 SessionCommand* CreateUpdateTabNavigationCommand( 117 SessionID::id_type command_id, 118 SessionID::id_type tab_id, 119 int index, 120 const NavigationEntry& entry); 121 122 // Creates a SessionCommand that represents marking a tab as an application. 123 SessionCommand* CreateSetTabExtensionAppIDCommand( 124 SessionID::id_type command_id, 125 SessionID::id_type tab_id, 126 const std::string& extension_id); 127 128 // Converts a SessionCommand previously created by 129 // CreateUpdateTabNavigationCommand into a TabNavigation. Returns true 130 // on success. If successful |tab_id| is set to the id of the restored tab. 131 bool RestoreUpdateTabNavigationCommand(const SessionCommand& command, 132 TabNavigation* navigation, 133 SessionID::id_type* tab_id); 134 135 // Extracts a SessionCommand as previously created by 136 // CreateSetTabExtensionAppIDCommand into the tab id and application 137 // extension id. 138 bool RestoreSetTabExtensionAppIDCommand( 139 const SessionCommand& command, 140 SessionID::id_type* tab_id, 141 std::string* extension_app_id); 142 143 // Returns true if the NavigationEntry should be written to disk. 144 bool ShouldTrackEntry(const NavigationEntry& entry); 145 146 // Returns true if the TabNavigationshould be written to disk. 147 bool ShouldTrackEntry(const TabNavigation& navigation); 148 149 // Invokes ReadLastSessionCommands with request on the backend thread. 150 // If testing, ReadLastSessionCommands is invoked directly. 151 Handle ScheduleGetLastSessionCommands( 152 InternalGetCommandsRequest* request, 153 CancelableRequestConsumerBase* consumer); 154 155 // Invokes ReadCurrentSessionCommands with request on the backend thread. 156 // If testing, ReadLastSessionCommands is invoked directly. 157 Handle ScheduleGetCurrentSessionCommands( 158 InternalGetCommandsRequest* request, 159 CancelableRequestConsumerBase* consumer); 160 161 // Max number of navigation entries in each direction we'll persist. 162 static const int max_persist_navigation_count; 163 164 private: 165 // The profile. This may be null during testing. 166 Profile* profile_; 167 168 // Path to read from. This is only used if profile_ is NULL. 169 const FilePath& path_; 170 171 // The backend. 172 scoped_refptr<SessionBackend> backend_; 173 174 // Thread backend tasks are run on, is NULL during testing. 175 base::Thread* backend_thread_; 176 177 // Used to invoke Save. 178 ScopedRunnableMethodFactory<BaseSessionService> save_factory_; 179 180 // Commands we need to send over to the backend. 181 std::vector<SessionCommand*> pending_commands_; 182 183 // Whether the backend file should be recreated the next time we send 184 // over the commands. 185 bool pending_reset_; 186 187 // The number of commands sent to the backend before doing a reset. 188 int commands_since_reset_; 189 190 DISALLOW_COPY_AND_ASSIGN(BaseSessionService); 191 }; 192 193 #endif // CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_H_ 194