| OLD | NEW | 
|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "chrome/browser/sync_file_system/local/local_file_sync_context.h" | 5 #include "chrome/browser/sync_file_system/local/local_file_sync_context.h" | 
| 6 | 6 | 
| 7 #include "base/bind.h" | 7 #include "base/bind.h" | 
|  | 8 #include "base/file_util.h" | 
| 8 #include "base/location.h" | 9 #include "base/location.h" | 
| 9 #include "base/platform_file.h" | 10 #include "base/platform_file.h" | 
| 10 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" | 
| 11 #include "base/stl_util.h" | 12 #include "base/stl_util.h" | 
| 12 #include "base/task_runner_util.h" | 13 #include "base/task_runner_util.h" | 
| 13 #include "chrome/browser/sync_file_system/file_change.h" | 14 #include "chrome/browser/sync_file_system/file_change.h" | 
| 14 #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h" | 15 #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h" | 
| 15 #include "chrome/browser/sync_file_system/local/local_origin_change_observer.h" | 16 #include "chrome/browser/sync_file_system/local/local_origin_change_observer.h" | 
| 16 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" | 17 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" | 
| 17 #include "chrome/browser/sync_file_system/local/syncable_file_operation_runner.h
     " | 18 #include "chrome/browser/sync_file_system/local/syncable_file_operation_runner.h
     " | 
