summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sessions/base_session_service.h
blob: 527ca404a6d0c19c5cf4ca873d86d1da400d767a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_H_
#define CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_H_

#include "base/basictypes.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/threading/sequenced_worker_pool.h"
#include "components/sessions/session_id.h"
#include "url/gurl.h"

class Profile;
class SessionBackend;
class SessionCommand;

namespace sessions {
class SerializedNavigationEntry;
}

// BaseSessionService is the super class of both tab restore service and
// session service. It contains commonality needed by both, in particular
// it manages a set of SessionCommands that are periodically sent to a
// SessionBackend.
class BaseSessionService {
 public:
  // Identifies the type of session service this is. This is used by the
  // backend to determine the name of the files.
  enum SessionType {
    SESSION_RESTORE,
    TAB_RESTORE
  };

  // Creates a new BaseSessionService. After creation you need to invoke
  // Init.
  // |type| gives the type of session service, |profile| the profile and
  // |path| the path to save files to. If |profile| is non-NULL, |path| is
  // ignored and instead the path comes from the profile.
  BaseSessionService(SessionType type,
                     Profile* profile,
                     const base::FilePath& path);

  Profile* profile() const { return profile_; }

  // Deletes the last session.
  void DeleteLastSession();

  typedef base::Callback<void(ScopedVector<SessionCommand>)>
      InternalGetCommandsCallback;

 protected:
  virtual ~BaseSessionService();

  // Returns the backend.
  SessionBackend* backend() const { return backend_.get(); }

  // Returns the set of commands that needed to be scheduled. The commands
  // in the vector are owned by BaseSessionService, until they are scheduled
  // on the backend at which point the backend owns the commands.
  std::vector<SessionCommand*>&  pending_commands() {
    return pending_commands_;
  }

  // Whether the next save resets the file before writing to it.
  void set_pending_reset(bool value) { pending_reset_ = value; }
  bool pending_reset() const { return pending_reset_; }

  // Returns the number of commands sent down since the last reset.
  int commands_since_reset() const { return commands_since_reset_; }

  // Schedules a command. This adds |command| to pending_commands_ and
  // invokes StartSaveTimer to start a timer that invokes Save at a later
  // time.
  virtual void ScheduleCommand(SessionCommand* command);

  // Starts the timer that invokes Save (if timer isn't already running).
  void StartSaveTimer();

  // Saves pending commands to the backend. This is invoked from the timer
  // scheduled by StartSaveTimer.
  virtual void Save();

  // Creates a SessionCommand that represents a navigation.
  SessionCommand* CreateUpdateTabNavigationCommand(
      SessionID::id_type command_id,
      SessionID::id_type tab_id,
      const sessions::SerializedNavigationEntry& navigation);

  // Creates a SessionCommand that represents marking a tab as an application.
  SessionCommand* CreateSetTabExtensionAppIDCommand(
      SessionID::id_type command_id,
      SessionID::id_type tab_id,
      const std::string& extension_id);

  // Creates a SessionCommand that containing user agent override used by a
  // tab's navigations.
  SessionCommand* CreateSetTabUserAgentOverrideCommand(
      SessionID::id_type command_id,
      SessionID::id_type tab_id,
      const std::string& user_agent_override);

  // Creates a SessionCommand stores a browser window's app name.
  SessionCommand* CreateSetWindowAppNameCommand(
      SessionID::id_type command_id,
      SessionID::id_type window_id,
      const std::string& app_name);

  // Converts a SessionCommand previously created by
  // CreateUpdateTabNavigationCommand into a
  // sessions::SerializedNavigationEntry. Returns true on success. If
  // successful |tab_id| is set to the id of the restored tab.
  bool RestoreUpdateTabNavigationCommand(
      const SessionCommand& command,
      sessions::SerializedNavigationEntry* navigation,
      SessionID::id_type* tab_id);

  // Extracts a SessionCommand as previously created by
  // CreateSetTabExtensionAppIDCommand into the tab id and application
  // extension id.
  bool RestoreSetTabExtensionAppIDCommand(
      const SessionCommand& command,
      SessionID::id_type* tab_id,
      std::string* extension_app_id);

  // Extracts a SessionCommand as previously created by
  // CreateSetTabUserAgentOverrideCommand into the tab id and user agent.
  bool RestoreSetTabUserAgentOverrideCommand(
      const SessionCommand& command,
      SessionID::id_type* tab_id,
      std::string* user_agent_override);

  // Extracts a SessionCommand as previously created by
  // CreateSetWindowAppNameCommand into the window id and application name.
  bool RestoreSetWindowAppNameCommand(
      const SessionCommand& command,
      SessionID::id_type* window_id,
      std::string* app_name);

  // Returns true if the entry at specified |url| should be written to disk.
  bool ShouldTrackEntry(const GURL& url);

  // Invokes SessionBackend::ReadLastSessionCommands with callback on the
  // backend thread.
  // If testing, SessionBackend::ReadLastSessionCommands is invoked directly.
  base::CancelableTaskTracker::TaskId ScheduleGetLastSessionCommands(
      const InternalGetCommandsCallback& callback,
      base::CancelableTaskTracker* tracker);

  // This posts the task to the SequencedWorkerPool, or run immediately
  // if the SequencedWorkerPool has been shutdown.
  void RunTaskOnBackendThread(const tracked_objects::Location& from_here,
                              const base::Closure& task);

  // Max number of navigation entries in each direction we'll persist.
  static const int max_persist_navigation_count;

 private:
  friend class BetterSessionRestoreCrashTest;

  // The profile. This may be null during testing.
  Profile* profile_;

  // The backend.
  scoped_refptr<SessionBackend> backend_;

  // Commands we need to send over to the backend.
  std::vector<SessionCommand*>  pending_commands_;

  // Whether the backend file should be recreated the next time we send
  // over the commands.
  bool pending_reset_;

  // The number of commands sent to the backend before doing a reset.
  int commands_since_reset_;

  // A token to make sure that all tasks will be serialized.
  base::SequencedWorkerPool::SequenceToken sequence_token_;

  // Used to invoke Save.
  base::WeakPtrFactory<BaseSessionService> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(BaseSessionService);
};

#endif  // CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_H_