Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sync_file_system/drive_file_sync_service.h" | 5 #include "chrome/browser/sync_file_system/drive_file_sync_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
| 14 #include "base/message_loop_proxy.h" | 14 #include "base/message_loop_proxy.h" |
| 15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 16 #include "base/values.h" | 16 #include "base/values.h" |
| 17 #include "chrome/browser/google_apis/gdata_wapi_service.h" | 17 #include "chrome/browser/google_apis/gdata_wapi_service.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/sync_file_system/drive_file_sync_client.h" | 19 #include "chrome/browser/sync_file_system/drive_file_sync_client.h" |
| 20 #include "chrome/browser/sync_file_system/drive_file_sync_util.h" | 20 #include "chrome/browser/sync_file_system/drive_file_sync_util.h" |
| 21 #include "chrome/browser/sync_file_system/drive_metadata_store.h" | 21 #include "chrome/browser/sync_file_system/drive_metadata_store.h" |
| 22 #include "chrome/browser/sync_file_system/remote_change_processor.h" | 22 #include "chrome/browser/sync_file_system/remote_change_processor.h" |
| 23 #include "chrome/browser/sync_file_system/sync_file_system.pb.h" | 23 #include "chrome/browser/sync_file_system/sync_file_system.pb.h" |
| 24 #include "chrome/common/extensions/extension.h" | |
| 24 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| 25 #include "net/base/escape.h" | 26 #include "extensions/common/constants.h" |
| 26 #include "webkit/fileapi/file_system_url.h" | 27 #include "webkit/fileapi/file_system_url.h" |
| 27 #include "webkit/fileapi/syncable/sync_file_metadata.h" | 28 #include "webkit/fileapi/syncable/sync_file_metadata.h" |
| 28 #include "webkit/fileapi/syncable/sync_file_type.h" | 29 #include "webkit/fileapi/syncable/sync_file_type.h" |
| 29 #include "webkit/fileapi/syncable/syncable_file_system_util.h" | 30 #include "webkit/fileapi/syncable/syncable_file_system_util.h" |
| 30 | 31 |
| 31 namespace sync_file_system { | 32 namespace sync_file_system { |
| 32 | 33 |
| 33 namespace { | 34 namespace { |
| 34 | 35 |
| 35 const FilePath::CharType kTempDirName[] = FILE_PATH_LITERAL("tmp"); | 36 const FilePath::CharType kTempDirName[] = FILE_PATH_LITERAL("tmp"); |
| 36 const FilePath::CharType kSyncFileSystemDir[] = | 37 const FilePath::CharType kSyncFileSystemDir[] = |
| 37 FILE_PATH_LITERAL("Sync FileSystem"); | 38 FILE_PATH_LITERAL("Sync FileSystem"); |
| 39 const int64 kMinimumPollingDelaySeconds = 10; | |
| 40 const int64 kMaximumPollingDelaySeconds = 60 * 60; // 1 hour | |
| 41 const double kDelayMultiplier = 2; | |
| 38 | 42 |
| 39 bool CreateTemporaryFile(const FilePath& dir_path, FilePath* temp_file) { | 43 bool CreateTemporaryFile(const FilePath& dir_path, FilePath* temp_file) { |
| 40 return file_util::CreateDirectory(dir_path) && | 44 return file_util::CreateDirectory(dir_path) && |
| 41 file_util::CreateTemporaryFileInDir(dir_path, temp_file); | 45 file_util::CreateTemporaryFileInDir(dir_path, temp_file); |
| 42 } | 46 } |
| 43 | 47 |
| 44 void DeleteTemporaryFile(const FilePath& file_path) { | 48 void DeleteTemporaryFile(const FilePath& file_path) { |
| 45 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) { | 49 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) { |
| 46 content::BrowserThread::PostTask( | 50 content::BrowserThread::PostTask( |
| 47 content::BrowserThread::FILE, FROM_HERE, | 51 content::BrowserThread::FILE, FROM_HERE, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 TaskType task_type() const { return task_type_; } | 96 TaskType task_type() const { return task_type_; } |
| 93 const std::string& description() const { return description_; } | 97 const std::string& description() const { return description_; } |
| 94 std::string done_description() const { return description_ + " done"; } | 98 std::string done_description() const { return description_ + " done"; } |
| 95 | 99 |
| 96 ~TaskToken() { | 100 ~TaskToken() { |
| 97 // All task on DriveFileSyncService must hold TaskToken instance to ensure | 101 // All task on DriveFileSyncService must hold TaskToken instance to ensure |
| 98 // no other tasks are running. Also, as soon as a task finishes to work, | 102 // no other tasks are running. Also, as soon as a task finishes to work, |
| 99 // it must return the token to DriveFileSyncService. | 103 // it must return the token to DriveFileSyncService. |
| 100 // Destroying a token with valid |sync_service_| indicates the token was | 104 // Destroying a token with valid |sync_service_| indicates the token was |
| 101 // dropped by a task without returning. | 105 // dropped by a task without returning. |
| 102 DCHECK(!sync_service_); | |
| 103 if (sync_service_) { | 106 if (sync_service_) { |
| 104 LOG(ERROR) << "Unexpected TaskToken deletion from: " | 107 LOG(ERROR) << "Unexpected TaskToken deletion from: " |
| 105 << location_.ToString() << " while: " << description_; | 108 << location_.ToString() << " while: " << description_; |
| 106 } | 109 } |
| 110 DCHECK(!sync_service_); | |
| 107 } | 111 } |
| 108 | 112 |
| 109 private: | 113 private: |
| 110 base::WeakPtr<DriveFileSyncService> sync_service_; | 114 base::WeakPtr<DriveFileSyncService> sync_service_; |
| 111 tracked_objects::Location location_; | 115 tracked_objects::Location location_; |
| 112 TaskType task_type_; | 116 TaskType task_type_; |
| 113 std::string description_; | 117 std::string description_; |
| 114 | 118 |
| 115 DISALLOW_COPY_AND_ASSIGN(TaskToken); | 119 DISALLOW_COPY_AND_ASSIGN(TaskToken); |
| 116 }; | 120 }; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 195 // Smaller changestamps have higher priorities (i.e. need to be processed | 199 // Smaller changestamps have higher priorities (i.e. need to be processed |
| 196 // earlier). | 200 // earlier). |
| 197 if (left.changestamp != right.changestamp) | 201 if (left.changestamp != right.changestamp) |
| 198 return left.changestamp > right.changestamp; | 202 return left.changestamp > right.changestamp; |
| 199 return false; | 203 return false; |
| 200 } | 204 } |
| 201 | 205 |
| 202 DriveFileSyncService::DriveFileSyncService(Profile* profile) | 206 DriveFileSyncService::DriveFileSyncService(Profile* profile) |
| 203 : last_operation_status_(fileapi::SYNC_STATUS_OK), | 207 : last_operation_status_(fileapi::SYNC_STATUS_OK), |
| 204 state_(REMOTE_SERVICE_OK), | 208 state_(REMOTE_SERVICE_OK), |
| 205 largest_changestamp_(0), | 209 largest_fetched_changestamp_(0), |
| 210 polling_delay_(base::TimeDelta::FromSeconds(kMinimumPollingDelaySeconds)), | |
| 211 polling_enabled_(true), | |
| 206 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 212 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 207 temporary_file_dir_ = | 213 temporary_file_dir_ = |
| 208 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); | 214 profile->GetPath().Append(kSyncFileSystemDir).Append(kTempDirName); |
| 209 token_.reset(new TaskToken(AsWeakPtr())); | 215 token_.reset(new TaskToken(AsWeakPtr())); |
| 210 | 216 |
| 211 sync_client_.reset(new DriveFileSyncClient(profile)); | 217 sync_client_.reset(new DriveFileSyncClient(profile)); |
| 212 | 218 |
| 213 metadata_store_.reset(new DriveMetadataStore( | 219 metadata_store_.reset(new DriveMetadataStore( |
| 214 profile->GetPath().Append(kSyncFileSystemDir), | 220 profile->GetPath().Append(kSyncFileSystemDir), |
| 215 content::BrowserThread::GetMessageLoopProxyForThread( | 221 content::BrowserThread::GetMessageLoopProxyForThread( |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 241 observers_.AddObserver(observer); | 247 observers_.AddObserver(observer); |
| 242 } | 248 } |
| 243 | 249 |
| 244 void DriveFileSyncService::RemoveObserver(Observer* observer) { | 250 void DriveFileSyncService::RemoveObserver(Observer* observer) { |
| 245 observers_.RemoveObserver(observer); | 251 observers_.RemoveObserver(observer); |
| 246 } | 252 } |
| 247 | 253 |
| 248 void DriveFileSyncService::RegisterOriginForTrackingChanges( | 254 void DriveFileSyncService::RegisterOriginForTrackingChanges( |
| 249 const GURL& origin, | 255 const GURL& origin, |
| 250 const fileapi::SyncStatusCallback& callback) { | 256 const fileapi::SyncStatusCallback& callback) { |
| 257 DCHECK(origin.SchemeIs(extensions::kExtensionScheme)); | |
| 251 scoped_ptr<TaskToken> token(GetToken( | 258 scoped_ptr<TaskToken> token(GetToken( |
| 252 FROM_HERE, TASK_TYPE_DRIVE, "Retrieving origin metadata")); | 259 FROM_HERE, TASK_TYPE_DRIVE, "Retrieving origin metadata")); |
| 253 if (!token) { | 260 if (!token) { |
| 254 pending_tasks_.push_back(base::Bind( | 261 pending_tasks_.push_back(base::Bind( |
| 255 &DriveFileSyncService::RegisterOriginForTrackingChanges, | 262 &DriveFileSyncService::RegisterOriginForTrackingChanges, |
| 256 AsWeakPtr(), origin, callback)); | 263 AsWeakPtr(), origin, callback)); |
| 257 return; | 264 return; |
| 258 } | 265 } |
| 259 | 266 |
| 260 if (state_ == REMOTE_SERVICE_DISABLED) { | 267 if (state_ == REMOTE_SERVICE_DISABLED) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 ¶m->drive_metadata); | 1043 ¶m->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 Loading... | |
| 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(¶m))); | 1135 base::Passed(¶m))); |
| 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 Loading... | |
| 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(¶m))); | 1179 AsWeakPtr(), base::Passed(¶m))); |
| 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(¶m))); | 1205 AsWeakPtr(), base::Passed(¶m))); |
| 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(¶m))); | 1229 AsWeakPtr(), base::Passed(¶m))); |
| 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(¶m))); | 1238 AsWeakPtr(), base::Passed(¶m))); |
| 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(¶m))); | 1257 AsWeakPtr(), base::Passed(¶m))); |
| 1226 return; | 1258 return; |
| 1227 } | 1259 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 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 |
| OLD | NEW |