| 18 #include "chrome/browser/sync_file_system/sync_file_metadata.h" | 19 #include "chrome/browser/sync_file_system/sync_file_metadata.h" | 
| 19 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" | 20 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" | 
| 20 #include "webkit/browser/fileapi/file_system_context.h" | 21 #include "webkit/browser/fileapi/file_system_context.h" | 
| 21 #include "webkit/browser/fileapi/file_system_file_util.h" | 22 #include "webkit/browser/fileapi/file_system_file_util.h" | 
| 22 #include "webkit/browser/fileapi/file_system_operation_context.h" | 23 #include "webkit/browser/fileapi/file_system_operation_context.h" | 
| 23 #include "webkit/browser/fileapi/file_system_operation_runner.h" | 24 #include "webkit/browser/fileapi/file_system_operation_runner.h" | 
|  | 25 #include "webkit/common/blob/scoped_file.h" | 
| 24 #include "webkit/common/fileapi/file_system_util.h" | 26 #include "webkit/common/fileapi/file_system_util.h" | 
| 25 | 27 | 
| 26 using fileapi::FileSystemContext; | 28 using fileapi::FileSystemContext; | 
| 27 using fileapi::FileSystemFileUtil; | 29 using fileapi::FileSystemFileUtil; | 
| 28 using fileapi::FileSystemOperation; | 30 using fileapi::FileSystemOperation; | 
| 29 using fileapi::FileSystemOperationContext; | 31 using fileapi::FileSystemOperationContext; | 
| 30 using fileapi::FileSystemURL; | 32 using fileapi::FileSystemURL; | 
| 31 | 33 | 
| 32 namespace sync_file_system { | 34 namespace sync_file_system { | 
| 33 | 35 | 
| 34 namespace { | 36 namespace { | 
| 35 | 37 | 
| 36 const int kMaxConcurrentSyncableOperation = 3; | 38 const int kMaxConcurrentSyncableOperation = 3; | 
| 37 const int kNotifyChangesDurationInSec = 1; | 39 const int kNotifyChangesDurationInSec = 1; | 
| 38 const int kMaxURLsToFetchForLocalSync = 5; | 40 const int kMaxURLsToFetchForLocalSync = 5; | 
| 39 | 41 | 
|  | 42 const base::FilePath::CharType kSnapshotDir[] = FILE_PATH_LITERAL("snapshots"); | 
|  | 43 | 
| 40 }  // namespace | 44 }  // namespace | 
| 41 | 45 | 
| 42 LocalFileSyncContext::LocalFileSyncContext( | 46 LocalFileSyncContext::LocalFileSyncContext( | 
|  | 47     const base::FilePath& base_path, | 
| 43     base::SingleThreadTaskRunner* ui_task_runner, | 48     base::SingleThreadTaskRunner* ui_task_runner, | 
| 44     base::SingleThreadTaskRunner* io_task_runner) | 49     base::SingleThreadTaskRunner* io_task_runner) | 
| 45     : ui_task_runner_(ui_task_runner), | 50     : local_base_path_(base_path.Append(FILE_PATH_LITERAL("local"))), | 
|  | 51       ui_task_runner_(ui_task_runner), | 
| 46       io_task_runner_(io_task_runner), | 52       io_task_runner_(io_task_runner), | 
| 47       shutdown_on_ui_(false), | 53       shutdown_on_ui_(false), | 
| 48       mock_notify_changes_duration_in_sec_(-1) { | 54       mock_notify_changes_duration_in_sec_(-1) { | 
| 49   DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 55   DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 
| 50 } | 56 } | 
| 51 | 57 | 
| 52 void LocalFileSyncContext::MaybeInitializeFileSystemContext( | 58 void LocalFileSyncContext::MaybeInitializeFileSystemContext( | 
| 53     const GURL& source_url, | 59     const GURL& source_url, | 
| 54     FileSystemContext* file_system_context, | 60     FileSystemContext* file_system_context, | 
| 55     const SyncStatusCallback& callback) { | 61     const SyncStatusCallback& callback) { | 
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 152 | 158 | 
| 153   if (sync_finish_status == SYNC_STATUS_OK || | 159   if (sync_finish_status == SYNC_STATUS_OK || | 
| 154       sync_finish_status == SYNC_STATUS_HAS_CONFLICT) { | 160       sync_finish_status == SYNC_STATUS_HAS_CONFLICT) { | 
| 155     // Commit the in-memory mirror change. | 161     // Commit the in-memory mirror change. | 
| 156     backend->change_tracker()->ResetToMirrorAndCommitChangesForURL(url); | 162     backend->change_tracker()->ResetToMirrorAndCommitChangesForURL(url); | 
| 157   } else { | 163   } else { | 
| 158     // Abort in-memory mirror change. | 164     // Abort in-memory mirror change. | 
| 159     backend->change_tracker()->RemoveMirrorAndCommitChangesForURL(url); | 165     backend->change_tracker()->RemoveMirrorAndCommitChangesForURL(url); | 
| 160   } | 166   } | 
| 161 | 167 | 
|  | 168   // We've been keeping it in writing mode, so clear the writing counter | 
|  | 169   // to unblock sync activities. | 
|  | 170   io_task_runner_->PostTask( | 
|  | 171       FROM_HERE, base::Bind(&LocalFileSyncContext::EndWritingOnIOThread, | 
|  | 172                             this, url)); | 
|  | 173 | 
| 162   // Call the completion callback on UI thread. | 174   // Call the completion callback on UI thread. | 
| 163   ui_task_runner_->PostTask(FROM_HERE, done_callback); | 175   ui_task_runner_->PostTask(FROM_HERE, done_callback); | 
| 164 } | 176 } | 
| 165 | 177 | 
| 166 void LocalFileSyncContext::ClearSyncFlagForURL(const FileSystemURL& url) { | 178 void LocalFileSyncContext::ClearSyncFlagForURL(const FileSystemURL& url) { | 
| 167   // This is initially called on UI thread and to be relayed to IO thread. | 179   // This is initially called on UI thread and to be relayed to IO thread. | 
| 168   io_task_runner_->PostTask( | 180   io_task_runner_->PostTask( | 
| 169       FROM_HERE, | 181       FROM_HERE, | 
| 170       base::Bind(&LocalFileSyncContext::EnableWritingOnIOThread, | 182       base::Bind(&LocalFileSyncContext::ClearSyncFlagOnIOThread, | 
| 171                  this, url, true /* may_have_updates */)); | 183                  this, url, false /* keep_url_in_writing */)); | 
| 172 } | 184 } | 
| 173 | 185 | 
| 174 void LocalFileSyncContext::PrepareForSync( | 186 void LocalFileSyncContext::PrepareForSync( | 
| 175     FileSystemContext* file_system_context, | 187     FileSystemContext* file_system_context, | 
| 176     const FileSystemURL& url, | 188     const FileSystemURL& url, | 
| 177     SyncMode sync_mode, | 189     SyncMode sync_mode, | 
| 178     const LocalFileSyncInfoCallback& callback) { | 190     const LocalFileSyncInfoCallback& callback) { | 
| 179   // This is initially called on UI thread and to be relayed to IO thread. | 191   // This is initially called on UI thread and to be relayed to IO thread. | 
| 180   if (!io_task_runner_->RunsTasksOnCurrentThread()) { | 192   if (!io_task_runner_->RunsTasksOnCurrentThread()) { | 
| 181     DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 193     DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 543   if (status != SYNC_STATUS_OK) | 555   if (status != SYNC_STATUS_OK) | 
| 544     return status; | 556     return status; | 
| 545 | 557 | 
| 546   // Get all origins that have pending changes. | 558   // Get all origins that have pending changes. | 
| 547   std::deque<FileSystemURL> urls; | 559   std::deque<FileSystemURL> urls; | 
| 548   (*tracker_ptr)->GetNextChangedURLs(&urls, 0); | 560   (*tracker_ptr)->GetNextChangedURLs(&urls, 0); | 
| 549   for (std::deque<FileSystemURL>::iterator iter = urls.begin(); | 561   for (std::deque<FileSystemURL>::iterator iter = urls.begin(); | 
| 550        iter != urls.end(); ++iter) { | 562        iter != urls.end(); ++iter) { | 
| 551     origins_with_changes->insert(iter->origin()); | 563     origins_with_changes->insert(iter->origin()); | 
| 552   } | 564   } | 
|  | 565 | 
|  | 566   // Creates snapshot directory. | 
|  | 567   file_util::CreateDirectory(local_base_path_.Append(kSnapshotDir)); | 
|  | 568 | 
| 553   return status; | 569   return status; | 
| 554 } | 570 } | 
| 555 | 571 | 
| 556 void LocalFileSyncContext::DidInitializeChangeTrackerOnIOThread( | 572 void LocalFileSyncContext::DidInitializeChangeTrackerOnIOThread( | 
| 557     scoped_ptr<LocalFileChangeTracker>* tracker_ptr, | 573     scoped_ptr<LocalFileChangeTracker>* tracker_ptr, | 
| 558     const GURL& source_url, | 574     const GURL& source_url, | 
| 559     FileSystemContext* file_system_context, | 575     FileSystemContext* file_system_context, | 
| 560     std::set<GURL>* origins_with_changes, | 576     std::set<GURL>* origins_with_changes, | 
| 561     SyncStatusCode status) { | 577     SyncStatusCode status) { | 
| 562   DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 578   DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 626 } | 642 } | 
| 627 | 643 | 
| 628 void LocalFileSyncContext::TryPrepareForLocalSync( | 644 void LocalFileSyncContext::TryPrepareForLocalSync( | 
| 629     FileSystemContext* file_system_context, | 645     FileSystemContext* file_system_context, | 
| 630     std::deque<FileSystemURL>* urls, | 646     std::deque<FileSystemURL>* urls, | 
| 631     const LocalFileSyncInfoCallback& callback) { | 647     const LocalFileSyncInfoCallback& callback) { | 
| 632   DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 648   DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 
| 633   DCHECK(urls); | 649   DCHECK(urls); | 
| 634 | 650 | 
| 635   if (shutdown_on_ui_) { | 651   if (shutdown_on_ui_) { | 
| 636     callback.Run(SYNC_STATUS_ABORT, LocalFileSyncInfo()); | 652     callback.Run(SYNC_STATUS_ABORT, LocalFileSyncInfo(), | 
|  | 653                  scoped_ptr<webkit_blob::ScopedFile>()); | 
| 637     return; | 654     return; | 
| 638   } | 655   } | 
| 639 | 656 | 
| 640   if (urls->empty()) { | 657   if (urls->empty()) { | 
| 641     callback.Run(SYNC_STATUS_NO_CHANGE_TO_SYNC, | 658     callback.Run(SYNC_STATUS_NO_CHANGE_TO_SYNC, LocalFileSyncInfo(), | 
| 642                  LocalFileSyncInfo()); | 659                  scoped_ptr<webkit_blob::ScopedFile>()); | 
| 643     return; | 660     return; | 
| 644   } | 661   } | 
| 645 | 662 | 
| 646   const FileSystemURL url = urls->front(); | 663   const FileSystemURL url = urls->front(); | 
| 647   urls->pop_front(); | 664   urls->pop_front(); | 
| 648   std::deque<FileSystemURL>* remaining = new std::deque<FileSystemURL>; | 665   std::deque<FileSystemURL>* remaining = new std::deque<FileSystemURL>; | 
| 649   remaining->swap(*urls); | 666   remaining->swap(*urls); | 
| 650 | 667 | 
| 651   // TODO(kinuko): Call PrepareForSync with SYNC_SNAPSHOT when it becomes ready. |  | 
| 652   PrepareForSync( | 668   PrepareForSync( | 
| 653       file_system_context, url, SYNC_EXCLUSIVE, | 669       file_system_context, url, SYNC_SNAPSHOT, | 
| 654       base::Bind(&LocalFileSyncContext::DidTryPrepareForLocalSync, | 670       base::Bind(&LocalFileSyncContext::DidTryPrepareForLocalSync, | 
| 655                  this, make_scoped_refptr(file_system_context), | 671                  this, make_scoped_refptr(file_system_context), | 
| 656                  base::Owned(remaining), callback)); | 672                  base::Owned(remaining), callback)); | 
| 657 } | 673 } | 
| 658 | 674 | 
| 659 void LocalFileSyncContext::DidTryPrepareForLocalSync( | 675 void LocalFileSyncContext::DidTryPrepareForLocalSync( | 
| 660     FileSystemContext* file_system_context, | 676     FileSystemContext* file_system_context, | 
| 661     std::deque<FileSystemURL>* remaining_urls, | 677     std::deque<FileSystemURL>* remaining_urls, | 
| 662     const LocalFileSyncInfoCallback& callback, | 678     const LocalFileSyncInfoCallback& callback, | 
| 663     SyncStatusCode status, | 679     SyncStatusCode status, | 
| 664     const LocalFileSyncInfo& sync_file_info) { | 680     const LocalFileSyncInfo& sync_file_info, | 
|  | 681     scoped_ptr<webkit_blob::ScopedFile> snapshot) { | 
| 665   DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 682   DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 
| 666   if (status != SYNC_STATUS_FILE_BUSY) { | 683   if (status != SYNC_STATUS_FILE_BUSY) { | 
| 667     callback.Run(status, sync_file_info); | 684     callback.Run(status, sync_file_info, snapshot.Pass()); | 
| 668     return; | 685     return; | 
| 669   } | 686   } | 
| 670   // Recursively call TryPrepareForLocalSync with remaining_urls. | 687   // Recursively call TryPrepareForLocalSync with remaining_urls. | 
| 671   TryPrepareForLocalSync(file_system_context, remaining_urls, callback); | 688   TryPrepareForLocalSync(file_system_context, remaining_urls, callback); | 
| 672 } | 689 } | 
| 673 | 690 | 
| 674 void LocalFileSyncContext::DidGetWritingStatusForSync( | 691 void LocalFileSyncContext::DidGetWritingStatusForSync( | 
| 675     FileSystemContext* file_system_context, | 692     FileSystemContext* file_system_context, | 
| 676     SyncStatusCode status, | 693     SyncStatusCode status, | 
| 677     const FileSystemURL& url, | 694     const FileSystemURL& url, | 
| 678     SyncMode sync_mode, | 695     SyncMode sync_mode, | 
| 679     const LocalFileSyncInfoCallback& callback) { | 696     const LocalFileSyncInfoCallback& callback) { | 
| 680   // This gets called on UI thread and relays the task on FILE thread. | 697   // This gets called on UI thread and relays the task on FILE thread. | 
| 681   DCHECK(file_system_context); | 698   DCHECK(file_system_context); | 
| 682   if (!file_system_context->default_file_task_runner()-> | 699   if (!file_system_context->default_file_task_runner()-> | 
| 683           RunsTasksOnCurrentThread()) { | 700           RunsTasksOnCurrentThread()) { | 
| 684     DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 701     DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 
| 685     if (shutdown_on_ui_) { | 702     if (shutdown_on_ui_) { | 
| 686       callback.Run(SYNC_STATUS_ABORT, LocalFileSyncInfo()); | 703       callback.Run(SYNC_STATUS_ABORT, LocalFileSyncInfo(), | 
|  | 704                    scoped_ptr<webkit_blob::ScopedFile>()); | 
| 687       return; | 705       return; | 
| 688     } | 706     } | 
| 689     file_system_context->default_file_task_runner()->PostTask( | 707     file_system_context->default_file_task_runner()->PostTask( | 
| 690         FROM_HERE, | 708         FROM_HERE, | 
| 691         base::Bind(&LocalFileSyncContext::DidGetWritingStatusForSync, | 709         base::Bind(&LocalFileSyncContext::DidGetWritingStatusForSync, | 
| 692                    this, make_scoped_refptr(file_system_context), | 710                    this, make_scoped_refptr(file_system_context), | 
| 693                    status, url, sync_mode, callback)); | 711                    status, url, sync_mode, callback)); | 
| 694     return; | 712     return; | 
| 695   } | 713   } | 
| 696 | 714 | 
| 697   SyncFileSystemBackend* backend = | 715   SyncFileSystemBackend* backend = | 
| 698       SyncFileSystemBackend::GetBackend(file_system_context); | 716       SyncFileSystemBackend::GetBackend(file_system_context); | 
| 699   DCHECK(backend); | 717   DCHECK(backend); | 
| 700   DCHECK(backend->change_tracker()); | 718   DCHECK(backend->change_tracker()); | 
| 701   FileChangeList changes; | 719   FileChangeList changes; | 
| 702   backend->change_tracker()->GetChangesForURL(url, &changes); | 720   backend->change_tracker()->GetChangesForURL(url, &changes); | 
| 703 | 721 | 
| 704   base::FilePath platform_path; | 722   base::FilePath platform_path; | 
| 705   base::PlatformFileInfo file_info; | 723   base::PlatformFileInfo file_info; | 
| 706   FileSystemFileUtil* file_util = | 724   FileSystemFileUtil* file_util = | 
| 707       file_system_context->sandbox_delegate()->sync_file_util(); | 725       file_system_context->sandbox_delegate()->sync_file_util(); | 
| 708   DCHECK(file_util); | 726   DCHECK(file_util); | 
| 709 | 727 | 
| 710   base::PlatformFileError file_error = file_util->GetFileInfo( | 728   base::PlatformFileError file_error = file_util->GetFileInfo( | 
| 711       make_scoped_ptr( | 729       make_scoped_ptr( | 
| 712           new FileSystemOperationContext(file_system_context)).get(), | 730           new FileSystemOperationContext(file_system_context)).get(), | 
| 713       url, | 731       url, | 
| 714       &file_info, | 732       &file_info, | 
| 715       &platform_path); | 733       &platform_path); | 
|  | 734 | 
|  | 735   scoped_ptr<webkit_blob::ScopedFile> snapshot; | 
| 716   if (file_error == base::PLATFORM_FILE_OK && sync_mode == SYNC_SNAPSHOT) { | 736   if (file_error == base::PLATFORM_FILE_OK && sync_mode == SYNC_SNAPSHOT) { | 
| 717     // TODO(kinuko): creates a snapshot file. | 737     base::FilePath snapshot_path; | 
|  | 738     file_util::CreateTemporaryFileInDir(local_base_path_.Append(kSnapshotDir), | 
|  | 739                                         &snapshot_path); | 
|  | 740     if (base::CopyFile(platform_path, snapshot_path)) { | 
|  | 741       platform_path = snapshot_path; | 
|  | 742       snapshot.reset(new webkit_blob::ScopedFile( | 
|  | 743           snapshot_path, | 
|  | 744           webkit_blob::ScopedFile::DELETE_ON_SCOPE_OUT, | 
|  | 745           file_system_context->default_file_task_runner())); | 
|  | 746     } | 
| 718   } | 747   } | 
|  | 748 | 
| 719   if (status == SYNC_STATUS_OK && | 749   if (status == SYNC_STATUS_OK && | 
| 720       file_error != base::PLATFORM_FILE_OK && | 750       file_error != base::PLATFORM_FILE_OK && | 
| 721       file_error != base::PLATFORM_FILE_ERROR_NOT_FOUND) | 751       file_error != base::PLATFORM_FILE_ERROR_NOT_FOUND) | 
| 722     status = PlatformFileErrorToSyncStatusCode(file_error); | 752     status = PlatformFileErrorToSyncStatusCode(file_error); | 
| 723 | 753 | 
| 724   DCHECK(!file_info.is_symbolic_link); | 754   DCHECK(!file_info.is_symbolic_link); | 
| 725 | 755 | 
| 726   SyncFileType file_type = SYNC_FILE_TYPE_FILE; | 756   SyncFileType file_type = SYNC_FILE_TYPE_FILE; | 
| 727   if (file_error == base::PLATFORM_FILE_ERROR_NOT_FOUND) | 757   if (file_error == base::PLATFORM_FILE_ERROR_NOT_FOUND) | 
| 728     file_type = SYNC_FILE_TYPE_UNKNOWN; | 758     file_type = SYNC_FILE_TYPE_UNKNOWN; | 
| 729   else if (file_info.is_directory) | 759   else if (file_info.is_directory) | 
| 730     file_type = SYNC_FILE_TYPE_DIRECTORY; | 760     file_type = SYNC_FILE_TYPE_DIRECTORY; | 
| 731 | 761 | 
| 732   // TODO(kinuko): returns the snapshot file path if snapshot is available. |  | 
| 733   LocalFileSyncInfo sync_file_info; | 762   LocalFileSyncInfo sync_file_info; | 
| 734   sync_file_info.url = url; | 763   sync_file_info.url = url; | 
| 735   sync_file_info.local_file_path = platform_path; | 764   sync_file_info.local_file_path = platform_path; | 
| 736   sync_file_info.metadata.file_type = file_type; | 765   sync_file_info.metadata.file_type = file_type; | 
| 737   sync_file_info.metadata.size = file_info.size; | 766   sync_file_info.metadata.size = file_info.size; | 
| 738   sync_file_info.metadata.last_modified = file_info.last_modified; | 767   sync_file_info.metadata.last_modified = file_info.last_modified; | 
| 739   sync_file_info.changes = changes; | 768   sync_file_info.changes = changes; | 
| 740 | 769 | 
| 741   if (status == SYNC_STATUS_OK) { | 770   if (status == SYNC_STATUS_OK) { | 
| 742     if (!changes.empty()) { | 771     if (!changes.empty()) { | 
| 743       // Now we create an empty mirror change record for URL (and we record | 772       // Now we create an empty mirror change record for URL (and we record | 
| 744       // changes to both mirror and original records during sync), so that | 773       // changes to both mirror and original records during sync), so that | 
| 745       // we can reset to the mirror when the sync succeeds. | 774       // we can reset to the mirror when the sync succeeds. | 
| 746       backend->change_tracker()->CreateFreshMirrorForURL(url); | 775       backend->change_tracker()->CreateFreshMirrorForURL(url); | 
| 747     } | 776     } | 
| 748 | 777 | 
| 749     // 'Unlock' the file if sync_mode is not SYNC_EXCLUSIVE. | 778     // 'Unlock' the file if sync_mode is not SYNC_EXCLUSIVE. | 
|  | 779     // (But keep it in writing status so that no other sync starts on | 
|  | 780     // the same URL) | 
| 750     if (sync_mode != SYNC_EXCLUSIVE) { | 781     if (sync_mode != SYNC_EXCLUSIVE) { | 
| 751       io_task_runner_->PostTask( | 782       io_task_runner_->PostTask( | 
| 752           FROM_HERE, | 783           FROM_HERE, | 
| 753           base::Bind(&LocalFileSyncContext::EnableWritingOnIOThread, | 784           base::Bind(&LocalFileSyncContext::ClearSyncFlagOnIOThread, | 
| 754                     this, url, false /* may_have_updates */)); | 785                      this, url, true /* keep_url_in_writing */)); | 
| 755     } | 786     } | 
| 756   } | 787   } | 
| 757 | 788 | 
| 758   ui_task_runner_->PostTask(FROM_HERE, | 789   ui_task_runner_->PostTask(FROM_HERE, | 
| 759                             base::Bind(callback, status, sync_file_info)); | 790                             base::Bind(callback, status, sync_file_info, | 
|  | 791                                        base::Passed(&snapshot))); | 
| 760 } | 792 } | 
| 761 | 793 | 
| 762 void LocalFileSyncContext::EnableWritingOnIOThread( | 794 void LocalFileSyncContext::ClearSyncFlagOnIOThread( | 
| 763     const FileSystemURL& url, | 795     const FileSystemURL& url, | 
| 764     bool may_have_updates) { | 796     bool keep_url_in_writing) { | 
| 765   DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 797   DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 
| 766   if (!sync_status()) { | 798   if (!sync_status()) { | 
| 767     // The service might have been shut down. | 799     // The service might have been shut down. | 
| 768     return; | 800     return; | 
| 769   } | 801   } | 
| 770   sync_status()->EndSyncing(url); | 802   sync_status()->EndSyncing(url); | 
| 771 | 803 | 
| 772   if (!may_have_updates) | 804   if (keep_url_in_writing) { | 
|  | 805     // The caller will hold shared lock on this one. | 
|  | 806     sync_status()->StartWriting(url); | 
| 773     return; | 807     return; | 
|  | 808   } | 
| 774 | 809 | 
| 775   // Since a sync has finished the number of changes must have been updated. | 810   // Since a sync has finished the number of changes must have been updated. | 
| 776   origins_with_pending_changes_.insert(url.origin()); | 811   origins_with_pending_changes_.insert(url.origin()); | 
| 777   ScheduleNotifyChangesUpdatedOnIOThread(); | 812   ScheduleNotifyChangesUpdatedOnIOThread(); | 
| 778 } | 813 } | 
| 779 | 814 | 
|  | 815 void LocalFileSyncContext::EndWritingOnIOThread( | 
|  | 816     const FileSystemURL& url) { | 
|  | 817   DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 
|  | 818   if (!sync_status()) { | 
|  | 819     // The service might have been shut down. | 
|  | 820     return; | 
|  | 821   } | 
|  | 822   sync_status()->EndWriting(url); | 
|  | 823 } | 
|  | 824 | 
| 780 void LocalFileSyncContext::DidApplyRemoteChange( | 825 void LocalFileSyncContext::DidApplyRemoteChange( | 
| 781     const FileSystemURL& url, | 826     const FileSystemURL& url, | 
| 782     const SyncStatusCallback& callback_on_ui, | 827     const SyncStatusCallback& callback_on_ui, | 
| 783     base::PlatformFileError file_error) { | 828     base::PlatformFileError file_error) { | 
| 784   DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 829   DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 
| 785   ui_task_runner_->PostTask( | 830   ui_task_runner_->PostTask( | 
| 786       FROM_HERE, | 831       FROM_HERE, | 
| 787       base::Bind(callback_on_ui, | 832       base::Bind(callback_on_ui, | 
| 788                  PlatformFileErrorToSyncStatusCode(file_error))); | 833                  PlatformFileErrorToSyncStatusCode(file_error))); | 
| 789   EnableWritingOnIOThread(url, true /* may_have_updates */); | 834   ClearSyncFlagOnIOThread(url, false /* keep_url_in_writing */); | 
| 790 } | 835 } | 
| 791 | 836 | 
| 792 void LocalFileSyncContext::DidGetFileMetadata( | 837 void LocalFileSyncContext::DidGetFileMetadata( | 
| 793     const SyncFileMetadataCallback& callback, | 838     const SyncFileMetadataCallback& callback, | 
| 794     base::PlatformFileError file_error, | 839     base::PlatformFileError file_error, | 
| 795     const base::PlatformFileInfo& file_info) { | 840     const base::PlatformFileInfo& file_info) { | 
| 796   DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 841   DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 
| 797   SyncFileMetadata metadata; | 842   SyncFileMetadata metadata; | 
| 798   if (file_error == base::PLATFORM_FILE_OK) { | 843   if (file_error == base::PLATFORM_FILE_OK) { | 
| 799     metadata.file_type = file_info.is_directory ? | 844     metadata.file_type = file_info.is_directory ? | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 825     return; | 870     return; | 
| 826   } | 871   } | 
| 827 | 872 | 
| 828   FileSystemURL url_for_sync = CreateSyncableFileSystemURLForSync( | 873   FileSystemURL url_for_sync = CreateSyncableFileSystemURLForSync( | 
| 829       file_system_context, dest_url); | 874       file_system_context, dest_url); | 
| 830   file_system_context->operation_runner()->CopyInForeignFile( | 875   file_system_context->operation_runner()->CopyInForeignFile( | 
| 831       local_path, url_for_sync, callback); | 876       local_path, url_for_sync, callback); | 
| 832 } | 877 } | 
| 833 | 878 | 
| 834 }  // namespace sync_file_system | 879 }  // namespace sync_file_system | 
| OLD | NEW | 
|---|