summaryrefslogtreecommitdiffstats
path: root/components/sync_driver/non_blocking_data_type_controller.cc
blob: 4e7f4f274d9d1fb126363b263d733c89ec7ec60b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// 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/model_type_sync_proxy_impl.h"

namespace sync_driver {

NonBlockingDataTypeController::NonBlockingDataTypeController(
    syncer::ModelType type, bool is_preferred)
    : type_(type),
      current_state_(DISCONNECTED),
      is_preferred_(is_preferred) {}

NonBlockingDataTypeController::~NonBlockingDataTypeController() {}

void NonBlockingDataTypeController::InitializeType(
    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
    const base::WeakPtr<syncer_v2::ModelTypeSyncProxyImpl>& type_sync_proxy) {
  DCHECK(!IsSyncProxyConnected());
  task_runner_ = task_runner;
  type_sync_proxy_ = type_sync_proxy;
  DCHECK(IsSyncProxyConnected());

  UpdateState();
}

void NonBlockingDataTypeController::InitializeSyncContext(
    scoped_ptr<syncer_v2::SyncContextProxy> sync_context_proxy) {
  DCHECK(!IsSyncBackendConnected());
  sync_context_proxy_ = sync_context_proxy.Pass();

  UpdateState();
}

void NonBlockingDataTypeController::ClearSyncContext() {
  // Never had a sync context proxy to begin with.  No change.
  if (!sync_context_proxy_)
    return;
  sync_context_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 sync context proxy is not ready yet.
  if (!IsSyncProxyConnected()) {
    return;
  }

  // Send the appropriate state transition request to the type sync proxy.
  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_v2::ModelTypeSyncProxyImpl::Enable, type_sync_proxy_,
                 base::Passed(sync_context_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_v2::ModelTypeSyncProxyImpl::Disable,
                                    type_sync_proxy_));
  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_v2::ModelTypeSyncProxyImpl::Disconnect,
                            type_sync_proxy_));
  current_state_ = DISCONNECTED;
}

bool NonBlockingDataTypeController::IsPreferred() const {
  return is_preferred_;
}

bool NonBlockingDataTypeController::IsSyncProxyConnected() const {
  return task_runner_.get() != NULL;
}

bool NonBlockingDataTypeController::IsSyncBackendConnected() const {
  return sync_context_proxy_;
}

NonBlockingDataTypeController::TypeState
NonBlockingDataTypeController::GetDesiredState() const {
  if (!IsPreferred()) {
    return DISABLED;
  } else if (!IsSyncBackendConnected() || !IsSyncProxyConnected()) {
    return DISCONNECTED;
  } else {
    return ENABLED;
  }
}

}  // namespace sync_driver