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_GENERIC_CHANGE_PROCESSOR_H_ 6 #define COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_ 7 8 #include <vector> 9 10 #include "base/compiler_specific.h" 11 #include "base/memory/weak_ptr.h" 12 #include "base/threading/non_thread_safe.h" 13 #include "components/sync_driver/change_processor.h" 14 #include "components/sync_driver/data_type_controller.h" 15 #include "components/sync_driver/data_type_error_handler.h" 16 #include "sync/api/attachments/attachment_service.h" 17 #include "sync/api/attachments/attachment_service_proxy.h" 18 #include "sync/api/sync_change_processor.h" 19 #include "sync/api/sync_merge_result.h" 20 21 namespace syncer { 22 class SyncData; 23 class SyncableService; 24 class WriteNode; 25 class WriteTransaction; 26 27 typedef std::vector<syncer::SyncData> SyncDataList; 28 } // namespace syncer 29 30 namespace browser_sync { 31 class SyncApiComponentFactory; 32 33 // Datatype agnostic change processor. One instance of GenericChangeProcessor 34 // is created for each datatype and lives on the datatype's thread. It then 35 // handles all interaction with the sync api, both translating pushes from the 36 // local service into transactions and receiving changes from the sync model, 37 // which then get converted into SyncChange's and sent to the local service. 38 // 39 // As a rule, the GenericChangeProcessor is not thread safe, and should only 40 // be used on the same thread in which it was created. 41 class GenericChangeProcessor : public ChangeProcessor, 42 public syncer::SyncChangeProcessor, 43 public syncer::AttachmentService::Delegate, 44 public base::NonThreadSafe { 45 public: 46 // Create a change processor and connect it to the syncer. 47 GenericChangeProcessor( 48 DataTypeErrorHandler* error_handler, 49 const base::WeakPtr<syncer::SyncableService>& local_service, 50 const base::WeakPtr<syncer::SyncMergeResult>& merge_result, 51 syncer::UserShare* user_share, 52 SyncApiComponentFactory* sync_factory); 53 virtual ~GenericChangeProcessor(); 54 55 // ChangeProcessor interface. 56 // Build and store a list of all changes into |syncer_changes_|. 57 virtual void ApplyChangesFromSyncModel( 58 const syncer::BaseTransaction* trans, 59 int64 version, 60 const syncer::ImmutableChangeRecordList& changes) OVERRIDE; 61 // Passes |syncer_changes_|, built in ApplyChangesFromSyncModel, onto 62 // |local_service_| by way of its ProcessSyncChanges method. 63 virtual void CommitChangesFromSyncModel() OVERRIDE; 64 65 // syncer::SyncChangeProcessor implementation. 66 virtual syncer::SyncError ProcessSyncChanges( 67 const tracked_objects::Location& from_here, 68 const syncer::SyncChangeList& change_list) OVERRIDE; 69 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) 70 const OVERRIDE; 71 virtual syncer::SyncError UpdateDataTypeContext( 72 syncer::ModelType type, 73 syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, 74 const std::string& context) OVERRIDE; 75 76 // syncer::AttachmentService::Delegate implementation. 77 virtual void OnAttachmentUploaded( 78 const syncer::AttachmentId& attachment_id) OVERRIDE; 79 80 // Similar to above, but returns a SyncError for use by direct clients 81 // of GenericChangeProcessor that may need more error visibility. 82 virtual syncer::SyncError GetAllSyncDataReturnError( 83 syncer::ModelType type, 84 syncer::SyncDataList* data) const; 85 86 // If a datatype context associated with |type| exists, fills |context| and 87 // returns true. Otheriwse, if there has not been a context set, returns 88 // false. 89 virtual bool GetDataTypeContext(syncer::ModelType type, 90 std::string* context) const; 91 92 // Returns the number of items for this type. 93 virtual int GetSyncCountForType(syncer::ModelType type); 94 95 // Generic versions of AssociatorInterface methods. Called by 96 // syncer::SyncableServiceAdapter or the DataTypeController. 97 virtual bool SyncModelHasUserCreatedNodes(syncer::ModelType type, 98 bool* has_nodes); 99 virtual bool CryptoReadyIfNecessary(syncer::ModelType type); 100 101 protected: 102 // ChangeProcessor interface. 103 virtual void StartImpl() OVERRIDE; // Does nothing. 104 virtual syncer::UserShare* share_handle() const OVERRIDE; 105 106 private: 107 // Logically part of ProcessSyncChanges. 108 // 109 // |new_attachments| is an output parameter containing newly added attachments 110 // that need to be stored. This method will append to it. 111 syncer::SyncError HandleActionAdd(const syncer::SyncChange& change, 112 const std::string& type_str, 113 const syncer::ModelType& type, 114 const syncer::WriteTransaction& trans, 115 syncer::WriteNode* sync_node, 116 syncer::AttachmentList* new_attachments); 117 118 // Logically part of ProcessSyncChanges. 119 // 120 // |new_attachments| is an output parameter containing newly added attachments 121 // that need to be stored. This method will append to it. 122 syncer::SyncError HandleActionUpdate(const syncer::SyncChange& change, 123 const std::string& type_str, 124 const syncer::ModelType& type, 125 const syncer::WriteTransaction& trans, 126 syncer::WriteNode* sync_node, 127 syncer::AttachmentList* new_attachments); 128 129 // The SyncableService this change processor will forward changes on to. 130 const base::WeakPtr<syncer::SyncableService> local_service_; 131 132 // A SyncMergeResult used to track the changes made during association. The 133 // owner will invalidate the weak pointer when association is complete. While 134 // the pointer is valid though, we increment it with any changes received 135 // via ProcessSyncChanges. 136 const base::WeakPtr<syncer::SyncMergeResult> merge_result_; 137 138 // The current list of changes received from the syncer. We buffer because 139 // we must ensure no syncapi transaction is held when we pass it on to 140 // |local_service_|. 141 // Set in ApplyChangesFromSyncModel, consumed in CommitChangesFromSyncModel. 142 syncer::SyncChangeList syncer_changes_; 143 144 // Our handle to the sync model. Unlike normal ChangeProcessors, we need to 145 // be able to access the sync model before the change processor begins 146 // listening to changes (the local_service_ will be interacting with us 147 // when it starts up). As such we can't wait until Start(_) has been called, 148 // and have to keep a local pointer to the user_share. 149 syncer::UserShare* const share_handle_; 150 151 scoped_ptr<syncer::AttachmentService> attachment_service_; 152 // Must be destroyed before attachment_service_ to ensure WeakPtrs are 153 // invalidated before attachment_service_ is destroyed. 154 base::WeakPtrFactory<syncer::AttachmentService> 155 attachment_service_weak_ptr_factory_; 156 syncer::AttachmentServiceProxy attachment_service_proxy_; 157 158 DISALLOW_COPY_AND_ASSIGN(GenericChangeProcessor); 159 }; 160 161 } // namespace browser_sync 162 163 #endif // COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_ 164