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" |
11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
14 #include "base/message_loop_proxy.h" | 14 #include "base/message_loop_proxy.h" |
15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
16 #include "base/values.h" | 16 #include "base/values.h" |
17 #include "chrome/browser/google_apis/gdata_wapi_service.h" | 17 #include "chrome/browser/google_apis/gdata_wapi_service.h" |
18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/sync_file_system/drive_file_sync_client.h" | 19 #include "chrome/browser/sync_file_system/drive_file_sync_client.h" |
20 #include "chrome/browser/sync_file_system/drive_file_sync_util.h" | 20 #include "chrome/browser/sync_file_system/drive_file_sync_util.h" |
21 #include "chrome/browser/sync_file_system/drive_metadata_store.h" | 21 #include "chrome/browser/sync_file_system/drive_metadata_store.h" |
22 #include "chrome/browser/sync_file_system/remote_change_processor.h" | 22 #include "chrome/browser/sync_file_system/remote_change_processor.h" |
23 #include "chrome/browser/sync_file_system/sync_file_system.pb.h" | 23 #include "chrome/browser/sync_file_system/sync_file_system.pb.h" |
24 #include "chrome/common/extensions/extension.h" | |
24 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
25 #include "net/base/escape.h" | 26 #include "extensions/common/constants.h" |
26 #include "webkit/fileapi/file_system_url.h" | 27 #include "webkit/fileapi/file_system_url.h" |
27 #include "webkit/fileapi/syncable/sync_file_metadata.h" | 28 #include "webkit/fileapi/syncable/sync_file_metadata.h" |
28 #include "webkit/fileapi/syncable/sync_file_type.h" | 29 #include "webkit/fileapi/syncable/sync_file_type.h" |
29 #include "webkit/fileapi/syncable/syncable_file_system_util.h" | 30 #include "webkit/fileapi/syncable/syncable_file_system_util.h" |
30 | 31 |
31 namespace sync_file_system { | 32 namespace sync_file_system { |
32 | 33 |
33 namespace { | 34 namespace { |
34 | 35 |
35 const FilePath::CharType kTempDirName[] = FILE_PATH_LITERAL("tmp"); | 36 const FilePath::CharType kTempDirName[] = FILE_PATH_LITERAL("tmp"); |
36 const FilePath::CharType kSyncFileSystemDir[] = | 37 const FilePath::CharType kSyncFileSystemDir[] = |
37 FILE_PATH_LITERAL("Sync FileSystem"); | 38 FILE_PATH_LITERAL("Sync FileSystem"); |
39 const int64 kMinimumPollingDelaySeconds = 10; | |
40 const int64 kMaximumPollingDelaySeconds = 60 * 60; // 1 hour | |
41 const double kDelayMultiplier = 2; | |
38 | 42 |
39 bool CreateTemporaryFile(const FilePath& dir_path, FilePath* temp_file) { | 43 bool CreateTemporaryFile(const FilePath& dir_path, FilePath* temp_file) { |
40 return file_util::CreateDirectory(dir_path) && | 44 return file_util::CreateDirectory(dir_path) && |
41 file_util::CreateTemporaryFileInDir(dir_path, temp_file); | 45 file_util::CreateTemporaryFileInDir(dir_path, temp_file); |
42 } | 46 } |
43 | 47 |
44 void DeleteTemporaryFile(const FilePath& file_path) { | 48 void DeleteTemporaryFile(const FilePath& file_path) { |
45 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) { | 49 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) { |
46 content::BrowserThread::PostTask( | 50 content::BrowserThread::PostTask( |
47 content::BrowserThread::FILE, FROM_HERE, | 51 content::BrowserThread::FILE, FROM_HERE, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 TaskType task_type() const { return task_type_; } | 96 TaskType task_type() const { return task_type_; } |
93 const std::string& description() const { return description_; } | 97 const std::string& description() const { return description_; } |
94 std::string done_description() const { return description_ + " done"; } | 98 std::string done_description() const { return description_ + " done"; } |
95 | 99 |
96 ~TaskToken() { | 100 ~TaskToken() { |
97 // All task on DriveFileSyncService must hold TaskToken instance to ensure | 101 // All task on DriveFileSyncService must hold TaskToken instance to ensure |
98 // no other tasks are running. Also, as soon as a task finishes to work, | 102 // no other tasks are running. Also, as soon as a task finishes to work, |
99 // it must return the token to DriveFileSyncService. | 103 // it must return the token to DriveFileSyncService. |
100 // Destroying a token with valid |sync_service_| indicates the token was | 104 // Destroying a token with valid |sync_service_| indicates the token was |
101 // dropped by a task without returning. | 105 // dropped by a task without returning. |
102 DCHECK(!sync_service_); | |
103 if (sync_service_) { | 106 if (sync_service_) { |
104 LOG(ERROR) << "Unexpected TaskToken deletion from: " | 107 LOG(ERROR) << "Unexpected TaskToken deletion from: " |
105 << location_.ToString() << " while: " << description_; | 108 << location_.ToString() << " while: " << description_; |
106 } | 109 } |
110 DCHECK(!sync_service_); | |
107 } | 111 } |
108 | 112 |
109 private: | 113 private: |
110 base::WeakPtr<DriveFileSyncService> sync_service_; | 114 base::WeakPtr<DriveFileSyncService> sync_service_; |
111 tracked_objects::Location location_; | 115 tracked_objects::Location location_; |
112 TaskType task_type_; | 116 TaskType task_type_; |
113 std::string description_; | 117 std::string description_; |
114 | 118 |
115 DISALLOW_COPY_AND_ASSIGN(TaskToken); | 119 DISALLOW_COPY_AND_ASSIGN(TaskToken); |
116 }; | 120 }; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 // Smaller changestamps have higher priorities (i.e. need to be processed | 199 // Smaller changestamps have higher priorities (i.e. need to be processed |
196 // earlier). | 200 // earlier). |
197 if (left.changestamp != right.changestamp) | 201 if (left.changestamp != right.changestamp) |
198 return left.changestamp > right.changestamp; | 202 return left.changestamp > right.changestamp; |
199 return false; | 203 return false; |
200 } | 204 } |
201 | 205 |
202 DriveFileSyncService::DriveFileSyncService(Profile* profile) | 206 DriveFileSyncService::DriveFileSyncService(Profile* profile) |
203 : last_operation_status_(fileapi::SYNC_STATUS_OK), | 207 : last_operation_status_(fileapi::SYNC_STATUS_OK), |
204 state_(REMOTE_SERVICE_OK), | 208 state_(REMOTE_SERVICE_OK), |
205 largest_changestamp_(0), | 209 largest_fetched_changestamp_(0), |
210 polling_delay_(base::TimeDelta::FromSeconds(kMinimumPollingDelaySeconds)), | |
211 polling_enabled_(true), | |
206 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 212 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
207 temporary_file_dir_ = | 213 temporary_file_dir_ = |
208 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); | 214 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); |
209 token_.reset(new TaskToken(AsWeakPtr())); | 215 token_.reset(new TaskToken(AsWeakPtr())); |
210 | 216 |
211 sync_client_.reset(new DriveFileSyncClient(profile)); | 217 sync_client_.reset(new DriveFileSyncClient(profile)); |
212 | 218 |
213 metadata_store_.reset(new DriveMetadataStore( | 219 metadata_store_.reset(new DriveMetadataStore( |
214 profile->GetPath().Append(kSyncFileSystemDir), | 220 profile->GetPath().Append(kSyncFileSystemDir), |
215 content::BrowserThread::GetMessageLoopProxyForThread( | 221 content::BrowserThread::GetMessageLoopProxyForThread( |
(...skipping 25 matching lines...) Expand all Loading... | |
241 observers_.AddObserver(observer); | 247 observers_.AddObserver(observer); |
242 } | 248 } |
243 | 249 |
244 void DriveFileSyncService::RemoveObserver(Observer* observer) { | 250 void DriveFileSyncService::RemoveObserver(Observer* observer) { |
245 observers_.RemoveObserver(observer); | 251 observers_.RemoveObserver(observer); |
246 } | 252 } |
247 | 253 |
248 void DriveFileSyncService::RegisterOriginForTrackingChanges( | 254 void DriveFileSyncService::RegisterOriginForTrackingChanges( |
249 const GURL& origin, | 255 const GURL& origin, |
250 const fileapi::SyncStatusCallback& callback) { | 256 const fileapi::SyncStatusCallback& callback) { |
257 DCHECK(origin.SchemeIs(extensions::kExtensionScheme)); | |
251 scoped_ptr<TaskToken> token(GetToken( | 258 scoped_ptr<TaskToken> token(GetToken( |
252 FROM_HERE, TASK_TYPE_DRIVE, "Retrieving origin metadata")); | 259 FROM_HERE, TASK_TYPE_DRIVE, "Retrieving origin metadata")); |
253 if (!token) { | 260 if (!token) { |
254 pending_tasks_.push_back(base::Bind( | 261 pending_tasks_.push_back(base::Bind( |
255 &DriveFileSyncService::RegisterOriginForTrackingChanges, | 262 &DriveFileSyncService::RegisterOriginForTrackingChanges, |
256 AsWeakPtr(), origin, callback)); | 263 AsWeakPtr(), origin, callback)); |
257 return; | 264 return; |
258 } | 265 } |
259 | 266 |
260 if (state_ == REMOTE_SERVICE_DISABLED) { | 267 if (state_ == REMOTE_SERVICE_DISABLED) { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 | 423 |
417 DVLOG(1) << "ApplyLocalChange for " << url.DebugString() | 424 DVLOG(1) << "ApplyLocalChange for " << url.DebugString() |
418 << " local_change:" << local_file_change.DebugString() | 425 << " local_change:" << local_file_change.DebugString() |
419 << " ==> operation:" << operation; | 426 << " ==> operation:" << operation; |
420 | 427 |
421 switch (operation) { | 428 switch (operation) { |
422 case SYNC_OPERATION_UPLOAD_NEW_FILE: { | 429 case SYNC_OPERATION_UPLOAD_NEW_FILE: { |
423 sync_client_->UploadNewFile( | 430 sync_client_->UploadNewFile( |
424 metadata_store_->GetResourceIdForOrigin(url.origin()), | 431 metadata_store_->GetResourceIdForOrigin(url.origin()), |
425 local_file_path, | 432 local_file_path, |
426 net::EscapePath(url.path().AsUTF8Unsafe()), | 433 url.path().AsUTF8Unsafe(), |
427 local_file_metadata.size, | 434 local_file_metadata.size, |
428 base::Bind(&DriveFileSyncService::DidUploadNewFile, | 435 base::Bind(&DriveFileSyncService::DidUploadNewFile, |
429 AsWeakPtr(), base::Passed(&token), url, callback)); | 436 AsWeakPtr(), base::Passed(&token), url, callback)); |
430 return; | 437 return; |
431 } | 438 } |
432 case SYNC_OPERATION_UPLOAD_EXISTING_FILE: { | 439 case SYNC_OPERATION_UPLOAD_EXISTING_FILE: { |
433 DriveMetadata metadata; | 440 DriveMetadata metadata; |
434 const fileapi::SyncStatusCode status = | 441 const fileapi::SyncStatusCode status = |
435 metadata_store_->ReadEntry(url, &metadata); | 442 metadata_store_->ReadEntry(url, &metadata); |
436 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status); | 443 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 callback, fileapi::SYNC_STATUS_FAILED); | 503 callback, fileapi::SYNC_STATUS_FAILED); |
497 } | 504 } |
498 | 505 |
499 // Called by CreateForTesting. | 506 // Called by CreateForTesting. |
500 DriveFileSyncService::DriveFileSyncService( | 507 DriveFileSyncService::DriveFileSyncService( |
501 const FilePath& base_dir, | 508 const FilePath& base_dir, |
502 scoped_ptr<DriveFileSyncClient> sync_client, | 509 scoped_ptr<DriveFileSyncClient> sync_client, |
503 scoped_ptr<DriveMetadataStore> metadata_store) | 510 scoped_ptr<DriveMetadataStore> metadata_store) |
504 : last_operation_status_(fileapi::SYNC_STATUS_OK), | 511 : last_operation_status_(fileapi::SYNC_STATUS_OK), |
505 state_(REMOTE_SERVICE_OK), | 512 state_(REMOTE_SERVICE_OK), |
506 largest_changestamp_(0), | 513 largest_fetched_changestamp_(0), |
514 polling_enabled_(false), | |
507 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 515 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
508 temporary_file_dir_ = base_dir.Append(kTempDirName); | 516 temporary_file_dir_ = base_dir.Append(kTempDirName); |
509 | 517 |
510 token_.reset(new TaskToken(AsWeakPtr())); | 518 token_.reset(new TaskToken(AsWeakPtr())); |
511 sync_client_ = sync_client.Pass(); | 519 sync_client_ = sync_client.Pass(); |
512 metadata_store_ = metadata_store.Pass(); | 520 metadata_store_ = metadata_store.Pass(); |
513 | 521 |
514 DidInitializeMetadataStore( | 522 DidInitializeMetadataStore( |
515 GetToken(FROM_HERE, TASK_TYPE_NONE, "Drive initialization for testing"), | 523 GetToken(FROM_HERE, TASK_TYPE_NONE, "Drive initialization for testing"), |
516 fileapi::SYNC_STATUS_OK, false); | 524 fileapi::SYNC_STATUS_OK, false); |
517 } | 525 } |
518 | 526 |
519 scoped_ptr<DriveFileSyncService::TaskToken> DriveFileSyncService::GetToken( | 527 scoped_ptr<DriveFileSyncService::TaskToken> DriveFileSyncService::GetToken( |
520 const tracked_objects::Location& from_here, | 528 const tracked_objects::Location& from_here, |
521 TaskType task_type, | 529 TaskType task_type, |
522 const std::string& description) { | 530 const std::string& description) { |
523 if (!token_) | 531 if (!token_) |
524 return scoped_ptr<TaskToken>(); | 532 return scoped_ptr<TaskToken>(); |
525 token_->UpdateTask(from_here, task_type, description); | 533 token_->UpdateTask(from_here, task_type, description); |
526 return token_.Pass(); | 534 return token_.Pass(); |
527 } | 535 } |
528 | 536 |
529 void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status, | 537 void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status, |
530 scoped_ptr<TaskToken> token) { | 538 scoped_ptr<TaskToken> token) { |
531 DCHECK(token); | 539 DCHECK(token); |
532 last_operation_status_ = status; | 540 last_operation_status_ = status; |
533 token_ = token.Pass(); | 541 token_ = token.Pass(); |
534 | 542 |
535 RemoteServiceState old_state = state_; | |
536 if (token_->task_type() != TASK_TYPE_NONE) { | 543 if (token_->task_type() != TASK_TYPE_NONE) { |
537 DVLOG(1) << "NotifyTaskDone: " << token_->description() | 544 DVLOG(1) << "NotifyTaskDone: " << token_->description() |
538 << ": finished with status=" << status | 545 << ": finished with status=" << status |
539 << " " << token_->location().ToString(); | 546 << " " << token_->location().ToString(); |
540 | 547 |
541 RemoteServiceState old_state = state_; | 548 RemoteServiceState old_state = state_; |
542 UpdateServiceState(); | 549 UpdateServiceState(); |
543 | 550 |
544 // Notify remote sync service state if the state has been changed. | 551 // Notify remote sync service state if the state has been changed. |
545 if (!token_->description().empty() || old_state != state_) { | 552 if (!token_->description().empty() || old_state != state_) { |
546 FOR_EACH_OBSERVER( | 553 FOR_EACH_OBSERVER( |
547 Observer, observers_, | 554 Observer, observers_, |
548 OnRemoteServiceStateUpdated(state_, token_->done_description())); | 555 OnRemoteServiceStateUpdated(state_, token_->done_description())); |
549 } | 556 } |
550 } | 557 } |
551 | 558 |
552 token_->ResetTask(FROM_HERE); | 559 token_->ResetTask(FROM_HERE); |
553 if (!pending_tasks_.empty()) { | 560 if (!pending_tasks_.empty()) { |
554 base::Closure closure = pending_tasks_.front(); | 561 base::Closure closure = pending_tasks_.front(); |
555 pending_tasks_.pop_front(); | 562 pending_tasks_.pop_front(); |
556 closure.Run(); | 563 closure.Run(); |
557 return; | 564 return; |
558 } | 565 } |
559 | 566 |
560 if (state_ != REMOTE_SERVICE_OK || old_state == state_) | 567 if (state_ != REMOTE_SERVICE_OK) { |
568 if (state_ == REMOTE_SERVICE_TEMPORARY_UNAVAILABLE) { | |
kinuko
2012/12/04 05:18:30
Should we also check the same conditions as line 5
tzik
2012/12/04 06:32:32
Done.
| |
569 polling_delay_ = | |
570 base::TimeDelta::FromSeconds(kMaximumPollingDelaySeconds); | |
571 SchedulePolling(); | |
572 } | |
561 return; | 573 return; |
574 } | |
562 | 575 |
563 // If the state has become OK and we have any pending batch sync origins | 576 // If the state has become OK and we have any pending batch sync origins |
564 // restart batch sync for them. | 577 // restart batch sync for them. |
565 if (!pending_batch_sync_origins_.empty()) { | 578 if (!pending_batch_sync_origins_.empty()) { |
566 GURL origin = *pending_batch_sync_origins_.begin(); | 579 GURL origin = *pending_batch_sync_origins_.begin(); |
567 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin()); | 580 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin()); |
568 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin); | 581 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin); |
569 StartBatchSyncForOrigin(origin, resource_id); | 582 StartBatchSyncForOrigin(origin, resource_id); |
583 return; | |
570 } | 584 } |
585 | |
586 // Notify observer of the right timing to run ProcessRemoteChange. | |
587 FOR_EACH_OBSERVER(Observer, observers_, | |
588 OnRemoteChangeAvailable(pending_changes_.size())); | |
589 | |
590 if (!metadata_store_->incremental_sync_origins().empty() && | |
591 pending_changes_.empty() && | |
592 polling_enabled_) | |
593 SchedulePolling(); | |
571 } | 594 } |
572 | 595 |
573 void DriveFileSyncService::UpdateServiceState() { | 596 void DriveFileSyncService::UpdateServiceState() { |
574 switch (last_operation_status_) { | 597 switch (last_operation_status_) { |
575 // Possible regular operation errors. | 598 // Possible regular operation errors. |
576 case fileapi::SYNC_STATUS_OK: | 599 case fileapi::SYNC_STATUS_OK: |
577 case fileapi::SYNC_STATUS_FILE_BUSY: | 600 case fileapi::SYNC_STATUS_FILE_BUSY: |
578 case fileapi::SYNC_STATUS_HAS_CONFLICT: | 601 case fileapi::SYNC_STATUS_HAS_CONFLICT: |
579 case fileapi::SYNC_STATUS_NO_CONFLICT: | 602 case fileapi::SYNC_STATUS_NO_CONFLICT: |
580 case fileapi::SYNC_STATUS_NO_CHANGE_TO_SYNC: | 603 case fileapi::SYNC_STATUS_NO_CHANGE_TO_SYNC: |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
622 | 645 |
623 void DriveFileSyncService::DidInitializeMetadataStore( | 646 void DriveFileSyncService::DidInitializeMetadataStore( |
624 scoped_ptr<TaskToken> token, | 647 scoped_ptr<TaskToken> token, |
625 fileapi::SyncStatusCode status, | 648 fileapi::SyncStatusCode status, |
626 bool created) { | 649 bool created) { |
627 if (status != fileapi::SYNC_STATUS_OK) { | 650 if (status != fileapi::SYNC_STATUS_OK) { |
628 NotifyTaskDone(status, token.Pass()); | 651 NotifyTaskDone(status, token.Pass()); |
629 return; | 652 return; |
630 } | 653 } |
631 | 654 |
655 largest_fetched_changestamp_ = metadata_store_->GetLargestChangeStamp(); | |
656 | |
632 if (metadata_store_->sync_root_directory().empty()) { | 657 if (metadata_store_->sync_root_directory().empty()) { |
633 GetSyncRootDirectory(token.Pass(), base::Bind(&EmptyStatusCallback)); | 658 GetSyncRootDirectory(token.Pass(), base::Bind(&EmptyStatusCallback)); |
634 return; | 659 return; |
635 } | 660 } |
636 | 661 |
637 NotifyTaskDone(status, token.Pass()); | 662 NotifyTaskDone(status, token.Pass()); |
638 | 663 |
639 for (std::map<GURL, std::string>::const_iterator itr = | 664 for (std::map<GURL, std::string>::const_iterator itr = |
640 metadata_store_->batch_sync_origins().begin(); | 665 metadata_store_->batch_sync_origins().begin(); |
641 itr != metadata_store_->batch_sync_origins().end(); | 666 itr != metadata_store_->batch_sync_origins().end(); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
732 const std::string& resource_id, | 757 const std::string& resource_id, |
733 google_apis::GDataErrorCode error, | 758 google_apis::GDataErrorCode error, |
734 int64 largest_changestamp) { | 759 int64 largest_changestamp) { |
735 if (error != google_apis::HTTP_SUCCESS) { | 760 if (error != google_apis::HTTP_SUCCESS) { |
736 pending_batch_sync_origins_.insert(origin); | 761 pending_batch_sync_origins_.insert(origin); |
737 // TODO(tzik): Refine this error code. | 762 // TODO(tzik): Refine this error code. |
738 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); | 763 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); |
739 return; | 764 return; |
740 } | 765 } |
741 | 766 |
767 if (metadata_store_->incremental_sync_origins().empty()) { | |
768 largest_fetched_changestamp_ = largest_changestamp; | |
769 metadata_store_->SetLargestChangeStamp( | |
770 largest_changestamp, | |
771 base::Bind(&EmptyStatusCallback)); | |
772 } | |
773 | |
742 DCHECK(token); | 774 DCHECK(token); |
743 token->UpdateTask(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving remote files"); | 775 token->UpdateTask(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving remote files"); |
744 sync_client_->ListFiles( | 776 sync_client_->ListFiles( |
745 resource_id, | 777 resource_id, |
746 base::Bind( | 778 base::Bind( |
747 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, | 779 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, |
748 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); | 780 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); |
749 } | 781 } |
750 | 782 |
751 void DriveFileSyncService::DidGetDirectoryContentForBatchSync( | 783 void DriveFileSyncService::DidGetDirectoryContentForBatchSync( |
752 scoped_ptr<TaskToken> token, | 784 scoped_ptr<TaskToken> token, |
753 const GURL& origin, | 785 const GURL& origin, |
754 int64 largest_changestamp, | 786 int64 largest_changestamp, |
755 google_apis::GDataErrorCode error, | 787 google_apis::GDataErrorCode error, |
756 scoped_ptr<google_apis::DocumentFeed> feed) { | 788 scoped_ptr<google_apis::DocumentFeed> feed) { |
757 if (error != google_apis::HTTP_SUCCESS) { | 789 if (error != google_apis::HTTP_SUCCESS) { |
758 pending_batch_sync_origins_.insert(origin); | 790 pending_batch_sync_origins_.insert(origin); |
759 // TODO(tzik): Refine this error code. | 791 // TODO(tzik): Refine this error code. |
760 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); | 792 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); |
761 return; | 793 return; |
762 } | 794 } |
763 | 795 |
764 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator; | 796 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator; |
765 for (iterator itr = feed->entries().begin(); | 797 for (iterator itr = feed->entries().begin(); |
766 itr != feed->entries().end(); ++itr) { | 798 itr != feed->entries().end(); ++itr) { |
767 AppendNewRemoteChange(origin, *itr, largest_changestamp, | 799 AppendNewRemoteChange(origin, **itr, largest_changestamp, |
768 REMOTE_SYNC_TYPE_BATCH); | 800 REMOTE_SYNC_TYPE_BATCH); |
769 } | 801 } |
770 | 802 |
771 GURL next_feed_url; | 803 GURL next_feed_url; |
772 if (feed->GetNextFeedURL(&next_feed_url)) { | 804 if (feed->GetNextFeedURL(&next_feed_url)) { |
773 sync_client_->ContinueListing( | 805 sync_client_->ContinueListing( |
774 next_feed_url, | 806 next_feed_url, |
775 base::Bind( | 807 base::Bind( |
776 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, | 808 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, |
777 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); | 809 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
862 return SYNC_OPERATION_FAILED; | 894 return SYNC_OPERATION_FAILED; |
863 } | 895 } |
864 | 896 |
865 void DriveFileSyncService::DidApplyLocalChange( | 897 void DriveFileSyncService::DidApplyLocalChange( |
866 scoped_ptr<TaskToken> token, | 898 scoped_ptr<TaskToken> token, |
867 const fileapi::FileSystemURL& url, | 899 const fileapi::FileSystemURL& url, |
868 const google_apis::GDataErrorCode error, | 900 const google_apis::GDataErrorCode error, |
869 const fileapi::SyncStatusCallback& callback, | 901 const fileapi::SyncStatusCallback& callback, |
870 fileapi::SyncStatusCode status) { | 902 fileapi::SyncStatusCode status) { |
871 if (status == fileapi::SYNC_STATUS_OK) { | 903 if (status == fileapi::SYNC_STATUS_OK) { |
872 CancelRemoteChange(url); | 904 RemoveRemoteChange(url); |
873 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); | 905 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); |
874 callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); | 906 callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); |
875 return; | 907 return; |
876 } | 908 } |
877 NotifyTaskDone(status, token.Pass()); | 909 NotifyTaskDone(status, token.Pass()); |
878 callback.Run(status); | 910 callback.Run(status); |
879 } | 911 } |
880 | 912 |
881 void DriveFileSyncService::DidUploadNewFile( | 913 void DriveFileSyncService::DidUploadNewFile( |
882 scoped_ptr<TaskToken> token, | 914 scoped_ptr<TaskToken> token, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
997 const DriveMetadata& drive_metadata = param->drive_metadata; | 1029 const DriveMetadata& drive_metadata = param->drive_metadata; |
998 | 1030 |
999 status = metadata_store_->ReadEntry(param->remote_change.url, | 1031 status = metadata_store_->ReadEntry(param->remote_change.url, |
1000 ¶m->drive_metadata); | 1032 ¶m->drive_metadata); |
1001 DCHECK(status == fileapi::SYNC_STATUS_OK || | 1033 DCHECK(status == fileapi::SYNC_STATUS_OK || |
1002 status == fileapi::SYNC_DATABASE_ERROR_NOT_FOUND); | 1034 status == fileapi::SYNC_DATABASE_ERROR_NOT_FOUND); |
1003 | 1035 |
1004 bool missing_db_entry = (status != fileapi::SYNC_STATUS_OK); | 1036 bool missing_db_entry = (status != fileapi::SYNC_STATUS_OK); |
1005 if (missing_db_entry) { | 1037 if (missing_db_entry) { |
1006 param->drive_metadata.set_resource_id(param->remote_change.resource_id); | 1038 param->drive_metadata.set_resource_id(param->remote_change.resource_id); |
1039 param->drive_metadata.set_md5_checksum(std::string()); | |
1007 param->drive_metadata.set_conflicted(false); | 1040 param->drive_metadata.set_conflicted(false); |
1008 } | 1041 } |
1009 bool missing_local_file = | 1042 bool missing_local_file = |
1010 (metadata.file_type == fileapi::SYNC_FILE_TYPE_UNKNOWN); | 1043 (metadata.file_type == fileapi::SYNC_FILE_TYPE_UNKNOWN); |
1011 | 1044 |
1012 if (param->drive_metadata.conflicted()) { | 1045 if (param->drive_metadata.conflicted()) { |
1013 if (missing_local_file) { | 1046 if (missing_local_file) { |
1014 if (param->remote_change.change.IsAddOrUpdate()) { | 1047 if (param->remote_change.change.IsAddOrUpdate()) { |
1015 NOTIMPLEMENTED() << "ResolveToRemote()"; | 1048 NOTIMPLEMENTED() << "ResolveToRemote()"; |
1016 AbortRemoteSync(param.Pass(), fileapi::SYNC_STATUS_FAILED); | 1049 AbortRemoteSync(param.Pass(), fileapi::SYNC_STATUS_FAILED); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1076 | 1109 |
1077 DCHECK(param->remote_change.change.IsDelete()); | 1110 DCHECK(param->remote_change.change.IsDelete()); |
1078 if (local_changes.empty()) { | 1111 if (local_changes.empty()) { |
1079 if (missing_local_file) { | 1112 if (missing_local_file) { |
1080 param->operation_type = fileapi::SYNC_OPERATION_NONE; | 1113 param->operation_type = fileapi::SYNC_OPERATION_NONE; |
1081 DeleteMetadataForRemoteSync(param.Pass()); | 1114 DeleteMetadataForRemoteSync(param.Pass()); |
1082 return; | 1115 return; |
1083 } | 1116 } |
1084 DCHECK(!missing_local_file); | 1117 DCHECK(!missing_local_file); |
1085 param->operation_type = fileapi::SYNC_OPERATION_DELETE; | 1118 param->operation_type = fileapi::SYNC_OPERATION_DELETE; |
1119 | |
1120 const fileapi::FileChange& file_change = param->remote_change.change; | |
1086 param->processor->ApplyRemoteChange( | 1121 param->processor->ApplyRemoteChange( |
1087 param->remote_change.change, FilePath(), url, | 1122 file_change, FilePath(), url, |
1088 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, AsWeakPtr(), | 1123 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, AsWeakPtr(), |
1089 base::Passed(¶m))); | 1124 base::Passed(¶m))); |
1090 return; | 1125 return; |
1091 } | 1126 } |
1092 | 1127 |
1093 DCHECK(!local_changes.empty()); | 1128 DCHECK(!local_changes.empty()); |
1094 if (local_changes.list().back().IsAddOrUpdate()) { | 1129 if (local_changes.list().back().IsAddOrUpdate()) { |
1095 param->operation_type = fileapi::SYNC_OPERATION_NONE; | 1130 param->operation_type = fileapi::SYNC_OPERATION_NONE; |
1096 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); | 1131 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); |
1097 return; | 1132 return; |
(...skipping 18 matching lines...) Expand all Loading... | |
1116 } | 1151 } |
1117 | 1152 |
1118 void DriveFileSyncService::DidGetTemporaryFileForDownload( | 1153 void DriveFileSyncService::DidGetTemporaryFileForDownload( |
1119 scoped_ptr<ProcessRemoteChangeParam> param, | 1154 scoped_ptr<ProcessRemoteChangeParam> param, |
1120 bool success) { | 1155 bool success) { |
1121 if (!success) { | 1156 if (!success) { |
1122 AbortRemoteSync(param.Pass(), fileapi::SYNC_FILE_ERROR_FAILED); | 1157 AbortRemoteSync(param.Pass(), fileapi::SYNC_FILE_ERROR_FAILED); |
1123 return; | 1158 return; |
1124 } | 1159 } |
1125 | 1160 |
1126 DriveMetadata metadata; | |
1127 metadata_store_->ReadEntry(param->remote_change.url, &metadata); | |
1128 | |
1129 const FilePath& temporary_file_path = param->temporary_file_path; | 1161 const FilePath& temporary_file_path = param->temporary_file_path; |
1130 std::string resource_id = param->remote_change.resource_id; | 1162 std::string resource_id = param->remote_change.resource_id; |
1163 const DriveMetadata& drive_metadata = param->drive_metadata; | |
1131 sync_client_->DownloadFile( | 1164 sync_client_->DownloadFile( |
1132 resource_id, metadata.md5_checksum(), | 1165 resource_id, drive_metadata.md5_checksum(), |
1133 temporary_file_path, | 1166 temporary_file_path, |
1134 base::Bind(&DriveFileSyncService::DidDownloadFile, | 1167 base::Bind(&DriveFileSyncService::DidDownloadFile, |
1135 AsWeakPtr(), base::Passed(¶m))); | 1168 AsWeakPtr(), base::Passed(¶m))); |
1136 } | 1169 } |
1137 | 1170 |
1138 void DriveFileSyncService::DidDownloadFile( | 1171 void DriveFileSyncService::DidDownloadFile( |
1139 scoped_ptr<ProcessRemoteChangeParam> param, | 1172 scoped_ptr<ProcessRemoteChangeParam> param, |
1140 google_apis::GDataErrorCode error, | 1173 google_apis::GDataErrorCode error, |
1141 const std::string& md5_checksum) { | 1174 const std::string& md5_checksum) { |
1142 if (error == google_apis::HTTP_NOT_MODIFIED) { | 1175 if (error == google_apis::HTTP_NOT_MODIFIED) { |
1143 param->operation_type = fileapi::SYNC_OPERATION_NONE; | 1176 param->operation_type = fileapi::SYNC_OPERATION_NONE; |
1144 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); | 1177 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); |
1145 return; | 1178 return; |
1146 } | 1179 } |
1147 | 1180 |
1148 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCodeWrapper(error); | 1181 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCodeWrapper(error); |
1149 if (status != fileapi::SYNC_STATUS_OK) { | 1182 if (status != fileapi::SYNC_STATUS_OK) { |
1150 AbortRemoteSync(param.Pass(), status); | 1183 AbortRemoteSync(param.Pass(), status); |
1151 return; | 1184 return; |
1152 } | 1185 } |
1153 | 1186 |
1154 param->md5_checksum = md5_checksum; | 1187 param->drive_metadata.set_md5_checksum(md5_checksum); |
1155 const fileapi::FileChange& change = param->remote_change.change; | 1188 const fileapi::FileChange& change = param->remote_change.change; |
1156 const FilePath& temporary_file_path = param->temporary_file_path; | 1189 const FilePath& temporary_file_path = param->temporary_file_path; |
1157 const fileapi::FileSystemURL& url = param->remote_change.url; | 1190 const fileapi::FileSystemURL& url = param->remote_change.url; |
1158 param->processor->ApplyRemoteChange( | 1191 param->processor->ApplyRemoteChange( |
1159 change, temporary_file_path, url, | 1192 change, temporary_file_path, url, |
1160 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, | 1193 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, |
1161 AsWeakPtr(), base::Passed(¶m))); | 1194 AsWeakPtr(), base::Passed(¶m))); |
1162 } | 1195 } |
1163 | 1196 |
1164 void DriveFileSyncService::DidApplyRemoteChange( | 1197 void DriveFileSyncService::DidApplyRemoteChange( |
1165 scoped_ptr<ProcessRemoteChangeParam> param, | 1198 scoped_ptr<ProcessRemoteChangeParam> param, |
1166 fileapi::SyncStatusCode status) { | 1199 fileapi::SyncStatusCode status) { |
1167 if (status != fileapi::SYNC_STATUS_OK) { | 1200 if (status != fileapi::SYNC_STATUS_OK) { |
1168 AbortRemoteSync(param.Pass(), status); | 1201 AbortRemoteSync(param.Pass(), status); |
1169 return; | 1202 return; |
1170 } | 1203 } |
1171 | 1204 |
1172 fileapi::FileSystemURL url = param->remote_change.url; | 1205 fileapi::FileSystemURL url = param->remote_change.url; |
1173 if (param->remote_change.change.IsDelete()) { | 1206 if (param->remote_change.change.IsDelete()) { |
1174 DeleteMetadataForRemoteSync(param.Pass()); | 1207 DeleteMetadataForRemoteSync(param.Pass()); |
1175 return; | 1208 return; |
1176 } | 1209 } |
1177 | 1210 |
1178 DriveMetadata metadata; | 1211 const DriveMetadata& drive_metadata = param->drive_metadata; |
1179 metadata.set_resource_id(param->remote_change.resource_id); | 1212 param->drive_metadata.set_resource_id(param->remote_change.resource_id); |
1180 metadata.set_md5_checksum(param->md5_checksum); | 1213 param->drive_metadata.set_conflicted(false); |
1181 metadata.set_conflicted(false); | |
1182 | 1214 |
1183 metadata_store_->UpdateEntry( | 1215 metadata_store_->UpdateEntry( |
1184 url, metadata, | 1216 url, drive_metadata, |
1185 base::Bind(&DriveFileSyncService::CompleteRemoteSync, | 1217 base::Bind(&DriveFileSyncService::CompleteRemoteSync, |
1186 AsWeakPtr(), base::Passed(¶m))); | 1218 AsWeakPtr(), base::Passed(¶m))); |
1187 } | 1219 } |
1188 | 1220 |
1189 void DriveFileSyncService::DeleteMetadataForRemoteSync( | 1221 void DriveFileSyncService::DeleteMetadataForRemoteSync( |
1190 scoped_ptr<ProcessRemoteChangeParam> param) { | 1222 scoped_ptr<ProcessRemoteChangeParam> param) { |
1191 fileapi::FileSystemURL url = param->remote_change.url; | 1223 fileapi::FileSystemURL url = param->remote_change.url; |
1192 metadata_store_->DeleteEntry( | 1224 metadata_store_->DeleteEntry( |
1193 url, | 1225 url, |
1194 base::Bind(&DriveFileSyncService::CompleteRemoteSync, | 1226 base::Bind(&DriveFileSyncService::CompleteRemoteSync, |
1195 AsWeakPtr(), base::Passed(¶m))); | 1227 AsWeakPtr(), base::Passed(¶m))); |
1196 } | 1228 } |
1197 | 1229 |
1198 void DriveFileSyncService::CompleteRemoteSync( | 1230 void DriveFileSyncService::CompleteRemoteSync( |
1199 scoped_ptr<ProcessRemoteChangeParam> param, | 1231 scoped_ptr<ProcessRemoteChangeParam> param, |
1200 fileapi::SyncStatusCode status) { | 1232 fileapi::SyncStatusCode status) { |
1201 if (status != fileapi::SYNC_STATUS_OK) { | 1233 if (status != fileapi::SYNC_STATUS_OK) { |
1202 AbortRemoteSync(param.Pass(), status); | 1234 AbortRemoteSync(param.Pass(), status); |
1203 return; | 1235 return; |
1204 } | 1236 } |
1205 | 1237 |
1206 CancelRemoteChange(param->remote_change.url); | 1238 RemoveRemoteChange(param->remote_change.url); |
1207 | 1239 |
1208 GURL origin = param->remote_change.url.origin(); | 1240 GURL origin = param->remote_change.url.origin(); |
1209 if (metadata_store_->IsIncrementalSyncOrigin(origin)) { | 1241 if (metadata_store_->IsIncrementalSyncOrigin(origin)) { |
1210 int64 changestamp = param->remote_change.changestamp; | 1242 int64 changestamp = param->remote_change.changestamp; |
1211 metadata_store_->SetLargestChangeStamp( | 1243 metadata_store_->SetLargestChangeStamp( |
1212 changestamp, | 1244 changestamp, |
1213 base::Bind(&DriveFileSyncService::FinalizeRemoteSync, | 1245 base::Bind(&DriveFileSyncService::FinalizeRemoteSync, |
1214 AsWeakPtr(), base::Passed(¶m))); | 1246 AsWeakPtr(), base::Passed(¶m))); |
1215 return; | 1247 return; |
1216 } | 1248 } |
(...skipping 20 matching lines...) Expand all Loading... | |
1237 param->callback.Run(status, param->remote_change.url, | 1269 param->callback.Run(status, param->remote_change.url, |
1238 param->operation_type); | 1270 param->operation_type); |
1239 } else { | 1271 } else { |
1240 param->callback.Run(status, param->remote_change.url, | 1272 param->callback.Run(status, param->remote_change.url, |
1241 fileapi::SYNC_OPERATION_NONE); | 1273 fileapi::SYNC_OPERATION_NONE); |
1242 } | 1274 } |
1243 } | 1275 } |
1244 | 1276 |
1245 void DriveFileSyncService::AppendNewRemoteChange( | 1277 void DriveFileSyncService::AppendNewRemoteChange( |
1246 const GURL& origin, | 1278 const GURL& origin, |
1247 google_apis::DocumentEntry* entry, | 1279 const google_apis::DocumentEntry& entry, |
1248 int64 changestamp, | 1280 int64 changestamp, |
1249 RemoteSyncType sync_type) { | 1281 RemoteSyncType sync_type) { |
1250 // TODO(tzik): Normalize the path here. | 1282 // TODO(tzik): Normalize the path here. |
1251 FilePath path = FilePath::FromUTF8Unsafe(UTF16ToUTF8(entry->title())); | 1283 FilePath path = FilePath::FromUTF8Unsafe(UTF16ToUTF8(entry.title())); |
1252 | 1284 |
1253 PathToChange* path_to_change = &url_to_change_[origin]; | 1285 PathToChange* path_to_change = &url_to_change_[origin]; |
1254 PathToChange::iterator found = path_to_change->find(path); | 1286 PathToChange::iterator found = path_to_change->find(path); |
1255 if (found != path_to_change->end()) { | 1287 if (found != path_to_change->end()) { |
1256 if (found->second.changestamp >= changestamp) | 1288 if (found->second.changestamp >= changestamp) |
1257 return; | 1289 return; |
1258 pending_changes_.erase(found->second.position_in_queue); | 1290 pending_changes_.erase(found->second.position_in_queue); |
1259 } | 1291 } |
1260 | 1292 |
1261 fileapi::FileSystemURL url( | 1293 fileapi::FileSystemURL url( |
1262 fileapi::CreateSyncableFileSystemURL(origin, kServiceName, path)); | 1294 fileapi::CreateSyncableFileSystemURL(origin, kServiceName, path)); |
1263 | 1295 |
1264 fileapi::FileChange::ChangeType change_type; | 1296 fileapi::FileChange::ChangeType change_type; |
1265 fileapi::SyncFileType file_type; | 1297 fileapi::SyncFileType file_type; |
1266 if (entry->deleted()) { | 1298 if (entry.deleted()) { |
1267 change_type = fileapi::FileChange::FILE_CHANGE_DELETE; | 1299 change_type = fileapi::FileChange::FILE_CHANGE_DELETE; |
1268 file_type = fileapi::SYNC_FILE_TYPE_UNKNOWN; | 1300 file_type = fileapi::SYNC_FILE_TYPE_UNKNOWN; |
1269 } else { | 1301 } else { |
1270 change_type = fileapi::FileChange::FILE_CHANGE_ADD_OR_UPDATE; | 1302 change_type = fileapi::FileChange::FILE_CHANGE_ADD_OR_UPDATE; |
1271 if (entry->kind() == google_apis::ENTRY_KIND_FOLDER) | 1303 if (entry.is_folder()) |
1272 file_type = fileapi::SYNC_FILE_TYPE_DIRECTORY; | 1304 file_type = fileapi::SYNC_FILE_TYPE_DIRECTORY; |
1273 else | 1305 else |
1274 file_type = fileapi::SYNC_FILE_TYPE_FILE; | 1306 file_type = fileapi::SYNC_FILE_TYPE_FILE; |
1275 } | 1307 } |
1276 | 1308 |
1277 fileapi::FileChange file_change(change_type, file_type); | 1309 fileapi::FileChange file_change(change_type, file_type); |
1278 | 1310 |
1279 std::pair<PendingChangeQueue::iterator, bool> inserted_to_queue = | 1311 std::pair<PendingChangeQueue::iterator, bool> inserted_to_queue = |
1280 pending_changes_.insert(ChangeQueueItem(changestamp, sync_type, url)); | 1312 pending_changes_.insert(ChangeQueueItem(changestamp, sync_type, url)); |
1281 DCHECK(inserted_to_queue.second); | 1313 DCHECK(inserted_to_queue.second); |
1282 | 1314 |
1283 (*path_to_change)[path] = RemoteChange( | 1315 (*path_to_change)[path] = RemoteChange( |
1284 changestamp, entry->resource_id(), url, file_change, | 1316 changestamp, entry.resource_id(), url, file_change, |
1285 inserted_to_queue.first); | 1317 inserted_to_queue.first); |
1286 } | 1318 } |
1287 | 1319 |
1288 void DriveFileSyncService::CancelRemoteChange( | 1320 void DriveFileSyncService::RemoveRemoteChange( |
1289 const fileapi::FileSystemURL& url) { | 1321 const fileapi::FileSystemURL& url) { |
1290 URLToChange::iterator found_origin = url_to_change_.find(url.origin()); | 1322 URLToChange::iterator found_origin = url_to_change_.find(url.origin()); |
1291 if (found_origin == url_to_change_.end()) | 1323 if (found_origin == url_to_change_.end()) |
1292 return; | 1324 return; |
1293 | 1325 |
1294 PathToChange* path_to_change = &found_origin->second; | 1326 PathToChange* path_to_change = &found_origin->second; |
1295 PathToChange::iterator found_change = path_to_change->find(url.path()); | 1327 PathToChange::iterator found_change = path_to_change->find(url.path()); |
1296 if (found_change == path_to_change->end()) | 1328 if (found_change == path_to_change->end()) |
1297 return; | 1329 return; |
1298 | 1330 |
1299 pending_changes_.erase(found_change->second.position_in_queue); | 1331 pending_changes_.erase(found_change->second.position_in_queue); |
1300 path_to_change->erase(found_change); | 1332 path_to_change->erase(found_change); |
1301 if (path_to_change->empty()) | 1333 if (path_to_change->empty()) |
1302 url_to_change_.erase(found_origin); | 1334 url_to_change_.erase(found_origin); |
1303 | 1335 |
1304 MaybeMarkAsIncrementalSyncOrigin(url.origin()); | 1336 if (metadata_store_->IsBatchSyncOrigin(url.origin()) && |
1305 } | 1337 !ContainsKey(url_to_change_, url.origin())) { |
1306 | 1338 metadata_store_->MoveBatchSyncOriginToIncremental(url.origin()); |
1307 void DriveFileSyncService::MaybeMarkAsIncrementalSyncOrigin( | 1339 } |
1308 const GURL& origin) { | |
1309 if (metadata_store_->IsBatchSyncOrigin(origin) && | |
1310 !ContainsKey(url_to_change_, origin)) | |
1311 metadata_store_->MoveBatchSyncOriginToIncremental(origin); | |
1312 } | 1340 } |
1313 | 1341 |
1314 bool DriveFileSyncService::GetPendingChangeForFileSystemURL( | 1342 bool DriveFileSyncService::GetPendingChangeForFileSystemURL( |
1315 const fileapi::FileSystemURL& url, | 1343 const fileapi::FileSystemURL& url, |
1316 RemoteChange* change) const { | 1344 RemoteChange* change) const { |
1317 DCHECK(change); | 1345 DCHECK(change); |
1318 URLToChange::const_iterator found_url = url_to_change_.find(url.origin()); | 1346 URLToChange::const_iterator found_url = url_to_change_.find(url.origin()); |
1319 if (found_url == url_to_change_.end()) | 1347 if (found_url == url_to_change_.end()) |
1320 return false; | 1348 return false; |
1321 const PathToChange& path_to_change = found_url->second; | 1349 const PathToChange& path_to_change = found_url->second; |
1322 PathToChange::const_iterator found_path = path_to_change.find(url.path()); | 1350 PathToChange::const_iterator found_path = path_to_change.find(url.path()); |
1323 if (found_path == path_to_change.end()) | 1351 if (found_path == path_to_change.end()) |
1324 return false; | 1352 return false; |
1325 *change = found_path->second; | 1353 *change = found_path->second; |
1326 return true; | 1354 return true; |
1327 } | 1355 } |
1328 | 1356 |
1357 void DriveFileSyncService::FetchChangesForIncrementalSync() { | |
1358 scoped_ptr<TaskToken> token(GetToken(FROM_HERE, TASK_TYPE_DRIVE, | |
1359 "Fetching remote change list")); | |
1360 if (!token) { | |
1361 pending_tasks_.push_back(base::Bind( | |
1362 &DriveFileSyncService::FetchChangesForIncrementalSync, AsWeakPtr())); | |
1363 return; | |
1364 } | |
1365 | |
1366 if (metadata_store_->incremental_sync_origins().empty()) { | |
1367 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass()); | |
1368 return; | |
1369 } | |
1370 | |
1371 sync_client_->ListChanges( | |
1372 largest_fetched_changestamp_, | |
1373 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync, | |
1374 AsWeakPtr(), base::Passed(&token))); | |
1375 } | |
1376 | |
1377 void DriveFileSyncService::DidFetchChangesForIncrementalSync( | |
1378 scoped_ptr<TaskToken> token, | |
1379 google_apis::GDataErrorCode error, | |
1380 scoped_ptr<google_apis::DocumentFeed> changes) { | |
1381 if (error != google_apis::HTTP_SUCCESS) { | |
1382 NotifyTaskDone(fileapi::SYNC_STATUS_FAILED, token.Pass()); | |
kinuko
2012/12/04 05:18:30
GDataErrorCodeToSyncStatusCodeWrapper(error) ?
tzik
2012/12/04 06:32:32
Done.
| |
1383 return; | |
1384 } | |
1385 | |
1386 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator; | |
1387 for (iterator itr = changes->entries().begin(); | |
1388 itr != changes->entries().end(); ++itr) { | |
1389 const google_apis::DocumentEntry& entry = **itr; | |
1390 GURL origin; | |
1391 if (!GetOriginForEntry(entry, &origin)) | |
1392 continue; | |
1393 | |
1394 AppendNewRemoteChange(origin, entry, entry.changestamp(), | |
1395 REMOTE_SYNC_TYPE_INCREMENTAL); | |
1396 } | |
1397 | |
1398 GURL next_feed; | |
1399 if (changes->GetNextFeedURL(&next_feed)) { | |
1400 sync_client_->ContinueListing( | |
1401 next_feed, | |
1402 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync, | |
1403 AsWeakPtr(), base::Passed(&token))); | |
1404 return; | |
1405 } | |
1406 | |
1407 largest_fetched_changestamp_ = changes->largest_changestamp(); | |
1408 | |
1409 if (changes->start_index() == 0 && changes->entries().empty()) { | |
1410 // If this set of changes is the first feed and it's empty, update | |
1411 // the polling delay to wait longer. | |
1412 base::TimeDelta max_delay( | |
1413 base::TimeDelta::FromSeconds(kMaximumPollingDelaySeconds)); | |
1414 | |
1415 polling_delay_ = base::TimeDelta::FromInternalValue(static_cast<int64>( | |
1416 kDelayMultiplier * polling_delay_.ToInternalValue())); | |
1417 if (polling_delay_ >= max_delay) | |
1418 polling_delay_ = max_delay; | |
1419 } else { | |
1420 polling_delay_ = base::TimeDelta::FromSeconds( | |
1421 kMinimumPollingDelaySeconds); | |
kinuko
2012/12/04 05:18:30
nit: this code is totally ok but just keeping poll
tzik
2012/12/04 06:32:32
Done.
| |
1422 } | |
1423 | |
1424 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass()); | |
1425 } | |
1426 | |
1427 bool DriveFileSyncService::GetOriginForEntry( | |
1428 const google_apis::DocumentEntry& entry, | |
1429 GURL* origin_out) { | |
1430 typedef ScopedVector<google_apis::Link>::const_iterator iterator; | |
1431 for (iterator itr = entry.links().begin(); | |
1432 itr != entry.links().end(); ++itr) { | |
1433 if ((*itr)->type() != google_apis::Link::LINK_PARENT) | |
1434 continue; | |
1435 GURL origin(UTF16ToUTF8((*itr)->title())); | |
1436 if (!origin.is_valid()) | |
1437 continue; | |
1438 | |
1439 if (!metadata_store_->IsBatchSyncOrigin(origin) && | |
1440 !metadata_store_->IsIncrementalSyncOrigin(origin)) | |
1441 continue; | |
1442 std::string resource_id(metadata_store_->GetResourceIdForOrigin(origin)); | |
1443 GURL resource_link(sync_client_->ResourceIdToResourceLink(resource_id)); | |
1444 if ((*itr)->href().GetOrigin() != resource_link.GetOrigin() || | |
1445 (*itr)->href().path() != resource_link.path()) | |
1446 continue; | |
1447 | |
1448 *origin_out = origin; | |
1449 return true; | |
1450 } | |
1451 return false; | |
1452 } | |
1453 | |
1454 void DriveFileSyncService::SchedulePolling() { | |
1455 if (polling_timer_.IsRunning()) | |
1456 return; | |
1457 | |
1458 DVLOG(1) << "Polling scheduled" | |
1459 << " (delay:" << polling_delay_.InSeconds() << ")"; | |
1460 | |
1461 polling_timer_.Start( | |
1462 FROM_HERE, polling_delay_, | |
1463 base::Bind(&DriveFileSyncService::FetchChangesForIncrementalSync, | |
1464 AsWeakPtr())); | |
1465 } | |
1466 | |
1329 fileapi::SyncStatusCode | 1467 fileapi::SyncStatusCode |
1330 DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper( | 1468 DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper( |
1331 google_apis::GDataErrorCode error) const { | 1469 google_apis::GDataErrorCode error) const { |
1332 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); | 1470 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); |
1333 if (status != fileapi::SYNC_STATUS_OK && !sync_client_->IsAuthenticated()) | 1471 if (status != fileapi::SYNC_STATUS_OK && !sync_client_->IsAuthenticated()) |
1334 return fileapi::SYNC_STATUS_AUTHENTICATION_FAILED; | 1472 return fileapi::SYNC_STATUS_AUTHENTICATION_FAILED; |
1335 return status; | 1473 return status; |
1336 } | 1474 } |
1337 | 1475 |
1338 } // namespace sync_file_system | 1476 } // namespace sync_file_system |
OLD | NEW |