blob: 55af70817573be91df38ce865fa0df8408750684 [file] [log] [blame]
// Copyright 2014 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 "components/sync_driver/non_blocking_data_type_controller.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "sync/engine/non_blocking_type_processor.h"
namespace browser_sync {
NonBlockingDataTypeController::NonBlockingDataTypeController(
syncer::ModelType type, bool is_preferred)
: type_(type),
current_state_(DISCONNECTED),
is_preferred_(is_preferred) {}
NonBlockingDataTypeController::~NonBlockingDataTypeController() {}
void NonBlockingDataTypeController::InitializeProcessor(
scoped_refptr<base::SequencedTaskRunner> task_runner,
base::WeakPtr<syncer::NonBlockingTypeProcessor> processor) {
DCHECK(!IsTypeProcessorConnected());
task_runner_ = task_runner;
processor_ = processor;
DCHECK(IsTypeProcessorConnected());
UpdateState();
}
void NonBlockingDataTypeController::InitializeSyncCoreProxy(
scoped_ptr<syncer::SyncCoreProxy> proxy) {
DCHECK(!IsSyncBackendConnected());
proxy_ = proxy.Pass();
UpdateState();
}
void NonBlockingDataTypeController::ClearSyncCoreProxy() {
// Never had a sync core proxy to begin with. No change.
if (!proxy_)
return;
proxy_.reset();
UpdateState();
}
void NonBlockingDataTypeController::SetIsPreferred(bool is_preferred) {
is_preferred_ = is_preferred;
UpdateState();
}
void NonBlockingDataTypeController::UpdateState() {
// Return immediately if no updates are necessary.
if (GetDesiredState() == current_state_) {
return;
}
// Return immediately if the processor is not ready yet.
if (!IsTypeProcessorConnected()) {
return;
}
// Send the appropriate state transition request to the processor.
switch (GetDesiredState()) {
case ENABLED:
SendEnableSignal();
return;
case DISABLED:
SendDisableSignal();
return;
case DISCONNECTED:
SendDisconnectSignal();
return;
}
NOTREACHED();
return;
}
void NonBlockingDataTypeController::SendEnableSignal() {
DCHECK_EQ(ENABLED, GetDesiredState());
DVLOG(1) << "Enabling non-blocking sync type " << ModelTypeToString(type_);
task_runner_->PostTask(FROM_HERE,
base::Bind(&syncer::NonBlockingTypeProcessor::Enable,
processor_,
base::Passed(proxy_->Clone())));
current_state_ = ENABLED;
}
void NonBlockingDataTypeController::SendDisableSignal() {
DCHECK_EQ(DISABLED, GetDesiredState());
DVLOG(1) << "Disabling non-blocking sync type " << ModelTypeToString(type_);
task_runner_->PostTask(
FROM_HERE,
base::Bind(&syncer::NonBlockingTypeProcessor::Disable, processor_));
current_state_ = DISABLED;
}
void NonBlockingDataTypeController::SendDisconnectSignal() {
DCHECK_EQ(DISCONNECTED, GetDesiredState());
DVLOG(1) << "Disconnecting non-blocking sync type "
<< ModelTypeToString(type_);
task_runner_->PostTask(
FROM_HERE,
base::Bind(&syncer::NonBlockingTypeProcessor::Disconnect, processor_));
current_state_ = DISCONNECTED;
}
bool NonBlockingDataTypeController::IsPreferred() const {
return is_preferred_;
}
bool NonBlockingDataTypeController::IsTypeProcessorConnected() const {
return task_runner_ != NULL;
}
bool NonBlockingDataTypeController::IsSyncBackendConnected() const {
return proxy_;
}
NonBlockingDataTypeController::TypeProcessorState
NonBlockingDataTypeController::GetDesiredState() const {
if (!IsPreferred()) {
return DISABLED;
} else if (!IsSyncBackendConnected() || !IsTypeProcessorConnected()) {
return DISCONNECTED;
} else {
return ENABLED;
}
}
} // namespace browser_sync