Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: chrome/browser/sync_file_system/drive_file_sync_service.cc

Issue 11421125: Implement polling part of DriveFileSyncService (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix for optional changestamp field Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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 &param->drive_metadata); 1020 &param->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
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(&param))); 1112 base::Passed(&param)));
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
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(&param))); 1156 AsWeakPtr(), base::Passed(&param)));
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(&param))); 1182 AsWeakPtr(), base::Passed(&param)));
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(&param))); 1206 AsWeakPtr(), base::Passed(&param)));
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(&param))); 1215 AsWeakPtr(), base::Passed(&param)));
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(&param))); 1237 AsWeakPtr(), base::Passed(&param)));
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698