| 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) { |
| 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 |