 Chromium Code Reviews
 Chromium Code Reviews Issue 24106002:
  Add SNAPSHOT sync mode to LocalFileSyncContext::PrepareForSync  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 24106002:
  Add SNAPSHOT sync mode to LocalFileSyncContext::PrepareForSync  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| 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/location.h" | 8 #include "base/location.h" | 
| 9 #include "base/platform_file.h" | 9 #include "base/platform_file.h" | 
| 10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" | 
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 SyncFileSystemBackend* backend = | 122 SyncFileSystemBackend* backend = | 
| 123 SyncFileSystemBackend::GetBackend(file_system_context); | 123 SyncFileSystemBackend::GetBackend(file_system_context); | 
| 124 DCHECK(backend); | 124 DCHECK(backend); | 
| 125 DCHECK(backend->change_tracker()); | 125 DCHECK(backend->change_tracker()); | 
| 126 backend->change_tracker()->ClearChangesForURL(url); | 126 backend->change_tracker()->ClearChangesForURL(url); | 
| 127 | 127 | 
| 128 // Call the completion callback on UI thread. | 128 // Call the completion callback on UI thread. | 
| 129 ui_task_runner_->PostTask(FROM_HERE, done_callback); | 129 ui_task_runner_->PostTask(FROM_HERE, done_callback); | 
| 130 } | 130 } | 
| 131 | 131 | 
| 132 void LocalFileSyncContext::CommitChangeStatusForURL( | |
| 133 fileapi::FileSystemContext* file_system_context, | |
| 134 const fileapi::FileSystemURL& url, | |
| 135 SyncStatusCode sync_finish_status, | |
| 136 const base::Closure& done_callback) { | |
| 137 DCHECK(file_system_context); | |
| 138 if (!file_system_context->default_file_task_runner()-> | |
| 139 RunsTasksOnCurrentThread()) { | |
| 140 file_system_context->default_file_task_runner()->PostTask( | |
| 141 FROM_HERE, | |
| 142 base::Bind(&LocalFileSyncContext::CommitChangeStatusForURL, | |
| 143 this, make_scoped_refptr(file_system_context), | |
| 144 url, sync_finish_status, done_callback)); | |
| 145 return; | |
| 146 } | |
| 147 | |
| 148 SyncFileSystemBackend* backend = | |
| 149 SyncFileSystemBackend::GetBackend(file_system_context); | |
| 150 DCHECK(backend); | |
| 151 DCHECK(backend->change_tracker()); | |
| 152 | |
| 153 if (sync_finish_status == SYNC_STATUS_OK || | |
| 154 sync_finish_status == SYNC_STATUS_HAS_CONFLICT) { | |
| 155 // Commit the in-memory mirror change. | |
| 156 backend->change_tracker()->ResetToMirrorAndCommitChangesForURL(url); | |
| 157 } else { | |
| 158 // Abort in-memory mirror change. | |
| 159 backend->change_tracker()->RemoveMirrorAndCommitChangesForURL(url); | |
| 160 } | |
| 161 | |
| 162 // Call the completion callback on UI thread. | |
| 163 ui_task_runner_->PostTask(FROM_HERE, done_callback); | |
| 164 } | |
| 165 | |
| 132 void LocalFileSyncContext::ClearSyncFlagForURL(const FileSystemURL& url) { | 166 void LocalFileSyncContext::ClearSyncFlagForURL(const FileSystemURL& url) { | 
| 133 // This is initially called on UI thread and to be relayed to IO thread. | 167 // This is initially called on UI thread and to be relayed to IO thread. | 
| 134 io_task_runner_->PostTask( | 168 io_task_runner_->PostTask( | 
| 135 FROM_HERE, | 169 FROM_HERE, | 
| 136 base::Bind(&LocalFileSyncContext::EnableWritingOnIOThread, | 170 base::Bind(&LocalFileSyncContext::EnableWritingOnIOThread, | 
| 137 this, url)); | 171 this, url, true /* may_have_updates */)); | 
| 138 } | 172 } | 
| 139 | 173 | 
| 140 void LocalFileSyncContext::PrepareForSync( | 174 void LocalFileSyncContext::PrepareForSync( | 
| 141 FileSystemContext* file_system_context, | 175 FileSystemContext* file_system_context, | 
| 142 const FileSystemURL& url, | 176 const FileSystemURL& url, | 
| 177 SyncMode sync_mode, | |
| 143 const LocalFileSyncInfoCallback& callback) { | 178 const LocalFileSyncInfoCallback& callback) { | 
| 144 // 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. | 
| 145 if (!io_task_runner_->RunsTasksOnCurrentThread()) { | 180 if (!io_task_runner_->RunsTasksOnCurrentThread()) { | 
| 146 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 181 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 
| 147 io_task_runner_->PostTask( | 182 io_task_runner_->PostTask( | 
| 148 FROM_HERE, | 183 FROM_HERE, | 
| 149 base::Bind(&LocalFileSyncContext::PrepareForSync, this, | 184 base::Bind(&LocalFileSyncContext::PrepareForSync, this, | 
| 150 make_scoped_refptr(file_system_context), url, callback)); | 185 make_scoped_refptr(file_system_context), url, | 
| 186 sync_mode, callback)); | |
| 151 return; | 187 return; | 
| 152 } | 188 } | 
| 153 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 189 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 
| 154 const bool syncable = sync_status()->IsSyncable(url); | 190 const bool syncable = sync_status()->IsSyncable(url); | 
| 155 // Disable writing if it's ready to be synced. | 191 // Disable writing if it's ready to be synced. | 
| 156 if (syncable) | 192 if (syncable) | 
| 157 sync_status()->StartSyncing(url); | 193 sync_status()->StartSyncing(url); | 
| 158 ui_task_runner_->PostTask( | 194 ui_task_runner_->PostTask( | 
| 159 FROM_HERE, | 195 FROM_HERE, | 
| 160 base::Bind(&LocalFileSyncContext::DidGetWritingStatusForSync, | 196 base::Bind(&LocalFileSyncContext::DidGetWritingStatusForSync, | 
| 161 this, make_scoped_refptr(file_system_context), | 197 this, make_scoped_refptr(file_system_context), | 
| 162 syncable ? SYNC_STATUS_OK : | 198 syncable ? SYNC_STATUS_OK : | 
| 163 SYNC_STATUS_FILE_BUSY, | 199 SYNC_STATUS_FILE_BUSY, | 
| 164 url, callback)); | 200 url, sync_mode, callback)); | 
| 165 } | 201 } | 
| 166 | 202 | 
| 167 void LocalFileSyncContext::RegisterURLForWaitingSync( | 203 void LocalFileSyncContext::RegisterURLForWaitingSync( | 
| 168 const FileSystemURL& url, | 204 const FileSystemURL& url, | 
| 169 const base::Closure& on_syncable_callback) { | 205 const base::Closure& on_syncable_callback) { | 
| 170 // This is initially called on UI thread and to be relayed to IO thread. | 206 // This is initially called on UI thread and to be relayed to IO thread. | 
| 171 if (!io_task_runner_->RunsTasksOnCurrentThread()) { | 207 if (!io_task_runner_->RunsTasksOnCurrentThread()) { | 
| 172 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 208 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 
| 173 io_task_runner_->PostTask( | 209 io_task_runner_->PostTask( | 
| 174 FROM_HERE, | 210 FROM_HERE, | 
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 607 callback.Run(SYNC_STATUS_NO_CHANGE_TO_SYNC, | 643 callback.Run(SYNC_STATUS_NO_CHANGE_TO_SYNC, | 
| 608 LocalFileSyncInfo()); | 644 LocalFileSyncInfo()); | 
| 609 return; | 645 return; | 
| 610 } | 646 } | 
| 611 | 647 | 
| 612 const FileSystemURL url = urls->front(); | 648 const FileSystemURL url = urls->front(); | 
| 613 urls->pop_front(); | 649 urls->pop_front(); | 
| 614 std::deque<FileSystemURL>* remaining = new std::deque<FileSystemURL>; | 650 std::deque<FileSystemURL>* remaining = new std::deque<FileSystemURL>; | 
| 615 remaining->swap(*urls); | 651 remaining->swap(*urls); | 
| 616 | 652 | 
| 653 // TODO(kinuko): Call PrepareForSync with SYNC_SNAPSHOT when it becomes ready. | |
| 617 PrepareForSync( | 654 PrepareForSync( | 
| 618 file_system_context, url, | 655 file_system_context, url, SYNC_EXCLUSIVE, | 
| 619 base::Bind(&LocalFileSyncContext::DidTryPrepareForLocalSync, | 656 base::Bind(&LocalFileSyncContext::DidTryPrepareForLocalSync, | 
| 620 this, make_scoped_refptr(file_system_context), | 657 this, make_scoped_refptr(file_system_context), | 
| 621 base::Owned(remaining), callback)); | 658 base::Owned(remaining), callback)); | 
| 622 } | 659 } | 
| 623 | 660 | 
| 624 void LocalFileSyncContext::DidTryPrepareForLocalSync( | 661 void LocalFileSyncContext::DidTryPrepareForLocalSync( | 
| 625 FileSystemContext* file_system_context, | 662 FileSystemContext* file_system_context, | 
| 626 std::deque<FileSystemURL>* remaining_urls, | 663 std::deque<FileSystemURL>* remaining_urls, | 
| 627 const LocalFileSyncInfoCallback& callback, | 664 const LocalFileSyncInfoCallback& callback, | 
| 628 SyncStatusCode status, | 665 SyncStatusCode status, | 
| 629 const LocalFileSyncInfo& sync_file_info) { | 666 const LocalFileSyncInfo& sync_file_info) { | 
| 630 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 667 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 
| 631 if (status != SYNC_STATUS_FILE_BUSY) { | 668 if (status != SYNC_STATUS_FILE_BUSY) { | 
| 632 callback.Run(status, sync_file_info); | 669 callback.Run(status, sync_file_info); | 
| 633 return; | 670 return; | 
| 634 } | 671 } | 
| 635 // Recursively call TryPrepareForLocalSync with remaining_urls. | 672 // Recursively call TryPrepareForLocalSync with remaining_urls. | 
| 636 TryPrepareForLocalSync(file_system_context, remaining_urls, callback); | 673 TryPrepareForLocalSync(file_system_context, remaining_urls, callback); | 
| 637 } | 674 } | 
| 638 | 675 | 
| 639 void LocalFileSyncContext::DidGetWritingStatusForSync( | 676 void LocalFileSyncContext::DidGetWritingStatusForSync( | 
| 640 FileSystemContext* file_system_context, | 677 FileSystemContext* file_system_context, | 
| 641 SyncStatusCode status, | 678 SyncStatusCode status, | 
| 642 const FileSystemURL& url, | 679 const FileSystemURL& url, | 
| 680 SyncMode sync_mode, | |
| 643 const LocalFileSyncInfoCallback& callback) { | 681 const LocalFileSyncInfoCallback& callback) { | 
| 644 // This gets called on UI thread and relays the task on FILE thread. | 682 // This gets called on UI thread and relays the task on FILE thread. | 
| 645 DCHECK(file_system_context); | 683 DCHECK(file_system_context); | 
| 646 if (!file_system_context->default_file_task_runner()-> | 684 if (!file_system_context->default_file_task_runner()-> | 
| 647 RunsTasksOnCurrentThread()) { | 685 RunsTasksOnCurrentThread()) { | 
| 648 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 686 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 
| 649 if (shutdown_on_ui_) { | 687 if (shutdown_on_ui_) { | 
| 650 callback.Run(SYNC_STATUS_ABORT, LocalFileSyncInfo()); | 688 callback.Run(SYNC_STATUS_ABORT, LocalFileSyncInfo()); | 
| 651 return; | 689 return; | 
| 652 } | 690 } | 
| 653 file_system_context->default_file_task_runner()->PostTask( | 691 file_system_context->default_file_task_runner()->PostTask( | 
| 654 FROM_HERE, | 692 FROM_HERE, | 
| 655 base::Bind(&LocalFileSyncContext::DidGetWritingStatusForSync, | 693 base::Bind(&LocalFileSyncContext::DidGetWritingStatusForSync, | 
| 656 this, make_scoped_refptr(file_system_context), | 694 this, make_scoped_refptr(file_system_context), | 
| 657 status, url, callback)); | 695 status, url, sync_mode, callback)); | 
| 658 return; | 696 return; | 
| 659 } | 697 } | 
| 660 | 698 | 
| 661 SyncFileSystemBackend* backend = | 699 SyncFileSystemBackend* backend = | 
| 662 SyncFileSystemBackend::GetBackend(file_system_context); | 700 SyncFileSystemBackend::GetBackend(file_system_context); | 
| 663 DCHECK(backend); | 701 DCHECK(backend); | 
| 664 DCHECK(backend->change_tracker()); | 702 DCHECK(backend->change_tracker()); | 
| 665 FileChangeList changes; | 703 FileChangeList changes; | 
| 666 backend->change_tracker()->GetChangesForURL(url, &changes); | 704 backend->change_tracker()->GetChangesForURL(url, &changes); | 
| 667 | 705 | 
| 668 base::FilePath platform_path; | 706 base::FilePath platform_path; | 
| 669 base::PlatformFileInfo file_info; | 707 base::PlatformFileInfo file_info; | 
| 670 FileSystemFileUtil* file_util = | 708 FileSystemFileUtil* file_util = | 
| 671 file_system_context->sandbox_delegate()->sync_file_util(); | 709 file_system_context->sandbox_delegate()->sync_file_util(); | 
| 672 DCHECK(file_util); | 710 DCHECK(file_util); | 
| 711 | |
| 673 base::PlatformFileError file_error = file_util->GetFileInfo( | 712 base::PlatformFileError file_error = file_util->GetFileInfo( | 
| 674 make_scoped_ptr( | 713 make_scoped_ptr( | 
| 675 new FileSystemOperationContext(file_system_context)).get(), | 714 new FileSystemOperationContext(file_system_context)).get(), | 
| 676 url, | 715 url, | 
| 677 &file_info, | 716 &file_info, | 
| 678 &platform_path); | 717 &platform_path); | 
| 718 if (file_error == base::PLATFORM_FILE_OK && sync_mode == SYNC_SNAPSHOT) { | |
| 719 // TODO(kinuko): creates a snapshot file. | |
| 720 } | |
| 679 if (status == SYNC_STATUS_OK && | 721 if (status == SYNC_STATUS_OK && | 
| 680 file_error != base::PLATFORM_FILE_OK && | 722 file_error != base::PLATFORM_FILE_OK && | 
| 681 file_error != base::PLATFORM_FILE_ERROR_NOT_FOUND) | 723 file_error != base::PLATFORM_FILE_ERROR_NOT_FOUND) | 
| 682 status = PlatformFileErrorToSyncStatusCode(file_error); | 724 status = PlatformFileErrorToSyncStatusCode(file_error); | 
| 683 | 725 | 
| 684 DCHECK(!file_info.is_symbolic_link); | 726 DCHECK(!file_info.is_symbolic_link); | 
| 685 | 727 | 
| 686 SyncFileType file_type = SYNC_FILE_TYPE_FILE; | 728 SyncFileType file_type = SYNC_FILE_TYPE_FILE; | 
| 687 if (file_error == base::PLATFORM_FILE_ERROR_NOT_FOUND) | 729 if (file_error == base::PLATFORM_FILE_ERROR_NOT_FOUND) | 
| 688 file_type = SYNC_FILE_TYPE_UNKNOWN; | 730 file_type = SYNC_FILE_TYPE_UNKNOWN; | 
| 689 else if (file_info.is_directory) | 731 else if (file_info.is_directory) | 
| 690 file_type = SYNC_FILE_TYPE_DIRECTORY; | 732 file_type = SYNC_FILE_TYPE_DIRECTORY; | 
| 691 | 733 | 
| 734 // TODO(kinuko): returns the snapshot file path if snapshot is available. | |
| 692 LocalFileSyncInfo sync_file_info; | 735 LocalFileSyncInfo sync_file_info; | 
| 693 sync_file_info.url = url; | 736 sync_file_info.url = url; | 
| 694 sync_file_info.local_file_path = platform_path; | 737 sync_file_info.local_file_path = platform_path; | 
| 695 sync_file_info.metadata.file_type = file_type; | 738 sync_file_info.metadata.file_type = file_type; | 
| 696 sync_file_info.metadata.size = file_info.size; | 739 sync_file_info.metadata.size = file_info.size; | 
| 697 sync_file_info.metadata.last_modified = file_info.last_modified; | 740 sync_file_info.metadata.last_modified = file_info.last_modified; | 
| 698 sync_file_info.changes = changes; | 741 sync_file_info.changes = changes; | 
| 699 | 742 | 
| 743 if (status == SYNC_STATUS_OK) { | |
| 744 if (!changes.empty()) { | |
| 745 // Now we create an empty mirror change record for URL (and we record | |
| 746 // changes to both mirror and original records during sync), so that | |
| 747 // we can reset to the mirror when the sync succeeds. | |
| 748 backend->change_tracker()->CreateFreshMirrorForURL(url); | |
| 749 } | |
| 750 | |
| 751 // 'Unlock' the file if sync_mode is not SYNC_EXCLUSIVE. | |
| 752 if (sync_mode != SYNC_EXCLUSIVE) { | |
| 
nhiroki
2013/09/13 06:23:08
Do you have any plans to add new SyncMode other th
 
kinuko
2013/09/13 08:21:46
Not for now, but "If it's not exclusive we can rel
 | |
| 753 io_task_runner_->PostTask( | |
| 754 FROM_HERE, | |
| 755 base::Bind(&LocalFileSyncContext::EnableWritingOnIOThread, | |
| 756 this, url, false /* may_have_updates */)); | |
| 757 } | |
| 758 } | |
| 759 | |
| 700 ui_task_runner_->PostTask(FROM_HERE, | 760 ui_task_runner_->PostTask(FROM_HERE, | 
| 701 base::Bind(callback, status, sync_file_info)); | 761 base::Bind(callback, status, sync_file_info)); | 
| 702 } | 762 } | 
| 703 | 763 | 
| 704 void LocalFileSyncContext::EnableWritingOnIOThread( | 764 void LocalFileSyncContext::EnableWritingOnIOThread( | 
| 705 const FileSystemURL& url) { | 765 const FileSystemURL& url, | 
| 766 bool may_have_updates) { | |
| 706 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 767 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 
| 707 if (!sync_status()) { | 768 if (!sync_status()) { | 
| 708 // The service might have been shut down. | 769 // The service might have been shut down. | 
| 709 return; | 770 return; | 
| 710 } | 771 } | 
| 711 sync_status()->EndSyncing(url); | 772 sync_status()->EndSyncing(url); | 
| 773 | |
| 774 if (!may_have_updates) | |
| 775 return; | |
| 776 | |
| 712 // Since a sync has finished the number of changes must have been updated. | 777 // Since a sync has finished the number of changes must have been updated. | 
| 713 origins_with_pending_changes_.insert(url.origin()); | 778 origins_with_pending_changes_.insert(url.origin()); | 
| 714 ScheduleNotifyChangesUpdatedOnIOThread(); | 779 ScheduleNotifyChangesUpdatedOnIOThread(); | 
| 715 } | 780 } | 
| 716 | 781 | 
| 717 void LocalFileSyncContext::DidApplyRemoteChange( | 782 void LocalFileSyncContext::DidApplyRemoteChange( | 
| 718 const FileSystemURL& url, | 783 const FileSystemURL& url, | 
| 719 const SyncStatusCallback& callback_on_ui, | 784 const SyncStatusCallback& callback_on_ui, | 
| 720 base::PlatformFileError file_error) { | 785 base::PlatformFileError file_error) { | 
| 721 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 786 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 
| 722 ui_task_runner_->PostTask( | 787 ui_task_runner_->PostTask( | 
| 723 FROM_HERE, | 788 FROM_HERE, | 
| 724 base::Bind(callback_on_ui, | 789 base::Bind(callback_on_ui, | 
| 725 PlatformFileErrorToSyncStatusCode(file_error))); | 790 PlatformFileErrorToSyncStatusCode(file_error))); | 
| 726 EnableWritingOnIOThread(url); | 791 EnableWritingOnIOThread(url, true /* may_have_updates */); | 
| 727 } | 792 } | 
| 728 | 793 | 
| 729 void LocalFileSyncContext::DidGetFileMetadata( | 794 void LocalFileSyncContext::DidGetFileMetadata( | 
| 730 const SyncFileMetadataCallback& callback, | 795 const SyncFileMetadataCallback& callback, | 
| 731 base::PlatformFileError file_error, | 796 base::PlatformFileError file_error, | 
| 732 const base::PlatformFileInfo& file_info) { | 797 const base::PlatformFileInfo& file_info) { | 
| 733 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 798 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 
| 734 SyncFileMetadata metadata; | 799 SyncFileMetadata metadata; | 
| 735 if (file_error == base::PLATFORM_FILE_OK) { | 800 if (file_error == base::PLATFORM_FILE_OK) { | 
| 736 metadata.file_type = file_info.is_directory ? | 801 metadata.file_type = file_info.is_directory ? | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 762 return; | 827 return; | 
| 763 } | 828 } | 
| 764 | 829 | 
| 765 FileSystemURL url_for_sync = CreateSyncableFileSystemURLForSync( | 830 FileSystemURL url_for_sync = CreateSyncableFileSystemURLForSync( | 
| 766 file_system_context, dest_url); | 831 file_system_context, dest_url); | 
| 767 file_system_context->operation_runner()->CopyInForeignFile( | 832 file_system_context->operation_runner()->CopyInForeignFile( | 
| 768 local_path, url_for_sync, callback); | 833 local_path, url_for_sync, callback); | 
| 769 } | 834 } | 
| 770 | 835 | 
| 771 } // namespace sync_file_system | 836 } // namespace sync_file_system | 
| OLD | NEW |