Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / sync_file_system / local / canned_syncable_file_system.cc
blob9eb24c74e0444e09d76c406ba146497c6fdd75b6
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.
5 #include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
7 #include <algorithm>
8 #include <iterator>
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/files/file.h"
13 #include "base/files/file_util.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 "storage/browser/blob/shareable_file_reference.h"
28 #include "storage/browser/fileapi/external_mount_points.h"
29 #include "storage/browser/fileapi/file_system_backend.h"
30 #include "storage/browser/fileapi/file_system_context.h"
31 #include "storage/browser/fileapi/file_system_operation_context.h"
32 #include "storage/browser/fileapi/file_system_operation_runner.h"
33 #include "storage/browser/quota/quota_manager.h"
34 #include "testing/gtest/include/gtest/gtest.h"
36 using base::File;
37 using storage::FileSystemContext;
38 using storage::FileSystemOperationRunner;
39 using storage::FileSystemURL;
40 using storage::FileSystemURLSet;
41 using storage::QuotaManager;
42 using content::MockBlobURLRequestContext;
43 using content::ScopedTextBlob;
45 namespace sync_file_system {
47 namespace {
49 template <typename R>
50 void 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);
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 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;
75 void 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();
88 void EnsureRunningOn(base::SingleThreadTaskRunner* runner) {
89 EXPECT_TRUE(runner->RunsTasksOnCurrentThread());
92 void VerifySameTaskRunner(
93 base::SingleThreadTaskRunner* runner1,
94 base::SingleThreadTaskRunner* runner2) {
95 ASSERT_TRUE(runner1 != nullptr);
96 ASSERT_TRUE(runner2 != nullptr);
97 runner1->PostTask(FROM_HERE,
98 base::Bind(&EnsureRunningOn, make_scoped_refptr(runner2)));
101 void 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;
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);
120 void 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);
136 void 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));
145 if (!has_more)
146 callback.Run(error);
149 class 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)) {
161 ~WriteHelper() {
162 if (request_context_) {
163 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(
164 FROM_HERE, request_context_.release());
168 ScopedTextBlob* scoped_text_blob() const { return blob_data_.get(); }
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;
177 completion_callback.Run(error == base::File::FILE_OK ?
178 bytes_written_ : static_cast<int64>(error));
181 private:
182 int64 bytes_written_;
183 scoped_ptr<MockBlobURLRequestContext> request_context_;
184 scoped_ptr<ScopedTextBlob> blob_data_;
186 DISALLOW_COPY_AND_ASSIGN(WriteHelper);
189 void 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);
200 void 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();
207 } // namespace
209 CannedSyncableFileSystem::CannedSyncableFileSystem(
210 const GURL& origin,
211 leveldb::Env* env_override,
212 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
213 const scoped_refptr<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) {
226 CannedSyncableFileSystem::~CannedSyncableFileSystem() {}
228 void CannedSyncableFileSystem::SetUp(QuotaMode quota_mode) {
229 ASSERT_FALSE(is_filesystem_set_up_);
230 ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
232 scoped_refptr<storage::SpecialStoragePolicy> storage_policy =
233 new content::MockSpecialStoragePolicy();
235 if (quota_mode == QUOTA_ENABLED) {
236 quota_manager_ = new QuotaManager(false /* is_incognito */,
237 data_dir_.path(),
238 io_task_runner_.get(),
239 base::ThreadTaskRunnerHandle::Get().get(),
240 storage_policy.get());
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_);
250 ScopedVector<storage::FileSystemBackend> additional_backends;
251 additional_backends.push_back(SyncFileSystemBackend::CreateForTesting());
253 file_system_context_ = new FileSystemContext(
254 io_task_runner_.get(),
255 file_task_runner_.get(),
256 storage::ExternalMountPoints::CreateRefCounted().get(),
257 storage_policy.get(),
258 quota_manager_.get() ? quota_manager_->proxy() : nullptr,
259 additional_backends.Pass(),
260 std::vector<storage::URLRequestAutoMountHandler>(),
261 data_dir_.path(),
262 options);
264 is_filesystem_set_up_ = true;
267 void CannedSyncableFileSystem::TearDown() {
268 quota_manager_ = nullptr;
269 file_system_context_ = nullptr;
271 // Make sure we give some more time to finish tasks on other threads.
272 EnsureLastTaskRuns(io_task_runner_.get());
273 EnsureLastTaskRuns(file_task_runner_.get());
276 FileSystemURL CannedSyncableFileSystem::URL(const std::string& path) const {
277 EXPECT_TRUE(is_filesystem_set_up_);
278 EXPECT_FALSE(root_url_.is_empty());
280 GURL url(root_url_.spec() + path);
281 return file_system_context_->CrackURL(url);
284 File::Error CannedSyncableFileSystem::OpenFileSystem() {
285 EXPECT_TRUE(is_filesystem_set_up_);
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();
298 if (backend()->sync_context()) {
299 // Register 'this' as a sync status observer.
300 RunOnThread(
301 io_task_runner_.get(),
302 FROM_HERE,
303 base::Bind(&CannedSyncableFileSystem::InitializeSyncStatusObserver,
304 base::Unretained(this)));
306 return result_;
309 void CannedSyncableFileSystem::AddSyncStatusObserver(
310 LocalFileSyncStatus::Observer* observer) {
311 sync_status_observers_->AddObserver(observer);
314 void CannedSyncableFileSystem::RemoveSyncStatusObserver(
315 LocalFileSyncStatus::Observer* observer) {
316 sync_status_observers_->RemoveObserver(observer);
319 SyncStatusCode 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_.get(),
325 sync_context->io_task_runner_.get());
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_;
336 File::Error CannedSyncableFileSystem::CreateDirectory(
337 const FileSystemURL& url) {
338 return RunOnThread<File::Error>(
339 io_task_runner_.get(),
340 FROM_HERE,
341 base::Bind(&CannedSyncableFileSystem::DoCreateDirectory,
342 base::Unretained(this),
343 url));
346 File::Error CannedSyncableFileSystem::CreateFile(const FileSystemURL& url) {
347 return RunOnThread<File::Error>(
348 io_task_runner_.get(),
349 FROM_HERE,
350 base::Bind(&CannedSyncableFileSystem::DoCreateFile,
351 base::Unretained(this),
352 url));
355 File::Error CannedSyncableFileSystem::Copy(
356 const FileSystemURL& src_url, const FileSystemURL& dest_url) {
357 return RunOnThread<File::Error>(io_task_runner_.get(),
358 FROM_HERE,
359 base::Bind(&CannedSyncableFileSystem::DoCopy,
360 base::Unretained(this),
361 src_url,
362 dest_url));
365 File::Error CannedSyncableFileSystem::Move(
366 const FileSystemURL& src_url, const FileSystemURL& dest_url) {
367 return RunOnThread<File::Error>(io_task_runner_.get(),
368 FROM_HERE,
369 base::Bind(&CannedSyncableFileSystem::DoMove,
370 base::Unretained(this),
371 src_url,
372 dest_url));
375 File::Error CannedSyncableFileSystem::TruncateFile(
376 const FileSystemURL& url, int64 size) {
377 return RunOnThread<File::Error>(
378 io_task_runner_.get(),
379 FROM_HERE,
380 base::Bind(&CannedSyncableFileSystem::DoTruncateFile,
381 base::Unretained(this),
382 url,
383 size));
386 File::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_.get(),
392 FROM_HERE,
393 base::Bind(&CannedSyncableFileSystem::DoTouchFile,
394 base::Unretained(this),
395 url,
396 last_access_time,
397 last_modified_time));
400 File::Error CannedSyncableFileSystem::Remove(
401 const FileSystemURL& url, bool recursive) {
402 return RunOnThread<File::Error>(
403 io_task_runner_.get(),
404 FROM_HERE,
405 base::Bind(&CannedSyncableFileSystem::DoRemove,
406 base::Unretained(this),
407 url,
408 recursive));
411 File::Error CannedSyncableFileSystem::FileExists(
412 const FileSystemURL& url) {
413 return RunOnThread<File::Error>(
414 io_task_runner_.get(),
415 FROM_HERE,
416 base::Bind(&CannedSyncableFileSystem::DoFileExists,
417 base::Unretained(this),
418 url));
421 File::Error CannedSyncableFileSystem::DirectoryExists(
422 const FileSystemURL& url) {
423 return RunOnThread<File::Error>(
424 io_task_runner_.get(),
425 FROM_HERE,
426 base::Bind(&CannedSyncableFileSystem::DoDirectoryExists,
427 base::Unretained(this),
428 url));
431 File::Error CannedSyncableFileSystem::VerifyFile(
432 const FileSystemURL& url,
433 const std::string& expected_data) {
434 return RunOnThread<File::Error>(
435 io_task_runner_.get(),
436 FROM_HERE,
437 base::Bind(&CannedSyncableFileSystem::DoVerifyFile,
438 base::Unretained(this),
439 url,
440 expected_data));
443 File::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_.get(),
449 FROM_HERE,
450 base::Bind(&CannedSyncableFileSystem::DoGetMetadataAndPlatformPath,
451 base::Unretained(this),
452 url,
453 info,
454 platform_path));
457 File::Error CannedSyncableFileSystem::ReadDirectory(
458 const storage::FileSystemURL& url,
459 FileEntryList* entries) {
460 return RunOnThread<File::Error>(
461 io_task_runner_.get(),
462 FROM_HERE,
463 base::Bind(&CannedSyncableFileSystem::DoReadDirectory,
464 base::Unretained(this),
465 url,
466 entries));
469 int64 CannedSyncableFileSystem::Write(
470 net::URLRequestContext* url_request_context,
471 const FileSystemURL& url,
472 scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
473 return RunOnThread<int64>(io_task_runner_.get(),
474 FROM_HERE,
475 base::Bind(&CannedSyncableFileSystem::DoWrite,
476 base::Unretained(this),
477 url_request_context,
478 url,
479 base::Passed(&blob_data_handle)));
482 int64 CannedSyncableFileSystem::WriteString(
483 const FileSystemURL& url, const std::string& data) {
484 return RunOnThread<int64>(io_task_runner_.get(),
485 FROM_HERE,
486 base::Bind(&CannedSyncableFileSystem::DoWriteString,
487 base::Unretained(this),
488 url,
489 data));
492 File::Error CannedSyncableFileSystem::DeleteFileSystem() {
493 EXPECT_TRUE(is_filesystem_set_up_);
494 return RunOnThread<File::Error>(
495 io_task_runner_.get(),
496 FROM_HERE,
497 base::Bind(&FileSystemContext::DeleteFileSystem,
498 file_system_context_,
499 origin_,
500 type_));
503 storage::QuotaStatusCode CannedSyncableFileSystem::GetUsageAndQuota(
504 int64* usage,
505 int64* quota) {
506 return RunOnThread<storage::QuotaStatusCode>(
507 io_task_runner_.get(),
508 FROM_HERE,
509 base::Bind(&CannedSyncableFileSystem::DoGetUsageAndQuota,
510 base::Unretained(this),
511 usage,
512 quota));
515 void CannedSyncableFileSystem::GetChangedURLsInTracker(
516 FileSystemURLSet* urls) {
517 RunOnThread(file_task_runner_.get(),
518 FROM_HERE,
519 base::Bind(&LocalFileChangeTracker::GetAllChangedURLs,
520 base::Unretained(backend()->change_tracker()),
521 urls));
524 void CannedSyncableFileSystem::ClearChangeForURLInTracker(
525 const FileSystemURL& url) {
526 RunOnThread(file_task_runner_.get(),
527 FROM_HERE,
528 base::Bind(&LocalFileChangeTracker::ClearChangesForURL,
529 base::Unretained(backend()->change_tracker()),
530 url));
533 void CannedSyncableFileSystem::GetChangesForURLInTracker(
534 const FileSystemURL& url,
535 FileChangeList* changes) {
536 RunOnThread(file_task_runner_.get(),
537 FROM_HERE,
538 base::Bind(&LocalFileChangeTracker::GetChangesForURL,
539 base::Unretained(backend()->change_tracker()),
540 url,
541 changes));
544 SyncFileSystemBackend* CannedSyncableFileSystem::backend() {
545 return SyncFileSystemBackend::GetBackend(file_system_context_.get());
548 FileSystemOperationRunner* CannedSyncableFileSystem::operation_runner() {
549 return file_system_context_->operation_runner();
552 void CannedSyncableFileSystem::OnSyncEnabled(const FileSystemURL& url) {
553 sync_status_observers_->Notify(
554 FROM_HERE, &LocalFileSyncStatus::Observer::OnSyncEnabled, url);
557 void CannedSyncableFileSystem::OnWriteEnabled(const FileSystemURL& url) {
558 sync_status_observers_->Notify(
559 FROM_HERE, &LocalFileSyncStatus::Observer::OnWriteEnabled, url);
562 void CannedSyncableFileSystem::DoOpenFileSystem(
563 const OpenFileSystemCallback& callback) {
564 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
565 EXPECT_FALSE(is_filesystem_opened_);
566 file_system_context_->OpenFileSystem(
567 origin_,
568 type_,
569 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
570 callback);
573 void 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);
582 void 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);
590 void 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, storage::FileSystemOperation::OPTION_NONE,
598 storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
599 storage::FileSystemOperationRunner::CopyProgressCallback(), callback);
602 void 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, storage::FileSystemOperation::OPTION_NONE, callback);
612 void 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);
620 void 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);
631 void 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);
639 void 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);
646 void 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);
653 void 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));
664 void 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));
675 void 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));
685 void CannedSyncableFileSystem::DoWrite(
686 net::URLRequestContext* url_request_context,
687 const FileSystemURL& url,
688 scoped_ptr<storage::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));
699 void 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));
714 void CannedSyncableFileSystem::DoGetUsageAndQuota(
715 int64* usage,
716 int64* quota,
717 const storage::StatusCallback& callback) {
718 EXPECT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
719 EXPECT_TRUE(is_filesystem_opened_);
720 DCHECK(quota_manager_.get());
721 quota_manager_->GetUsageAndQuota(
722 origin_, storage_type(),
723 base::Bind(&DidGetUsageAndQuota, callback, usage, quota));
726 void 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;
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;
747 result_ = result;
748 root_url_ = root;
749 quit_closure.Run();
752 void CannedSyncableFileSystem::DidInitializeFileSystemContext(
753 const base::Closure& quit_closure,
754 SyncStatusCode status) {
755 sync_status_ = status;
756 quit_closure.Run();
759 void CannedSyncableFileSystem::InitializeSyncStatusObserver() {
760 ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
761 backend()->sync_context()->sync_status()->AddObserver(this);
764 } // namespace sync_file_system