OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/drive_file_sync_service.h" | 5 #include "chrome/browser/sync_file_system/drive_file_sync_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 17 matching lines...) Expand all Loading... | |
28 #include "webkit/fileapi/syncable/sync_file_type.h" | 28 #include "webkit/fileapi/syncable/sync_file_type.h" |
29 #include "webkit/fileapi/syncable/syncable_file_system_util.h" | 29 #include "webkit/fileapi/syncable/syncable_file_system_util.h" |
30 | 30 |
31 namespace sync_file_system { | 31 namespace sync_file_system { |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 const FilePath::CharType kTempDirName[] = FILE_PATH_LITERAL("tmp"); | 35 const FilePath::CharType kTempDirName[] = FILE_PATH_LITERAL("tmp"); |
36 const FilePath::CharType kSyncFileSystemDir[] = | 36 const FilePath::CharType kSyncFileSystemDir[] = |
37 FILE_PATH_LITERAL("Sync FileSystem"); | 37 FILE_PATH_LITERAL("Sync FileSystem"); |
38 const char kResourceLinkPrefix[] = | |
39 "https://docs.google.com/feeds/default/private/full/"; | |
kinuko
2012/11/29 11:40:46
Can we use GDataWapiUrlGenerator::GenerateDocument
tzik
2012/12/03 10:00:08
Done
| |
40 const int64 kMinimumPollingDelaySeconds = 10; | |
41 const int64 kMaximumPollingDelaySeconds = 60 * 60; // 1 hour | |
42 const int64 kDelayMultiplier = 2; | |
38 | 43 |
39 bool CreateTemporaryFile(const FilePath& dir_path, FilePath* temp_file) { | 44 bool CreateTemporaryFile(const FilePath& dir_path, FilePath* temp_file) { |
40 return file_util::CreateDirectory(dir_path) && | 45 return file_util::CreateDirectory(dir_path) && |
41 file_util::CreateTemporaryFileInDir(dir_path, temp_file); | 46 file_util::CreateTemporaryFileInDir(dir_path, temp_file); |
42 } | 47 } |
43 | 48 |
44 void DeleteTemporaryFile(const FilePath& file_path) { | 49 void DeleteTemporaryFile(const FilePath& file_path) { |
45 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) { | 50 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) { |
46 content::BrowserThread::PostTask( | 51 content::BrowserThread::PostTask( |
47 content::BrowserThread::FILE, FROM_HERE, | 52 content::BrowserThread::FILE, FROM_HERE, |
48 base::Bind(&DeleteTemporaryFile, file_path)); | 53 base::Bind(&DeleteTemporaryFile, file_path)); |
49 return; | 54 return; |
50 } | 55 } |
51 | 56 |
52 if (!file_util::Delete(file_path, true)) | 57 if (!file_util::Delete(file_path, true)) |
53 LOG(ERROR) << "Leaked temporary file for Sync FileSystem: " | 58 LOG(ERROR) << "Leaked temporary file for Sync FileSystem: " |
54 << file_path.value(); | 59 << file_path.value(); |
55 } | 60 } |
56 | 61 |
57 void DidUpdateConflictState(fileapi::SyncStatusCode status) { | 62 void DidUpdateConflictState(fileapi::SyncStatusCode status) { |
58 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status); | 63 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status); |
59 } | 64 } |
60 | 65 |
61 void EmptyStatusCallback(fileapi::SyncStatusCode code) {} | 66 void EmptyStatusCallback(fileapi::SyncStatusCode code) {} |
62 | 67 |
68 | |
kinuko
2012/11/29 11:40:46
nit: extra empty line
tzik
2012/12/03 10:00:08
Done.
| |
69 GURL ResourceIdToResourceLink(const std::string& resource_id) { | |
70 return GURL(kResourceLinkPrefix + net::EscapePath(resource_id)); | |
71 } | |
72 | |
63 } // namespace | 73 } // namespace |
64 | 74 |
65 const char DriveFileSyncService::kServiceName[] = "drive"; | 75 const char DriveFileSyncService::kServiceName[] = "drive"; |
66 | 76 |
67 class DriveFileSyncService::TaskToken { | 77 class DriveFileSyncService::TaskToken { |
68 public: | 78 public: |
69 explicit TaskToken(const base::WeakPtr<DriveFileSyncService>& sync_service) | 79 explicit TaskToken(const base::WeakPtr<DriveFileSyncService>& sync_service) |
70 : sync_service_(sync_service), | 80 : sync_service_(sync_service), |
71 task_type_(TASK_TYPE_NONE) { | 81 task_type_(TASK_TYPE_NONE) { |
72 } | 82 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 // Smaller changestamps have higher priorities (i.e. need to be processed | 205 // Smaller changestamps have higher priorities (i.e. need to be processed |
196 // earlier). | 206 // earlier). |
197 if (left.changestamp != right.changestamp) | 207 if (left.changestamp != right.changestamp) |
198 return left.changestamp > right.changestamp; | 208 return left.changestamp > right.changestamp; |
199 return false; | 209 return false; |
200 } | 210 } |
201 | 211 |
202 DriveFileSyncService::DriveFileSyncService(Profile* profile) | 212 DriveFileSyncService::DriveFileSyncService(Profile* profile) |
203 : last_operation_status_(fileapi::SYNC_STATUS_OK), | 213 : last_operation_status_(fileapi::SYNC_STATUS_OK), |
204 state_(REMOTE_SERVICE_OK), | 214 state_(REMOTE_SERVICE_OK), |
205 largest_changestamp_(0), | 215 largest_synced_changestamp_(0), |
kinuko
2012/11/29 11:47:43
We're not using this?
tzik
2012/12/03 10:00:08
Done. Removed.
| |
216 largest_fetched_changestamp_(0), | |
217 polling_delay_(base::TimeDelta::FromSeconds(kMinimumPollingDelaySeconds)), | |
206 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 218 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
207 temporary_file_dir_ = | 219 temporary_file_dir_ = |
208 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); | 220 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); |
209 token_.reset(new TaskToken(AsWeakPtr())); | 221 token_.reset(new TaskToken(AsWeakPtr())); |
210 | 222 |
211 sync_client_.reset(new DriveFileSyncClient(profile)); | 223 sync_client_.reset(new DriveFileSyncClient(profile)); |
212 | 224 |
213 metadata_store_.reset(new DriveMetadataStore( | 225 metadata_store_.reset(new DriveMetadataStore( |
214 profile->GetPath().Append(kSyncFileSystemDir), | 226 profile->GetPath().Append(kSyncFileSystemDir), |
215 content::BrowserThread::GetMessageLoopProxyForThread( | 227 content::BrowserThread::GetMessageLoopProxyForThread( |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 callback, fileapi::SYNC_STATUS_FAILED); | 508 callback, fileapi::SYNC_STATUS_FAILED); |
497 } | 509 } |
498 | 510 |
499 // Called by CreateForTesting. | 511 // Called by CreateForTesting. |
500 DriveFileSyncService::DriveFileSyncService( | 512 DriveFileSyncService::DriveFileSyncService( |
501 const FilePath& base_dir, | 513 const FilePath& base_dir, |
502 scoped_ptr<DriveFileSyncClient> sync_client, | 514 scoped_ptr<DriveFileSyncClient> sync_client, |
503 scoped_ptr<DriveMetadataStore> metadata_store) | 515 scoped_ptr<DriveMetadataStore> metadata_store) |
504 : last_operation_status_(fileapi::SYNC_STATUS_OK), | 516 : last_operation_status_(fileapi::SYNC_STATUS_OK), |
505 state_(REMOTE_SERVICE_OK), | 517 state_(REMOTE_SERVICE_OK), |
506 largest_changestamp_(0), | 518 largest_synced_changestamp_(0), |
519 largest_fetched_changestamp_(0), | |
507 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 520 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
508 temporary_file_dir_ = base_dir.Append(kTempDirName); | 521 temporary_file_dir_ = base_dir.Append(kTempDirName); |
509 | 522 |
510 token_.reset(new TaskToken(AsWeakPtr())); | 523 token_.reset(new TaskToken(AsWeakPtr())); |
511 sync_client_ = sync_client.Pass(); | 524 sync_client_ = sync_client.Pass(); |
512 metadata_store_ = metadata_store.Pass(); | 525 metadata_store_ = metadata_store.Pass(); |
513 | 526 |
514 DidInitializeMetadataStore( | 527 DidInitializeMetadataStore( |
515 GetToken(FROM_HERE, TASK_TYPE_NONE, "Drive initialization for testing"), | 528 GetToken(FROM_HERE, TASK_TYPE_NONE, "Drive initialization for testing"), |
516 fileapi::SYNC_STATUS_OK, false); | 529 fileapi::SYNC_STATUS_OK, false); |
517 } | 530 } |
518 | 531 |
519 scoped_ptr<DriveFileSyncService::TaskToken> DriveFileSyncService::GetToken( | 532 scoped_ptr<DriveFileSyncService::TaskToken> DriveFileSyncService::GetToken( |
520 const tracked_objects::Location& from_here, | 533 const tracked_objects::Location& from_here, |
521 TaskType task_type, | 534 TaskType task_type, |
522 const std::string& description) { | 535 const std::string& description) { |
523 if (!token_) | 536 if (!token_) |
524 return scoped_ptr<TaskToken>(); | 537 return scoped_ptr<TaskToken>(); |
525 token_->UpdateTask(from_here, task_type, description); | 538 token_->UpdateTask(from_here, task_type, description); |
526 return token_.Pass(); | 539 return token_.Pass(); |
527 } | 540 } |
528 | 541 |
529 void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status, | 542 void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status, |
530 scoped_ptr<TaskToken> token) { | 543 scoped_ptr<TaskToken> token) { |
531 DCHECK(token); | 544 DCHECK(token); |
532 last_operation_status_ = status; | 545 last_operation_status_ = status; |
533 token_ = token.Pass(); | 546 token_ = token.Pass(); |
534 | 547 |
535 RemoteServiceState old_state = state_; | |
536 if (token_->task_type() != TASK_TYPE_NONE) { | 548 if (token_->task_type() != TASK_TYPE_NONE) { |
537 DVLOG(1) << "NotifyTaskDone: " << token_->description() | 549 DVLOG(1) << "NotifyTaskDone: " << token_->description() |
538 << ": finished with status=" << status | 550 << ": finished with status=" << status |
539 << " " << token_->location().ToString(); | 551 << " " << token_->location().ToString(); |
540 | 552 |
541 RemoteServiceState old_state = state_; | 553 RemoteServiceState old_state = state_; |
542 UpdateServiceState(); | 554 UpdateServiceState(); |
543 | 555 |
544 // Notify remote sync service state if the state has been changed. | 556 // Notify remote sync service state if the state has been changed. |
545 if (!token_->description().empty() || old_state != state_) { | 557 if (!token_->description().empty() || old_state != state_) { |
546 FOR_EACH_OBSERVER( | 558 FOR_EACH_OBSERVER( |
547 Observer, observers_, | 559 Observer, observers_, |
548 OnRemoteServiceStateUpdated(state_, token_->done_description())); | 560 OnRemoteServiceStateUpdated(state_, token_->done_description())); |
549 } | 561 } |
550 } | 562 } |
551 | 563 |
552 token_->ResetTask(FROM_HERE); | 564 token_->ResetTask(FROM_HERE); |
553 if (!pending_tasks_.empty()) { | 565 if (!pending_tasks_.empty()) { |
554 base::Closure closure = pending_tasks_.front(); | 566 base::Closure closure = pending_tasks_.front(); |
555 pending_tasks_.pop_front(); | 567 pending_tasks_.pop_front(); |
556 closure.Run(); | 568 closure.Run(); |
557 return; | 569 return; |
558 } | 570 } |
559 | 571 |
560 if (state_ != REMOTE_SERVICE_OK || old_state == state_) | 572 if (state_ != REMOTE_SERVICE_OK) |
561 return; | 573 return; |
562 | 574 |
563 // If the state has become OK and we have any pending batch sync origins | 575 // If the state has become OK and we have any pending batch sync origins |
564 // restart batch sync for them. | 576 // restart batch sync for them. |
565 if (!pending_batch_sync_origins_.empty()) { | 577 if (!pending_batch_sync_origins_.empty()) { |
566 GURL origin = *pending_batch_sync_origins_.begin(); | 578 GURL origin = *pending_batch_sync_origins_.begin(); |
567 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin()); | 579 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin()); |
568 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin); | 580 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin); |
569 StartBatchSyncForOrigin(origin, resource_id); | 581 StartBatchSyncForOrigin(origin, resource_id); |
582 return; | |
570 } | 583 } |
584 | |
585 FOR_EACH_OBSERVER(Observer, observers_, | |
kinuko
2012/11/29 11:40:46
Can you comment why we do this here?
tzik
2012/12/03 10:00:08
Done.
| |
586 OnRemoteChangeAvailable(pending_changes_.size())); | |
587 | |
588 if (pending_changes_.empty()) | |
589 SchedulePolling(); | |
571 } | 590 } |
572 | 591 |
573 void DriveFileSyncService::UpdateServiceState() { | 592 void DriveFileSyncService::UpdateServiceState() { |
574 switch (last_operation_status_) { | 593 switch (last_operation_status_) { |
575 // Possible regular operation errors. | 594 // Possible regular operation errors. |
576 case fileapi::SYNC_STATUS_OK: | 595 case fileapi::SYNC_STATUS_OK: |
577 case fileapi::SYNC_STATUS_FILE_BUSY: | 596 case fileapi::SYNC_STATUS_FILE_BUSY: |
578 case fileapi::SYNC_STATUS_HAS_CONFLICT: | 597 case fileapi::SYNC_STATUS_HAS_CONFLICT: |
579 case fileapi::SYNC_STATUS_NOT_A_CONFLICT: | 598 case fileapi::SYNC_STATUS_NOT_A_CONFLICT: |
580 case fileapi::SYNC_STATUS_NO_CHANGE_TO_SYNC: | 599 case fileapi::SYNC_STATUS_NO_CHANGE_TO_SYNC: |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
622 | 641 |
623 void DriveFileSyncService::DidInitializeMetadataStore( | 642 void DriveFileSyncService::DidInitializeMetadataStore( |
624 scoped_ptr<TaskToken> token, | 643 scoped_ptr<TaskToken> token, |
625 fileapi::SyncStatusCode status, | 644 fileapi::SyncStatusCode status, |
626 bool created) { | 645 bool created) { |
627 if (status != fileapi::SYNC_STATUS_OK) { | 646 if (status != fileapi::SYNC_STATUS_OK) { |
628 NotifyTaskDone(status, token.Pass()); | 647 NotifyTaskDone(status, token.Pass()); |
629 return; | 648 return; |
630 } | 649 } |
631 | 650 |
651 largest_synced_changestamp_ = metadata_store_->GetLargestChangeStamp(); | |
652 largest_fetched_changestamp_ = metadata_store_->GetLargestChangeStamp(); | |
653 | |
632 if (metadata_store_->sync_root_directory().empty()) { | 654 if (metadata_store_->sync_root_directory().empty()) { |
633 GetSyncRootDirectory(token.Pass(), base::Bind(&EmptyStatusCallback)); | 655 GetSyncRootDirectory(token.Pass(), base::Bind(&EmptyStatusCallback)); |
634 return; | 656 return; |
635 } | 657 } |
636 | 658 |
637 NotifyTaskDone(status, token.Pass()); | 659 NotifyTaskDone(status, token.Pass()); |
638 | 660 |
639 for (std::map<GURL, std::string>::const_iterator itr = | 661 for (std::map<GURL, std::string>::const_iterator itr = |
640 metadata_store_->batch_sync_origins().begin(); | 662 metadata_store_->batch_sync_origins().begin(); |
641 itr != metadata_store_->batch_sync_origins().end(); | 663 itr != metadata_store_->batch_sync_origins().end(); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
756 if (error != google_apis::HTTP_SUCCESS) { | 778 if (error != google_apis::HTTP_SUCCESS) { |
757 pending_batch_sync_origins_.insert(origin); | 779 pending_batch_sync_origins_.insert(origin); |
758 // TODO(tzik): Refine this error code. | 780 // TODO(tzik): Refine this error code. |
759 NotifyTaskDone(GDataErrorCodeToSyncStatusCode(error), token.Pass()); | 781 NotifyTaskDone(GDataErrorCodeToSyncStatusCode(error), token.Pass()); |
760 return; | 782 return; |
761 } | 783 } |
762 | 784 |
763 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator; | 785 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator; |
764 for (iterator itr = feed->entries().begin(); | 786 for (iterator itr = feed->entries().begin(); |
765 itr != feed->entries().end(); ++itr) { | 787 itr != feed->entries().end(); ++itr) { |
766 AppendNewRemoteChange(origin, *itr, largest_changestamp, | 788 AppendNewRemoteChange(origin, **itr, largest_changestamp, |
767 REMOTE_SYNC_TYPE_BATCH); | 789 REMOTE_SYNC_TYPE_BATCH); |
768 } | 790 } |
769 | 791 |
770 GURL next_feed_url; | 792 GURL next_feed_url; |
771 if (feed->GetNextFeedURL(&next_feed_url)) { | 793 if (feed->GetNextFeedURL(&next_feed_url)) { |
772 sync_client_->ContinueListing( | 794 sync_client_->ContinueListing( |
773 next_feed_url, | 795 next_feed_url, |
774 base::Bind( | 796 base::Bind( |
775 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, | 797 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, |
776 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); | 798 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
995 const DriveMetadata& drive_metadata = param->drive_metadata; | 1017 const DriveMetadata& drive_metadata = param->drive_metadata; |
996 | 1018 |
997 status = metadata_store_->ReadEntry(param->remote_change.url, | 1019 status = metadata_store_->ReadEntry(param->remote_change.url, |
998 ¶m->drive_metadata); | 1020 ¶m->drive_metadata); |
999 DCHECK(status == fileapi::SYNC_STATUS_OK || | 1021 DCHECK(status == fileapi::SYNC_STATUS_OK || |
1000 status == fileapi::SYNC_DATABASE_ERROR_NOT_FOUND); | 1022 status == fileapi::SYNC_DATABASE_ERROR_NOT_FOUND); |
1001 | 1023 |
1002 bool missing_db_entry = (status != fileapi::SYNC_STATUS_OK); | 1024 bool missing_db_entry = (status != fileapi::SYNC_STATUS_OK); |
1003 if (missing_db_entry) { | 1025 if (missing_db_entry) { |
1004 param->drive_metadata.set_resource_id(param->remote_change.resource_id); | 1026 param->drive_metadata.set_resource_id(param->remote_change.resource_id); |
1027 param->drive_metadata.set_md5_checksum(std::string()); | |
1005 param->drive_metadata.set_conflicted(false); | 1028 param->drive_metadata.set_conflicted(false); |
1006 } | 1029 } |
1007 bool missing_local_file = | 1030 bool missing_local_file = |
1008 (metadata.file_type == fileapi::SYNC_FILE_TYPE_UNKNOWN); | 1031 (metadata.file_type == fileapi::SYNC_FILE_TYPE_UNKNOWN); |
1009 | 1032 |
1010 if (param->drive_metadata.conflicted()) { | 1033 if (param->drive_metadata.conflicted()) { |
1011 if (missing_local_file) { | 1034 if (missing_local_file) { |
1012 if (param->remote_change.change.IsAddOrUpdate()) { | 1035 if (param->remote_change.change.IsAddOrUpdate()) { |
1013 NOTIMPLEMENTED() << "ResolveToRemote()"; | 1036 NOTIMPLEMENTED() << "ResolveToRemote()"; |
1014 AbortRemoteSync(param.Pass(), fileapi::SYNC_STATUS_FAILED); | 1037 AbortRemoteSync(param.Pass(), fileapi::SYNC_STATUS_FAILED); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1074 | 1097 |
1075 DCHECK(param->remote_change.change.IsDelete()); | 1098 DCHECK(param->remote_change.change.IsDelete()); |
1076 if (local_changes.empty()) { | 1099 if (local_changes.empty()) { |
1077 if (missing_local_file) { | 1100 if (missing_local_file) { |
1078 param->operation_type = fileapi::SYNC_OPERATION_NONE; | 1101 param->operation_type = fileapi::SYNC_OPERATION_NONE; |
1079 DeleteMetadataForRemoteSync(param.Pass()); | 1102 DeleteMetadataForRemoteSync(param.Pass()); |
1080 return; | 1103 return; |
1081 } | 1104 } |
1082 DCHECK(!missing_local_file); | 1105 DCHECK(!missing_local_file); |
1083 param->operation_type = fileapi::SYNC_OPERATION_DELETE; | 1106 param->operation_type = fileapi::SYNC_OPERATION_DELETE; |
1107 | |
1108 const fileapi::FileChange& file_change = param->remote_change.change; | |
1084 param->processor->ApplyRemoteChange( | 1109 param->processor->ApplyRemoteChange( |
1085 param->remote_change.change, FilePath(), url, | 1110 file_change, FilePath(), url, |
1086 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, AsWeakPtr(), | 1111 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, AsWeakPtr(), |
1087 base::Passed(¶m))); | 1112 base::Passed(¶m))); |
1088 return; | 1113 return; |
1089 } | 1114 } |
1090 | 1115 |
1091 DCHECK(!local_changes.empty()); | 1116 DCHECK(!local_changes.empty()); |
1092 if (local_changes.list().back().IsAddOrUpdate()) { | 1117 if (local_changes.list().back().IsAddOrUpdate()) { |
1093 param->operation_type = fileapi::SYNC_OPERATION_NONE; | 1118 param->operation_type = fileapi::SYNC_OPERATION_NONE; |
1094 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); | 1119 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); |
1095 return; | 1120 return; |
(...skipping 18 matching lines...) Expand all Loading... | |
1114 } | 1139 } |
1115 | 1140 |
1116 void DriveFileSyncService::DidGetTemporaryFileForDownload( | 1141 void DriveFileSyncService::DidGetTemporaryFileForDownload( |
1117 scoped_ptr<ProcessRemoteChangeParam> param, | 1142 scoped_ptr<ProcessRemoteChangeParam> param, |
1118 bool success) { | 1143 bool success) { |
1119 if (!success) { | 1144 if (!success) { |
1120 AbortRemoteSync(param.Pass(), fileapi::SYNC_FILE_ERROR_FAILED); | 1145 AbortRemoteSync(param.Pass(), fileapi::SYNC_FILE_ERROR_FAILED); |
1121 return; | 1146 return; |
1122 } | 1147 } |
1123 | 1148 |
1124 DriveMetadata metadata; | |
1125 metadata_store_->ReadEntry(param->remote_change.url, &metadata); | |
1126 | |
1127 const FilePath& temporary_file_path = param->temporary_file_path; | 1149 const FilePath& temporary_file_path = param->temporary_file_path; |
1128 std::string resource_id = param->remote_change.resource_id; | 1150 std::string resource_id = param->remote_change.resource_id; |
1151 const DriveMetadata& drive_metadata = param->drive_metadata; | |
1129 sync_client_->DownloadFile( | 1152 sync_client_->DownloadFile( |
1130 resource_id, metadata.md5_checksum(), | 1153 resource_id, drive_metadata.md5_checksum(), |
1131 temporary_file_path, | 1154 temporary_file_path, |
1132 base::Bind(&DriveFileSyncService::DidDownloadFile, | 1155 base::Bind(&DriveFileSyncService::DidDownloadFile, |
1133 AsWeakPtr(), base::Passed(¶m))); | 1156 AsWeakPtr(), base::Passed(¶m))); |
1134 } | 1157 } |
1135 | 1158 |
1136 void DriveFileSyncService::DidDownloadFile( | 1159 void DriveFileSyncService::DidDownloadFile( |
1137 scoped_ptr<ProcessRemoteChangeParam> param, | 1160 scoped_ptr<ProcessRemoteChangeParam> param, |
1138 google_apis::GDataErrorCode error, | 1161 google_apis::GDataErrorCode error, |
1139 const std::string& md5_checksum) { | 1162 const std::string& md5_checksum) { |
1140 if (error == google_apis::HTTP_NOT_MODIFIED) { | 1163 if (error == google_apis::HTTP_NOT_MODIFIED) { |
1141 param->operation_type = fileapi::SYNC_OPERATION_NONE; | 1164 param->operation_type = fileapi::SYNC_OPERATION_NONE; |
1142 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); | 1165 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); |
1143 return; | 1166 return; |
1144 } | 1167 } |
1145 | 1168 |
1146 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); | 1169 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); |
1147 if (status != fileapi::SYNC_STATUS_OK) { | 1170 if (status != fileapi::SYNC_STATUS_OK) { |
1148 AbortRemoteSync(param.Pass(), status); | 1171 AbortRemoteSync(param.Pass(), status); |
1149 return; | 1172 return; |
1150 } | 1173 } |
1151 | 1174 |
1152 param->md5_checksum = md5_checksum; | 1175 param->drive_metadata.set_md5_checksum(md5_checksum); |
1153 const fileapi::FileChange& change = param->remote_change.change; | 1176 const fileapi::FileChange& change = param->remote_change.change; |
1154 const FilePath& temporary_file_path = param->temporary_file_path; | 1177 const FilePath& temporary_file_path = param->temporary_file_path; |
1155 const fileapi::FileSystemURL& url = param->remote_change.url; | 1178 const fileapi::FileSystemURL& url = param->remote_change.url; |
1156 param->processor->ApplyRemoteChange( | 1179 param->processor->ApplyRemoteChange( |
1157 change, temporary_file_path, url, | 1180 change, temporary_file_path, url, |
1158 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, | 1181 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, |
1159 AsWeakPtr(), base::Passed(¶m))); | 1182 AsWeakPtr(), base::Passed(¶m))); |
1160 } | 1183 } |
1161 | 1184 |
1162 void DriveFileSyncService::DidApplyRemoteChange( | 1185 void DriveFileSyncService::DidApplyRemoteChange( |
1163 scoped_ptr<ProcessRemoteChangeParam> param, | 1186 scoped_ptr<ProcessRemoteChangeParam> param, |
1164 fileapi::SyncStatusCode status) { | 1187 fileapi::SyncStatusCode status) { |
1165 if (status != fileapi::SYNC_STATUS_OK) { | 1188 if (status != fileapi::SYNC_STATUS_OK) { |
1166 AbortRemoteSync(param.Pass(), status); | 1189 AbortRemoteSync(param.Pass(), status); |
1167 return; | 1190 return; |
1168 } | 1191 } |
1169 | 1192 |
1170 fileapi::FileSystemURL url = param->remote_change.url; | 1193 fileapi::FileSystemURL url = param->remote_change.url; |
1171 if (param->remote_change.change.IsDelete()) { | 1194 if (param->remote_change.change.IsDelete()) { |
1172 DeleteMetadataForRemoteSync(param.Pass()); | 1195 DeleteMetadataForRemoteSync(param.Pass()); |
1173 return; | 1196 return; |
1174 } | 1197 } |
1175 | 1198 |
1176 DriveMetadata metadata; | 1199 const DriveMetadata& drive_metadata = param->drive_metadata; |
1177 metadata.set_resource_id(param->remote_change.resource_id); | 1200 param->drive_metadata.set_resource_id(param->remote_change.resource_id); |
1178 metadata.set_md5_checksum(param->md5_checksum); | 1201 param->drive_metadata.set_conflicted(false); |
1179 metadata.set_conflicted(false); | |
1180 | 1202 |
1181 metadata_store_->UpdateEntry( | 1203 metadata_store_->UpdateEntry( |
1182 url, metadata, | 1204 url, drive_metadata, |
1183 base::Bind(&DriveFileSyncService::CompleteRemoteSync, | 1205 base::Bind(&DriveFileSyncService::CompleteRemoteSync, |
1184 AsWeakPtr(), base::Passed(¶m))); | 1206 AsWeakPtr(), base::Passed(¶m))); |
1185 } | 1207 } |
1186 | 1208 |
1187 void DriveFileSyncService::DeleteMetadataForRemoteSync( | 1209 void DriveFileSyncService::DeleteMetadataForRemoteSync( |
1188 scoped_ptr<ProcessRemoteChangeParam> param) { | 1210 scoped_ptr<ProcessRemoteChangeParam> param) { |
1189 fileapi::FileSystemURL url = param->remote_change.url; | 1211 fileapi::FileSystemURL url = param->remote_change.url; |
1190 metadata_store_->DeleteEntry( | 1212 metadata_store_->DeleteEntry( |
1191 url, | 1213 url, |
1192 base::Bind(&DriveFileSyncService::CompleteRemoteSync, | 1214 base::Bind(&DriveFileSyncService::CompleteRemoteSync, |
1193 AsWeakPtr(), base::Passed(¶m))); | 1215 AsWeakPtr(), base::Passed(¶m))); |
1194 } | 1216 } |
1195 | 1217 |
1196 void DriveFileSyncService::CompleteRemoteSync( | 1218 void DriveFileSyncService::CompleteRemoteSync( |
1197 scoped_ptr<ProcessRemoteChangeParam> param, | 1219 scoped_ptr<ProcessRemoteChangeParam> param, |
1198 fileapi::SyncStatusCode status) { | 1220 fileapi::SyncStatusCode status) { |
1199 if (status != fileapi::SYNC_STATUS_OK) { | 1221 if (status != fileapi::SYNC_STATUS_OK) { |
1200 AbortRemoteSync(param.Pass(), status); | 1222 AbortRemoteSync(param.Pass(), status); |
1201 return; | 1223 return; |
1202 } | 1224 } |
1203 | 1225 |
1204 CancelRemoteChange(param->remote_change.url); | 1226 CancelRemoteChange(param->remote_change.url); |
1205 | 1227 |
1206 GURL origin = param->remote_change.url.origin(); | 1228 GURL origin = param->remote_change.url.origin(); |
1207 if (metadata_store_->IsIncrementalSyncOrigin(origin)) { | 1229 if (metadata_store_->IsIncrementalSyncOrigin(origin)) { |
1208 int64 changestamp = param->remote_change.changestamp; | 1230 int64 changestamp = param->remote_change.changestamp; |
1231 largest_synced_changestamp_ = changestamp; | |
1232 DCHECK_GE(largest_fetched_changestamp_, largest_synced_changestamp_); | |
1233 | |
1209 metadata_store_->SetLargestChangeStamp( | 1234 metadata_store_->SetLargestChangeStamp( |
1210 changestamp, | 1235 changestamp, |
1211 base::Bind(&DriveFileSyncService::FinalizeRemoteSync, | 1236 base::Bind(&DriveFileSyncService::FinalizeRemoteSync, |
1212 AsWeakPtr(), base::Passed(¶m))); | 1237 AsWeakPtr(), base::Passed(¶m))); |
1213 return; | 1238 return; |
1214 } | 1239 } |
1215 | 1240 |
1216 if (param->drive_metadata.conflicted()) | 1241 if (param->drive_metadata.conflicted()) |
1217 status = fileapi::SYNC_STATUS_HAS_CONFLICT; | 1242 status = fileapi::SYNC_STATUS_HAS_CONFLICT; |
1218 FinalizeRemoteSync(param.Pass(), status); | 1243 FinalizeRemoteSync(param.Pass(), status); |
(...skipping 16 matching lines...) Expand all Loading... | |
1235 param->callback.Run(status, param->remote_change.url, | 1260 param->callback.Run(status, param->remote_change.url, |
1236 param->operation_type); | 1261 param->operation_type); |
1237 } else { | 1262 } else { |
1238 param->callback.Run(status, param->remote_change.url, | 1263 param->callback.Run(status, param->remote_change.url, |
1239 fileapi::SYNC_OPERATION_NONE); | 1264 fileapi::SYNC_OPERATION_NONE); |
1240 } | 1265 } |
1241 } | 1266 } |
1242 | 1267 |
1243 void DriveFileSyncService::AppendNewRemoteChange( | 1268 void DriveFileSyncService::AppendNewRemoteChange( |
1244 const GURL& origin, | 1269 const GURL& origin, |
1245 google_apis::DocumentEntry* entry, | 1270 const google_apis::DocumentEntry& entry, |
1246 int64 changestamp, | 1271 int64 changestamp, |
1247 RemoteSyncType sync_type) { | 1272 RemoteSyncType sync_type) { |
1248 // TODO(tzik): Normalize the path here. | 1273 // TODO(tzik): Normalize the path here. |
1249 FilePath path = FilePath::FromUTF8Unsafe(UTF16ToUTF8(entry->title())); | 1274 FilePath path = FilePath::FromUTF8Unsafe(UTF16ToUTF8(entry.title())); |
1250 | 1275 |
1251 PathToChange* path_to_change = &url_to_change_[origin]; | 1276 PathToChange* path_to_change = &url_to_change_[origin]; |
1252 PathToChange::iterator found = path_to_change->find(path); | 1277 PathToChange::iterator found = path_to_change->find(path); |
1253 if (found != path_to_change->end()) { | 1278 if (found != path_to_change->end()) { |
1254 if (found->second.changestamp >= changestamp) | 1279 if (found->second.changestamp >= changestamp) |
1255 return; | 1280 return; |
1256 pending_changes_.erase(found->second.position_in_queue); | 1281 pending_changes_.erase(found->second.position_in_queue); |
1257 } | 1282 } |
1258 | 1283 |
1259 fileapi::FileSystemURL url( | 1284 fileapi::FileSystemURL url( |
1260 fileapi::CreateSyncableFileSystemURL(origin, kServiceName, path)); | 1285 fileapi::CreateSyncableFileSystemURL(origin, kServiceName, path)); |
1261 | 1286 |
1262 fileapi::FileChange::ChangeType change_type; | 1287 fileapi::FileChange::ChangeType change_type; |
1263 fileapi::SyncFileType file_type; | 1288 fileapi::SyncFileType file_type; |
1264 if (entry->deleted()) { | 1289 if (entry.deleted()) { |
1265 change_type = fileapi::FileChange::FILE_CHANGE_DELETE; | 1290 change_type = fileapi::FileChange::FILE_CHANGE_DELETE; |
1266 file_type = fileapi::SYNC_FILE_TYPE_UNKNOWN; | 1291 file_type = fileapi::SYNC_FILE_TYPE_UNKNOWN; |
1267 } else { | 1292 } else { |
1268 change_type = fileapi::FileChange::FILE_CHANGE_ADD_OR_UPDATE; | 1293 change_type = fileapi::FileChange::FILE_CHANGE_ADD_OR_UPDATE; |
1269 if (entry->kind() == google_apis::ENTRY_KIND_FOLDER) | 1294 if (entry.kind() == google_apis::ENTRY_KIND_FOLDER) |
nhiroki
2012/11/30 06:23:53
You may want to use "entry.is_folder()".
tzik
2012/12/03 10:00:08
Done.
| |
1270 file_type = fileapi::SYNC_FILE_TYPE_DIRECTORY; | 1295 file_type = fileapi::SYNC_FILE_TYPE_DIRECTORY; |
1271 else | 1296 else |
1272 file_type = fileapi::SYNC_FILE_TYPE_FILE; | 1297 file_type = fileapi::SYNC_FILE_TYPE_FILE; |
1273 } | 1298 } |
1274 | 1299 |
1275 fileapi::FileChange file_change(change_type, file_type); | 1300 fileapi::FileChange file_change(change_type, file_type); |
1276 | 1301 |
1277 std::pair<PendingChangeQueue::iterator, bool> inserted_to_queue = | 1302 std::pair<PendingChangeQueue::iterator, bool> inserted_to_queue = |
1278 pending_changes_.insert(ChangeQueueItem(changestamp, sync_type, url)); | 1303 pending_changes_.insert(ChangeQueueItem(changestamp, sync_type, url)); |
1279 DCHECK(inserted_to_queue.second); | 1304 DCHECK(inserted_to_queue.second); |
1280 | 1305 |
1281 (*path_to_change)[path] = RemoteChange( | 1306 (*path_to_change)[path] = RemoteChange( |
1282 changestamp, entry->resource_id(), url, file_change, | 1307 changestamp, entry.resource_id(), url, file_change, |
1283 inserted_to_queue.first); | 1308 inserted_to_queue.first); |
1284 } | 1309 } |
1285 | 1310 |
1286 void DriveFileSyncService::CancelRemoteChange( | 1311 void DriveFileSyncService::CancelRemoteChange( |
kinuko
2012/11/29 11:40:46
Well I think we definitely need to change this met
tzik
2012/12/03 10:00:08
Done.
| |
1287 const fileapi::FileSystemURL& url) { | 1312 const fileapi::FileSystemURL& url) { |
1288 URLToChange::iterator found_origin = url_to_change_.find(url.origin()); | 1313 URLToChange::iterator found_origin = url_to_change_.find(url.origin()); |
1289 if (found_origin == url_to_change_.end()) | 1314 if (found_origin == url_to_change_.end()) |
1290 return; | 1315 return; |
1291 | 1316 |
1292 PathToChange* path_to_change = &found_origin->second; | 1317 PathToChange* path_to_change = &found_origin->second; |
1293 PathToChange::iterator found_change = path_to_change->find(url.path()); | 1318 PathToChange::iterator found_change = path_to_change->find(url.path()); |
1294 if (found_change == path_to_change->end()) | 1319 if (found_change == path_to_change->end()) |
1295 return; | 1320 return; |
1296 | 1321 |
1322 int64 changestamp = found_change->second.changestamp; | |
1297 pending_changes_.erase(found_change->second.position_in_queue); | 1323 pending_changes_.erase(found_change->second.position_in_queue); |
1298 path_to_change->erase(found_change); | 1324 path_to_change->erase(found_change); |
1299 if (path_to_change->empty()) | 1325 if (path_to_change->empty()) |
1300 url_to_change_.erase(found_origin); | 1326 url_to_change_.erase(found_origin); |
1301 | 1327 |
1302 MaybeMarkAsIncrementalSyncOrigin(url.origin()); | 1328 if (metadata_store_->IsBatchSyncOrigin(url.origin()) && |
1303 } | 1329 !ContainsKey(url_to_change_, url.origin())) { |
1304 | 1330 if (metadata_store_->incremental_sync_origins().empty()) { |
1305 void DriveFileSyncService::MaybeMarkAsIncrementalSyncOrigin( | 1331 largest_synced_changestamp_ = changestamp; |
1306 const GURL& origin) { | 1332 largest_fetched_changestamp_ = changestamp; |
1307 if (metadata_store_->IsBatchSyncOrigin(origin) && | 1333 metadata_store_->SetLargestChangeStamp(changestamp, |
1308 !ContainsKey(url_to_change_, origin)) | 1334 base::Bind(&EmptyStatusCallback)); |
kinuko
2012/11/29 11:40:46
Let's change this part per discussion!
tzik
2012/12/03 10:00:08
Done.
| |
1309 metadata_store_->MoveBatchSyncOriginToIncremental(origin); | 1335 } |
1336 metadata_store_->MoveBatchSyncOriginToIncremental(url.origin()); | |
1337 } | |
1310 } | 1338 } |
1311 | 1339 |
1312 bool DriveFileSyncService::GetPendingChangeForFileSystemURL( | 1340 bool DriveFileSyncService::GetPendingChangeForFileSystemURL( |
1313 const fileapi::FileSystemURL& url, | 1341 const fileapi::FileSystemURL& url, |
1314 RemoteChange* change) const { | 1342 RemoteChange* change) const { |
1315 DCHECK(change); | 1343 DCHECK(change); |
1316 URLToChange::const_iterator found_url = url_to_change_.find(url.origin()); | 1344 URLToChange::const_iterator found_url = url_to_change_.find(url.origin()); |
1317 if (found_url == url_to_change_.end()) | 1345 if (found_url == url_to_change_.end()) |
1318 return false; | 1346 return false; |
1319 const PathToChange& path_to_change = found_url->second; | 1347 const PathToChange& path_to_change = found_url->second; |
1320 PathToChange::const_iterator found_path = path_to_change.find(url.path()); | 1348 PathToChange::const_iterator found_path = path_to_change.find(url.path()); |
1321 if (found_path == path_to_change.end()) | 1349 if (found_path == path_to_change.end()) |
1322 return false; | 1350 return false; |
1323 *change = found_path->second; | 1351 *change = found_path->second; |
1324 return true; | 1352 return true; |
1325 } | 1353 } |
1326 | 1354 |
1355 void DriveFileSyncService::FetchChangesForIncrementalSync() { | |
1356 scoped_ptr<TaskToken> token(GetToken(FROM_HERE, TASK_TYPE_DRIVE, | |
1357 "Fetching remote change list")); | |
1358 if (!token) { | |
1359 pending_tasks_.push_back(base::Bind( | |
1360 &DriveFileSyncService::FetchChangesForIncrementalSync, AsWeakPtr())); | |
1361 return; | |
1362 } | |
1363 | |
1364 if (metadata_store_->incremental_sync_origins().empty()) { | |
1365 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass()); | |
1366 return; | |
1367 } | |
1368 | |
1369 sync_client_->ListChanges( | |
1370 largest_fetched_changestamp_, | |
1371 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync, | |
1372 AsWeakPtr(), base::Passed(&token))); | |
1373 } | |
1374 | |
1375 void DriveFileSyncService::DidFetchChangesForIncrementalSync( | |
1376 scoped_ptr<TaskToken> token, | |
1377 google_apis::GDataErrorCode error, | |
1378 scoped_ptr<google_apis::DocumentFeed> changes) { | |
1379 GURL next_feed; | |
1380 | |
1381 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator; | |
1382 for (iterator itr = changes->entries().begin(); | |
1383 itr != changes->entries().end(); ++itr) { | |
1384 const google_apis::DocumentEntry& entry = **itr; | |
1385 GURL origin; | |
1386 if (!GetOriginForEntry(entry, &origin)) | |
1387 continue; | |
1388 | |
1389 AppendNewRemoteChange(origin, entry, entry.changestamp(), | |
1390 REMOTE_SYNC_TYPE_INCREMENTAL); | |
1391 } | |
1392 | |
1393 if (changes->GetNextFeedURL(&next_feed)) { | |
1394 sync_client_->ContinueListing( | |
1395 next_feed, | |
1396 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync, | |
1397 AsWeakPtr(), base::Passed(&token))); | |
1398 } else { | |
1399 largest_fetched_changestamp_ = changes->largest_changestamp(); | |
1400 | |
1401 if (changes->start_index() == 0 && changes->entries().empty()) { | |
kinuko
2012/11/29 11:47:43
nit: can you add a comment: 'If this set of change
tzik
2012/12/03 10:00:08
Done.
| |
1402 base::TimeDelta max_delay( | |
1403 base::TimeDelta::FromSeconds(kMaximumPollingDelaySeconds)); | |
1404 | |
1405 polling_delay_ *= kDelayMultiplier; | |
1406 if (polling_delay_ >= max_delay) | |
1407 polling_delay_ = max_delay; | |
1408 } else { | |
1409 polling_delay_ = base::TimeDelta::FromSeconds( | |
1410 kMinimumPollingDelaySeconds); | |
1411 } | |
1412 | |
1413 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass()); | |
1414 } | |
1415 } | |
1416 | |
1417 bool DriveFileSyncService::GetOriginForEntry( | |
1418 const google_apis::DocumentEntry& entry, | |
1419 GURL* origin_out) { | |
1420 typedef ScopedVector<google_apis::Link>::const_iterator iterator; | |
1421 for (iterator itr = entry.links().begin(); | |
1422 itr != entry.links().end(); ++itr) { | |
1423 if ((*itr)->type() != google_apis::Link::LINK_PARENT) | |
1424 continue; | |
1425 GURL origin(UTF16ToUTF8((*itr)->title())); | |
1426 if (!origin.is_valid()) | |
1427 continue; | |
1428 | |
1429 if (!metadata_store_->IsBatchSyncOrigin(origin) && | |
1430 !metadata_store_->IsIncrementalSyncOrigin(origin)) | |
1431 continue; | |
1432 std::string resource_id(metadata_store_->GetResourceIdForOrigin(origin)); | |
1433 if ((*itr)->href() != ResourceIdToResourceLink(resource_id)) | |
1434 continue; | |
1435 | |
1436 *origin_out = origin; | |
1437 return true; | |
1438 } | |
1439 return false; | |
1440 } | |
1441 | |
1442 void DriveFileSyncService::SchedulePolling() { | |
1443 if (!polling_timer_.IsRunning()) | |
1444 polling_timer_.Start( | |
1445 FROM_HERE, polling_delay_, | |
1446 base::Bind(&DriveFileSyncService::FetchChangesForIncrementalSync, | |
1447 AsWeakPtr())); | |
1448 } | |
1449 | |
1327 } // namespace sync_file_system | 1450 } // namespace sync_file_system |
OLD | NEW |