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

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: '' 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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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 &param->drive_metadata); 1032 &param->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
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(&param))); 1124 base::Passed(&param)));
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
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(&param))); 1168 AsWeakPtr(), base::Passed(&param)));
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(&param))); 1194 AsWeakPtr(), base::Passed(&param)));
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(&param))); 1218 AsWeakPtr(), base::Passed(&param)));
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(&param))); 1227 AsWeakPtr(), base::Passed(&param)));
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(&param))); 1246 AsWeakPtr(), base::Passed(&param)));
1215 return; 1247 return;
1216 } 1248 }
(...skipping 20 matching lines...) Expand all
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698