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 "webkit/fileapi/file_writer_delegate.h" | 5 #include "webkit/fileapi/file_writer_delegate.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/file_util_proxy.h" | 9 #include "base/file_util_proxy.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
11 #include "base/message_loop_proxy.h" | 11 #include "base/message_loop_proxy.h" |
12 #include "base/sequenced_task_runner.h" | 12 #include "base/sequenced_task_runner.h" |
13 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
14 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
15 #include "webkit/fileapi/file_stream_writer.h" | 15 #include "webkit/fileapi/file_stream_writer.h" |
16 #include "webkit/fileapi/file_system_context.h" | 16 #include "webkit/fileapi/file_system_context.h" |
17 | 17 |
18 namespace fileapi { | 18 namespace fileapi { |
19 | 19 |
20 static const int kReadBufSize = 32768; | 20 static const int kReadBufSize = 32768; |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 base::PlatformFileError NetErrorToPlatformFileError(int error) { | 24 base::PlatformFileError NetErrorToPlatformFileError(int error) { |
25 // TODO(kinuko): Move this static method to more convenient place. | 25 // TODO(kinuko): Move this static method to more convenient place. |
26 switch (error) { | 26 switch (error) { |
| 27 case net::OK: |
| 28 return base::PLATFORM_FILE_OK; |
27 case net::ERR_FILE_NO_SPACE: | 29 case net::ERR_FILE_NO_SPACE: |
28 return base::PLATFORM_FILE_ERROR_NO_SPACE; | 30 return base::PLATFORM_FILE_ERROR_NO_SPACE; |
29 case net::ERR_FILE_NOT_FOUND: | 31 case net::ERR_FILE_NOT_FOUND: |
30 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 32 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
31 case net::ERR_ACCESS_DENIED: | 33 case net::ERR_ACCESS_DENIED: |
32 return base::PLATFORM_FILE_ERROR_ACCESS_DENIED; | 34 return base::PLATFORM_FILE_ERROR_ACCESS_DENIED; |
33 default: | 35 default: |
34 return base::PLATFORM_FILE_ERROR_FAILED; | 36 return base::PLATFORM_FILE_ERROR_FAILED; |
35 } | 37 } |
36 } | 38 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 FileWriterDelegate::GetCompletionStatusOnError() const { | 182 FileWriterDelegate::GetCompletionStatusOnError() const { |
181 return writing_started_ ? ERROR_WRITE_STARTED : ERROR_WRITE_NOT_STARTED; | 183 return writing_started_ ? ERROR_WRITE_STARTED : ERROR_WRITE_NOT_STARTED; |
182 } | 184 } |
183 | 185 |
184 void FileWriterDelegate::OnError(base::PlatformFileError error) { | 186 void FileWriterDelegate::OnError(base::PlatformFileError error) { |
185 if (request_.get()) { | 187 if (request_.get()) { |
186 request_->set_delegate(NULL); | 188 request_->set_delegate(NULL); |
187 request_->Cancel(); | 189 request_->Cancel(); |
188 } | 190 } |
189 | 191 |
190 write_callback_.Run(error, 0, GetCompletionStatusOnError()); | 192 if (writing_started_) |
| 193 FlushForCompletion(error, 0, ERROR_WRITE_STARTED); |
| 194 else |
| 195 write_callback_.Run(error, 0, ERROR_WRITE_NOT_STARTED); |
191 } | 196 } |
192 | 197 |
193 void FileWriterDelegate::OnProgress(int bytes_written, bool done) { | 198 void FileWriterDelegate::OnProgress(int bytes_written, bool done) { |
194 DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); | 199 DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); |
195 static const int kMinProgressDelayMS = 200; | 200 static const int kMinProgressDelayMS = 200; |
196 base::Time currentTime = base::Time::Now(); | 201 base::Time currentTime = base::Time::Now(); |
197 if (done || last_progress_event_time_.is_null() || | 202 if (done || last_progress_event_time_.is_null() || |
198 (currentTime - last_progress_event_time_).InMilliseconds() > | 203 (currentTime - last_progress_event_time_).InMilliseconds() > |
199 kMinProgressDelayMS) { | 204 kMinProgressDelayMS) { |
200 bytes_written += bytes_written_backlog_; | 205 bytes_written += bytes_written_backlog_; |
201 last_progress_event_time_ = currentTime; | 206 last_progress_event_time_ = currentTime; |
202 bytes_written_backlog_ = 0; | 207 bytes_written_backlog_ = 0; |
203 | 208 |
204 WriteProgressStatus status = done ? SUCCESS_COMPLETED : SUCCESS_IO_PENDING; | 209 if (done) { |
205 write_callback_.Run(base::PLATFORM_FILE_OK, bytes_written, status); | 210 FlushForCompletion(base::PLATFORM_FILE_OK, bytes_written, |
| 211 SUCCESS_COMPLETED); |
| 212 } else { |
| 213 write_callback_.Run(base::PLATFORM_FILE_OK, bytes_written, |
| 214 SUCCESS_IO_PENDING); |
| 215 } |
206 return; | 216 return; |
207 } | 217 } |
208 bytes_written_backlog_ += bytes_written; | 218 bytes_written_backlog_ += bytes_written; |
209 } | 219 } |
210 | 220 |
211 void FileWriterDelegate::OnWriteCancelled(int status) { | 221 void FileWriterDelegate::OnWriteCancelled(int status) { |
212 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, | 222 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, |
213 GetCompletionStatusOnError()); | 223 GetCompletionStatusOnError()); |
214 } | 224 } |
215 | 225 |
| 226 void FileWriterDelegate::FlushForCompletion( |
| 227 base::PlatformFileError error, |
| 228 int bytes_written, |
| 229 WriteProgressStatus progress_status) { |
| 230 int flush_error = file_stream_writer_->Flush( |
| 231 base::Bind(&FileWriterDelegate::OnFlushed, |
| 232 weak_factory_.GetWeakPtr(), |
| 233 error, bytes_written, progress_status)); |
| 234 if (flush_error != net::ERR_IO_PENDING) |
| 235 OnFlushed(error, bytes_written, progress_status, flush_error); |
| 236 } |
| 237 |
| 238 void FileWriterDelegate::OnFlushed(base::PlatformFileError error, |
| 239 int bytes_written, |
| 240 WriteProgressStatus progress_status, |
| 241 int flush_error) { |
| 242 if (error == base::PLATFORM_FILE_OK && flush_error != net::OK) { |
| 243 // If the Flush introduced an error, overwrite the status. |
| 244 // Otherwise, keep the original error status. |
| 245 error = NetErrorToPlatformFileError(flush_error); |
| 246 progress_status = GetCompletionStatusOnError(); |
| 247 } |
| 248 write_callback_.Run(error, bytes_written, progress_status); |
| 249 } |
| 250 |
216 } // namespace fileapi | 251 } // namespace fileapi |
OLD | NEW |