| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sessions/session_backend.h" | 5 #include "chrome/browser/sessions/session_backend.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/files/file.h" | 9 #include "base/files/file.h" |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 buffer_(SessionBackend::kFileReadBufferSize, 0), | 45 buffer_(SessionBackend::kFileReadBufferSize, 0), |
| 46 buffer_position_(0), | 46 buffer_position_(0), |
| 47 available_count_(0) { | 47 available_count_(0) { |
| 48 file_.reset(new base::File( | 48 file_.reset(new base::File( |
| 49 path, base::File::FLAG_OPEN | base::File::FLAG_READ)); | 49 path, base::File::FLAG_OPEN | base::File::FLAG_READ)); |
| 50 } | 50 } |
| 51 // Reads the contents of the file specified in the constructor, returning | 51 // Reads the contents of the file specified in the constructor, returning |
| 52 // true on success. It is up to the caller to free all SessionCommands | 52 // true on success. It is up to the caller to free all SessionCommands |
| 53 // added to commands. | 53 // added to commands. |
| 54 bool Read(BaseSessionService::SessionType type, | 54 bool Read(BaseSessionService::SessionType type, |
| 55 std::vector<SessionCommand*>* commands); | 55 ScopedVector<SessionCommand>* commands); |
| 56 | 56 |
| 57 private: | 57 private: |
| 58 // Reads a single command, returning it. A return value of NULL indicates | 58 // Reads a single command, returning it. A return value of NULL indicates |
| 59 // either there are no commands, or there was an error. Use errored_ to | 59 // either there are no commands, or there was an error. Use errored_ to |
| 60 // distinguish the two. If NULL is returned, and there is no error, it means | 60 // distinguish the two. If NULL is returned, and there is no error, it means |
| 61 // the end of file was successfully reached. | 61 // the end of file was successfully reached. |
| 62 SessionCommand* ReadCommand(); | 62 SessionCommand* ReadCommand(); |
| 63 | 63 |
| 64 // Shifts the unused portion of buffer_ to the beginning and fills the | 64 // Shifts the unused portion of buffer_ to the beginning and fills the |
| 65 // remaining portion with data from the file. Returns false if the buffer | 65 // remaining portion with data from the file. Returns false if the buffer |
| (...skipping 13 matching lines...) Expand all Loading... |
| 79 // Position in buffer_ of the data. | 79 // Position in buffer_ of the data. |
| 80 size_t buffer_position_; | 80 size_t buffer_position_; |
| 81 | 81 |
| 82 // Number of available bytes; relative to buffer_position_. | 82 // Number of available bytes; relative to buffer_position_. |
| 83 size_t available_count_; | 83 size_t available_count_; |
| 84 | 84 |
| 85 DISALLOW_COPY_AND_ASSIGN(SessionFileReader); | 85 DISALLOW_COPY_AND_ASSIGN(SessionFileReader); |
| 86 }; | 86 }; |
| 87 | 87 |
| 88 bool SessionFileReader::Read(BaseSessionService::SessionType type, | 88 bool SessionFileReader::Read(BaseSessionService::SessionType type, |
| 89 std::vector<SessionCommand*>* commands) { | 89 ScopedVector<SessionCommand>* commands) { |
| 90 if (!file_->IsValid()) | 90 if (!file_->IsValid()) |
| 91 return false; | 91 return false; |
| 92 FileHeader header; | 92 FileHeader header; |
| 93 int read_count; | 93 int read_count; |
| 94 TimeTicks start_time = TimeTicks::Now(); | 94 TimeTicks start_time = TimeTicks::Now(); |
| 95 read_count = file_->ReadAtCurrentPos(reinterpret_cast<char*>(&header), | 95 read_count = file_->ReadAtCurrentPos(reinterpret_cast<char*>(&header), |
| 96 sizeof(header)); | 96 sizeof(header)); |
| 97 if (read_count != sizeof(header) || header.signature != kFileSignature || | 97 if (read_count != sizeof(header) || header.signature != kFileSignature || |
| 98 header.version != kFileCurrentVersion) | 98 header.version != kFileCurrentVersion) |
| 99 return false; | 99 return false; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 | 214 |
| 215 inited_ = true; | 215 inited_ = true; |
| 216 | 216 |
| 217 // Create the directory for session info. | 217 // Create the directory for session info. |
| 218 base::CreateDirectory(path_to_dir_); | 218 base::CreateDirectory(path_to_dir_); |
| 219 | 219 |
| 220 MoveCurrentSessionToLastSession(); | 220 MoveCurrentSessionToLastSession(); |
| 221 } | 221 } |
| 222 | 222 |
| 223 void SessionBackend::AppendCommands( | 223 void SessionBackend::AppendCommands( |
| 224 std::vector<SessionCommand*>* commands, | 224 ScopedVector<SessionCommand>* commands, |
| 225 bool reset_first) { | 225 bool reset_first) { |
| 226 Init(); | 226 Init(); |
| 227 // Make sure and check current_session_file_, if opening the file failed | 227 // Make sure and check current_session_file_, if opening the file failed |
| 228 // current_session_file_ will be NULL. | 228 // current_session_file_ will be NULL. |
| 229 if ((reset_first && !empty_file_) || !current_session_file_.get() || | 229 if ((reset_first && !empty_file_) || !current_session_file_.get() || |
| 230 !current_session_file_->IsValid()) { | 230 !current_session_file_->IsValid()) { |
| 231 ResetFile(); | 231 ResetFile(); |
| 232 } | 232 } |
| 233 // Need to check current_session_file_ again, ResetFile may fail. | 233 // Need to check current_session_file_ again, ResetFile may fail. |
| 234 if (current_session_file_.get() && current_session_file_->IsValid() && | 234 if (current_session_file_.get() && current_session_file_->IsValid() && |
| 235 !AppendCommandsToFile(current_session_file_.get(), *commands)) { | 235 !AppendCommandsToFile(current_session_file_.get(), *commands)) { |
| 236 current_session_file_.reset(NULL); | 236 current_session_file_.reset(NULL); |
| 237 } | 237 } |
| 238 empty_file_ = false; | 238 empty_file_ = false; |
| 239 STLDeleteElements(commands); | 239 // Deleting the ScopedVector will also delete its elements. |
| 240 delete commands; | 240 delete commands; |
| 241 } | 241 } |
| 242 | 242 |
| 243 void SessionBackend::ReadLastSessionCommands( | 243 void SessionBackend::ReadLastSessionCommands( |
| 244 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled, | 244 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled, |
| 245 const BaseSessionService::InternalGetCommandsCallback& callback) { | 245 const BaseSessionService::GetCommandsCallback& callback) { |
| 246 if (is_canceled.Run()) | 246 if (is_canceled.Run()) |
| 247 return; | 247 return; |
| 248 | 248 |
| 249 Init(); | 249 Init(); |
| 250 | 250 |
| 251 ScopedVector<SessionCommand> commands; | 251 ScopedVector<SessionCommand> commands; |
| 252 ReadLastSessionCommandsImpl(&(commands.get())); | 252 ReadLastSessionCommandsImpl(&commands); |
| 253 callback.Run(commands.Pass()); | 253 callback.Run(commands.Pass()); |
| 254 } | 254 } |
| 255 | 255 |
| 256 bool SessionBackend::ReadLastSessionCommandsImpl( | 256 bool SessionBackend::ReadLastSessionCommandsImpl( |
| 257 std::vector<SessionCommand*>* commands) { | 257 ScopedVector<SessionCommand>* commands) { |
| 258 Init(); | 258 Init(); |
| 259 SessionFileReader file_reader(GetLastSessionPath()); | 259 SessionFileReader file_reader(GetLastSessionPath()); |
| 260 return file_reader.Read(type_, commands); | 260 return file_reader.Read(type_, commands); |
| 261 } | 261 } |
| 262 | 262 |
| 263 void SessionBackend::DeleteLastSession() { | 263 void SessionBackend::DeleteLastSession() { |
| 264 Init(); | 264 Init(); |
| 265 base::DeleteFile(GetLastSessionPath(), false); | 265 base::DeleteFile(GetLastSessionPath(), false); |
| 266 } | 266 } |
| 267 | 267 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 288 } | 288 } |
| 289 | 289 |
| 290 if (base::PathExists(current_session_path)) | 290 if (base::PathExists(current_session_path)) |
| 291 base::DeleteFile(current_session_path, false); | 291 base::DeleteFile(current_session_path, false); |
| 292 | 292 |
| 293 // Create and open the file for the current session. | 293 // Create and open the file for the current session. |
| 294 ResetFile(); | 294 ResetFile(); |
| 295 } | 295 } |
| 296 | 296 |
| 297 bool SessionBackend::ReadCurrentSessionCommandsImpl( | 297 bool SessionBackend::ReadCurrentSessionCommandsImpl( |
| 298 std::vector<SessionCommand*>* commands) { | 298 ScopedVector<SessionCommand>* commands) { |
| 299 Init(); | 299 Init(); |
| 300 SessionFileReader file_reader(GetCurrentSessionPath()); | 300 SessionFileReader file_reader(GetCurrentSessionPath()); |
| 301 return file_reader.Read(type_, commands); | 301 return file_reader.Read(type_, commands); |
| 302 } | 302 } |
| 303 | 303 |
| 304 bool SessionBackend::AppendCommandsToFile(base::File* file, | 304 bool SessionBackend::AppendCommandsToFile(base::File* file, |
| 305 const std::vector<SessionCommand*>& commands) { | 305 const ScopedVector<SessionCommand>& commands) { |
| 306 for (std::vector<SessionCommand*>::const_iterator i = commands.begin(); | 306 for (ScopedVector<SessionCommand>::const_iterator i = commands.begin(); |
| 307 i != commands.end(); ++i) { | 307 i != commands.end(); ++i) { |
| 308 int wrote; | 308 int wrote; |
| 309 const size_type content_size = static_cast<size_type>((*i)->size()); | 309 const size_type content_size = static_cast<size_type>((*i)->size()); |
| 310 const size_type total_size = content_size + sizeof(id_type); | 310 const size_type total_size = content_size + sizeof(id_type); |
| 311 if (type_ == BaseSessionService::TAB_RESTORE) | 311 if (type_ == BaseSessionService::TAB_RESTORE) |
| 312 UMA_HISTOGRAM_COUNTS("TabRestore.command_size", total_size); | 312 UMA_HISTOGRAM_COUNTS("TabRestore.command_size", total_size); |
| 313 else | 313 else |
| 314 UMA_HISTOGRAM_COUNTS("SessionRestore.command_size", total_size); | 314 UMA_HISTOGRAM_COUNTS("SessionRestore.command_size", total_size); |
| 315 wrote = file->WriteAtCurrentPos(reinterpret_cast<const char*>(&total_size), | 315 wrote = file->WriteAtCurrentPos(reinterpret_cast<const char*>(&total_size), |
| 316 sizeof(total_size)); | 316 sizeof(total_size)); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 } | 395 } |
| 396 | 396 |
| 397 base::FilePath SessionBackend::GetCurrentSessionPath() { | 397 base::FilePath SessionBackend::GetCurrentSessionPath() { |
| 398 base::FilePath path = path_to_dir_; | 398 base::FilePath path = path_to_dir_; |
| 399 if (type_ == BaseSessionService::TAB_RESTORE) | 399 if (type_ == BaseSessionService::TAB_RESTORE) |
| 400 path = path.AppendASCII(kCurrentTabSessionFileName); | 400 path = path.AppendASCII(kCurrentTabSessionFileName); |
| 401 else | 401 else |
| 402 path = path.AppendASCII(kCurrentSessionFileName); | 402 path = path.AppendASCII(kCurrentSessionFileName); |
| 403 return path; | 403 return path; |
| 404 } | 404 } |
| OLD | NEW |