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

Unified Diff: chrome/browser/sync/glue/ui_data_type_controller.cc

Issue 9395058: [Sync] Remove SyncableServiceAdapter. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 9 months 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/glue/ui_data_type_controller.cc
diff --git a/chrome/browser/sync/glue/ui_data_type_controller.cc b/chrome/browser/sync/glue/ui_data_type_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..de5ef9efc54e303492177815546639720c8cf9b9
--- /dev/null
+++ b/chrome/browser/sync/glue/ui_data_type_controller.cc
@@ -0,0 +1,267 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/sync/glue/ui_data_type_controller.h"
+
+#include "base/logging.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/api/sync_error.h"
+#include "chrome/browser/sync/api/syncable_service.h"
+#include "chrome/browser/sync/glue/generic_change_processor.h"
+#include "chrome/browser/sync/profile_sync_components_factory.h"
+#include "chrome/browser/sync/profile_sync_service.h"
+#include "chrome/browser/sync/syncable/model_type.h"
+#include "chrome/browser/sync/util/data_type_histogram.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace browser_sync {
+
+UIDataTypeController::UIDataTypeController()
+ : profile_sync_factory_(NULL),
+ profile_(NULL),
+ sync_service_(NULL),
+ state_(NOT_RUNNING),
+ type_(syncable::UNSPECIFIED) {
+}
+
+UIDataTypeController::UIDataTypeController(
+ syncable::ModelType type,
+ ProfileSyncComponentsFactory* profile_sync_factory,
+ Profile* profile,
+ ProfileSyncService* sync_service)
+ : profile_sync_factory_(profile_sync_factory),
+ profile_(profile),
+ sync_service_(sync_service),
+ state_(NOT_RUNNING),
+ type_(type) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(profile_sync_factory);
+ DCHECK(profile);
+ DCHECK(sync_service);
+ DCHECK(syncable::IsRealDataType(type_));
+}
+
+UIDataTypeController::~UIDataTypeController() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+}
+
+void UIDataTypeController::Start(const StartCallback& start_callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!start_callback.is_null());
+ DCHECK(syncable::IsRealDataType(type_));
+ if (state_ != NOT_RUNNING) {
+ start_callback.Run(BUSY, SyncError());
+ return;
+ }
+
+ start_callback_ = start_callback;
+
+ state_ = MODEL_STARTING;
+ if (!StartModels()) {
+ // If we are waiting for some external service to load before associating
+ // or we failed to start the models, we exit early. state_ will control
+ // what we perform next.
+ DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING);
+ return;
+ }
+
+ state_ = ASSOCIATING;
+ Associate();
+ // It's possible StartDone(..) resulted in a Stop() call, or that association
+ // failed, so we just verify that the state has moved foward.
+ DCHECK_NE(state_, ASSOCIATING);
+}
+
+bool UIDataTypeController::StartModels() {
+ DCHECK_EQ(state_, MODEL_STARTING);
+ // By default, no additional services need to be started before we can proceed
+ // with model association.
+ return true;
+}
+
+void UIDataTypeController::Associate() {
+ DCHECK_EQ(state_, ASSOCIATING);
+ local_service_ = profile_sync_factory_->GetSyncableServiceForType(type());
+ if (!local_service_.get()) {
+ SyncError error(FROM_HERE, "Failed to connect to syncable service.",
+ type());
+ StartFailed(UNRECOVERABLE_ERROR, error);
+ return;
+ }
+
+ // We maintain ownership until MergeDataAndStartSyncing is called.
+ scoped_ptr<GenericChangeProcessor> sync_processor(
+ profile_sync_factory_->CreateGenericChangeProcessor(
+ sync_service_, this, local_service_));
+
+ if (!sync_processor->CryptoReadyIfNecessary(type())) {
+ StartFailed(NEEDS_CRYPTO, SyncError());
+ return;
+ }
+
+ bool sync_has_nodes = false;
+ if (!sync_processor->SyncModelHasUserCreatedNodes(type(), &sync_has_nodes)) {
+ SyncError error(FROM_HERE, "Failed to load sync nodes", type());
+ StartFailed(UNRECOVERABLE_ERROR, error);
+ return;
+ }
+
+ base::TimeTicks start_time = base::TimeTicks::Now();
+ SyncDataList initial_sync_data;
+ SyncError error = sync_processor->GetSyncDataForType(
+ type(), &initial_sync_data);
+ if (error.IsSet()) {
+ StartFailed(ASSOCIATION_FAILED, error);
+ return;
+ }
+
+ // TODO(zea): this should use scoped_ptr<T>::Pass semantics.
+ GenericChangeProcessor* saved_sync_processor = sync_processor.get();
+ // Takes ownership of sync_processor.
+ error = local_service_->MergeDataAndStartSyncing(type(),
+ initial_sync_data,
+ sync_processor.release());
+ if (error.IsSet()) {
+ StartFailed(ASSOCIATION_FAILED, error);
+ return;
+ }
+ RecordAssociationTime(base::TimeTicks::Now() - start_time);
+
+ sync_service_->ActivateDataType(type(), model_safe_group(),
+ saved_sync_processor);
+
+ // StartDone(..) invokes the DataTypeManager callback, which can lead to a
+ // call to Stop() if one of the other data types being started generates an
+ // error.
+ state_ = RUNNING;
+ StartDone(sync_has_nodes ? OK : OK_FIRST_RUN);
+}
+
+void UIDataTypeController::StartFailed(StartResult result,
+ const SyncError& error) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ StopModels();
+ if (result == ASSOCIATION_FAILED) {
+ state_ = DISABLED;
+ } else {
+ state_ = NOT_RUNNING;
+ }
+ RecordStartFailure(result);
+
+ // We have to release the callback before we call it, since it's possible
+ // invoking the callback will trigger a call to Stop(), which will get
+ // confused by the non-NULL start_callback_.
+ StartCallback callback = start_callback_;
+ start_callback_.Reset();
+ callback.Run(result, error);
+}
+
+void UIDataTypeController::StartDone(StartResult result) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // We have to release the callback before we call it, since it's possible
+ // invoking the callback will trigger a call to Stop(), which will get
+ // confused by the non-NULL start_callback_.
+ StartCallback callback = start_callback_;
+ start_callback_.Reset();
+ callback.Run(result, SyncError());
+}
+
+void UIDataTypeController::Stop() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(syncable::IsRealDataType(type_));
+ // If Stop() is called while Start() is waiting for the datatype model to
+ // load, abort the start.
+ if (state_ == MODEL_STARTING) {
+ StartFailed(ABORTED, SyncError());
+ // We can just return here since we haven't performed association if we're
+ // still in MODEL_STARTING.
+ return;
+ }
+ DCHECK(start_callback_.is_null());
+
+ StopModels();
+
+ sync_service_->DeactivateDataType(type());
+
+ if (local_service_.get()) {
+ local_service_->StopSyncing(type());
+ }
+
+ state_ = NOT_RUNNING;
+}
+
+syncable::ModelType UIDataTypeController::type() const {
+ DCHECK(syncable::IsRealDataType(type_));
+ return type_;
+}
+
+void UIDataTypeController::StopModels() {
+ // Do nothing by default.
+}
+
+browser_sync::ModelSafeGroup UIDataTypeController::model_safe_group() const {
+ DCHECK(syncable::IsRealDataType(type_));
+ return browser_sync::GROUP_UI;
+}
+
+std::string UIDataTypeController::name() const {
+ // For logging only.
+ return syncable::ModelTypeToString(type());
+}
+
+DataTypeController::State UIDataTypeController::state() const {
+ return state_;
+}
+
+void UIDataTypeController::OnUnrecoverableError(
+ const tracked_objects::Location& from_here, const std::string& message) {
+ RecordUnrecoverableError(from_here, message);
+
+ // The ProfileSyncService will invoke our Stop() method in response to this.
+ // We dont know the current state of the caller. Posting a task will allow
+ // the caller to unwind the stack before we process unrecoverable error.
+ MessageLoop::current()->PostTask(from_here,
+ base::Bind(&ProfileSyncService::OnUnrecoverableError,
+ sync_service_->AsWeakPtr(),
+ from_here,
+ message));
+}
+
+void UIDataTypeController::OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here, const std::string& message) {
+ RecordUnrecoverableError(from_here, message);
+ sync_service_->OnDisableDatatype(type(), from_here, message);
+}
+
+void UIDataTypeController::RecordUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", type(),
+ syncable::MODEL_TYPE_COUNT);
+}
+
+void UIDataTypeController::RecordAssociationTime(base::TimeDelta time) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+#define PER_DATA_TYPE_MACRO(type_str) \
+ UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time);
+ SYNC_DATA_TYPE_HISTOGRAM(type());
+#undef PER_DATA_TYPE_MACRO
+}
+
+void UIDataTypeController::RecordStartFailure(StartResult result) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", type(),
+ syncable::MODEL_TYPE_COUNT);
+#define PER_DATA_TYPE_MACRO(type_str) \
+ UMA_HISTOGRAM_ENUMERATION("Sync." type_str "StartFailure", result, \
+ MAX_START_RESULT);
+ SYNC_DATA_TYPE_HISTOGRAM(type());
+#undef PER_DATA_TYPE_MACRO
+}
+
+} // namespace browser_sync
« no previous file with comments | « chrome/browser/sync/glue/ui_data_type_controller.h ('k') | chrome/browser/sync/glue/ui_data_type_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698