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