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 #pragma once 8 9 #include <vector> 10 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "chrome/browser/sessions/base_session_service.h" 14 #include "chrome/browser/sessions/session_command.h" 15 16 namespace net { 17 class 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. 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 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 58 // Appends the specified commands to the current file. If reset_first is 59 // true the the current file is recreated. 60 // 61 // NOTE: this deletes SessionCommands in commands as well as the supplied 62 // vector. 63 void AppendCommands(std::vector<SessionCommand*>* commands, 64 bool reset_first); 65 66 // Invoked from the service to read the commands that make up the last 67 // session, invokes ReadLastSessionCommandsImpl to do the work. 68 void ReadLastSessionCommands( 69 scoped_refptr<BaseSessionService::InternalGetCommandsRequest> request); 70 71 // Reads the commands from the last file. 72 // 73 // On success, the read commands are added to commands. It is up to the 74 // caller to delete the commands. 75 bool ReadLastSessionCommandsImpl(std::vector<SessionCommand*>* commands); 76 77 // Deletes the file containing the commands for the last session. 78 void DeleteLastSession(); 79 80 // Moves the current session to the last and resets the current. This is 81 // called during startup and if the user launchs the app and no tabbed 82 // browsers are running. 83 void MoveCurrentSessionToLastSession(); 84 85 // Invoked from the service to read the commands that make up the current 86 // session, invokes ReadCurrentSessionCommandsImpl to do the work. 87 void ReadCurrentSessionCommands( 88 scoped_refptr<BaseSessionService::InternalGetCommandsRequest> request); 89 90 // Reads the commands from the current file. 91 // 92 // On success, the read commands are added to commands. It is up to the 93 // caller to delete the commands. 94 bool ReadCurrentSessionCommandsImpl(std::vector<SessionCommand*>* commands); 95 96 private: 97 friend class base::RefCountedThreadSafe<SessionBackend>; 98 99 ~SessionBackend(); 100 101 // If current_session_file_ is open, it is truncated so that it is essentially 102 // empty (only contains the header). If current_session_file_ isn't open, it 103 // is is opened and the header is written to it. After this 104 // current_session_file_ contains no commands. 105 // NOTE: current_session_file_ may be NULL if the file couldn't be opened or 106 // the header couldn't be written. 107 void ResetFile(); 108 109 // Opens the current file and writes the header. On success a handle to 110 // the file is returned. 111 net::FileStream* OpenAndWriteHeader(const FilePath& path); 112 113 // Appends the specified commands to the specified file. 114 bool AppendCommandsToFile(net::FileStream* file, 115 const std::vector<SessionCommand*>& commands); 116 117 const BaseSessionService::SessionType type_; 118 119 // Returns the path to the last file. 120 FilePath GetLastSessionPath(); 121 122 // Returns the path to the current file. 123 FilePath GetCurrentSessionPath(); 124 125 // Directory files are relative to. 126 const FilePath path_to_dir_; 127 128 // Whether the previous target file is valid. 129 bool last_session_valid_; 130 131 // Handle to the target file. 132 scoped_ptr<net::FileStream> current_session_file_; 133 134 // Whether we've inited. Remember, the constructor is run on the 135 // Main thread, all others on the IO thread, hence lazy initialization. 136 bool inited_; 137 138 // If true, the file is empty (no commands have been added to it). 139 bool empty_file_; 140 141 DISALLOW_COPY_AND_ASSIGN(SessionBackend); 142 }; 143 144 #endif // CHROME_BROWSER_SESSIONS_SESSION_BACKEND_H_ 145