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
|
// 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_SHARED_CHANGE_PROCESSOR_H_
#define COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_H_
#include <memory>
#include <string>
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "components/sync/driver/data_type_controller.h"
#include "components/sync/engine/model_safe_worker.h"
#include "components/sync/model/data_type_error_handler.h"
#include "components/sync/model/sync_change_processor.h"
#include "components/sync/model/sync_data.h"
#include "components/sync/model/sync_error.h"
#include "components/sync/model/sync_error_factory.h"
#include "components/sync/model/sync_merge_result.h"
namespace syncer {
class ChangeProcessor;
class GenericChangeProcessor;
class GenericChangeProcessorFactory;
class SyncClient;
class SyncableService;
struct UserShare;
// A ref-counted wrapper around a GenericChangeProcessor for use with datatypes
// that don't live on the UI thread.
//
// We need to make it refcounted as the ownership transfer from the
// DataTypeController is dependent on threading, and hence racy. The
// SharedChangeProcessor should be created on the UI thread, but should only be
// connected and used on the same thread as the datatype it interacts with.
//
// The only thread-safe method is Disconnect, which will disconnect from the
// generic change processor, letting us shut down the syncer/datatype without
// waiting for non-UI threads.
//
// Note: since we control the work being done while holding the lock, we ensure
// no I/O or other intensive work is done while blocking the UI thread (all
// the work is in-memory sync interactions).
//
// We use virtual methods so that we can use mock's in testing.
class SharedChangeProcessor
: public base::RefCountedThreadSafe<SharedChangeProcessor> {
public:
typedef base::Callback<void(DataTypeController::ConfigureResult start_result,
const SyncMergeResult& local_merge_result,
const SyncMergeResult& syncer_merge_result)>
StartDoneCallback;
// Create an uninitialized SharedChangeProcessor.
explicit SharedChangeProcessor(ModelType type);
void StartAssociation(StartDoneCallback start_done,
SyncClient* const sync_client,
GenericChangeProcessorFactory* processor_factory,
UserShare* user_share,
std::unique_ptr<DataTypeErrorHandler> error_handler);
// Connect to the Syncer and prepare to handle changes for |type|. Will
// create and store a new GenericChangeProcessor and return a weak pointer to
// the SyncableService associated with |type|.
// Note: If this SharedChangeProcessor has been disconnected, or the
// SyncableService was not alive, will return a null weak pointer.
virtual base::WeakPtr<SyncableService> Connect(
SyncClient* sync_client,
GenericChangeProcessorFactory* processor_factory,
UserShare* user_share,
std::unique_ptr<DataTypeErrorHandler> error_handler,
const base::WeakPtr<SyncMergeResult>& merge_result);
// Disconnects from the generic change processor. This method is thread-safe.
// After this, all attempts to interact with the change processor by
// |local_service_| are dropped and return errors. The syncer will be safe to
// shut down from the point of view of this datatype.
// Note: Once disconnected, you cannot reconnect without creating a new
// SharedChangeProcessor.
// Returns: true if we were previously succesfully connected, false if we were
// already disconnected.
virtual bool Disconnect();
// GenericChangeProcessor stubs (with disconnect support).
// Should only be called on the same sequence the datatype resides.
virtual int GetSyncCount();
virtual SyncError ProcessSyncChanges(
const tracked_objects::Location& from_here,
const SyncChangeList& change_list);
virtual SyncDataList GetAllSyncData(ModelType type) const;
virtual SyncError GetAllSyncDataReturnError(ModelType type,
SyncDataList* data) const;
virtual SyncError UpdateDataTypeContext(
ModelType type,
SyncChangeProcessor::ContextRefreshStatus refresh_status,
const std::string& context);
virtual void AddLocalChangeObserver(LocalChangeObserver* observer);
virtual void RemoveLocalChangeObserver(LocalChangeObserver* observer);
virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
virtual bool CryptoReadyIfNecessary();
// If a datatype context associated with the current type exists, fills
// |context| and returns true. Otheriwse, if there has not been a context
// set, returns false.
virtual bool GetDataTypeContext(std::string* context) const;
virtual SyncError CreateAndUploadError(
const tracked_objects::Location& location,
const std::string& message);
// Calls local_service_->StopSyncing() and releases our reference to it.
void StopLocalService();
ChangeProcessor* generic_change_processor();
protected:
friend class base::RefCountedThreadSafe<SharedChangeProcessor>;
virtual ~SharedChangeProcessor();
private:
// Record association time.
virtual void RecordAssociationTime(base::TimeDelta time);
// Monitor lock for this object. All methods that interact with the change
// processor must aquire this lock and check whether we're disconnected or
// not. Once disconnected, all attempted changes to or loads from the change
// processor return errors. This enables us to shut down the syncer without
// having to wait for possibly non-UI thread datatypes to complete work.
mutable base::Lock monitor_lock_;
bool disconnected_;
// The sync datatype we process changes for.
const ModelType type_;
// The frontend / UI MessageLoop this object is constructed on. May also be
// destructed and/or disconnected on this loop, see ~SharedChangeProcessor.
const scoped_refptr<const base::SingleThreadTaskRunner> frontend_task_runner_;
// The execution sequence that all methods except the constructor, destructor,
// and Disconnect() should be called on. Set in Connect().
scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
// Used only on |backend_task_runner_|.
GenericChangeProcessor* generic_change_processor_;
std::unique_ptr<DataTypeErrorHandler> error_handler_;
// The local service for this type. Only set if the DTC for the type uses
// SharedChangeProcessor::StartAssociation().
base::WeakPtr<SyncableService> local_service_;
DISALLOW_COPY_AND_ASSIGN(SharedChangeProcessor);
};
} // namespace syncer
#endif // COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_H_
|