15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/task/cancelable_task_tracker.h" 17c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "base/threading/sequenced_worker_pool.h" 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/sessions/session_id.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Profile; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SessionBackend; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SessionCommand; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace sessions { 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SerializedNavigationEntry; 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BaseSessionService is the super class of both tab restore service and 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// session service. It contains commonality needed by both, in particular 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it manages a set of SessionCommands that are periodically sent to a 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SessionBackend. 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class BaseSessionService { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Identifies the type of session service this is. This is used by the 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // backend to determine the name of the files. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum SessionType { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SESSION_RESTORE, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAB_RESTORE 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a new BaseSessionService. After creation you need to invoke 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Init. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |type| gives the type of session service, |profile| the profile and 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |path| the path to save files to. If |profile| is non-NULL, |path| is 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ignored and instead the path comes from the profile. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BaseSessionService(SessionType type, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile() const { return profile_; } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deletes the last session. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeleteLastSession(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef base::Callback<void(ScopedVector<SessionCommand>)> 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InternalGetCommandsCallback; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BaseSessionService(); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the backend. 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SessionBackend* backend() const { return backend_.get(); } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the set of commands that needed to be scheduled. The commands 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the vector are owned by BaseSessionService, until they are scheduled 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the backend at which point the backend owns the commands. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SessionCommand*>& pending_commands() { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pending_commands_; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether the next save resets the file before writing to it. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_pending_reset(bool value) { pending_reset_ = value; } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pending_reset() const { return pending_reset_; } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the number of commands sent down since the last reset. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int commands_since_reset() const { return commands_since_reset_; } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules a command. This adds |command| to pending_commands_ and 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invokes StartSaveTimer to start a timer that invokes Save at a later 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // time. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ScheduleCommand(SessionCommand* command); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts the timer that invokes Save (if timer isn't already running). 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartSaveTimer(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Saves pending commands to the backend. This is invoked from the timer 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scheduled by StartSaveTimer. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Save(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a SessionCommand that represents a navigation. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionCommand* CreateUpdateTabNavigationCommand( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type tab_id, 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const sessions::SerializedNavigationEntry& navigation); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a SessionCommand that represents marking a tab as an application. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionCommand* CreateSetTabExtensionAppIDCommand( 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type tab_id, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a SessionCommand that containing user agent override used by a 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tab's navigations. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionCommand* CreateSetTabUserAgentOverrideCommand( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type tab_id, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user_agent_override); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a SessionCommand stores a browser window's app name. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionCommand* CreateSetWindowAppNameCommand( 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type window_id, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& app_name); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Converts a SessionCommand previously created by 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // CreateUpdateTabNavigationCommand into a 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // sessions::SerializedNavigationEntry. Returns true on success. If 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // successful |tab_id| is set to the id of the restored tab. 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool RestoreUpdateTabNavigationCommand( 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const SessionCommand& command, 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sessions::SerializedNavigationEntry* navigation, 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SessionID::id_type* tab_id); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extracts a SessionCommand as previously created by 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CreateSetTabExtensionAppIDCommand into the tab id and application 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension id. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool RestoreSetTabExtensionAppIDCommand( 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* tab_id, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* extension_app_id); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extracts a SessionCommand as previously created by 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CreateSetTabUserAgentOverrideCommand into the tab id and user agent. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool RestoreSetTabUserAgentOverrideCommand( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* tab_id, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* user_agent_override); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extracts a SessionCommand as previously created by 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CreateSetWindowAppNameCommand into the window id and application name. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool RestoreSetWindowAppNameCommand( 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* window_id, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* app_name); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the entry at specified |url| should be written to disk. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ShouldTrackEntry(const GURL& url); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invokes SessionBackend::ReadLastSessionCommands with callback on the 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // backend thread. 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If testing, SessionBackend::ReadLastSessionCommands is invoked directly. 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::CancelableTaskTracker::TaskId ScheduleGetLastSessionCommands( 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InternalGetCommandsCallback& callback, 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::CancelableTaskTracker* tracker); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 157c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // This posts the task to the SequencedWorkerPool, or run immediately 158c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // if the SequencedWorkerPool has been shutdown. 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void RunTaskOnBackendThread(const tracked_objects::Location& from_here, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Max number of navigation entries in each direction we'll persist. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int max_persist_navigation_count; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class BetterSessionRestoreCrashTest; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The profile. This may be null during testing. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The backend. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SessionBackend> backend_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commands we need to send over to the backend. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SessionCommand*> pending_commands_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether the backend file should be recreated the next time we send 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // over the commands. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pending_reset_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The number of commands sent to the backend before doing a reset. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int commands_since_reset_; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 184c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // A token to make sure that all tasks will be serialized. 185c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch base::SequencedWorkerPool::SequenceToken sequence_token_; 186c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Used to invoke Save. 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtrFactory<BaseSessionService> weak_factory_; 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BaseSessionService); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_H_ 194