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

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: rebase 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"
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
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
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
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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 434
428 DVLOG(1) << "ApplyLocalChange for " << url.DebugString() 435 DVLOG(1) << "ApplyLocalChange for " << url.DebugString()
429 << " local_change:" << local_file_change.DebugString() 436 << " local_change:" << local_file_change.DebugString()
430 << " ==> operation:" << operation; 437 << " ==> operation:" << operation;
431 438
432 switch (operation) { 439 switch (operation) {
433 case SYNC_OPERATION_UPLOAD_NEW_FILE: { 440 case SYNC_OPERATION_UPLOAD_NEW_FILE: {
434 sync_client_->UploadNewFile( 441 sync_client_->UploadNewFile(
435 metadata_store_->GetResourceIdForOrigin(url.origin()), 442 metadata_store_->GetResourceIdForOrigin(url.origin()),
436 local_file_path, 443 local_file_path,
437 net::EscapePath(url.path().AsUTF8Unsafe()), 444 url.path().AsUTF8Unsafe(),
438 local_file_metadata.size, 445 local_file_metadata.size,
439 base::Bind(&DriveFileSyncService::DidUploadNewFile, 446 base::Bind(&DriveFileSyncService::DidUploadNewFile,
440 AsWeakPtr(), base::Passed(&token), url, callback)); 447 AsWeakPtr(), base::Passed(&token), url, callback));
441 return; 448 return;
442 } 449 }
443 case SYNC_OPERATION_UPLOAD_EXISTING_FILE: { 450 case SYNC_OPERATION_UPLOAD_EXISTING_FILE: {
444 DriveMetadata metadata; 451 DriveMetadata metadata;
445 const fileapi::SyncStatusCode status = 452 const fileapi::SyncStatusCode status =
446 metadata_store_->ReadEntry(url, &metadata); 453 metadata_store_->ReadEntry(url, &metadata);
447 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status); 454 DCHECK_EQ(fileapi::SYNC_STATUS_OK, status);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 callback, fileapi::SYNC_STATUS_FAILED); 514 callback, fileapi::SYNC_STATUS_FAILED);
508 } 515 }
509 516
510 // Called by CreateForTesting. 517 // Called by CreateForTesting.
511 DriveFileSyncService::DriveFileSyncService( 518 DriveFileSyncService::DriveFileSyncService(
512 const FilePath& base_dir, 519 const FilePath& base_dir,
513 scoped_ptr<DriveFileSyncClient> sync_client, 520 scoped_ptr<DriveFileSyncClient> sync_client,
514 scoped_ptr<DriveMetadataStore> metadata_store) 521 scoped_ptr<DriveMetadataStore> metadata_store)
515 : last_operation_status_(fileapi::SYNC_STATUS_OK), 522 : last_operation_status_(fileapi::SYNC_STATUS_OK),
516 state_(REMOTE_SERVICE_OK), 523 state_(REMOTE_SERVICE_OK),
517 largest_changestamp_(0), 524 largest_fetched_changestamp_(0),
525 polling_enabled_(false),
518 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 526 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
519 temporary_file_dir_ = base_dir.Append(kTempDirName); 527 temporary_file_dir_ = base_dir.Append(kTempDirName);
520 528
521 token_.reset(new TaskToken(AsWeakPtr())); 529 token_.reset(new TaskToken(AsWeakPtr()));
522 sync_client_ = sync_client.Pass(); 530 sync_client_ = sync_client.Pass();
523 metadata_store_ = metadata_store.Pass(); 531 metadata_store_ = metadata_store.Pass();
524 532
525 DidInitializeMetadataStore( 533 DidInitializeMetadataStore(
526 GetToken(FROM_HERE, TASK_TYPE_NONE, "Drive initialization for testing"), 534 GetToken(FROM_HERE, TASK_TYPE_NONE, "Drive initialization for testing"),
527 fileapi::SYNC_STATUS_OK, false); 535 fileapi::SYNC_STATUS_OK, false);
528 } 536 }
529 537
530 scoped_ptr<DriveFileSyncService::TaskToken> DriveFileSyncService::GetToken( 538 scoped_ptr<DriveFileSyncService::TaskToken> DriveFileSyncService::GetToken(
531 const tracked_objects::Location& from_here, 539 const tracked_objects::Location& from_here,
532 TaskType task_type, 540 TaskType task_type,
533 const std::string& description) { 541 const std::string& description) {
534 if (!token_) 542 if (!token_)
535 return scoped_ptr<TaskToken>(); 543 return scoped_ptr<TaskToken>();
536 token_->UpdateTask(from_here, task_type, description); 544 token_->UpdateTask(from_here, task_type, description);
537 return token_.Pass(); 545 return token_.Pass();
538 } 546 }
539 547
540 void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status, 548 void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status,
541 scoped_ptr<TaskToken> token) { 549 scoped_ptr<TaskToken> token) {
542 DCHECK(token); 550 DCHECK(token);
543 last_operation_status_ = status; 551 last_operation_status_ = status;
544 token_ = token.Pass(); 552 token_ = token.Pass();
545 553
546 RemoteServiceState old_state = state_;
547 if (token_->task_type() != TASK_TYPE_NONE) { 554 if (token_->task_type() != TASK_TYPE_NONE) {
548 DVLOG(1) << "NotifyTaskDone: " << token_->description() 555 DVLOG(1) << "NotifyTaskDone: " << token_->description()
549 << ": finished with status=" << status 556 << ": finished with status=" << status
550 << " " << token_->location().ToString(); 557 << " " << token_->location().ToString();
551 558
552 RemoteServiceState old_state = state_; 559 RemoteServiceState old_state = state_;
553 UpdateServiceState(); 560 UpdateServiceState();
554 561
555 // Notify remote sync service state if the state has been changed. 562 // Notify remote sync service state if the state has been changed.
556 if (!token_->description().empty() || old_state != state_) { 563 if (!token_->description().empty() || old_state != state_) {
557 FOR_EACH_OBSERVER( 564 FOR_EACH_OBSERVER(
558 Observer, observers_, 565 Observer, observers_,
559 OnRemoteServiceStateUpdated(state_, token_->done_description())); 566 OnRemoteServiceStateUpdated(state_, token_->done_description()));
560 } 567 }
561 } 568 }
562 569
563 token_->ResetTask(FROM_HERE); 570 token_->ResetTask(FROM_HERE);
564 if (!pending_tasks_.empty()) { 571 if (!pending_tasks_.empty()) {
565 base::Closure closure = pending_tasks_.front(); 572 base::Closure closure = pending_tasks_.front();
566 pending_tasks_.pop_front(); 573 pending_tasks_.pop_front();
567 closure.Run(); 574 closure.Run();
568 return; 575 return;
569 } 576 }
570 577
571 if (state_ != REMOTE_SERVICE_OK || old_state == state_) 578 if (state_ != REMOTE_SERVICE_OK) {
579 if (state_ == REMOTE_SERVICE_TEMPORARY_UNAVAILABLE) {
580 polling_delay_ =
581 base::TimeDelta::FromSeconds(kMaximumPollingDelaySeconds);
582 SchedulePolling();
583 }
572 return; 584 return;
585 }
573 586
574 // If the state has become OK and we have any pending batch sync origins 587 // If the state has become OK and we have any pending batch sync origins
575 // restart batch sync for them. 588 // restart batch sync for them.
576 if (!pending_batch_sync_origins_.empty()) { 589 if (!pending_batch_sync_origins_.empty()) {
577 GURL origin = *pending_batch_sync_origins_.begin(); 590 GURL origin = *pending_batch_sync_origins_.begin();
578 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin()); 591 pending_batch_sync_origins_.erase(pending_batch_sync_origins_.begin());
579 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin); 592 std::string resource_id = metadata_store_->GetResourceIdForOrigin(origin);
580 StartBatchSyncForOrigin(origin, resource_id); 593 StartBatchSyncForOrigin(origin, resource_id);
594 return;
581 } 595 }
596
597 // Notify observer of the right timing to run ProcessRemoteChange.
nhiroki 2012/12/04 05:55:31 "Notify observers in the right timing to run Proce
tzik 2012/12/04 06:32:32 Done.
tzik 2012/12/04 06:32:32 Done.
598 FOR_EACH_OBSERVER(Observer, observers_,
599 OnRemoteChangeAvailable(pending_changes_.size()));
600
601 if (!metadata_store_->incremental_sync_origins().empty() &&
602 pending_changes_.empty() &&
603 polling_enabled_)
604 SchedulePolling();
582 } 605 }
583 606
584 void DriveFileSyncService::UpdateServiceState() { 607 void DriveFileSyncService::UpdateServiceState() {
585 switch (last_operation_status_) { 608 switch (last_operation_status_) {
586 // Possible regular operation errors. 609 // Possible regular operation errors.
587 case fileapi::SYNC_STATUS_OK: 610 case fileapi::SYNC_STATUS_OK:
588 case fileapi::SYNC_STATUS_FILE_BUSY: 611 case fileapi::SYNC_STATUS_FILE_BUSY:
589 case fileapi::SYNC_STATUS_HAS_CONFLICT: 612 case fileapi::SYNC_STATUS_HAS_CONFLICT:
590 case fileapi::SYNC_STATUS_NO_CONFLICT: 613 case fileapi::SYNC_STATUS_NO_CONFLICT:
591 case fileapi::SYNC_STATUS_NO_CHANGE_TO_SYNC: 614 case fileapi::SYNC_STATUS_NO_CHANGE_TO_SYNC:
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 656
634 void DriveFileSyncService::DidInitializeMetadataStore( 657 void DriveFileSyncService::DidInitializeMetadataStore(
635 scoped_ptr<TaskToken> token, 658 scoped_ptr<TaskToken> token,
636 fileapi::SyncStatusCode status, 659 fileapi::SyncStatusCode status,
637 bool created) { 660 bool created) {
638 if (status != fileapi::SYNC_STATUS_OK) { 661 if (status != fileapi::SYNC_STATUS_OK) {
639 NotifyTaskDone(status, token.Pass()); 662 NotifyTaskDone(status, token.Pass());
640 return; 663 return;
641 } 664 }
642 665
666 largest_fetched_changestamp_ = metadata_store_->GetLargestChangeStamp();
667
643 if (metadata_store_->sync_root_directory().empty()) { 668 if (metadata_store_->sync_root_directory().empty()) {
644 GetSyncRootDirectory(token.Pass(), base::Bind(&EmptyStatusCallback)); 669 GetSyncRootDirectory(token.Pass(), base::Bind(&EmptyStatusCallback));
645 return; 670 return;
646 } 671 }
647 672
648 NotifyTaskDone(status, token.Pass()); 673 NotifyTaskDone(status, token.Pass());
649 674
650 for (std::map<GURL, std::string>::const_iterator itr = 675 for (std::map<GURL, std::string>::const_iterator itr =
651 metadata_store_->batch_sync_origins().begin(); 676 metadata_store_->batch_sync_origins().begin();
652 itr != metadata_store_->batch_sync_origins().end(); 677 itr != metadata_store_->batch_sync_origins().end();
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 const std::string& resource_id, 768 const std::string& resource_id,
744 google_apis::GDataErrorCode error, 769 google_apis::GDataErrorCode error,
745 int64 largest_changestamp) { 770 int64 largest_changestamp) {
746 if (error != google_apis::HTTP_SUCCESS) { 771 if (error != google_apis::HTTP_SUCCESS) {
747 pending_batch_sync_origins_.insert(origin); 772 pending_batch_sync_origins_.insert(origin);
748 // TODO(tzik): Refine this error code. 773 // TODO(tzik): Refine this error code.
749 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); 774 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass());
750 return; 775 return;
751 } 776 }
752 777
778 if (metadata_store_->incremental_sync_origins().empty()) {
779 largest_fetched_changestamp_ = largest_changestamp;
780 metadata_store_->SetLargestChangeStamp(
781 largest_changestamp,
782 base::Bind(&EmptyStatusCallback));
783 }
784
753 DCHECK(token); 785 DCHECK(token);
754 token->UpdateTask(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving remote files"); 786 token->UpdateTask(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving remote files");
755 sync_client_->ListFiles( 787 sync_client_->ListFiles(
756 resource_id, 788 resource_id,
757 base::Bind( 789 base::Bind(
758 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, 790 &DriveFileSyncService::DidGetDirectoryContentForBatchSync,
759 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); 791 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp));
760 } 792 }
761 793
762 void DriveFileSyncService::DidGetDirectoryContentForBatchSync( 794 void DriveFileSyncService::DidGetDirectoryContentForBatchSync(
763 scoped_ptr<TaskToken> token, 795 scoped_ptr<TaskToken> token,
764 const GURL& origin, 796 const GURL& origin,
765 int64 largest_changestamp, 797 int64 largest_changestamp,
766 google_apis::GDataErrorCode error, 798 google_apis::GDataErrorCode error,
767 scoped_ptr<google_apis::DocumentFeed> feed) { 799 scoped_ptr<google_apis::DocumentFeed> feed) {
768 if (error != google_apis::HTTP_SUCCESS) { 800 if (error != google_apis::HTTP_SUCCESS) {
769 pending_batch_sync_origins_.insert(origin); 801 pending_batch_sync_origins_.insert(origin);
770 // TODO(tzik): Refine this error code. 802 // TODO(tzik): Refine this error code.
771 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); 803 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass());
772 return; 804 return;
773 } 805 }
774 806
775 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator; 807 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator;
776 for (iterator itr = feed->entries().begin(); 808 for (iterator itr = feed->entries().begin();
777 itr != feed->entries().end(); ++itr) { 809 itr != feed->entries().end(); ++itr) {
778 AppendNewRemoteChange(origin, *itr, largest_changestamp, 810 AppendNewRemoteChange(origin, **itr, largest_changestamp,
779 REMOTE_SYNC_TYPE_BATCH); 811 REMOTE_SYNC_TYPE_BATCH);
780 } 812 }
781 813
782 GURL next_feed_url; 814 GURL next_feed_url;
783 if (feed->GetNextFeedURL(&next_feed_url)) { 815 if (feed->GetNextFeedURL(&next_feed_url)) {
784 sync_client_->ContinueListing( 816 sync_client_->ContinueListing(
785 next_feed_url, 817 next_feed_url,
786 base::Bind( 818 base::Bind(
787 &DriveFileSyncService::DidGetDirectoryContentForBatchSync, 819 &DriveFileSyncService::DidGetDirectoryContentForBatchSync,
788 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp)); 820 AsWeakPtr(), base::Passed(&token), origin, largest_changestamp));
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 return SYNC_OPERATION_FAILED; 905 return SYNC_OPERATION_FAILED;
874 } 906 }
875 907
876 void DriveFileSyncService::DidApplyLocalChange( 908 void DriveFileSyncService::DidApplyLocalChange(
877 scoped_ptr<TaskToken> token, 909 scoped_ptr<TaskToken> token,
878 const fileapi::FileSystemURL& url, 910 const fileapi::FileSystemURL& url,
879 const google_apis::GDataErrorCode error, 911 const google_apis::GDataErrorCode error,
880 const fileapi::SyncStatusCallback& callback, 912 const fileapi::SyncStatusCallback& callback,
881 fileapi::SyncStatusCode status) { 913 fileapi::SyncStatusCode status) {
882 if (status == fileapi::SYNC_STATUS_OK) { 914 if (status == fileapi::SYNC_STATUS_OK) {
883 CancelRemoteChange(url); 915 RemoveRemoteChange(url);
884 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass()); 916 NotifyTaskDone(GDataErrorCodeToSyncStatusCodeWrapper(error), token.Pass());
885 callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); 917 callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error));
886 return; 918 return;
887 } 919 }
888 NotifyTaskDone(status, token.Pass()); 920 NotifyTaskDone(status, token.Pass());
889 callback.Run(status); 921 callback.Run(status);
890 } 922 }
891 923
892 void DriveFileSyncService::DidUploadNewFile( 924 void DriveFileSyncService::DidUploadNewFile(
893 scoped_ptr<TaskToken> token, 925 scoped_ptr<TaskToken> token,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 const DriveMetadata& drive_metadata = param->drive_metadata; 1040 const DriveMetadata& drive_metadata = param->drive_metadata;
1009 1041
1010 status = metadata_store_->ReadEntry(param->remote_change.url, 1042 status = metadata_store_->ReadEntry(param->remote_change.url,
1011 &param->drive_metadata); 1043 &param->drive_metadata);
1012 DCHECK(status == fileapi::SYNC_STATUS_OK || 1044 DCHECK(status == fileapi::SYNC_STATUS_OK ||
1013 status == fileapi::SYNC_DATABASE_ERROR_NOT_FOUND); 1045 status == fileapi::SYNC_DATABASE_ERROR_NOT_FOUND);
1014 1046
1015 bool missing_db_entry = (status != fileapi::SYNC_STATUS_OK); 1047 bool missing_db_entry = (status != fileapi::SYNC_STATUS_OK);
1016 if (missing_db_entry) { 1048 if (missing_db_entry) {
1017 param->drive_metadata.set_resource_id(param->remote_change.resource_id); 1049 param->drive_metadata.set_resource_id(param->remote_change.resource_id);
1050 param->drive_metadata.set_md5_checksum(std::string());
1018 param->drive_metadata.set_conflicted(false); 1051 param->drive_metadata.set_conflicted(false);
1019 } 1052 }
1020 bool missing_local_file = 1053 bool missing_local_file =
1021 (metadata.file_type == fileapi::SYNC_FILE_TYPE_UNKNOWN); 1054 (metadata.file_type == fileapi::SYNC_FILE_TYPE_UNKNOWN);
1022 1055
1023 if (param->drive_metadata.conflicted()) { 1056 if (param->drive_metadata.conflicted()) {
1024 if (missing_local_file) { 1057 if (missing_local_file) {
1025 if (param->remote_change.change.IsAddOrUpdate()) { 1058 if (param->remote_change.change.IsAddOrUpdate()) {
1026 NOTIMPLEMENTED() << "ResolveToRemote()"; 1059 NOTIMPLEMENTED() << "ResolveToRemote()";
1027 AbortRemoteSync(param.Pass(), fileapi::SYNC_STATUS_FAILED); 1060 AbortRemoteSync(param.Pass(), fileapi::SYNC_STATUS_FAILED);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 1120
1088 DCHECK(param->remote_change.change.IsDelete()); 1121 DCHECK(param->remote_change.change.IsDelete());
1089 if (local_changes.empty()) { 1122 if (local_changes.empty()) {
1090 if (missing_local_file) { 1123 if (missing_local_file) {
1091 param->operation_type = fileapi::SYNC_OPERATION_NONE; 1124 param->operation_type = fileapi::SYNC_OPERATION_NONE;
1092 DeleteMetadataForRemoteSync(param.Pass()); 1125 DeleteMetadataForRemoteSync(param.Pass());
1093 return; 1126 return;
1094 } 1127 }
1095 DCHECK(!missing_local_file); 1128 DCHECK(!missing_local_file);
1096 param->operation_type = fileapi::SYNC_OPERATION_DELETE; 1129 param->operation_type = fileapi::SYNC_OPERATION_DELETE;
1130
1131 const fileapi::FileChange& file_change = param->remote_change.change;
1097 param->processor->ApplyRemoteChange( 1132 param->processor->ApplyRemoteChange(
1098 param->remote_change.change, FilePath(), url, 1133 file_change, FilePath(), url,
1099 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, AsWeakPtr(), 1134 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, AsWeakPtr(),
1100 base::Passed(&param))); 1135 base::Passed(&param)));
1101 return; 1136 return;
1102 } 1137 }
1103 1138
1104 DCHECK(!local_changes.empty()); 1139 DCHECK(!local_changes.empty());
1105 if (local_changes.list().back().IsAddOrUpdate()) { 1140 if (local_changes.list().back().IsAddOrUpdate()) {
1106 param->operation_type = fileapi::SYNC_OPERATION_NONE; 1141 param->operation_type = fileapi::SYNC_OPERATION_NONE;
1107 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); 1142 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK);
1108 return; 1143 return;
(...skipping 18 matching lines...) Expand all
1127 } 1162 }
1128 1163
1129 void DriveFileSyncService::DidGetTemporaryFileForDownload( 1164 void DriveFileSyncService::DidGetTemporaryFileForDownload(
1130 scoped_ptr<ProcessRemoteChangeParam> param, 1165 scoped_ptr<ProcessRemoteChangeParam> param,
1131 bool success) { 1166 bool success) {
1132 if (!success) { 1167 if (!success) {
1133 AbortRemoteSync(param.Pass(), fileapi::SYNC_FILE_ERROR_FAILED); 1168 AbortRemoteSync(param.Pass(), fileapi::SYNC_FILE_ERROR_FAILED);
1134 return; 1169 return;
1135 } 1170 }
1136 1171
1137 DriveMetadata metadata;
1138 metadata_store_->ReadEntry(param->remote_change.url, &metadata);
1139
1140 const FilePath& temporary_file_path = param->temporary_file_path; 1172 const FilePath& temporary_file_path = param->temporary_file_path;
1141 std::string resource_id = param->remote_change.resource_id; 1173 std::string resource_id = param->remote_change.resource_id;
1174 const DriveMetadata& drive_metadata = param->drive_metadata;
1142 sync_client_->DownloadFile( 1175 sync_client_->DownloadFile(
1143 resource_id, metadata.md5_checksum(), 1176 resource_id, drive_metadata.md5_checksum(),
1144 temporary_file_path, 1177 temporary_file_path,
1145 base::Bind(&DriveFileSyncService::DidDownloadFile, 1178 base::Bind(&DriveFileSyncService::DidDownloadFile,
1146 AsWeakPtr(), base::Passed(&param))); 1179 AsWeakPtr(), base::Passed(&param)));
1147 } 1180 }
1148 1181
1149 void DriveFileSyncService::DidDownloadFile( 1182 void DriveFileSyncService::DidDownloadFile(
1150 scoped_ptr<ProcessRemoteChangeParam> param, 1183 scoped_ptr<ProcessRemoteChangeParam> param,
1151 google_apis::GDataErrorCode error, 1184 google_apis::GDataErrorCode error,
1152 const std::string& md5_checksum) { 1185 const std::string& md5_checksum) {
1153 if (error == google_apis::HTTP_NOT_MODIFIED) { 1186 if (error == google_apis::HTTP_NOT_MODIFIED) {
1154 param->operation_type = fileapi::SYNC_OPERATION_NONE; 1187 param->operation_type = fileapi::SYNC_OPERATION_NONE;
1155 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK); 1188 CompleteRemoteSync(param.Pass(), fileapi::SYNC_STATUS_OK);
1156 return; 1189 return;
1157 } 1190 }
1158 1191
1159 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCodeWrapper(error); 1192 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCodeWrapper(error);
1160 if (status != fileapi::SYNC_STATUS_OK) { 1193 if (status != fileapi::SYNC_STATUS_OK) {
1161 AbortRemoteSync(param.Pass(), status); 1194 AbortRemoteSync(param.Pass(), status);
1162 return; 1195 return;
1163 } 1196 }
1164 1197
1165 param->md5_checksum = md5_checksum; 1198 param->drive_metadata.set_md5_checksum(md5_checksum);
1166 const fileapi::FileChange& change = param->remote_change.change; 1199 const fileapi::FileChange& change = param->remote_change.change;
1167 const FilePath& temporary_file_path = param->temporary_file_path; 1200 const FilePath& temporary_file_path = param->temporary_file_path;
1168 const fileapi::FileSystemURL& url = param->remote_change.url; 1201 const fileapi::FileSystemURL& url = param->remote_change.url;
1169 param->processor->ApplyRemoteChange( 1202 param->processor->ApplyRemoteChange(
1170 change, temporary_file_path, url, 1203 change, temporary_file_path, url,
1171 base::Bind(&DriveFileSyncService::DidApplyRemoteChange, 1204 base::Bind(&DriveFileSyncService::DidApplyRemoteChange,
1172 AsWeakPtr(), base::Passed(&param))); 1205 AsWeakPtr(), base::Passed(&param)));
1173 } 1206 }
1174 1207
1175 void DriveFileSyncService::DidApplyRemoteChange( 1208 void DriveFileSyncService::DidApplyRemoteChange(
1176 scoped_ptr<ProcessRemoteChangeParam> param, 1209 scoped_ptr<ProcessRemoteChangeParam> param,
1177 fileapi::SyncStatusCode status) { 1210 fileapi::SyncStatusCode status) {
1178 if (status != fileapi::SYNC_STATUS_OK) { 1211 if (status != fileapi::SYNC_STATUS_OK) {
1179 AbortRemoteSync(param.Pass(), status); 1212 AbortRemoteSync(param.Pass(), status);
1180 return; 1213 return;
1181 } 1214 }
1182 1215
1183 fileapi::FileSystemURL url = param->remote_change.url; 1216 fileapi::FileSystemURL url = param->remote_change.url;
1184 if (param->remote_change.change.IsDelete()) { 1217 if (param->remote_change.change.IsDelete()) {
1185 DeleteMetadataForRemoteSync(param.Pass()); 1218 DeleteMetadataForRemoteSync(param.Pass());
1186 return; 1219 return;
1187 } 1220 }
1188 1221
1189 DriveMetadata metadata; 1222 const DriveMetadata& drive_metadata = param->drive_metadata;
1190 metadata.set_resource_id(param->remote_change.resource_id); 1223 param->drive_metadata.set_resource_id(param->remote_change.resource_id);
1191 metadata.set_md5_checksum(param->md5_checksum); 1224 param->drive_metadata.set_conflicted(false);
1192 metadata.set_conflicted(false);
1193 1225
1194 metadata_store_->UpdateEntry( 1226 metadata_store_->UpdateEntry(
1195 url, metadata, 1227 url, drive_metadata,
1196 base::Bind(&DriveFileSyncService::CompleteRemoteSync, 1228 base::Bind(&DriveFileSyncService::CompleteRemoteSync,
1197 AsWeakPtr(), base::Passed(&param))); 1229 AsWeakPtr(), base::Passed(&param)));
1198 } 1230 }
1199 1231
1200 void DriveFileSyncService::DeleteMetadataForRemoteSync( 1232 void DriveFileSyncService::DeleteMetadataForRemoteSync(
1201 scoped_ptr<ProcessRemoteChangeParam> param) { 1233 scoped_ptr<ProcessRemoteChangeParam> param) {
1202 fileapi::FileSystemURL url = param->remote_change.url; 1234 fileapi::FileSystemURL url = param->remote_change.url;
1203 metadata_store_->DeleteEntry( 1235 metadata_store_->DeleteEntry(
1204 url, 1236 url,
1205 base::Bind(&DriveFileSyncService::CompleteRemoteSync, 1237 base::Bind(&DriveFileSyncService::CompleteRemoteSync,
1206 AsWeakPtr(), base::Passed(&param))); 1238 AsWeakPtr(), base::Passed(&param)));
1207 } 1239 }
1208 1240
1209 void DriveFileSyncService::CompleteRemoteSync( 1241 void DriveFileSyncService::CompleteRemoteSync(
1210 scoped_ptr<ProcessRemoteChangeParam> param, 1242 scoped_ptr<ProcessRemoteChangeParam> param,
1211 fileapi::SyncStatusCode status) { 1243 fileapi::SyncStatusCode status) {
1212 if (status != fileapi::SYNC_STATUS_OK) { 1244 if (status != fileapi::SYNC_STATUS_OK) {
1213 AbortRemoteSync(param.Pass(), status); 1245 AbortRemoteSync(param.Pass(), status);
1214 return; 1246 return;
1215 } 1247 }
1216 1248
1217 CancelRemoteChange(param->remote_change.url); 1249 RemoveRemoteChange(param->remote_change.url);
1218 1250
1219 GURL origin = param->remote_change.url.origin(); 1251 GURL origin = param->remote_change.url.origin();
1220 if (metadata_store_->IsIncrementalSyncOrigin(origin)) { 1252 if (metadata_store_->IsIncrementalSyncOrigin(origin)) {
1221 int64 changestamp = param->remote_change.changestamp; 1253 int64 changestamp = param->remote_change.changestamp;
1222 metadata_store_->SetLargestChangeStamp( 1254 metadata_store_->SetLargestChangeStamp(
1223 changestamp, 1255 changestamp,
1224 base::Bind(&DriveFileSyncService::FinalizeRemoteSync, 1256 base::Bind(&DriveFileSyncService::FinalizeRemoteSync,
1225 AsWeakPtr(), base::Passed(&param))); 1257 AsWeakPtr(), base::Passed(&param)));
1226 return; 1258 return;
1227 } 1259 }
(...skipping 20 matching lines...) Expand all
1248 param->callback.Run(status, param->remote_change.url, 1280 param->callback.Run(status, param->remote_change.url,
1249 param->operation_type); 1281 param->operation_type);
1250 } else { 1282 } else {
1251 param->callback.Run(status, param->remote_change.url, 1283 param->callback.Run(status, param->remote_change.url,
1252 fileapi::SYNC_OPERATION_NONE); 1284 fileapi::SYNC_OPERATION_NONE);
1253 } 1285 }
1254 } 1286 }
1255 1287
1256 void DriveFileSyncService::AppendNewRemoteChange( 1288 void DriveFileSyncService::AppendNewRemoteChange(
1257 const GURL& origin, 1289 const GURL& origin,
1258 google_apis::DocumentEntry* entry, 1290 const google_apis::DocumentEntry& entry,
1259 int64 changestamp, 1291 int64 changestamp,
1260 RemoteSyncType sync_type) { 1292 RemoteSyncType sync_type) {
1261 // TODO(tzik): Normalize the path here. 1293 // TODO(tzik): Normalize the path here.
1262 FilePath path = FilePath::FromUTF8Unsafe(UTF16ToUTF8(entry->title())); 1294 FilePath path = FilePath::FromUTF8Unsafe(UTF16ToUTF8(entry.title()));
1263 1295
1264 PathToChange* path_to_change = &url_to_change_[origin]; 1296 PathToChange* path_to_change = &url_to_change_[origin];
1265 PathToChange::iterator found = path_to_change->find(path); 1297 PathToChange::iterator found = path_to_change->find(path);
1266 if (found != path_to_change->end()) { 1298 if (found != path_to_change->end()) {
1267 if (found->second.changestamp >= changestamp) 1299 if (found->second.changestamp >= changestamp)
1268 return; 1300 return;
1269 pending_changes_.erase(found->second.position_in_queue); 1301 pending_changes_.erase(found->second.position_in_queue);
1270 } 1302 }
1271 1303
1272 fileapi::FileSystemURL url( 1304 fileapi::FileSystemURL url(
1273 fileapi::CreateSyncableFileSystemURL(origin, kServiceName, path)); 1305 fileapi::CreateSyncableFileSystemURL(origin, kServiceName, path));
1274 1306
1275 fileapi::FileChange::ChangeType change_type; 1307 fileapi::FileChange::ChangeType change_type;
1276 fileapi::SyncFileType file_type; 1308 fileapi::SyncFileType file_type;
1277 if (entry->deleted()) { 1309 if (entry.deleted()) {
1278 change_type = fileapi::FileChange::FILE_CHANGE_DELETE; 1310 change_type = fileapi::FileChange::FILE_CHANGE_DELETE;
1279 file_type = fileapi::SYNC_FILE_TYPE_UNKNOWN; 1311 file_type = fileapi::SYNC_FILE_TYPE_UNKNOWN;
1280 } else { 1312 } else {
1281 change_type = fileapi::FileChange::FILE_CHANGE_ADD_OR_UPDATE; 1313 change_type = fileapi::FileChange::FILE_CHANGE_ADD_OR_UPDATE;
1282 if (entry->kind() == google_apis::ENTRY_KIND_FOLDER) 1314 if (entry.is_folder())
1283 file_type = fileapi::SYNC_FILE_TYPE_DIRECTORY; 1315 file_type = fileapi::SYNC_FILE_TYPE_DIRECTORY;
1284 else 1316 else
1285 file_type = fileapi::SYNC_FILE_TYPE_FILE; 1317 file_type = fileapi::SYNC_FILE_TYPE_FILE;
1286 } 1318 }
1287 1319
1288 fileapi::FileChange file_change(change_type, file_type); 1320 fileapi::FileChange file_change(change_type, file_type);
1289 1321
1290 std::pair<PendingChangeQueue::iterator, bool> inserted_to_queue = 1322 std::pair<PendingChangeQueue::iterator, bool> inserted_to_queue =
1291 pending_changes_.insert(ChangeQueueItem(changestamp, sync_type, url)); 1323 pending_changes_.insert(ChangeQueueItem(changestamp, sync_type, url));
1292 DCHECK(inserted_to_queue.second); 1324 DCHECK(inserted_to_queue.second);
1293 1325
1294 (*path_to_change)[path] = RemoteChange( 1326 (*path_to_change)[path] = RemoteChange(
1295 changestamp, entry->resource_id(), url, file_change, 1327 changestamp, entry.resource_id(), url, file_change,
1296 inserted_to_queue.first); 1328 inserted_to_queue.first);
1297 } 1329 }
1298 1330
1299 void DriveFileSyncService::CancelRemoteChange( 1331 void DriveFileSyncService::RemoveRemoteChange(
1300 const fileapi::FileSystemURL& url) { 1332 const fileapi::FileSystemURL& url) {
1301 URLToChange::iterator found_origin = url_to_change_.find(url.origin()); 1333 URLToChange::iterator found_origin = url_to_change_.find(url.origin());
1302 if (found_origin == url_to_change_.end()) 1334 if (found_origin == url_to_change_.end())
1303 return; 1335 return;
1304 1336
1305 PathToChange* path_to_change = &found_origin->second; 1337 PathToChange* path_to_change = &found_origin->second;
1306 PathToChange::iterator found_change = path_to_change->find(url.path()); 1338 PathToChange::iterator found_change = path_to_change->find(url.path());
1307 if (found_change == path_to_change->end()) 1339 if (found_change == path_to_change->end())
1308 return; 1340 return;
1309 1341
1310 pending_changes_.erase(found_change->second.position_in_queue); 1342 pending_changes_.erase(found_change->second.position_in_queue);
1311 path_to_change->erase(found_change); 1343 path_to_change->erase(found_change);
1312 if (path_to_change->empty()) 1344 if (path_to_change->empty())
1313 url_to_change_.erase(found_origin); 1345 url_to_change_.erase(found_origin);
1314 1346
1315 MaybeMarkAsIncrementalSyncOrigin(url.origin()); 1347 if (metadata_store_->IsBatchSyncOrigin(url.origin()) &&
1316 } 1348 !ContainsKey(url_to_change_, url.origin())) {
1317 1349 metadata_store_->MoveBatchSyncOriginToIncremental(url.origin());
1318 void DriveFileSyncService::MaybeMarkAsIncrementalSyncOrigin( 1350 }
1319 const GURL& origin) {
1320 if (metadata_store_->IsBatchSyncOrigin(origin) &&
1321 !ContainsKey(url_to_change_, origin))
1322 metadata_store_->MoveBatchSyncOriginToIncremental(origin);
1323 } 1351 }
1324 1352
1325 bool DriveFileSyncService::GetPendingChangeForFileSystemURL( 1353 bool DriveFileSyncService::GetPendingChangeForFileSystemURL(
1326 const fileapi::FileSystemURL& url, 1354 const fileapi::FileSystemURL& url,
1327 RemoteChange* change) const { 1355 RemoteChange* change) const {
1328 DCHECK(change); 1356 DCHECK(change);
1329 URLToChange::const_iterator found_url = url_to_change_.find(url.origin()); 1357 URLToChange::const_iterator found_url = url_to_change_.find(url.origin());
1330 if (found_url == url_to_change_.end()) 1358 if (found_url == url_to_change_.end())
1331 return false; 1359 return false;
1332 const PathToChange& path_to_change = found_url->second; 1360 const PathToChange& path_to_change = found_url->second;
1333 PathToChange::const_iterator found_path = path_to_change.find(url.path()); 1361 PathToChange::const_iterator found_path = path_to_change.find(url.path());
1334 if (found_path == path_to_change.end()) 1362 if (found_path == path_to_change.end())
1335 return false; 1363 return false;
1336 *change = found_path->second; 1364 *change = found_path->second;
1337 return true; 1365 return true;
1338 } 1366 }
1339 1367
1368 void DriveFileSyncService::FetchChangesForIncrementalSync() {
1369 scoped_ptr<TaskToken> token(GetToken(FROM_HERE, TASK_TYPE_DRIVE,
1370 "Fetching remote change list"));
1371 if (!token) {
1372 pending_tasks_.push_back(base::Bind(
1373 &DriveFileSyncService::FetchChangesForIncrementalSync, AsWeakPtr()));
1374 return;
1375 }
1376
1377 if (metadata_store_->incremental_sync_origins().empty()) {
1378 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass());
1379 return;
1380 }
1381
1382 sync_client_->ListChanges(
1383 largest_fetched_changestamp_,
1384 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync,
1385 AsWeakPtr(), base::Passed(&token)));
1386 }
1387
1388 void DriveFileSyncService::DidFetchChangesForIncrementalSync(
1389 scoped_ptr<TaskToken> token,
1390 google_apis::GDataErrorCode error,
1391 scoped_ptr<google_apis::DocumentFeed> changes) {
1392 if (error != google_apis::HTTP_SUCCESS) {
1393 NotifyTaskDone(fileapi::SYNC_STATUS_FAILED, token.Pass());
1394 return;
1395 }
1396
1397 typedef ScopedVector<google_apis::DocumentEntry>::const_iterator iterator;
1398 for (iterator itr = changes->entries().begin();
1399 itr != changes->entries().end(); ++itr) {
1400 const google_apis::DocumentEntry& entry = **itr;
1401 GURL origin;
1402 if (!GetOriginForEntry(entry, &origin))
1403 continue;
1404
1405 AppendNewRemoteChange(origin, entry, entry.changestamp(),
1406 REMOTE_SYNC_TYPE_INCREMENTAL);
1407 }
1408
1409 GURL next_feed;
1410 if (changes->GetNextFeedURL(&next_feed)) {
1411 sync_client_->ContinueListing(
1412 next_feed,
1413 base::Bind(&DriveFileSyncService::DidFetchChangesForIncrementalSync,
1414 AsWeakPtr(), base::Passed(&token)));
1415 return;
1416 }
1417
1418 largest_fetched_changestamp_ = changes->largest_changestamp();
1419
1420 if (changes->start_index() == 0 && changes->entries().empty()) {
1421 // If this set of changes is the first feed and it's empty, update
1422 // the polling delay to wait longer.
1423 base::TimeDelta max_delay(
1424 base::TimeDelta::FromSeconds(kMaximumPollingDelaySeconds));
1425
1426 polling_delay_ = base::TimeDelta::FromInternalValue(static_cast<int64>(
1427 kDelayMultiplier * polling_delay_.ToInternalValue()));
1428 if (polling_delay_ >= max_delay)
1429 polling_delay_ = max_delay;
1430 } else {
1431 polling_delay_ = base::TimeDelta::FromSeconds(
1432 kMinimumPollingDelaySeconds);
1433 }
1434
1435 NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass());
1436 }
1437
1438 bool DriveFileSyncService::GetOriginForEntry(
1439 const google_apis::DocumentEntry& entry,
1440 GURL* origin_out) {
1441 typedef ScopedVector<google_apis::Link>::const_iterator iterator;
1442 for (iterator itr = entry.links().begin();
1443 itr != entry.links().end(); ++itr) {
1444 if ((*itr)->type() != google_apis::Link::LINK_PARENT)
1445 continue;
1446 GURL origin(UTF16ToUTF8((*itr)->title()));
1447 if (!origin.is_valid())
1448 continue;
1449
1450 if (!metadata_store_->IsBatchSyncOrigin(origin) &&
1451 !metadata_store_->IsIncrementalSyncOrigin(origin))
1452 continue;
1453 std::string resource_id(metadata_store_->GetResourceIdForOrigin(origin));
1454 GURL resource_link(sync_client_->ResourceIdToResourceLink(resource_id));
1455 if ((*itr)->href().GetOrigin() != resource_link.GetOrigin() ||
1456 (*itr)->href().path() != resource_link.path())
1457 continue;
1458
1459 *origin_out = origin;
1460 return true;
1461 }
1462 return false;
1463 }
1464
1465 void DriveFileSyncService::SchedulePolling() {
1466 if (polling_timer_.IsRunning())
1467 return;
1468
1469 DVLOG(1) << "Polling scheduled"
1470 << " (delay:" << polling_delay_.InSeconds() << ")";
1471
1472 polling_timer_.Start(
1473 FROM_HERE, polling_delay_,
1474 base::Bind(&DriveFileSyncService::FetchChangesForIncrementalSync,
1475 AsWeakPtr()));
1476 }
1477
1340 fileapi::SyncStatusCode 1478 fileapi::SyncStatusCode
1341 DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper( 1479 DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper(
1342 google_apis::GDataErrorCode error) const { 1480 google_apis::GDataErrorCode error) const {
1343 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); 1481 fileapi::SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error);
1344 if (status != fileapi::SYNC_STATUS_OK && !sync_client_->IsAuthenticated()) 1482 if (status != fileapi::SYNC_STATUS_OK && !sync_client_->IsAuthenticated())
1345 return fileapi::SYNC_STATUS_AUTHENTICATION_FAILED; 1483 return fileapi::SYNC_STATUS_AUTHENTICATION_FAILED;
1346 return status; 1484 return status;
1347 } 1485 }
1348 1486
1349 } // namespace sync_file_system 1487 } // namespace sync_file_system
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698