summaryrefslogtreecommitdiffstats
path: root/components/sync_driver/generic_change_processor.h
blob: a3139d8161a849c81425edc8309059800823e263 (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// 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 COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_
#define COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_

#include <vector>

#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "components/sync_driver/change_processor.h"
#include "components/sync_driver/data_type_controller.h"
#include "components/sync_driver/data_type_error_handler.h"
#include "sync/api/attachments/attachment_store.h"
#include "sync/api/sync_change_processor.h"
#include "sync/api/sync_merge_result.h"
#include "sync/internal_api/public/attachments/attachment_service.h"
#include "sync/internal_api/public/attachments/attachment_service_proxy.h"

namespace syncer {
class SyncData;
class SyncableService;
class WriteNode;
class WriteTransaction;

typedef std::vector<syncer::SyncData> SyncDataList;
}  // namespace syncer

namespace sync_driver {
class SyncApiComponentFactory;

// Datatype agnostic change processor. One instance of GenericChangeProcessor
// is created for each datatype and lives on the datatype's thread. It then
// handles all interaction with the sync api, both translating pushes from the
// local service into transactions and receiving changes from the sync model,
// which then get converted into SyncChange's and sent to the local service.
//
// As a rule, the GenericChangeProcessor is not thread safe, and should only
// be used on the same thread in which it was created.
class GenericChangeProcessor : public ChangeProcessor,
                               public syncer::SyncChangeProcessor,
                               public syncer::AttachmentService::Delegate,
                               public base::NonThreadSafe {
 public:
  // Create a change processor and connect it to the syncer.
  GenericChangeProcessor(
      DataTypeErrorHandler* error_handler,
      const base::WeakPtr<syncer::SyncableService>& local_service,
      const base::WeakPtr<syncer::SyncMergeResult>& merge_result,
      syncer::UserShare* user_share,
      SyncApiComponentFactory* sync_factory);
  virtual ~GenericChangeProcessor();

  // ChangeProcessor interface.
  // Build and store a list of all changes into |syncer_changes_|.
  virtual void ApplyChangesFromSyncModel(
      const syncer::BaseTransaction* trans,
      int64 version,
      const syncer::ImmutableChangeRecordList& changes) OVERRIDE;
  // Passes |syncer_changes_|, built in ApplyChangesFromSyncModel, onto
  // |local_service_| by way of its ProcessSyncChanges method.
  virtual void CommitChangesFromSyncModel() OVERRIDE;

  // syncer::SyncChangeProcessor implementation.
  virtual syncer::SyncError ProcessSyncChanges(
      const tracked_objects::Location& from_here,
      const syncer::SyncChangeList& change_list) OVERRIDE;
  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
      const OVERRIDE;
  virtual syncer::SyncError UpdateDataTypeContext(
      syncer::ModelType type,
      syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status,
      const std::string& context) OVERRIDE;

  // syncer::AttachmentService::Delegate implementation.
  virtual void OnAttachmentUploaded(
      const syncer::AttachmentId& attachment_id) OVERRIDE;

  // Similar to above, but returns a SyncError for use by direct clients
  // of GenericChangeProcessor that may need more error visibility.
  virtual syncer::SyncError GetAllSyncDataReturnError(
      syncer::ModelType type,
      syncer::SyncDataList* data) const;

  // If a datatype context associated with |type| exists, fills |context| and
  // returns true. Otheriwse, if there has not been a context set, returns
  // false.
  virtual bool GetDataTypeContext(syncer::ModelType type,
                                  std::string* context) const;

  // Returns the number of items for this type.
  virtual int GetSyncCountForType(syncer::ModelType type);

  // Generic versions of AssociatorInterface methods. Called by
  // syncer::SyncableServiceAdapter or the DataTypeController.
  virtual bool SyncModelHasUserCreatedNodes(syncer::ModelType type,
                                            bool* has_nodes);
  virtual bool CryptoReadyIfNecessary(syncer::ModelType type);

 protected:
  // ChangeProcessor interface.
  virtual void StartImpl() OVERRIDE;  // Does nothing.
  virtual syncer::UserShare* share_handle() const OVERRIDE;

 private:
  // Logically part of ProcessSyncChanges.
  //
  // |new_attachments| is an output parameter containing newly added attachments
  // that need to be stored.  This method will append to it.
  syncer::SyncError HandleActionAdd(const syncer::SyncChange& change,
                                    const std::string& type_str,
                                    const syncer::ModelType& type,
                                    const syncer::WriteTransaction& trans,
                                    syncer::WriteNode* sync_node,
                                    syncer::AttachmentList* new_attachments);

  // Logically part of ProcessSyncChanges.
  //
  // |new_attachments| is an output parameter containing newly added attachments
  // that need to be stored.  This method will append to it.
  syncer::SyncError HandleActionUpdate(const syncer::SyncChange& change,
                                       const std::string& type_str,
                                       const syncer::ModelType& type,
                                       const syncer::WriteTransaction& trans,
                                       syncer::WriteNode* sync_node,
                                       syncer::AttachmentList* new_attachments);

  // Store |attachments| locally then upload them to the sync server.
  //
  // Store and uploading are asynchronous operations.  |WriteAttachmentsDone|
  // will be invoked once the attachments have been stored on the local device.
  void StoreAndUploadAttachments(const syncer::AttachmentList& attachments);

  // Invoked once attachments have been stored locally.
  //
  // See also AttachmentStore::WriteCallback.
  void WriteAttachmentsDone(const syncer::AttachmentList& attachments,
                            const syncer::AttachmentStore::Result& result);

  // The SyncableService this change processor will forward changes on to.
  const base::WeakPtr<syncer::SyncableService> local_service_;

  // A SyncMergeResult used to track the changes made during association. The
  // owner will invalidate the weak pointer when association is complete. While
  // the pointer is valid though, we increment it with any changes received
  // via ProcessSyncChanges.
  const base::WeakPtr<syncer::SyncMergeResult> merge_result_;

  // The current list of changes received from the syncer. We buffer because
  // we must ensure no syncapi transaction is held when we pass it on to
  // |local_service_|.
  // Set in ApplyChangesFromSyncModel, consumed in CommitChangesFromSyncModel.
  syncer::SyncChangeList syncer_changes_;

  // Our handle to the sync model. Unlike normal ChangeProcessors, we need to
  // be able to access the sync model before the change processor begins
  // listening to changes (the local_service_ will be interacting with us
  // when it starts up). As such we can't wait until Start(_) has been called,
  // and have to keep a local pointer to the user_share.
  syncer::UserShare* const share_handle_;

  scoped_ptr<syncer::AttachmentService> attachment_service_;
  // Must be destroyed before attachment_service_ to ensure WeakPtrs are
  // invalidated before attachment_service_ is destroyed.
  base::WeakPtrFactory<syncer::AttachmentService>
      attachment_service_weak_ptr_factory_;
  syncer::AttachmentServiceProxy attachment_service_proxy_;

  base::WeakPtrFactory<GenericChangeProcessor> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(GenericChangeProcessor);
};

}  // namespace sync_driver

#endif  // COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_