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

Unified Diff: chrome/browser/sync_file_system/drive_file_sync_service.cc

Issue 11299008: Remote service state handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 8 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/sync_file_system/drive_file_sync_service.cc
diff --git a/chrome/browser/sync_file_system/drive_file_sync_service.cc b/chrome/browser/sync_file_system/drive_file_sync_service.cc
index da61e9ad3114ab98a058138a31f42fcf2c9a6e46..6e60df465dceb37a25199e09d37a76233f643932 100644
--- a/chrome/browser/sync_file_system/drive_file_sync_service.cc
+++ b/chrome/browser/sync_file_system/drive_file_sync_service.cc
@@ -30,13 +30,28 @@ const char DriveFileSyncService::kServiceName[] = "drive";
class DriveFileSyncService::TaskToken {
public:
explicit TaskToken(const base::WeakPtr<DriveFileSyncService>& sync_service)
- : sync_service_(sync_service) {
+ : sync_service_(sync_service),
+ task_type_(TASK_TYPE_NONE) {
}
- void set_location(const tracked_objects::Location& from_here) {
- from_here_ = from_here;
+ void ResetTask(const tracked_objects::Location& location) {
+ location_ = location;
+ task_type_ = TASK_TYPE_NONE;
+ description_.clear();
}
+ void UpdateTask(const tracked_objects::Location& location,
+ TaskType task_type,
+ const std::string& description) {
+ location_ = location;
+ task_type_ = task_type;
+ description_ = description;
+ }
+
+ const tracked_objects::Location& location() const { return location_; }
+ TaskType task_type() const { return task_type_; }
+ const std::string& description() const { return description_; }
+
~TaskToken() {
// All task on DriveFileSyncService must hold TaskToken instance to ensure
// no other tasks are running. Also, as soon as a task finishes to work,
@@ -46,18 +61,19 @@ class DriveFileSyncService::TaskToken {
DCHECK(!sync_service_);
if (sync_service_) {
LOG(ERROR) << "Unexpected TaskToken deletion from: "
- << from_here_.ToString();
+ << location_.ToString() << " while: " << description_;
}
}
private:
- tracked_objects::Location from_here_;
base::WeakPtr<DriveFileSyncService> sync_service_;
+ tracked_objects::Location location_;
+ TaskType task_type_;
+ std::string description_;
DISALLOW_COPY_AND_ASSIGN(TaskToken);
};
-
DriveFileSyncService::RemoteChange::RemoteChange()
: changestamp(0),
change(fileapi::FileChange::FILE_CHANGE_ADD_OR_UPDATE,
@@ -89,23 +105,9 @@ bool DriveFileSyncService::RemoteChangeComparator::operator()(
return false;
}
-// Called by CreateForTesting.
-DriveFileSyncService::DriveFileSyncService(
- scoped_ptr<DriveFileSyncClient> sync_client,
- scoped_ptr<DriveMetadataStore> metadata_store)
- : status_(fileapi::SYNC_STATUS_OK),
- largest_changestamp_(0),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
- token_.reset(new TaskToken(weak_factory_.GetWeakPtr()));
- sync_client_ = sync_client.Pass();
- metadata_store_ = metadata_store.Pass();
-
- DidInitializeMetadataStore(GetToken(FROM_HERE),
- fileapi::SYNC_STATUS_OK, false);
-}
-
DriveFileSyncService::DriveFileSyncService(Profile* profile)
- : status_(fileapi::SYNC_STATUS_OK),
+ : last_operation_status_(fileapi::SYNC_STATUS_OK),
+ state_(REMOTE_SERVICE_OK),
largest_changestamp_(0),
weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
token_.reset(new TaskToken(weak_factory_.GetWeakPtr()));
@@ -120,7 +122,8 @@ DriveFileSyncService::DriveFileSyncService(Profile* profile)
metadata_store_->Initialize(
base::Bind(&DriveFileSyncService::DidInitializeMetadataStore,
weak_factory_.GetWeakPtr(),
- base::Passed(GetToken(FROM_HERE))));
+ base::Passed(GetToken(FROM_HERE, TASK_TYPE_DATABASE,
+ "Metadata database initialization"))));
}
DriveFileSyncService::~DriveFileSyncService() {
@@ -145,7 +148,8 @@ void DriveFileSyncService::RemoveObserver(Observer* observer) {
void DriveFileSyncService::RegisterOriginForTrackingChanges(
const GURL& origin,
const fileapi::SyncStatusCallback& callback) {
- scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
+ scoped_ptr<TaskToken> token(GetToken(
+ FROM_HERE, TASK_TYPE_DRIVE, "Retrieving origin metadata"));
if (!token) {
pending_tasks_.push_back(base::Bind(
&DriveFileSyncService::RegisterOriginForTrackingChanges,
@@ -153,14 +157,16 @@ void DriveFileSyncService::RegisterOriginForTrackingChanges(
return;
}
- if (status_ != fileapi::SYNC_STATUS_OK) {
- NotifyTaskDone(status_, token.Pass());
- callback.Run(status_);
+ if (state_ == REMOTE_SERVICE_DISABLED) {
+ token->ResetTask(FROM_HERE);
+ NotifyTaskDone(last_operation_status_, token.Pass());
+ callback.Run(last_operation_status_);
return;
}
if (metadata_store_->IsIncrementalSyncOrigin(origin) ||
metadata_store_->IsBatchSyncOrigin(origin)) {
+ token->ResetTask(FROM_HERE);
NotifyTaskDone(fileapi::SYNC_STATUS_OK, token.Pass());
callback.Run(fileapi::SYNC_STATUS_OK);
return;
@@ -177,7 +183,7 @@ void DriveFileSyncService::RegisterOriginForTrackingChanges(
void DriveFileSyncService::UnregisterOriginForTrackingChanges(
const GURL& origin,
const fileapi::SyncStatusCallback& callback) {
- scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
+ scoped_ptr<TaskToken> token(GetToken(FROM_HERE, TASK_TYPE_DATABASE, ""));
if (!token) {
pending_tasks_.push_back(base::Bind(
&DriveFileSyncService::UnregisterOriginForTrackingChanges,
@@ -237,31 +243,104 @@ void DriveFileSyncService::ApplyLocalChange(
callback.Run(fileapi::SYNC_STATUS_FAILED);
}
+// Called by CreateForTesting.
+DriveFileSyncService::DriveFileSyncService(
+ scoped_ptr<DriveFileSyncClient> sync_client,
+ scoped_ptr<DriveMetadataStore> metadata_store)
+ : last_operation_status_(fileapi::SYNC_STATUS_OK),
+ state_(REMOTE_SERVICE_OK),
+ largest_changestamp_(0),
+ weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ token_.reset(new TaskToken(weak_factory_.GetWeakPtr()));
+ sync_client_ = sync_client.Pass();
+ metadata_store_ = metadata_store.Pass();
+
+ DidInitializeMetadataStore(
+ GetToken(FROM_HERE, TASK_TYPE_NONE, "Drive initialization for testing"),
+ fileapi::SYNC_STATUS_OK, false);
+}
+
scoped_ptr<DriveFileSyncService::TaskToken> DriveFileSyncService::GetToken(
- const tracked_objects::Location& from_here) {
+ const tracked_objects::Location& from_here,
+ TaskType task_type,
+ const std::string& description) {
if (!token_)
return scoped_ptr<TaskToken>();
- token_->set_location(from_here);
+ token_->UpdateTask(from_here, task_type, description);
return token_.Pass();
}
void DriveFileSyncService::NotifyTaskDone(fileapi::SyncStatusCode status,
scoped_ptr<TaskToken> token) {
DCHECK(token);
- bool status_changed = status_ != status;
- status_ = status;
+ last_operation_status_ = status;
token_ = token.Pass();
- token_->set_location(tracked_objects::Location());
+ if (token_->task_type() != TASK_TYPE_NONE) {
+ RemoteServiceState old_state = state_;
+ UpdateServiceState();
+
+ // Notify remote sync service state for healthy running updates (OK to OK
+ // state transition) and for any state changes.
+ if ((state_ == REMOTE_SERVICE_OK && !token_->description().empty()) ||
+ old_state != state_) {
+ FOR_EACH_OBSERVER(Observer, observers_,
+ OnRemoteServiceStateUpdated(state_,
+ token_->description()));
+ }
+ }
+
+ token_->ResetTask(FROM_HERE);
if (status == fileapi::SYNC_STATUS_OK && !pending_tasks_.empty()) {
base::Closure closure = pending_tasks_.front();
pending_tasks_.pop_front();
closure.Run();
}
+}
- if (status_changed) {
- // TODO(tzik): Refine the status to track the error.
- FOR_EACH_OBSERVER(Observer, observers_, OnRemoteSyncStatusChanged(status));
+void DriveFileSyncService::UpdateServiceState() {
+ switch (last_operation_status_) {
+ // Possible regular operation errors.
+ case fileapi::SYNC_STATUS_OK:
+ case fileapi::SYNC_STATUS_FILE_BUSY:
+ case fileapi::SYNC_STATUS_HAS_CONFLICT:
+ case fileapi::SYNC_STATUS_NOT_A_CONFLICT:
+ case fileapi::SYNC_STATUS_NO_CHANGE_TO_SYNC:
+ case fileapi::SYNC_FILE_ERROR_NOT_FOUND:
+ case fileapi::SYNC_FILE_ERROR_FAILED:
+ case fileapi::SYNC_FILE_ERROR_NO_SPACE:
+ // If the service type was DRIVE and the status was ok, the state
+ // should be migrated to OK state.
+ if (token_->task_type() == TASK_TYPE_DRIVE)
+ state_ = REMOTE_SERVICE_OK;
+ break;
+
+ // Authentication error.
+ case fileapi::SYNC_STATUS_AUTHENTICATION_FAILED:
+ state_ = REMOTE_SERVICE_AUTHENTICATION_REQUIRED;
+ break;
+
+ // Errors which could make the service temporarily unavailable.
+ case fileapi::SYNC_STATUS_RETRY:
+ case fileapi::SYNC_STATUS_NETWORK_ERROR:
+ state_ = REMOTE_SERVICE_TEMPORARY_UNAVAILABLE;
+ break;
+
+ // Errors which would require manual user intervention to resolve.
+ case fileapi::SYNC_DATABASE_ERROR_CORRUPTION:
+ case fileapi::SYNC_DATABASE_ERROR_IO_ERROR:
+ case fileapi::SYNC_DATABASE_ERROR_FAILED:
+ case fileapi::SYNC_STATUS_ABORT:
+ case fileapi::SYNC_STATUS_FAILED:
+ state_ = REMOTE_SERVICE_DISABLED;
+ break;
+
+ // Unexpected status code. They should be explicitly added to one of the
+ // above three cases.
+ default:
+ NOTREACHED();
+ state_ = REMOTE_SERVICE_DISABLED;
+ break;
}
}
@@ -278,6 +357,7 @@ void DriveFileSyncService::DidInitializeMetadataStore(
DCHECK(metadata_store_->batch_sync_origins().empty());
DCHECK(metadata_store_->incremental_sync_origins().empty());
+ token->UpdateTask(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving drive root");
sync_client_->GetDriveDirectoryForSyncRoot(
base::Bind(&DriveFileSyncService::DidGetSyncRootDirectory,
weak_factory_.GetWeakPtr(),
@@ -311,7 +391,8 @@ void DriveFileSyncService::DidGetSyncRootDirectory(
void DriveFileSyncService::StartBatchSyncForOrigin(
const GURL& origin,
const std::string& resource_id) {
- scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
+ scoped_ptr<TaskToken> token(
+ GetToken(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving largest changestamp"));
if (!token) {
pending_tasks_.push_back(base::Bind(
&DriveFileSyncService::StartBatchSyncForOrigin,
@@ -359,6 +440,8 @@ void DriveFileSyncService::DidGetLargestChangeStampForBatchSync(
return;
}
+ DCHECK(token);
+ token->UpdateTask(FROM_HERE, TASK_TYPE_DRIVE, "Retrieving remote files");
sync_client_->ListFiles(
resource_id,
base::Bind(&DriveFileSyncService::DidGetDirectoryContentForBatchSync,

Powered by Google App Engine
This is Rietveld 408576698