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