1 // Copyright 2013 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 "chrome/browser/sync_file_system/local/canned_syncable_file_system.h" 6 7 #include <algorithm> 8 #include <iterator> 9 10 #include "base/bind.h" 11 #include "base/bind_helpers.h" 12 #include "base/file_util.h" 13 #include "base/guid.h" 14 #include "base/message_loop/message_loop_proxy.h" 15 #include "base/run_loop.h" 16 #include "base/single_thread_task_runner.h" 17 #include "base/task_runner_util.h" 18 #include "chrome/browser/sync_file_system/file_change.h" 19 #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h" 20 #include "chrome/browser/sync_file_system/local/local_file_sync_context.h" 21 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" 22 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" 23 #include "content/public/test/test_file_system_options.h" 24 #include "testing/gtest/include/gtest/gtest.h" 25 #include "webkit/browser/blob/mock_blob_url_request_context.h" 26 #include "webkit/browser/fileapi/external_mount_points.h" 27 #include "webkit/browser/fileapi/file_system_backend.h" 28 #include "webkit/browser/fileapi/file_system_context.h" 29 #include "webkit/browser/fileapi/file_system_operation_context.h" 30 #include "webkit/browser/fileapi/file_system_operation_runner.h" 31 #include "webkit/browser/quota/mock_special_storage_policy.h" 32 #include "webkit/browser/quota/quota_manager.h" 33 #include "webkit/common/blob/shareable_file_reference.h" 34 35 using base::PlatformFileError; 36 using fileapi::FileSystemContext; 37 using fileapi::FileSystemOperationRunner; 38 using fileapi::FileSystemURL; 39 using fileapi::FileSystemURLSet; 40 using quota::QuotaManager; 41 using webkit_blob::MockBlobURLRequestContext; 42 using webkit_blob::ScopedTextBlob; 43 44 namespace sync_file_system { 45 46 namespace { 47 48 void Quit() { base::MessageLoop::current()->Quit(); } 49 50 template <typename R> 51 void AssignAndQuit(base::TaskRunner* original_task_runner, 52 R* result_out, R result) { 53 DCHECK(result_out); 54 *result_out = result; 55 original_task_runner->PostTask(FROM_HERE, base::Bind(&Quit)); 56 } 57 58 template <typename R> 59 R RunOnThread( 60 base::SingleThreadTaskRunner* task_runner, 61 const tracked_objects::Location& location, 62 const base::Callback<void(const base::Callback<void(R)>& callback)>& task) { 63 R result; 64 task_runner->PostTask( 65 location, 66 base::Bind(task, base::Bind(&AssignAndQuit<R>, 67 base::MessageLoopProxy::current(), 68 &result))); 69 base::MessageLoop::current()->Run(); 70 return result; 71 } 72 73 void RunOnThread(base::SingleThreadTaskRunner* task_runner, 74 const tracked_objects::Location& location, 75 const base::Closure& task) { 76 task_runner->PostTaskAndReply( 77 location, task, 78 base::Bind(base::IgnoreResult( 79 base::Bind(&base::MessageLoopProxy::PostTask, 80 base::MessageLoopProxy::current(), 81 FROM_HERE, base::Bind(&Quit))))); 82 base::MessageLoop::current()->Run(); 83 } 84 85 void EnsureRunningOn(base::SingleThreadTaskRunner* runner) { 86 EXPECT_TRUE(runner->RunsTasksOnCurrentThread()); 87 } 88 89 void VerifySameTaskRunner( 90 base::SingleThreadTaskRunner* runner1, 91 base::SingleThreadTaskRunner* runner2) { 92 ASSERT_TRUE(runner1 != NULL); 93 ASSERT_TRUE(runner2 != NULL); 94 runner1->PostTask(FROM_HERE, 95 base::Bind(&EnsureRunningOn, make_scoped_refptr(runner2))); 96 } 97 98 void OnCreateSnapshotFileAndVerifyData( 99 const std::string& expected_data, 100 const CannedSyncableFileSystem::StatusCallback& callback, 101 base::PlatformFileError result, 102 const base::PlatformFileInfo& file_info, 103 const base::FilePath& platform_path, 104 const scoped_refptr<webkit_blob::ShareableFileReference>& /* file_ref */) { 105 if (result != base::PLATFORM_FILE_OK) { 106 callback.Run(result); 107 return; 108 } 109 EXPECT_EQ(expected_data.size(), static_cast<size_t>(file_info.size)); 110 std::string data; 111 const bool read_status = base::ReadFileToString(platform_path, &data); 112 EXPECT_TRUE(read_status); 113 EXPECT_EQ(expected_data, data); 114 callback.Run(result); 115 } 116 117 void OnCreateSnapshotFile( 118 base::PlatformFileInfo* file_info_out, 119 base::FilePath* platform_path_out, 120 const CannedSyncableFileSystem::StatusCallback& callback, 121 base::PlatformFileError result, 122 const base::PlatformFileInfo& file_info, 123 const base::FilePath& platform_path, 124 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { 125 DCHECK(!file_ref.get()); 126 DCHECK(file_info_out); 127 DCHECK(platform_path_out); 128 *file_info_out = file_info; 129 *platform_path_out = platform_path; 130 callback.Run(result); 131 } 132 133 void OnReadDirectory( 134 CannedSyncableFileSystem::FileEntryList* entries_out, 135 const CannedSyncableFileSystem::StatusCallback& callback, 136 base::PlatformFileError error, 137 const fileapi::FileSystemOperation::FileEntryList& entries, 138 bool has_more) { 139 DCHECK(entries_out); 140 entries_out->reserve(entries_out->size() + entries.size()); 141 std::copy(entries.begin(), entries.end(), std::back_inserter(*entries_out)); 142 143 if (!has_more) 144 callback.Run(error); 145 } 146 147 class WriteHelper { 148 public: 149 WriteHelper() : bytes_written_(0) {} 150 WriteHelper(MockBlobURLRequestContext* request_context, 151 const std::string& blob_data) 152 : bytes_written_(0), 153 request_context_(request_context), 154 blob_data_(new ScopedTextBlob(*request_context, 155 base::GenerateGUID(), 156 blob_data)) { 157 } 158 159 ~WriteHelper() { 160 if (request_context_) { 161 base::MessageLoop::current()->DeleteSoon(FROM_HERE, 162 request_context_.release()); 163 } 164 } 165 166 ScopedTextBlob* scoped_text_blob() const { return blob_data_.get(); } 167 168 void DidWrite(const base::Callback<void(int64 result)>& completion_callback, 169 PlatformFileError error, int64 bytes, bool complete) { 170 if (error == base::PLATFORM_FILE_OK) { 171 bytes_written_ += bytes; 172 if (!complete) 173 return; 174 } 175 completion_callback.Run(error == base::PLATFORM_FILE_OK 176 ? bytes_written_ : static_cast<int64>(error)); 177 } 178 179 private: 180 int64 bytes_written_; 181 scoped_ptr<MockBlobURLRequestContext> request_context_; 182 scoped_ptr<ScopedTextBlob> blob_data_; 183 184 DISALLOW_COPY_AND_ASSIGN(WriteHelper); 185 }; 186 187 void DidGetUsageAndQuota(const quota::StatusCallback& callback, 188 int64* usage_out, int64* quota_out, 189 quota::QuotaStatusCode status, 190 int64 usage, int64 quota) { 191 *usage_out = usage; 192 *quota_out = quota; 193 callback.Run(status); 194 } 195 196 void EnsureLastTaskRuns(base::SingleThreadTaskRunner* runner) { 197 base::RunLoop run_loop; 198 runner->PostTaskAndReply( 199 FROM_HERE, base::Bind(&base::DoNothing), run_loop.QuitClosure()); 200 run_loop.Run(); 201 } 202 203 } // namespace 204 205 CannedSyncableFileSystem::CannedSyncableFileSystem( 206 const GURL& origin, 207 base::SingleThreadTaskRunner* io_task_runner, 208 base::SingleThreadTaskRunner* file_task_runner) 209 : origin_(origin), 210 type_(fileapi::kFileSystemTypeSyncable), 211 result_(base::PLATFORM_FILE_OK), 212 sync_status_(sync_file_system::SYNC_STATUS_OK), 213 io_task_runner_(io_task_runner), 214 file_task_runner_(file_task_runner), 215 is_filesystem_set_up_(false), 216 is_filesystem_opened_(false), 217 sync_status_observers_(new ObserverList) { 218 } 219 220 CannedSyncableFileSystem::~CannedSyncableFileSystem() {} 221 222 void CannedSyncableFileSystem::SetUp() { 223 ASSERT_FALSE(is_filesystem_set_up_); 224 ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); 225 226 scoped_refptr<quota::SpecialStoragePolicy> storage_policy = 227 new quota::MockSpecialStoragePolicy(); 228 229 quota_manager_ = new QuotaManager(false /* is_incognito */, 230 data_dir_.path(), 231 io_task_runner_.get(), 232 base::MessageLoopProxy::current().get(), 233 storage_policy.get()); 234 235 std::vector<std::string> additional_allowed_schemes; 236 additional_allowed_schemes.push_back(origin_.scheme()); 237 fileapi::FileSystemOptions options( 238 fileapi::FileSystemOptions::PROFILE_MODE_NORMAL, 239 additional_allowed_schemes); 240 241 ScopedVector<fileapi::FileSystemBackend> additional_backends; 242 additional_backends.push_back(SyncFileSystemBackend::CreateForTesting()); 243 244 file_system_context_ = new FileSystemContext( 245 io_task_runner_.get(), 246 file_task_runner_.get(), 247 fileapi::ExternalMountPoints::CreateRefCounted().get(), 248 storage_policy.get(), 249 quota_manager_->proxy(), 250 additional_backends.Pass(), 251 data_dir_.path(), options); 252 253 is_filesystem_set_up_ = true; 254 } 255 256 void CannedSyncableFileSystem::TearDown() { 257 quota_manager_ = NULL; 258 file_system_context_ = NULL; 259 260 // Make sure we give some more time to finish tasks on other threads. 261 EnsureLastTaskRuns(io_task_runner_.get()); 262 EnsureLastTaskRuns(file_task_runner_.get()); 263 } 264 265 FileSystemURL CannedSyncableFileSystem::URL(const std::string& path) const { 266 EXPECT_TRUE(is_filesystem_set_up_); 267 EXPECT_FALSE(root_url_.is_empty()); 268 269 GURL url(root_url_.spec() + path); 270 return file_system_context_->CrackURL(url); 271 } 272 273 PlatformFileError CannedSyncableFileSystem::OpenFileSystem() { 274 EXPECT_TRUE(is_filesystem_set_up_); 275 276 io_task_runner_->PostTask( 277 FROM_HERE, 278 base::Bind(&CannedSyncableFileSystem::DoOpenFileSystem, 279 base::Unretained(this), 280 base::Bind(&CannedSyncableFileSystem::DidOpenFileSystem, 281 base::Unretained(this), 282 base::MessageLoopProxy::current()))); 283 base::MessageLoop::current()->Run(); 284 285 if (backend()->sync_context()) { 286 // Register 'this' as a sync status observer. 287 RunOnThread( 288 io_task_runner_.get(), 289 FROM_HERE, 290 base::Bind(&CannedSyncableFileSystem::InitializeSyncStatusObserver, 291 base::Unretained(this))); 292 } 293 return result_; 294 } 295 296 void CannedSyncableFileSystem::AddSyncStatusObserver( 297 LocalFileSyncStatus::Observer* observer) { 298 sync_status_observers_->AddObserver(observer); 299 } 300 301 void CannedSyncableFileSystem::RemoveSyncStatusObserver( 302 LocalFileSyncStatus::Observer* observer) { 303 sync_status_observers_->RemoveObserver(observer); 304 } 305 306 SyncStatusCode CannedSyncableFileSystem::MaybeInitializeFileSystemContext( 307 LocalFileSyncContext* sync_context) { 308 DCHECK(sync_context); 309 sync_status_ = sync_file_system::SYNC_STATUS_UNKNOWN; 310 VerifySameTaskRunner(io_task_runner_.get(), 311 sync_context->io_task_runner_.get()); 312 sync_context->MaybeInitializeFileSystemContext( 313 origin_, 314 file_system_context_.get(), 315 base::Bind(&CannedSyncableFileSystem::DidInitializeFileSystemContext, 316 base::Unretained(this))); 317 base::MessageLoop::current()->Run(); 318 return sync_status_; 319 } 320 321 PlatformFileError CannedSyncableFileSystem::CreateDirectory( 322 const FileSystemURL& url) { 323 return RunOnThread<PlatformFileError>( 324 io_task_runner_.get(), 325 FROM_HERE, 326 base::Bind(&CannedSyncableFileSystem::DoCreateDirectory, 327 base::Unretained(this), 328 url)); 329 } 330 331 PlatformFileError CannedSyncableFileSystem::CreateFile( 332 const FileSystemURL& url) { 333 return RunOnThread<PlatformFileError>( 334 io_task_runner_.get(), 335 FROM_HERE, 336 base::Bind(&CannedSyncableFileSystem::DoCreateFile, 337 base::Unretained(this), 338 url)); 339 } 340 341 PlatformFileError CannedSyncableFileSystem::Copy( 342 const FileSystemURL& src_url, const FileSystemURL& dest_url) { 343 return RunOnThread<PlatformFileError>( 344 io_task_runner_.get(), 345 FROM_HERE, 346 base::Bind(&CannedSyncableFileSystem::DoCopy, 347 base::Unretained(this), 348 src_url, 349 dest_url)); 350 } 351 352 PlatformFileError CannedSyncableFileSystem::Move( 353 const FileSystemURL& src_url, const FileSystemURL& dest_url) { 354 return RunOnThread<PlatformFileError>( 355 io_task_runner_.get(), 356 FROM_HERE, 357 base::Bind(&CannedSyncableFileSystem::DoMove, 358 base::Unretained(this), 359 src_url, 360 dest_url)); 361 } 362 363 PlatformFileError CannedSyncableFileSystem::TruncateFile( 364 const FileSystemURL& url, int64 size) { 365 return RunOnThread<PlatformFileError>( 366 io_task_runner_.get(), 367 FROM_HERE, 368 base::Bind(&CannedSyncableFileSystem::DoTruncateFile, 369 base::Unretained(this), 370 url, 371 size)); 372 } 373 374 PlatformFileError CannedSyncableFileSystem::TouchFile( 375 const FileSystemURL& url, 376 const base::Time& last_access_time, 377 const base::Time& last_modified_time) { 378 return RunOnThread<PlatformFileError>( 379 io_task_runner_.get(), 380 FROM_HERE, 381 base::Bind(&CannedSyncableFileSystem::DoTouchFile, 382 base::Unretained(this), 383 url, 384 last_access_time, 385 last_modified_time)); 386 } 387 388 PlatformFileError CannedSyncableFileSystem::Remove( 389 const FileSystemURL& url, bool recursive) { 390 return RunOnThread<PlatformFileError>( 391 io_task_runner_.get(), 392 FROM_HERE, 393 base::Bind(&CannedSyncableFileSystem::DoRemove, 394 base::Unretained(this), 395 url, 396 recursive)); 397 } 398 399 PlatformFileError CannedSyncableFileSystem::FileExists( 400 const FileSystemURL& url) { 401 return RunOnThread<PlatformFileError>( 402 io_task_runner_.get(), 403 FROM_HERE, 404 base::Bind(&CannedSyncableFileSystem::DoFileExists, 405 base::Unretained(this), 406 url)); 407 } 408 409 PlatformFileError CannedSyncableFileSystem::DirectoryExists( 410 const FileSystemURL& url) { 411 return RunOnThread<PlatformFileError>( 412 io_task_runner_.get(), 413 FROM_HERE, 414 base::Bind(&CannedSyncableFileSystem::DoDirectoryExists, 415 base::Unretained(this), 416 url)); 417 } 418 419 PlatformFileError CannedSyncableFileSystem::VerifyFile( 420 const FileSystemURL& url, 421 const std::string& expected_data) { 422 return RunOnThread<PlatformFileError>( 423 io_task_runner_.get(), 424 FROM_HERE, 425 base::Bind(&CannedSyncableFileSystem::DoVerifyFile, 426 base::Unretained(this), 427 url, 428 expected_data)); 429 } 430 431 PlatformFileError CannedSyncableFileSystem::GetMetadataAndPlatformPath( 432 const FileSystemURL& url, 433 base::PlatformFileInfo* info, 434 base::FilePath* platform_path) { 435 return RunOnThread<PlatformFileError>( 436 io_task_runner_.get(), 437 FROM_HERE, 438 base::Bind(&CannedSyncableFileSystem::DoGetMetadataAndPlatformPath, 439 base::Unretained(this), 440 url, 441 info, 442 platform_path)); 443 } 444 445 PlatformFileError CannedSyncableFileSystem::ReadDirectory( 446 const fileapi::FileSystemURL& url, 447 FileEntryList* entries) { 448 return RunOnThread<PlatformFileError>( 449 io_task_runner_.get(), 450 FROM_HERE, 451 base::Bind(&CannedSyncableFileSystem::DoReadDirectory, 452 base::Unretained(this), 453 url, 454 entries)); 455 } 456 457 int64 CannedSyncableFileSystem::Write( 458 net::URLRequestContext* url_request_context, 459 const FileSystemURL& url, 460 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle) { 461 return RunOnThread<int64>(io_task_runner_.get(), 462 FROM_HERE, 463 base::Bind(&CannedSyncableFileSystem::DoWrite, 464 base::Unretained(this), 465 url_request_context, 466 url, 467 base::Passed(&blob_data_handle))); 468 } 469 470 int64 CannedSyncableFileSystem::WriteString( 471 const FileSystemURL& url, const std::string& data) { 472 return RunOnThread<int64>(io_task_runner_.get(), 473 FROM_HERE, 474 base::Bind(&CannedSyncableFileSystem::DoWriteString, 475 base::Unretained(this), 476 url, 477 data)); 478 } 479 480 PlatformFileError CannedSyncableFileSystem::DeleteFileSystem() { 481 EXPECT_TRUE(is_filesystem_set_up_); 482 return RunOnThread<PlatformFileError>( 483 io_task_runner_.get(), 484 FROM_HERE, 485 base::Bind(&FileSystemContext::DeleteFileSystem, 486 file_system_context_, 487 origin_, 488 type_)); 489 } 490 491 quota::QuotaStatusCode CannedSyncableFileSystem::GetUsageAndQuota( 492 int64* usage, int64* quota) { 493 return RunOnThread<quota::QuotaStatusCode>( 494 io_task_runner_.get(), 495 FROM_HERE, 496 base::Bind(&CannedSyncableFileSystem::DoGetUsageAndQuota, 497 base::Unretained(this), 498 usage, 499 quota)); 500 } 501 502 void CannedSyncableFileSystem::GetChangedURLsInTracker( 503 FileSystemURLSet* urls) { 504 RunOnThread( 505 file_task_runner_.get(), 506 FROM_HERE, 507 base::Bind(&LocalFileChangeTracker::GetAllChangedURLs, 508 base::Unretained(backend()->change_tracker()), 509 urls)); 510 } 511 512 void CannedSyncableFileSystem::ClearChangeForURLInTracker( 513 const FileSystemURL& url) { 514 RunOnThread( 515 file_task_runner_.get(), 516 FROM_HERE, 517 base::Bind(&LocalFileChangeTracker::ClearChangesForURL, 518 base::Unretained(backend()->change_tracker()), 519 url)); 520 } 521 522 void CannedSyncableFileSystem::GetChangesForURLInTracker( 523 const FileSystemURL& url, 524 FileChangeList* changes) { 525 RunOnThread( 526 file_task_runner_.get(), 527 FROM_HERE, 528 base::Bind(&LocalFileChangeTracker::GetChangesForURL, 529 base::Unretained(backend()->change_tracker()), 530 url, changes)); 531 } 532 533 SyncFileSystemBackend* CannedSyncableFileSystem::backend() { 534 return SyncFileSystemBackend::GetBackend(file_system_context_); 535 } 536 537 FileSystemOperationRunner* CannedSyncableFileSystem::operation_runner() { 538 return file_system_context_->operation_runner(); 539 } 540 541 void CannedSyncableFileSystem::OnSyncEnabled(const FileSystemURL& url) { 542 sync_status_observers_->Notify(&LocalFileSyncStatus::Observer::OnSyncEnabled, 543 url); 544 } 545 546 void CannedSyncableFileSystem::OnWriteEnabled(const FileSystemURL& url) { 547 sync_status_observers_->Notify(&LocalFileSyncStatus::Observer::OnWriteEnabled, 548 url); 549 } 550 551 void CannedSyncableFileSystem::DoOpenFileSystem( 552 const OpenFileSystemCallback& callback) { 553 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 554 EXPECT_FALSE(is_filesystem_opened_); 555 file_system_context_->OpenFileSystem( 556 origin_, type_, 557 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, 558 callback); 559 } 560 561 void CannedSyncableFileSystem::DoCreateDirectory( 562 const FileSystemURL& url, 563 const StatusCallback& callback) { 564 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 565 EXPECT_TRUE(is_filesystem_opened_); 566 operation_runner()->CreateDirectory( 567 url, false /* exclusive */, false /* recursive */, callback); 568 } 569 570 void CannedSyncableFileSystem::DoCreateFile( 571 const FileSystemURL& url, 572 const StatusCallback& callback) { 573 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 574 EXPECT_TRUE(is_filesystem_opened_); 575 operation_runner()->CreateFile(url, false /* exclusive */, callback); 576 } 577 578 void CannedSyncableFileSystem::DoCopy( 579 const FileSystemURL& src_url, 580 const FileSystemURL& dest_url, 581 const StatusCallback& callback) { 582 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 583 EXPECT_TRUE(is_filesystem_opened_); 584 operation_runner()->Copy( 585 src_url, dest_url, 586 fileapi::FileSystemOperation::OPTION_NONE, 587 fileapi::FileSystemOperationRunner::CopyProgressCallback(), callback); 588 } 589 590 void CannedSyncableFileSystem::DoMove( 591 const FileSystemURL& src_url, 592 const FileSystemURL& dest_url, 593 const StatusCallback& callback) { 594 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 595 EXPECT_TRUE(is_filesystem_opened_); 596 operation_runner()->Move( 597 src_url, dest_url, fileapi::FileSystemOperation::OPTION_NONE, callback); 598 } 599 600 void CannedSyncableFileSystem::DoTruncateFile( 601 const FileSystemURL& url, int64 size, 602 const StatusCallback& callback) { 603 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 604 EXPECT_TRUE(is_filesystem_opened_); 605 operation_runner()->Truncate(url, size, callback); 606 } 607 608 void CannedSyncableFileSystem::DoTouchFile( 609 const FileSystemURL& url, 610 const base::Time& last_access_time, 611 const base::Time& last_modified_time, 612 const StatusCallback& callback) { 613 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 614 EXPECT_TRUE(is_filesystem_opened_); 615 operation_runner()->TouchFile(url, last_access_time, 616 last_modified_time, callback); 617 } 618 619 void CannedSyncableFileSystem::DoRemove( 620 const FileSystemURL& url, bool recursive, 621 const StatusCallback& callback) { 622 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 623 EXPECT_TRUE(is_filesystem_opened_); 624 operation_runner()->Remove(url, recursive, callback); 625 } 626 627 void CannedSyncableFileSystem::DoFileExists( 628 const FileSystemURL& url, const StatusCallback& callback) { 629 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 630 EXPECT_TRUE(is_filesystem_opened_); 631 operation_runner()->FileExists(url, callback); 632 } 633 634 void CannedSyncableFileSystem::DoDirectoryExists( 635 const FileSystemURL& url, const StatusCallback& callback) { 636 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 637 EXPECT_TRUE(is_filesystem_opened_); 638 operation_runner()->DirectoryExists(url, callback); 639 } 640 641 void CannedSyncableFileSystem::DoVerifyFile( 642 const FileSystemURL& url, 643 const std::string& expected_data, 644 const StatusCallback& callback) { 645 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 646 EXPECT_TRUE(is_filesystem_opened_); 647 operation_runner()->CreateSnapshotFile( 648 url, 649 base::Bind(&OnCreateSnapshotFileAndVerifyData, expected_data, callback)); 650 } 651 652 void CannedSyncableFileSystem::DoGetMetadataAndPlatformPath( 653 const FileSystemURL& url, 654 base::PlatformFileInfo* info, 655 base::FilePath* platform_path, 656 const StatusCallback& callback) { 657 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 658 EXPECT_TRUE(is_filesystem_opened_); 659 operation_runner()->CreateSnapshotFile( 660 url, base::Bind(&OnCreateSnapshotFile, info, platform_path, callback)); 661 } 662 663 void CannedSyncableFileSystem::DoReadDirectory( 664 const FileSystemURL& url, 665 FileEntryList* entries, 666 const StatusCallback& callback) { 667 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 668 EXPECT_TRUE(is_filesystem_opened_); 669 operation_runner()->ReadDirectory( 670 url, base::Bind(&OnReadDirectory, entries, callback)); 671 } 672 673 void CannedSyncableFileSystem::DoWrite( 674 net::URLRequestContext* url_request_context, 675 const FileSystemURL& url, 676 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle, 677 const WriteCallback& callback) { 678 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 679 EXPECT_TRUE(is_filesystem_opened_); 680 WriteHelper* helper = new WriteHelper; 681 operation_runner()->Write(url_request_context, url, 682 blob_data_handle.Pass(), 0, 683 base::Bind(&WriteHelper::DidWrite, 684 base::Owned(helper), callback)); 685 } 686 687 void CannedSyncableFileSystem::DoWriteString( 688 const FileSystemURL& url, 689 const std::string& data, 690 const WriteCallback& callback) { 691 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 692 EXPECT_TRUE(is_filesystem_opened_); 693 MockBlobURLRequestContext* url_request_context( 694 new MockBlobURLRequestContext(file_system_context_.get())); 695 WriteHelper* helper = new WriteHelper(url_request_context, data); 696 operation_runner()->Write(url_request_context, url, 697 helper->scoped_text_blob()->GetBlobDataHandle(), 0, 698 base::Bind(&WriteHelper::DidWrite, 699 base::Owned(helper), callback)); 700 } 701 702 void CannedSyncableFileSystem::DoGetUsageAndQuota( 703 int64* usage, 704 int64* quota, 705 const quota::StatusCallback& callback) { 706 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 707 EXPECT_TRUE(is_filesystem_opened_); 708 quota_manager_->GetUsageAndQuota( 709 origin_, storage_type(), 710 base::Bind(&DidGetUsageAndQuota, callback, usage, quota)); 711 } 712 713 void CannedSyncableFileSystem::DidOpenFileSystem( 714 base::SingleThreadTaskRunner* original_task_runner, 715 const GURL& root, 716 const std::string& name, 717 PlatformFileError result) { 718 if (io_task_runner_->RunsTasksOnCurrentThread()) { 719 EXPECT_FALSE(is_filesystem_opened_); 720 is_filesystem_opened_ = true; 721 } 722 if (!original_task_runner->RunsTasksOnCurrentThread()) { 723 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 724 original_task_runner->PostTask( 725 FROM_HERE, 726 base::Bind(&CannedSyncableFileSystem::DidOpenFileSystem, 727 base::Unretained(this), 728 make_scoped_refptr(original_task_runner), 729 root, name, result)); 730 return; 731 } 732 result_ = result; 733 root_url_ = root; 734 base::MessageLoop::current()->Quit(); 735 } 736 737 void CannedSyncableFileSystem::DidInitializeFileSystemContext( 738 SyncStatusCode status) { 739 sync_status_ = status; 740 base::MessageLoop::current()->Quit(); 741 } 742 743 void CannedSyncableFileSystem::InitializeSyncStatusObserver() { 744 ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread()); 745 backend()->sync_context()->sync_status()->AddObserver(this); 746 } 747 748 } // namespace sync_file_system 749