session_backend.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2011 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_SESSION_BACKEND_H_
6#define CHROME_BROWSER_SESSIONS_SESSION_BACKEND_H_
7
8#include <vector>
9
10#include "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
12#include "chrome/browser/sessions/base_session_service.h"
13#include "chrome/browser/sessions/session_command.h"
14#include "chrome/common/cancelable_task_tracker.h"
15
16namespace net {
17class FileStream;
18}
19
20// SessionBackend -------------------------------------------------------------
21
22// SessionBackend is the backend used by BaseSessionService. It is responsible
23// for maintaining two files:
24// . The current file, which is the file commands passed to AppendCommands
25//   get written to.
26// . The last file. When created the current file is moved to the last
27//   file.
28//
29// Each file contains an arbitrary set of commands supplied from
30// BaseSessionService. A command consists of a unique id and a stream of bytes.
31// SessionBackend does not use the id in anyway, that is used by
32// BaseSessionService.
33class SessionBackend : public base::RefCountedThreadSafe<SessionBackend> {
34 public:
35  typedef SessionCommand::id_type id_type;
36  typedef SessionCommand::size_type size_type;
37
38  // Initial size of the buffer used in reading the file. This is exposed
39  // for testing.
40  static const int kFileReadBufferSize;
41
42  // Creates a SessionBackend. This method is invoked on the MAIN thread,
43  // and does no IO. The real work is done from Init, which is invoked on
44  // the file thread.
45  //
46  // |path_to_dir| gives the path the files are written two, and |type|
47  // indicates which service is using this backend. |type| is used to determine
48  // the name of the files to use as well as for logging.
49  SessionBackend(BaseSessionService::SessionType type,
50                 const base::FilePath& path_to_dir);
51
52  // Moves the current file to the last file, and recreates the current file.
53  //
54  // NOTE: this is invoked before every command, and does nothing if we've
55  // already Init'ed.
56  void Init();
57  bool inited() const { return inited_; }
58
59  // Appends the specified commands to the current file. If reset_first is
60  // true the the current file is recreated.
61  //
62  // NOTE: this deletes SessionCommands in commands as well as the supplied
63  // vector.
64  void AppendCommands(std::vector<SessionCommand*>* commands,
65                      bool reset_first);
66
67  // Invoked from the service to read the commands that make up the last
68  // session, invokes ReadLastSessionCommandsImpl to do the work.
69  void ReadLastSessionCommands(
70      const CancelableTaskTracker::IsCanceledCallback& is_canceled,
71      const BaseSessionService::InternalGetCommandsCallback& callback);
72
73  // Reads the commands from the last file.
74  //
75  // On success, the read commands are added to commands. It is up to the
76  // caller to delete the commands.
77  bool ReadLastSessionCommandsImpl(std::vector<SessionCommand*>* commands);
78
79  // Deletes the file containing the commands for the last session.
80  void DeleteLastSession();
81
82  // Moves the current session to the last and resets the current. This is
83  // called during startup and if the user launchs the app and no tabbed
84  // browsers are running.
85  void MoveCurrentSessionToLastSession();
86
87  // Reads the commands from the current file.
88  //
89  // On success, the read commands are added to commands. It is up to the
90  // caller to delete the commands.
91  bool ReadCurrentSessionCommandsImpl(std::vector<SessionCommand*>* commands);
92
93 private:
94  friend class base::RefCountedThreadSafe<SessionBackend>;
95
96  ~SessionBackend();
97
98  // If current_session_file_ is open, it is truncated so that it is essentially
99  // empty (only contains the header). If current_session_file_ isn't open, it
100  // is is opened and the header is written to it. After this
101  // current_session_file_ contains no commands.
102  // NOTE: current_session_file_ may be NULL if the file couldn't be opened or
103  // the header couldn't be written.
104  void ResetFile();
105
106  // Opens the current file and writes the header. On success a handle to
107  // the file is returned.
108  net::FileStream* OpenAndWriteHeader(const base::FilePath& path);
109
110  // Appends the specified commands to the specified file.
111  bool AppendCommandsToFile(net::FileStream* file,
112                            const std::vector<SessionCommand*>& commands);
113
114  const BaseSessionService::SessionType type_;
115
116  // Returns the path to the last file.
117  base::FilePath GetLastSessionPath();
118
119  // Returns the path to the current file.
120  base::FilePath GetCurrentSessionPath();
121
122  // Directory files are relative to.
123  const base::FilePath path_to_dir_;
124
125  // Whether the previous target file is valid.
126  bool last_session_valid_;
127
128  // Handle to the target file.
129  scoped_ptr<net::FileStream> current_session_file_;
130
131  // Whether we've inited. Remember, the constructor is run on the
132  // Main thread, all others on the IO thread, hence lazy initialization.
133  bool inited_;
134
135  // If true, the file is empty (no commands have been added to it).
136  bool empty_file_;
137
138  DISALLOW_COPY_AND_ASSIGN(SessionBackend);
139};
140
141#endif  // CHROME_BROWSER_SESSIONS_SESSION_BACKEND_H_
142