OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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/plugins/ppapi/quota_file_io.h" | 5 #include "webkit/plugins/ppapi/quota_file_io.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
11 #include "base/task.h" | 11 #include "base/task.h" |
12 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 12 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 13 #include "webkit/plugins/ppapi/resource_helper.h" |
| 14 #include "webkit/plugins/ppapi/resource_tracker.h" |
13 | 15 |
14 using base::PlatformFile; | 16 using base::PlatformFile; |
15 using base::PlatformFileError; | 17 using base::PlatformFileError; |
16 using quota::StorageType; | 18 using quota::StorageType; |
17 | 19 |
18 namespace webkit { | 20 namespace webkit { |
19 namespace ppapi { | 21 namespace ppapi { |
20 | 22 |
21 namespace { | 23 namespace { |
22 StorageType PPFileSystemTypeToQuotaStorageType(PP_FileSystemType type) { | 24 StorageType PPFileSystemTypeToQuotaStorageType(PP_FileSystemType type) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE); | 86 DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE); |
85 return; | 87 return; |
86 } | 88 } |
87 if (is_will_operation_) { | 89 if (is_will_operation_) { |
88 // Assuming the write will succeed. | 90 // Assuming the write will succeed. |
89 DidFinish(base::PLATFORM_FILE_OK, bytes_to_write_); | 91 DidFinish(base::PLATFORM_FILE_OK, bytes_to_write_); |
90 return; | 92 return; |
91 } | 93 } |
92 DCHECK(buffer_.get()); | 94 DCHECK(buffer_.get()); |
93 if (!base::FileUtilProxy::Write( | 95 if (!base::FileUtilProxy::Write( |
94 quota_io_->instance_->delegate()->GetFileThreadMessageLoopProxy(), | 96 quota_io_->GetPluginDelegate()->GetFileThreadMessageLoopProxy(), |
95 quota_io_->file_, offset_, buffer_.get(), bytes_to_write_, | 97 quota_io_->file_, offset_, buffer_.get(), bytes_to_write_, |
96 callback_factory_.NewCallback(&WriteOperation::DidFinish))) { | 98 callback_factory_.NewCallback(&WriteOperation::DidFinish))) { |
97 DidFail(base::PLATFORM_FILE_ERROR_FAILED); | 99 DidFail(base::PLATFORM_FILE_ERROR_FAILED); |
98 return; | 100 return; |
99 } | 101 } |
100 } | 102 } |
101 | 103 |
102 virtual void DidFail(PlatformFileError error) OVERRIDE { | 104 virtual void DidFail(PlatformFileError error) OVERRIDE { |
103 DidFinish(error, 0); | 105 DidFinish(error, 0); |
104 } | 106 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 DCHECK(quota_io_); | 159 DCHECK(quota_io_); |
158 if (quota_io_->CheckIfExceedsQuota(length_)) { | 160 if (quota_io_->CheckIfExceedsQuota(length_)) { |
159 DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE); | 161 DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE); |
160 return; | 162 return; |
161 } | 163 } |
162 if (is_will_operation_) { | 164 if (is_will_operation_) { |
163 DidFinish(base::PLATFORM_FILE_OK); | 165 DidFinish(base::PLATFORM_FILE_OK); |
164 return; | 166 return; |
165 } | 167 } |
166 if (!base::FileUtilProxy::Truncate( | 168 if (!base::FileUtilProxy::Truncate( |
167 quota_io_->instance_->delegate()->GetFileThreadMessageLoopProxy(), | 169 quota_io_->GetPluginDelegate()->GetFileThreadMessageLoopProxy(), |
168 quota_io_->file_, length_, | 170 quota_io_->file_, length_, |
169 callback_factory_.NewCallback(&SetLengthOperation::DidFinish))) { | 171 callback_factory_.NewCallback(&SetLengthOperation::DidFinish))) { |
170 DidFail(base::PLATFORM_FILE_ERROR_FAILED); | 172 DidFail(base::PLATFORM_FILE_ERROR_FAILED); |
171 return; | 173 return; |
172 } | 174 } |
173 } | 175 } |
174 | 176 |
175 virtual void DidFail(PlatformFileError error) OVERRIDE { | 177 virtual void DidFail(PlatformFileError error) OVERRIDE { |
176 DidFinish(error); | 178 DidFinish(error); |
177 } | 179 } |
178 | 180 |
179 private: | 181 private: |
180 void DidFinish(PlatformFileError status) { | 182 void DidFinish(PlatformFileError status) { |
181 quota_io_->DidSetLength(status, length_); | 183 quota_io_->DidSetLength(status, length_); |
182 DCHECK(callback_.get()); | 184 DCHECK(callback_.get()); |
183 callback_->Run(status); | 185 callback_->Run(status); |
184 callback_.reset(); | 186 callback_.reset(); |
185 delete this; | 187 delete this; |
186 } | 188 } |
187 | 189 |
188 int64_t length_; | 190 int64_t length_; |
189 scoped_ptr<StatusCallback> callback_; | 191 scoped_ptr<StatusCallback> callback_; |
190 base::ScopedCallbackFactory<SetLengthOperation> callback_factory_; | 192 base::ScopedCallbackFactory<SetLengthOperation> callback_factory_; |
191 }; | 193 }; |
192 | 194 |
193 // QuotaFileIO -------------------------------------------------------------- | 195 // QuotaFileIO -------------------------------------------------------------- |
194 | 196 |
195 QuotaFileIO::QuotaFileIO( | 197 QuotaFileIO::QuotaFileIO( |
196 PluginInstance* instance, | 198 PP_Instance instance, |
197 PlatformFile file, | 199 PlatformFile file, |
198 const GURL& file_url, | 200 const GURL& file_url, |
199 PP_FileSystemType type) | 201 PP_FileSystemType type) |
200 : instance_(instance), | 202 : pp_instance_(instance), |
201 file_(file), | 203 file_(file), |
202 file_url_(file_url), | 204 file_url_(file_url), |
203 storage_type_(PPFileSystemTypeToQuotaStorageType(type)), | 205 storage_type_(PPFileSystemTypeToQuotaStorageType(type)), |
204 cached_file_size_(0), | 206 cached_file_size_(0), |
205 cached_available_space_(0), | 207 cached_available_space_(0), |
206 outstanding_quota_queries_(0), | 208 outstanding_quota_queries_(0), |
207 outstanding_errors_(0), | 209 outstanding_errors_(0), |
208 max_written_offset_(0), | 210 max_written_offset_(0), |
209 inflight_operations_(0), | 211 inflight_operations_(0), |
210 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 212 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
211 DCHECK(instance_); | |
212 DCHECK_NE(base::kInvalidPlatformFileValue, file_); | 213 DCHECK_NE(base::kInvalidPlatformFileValue, file_); |
213 DCHECK_NE(quota::kStorageTypeUnknown, storage_type_); | 214 DCHECK_NE(quota::kStorageTypeUnknown, storage_type_); |
214 } | 215 } |
215 | 216 |
216 QuotaFileIO::~QuotaFileIO() { | 217 QuotaFileIO::~QuotaFileIO() { |
217 // Note that this doesn't dispatch pending callbacks. | 218 // Note that this doesn't dispatch pending callbacks. |
218 STLDeleteContainerPointers(pending_operations_.begin(), | 219 STLDeleteContainerPointers(pending_operations_.begin(), |
219 pending_operations_.end()); | 220 pending_operations_.end()); |
220 STLDeleteContainerPointers(pending_callbacks_.begin(), | 221 STLDeleteContainerPointers(pending_callbacks_.begin(), |
221 pending_callbacks_.end()); | 222 pending_callbacks_.end()); |
(...skipping 24 matching lines...) Expand all Loading... |
246 this, true, offset, NULL, bytes_to_write, callback); | 247 this, true, offset, NULL, bytes_to_write, callback); |
247 return RegisterOperationForQuotaChecks(op); | 248 return RegisterOperationForQuotaChecks(op); |
248 } | 249 } |
249 | 250 |
250 bool QuotaFileIO::WillSetLength(int64_t length, StatusCallback* callback) { | 251 bool QuotaFileIO::WillSetLength(int64_t length, StatusCallback* callback) { |
251 DCHECK(pending_operations_.empty()); | 252 DCHECK(pending_operations_.empty()); |
252 SetLengthOperation* op = new SetLengthOperation(this, true, length, callback); | 253 SetLengthOperation* op = new SetLengthOperation(this, true, length, callback); |
253 return RegisterOperationForQuotaChecks(op); | 254 return RegisterOperationForQuotaChecks(op); |
254 } | 255 } |
255 | 256 |
| 257 PluginDelegate* QuotaFileIO::GetPluginDelegate() const { |
| 258 PluginInstance* instance = ResourceTracker::Get()->GetInstance(pp_instance_); |
| 259 if (instance) |
| 260 return instance->delegate(); |
| 261 return NULL; |
| 262 } |
| 263 |
256 bool QuotaFileIO::RegisterOperationForQuotaChecks( | 264 bool QuotaFileIO::RegisterOperationForQuotaChecks( |
257 PendingOperationBase* op_ptr) { | 265 PendingOperationBase* op_ptr) { |
258 scoped_ptr<PendingOperationBase> op(op_ptr); | 266 scoped_ptr<PendingOperationBase> op(op_ptr); |
259 if (pending_operations_.empty()) { | 267 if (pending_operations_.empty()) { |
260 // This is the first pending quota check. Run querying the file size | 268 // This is the first pending quota check. Run querying the file size |
261 // and available space. | 269 // and available space. |
262 outstanding_quota_queries_ = 0; | 270 outstanding_quota_queries_ = 0; |
263 outstanding_errors_ = 0; | 271 outstanding_errors_ = 0; |
264 | 272 |
265 // Query the file size. | 273 // Query the file size. |
266 ++outstanding_quota_queries_; | 274 ++outstanding_quota_queries_; |
267 if (!base::FileUtilProxy::GetFileInfoFromPlatformFile( | 275 if (!base::FileUtilProxy::GetFileInfoFromPlatformFile( |
268 instance_->delegate()->GetFileThreadMessageLoopProxy(), file_, | 276 GetPluginDelegate()->GetFileThreadMessageLoopProxy(), file_, |
269 callback_factory_.NewCallback( | 277 callback_factory_.NewCallback( |
270 &QuotaFileIO::DidQueryInfoForQuota))) { | 278 &QuotaFileIO::DidQueryInfoForQuota))) { |
271 // This makes the call fail synchronously; we do not fire the callback | 279 // This makes the call fail synchronously; we do not fire the callback |
272 // here but just delete the operation and return false. | 280 // here but just delete the operation and return false. |
273 return false; | 281 return false; |
274 } | 282 } |
275 | 283 |
276 // Query the current available space. | 284 // Query the current available space. |
277 ++outstanding_quota_queries_; | 285 ++outstanding_quota_queries_; |
278 instance_->delegate()->QueryAvailableSpace( | 286 GetPluginDelegate()->QueryAvailableSpace( |
279 GURL(file_url_.path()).GetOrigin(), storage_type_, | 287 GURL(file_url_.path()).GetOrigin(), storage_type_, |
280 callback_factory_.NewCallback(&QuotaFileIO::DidQueryAvailableSpace)); | 288 callback_factory_.NewCallback(&QuotaFileIO::DidQueryAvailableSpace)); |
281 } | 289 } |
282 pending_operations_.push_back(op.release()); | 290 pending_operations_.push_back(op.release()); |
283 return true; | 291 return true; |
284 } | 292 } |
285 | 293 |
286 void QuotaFileIO::DidQueryInfoForQuota( | 294 void QuotaFileIO::DidQueryInfoForQuota( |
287 base::PlatformFileError error_code, | 295 base::PlatformFileError error_code, |
288 const base::PlatformFileInfo& file_info) { | 296 const base::PlatformFileInfo& file_info) { |
(...skipping 28 matching lines...) Expand all Loading... |
317 } | 325 } |
318 | 326 |
319 bool QuotaFileIO::CheckIfExceedsQuota(int64_t new_file_size) const { | 327 bool QuotaFileIO::CheckIfExceedsQuota(int64_t new_file_size) const { |
320 DCHECK_GE(cached_file_size_, 0); | 328 DCHECK_GE(cached_file_size_, 0); |
321 DCHECK_GE(cached_available_space_, 0); | 329 DCHECK_GE(cached_available_space_, 0); |
322 return new_file_size - cached_file_size_ > cached_available_space_; | 330 return new_file_size - cached_file_size_ > cached_available_space_; |
323 } | 331 } |
324 | 332 |
325 void QuotaFileIO::WillUpdate() { | 333 void QuotaFileIO::WillUpdate() { |
326 if (inflight_operations_++ == 0) { | 334 if (inflight_operations_++ == 0) { |
327 instance_->delegate()->WillUpdateFile(file_url_); | 335 GetPluginDelegate()->WillUpdateFile(file_url_); |
328 DCHECK_EQ(0, max_written_offset_); | 336 DCHECK_EQ(0, max_written_offset_); |
329 } | 337 } |
330 } | 338 } |
331 | 339 |
332 void QuotaFileIO::DidWrite(WriteOperation* op, | 340 void QuotaFileIO::DidWrite(WriteOperation* op, |
333 int64_t written_offset_end) { | 341 int64_t written_offset_end) { |
334 max_written_offset_ = std::max(max_written_offset_, written_offset_end); | 342 max_written_offset_ = std::max(max_written_offset_, written_offset_end); |
335 DCHECK_GT(inflight_operations_, 0); | 343 DCHECK_GT(inflight_operations_, 0); |
336 DCHECK(!pending_callbacks_.empty()); | 344 DCHECK(!pending_callbacks_.empty()); |
337 // Fire callbacks for finished operations. | 345 // Fire callbacks for finished operations. |
338 while (!pending_callbacks_.empty()) { | 346 while (!pending_callbacks_.empty()) { |
339 WriteOperation* op = static_cast<WriteOperation*>( | 347 WriteOperation* op = static_cast<WriteOperation*>( |
340 pending_callbacks_.front()); | 348 pending_callbacks_.front()); |
341 if (!op->finished()) | 349 if (!op->finished()) |
342 break; | 350 break; |
343 pending_callbacks_.pop_front(); | 351 pending_callbacks_.pop_front(); |
344 op->WillRunCallback(); | 352 op->WillRunCallback(); |
345 } | 353 } |
346 // If we have no more pending writes, notify the browser that we did | 354 // If we have no more pending writes, notify the browser that we did |
347 // update the file. | 355 // update the file. |
348 if (--inflight_operations_ == 0) { | 356 if (--inflight_operations_ == 0) { |
349 DCHECK(pending_operations_.empty()); | 357 DCHECK(pending_operations_.empty()); |
350 int64_t growth = max_written_offset_ - cached_file_size_; | 358 int64_t growth = max_written_offset_ - cached_file_size_; |
351 growth = growth < 0 ? 0 : growth; | 359 growth = growth < 0 ? 0 : growth; |
352 instance_->delegate()->DidUpdateFile(file_url_, growth); | 360 GetPluginDelegate()->DidUpdateFile(file_url_, growth); |
353 max_written_offset_ = 0; | 361 max_written_offset_ = 0; |
354 } | 362 } |
355 } | 363 } |
356 | 364 |
357 void QuotaFileIO::DidSetLength(PlatformFileError error, int64_t new_file_size) { | 365 void QuotaFileIO::DidSetLength(PlatformFileError error, int64_t new_file_size) { |
358 DCHECK_EQ(1, inflight_operations_); | 366 DCHECK_EQ(1, inflight_operations_); |
359 pending_callbacks_.pop_front(); | 367 pending_callbacks_.pop_front(); |
360 DCHECK(pending_callbacks_.empty()); | 368 DCHECK(pending_callbacks_.empty()); |
361 int64_t delta = (error != base::PLATFORM_FILE_OK) ? 0 : | 369 int64_t delta = (error != base::PLATFORM_FILE_OK) ? 0 : |
362 new_file_size - cached_file_size_; | 370 new_file_size - cached_file_size_; |
363 instance_->delegate()->DidUpdateFile(file_url_, delta); | 371 GetPluginDelegate()->DidUpdateFile(file_url_, delta); |
364 inflight_operations_ = 0; | 372 inflight_operations_ = 0; |
365 } | 373 } |
366 | 374 |
367 } // namespace ppapi | 375 } // namespace ppapi |
368 } // namespace webkit | 376 } // namespace webkit |
OLD | NEW |