• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_H_
6 #define COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_H_
7 
8 #include "base/location.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/synchronization/lock.h"
13 #include "components/sync_driver/data_type_error_handler.h"
14 #include "sync/api/sync_change_processor.h"
15 #include "sync/api/sync_data.h"
16 #include "sync/api/sync_error.h"
17 #include "sync/api/sync_error_factory.h"
18 #include "sync/api/sync_merge_result.h"
19 #include "sync/internal_api/public/engine/model_safe_worker.h"
20 
21 namespace syncer {
22 class SyncableService;
23 struct UserShare;
24 }  // namespace syncer
25 
26 namespace sync_driver {
27 
28 class ChangeProcessor;
29 class GenericChangeProcessor;
30 class GenericChangeProcessorFactory;
31 class DataTypeErrorHandler;
32 class SyncApiComponentFactory;
33 
34 // A ref-counted wrapper around a GenericChangeProcessor for use with datatypes
35 // that don't live on the UI thread.
36 //
37 // We need to make it refcounted as the ownership transfer from the
38 // DataTypeController is dependent on threading, and hence racy. The
39 // SharedChangeProcessor should be created on the UI thread, but should only be
40 // connected and used on the same thread as the datatype it interacts with.
41 //
42 // The only thread-safe method is Disconnect, which will disconnect from the
43 // generic change processor, letting us shut down the syncer/datatype without
44 // waiting for non-UI threads.
45 //
46 // Note: since we control the work being done while holding the lock, we ensure
47 // no I/O or other intensive work is done while blocking the UI thread (all
48 // the work is in-memory sync interactions).
49 //
50 // We use virtual methods so that we can use mock's in testing.
51 class SharedChangeProcessor
52     : public base::RefCountedThreadSafe<SharedChangeProcessor> {
53  public:
54   // Create an uninitialized SharedChangeProcessor.
55   SharedChangeProcessor();
56 
57   // Connect to the Syncer and prepare to handle changes for |type|. Will
58   // create and store a new GenericChangeProcessor and return a weak pointer to
59   // the syncer::SyncableService associated with |type|.
60   // Note: If this SharedChangeProcessor has been disconnected, or the
61   // syncer::SyncableService was not alive, will return a null weak pointer.
62   virtual base::WeakPtr<syncer::SyncableService> Connect(
63       SyncApiComponentFactory* sync_factory,
64       GenericChangeProcessorFactory* processor_factory,
65       syncer::UserShare* user_share,
66       DataTypeErrorHandler* error_handler,
67       syncer::ModelType type,
68       const base::WeakPtr<syncer::SyncMergeResult>& merge_result);
69 
70   // Disconnects from the generic change processor. May be called from any
71   // thread. After this, all attempts to interact with the change processor by
72   // |local_service_| are dropped and return errors. The syncer will be safe to
73   // shut down from the point of view of this datatype.
74   // Note: Once disconnected, you cannot reconnect without creating a new
75   // SharedChangeProcessor.
76   // Returns: true if we were previously succesfully connected, false if we were
77   // already disconnected.
78   virtual bool Disconnect();
79 
80   // GenericChangeProcessor stubs (with disconnect support).
81   // Should only be called on the same thread the datatype resides.
82   virtual int GetSyncCount();
83   virtual syncer::SyncError ProcessSyncChanges(
84       const tracked_objects::Location& from_here,
85       const syncer::SyncChangeList& change_list);
86   virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const;
87   virtual syncer::SyncError GetAllSyncDataReturnError(
88       syncer::ModelType type,
89       syncer::SyncDataList* data) const;
90   virtual syncer::SyncError UpdateDataTypeContext(
91       syncer::ModelType type,
92       syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status,
93       const std::string& context);
94   virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
95   virtual bool CryptoReadyIfNecessary();
96 
97   // If a datatype context associated with the current type exists, fills
98   // |context| and returns true. Otheriwse, if there has not been a context
99   // set, returns false.
100   virtual bool GetDataTypeContext(std::string* context) const;
101 
102   virtual syncer::SyncError CreateAndUploadError(
103       const tracked_objects::Location& location,
104       const std::string& message);
105 
106   ChangeProcessor* generic_change_processor();
107 
108  protected:
109   friend class base::RefCountedThreadSafe<SharedChangeProcessor>;
110   virtual ~SharedChangeProcessor();
111 
112  private:
113   // Monitor lock for this object. All methods that interact with the change
114   // processor must aquire this lock and check whether we're disconnected or
115   // not. Once disconnected, all attempted changes to or loads from the change
116   // processor return errors. This enables us to shut down the syncer without
117   // having to wait for possibly non-UI thread datatypes to complete work.
118   mutable base::Lock monitor_lock_;
119   bool disconnected_;
120 
121   // The sync datatype we were last connected to.
122   syncer::ModelType type_;
123 
124   // The frontend / UI MessageLoop this object is constructed on. May also be
125   // destructed and/or disconnected on this loop, see ~SharedChangeProcessor.
126   const scoped_refptr<const base::MessageLoopProxy> frontend_loop_;
127 
128   // The loop that all methods except the constructor, destructor, and
129   // Disconnect() should be called on.  Set in Connect().
130   scoped_refptr<base::MessageLoopProxy> backend_loop_;
131 
132   // Used only on |backend_loop_|.
133   GenericChangeProcessor* generic_change_processor_;
134 
135   DataTypeErrorHandler* error_handler_;
136 
137   DISALLOW_COPY_AND_ASSIGN(SharedChangeProcessor);
138 };
139 
140 }  // namespace sync_driver
141 
142 #endif  // COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_H_
143