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