| Index: chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc
|
| diff --git a/chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc b/chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ecea4b6b633874a3005e39b056fc6caadb1f809e
|
| --- /dev/null
|
| +++ b/chrome/browser/sync/glue/new_non_frontend_data_type_controller.cc
|
| @@ -0,0 +1,173 @@
|
| +// Copyright (c) 2011 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/new_non_frontend_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/shared_change_processor_ref.h"
|
| +#include "chrome/browser/sync/profile_sync_factory.h"
|
| +#include "chrome/browser/sync/profile_sync_service.h"
|
| +#include "chrome/browser/sync/syncable/model_type.h"
|
| +#include "content/browser/browser_thread.h"
|
| +
|
| +namespace browser_sync {
|
| +
|
| +NewNonFrontendDataTypeController::NewNonFrontendDataTypeController()
|
| + : user_share_(NULL),
|
| + local_service_(NULL),
|
| + shared_change_processor_(NULL) {}
|
| +
|
| +NewNonFrontendDataTypeController::NewNonFrontendDataTypeController(
|
| + ProfileSyncFactory* profile_sync_factory,
|
| + Profile* profile)
|
| + : NonFrontendDataTypeController(profile_sync_factory, profile),
|
| + user_share_(NULL),
|
| + local_service_(NULL),
|
| + shared_change_processor_(NULL) {
|
| +}
|
| +
|
| +NewNonFrontendDataTypeController::~NewNonFrontendDataTypeController() {}
|
| +
|
| +void NewNonFrontendDataTypeController::Start(StartCallback* start_callback) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(start_callback);
|
| + if (state() != NOT_RUNNING) {
|
| + start_callback->Run(BUSY, SyncError());
|
| + delete start_callback;
|
| + return;
|
| + }
|
| +
|
| + set_start_callback(start_callback);
|
| +
|
| + set_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.
|
| + DCHECK(state() == MODEL_STARTING || state() == NOT_RUNNING);
|
| + return;
|
| + }
|
| +
|
| + shared_change_processor_ =
|
| + profile_sync_factory()->CreateSharedChangeProcessor(this);
|
| + user_share_ = profile_sync_service()->GetUserShare();
|
| +
|
| + // Kick off association on the thread the datatype resides on.
|
| + set_state(ASSOCIATING);
|
| + if (!StartAssociationAsync()) {
|
| + shared_change_processor_ = NULL;
|
| + SyncError error(FROM_HERE, "Failed to post StartAssociation", type());
|
| + StartDoneImpl(ASSOCIATION_FAILED, NOT_RUNNING, error);
|
| + }
|
| +}
|
| +
|
| +void NewNonFrontendDataTypeController::StartAssociation() {
|
| + DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK_EQ(state(), ASSOCIATING);
|
| +
|
| + local_service_ = GetSyncableService();
|
| + shared_change_processor_->Connect(local_service_, user_share_);
|
| +
|
| + if (!shared_change_processor_->CryptoReadyIfNecessary(type())) {
|
| + StartFailed(NEEDS_CRYPTO, SyncError());
|
| + return;
|
| + }
|
| +
|
| + bool sync_has_nodes = false;
|
| + if (!shared_change_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();
|
| + SyncError error;
|
| + SyncDataList initial_sync_data;
|
| + error = shared_change_processor_->GetSyncDataForType(type(),
|
| + &initial_sync_data);
|
| + if (error.IsSet()) {
|
| + StartFailed(ASSOCIATION_FAILED, error);
|
| + return;
|
| + }
|
| + // Passes a reference to the shared_change_processor_;
|
| + error = local_service_->MergeDataAndStartSyncing(
|
| + type(),
|
| + initial_sync_data,
|
| + new SharedChangeProcessorRef(shared_change_processor_));
|
| + RecordAssociationTime(base::TimeTicks::Now() - start_time);
|
| + if (error.IsSet()) {
|
| + local_service_->StopSyncing(type());
|
| + StartFailed(ASSOCIATION_FAILED, error);
|
| + return;
|
| + }
|
| +
|
| + // This is kind of ugly, but safe since we guarantee that the SyncableService
|
| + // will be around longer than the PSS, and hence the referene it holds
|
| + // to the SharedChangeProcessor will stick around.
|
| + profile_sync_service()->ActivateDataType(type(), model_safe_group(),
|
| + shared_change_processor_);
|
| + StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, RUNNING, SyncError());
|
| +}
|
| +
|
| +void NewNonFrontendDataTypeController::Stop() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + // Disconnect the change processor. At this point, the SyncableService
|
| + // can no longer interact with the Syncer, even if it hasn't finished
|
| + // MergeDataAndStartSyncing. The shared change processor is owned by
|
| + // local_service_ so we don't have to delete it. Just post a task to tell it
|
| + // to StopSyncing.
|
| + if (shared_change_processor_.get()) {
|
| + shared_change_processor_->Disconnect();
|
| + if (!StopLocalServiceAsync()) {
|
| + LOG(ERROR) << "Failed to stop " << type() << "'s syncable service. "
|
| + << "Continuing, but this may cause problems on sync restart.";
|
| + }
|
| + }
|
| +
|
| + // If we haven't finished starting, we need to abort the start.
|
| + if (state() == MODEL_STARTING) {
|
| + set_state(STOPPING);
|
| + StartDoneImpl(ABORTED, NOT_RUNNING, SyncError());
|
| + return; // The datatype was never activated, we're done.
|
| + } else if (state() == ASSOCIATING) {
|
| + set_state(STOPPING);
|
| + StartDoneImpl(ABORTED, NOT_RUNNING, SyncError());
|
| + // We continue on to deactivate the datatype.
|
| + } else {
|
| + // Datatype was fully started.
|
| + set_state(STOPPING);
|
| + StopModels();
|
| + }
|
| +
|
| + // Deactivate the DataType on the UI thread. We dont want to listen
|
| + // for any more changes or process them from the server.
|
| + profile_sync_service()->DeactivateDataType(type());
|
| +
|
| + set_state(NOT_RUNNING);
|
| +}
|
| +
|
| +// Static.
|
| +void NewNonFrontendDataTypeController::StopLocalService(
|
| + SyncableService* service, syncable::ModelType type) {
|
| + service->StopSyncing(type);
|
| +}
|
| +
|
| +SyncableService* NewNonFrontendDataTypeController::local_service() const {
|
| + return local_service_;
|
| +}
|
| +
|
| +bool NewNonFrontendDataTypeController::StopAssociationAsync() {
|
| + NOTIMPLEMENTED();
|
| + return false;
|
| +}
|
| +
|
| +void NewNonFrontendDataTypeController::CreateSyncComponents() {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +} // namepsace browser_sync
|
|
|