| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2009 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 // SyncerSession holds the entire state of a single sync cycle; GetUpdates, | |
| 6 // Commit, and Conflict Resolution. After said cycle, the Session may contain | |
| 7 // items that were unable to be processed because of errors. | |
| 8 // | |
| 9 // THIS CLASS PROVIDES NO SYNCHRONIZATION GUARANTEES. | |
| 10 | |
| 11 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_SESSION_H_ | |
| 12 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_SESSION_H_ | |
| 13 | |
| 14 #include <string> | |
| 15 #include <utility> | |
| 16 #include <vector> | |
| 17 | |
| 18 #include "base/time.h" | |
| 19 #include "chrome/browser/sync/engine/net/server_connection_manager.h" | |
| 20 #include "chrome/browser/sync/engine/sync_cycle_state.h" | |
| 21 #include "chrome/browser/sync/engine/sync_process_state.h" | |
| 22 #include "chrome/browser/sync/engine/syncer_status.h" | |
| 23 #include "chrome/browser/sync/engine/syncer_types.h" | |
| 24 #include "chrome/browser/sync/engine/syncproto.h" | |
| 25 #include "chrome/browser/sync/util/event_sys.h" | |
| 26 #include "chrome/browser/sync/util/extensions_activity_monitor.h" | |
| 27 #include "chrome/browser/sync/util/sync_types.h" | |
| 28 #include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST | |
| 29 | |
| 30 namespace browser_sync { | |
| 31 | |
| 32 class ConflictResolver; | |
| 33 class ModelSafeWorker; | |
| 34 class ServerConnectionManager; | |
| 35 class SyncerStatus; | |
| 36 struct SyncerEvent; | |
| 37 | |
| 38 class SyncerSession { | |
| 39 friend class ConflictResolutionView; | |
| 40 friend class SyncerStatus; | |
| 41 public: | |
| 42 // A utility to set the session's write transaction member, and later clear | |
| 43 // it when it the utility falls out of scope. | |
| 44 class ScopedSetWriteTransaction { | |
| 45 public: | |
| 46 ScopedSetWriteTransaction(SyncerSession* session, | |
| 47 syncable::WriteTransaction* trans) | |
| 48 : session_(session) { | |
| 49 session_->set_write_transaction(trans); | |
| 50 } | |
| 51 ~ScopedSetWriteTransaction() { | |
| 52 session_->ClearWriteTransaction(); | |
| 53 } | |
| 54 private: | |
| 55 SyncerSession* session_; | |
| 56 DISALLOW_COPY_AND_ASSIGN(ScopedSetWriteTransaction); | |
| 57 }; | |
| 58 | |
| 59 SyncerSession(SyncCycleState* cycle_state, SyncProcessState* process_state) | |
| 60 : sync_process_state_(process_state), | |
| 61 sync_cycle_state_(cycle_state), | |
| 62 source_(sync_pb::GetUpdatesCallerInfo::UNKNOWN), | |
| 63 notifications_enabled_(false) { | |
| 64 DCHECK(NULL != process_state); | |
| 65 DCHECK(NULL != cycle_state); | |
| 66 } | |
| 67 | |
| 68 // Perhaps this should dictate the next step. (ie, don't do apply if you | |
| 69 // didn't get any from download). or put it in the while loop. | |
| 70 void set_update_response(const ClientToServerResponse& update_response) { | |
| 71 sync_cycle_state_->set_update_response(update_response); | |
| 72 } | |
| 73 | |
| 74 const ClientToServerResponse& update_response() const { | |
| 75 return sync_cycle_state_->update_response(); | |
| 76 } | |
| 77 | |
| 78 void set_commit_response(const ClientToServerResponse& commit_response) { | |
| 79 sync_cycle_state_->set_commit_response(commit_response); | |
| 80 } | |
| 81 | |
| 82 const ClientToServerResponse& commit_response() const { | |
| 83 return sync_cycle_state_->commit_response(); | |
| 84 } | |
| 85 | |
| 86 void AddVerifyResult(const VerifyResult& verify_result, | |
| 87 const sync_pb::SyncEntity& entity) { | |
| 88 sync_cycle_state_->AddVerifyResult(verify_result, entity); | |
| 89 } | |
| 90 | |
| 91 bool HasVerifiedUpdates() const { | |
| 92 return sync_cycle_state_->HasVerifiedUpdates(); | |
| 93 } | |
| 94 | |
| 95 void AddAppliedUpdate(const UpdateAttemptResponse& response, | |
| 96 const syncable::Id& id) { | |
| 97 sync_cycle_state_->AddAppliedUpdate(response, id); | |
| 98 } | |
| 99 | |
| 100 bool HasAppliedUpdates() const { | |
| 101 return sync_cycle_state_->HasAppliedUpdates(); | |
| 102 } | |
| 103 | |
| 104 std::string account_name() const { | |
| 105 return sync_process_state_->account_name(); | |
| 106 } | |
| 107 | |
| 108 syncable::DirectoryManager* dirman() const { | |
| 109 return sync_process_state_->dirman(); | |
| 110 } | |
| 111 | |
| 112 ServerConnectionManager* connection_manager() const { | |
| 113 return sync_process_state_->connection_manager(); | |
| 114 } | |
| 115 | |
| 116 ConflictResolver* resolver() const { | |
| 117 return sync_process_state_->resolver(); | |
| 118 } | |
| 119 | |
| 120 SyncerEventChannel* syncer_event_channel() const { | |
| 121 return sync_process_state_->syncer_event_channel(); | |
| 122 } | |
| 123 | |
| 124 int conflicting_update_count() const { | |
| 125 return sync_process_state_->conflicting_updates(); | |
| 126 } | |
| 127 | |
| 128 base::TimeTicks silenced_until() const { | |
| 129 return sync_process_state_->silenced_until(); | |
| 130 } | |
| 131 | |
| 132 void set_silenced_until(base::TimeTicks silenced_until) const { | |
| 133 sync_process_state_->set_silenced_until(silenced_until); | |
| 134 } | |
| 135 | |
| 136 const std::vector<int64>& unsynced_handles() const { | |
| 137 return sync_cycle_state_->unsynced_handles(); | |
| 138 } | |
| 139 | |
| 140 void set_unsynced_handles(const std::vector<int64>& unsynced_handles) { | |
| 141 sync_cycle_state_->set_unsynced_handles(unsynced_handles); | |
| 142 } | |
| 143 | |
| 144 int64 unsynced_count() const { return sync_cycle_state_->unsynced_count(); } | |
| 145 | |
| 146 const std::vector<syncable::Id>& commit_ids() const { | |
| 147 return sync_cycle_state_->commit_ids(); | |
| 148 } | |
| 149 | |
| 150 void set_commit_ids(const std::vector<syncable::Id>& commit_ids) { | |
| 151 sync_cycle_state_->set_commit_ids(commit_ids); | |
| 152 } | |
| 153 | |
| 154 bool commit_ids_empty() const { | |
| 155 return sync_cycle_state_->commit_ids_empty(); | |
| 156 } | |
| 157 | |
| 158 bool HadSuccessfulCommits() const { | |
| 159 return sync_process_state_->successful_commits() > 0; | |
| 160 } | |
| 161 | |
| 162 syncable::WriteTransaction* write_transaction() const { | |
| 163 return sync_cycle_state_->write_transaction(); | |
| 164 } | |
| 165 | |
| 166 bool has_open_write_transaction() const { | |
| 167 return sync_cycle_state_->has_open_write_transaction(); | |
| 168 } | |
| 169 | |
| 170 ClientToServerMessage* commit_message() const { | |
| 171 return sync_cycle_state_->commit_message(); | |
| 172 } | |
| 173 | |
| 174 void set_commit_message(const ClientToServerMessage& message) { | |
| 175 sync_cycle_state_->set_commit_message(message); | |
| 176 } | |
| 177 | |
| 178 bool HasRemainingItemsToCommit() const { | |
| 179 return commit_ids().size() < unsynced_handles().size(); | |
| 180 } | |
| 181 | |
| 182 void AddCommitConflict(const syncable::Id& the_id) { | |
| 183 sync_process_state_->AddConflictingItem(the_id); | |
| 184 } | |
| 185 | |
| 186 void EraseCommitConflict(const syncable::Id& the_id) { | |
| 187 sync_process_state_->EraseConflictingItem(the_id); | |
| 188 } | |
| 189 | |
| 190 // Returns true if at least one update application failed due to a conflict | |
| 191 // during this sync cycle. | |
| 192 bool HasConflictingUpdates() const { | |
| 193 std::vector<AppliedUpdate>::const_iterator it; | |
| 194 for (it = sync_cycle_state_->AppliedUpdatesBegin(); | |
| 195 it < sync_cycle_state_->AppliedUpdatesEnd(); | |
| 196 ++it) { | |
| 197 if (it->first == CONFLICT) { | |
| 198 return true; | |
| 199 } | |
| 200 } | |
| 201 return false; | |
| 202 } | |
| 203 | |
| 204 std::vector<VerifiedUpdate>::iterator VerifiedUpdatesBegin() const { | |
| 205 return sync_cycle_state_->VerifiedUpdatesBegin(); | |
| 206 } | |
| 207 | |
| 208 std::vector<VerifiedUpdate>::iterator VerifiedUpdatesEnd() const { | |
| 209 return sync_cycle_state_->VerifiedUpdatesEnd(); | |
| 210 } | |
| 211 | |
| 212 // Returns the number of updates received from the sync server. | |
| 213 int64 CountUpdates() const { | |
| 214 if (update_response().has_get_updates()) { | |
| 215 return update_response().get_updates().entries().size(); | |
| 216 } else { | |
| 217 return 0; | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 bool got_zero_updates() const { | |
| 222 return CountUpdates() == 0; | |
| 223 } | |
| 224 | |
| 225 void DumpSessionInfo() const { | |
| 226 LOG(INFO) << "Dumping session info"; | |
| 227 if (update_response().has_get_updates()) { | |
| 228 LOG(INFO) << update_response().get_updates().entries().size() | |
| 229 << " updates downloaded by last get_updates"; | |
| 230 } else { | |
| 231 LOG(INFO) << "No update response found"; | |
| 232 } | |
| 233 LOG(INFO) << sync_cycle_state_->VerifiedUpdatesSize() | |
| 234 << " updates verified"; | |
| 235 LOG(INFO) << sync_cycle_state_->AppliedUpdatesSize() << " updates applied"; | |
| 236 LOG(INFO) << commit_ids().size() << " items to commit"; | |
| 237 LOG(INFO) << unsynced_count() << " unsynced items"; | |
| 238 } | |
| 239 | |
| 240 void set_conflict_sets_built(const bool b) { | |
| 241 sync_cycle_state_->set_conflict_sets_built(b); | |
| 242 } | |
| 243 | |
| 244 bool conflict_sets_built() const { | |
| 245 return sync_cycle_state_->conflict_sets_built(); | |
| 246 } | |
| 247 | |
| 248 void set_conflicts_resolved(const bool b) { | |
| 249 sync_cycle_state_->set_conflicts_resolved(b); | |
| 250 } | |
| 251 | |
| 252 bool conflicts_resolved() const { | |
| 253 return sync_cycle_state_->conflicts_resolved(); | |
| 254 } | |
| 255 | |
| 256 ModelSafeWorker* model_safe_worker() const { | |
| 257 return sync_process_state_->model_safe_worker(); | |
| 258 } | |
| 259 | |
| 260 void set_item_committed() { | |
| 261 sync_cycle_state_->set_item_committed(); | |
| 262 } | |
| 263 | |
| 264 bool items_committed() const { | |
| 265 return sync_cycle_state_->items_committed(); | |
| 266 } | |
| 267 | |
| 268 void set_over_quota(const bool b) { | |
| 269 sync_cycle_state_->set_over_quota(b); | |
| 270 } | |
| 271 | |
| 272 // Volitile reader for the source member of the syncer session object. The | |
| 273 // value is set to the SYNC_CYCLE_CONTINUATION value to signal that it has | |
| 274 // been read. | |
| 275 sync_pb::GetUpdatesCallerInfo::GET_UPDATES_SOURCE TestAndSetSource() { | |
| 276 sync_pb::GetUpdatesCallerInfo::GET_UPDATES_SOURCE old_source = | |
| 277 source_; | |
| 278 set_source(sync_pb::GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION); | |
| 279 return old_source; | |
| 280 } | |
| 281 | |
| 282 void set_source(sync_pb::GetUpdatesCallerInfo::GET_UPDATES_SOURCE source) { | |
| 283 source_ = source; | |
| 284 } | |
| 285 | |
| 286 const ExtensionsActivityMonitor::Records& extensions_activity() const { | |
| 287 return extensions_activity_; | |
| 288 } | |
| 289 | |
| 290 ExtensionsActivityMonitor::Records* mutable_extensions_activity() { | |
| 291 return &extensions_activity_; | |
| 292 } | |
| 293 | |
| 294 bool notifications_enabled() const { | |
| 295 return notifications_enabled_; | |
| 296 } | |
| 297 | |
| 298 void set_notifications_enabled(const bool state) { | |
| 299 notifications_enabled_ = state; | |
| 300 } | |
| 301 | |
| 302 void set_timestamp_dirty() { | |
| 303 sync_cycle_state_->set_timestamp_dirty(); | |
| 304 } | |
| 305 | |
| 306 bool timestamp_dirty() const { | |
| 307 return sync_cycle_state_->is_timestamp_dirty(); | |
| 308 } | |
| 309 | |
| 310 // TODO(chron): Unit test for this method. | |
| 311 // returns true iff this session contains data that should go through the | |
| 312 // sync engine again. | |
| 313 bool HasMoreToSync() const { | |
| 314 return (HasRemainingItemsToCommit() && | |
| 315 sync_process_state_->successful_commits() > 0) || | |
| 316 conflict_sets_built() || | |
| 317 conflicts_resolved() || | |
| 318 // Or, we have conflicting updates, but we're making progress on | |
| 319 // resolving them... | |
| 320 !got_zero_updates() || | |
| 321 timestamp_dirty(); | |
| 322 } | |
| 323 | |
| 324 private: | |
| 325 // The write transaction must be destructed by the caller of this function. | |
| 326 // Here, we just clear the reference. | |
| 327 void set_write_transaction(syncable::WriteTransaction* write_transaction) { | |
| 328 sync_cycle_state_->set_write_transaction(write_transaction); | |
| 329 } | |
| 330 | |
| 331 // Sets the write transaction to null, but doesn't free the memory. | |
| 332 void ClearWriteTransaction() { | |
| 333 sync_cycle_state_->ClearWriteTransaction(); | |
| 334 } | |
| 335 | |
| 336 SyncProcessState* sync_process_state_; | |
| 337 SyncCycleState* sync_cycle_state_; | |
| 338 | |
| 339 // The source for initiating this syncer session. | |
| 340 sync_pb::GetUpdatesCallerInfo::GET_UPDATES_SOURCE source_; | |
| 341 | |
| 342 // Information about extensions activity since the last successful commit. | |
| 343 ExtensionsActivityMonitor::Records extensions_activity_; | |
| 344 | |
| 345 // True if notifications are enabled when this session was created. | |
| 346 bool notifications_enabled_; | |
| 347 | |
| 348 FRIEND_TEST(SyncerTest, TestCommitListOrderingCounterexample); | |
| 349 DISALLOW_COPY_AND_ASSIGN(SyncerSession); | |
| 350 }; | |
| 351 | |
| 352 } // namespace browser_sync | |
| 353 | |
| 354 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_SESSION_H_ | |
| OLD | NEW |