Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2010 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 #include "webkit/fileapi/file_system_file_util_proxy.h" | |
| 6 | |
| 7 #include "base/message_loop_proxy.h" | |
| 8 #include "webkit/fileapi/file_system_context.h" | |
| 9 #include "webkit/fileapi/file_system_file_util.h" | |
| 10 #include "webkit/fileapi/file_system_operation_context.h" | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 class MessageLoopRelay | |
| 15 : public base::RefCountedThreadSafe<MessageLoopRelay> { | |
| 16 public: | |
| 17 explicit MessageLoopRelay(fileapi::FileSystemOperationContext* context) | |
| 18 : origin_message_loop_proxy_( | |
| 19 base::MessageLoopProxy::CreateForCurrentThread()), | |
| 20 error_code_(base::PLATFORM_FILE_OK), | |
| 21 context_(context) { | |
| 22 } | |
| 23 | |
| 24 bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
| 25 const tracked_objects::Location& from_here) { | |
| 26 return message_loop_proxy->PostTask( | |
| 27 from_here, | |
| 28 NewRunnableMethod(this, &MessageLoopRelay::ProcessOnTargetThread)); | |
| 29 } | |
| 30 | |
| 31 protected: | |
| 32 friend class base::RefCountedThreadSafe<MessageLoopRelay>; | |
| 33 virtual ~MessageLoopRelay() {} | |
| 34 | |
| 35 // Called to perform work on the FILE thread. | |
| 36 virtual void RunWork() = 0; | |
| 37 | |
| 38 // Called to notify the callback on the origin thread. | |
| 39 virtual void RunCallback() = 0; | |
| 40 | |
| 41 void set_error_code(base::PlatformFileError error_code) { | |
| 42 error_code_ = error_code; | |
| 43 } | |
| 44 | |
| 45 base::PlatformFileError error_code() const { | |
| 46 return error_code_; | |
| 47 } | |
| 48 | |
| 49 fileapi::FileSystemOperationContext* context() { | |
| 50 return context_; | |
| 51 } | |
| 52 | |
| 53 fileapi::FileSystemFileUtil* file_system_file_util() { | |
| 54 return fileapi::FileSystemFileUtil::GetInstance(); | |
|
ericu
2011/03/03 01:05:11
Rather than access the singleton getter here, I th
ericu
2011/03/03 02:34:07
Incidentally, this explicitly only works for opera
Dai Mikurube (google.com)
2011/03/03 20:24:52
Agreed. I've changed FSFileUtil::GetInstance() to
| |
| 55 } | |
| 56 | |
| 57 private: | |
| 58 void ProcessOnTargetThread() { | |
| 59 RunWork(); | |
| 60 origin_message_loop_proxy_->PostTask( | |
| 61 FROM_HERE, | |
| 62 NewRunnableMethod(this, &MessageLoopRelay::RunCallback)); | |
| 63 } | |
| 64 | |
| 65 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; | |
| 66 base::PlatformFileError error_code_; | |
| 67 fileapi::FileSystemOperationContext* context_; | |
| 68 }; | |
| 69 | |
| 70 class RelayCreateOrOpen : public MessageLoopRelay { | |
| 71 public: | |
| 72 RelayCreateOrOpen( | |
| 73 fileapi::FileSystemOperationContext* context, | |
| 74 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
| 75 const FilePath& file_path, | |
| 76 int file_flags, | |
| 77 fileapi::FileSystemFileUtilProxy::CreateOrOpenCallback* callback) | |
| 78 : MessageLoopRelay(context), | |
| 79 message_loop_proxy_(message_loop_proxy), | |
| 80 file_path_(file_path), | |
| 81 file_flags_(file_flags), | |
| 82 callback_(callback), | |
| 83 file_handle_(base::kInvalidPlatformFileValue), | |
| 84 created_(false) { | |
| 85 DCHECK(callback); | |
| 86 } | |
| 87 | |
| 88 protected: | |
| 89 virtual ~RelayCreateOrOpen() { | |
| 90 if (file_handle_ != base::kInvalidPlatformFileValue) | |
| 91 fileapi::FileSystemFileUtilProxy::Close(context(), | |
| 92 message_loop_proxy_, file_handle_, NULL); | |
| 93 } | |
| 94 | |
| 95 virtual void RunWork() { | |
| 96 set_error_code( | |
| 97 file_system_file_util()->CreateOrOpen( | |
| 98 context(), file_path_, file_flags_, &file_handle_, &created_)); | |
| 99 } | |
| 100 | |
| 101 virtual void RunCallback() { | |
| 102 callback_->Run(error_code(), base::PassPlatformFile(&file_handle_), | |
| 103 created_); | |
| 104 delete callback_; | |
| 105 } | |
| 106 | |
| 107 private: | |
| 108 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | |
| 109 FilePath file_path_; | |
| 110 int file_flags_; | |
| 111 fileapi::FileSystemFileUtilProxy::CreateOrOpenCallback* callback_; | |
| 112 base::PlatformFile file_handle_; | |
| 113 bool created_; | |
| 114 }; | |
| 115 | |
| 116 class RelayWithStatusCallback : public MessageLoopRelay { | |
| 117 public: | |
| 118 RelayWithStatusCallback( | |
| 119 fileapi::FileSystemOperationContext* context, | |
| 120 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 121 : MessageLoopRelay(context), | |
| 122 callback_(callback) { | |
| 123 // It is OK for callback to be NULL. | |
| 124 } | |
| 125 | |
| 126 protected: | |
| 127 virtual void RunCallback() { | |
| 128 // The caller may not have been interested in the result. | |
| 129 if (callback_) { | |
| 130 callback_->Run(error_code()); | |
| 131 delete callback_; | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 private: | |
| 136 fileapi::FileSystemFileUtilProxy::StatusCallback* callback_; | |
| 137 }; | |
| 138 | |
| 139 class RelayClose : public RelayWithStatusCallback { | |
| 140 public: | |
| 141 RelayClose(fileapi::FileSystemOperationContext* context, | |
| 142 base::PlatformFile file_handle, | |
| 143 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 144 : RelayWithStatusCallback(context, callback), | |
| 145 file_handle_(file_handle) { | |
| 146 } | |
| 147 | |
| 148 protected: | |
| 149 virtual void RunWork() { | |
| 150 set_error_code( | |
| 151 file_system_file_util()->Close(context(), file_handle_)); | |
| 152 } | |
| 153 | |
| 154 private: | |
| 155 base::PlatformFile file_handle_; | |
| 156 }; | |
| 157 | |
| 158 class RelayEnsureFileExists : public MessageLoopRelay { | |
| 159 public: | |
| 160 RelayEnsureFileExists( | |
| 161 fileapi::FileSystemOperationContext* context, | |
| 162 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
| 163 const FilePath& file_path, | |
| 164 fileapi::FileSystemFileUtilProxy::EnsureFileExistsCallback* callback) | |
| 165 : MessageLoopRelay(context), | |
| 166 message_loop_proxy_(message_loop_proxy), | |
| 167 file_path_(file_path), | |
| 168 callback_(callback), | |
| 169 created_(false) { | |
| 170 DCHECK(callback); | |
| 171 } | |
| 172 | |
| 173 protected: | |
| 174 virtual void RunWork() { | |
| 175 set_error_code( | |
| 176 file_system_file_util()->EnsureFileExists( | |
| 177 context(), file_path_, &created_)); | |
| 178 } | |
| 179 | |
| 180 virtual void RunCallback() { | |
| 181 callback_->Run(error_code(), created_); | |
| 182 delete callback_; | |
| 183 } | |
| 184 | |
| 185 private: | |
| 186 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | |
| 187 FilePath file_path_; | |
| 188 fileapi::FileSystemFileUtilProxy::EnsureFileExistsCallback* callback_; | |
| 189 bool created_; | |
| 190 }; | |
| 191 | |
| 192 class RelayGetFileInfo : public MessageLoopRelay { | |
| 193 public: | |
| 194 RelayGetFileInfo( | |
| 195 fileapi::FileSystemOperationContext* context, | |
| 196 const FilePath& file_path, | |
| 197 fileapi::FileSystemFileUtilProxy::GetFileInfoCallback* callback) | |
| 198 : MessageLoopRelay(context), | |
| 199 callback_(callback), | |
| 200 file_path_(file_path) { | |
| 201 DCHECK(callback); | |
| 202 } | |
| 203 | |
| 204 protected: | |
| 205 virtual void RunWork() { | |
| 206 set_error_code( | |
| 207 file_system_file_util()->GetFileInfo( | |
| 208 context(), file_path_, &file_info_)); | |
| 209 } | |
| 210 | |
| 211 virtual void RunCallback() { | |
| 212 callback_->Run(error_code(), file_info_); | |
| 213 delete callback_; | |
| 214 } | |
| 215 | |
| 216 private: | |
| 217 fileapi::FileSystemFileUtilProxy::GetFileInfoCallback* callback_; | |
| 218 FilePath file_path_; | |
| 219 base::PlatformFileInfo file_info_; | |
| 220 }; | |
| 221 | |
| 222 class RelayReadDirectory : public MessageLoopRelay { | |
| 223 public: | |
| 224 RelayReadDirectory( | |
| 225 fileapi::FileSystemOperationContext* context, | |
| 226 const FilePath& file_path, | |
| 227 fileapi::FileSystemFileUtilProxy::ReadDirectoryCallback* callback) | |
| 228 : MessageLoopRelay(context), | |
| 229 callback_(callback), file_path_(file_path) { | |
| 230 DCHECK(callback); | |
| 231 } | |
| 232 | |
| 233 protected: | |
| 234 virtual void RunWork() { | |
| 235 // TODO(kkanetkar): Implement directory read in multiple chunks. | |
| 236 set_error_code( | |
| 237 file_system_file_util()->ReadDirectory( | |
| 238 context(), file_path_, &entries_)); | |
| 239 } | |
| 240 | |
| 241 virtual void RunCallback() { | |
| 242 callback_->Run(error_code(), entries_); | |
| 243 delete callback_; | |
| 244 } | |
| 245 | |
| 246 private: | |
| 247 fileapi::FileSystemFileUtilProxy::ReadDirectoryCallback* callback_; | |
| 248 FilePath file_path_; | |
| 249 std::vector<fileapi::FileSystemFileUtilProxy::Entry> entries_; | |
| 250 }; | |
| 251 | |
| 252 class RelayCreateDirectory : public RelayWithStatusCallback { | |
| 253 public: | |
| 254 RelayCreateDirectory( | |
| 255 fileapi::FileSystemOperationContext* context, | |
| 256 const FilePath& file_path, | |
| 257 bool exclusive, | |
| 258 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 259 : RelayWithStatusCallback(context, callback), | |
| 260 file_path_(file_path), | |
| 261 exclusive_(exclusive) { | |
| 262 } | |
| 263 | |
| 264 protected: | |
| 265 virtual void RunWork() { | |
| 266 set_error_code( | |
| 267 file_system_file_util()->CreateDirectory( | |
| 268 context(), file_path_, exclusive_)); | |
| 269 } | |
| 270 | |
| 271 private: | |
| 272 FilePath file_path_; | |
| 273 bool exclusive_; | |
| 274 }; | |
| 275 | |
| 276 class RelayCopy : public RelayWithStatusCallback { | |
| 277 public: | |
| 278 RelayCopy(fileapi::FileSystemOperationContext* context, | |
| 279 const FilePath& src_file_path, | |
| 280 const FilePath& dest_file_path, | |
| 281 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 282 : RelayWithStatusCallback(context, callback), | |
| 283 src_file_path_(src_file_path), | |
| 284 dest_file_path_(dest_file_path) { | |
| 285 } | |
| 286 | |
| 287 protected: | |
| 288 virtual void RunWork() { | |
| 289 set_error_code( | |
| 290 file_system_file_util()->Copy( | |
| 291 context(), src_file_path_, dest_file_path_)); | |
| 292 } | |
| 293 | |
| 294 private: | |
| 295 FilePath src_file_path_; | |
| 296 FilePath dest_file_path_; | |
| 297 }; | |
| 298 | |
| 299 class RelayMove : public RelayWithStatusCallback { | |
| 300 public: | |
| 301 RelayMove(fileapi::FileSystemOperationContext* context, | |
| 302 const FilePath& src_file_path, | |
| 303 const FilePath& dest_file_path, | |
| 304 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 305 : RelayWithStatusCallback(context, callback), | |
| 306 src_file_path_(src_file_path), | |
| 307 dest_file_path_(dest_file_path) { | |
| 308 } | |
| 309 | |
| 310 protected: | |
| 311 virtual void RunWork() { | |
| 312 set_error_code( | |
| 313 file_system_file_util()->Move( | |
| 314 context(), src_file_path_, dest_file_path_)); | |
| 315 } | |
| 316 | |
| 317 private: | |
| 318 FilePath src_file_path_; | |
| 319 FilePath dest_file_path_; | |
| 320 }; | |
| 321 | |
| 322 class RelayDelete : public RelayWithStatusCallback { | |
| 323 public: | |
| 324 RelayDelete(fileapi::FileSystemOperationContext* context, | |
| 325 const FilePath& file_path, | |
| 326 bool recursive, | |
| 327 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 328 : RelayWithStatusCallback(context, callback), | |
| 329 file_path_(file_path), | |
| 330 recursive_(recursive) { | |
| 331 } | |
| 332 | |
| 333 protected: | |
| 334 virtual void RunWork() { | |
| 335 set_error_code( | |
| 336 file_system_file_util()->Delete( | |
| 337 context(), file_path_, recursive_)); | |
| 338 } | |
| 339 | |
| 340 private: | |
| 341 FilePath file_path_; | |
| 342 bool recursive_; | |
| 343 }; | |
| 344 | |
| 345 class RelayTouchFilePath : public RelayWithStatusCallback { | |
| 346 public: | |
| 347 RelayTouchFilePath(fileapi::FileSystemOperationContext* context, | |
| 348 const FilePath& file_path, | |
| 349 const base::Time& last_access_time, | |
| 350 const base::Time& last_modified_time, | |
| 351 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 352 : RelayWithStatusCallback(context, callback), | |
| 353 file_path_(file_path), | |
| 354 last_access_time_(last_access_time), | |
| 355 last_modified_time_(last_modified_time) { | |
| 356 } | |
| 357 | |
| 358 protected: | |
| 359 virtual void RunWork() { | |
| 360 set_error_code( | |
| 361 file_system_file_util()->Touch( | |
| 362 context(), file_path_, last_access_time_, last_modified_time_)); | |
| 363 } | |
| 364 | |
| 365 private: | |
| 366 FilePath file_path_; | |
| 367 base::Time last_access_time_; | |
| 368 base::Time last_modified_time_; | |
| 369 }; | |
| 370 | |
| 371 class RelayTruncate : public RelayWithStatusCallback { | |
| 372 public: | |
| 373 RelayTruncate(fileapi::FileSystemOperationContext* context, | |
| 374 const FilePath& file_path, | |
| 375 int64 length, | |
| 376 fileapi::FileSystemFileUtilProxy::StatusCallback* callback) | |
| 377 : RelayWithStatusCallback(context, callback), | |
| 378 file_path_(file_path), | |
| 379 length_(length) { | |
| 380 } | |
| 381 | |
| 382 protected: | |
| 383 virtual void RunWork() { | |
| 384 set_error_code( | |
| 385 file_system_file_util()->Truncate(context(), file_path_, length_)); | |
| 386 } | |
| 387 | |
| 388 private: | |
| 389 FilePath file_path_; | |
| 390 int64 length_; | |
| 391 }; | |
| 392 | |
| 393 bool Start(const tracked_objects::Location& from_here, | |
| 394 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | |
| 395 scoped_refptr<MessageLoopRelay> relay) { | |
| 396 return relay->Start(message_loop_proxy, from_here); | |
| 397 } | |
| 398 | |
| 399 } // namespace | |
| 400 | |
| 401 namespace fileapi { | |
| 402 | |
| 403 // static | |
| 404 bool FileSystemFileUtilProxy::CreateOrOpen( | |
| 405 FileSystemOperationContext* context, | |
| 406 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 407 const FilePath& file_path, int file_flags, | |
| 408 CreateOrOpenCallback* callback) { | |
| 409 return Start(FROM_HERE, message_loop_proxy, new RelayCreateOrOpen(context, | |
| 410 message_loop_proxy, file_path, file_flags, callback)); | |
| 411 } | |
| 412 | |
| 413 // static | |
| 414 bool FileSystemFileUtilProxy::Close( | |
| 415 FileSystemOperationContext* context, | |
| 416 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 417 base::PlatformFile file_handle, | |
| 418 StatusCallback* callback) { | |
| 419 return Start(FROM_HERE, message_loop_proxy, | |
| 420 new RelayClose(context, file_handle, callback)); | |
| 421 } | |
| 422 | |
| 423 // static | |
| 424 bool FileSystemFileUtilProxy::EnsureFileExists( | |
| 425 FileSystemOperationContext* context, | |
| 426 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 427 const FilePath& file_path, | |
| 428 EnsureFileExistsCallback* callback) { | |
| 429 return Start(FROM_HERE, message_loop_proxy, new RelayEnsureFileExists( | |
| 430 context, message_loop_proxy, file_path, callback)); | |
| 431 } | |
| 432 | |
| 433 // Retrieves the information about a file. It is invalid to pass NULL for the | |
| 434 // callback. | |
| 435 bool FileSystemFileUtilProxy::GetFileInfo( | |
| 436 FileSystemOperationContext* context, | |
| 437 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 438 const FilePath& file_path, | |
| 439 GetFileInfoCallback* callback) { | |
| 440 return Start(FROM_HERE, message_loop_proxy, new RelayGetFileInfo(context, | |
| 441 file_path, callback)); | |
| 442 } | |
| 443 | |
| 444 // static | |
| 445 bool FileSystemFileUtilProxy::ReadDirectory( | |
| 446 FileSystemOperationContext* context, | |
| 447 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 448 const FilePath& file_path, | |
| 449 ReadDirectoryCallback* callback) { | |
| 450 return Start(FROM_HERE, message_loop_proxy, new RelayReadDirectory(context, | |
| 451 file_path, callback)); | |
| 452 } | |
| 453 | |
| 454 // static | |
| 455 bool FileSystemFileUtilProxy::CreateDirectory( | |
| 456 FileSystemOperationContext* context, | |
| 457 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 458 const FilePath& file_path, | |
| 459 bool exclusive, | |
| 460 StatusCallback* callback) { | |
| 461 return Start(FROM_HERE, message_loop_proxy, new RelayCreateDirectory( | |
| 462 context, file_path, exclusive, callback)); | |
| 463 } | |
| 464 | |
| 465 // static | |
| 466 bool FileSystemFileUtilProxy::Copy( | |
| 467 FileSystemOperationContext* context, | |
| 468 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 469 const FilePath& src_file_path, | |
| 470 const FilePath& dest_file_path, | |
| 471 StatusCallback* callback) { | |
| 472 return Start(FROM_HERE, message_loop_proxy, | |
| 473 new RelayCopy(context, src_file_path, dest_file_path, | |
| 474 callback)); | |
| 475 } | |
| 476 | |
| 477 // static | |
| 478 bool FileSystemFileUtilProxy::Move( | |
| 479 FileSystemOperationContext* context, | |
| 480 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 481 const FilePath& src_file_path, | |
| 482 const FilePath& dest_file_path, | |
| 483 StatusCallback* callback) { | |
| 484 return Start(FROM_HERE, message_loop_proxy, | |
| 485 new RelayMove(context, src_file_path, dest_file_path, | |
| 486 callback)); | |
| 487 } | |
| 488 | |
| 489 // static | |
| 490 bool FileSystemFileUtilProxy::Delete( | |
| 491 FileSystemOperationContext* context, | |
| 492 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 493 const FilePath& file_path, | |
| 494 bool recursive, | |
| 495 StatusCallback* callback) { | |
| 496 return Start(FROM_HERE, message_loop_proxy, | |
| 497 new RelayDelete(context, file_path, recursive, callback)); | |
| 498 } | |
| 499 | |
| 500 // static | |
| 501 bool FileSystemFileUtilProxy::Touch( | |
| 502 FileSystemOperationContext* context, | |
| 503 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 504 const FilePath& file_path, | |
| 505 const base::Time& last_access_time, | |
| 506 const base::Time& last_modified_time, | |
| 507 StatusCallback* callback) { | |
| 508 return Start(FROM_HERE, message_loop_proxy, | |
| 509 new RelayTouchFilePath(context, file_path, last_access_time, | |
| 510 last_modified_time, callback)); | |
| 511 } | |
| 512 | |
| 513 // static | |
| 514 bool FileSystemFileUtilProxy::Truncate( | |
| 515 FileSystemOperationContext* context, | |
| 516 scoped_refptr<MessageLoopProxy> message_loop_proxy, | |
| 517 const FilePath& path, | |
| 518 int64 length, | |
| 519 StatusCallback* callback) { | |
| 520 return Start(FROM_HERE, message_loop_proxy, | |
| 521 new RelayTruncate(context, path, length, callback)); | |
| 522 } | |
| 523 | |
| 524 } // namespace fileapi | |
| OLD | NEW |