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