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