Chromium Code Reviews| 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" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 }; | 84 }; |
| 85 | 85 |
| 86 } // namespace (anonymous) | 86 } // namespace (anonymous) |
| 87 | 87 |
| 88 FileWriterDelegate::FileWriterDelegate( | 88 FileWriterDelegate::FileWriterDelegate( |
| 89 FileSystemOperation* file_system_operation, | 89 FileSystemOperation* file_system_operation, |
| 90 const FileSystemPath& path, | 90 const FileSystemPath& path, |
| 91 int64 offset, | 91 int64 offset, |
| 92 scoped_refptr<base::MessageLoopProxy> proxy) | 92 scoped_refptr<base::MessageLoopProxy> proxy) |
| 93 : file_system_operation_(file_system_operation), | 93 : file_system_operation_(file_system_operation), |
| 94 state_(FILE_WRITER_STATE_CREATED), | |
| 94 file_(base::kInvalidPlatformFileValue), | 95 file_(base::kInvalidPlatformFileValue), |
| 95 path_(path), | 96 path_(path), |
| 96 offset_(offset), | 97 offset_(offset), |
| 97 proxy_(proxy), | 98 proxy_(proxy), |
| 98 bytes_written_backlog_(0), | 99 bytes_written_backlog_(0), |
| 99 bytes_written_(0), | 100 bytes_written_(0), |
| 100 bytes_read_(0), | 101 bytes_read_(0), |
| 101 total_bytes_written_(0), | 102 total_bytes_written_(0), |
| 102 allowed_bytes_to_write_(0), | 103 allowed_bytes_to_write_(0), |
| 103 io_buffer_(new net::IOBufferWithSize(kReadBufSize)), | 104 io_buffer_(new net::IOBufferWithSize(kReadBufSize)), |
| 104 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 105 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| 105 } | 106 } |
| 106 | 107 |
| 107 FileWriterDelegate::~FileWriterDelegate() { | 108 FileWriterDelegate::~FileWriterDelegate() { |
| 108 } | 109 } |
| 109 | 110 |
| 110 void FileWriterDelegate::OnGetFileInfoAndCallStartUpdate( | 111 void FileWriterDelegate::OnGetFileInfoAndCallStartUpdate( |
| 111 base::PlatformFileError error, | 112 base::PlatformFileError error, |
| 112 const base::PlatformFileInfo& file_info) { | 113 const base::PlatformFileInfo& file_info) { |
| 114 if (state_ == FILE_WRITER_STATE_CANCELED) { | |
|
ericu
2012/04/10 22:10:32
If we cancel while starting up, we call OnError(AB
kinuko
2012/04/11 01:11:46
We will eventually call OnError (or OnProgress(com
| |
| 115 OnError(base::PLATFORM_FILE_ERROR_ABORT); | |
| 116 return; | |
| 117 } | |
| 113 if (error) { | 118 if (error) { |
| 114 OnError(error); | 119 OnError(error); |
| 115 return; | 120 return; |
| 116 } | 121 } |
| 117 int64 allowed_bytes_growth = | 122 int64 allowed_bytes_growth = |
| 118 file_system_operation_context()->allowed_bytes_growth(); | 123 file_system_operation_context()->allowed_bytes_growth(); |
| 119 if (allowed_bytes_growth < 0) | 124 if (allowed_bytes_growth < 0) |
| 120 allowed_bytes_growth = 0; | 125 allowed_bytes_growth = 0; |
| 121 int64 overlap = file_info.size - offset_; | 126 int64 overlap = file_info.size - offset_; |
| 122 allowed_bytes_to_write_ = allowed_bytes_growth; | 127 allowed_bytes_to_write_ = allowed_bytes_growth; |
| 123 if (kint64max - overlap > allowed_bytes_growth) | 128 if (kint64max - overlap > allowed_bytes_growth) |
| 124 allowed_bytes_to_write_ += overlap; | 129 allowed_bytes_to_write_ += overlap; |
| 125 size_ = file_info.size; | 130 size_ = file_info.size; |
| 126 file_stream_.reset(new net::FileStream( | 131 file_stream_.reset(new net::FileStream( |
| 127 file_, | 132 file_, |
| 128 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | | 133 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | |
| 129 base::PLATFORM_FILE_ASYNC, | 134 base::PLATFORM_FILE_ASYNC, |
| 130 NULL)); | 135 NULL)); |
| 136 DCHECK_EQ(FILE_WRITER_STATE_CREATED, state_); | |
| 137 state_ = FILE_WRITER_STATE_REQUEST_STARTED; | |
| 131 request_->Start(); | 138 request_->Start(); |
| 132 } | 139 } |
| 133 | 140 |
| 134 void FileWriterDelegate::Start(base::PlatformFile file, | 141 void FileWriterDelegate::Start(base::PlatformFile file, |
| 135 net::URLRequest* request) { | 142 scoped_ptr<net::URLRequest> request) { |
| 143 DCHECK(!request_.get()); | |
| 144 DCHECK_EQ(FILE_WRITER_STATE_CREATED, state_); | |
| 145 | |
| 136 file_ = file; | 146 file_ = file; |
| 137 request_ = request; | 147 request_ = request.Pass(); |
| 138 | 148 |
| 139 scoped_refptr<InitializeTask> relay = new InitializeTask( | 149 scoped_refptr<InitializeTask> relay = new InitializeTask( |
| 140 file_, path_, | 150 file_, path_, |
| 141 file_system_operation_context(), | 151 file_system_operation_context(), |
| 142 base::Bind(&FileWriterDelegate::OnGetFileInfoAndCallStartUpdate, | 152 base::Bind(&FileWriterDelegate::OnGetFileInfoAndCallStartUpdate, |
| 143 weak_factory_.GetWeakPtr())); | 153 weak_factory_.GetWeakPtr())); |
| 144 relay->Start(proxy_, FROM_HERE); | 154 relay->Start(proxy_, FROM_HERE); |
| 145 } | 155 } |
| 146 | 156 |
| 157 void FileWriterDelegate::Cancel() { | |
| 158 if (state_ == FILE_WRITER_STATE_REQUEST_STARTED) { | |
| 159 DCHECK(request_.get()); | |
| 160 // This halts any callbacks on this delegate. | |
| 161 request_->Cancel(); | |
| 162 } | |
| 163 state_ = FILE_WRITER_STATE_CANCELED; | |
|
ericu
2012/04/10 22:10:32
This doesn't call quota_util()->proxy()->EndUpdate
kinuko
2012/04/11 01:11:46
We'll eventually call it.
If we've already starte
ericu
2012/04/11 03:24:13
The URLRequest header comments say
// ...It is g
kinuko
2012/04/11 09:06:02
Oh ok, I dived into the code before looking at the
| |
| 164 } | |
| 165 | |
| 147 void FileWriterDelegate::OnReceivedRedirect(net::URLRequest* request, | 166 void FileWriterDelegate::OnReceivedRedirect(net::URLRequest* request, |
| 148 const GURL& new_url, | 167 const GURL& new_url, |
| 149 bool* defer_redirect) { | 168 bool* defer_redirect) { |
| 150 NOTREACHED(); | 169 NOTREACHED(); |
| 151 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 170 OnError(base::PLATFORM_FILE_ERROR_SECURITY); |
| 152 } | 171 } |
| 153 | 172 |
| 154 void FileWriterDelegate::OnAuthRequired(net::URLRequest* request, | 173 void FileWriterDelegate::OnAuthRequired(net::URLRequest* request, |
| 155 net::AuthChallengeInfo* auth_info) { | 174 net::AuthChallengeInfo* auth_info) { |
| 156 NOTREACHED(); | 175 NOTREACHED(); |
| 157 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 176 OnError(base::PLATFORM_FILE_ERROR_SECURITY); |
| 158 } | 177 } |
| 159 | 178 |
| 160 void FileWriterDelegate::OnCertificateRequested( | 179 void FileWriterDelegate::OnCertificateRequested( |
| 161 net::URLRequest* request, | 180 net::URLRequest* request, |
| 162 net::SSLCertRequestInfo* cert_request_info) { | 181 net::SSLCertRequestInfo* cert_request_info) { |
| 163 NOTREACHED(); | 182 NOTREACHED(); |
| 164 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 183 OnError(base::PLATFORM_FILE_ERROR_SECURITY); |
| 165 } | 184 } |
| 166 | 185 |
| 167 void FileWriterDelegate::OnSSLCertificateError(net::URLRequest* request, | 186 void FileWriterDelegate::OnSSLCertificateError(net::URLRequest* request, |
| 168 const net::SSLInfo& ssl_info, | 187 const net::SSLInfo& ssl_info, |
| 169 bool fatal) { | 188 bool fatal) { |
| 170 NOTREACHED(); | 189 NOTREACHED(); |
| 171 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 190 OnError(base::PLATFORM_FILE_ERROR_SECURITY); |
| 172 } | 191 } |
| 173 | 192 |
| 174 void FileWriterDelegate::OnResponseStarted(net::URLRequest* request) { | 193 void FileWriterDelegate::OnResponseStarted(net::URLRequest* request) { |
| 175 DCHECK_EQ(request_, request); | 194 DCHECK_EQ(request_.get(), request); |
| 176 // file_stream_->Seek() blocks the IO thread. | 195 // file_stream_->Seek() blocks the IO thread. |
| 177 // See http://crbug.com/75548. | 196 // See http://crbug.com/75548. |
| 178 base::ThreadRestrictions::ScopedAllowIO allow_io; | 197 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 179 if (!request->status().is_success() || request->GetResponseCode() != 200) { | 198 if (!request->status().is_success() || request->GetResponseCode() != 200) { |
| 180 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 199 OnError(base::PLATFORM_FILE_ERROR_FAILED); |
| 181 return; | 200 return; |
| 182 } | 201 } |
| 183 int64 error = file_stream_->Seek(net::FROM_BEGIN, offset_); | 202 int64 error = file_stream_->Seek(net::FROM_BEGIN, offset_); |
| 184 if (error != offset_) { | 203 if (error != offset_) { |
| 185 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 204 OnError(base::PLATFORM_FILE_ERROR_FAILED); |
| 186 return; | 205 return; |
| 187 } | 206 } |
| 188 Read(); | 207 Read(); |
| 189 } | 208 } |
| 190 | 209 |
| 191 void FileWriterDelegate::OnReadCompleted(net::URLRequest* request, | 210 void FileWriterDelegate::OnReadCompleted(net::URLRequest* request, |
| 192 int bytes_read) { | 211 int bytes_read) { |
| 193 DCHECK_EQ(request_, request); | 212 DCHECK_EQ(request_.get(), request); |
| 194 if (!request->status().is_success()) { | 213 if (!request->status().is_success()) { |
| 195 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 214 OnError(base::PLATFORM_FILE_ERROR_FAILED); |
| 196 return; | 215 return; |
| 197 } | 216 } |
| 198 OnDataReceived(bytes_read); | 217 OnDataReceived(bytes_read); |
| 199 } | 218 } |
| 200 | 219 |
| 201 void FileWriterDelegate::Read() { | 220 void FileWriterDelegate::Read() { |
| 202 bytes_written_ = 0; | 221 bytes_written_ = 0; |
| 203 bytes_read_ = 0; | 222 bytes_read_ = 0; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 MessageLoop::current()->PostTask( | 269 MessageLoop::current()->PostTask( |
| 251 FROM_HERE, | 270 FROM_HERE, |
| 252 base::Bind(&FileWriterDelegate::OnDataWritten, | 271 base::Bind(&FileWriterDelegate::OnDataWritten, |
| 253 weak_factory_.GetWeakPtr(), write_response)); | 272 weak_factory_.GetWeakPtr(), write_response)); |
| 254 else if (net::ERR_IO_PENDING != write_response) | 273 else if (net::ERR_IO_PENDING != write_response) |
| 255 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 274 OnError(base::PLATFORM_FILE_ERROR_FAILED); |
| 256 } | 275 } |
| 257 | 276 |
| 258 void FileWriterDelegate::OnDataWritten(int write_response) { | 277 void FileWriterDelegate::OnDataWritten(int write_response) { |
| 259 if (write_response > 0) { | 278 if (write_response > 0) { |
| 279 if (state_ == FILE_WRITER_STATE_CANCELED) { | |
| 280 // If the request has been cancelled (we could still be here if Cancel | |
| 281 // is made right after the last write) OnProgress will delete this | |
| 282 // (in FileWriterDelegate::DidWrite). | |
|
ericu
2012/04/10 22:10:32
s/FileWriterDelete/FileSystemOperation/?
kinuko
2012/04/11 01:11:46
Done.
| |
| 283 OnProgress(write_response, true); | |
| 284 return; | |
| 285 } | |
| 260 OnProgress(write_response, false); | 286 OnProgress(write_response, false); |
| 261 cursor_->DidConsume(write_response); | 287 cursor_->DidConsume(write_response); |
| 262 bytes_written_ += write_response; | 288 bytes_written_ += write_response; |
| 263 total_bytes_written_ += write_response; | 289 total_bytes_written_ += write_response; |
| 264 if (bytes_written_ == bytes_read_) | 290 if (bytes_written_ == bytes_read_) |
| 265 Read(); | 291 Read(); |
| 266 else | 292 else |
| 267 Write(); | 293 Write(); |
| 268 } else { | 294 } else { |
| 269 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 295 OnError(base::PLATFORM_FILE_ERROR_FAILED); |
| 270 } | 296 } |
| 271 } | 297 } |
| 272 | 298 |
| 273 void FileWriterDelegate::OnError(base::PlatformFileError error) { | 299 void FileWriterDelegate::OnError(base::PlatformFileError error) { |
| 274 request_->set_delegate(NULL); | 300 if (state_ == FILE_WRITER_STATE_REQUEST_STARTED) { |
| 275 request_->Cancel(); | 301 DCHECK(request_.get()); |
| 302 request_->set_delegate(NULL); | |
| 303 request_->Cancel(); | |
| 304 } | |
| 276 | 305 |
| 277 if (quota_util()) | 306 if (quota_util()) |
| 278 quota_util()->proxy()->EndUpdateOrigin(path_.origin(), path_.type()); | 307 quota_util()->proxy()->EndUpdateOrigin(path_.origin(), path_.type()); |
| 279 | 308 |
| 280 file_system_operation_->DidWrite(error, 0, true); | 309 file_system_operation_->DidWrite(error, 0, true); |
| 281 } | 310 } |
| 282 | 311 |
| 283 void FileWriterDelegate::OnProgress(int bytes_written, bool done) { | 312 void FileWriterDelegate::OnProgress(int bytes_written, bool done) { |
| 284 DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); | 313 DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); |
| 285 if (quota_util() && | 314 if (quota_util() && |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 | 348 |
| 320 FileSystemQuotaUtil* FileWriterDelegate::quota_util() const { | 349 FileSystemQuotaUtil* FileWriterDelegate::quota_util() const { |
| 321 DCHECK(file_system_operation_); | 350 DCHECK(file_system_operation_); |
| 322 DCHECK(file_system_operation_->file_system_context()); | 351 DCHECK(file_system_operation_->file_system_context()); |
| 323 DCHECK(file_system_operation_->file_system_operation_context()); | 352 DCHECK(file_system_operation_->file_system_operation_context()); |
| 324 return file_system_operation_->file_system_context()->GetQuotaUtil( | 353 return file_system_operation_->file_system_context()->GetQuotaUtil( |
| 325 path_.type()); | 354 path_.type()); |
| 326 } | 355 } |
| 327 | 356 |
| 328 } // namespace fileapi | 357 } // namespace fileapi |
| OLD | NEW |