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