summaryrefslogtreecommitdiffstats
path: root/sync/engine/model_type_processor_impl.h
blob: 80dc15df42d63e8203f7d5085aa109b7bc9ab641 (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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// 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.

#ifndef SYNC_ENGINE_MODEL_TYPE_SYNC_PROXY_IMPL_H_
#define SYNC_ENGINE_MODEL_TYPE_SYNC_PROXY_IMPL_H_

#include "base/containers/scoped_ptr_map.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "sync/base/sync_export.h"
#include "sync/engine/model_type_processor.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/internal_api/public/non_blocking_sync_common.h"
#include "sync/protocol/sync.pb.h"

namespace syncer_v2 {
struct ActivationContext;
class CommitQueue;
class ModelTypeEntity;
class ModelTypeStore;

// A sync component embedded on the synced type's thread that helps to handle
// communication between sync and model type threads.
class SYNC_EXPORT_PRIVATE ModelTypeProcessorImpl : public ModelTypeProcessor,
                                                   base::NonThreadSafe {
 public:
  ModelTypeProcessorImpl(syncer::ModelType type,
                         base::WeakPtr<ModelTypeStore> store);
  ~ModelTypeProcessorImpl() override;

  typedef base::Callback<void(
      /*syncer::SyncError,*/ scoped_ptr<ActivationContext>)> StartCallback;

  // Called by DataTypeController to begins asynchronous operation of preparing
  // the model to sync. Once the model is ready to be activated with Sync the
  // callback will be invoked with the activation context. If the model is
  // already ready it is safe to call the callback right away. Otherwise the
  // callback needs to be stored and called when the model is ready.
  void Start(StartCallback callback);

  // Called by DataTypeController to inform the model that the sync is
  // stopping for the model type.
  void Stop();

  // Returns true if the datatype is enabled.
  // TODO(stanisc): crbug.com/537027: There is no explicit call to indicate
  // that the datatype is enabled. The flag is set to true when Start is called
  // and reset to false when Disable is called.
  bool IsEnabled() const;

  // TODO(stanisc): crbug.com/537027: This needs to be called from
  // DataTypeController when the type is disabled
  // Severs all ties to the sync thread and may delete local sync state.
  // Another call to Enable() can be used to re-establish this connection.
  void Disable();

  // Callback used to process the handshake response from the sync thread.
  void OnConnect(scoped_ptr<CommitQueue> worker) override;

  // Returns true if the handshake with sync thread is complete.
  bool IsConnected() const;

  // Requests that an item be stored in sync.
  void Put(const std::string& client_tag,
           const sync_pb::EntitySpecifics& specifics);

  // Deletes an item from sync.
  void Delete(const std::string& client_tag);

  // Informs this object that some of its commit requests have been
  // successfully serviced.
  void OnCommitCompleted(const DataTypeState& type_state,
                         const CommitResponseDataList& response_list) override;

  // Informs this object that there are some incoming updates is should
  // handle.
  void OnUpdateReceived(const DataTypeState& type_state,
                        const UpdateResponseDataList& response_list,
                        const UpdateResponseDataList& pending_updates) override;

  // Returns the list of pending updates.
  //
  // This is used as a helper function, but it's public mainly for testing.
  // The current test harness setup doesn't allow us to test the data that the
  // proxy sends to the worker during initialization, so we use this to inspect
  // its state instead.
  UpdateResponseDataList GetPendingUpdates();

  // Returns the long-lived WeakPtr that is intended to be registered with the
  // ProfileSyncService.
  base::WeakPtr<ModelTypeProcessorImpl> AsWeakPtrForUI();

 private:
  typedef base::ScopedPtrMap<std::string, scoped_ptr<ModelTypeEntity>>
      EntityMap;
  typedef base::ScopedPtrMap<std::string, scoped_ptr<UpdateResponseData>>
      UpdateMap;

  // Sends all commit requests that are due to be sent to the sync thread.
  void FlushPendingCommitRequests();

  // Clears any state related to outstanding communications with the
  // CommitQueue.  Used when we want to disconnect from
  // the current worker.
  void ClearTransientSyncState();

  // Clears any state related to our communications with the current sync
  // account.  Useful when a user signs out of the current account.
  void ClearSyncState();

  syncer::ModelType type_;
  DataTypeState data_type_state_;

  // Whether or not sync is enabled by this type's DataTypeController.
  bool is_enabled_;

  // Whether or not this object has completed its initial handshake with the
  // SyncContextProxy.
  bool is_connected_;

  // Reference to the CommitQueue.
  //
  // The interface hides the posting of tasks across threads as well as the
  // CommitQueue's implementation.  Both of these features are
  // useful in tests.
  scoped_ptr<CommitQueue> worker_;

  // The set of sync entities known to this object.
  EntityMap entities_;

  // A set of updates that can not be applied at this time.  These are never
  // used by the model.  They are kept here only so we can save and restore
  // them across restarts, and keep them in sync with our progress markers.
  UpdateMap pending_updates_map_;

  // Store is supplied by model type implementation. ModelTypeProcessorImpl
  // uses store for persisting sync related data (entity state and data type
  // state).
  base::WeakPtr<ModelTypeStore> store_;

  // We use two different WeakPtrFactories because we want the pointers they
  // issue to have different lifetimes.  When asked to disconnect from the sync
  // thread, we want to make sure that no tasks generated as part of the
  // now-obsolete connection to affect us.  But we also want the WeakPtr we
  // sent to the UI thread to remain valid.
  base::WeakPtrFactory<ModelTypeProcessorImpl> weak_ptr_factory_for_ui_;
  base::WeakPtrFactory<ModelTypeProcessorImpl> weak_ptr_factory_for_sync_;
};

}  // namespace syncer

#endif  // SYNC_ENGINE_MODEL_TYPE_SYNC_PROXY_IMPL_H_