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 "base/task/cancelable_task_tracker.h" 13 #include "chrome/browser/sessions/base_session_service.h" 14 #include "chrome/browser/sessions/session_command.h" 15 16 namespace base { 17 class File; 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. 33 class 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(); inited()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 base::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 base::File* OpenAndWriteHeader(const base::FilePath& path); 109 110 // Appends the specified commands to the specified file. 111 bool AppendCommandsToFile(base::File* 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<base::File> 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