| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sync/glue/ui_data_type_controller.h" | 5 #include "chrome/browser/sync/glue/ui_data_type_controller.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "chrome/browser/profiles/profile.h" | 8 #include "chrome/browser/profiles/profile.h" |
| 9 #include "chrome/browser/sync/glue/shared_change_processor_ref.h" | 9 #include "chrome/browser/sync/glue/shared_change_processor_ref.h" |
| 10 #include "chrome/browser/sync/profile_sync_components_factory.h" | 10 #include "chrome/browser/sync/profile_sync_components_factory.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 UIDataTypeController::~UIDataTypeController() { | 47 UIDataTypeController::~UIDataTypeController() { |
| 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 49 } | 49 } |
| 50 | 50 |
| 51 void UIDataTypeController::LoadModels( | 51 void UIDataTypeController::LoadModels( |
| 52 const ModelLoadCallback& model_load_callback) { | 52 const ModelLoadCallback& model_load_callback) { |
| 53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 54 DCHECK(!model_load_callback.is_null()); | 54 DCHECK(!model_load_callback.is_null()); |
| 55 DCHECK(syncable::IsRealDataType(type_)); | 55 DCHECK(syncable::IsRealDataType(type_)); |
| 56 if (state_ != NOT_RUNNING) { | 56 if (state_ != NOT_RUNNING) { |
| 57 model_load_callback.Run(type(), SyncError(FROM_HERE, | 57 model_load_callback.Run(type(), csync::SyncError(FROM_HERE, |
| 58 "Model already loaded", | 58 "Model already loaded", |
| 59 type())); | 59 type())); |
| 60 return; | 60 return; |
| 61 } | 61 } |
| 62 | 62 |
| 63 // Since we can't be called multiple times before Stop() is called, | 63 // Since we can't be called multiple times before Stop() is called, |
| 64 // |shared_change_processor_| must be NULL here. | 64 // |shared_change_processor_| must be NULL here. |
| 65 DCHECK(!shared_change_processor_.get()); | 65 DCHECK(!shared_change_processor_.get()); |
| 66 shared_change_processor_ = | 66 shared_change_processor_ = |
| 67 profile_sync_factory_->CreateSharedChangeProcessor(); | 67 profile_sync_factory_->CreateSharedChangeProcessor(); |
| 68 DCHECK(shared_change_processor_.get()); | 68 DCHECK(shared_change_processor_.get()); |
| 69 | 69 |
| 70 model_load_callback_ = model_load_callback; | 70 model_load_callback_ = model_load_callback; |
| 71 state_ = MODEL_STARTING; | 71 state_ = MODEL_STARTING; |
| 72 if (!StartModels()) { | 72 if (!StartModels()) { |
| 73 // If we are waiting for some external service to load before associating | 73 // If we are waiting for some external service to load before associating |
| 74 // or we failed to start the models, we exit early. state_ will control | 74 // or we failed to start the models, we exit early. state_ will control |
| 75 // what we perform next. | 75 // what we perform next. |
| 76 DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); | 76 DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); |
| 77 return; | 77 return; |
| 78 } | 78 } |
| 79 | 79 |
| 80 state_ = MODEL_LOADED; | 80 state_ = MODEL_LOADED; |
| 81 model_load_callback_.Reset(); | 81 model_load_callback_.Reset(); |
| 82 model_load_callback.Run(type(), SyncError()); | 82 model_load_callback.Run(type(), csync::SyncError()); |
| 83 } | 83 } |
| 84 | 84 |
| 85 void UIDataTypeController::OnModelLoaded() { | 85 void UIDataTypeController::OnModelLoaded() { |
| 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 87 DCHECK(!model_load_callback_.is_null()); | 87 DCHECK(!model_load_callback_.is_null()); |
| 88 DCHECK_EQ(state_, MODEL_STARTING); | 88 DCHECK_EQ(state_, MODEL_STARTING); |
| 89 | 89 |
| 90 state_ = MODEL_LOADED; | 90 state_ = MODEL_LOADED; |
| 91 ModelLoadCallback model_load_callback = model_load_callback_; | 91 ModelLoadCallback model_load_callback = model_load_callback_; |
| 92 model_load_callback_.Reset(); | 92 model_load_callback_.Reset(); |
| 93 model_load_callback.Run(type(), SyncError()); | 93 model_load_callback.Run(type(), csync::SyncError()); |
| 94 } | 94 } |
| 95 | 95 |
| 96 void UIDataTypeController::StartAssociating( | 96 void UIDataTypeController::StartAssociating( |
| 97 const StartCallback& start_callback) { | 97 const StartCallback& start_callback) { |
| 98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 99 DCHECK(!start_callback.is_null()); | 99 DCHECK(!start_callback.is_null()); |
| 100 DCHECK_EQ(state_, MODEL_LOADED); | 100 DCHECK_EQ(state_, MODEL_LOADED); |
| 101 | 101 |
| 102 start_callback_ = start_callback; | 102 start_callback_ = start_callback; |
| 103 state_ = ASSOCIATING; | 103 state_ = ASSOCIATING; |
| 104 Associate(); | 104 Associate(); |
| 105 // It's possible StartDone(..) resulted in a Stop() call, or that association | 105 // It's possible StartDone(..) resulted in a Stop() call, or that association |
| 106 // failed, so we just verify that the state has moved foward. | 106 // failed, so we just verify that the state has moved foward. |
| 107 DCHECK_NE(state_, ASSOCIATING); | 107 DCHECK_NE(state_, ASSOCIATING); |
| 108 } | 108 } |
| 109 | 109 |
| 110 bool UIDataTypeController::StartModels() { | 110 bool UIDataTypeController::StartModels() { |
| 111 DCHECK_EQ(state_, MODEL_STARTING); | 111 DCHECK_EQ(state_, MODEL_STARTING); |
| 112 // By default, no additional services need to be started before we can proceed | 112 // By default, no additional services need to be started before we can proceed |
| 113 // with model association. | 113 // with model association. |
| 114 return true; | 114 return true; |
| 115 } | 115 } |
| 116 | 116 |
| 117 void UIDataTypeController::Associate() { | 117 void UIDataTypeController::Associate() { |
| 118 DCHECK_EQ(state_, ASSOCIATING); | 118 DCHECK_EQ(state_, ASSOCIATING); |
| 119 | 119 |
| 120 // Connect |shared_change_processor_| to the syncer and get the | 120 // Connect |shared_change_processor_| to the syncer and get the |
| 121 // SyncableService associated with type(). | 121 // csync::SyncableService associated with type(). |
| 122 local_service_ = shared_change_processor_->Connect(profile_sync_factory_, | 122 local_service_ = shared_change_processor_->Connect(profile_sync_factory_, |
| 123 sync_service_, | 123 sync_service_, |
| 124 this, | 124 this, |
| 125 type()); | 125 type()); |
| 126 if (!local_service_.get()) { | 126 if (!local_service_.get()) { |
| 127 SyncError error(FROM_HERE, "Failed to connect to syncer.", type()); | 127 csync::SyncError error(FROM_HERE, "Failed to connect to syncer.", type()); |
| 128 StartFailed(UNRECOVERABLE_ERROR, error); | 128 StartFailed(UNRECOVERABLE_ERROR, error); |
| 129 return; | 129 return; |
| 130 } | 130 } |
| 131 | 131 |
| 132 if (!shared_change_processor_->CryptoReadyIfNecessary()) { | 132 if (!shared_change_processor_->CryptoReadyIfNecessary()) { |
| 133 StartFailed(NEEDS_CRYPTO, SyncError()); | 133 StartFailed(NEEDS_CRYPTO, csync::SyncError()); |
| 134 return; | 134 return; |
| 135 } | 135 } |
| 136 | 136 |
| 137 bool sync_has_nodes = false; | 137 bool sync_has_nodes = false; |
| 138 if (!shared_change_processor_->SyncModelHasUserCreatedNodes( | 138 if (!shared_change_processor_->SyncModelHasUserCreatedNodes( |
| 139 &sync_has_nodes)) { | 139 &sync_has_nodes)) { |
| 140 SyncError error(FROM_HERE, "Failed to load sync nodes", type()); | 140 csync::SyncError error(FROM_HERE, "Failed to load sync nodes", type()); |
| 141 StartFailed(UNRECOVERABLE_ERROR, error); | 141 StartFailed(UNRECOVERABLE_ERROR, error); |
| 142 return; | 142 return; |
| 143 } | 143 } |
| 144 | 144 |
| 145 base::TimeTicks start_time = base::TimeTicks::Now(); | 145 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 146 SyncError error; | 146 csync::SyncError error; |
| 147 SyncDataList initial_sync_data; | 147 csync::SyncDataList initial_sync_data; |
| 148 error = shared_change_processor_->GetSyncData(&initial_sync_data); | 148 error = shared_change_processor_->GetSyncData(&initial_sync_data); |
| 149 if (error.IsSet()) { | 149 if (error.IsSet()) { |
| 150 StartFailed(ASSOCIATION_FAILED, error); | 150 StartFailed(ASSOCIATION_FAILED, error); |
| 151 return; | 151 return; |
| 152 } | 152 } |
| 153 | 153 |
| 154 // Passes a reference to |shared_change_processor_|. | 154 // Passes a reference to |shared_change_processor_|. |
| 155 error = local_service_->MergeDataAndStartSyncing( | 155 error = local_service_->MergeDataAndStartSyncing( |
| 156 type(), | 156 type(), |
| 157 initial_sync_data, | 157 initial_sync_data, |
| 158 scoped_ptr<SyncChangeProcessor>( | 158 scoped_ptr<csync::SyncChangeProcessor>( |
| 159 new SharedChangeProcessorRef(shared_change_processor_)), | 159 new SharedChangeProcessorRef(shared_change_processor_)), |
| 160 scoped_ptr<SyncErrorFactory>( | 160 scoped_ptr<csync::SyncErrorFactory>( |
| 161 new SharedChangeProcessorRef(shared_change_processor_))); | 161 new SharedChangeProcessorRef(shared_change_processor_))); |
| 162 RecordAssociationTime(base::TimeTicks::Now() - start_time); | 162 RecordAssociationTime(base::TimeTicks::Now() - start_time); |
| 163 if (error.IsSet()) { | 163 if (error.IsSet()) { |
| 164 StartFailed(ASSOCIATION_FAILED, error); | 164 StartFailed(ASSOCIATION_FAILED, error); |
| 165 return; | 165 return; |
| 166 } | 166 } |
| 167 | 167 |
| 168 shared_change_processor_->ActivateDataType(model_safe_group()); | 168 shared_change_processor_->ActivateDataType(model_safe_group()); |
| 169 state_ = RUNNING; | 169 state_ = RUNNING; |
| 170 StartDone(sync_has_nodes ? OK : OK_FIRST_RUN); | 170 StartDone(sync_has_nodes ? OK : OK_FIRST_RUN); |
| 171 } | 171 } |
| 172 | 172 |
| 173 void UIDataTypeController::StartFailed(StartResult result, | 173 void UIDataTypeController::StartFailed(StartResult result, |
| 174 const SyncError& error) { | 174 const csync::SyncError& error) { |
| 175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 176 if (IsUnrecoverableResult(result)) | 176 if (IsUnrecoverableResult(result)) |
| 177 RecordUnrecoverableError(FROM_HERE, "StartFailed"); | 177 RecordUnrecoverableError(FROM_HERE, "StartFailed"); |
| 178 StopModels(); | 178 StopModels(); |
| 179 if (result == ASSOCIATION_FAILED) { | 179 if (result == ASSOCIATION_FAILED) { |
| 180 state_ = DISABLED; | 180 state_ = DISABLED; |
| 181 } else { | 181 } else { |
| 182 state_ = NOT_RUNNING; | 182 state_ = NOT_RUNNING; |
| 183 } | 183 } |
| 184 RecordStartFailure(result); | 184 RecordStartFailure(result); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 199 void UIDataTypeController::AbortModelLoad() { | 199 void UIDataTypeController::AbortModelLoad() { |
| 200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 201 state_ = NOT_RUNNING; | 201 state_ = NOT_RUNNING; |
| 202 | 202 |
| 203 if (shared_change_processor_.get()) { | 203 if (shared_change_processor_.get()) { |
| 204 shared_change_processor_ = NULL; | 204 shared_change_processor_ = NULL; |
| 205 } | 205 } |
| 206 | 206 |
| 207 ModelLoadCallback model_load_callback = model_load_callback_; | 207 ModelLoadCallback model_load_callback = model_load_callback_; |
| 208 model_load_callback_.Reset(); | 208 model_load_callback_.Reset(); |
| 209 model_load_callback.Run(type(), SyncError(FROM_HERE, | 209 model_load_callback.Run(type(), csync::SyncError(FROM_HERE, |
| 210 "Aborted", | 210 "Aborted", |
| 211 type())); | 211 type())); |
| 212 } | 212 } |
| 213 | 213 |
| 214 void UIDataTypeController::StartDone(StartResult result) { | 214 void UIDataTypeController::StartDone(StartResult result) { |
| 215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 216 | 216 |
| 217 // We have to release the callback before we call it, since it's possible | 217 // We have to release the callback before we call it, since it's possible |
| 218 // invoking the callback will trigger a call to Stop(), which will get | 218 // invoking the callback will trigger a call to Stop(), which will get |
| 219 // confused by the non-NULL start_callback_. | 219 // confused by the non-NULL start_callback_. |
| 220 StartCallback callback = start_callback_; | 220 StartCallback callback = start_callback_; |
| 221 start_callback_.Reset(); | 221 start_callback_.Reset(); |
| 222 callback.Run(result, SyncError()); | 222 callback.Run(result, csync::SyncError()); |
| 223 } | 223 } |
| 224 | 224 |
| 225 void UIDataTypeController::Stop() { | 225 void UIDataTypeController::Stop() { |
| 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 227 DCHECK(syncable::IsRealDataType(type_)); | 227 DCHECK(syncable::IsRealDataType(type_)); |
| 228 | 228 |
| 229 State prev_state = state_; | 229 State prev_state = state_; |
| 230 state_ = STOPPING; | 230 state_ = STOPPING; |
| 231 | 231 |
| 232 if (shared_change_processor_.get()) { | 232 if (shared_change_processor_.get()) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", type(), | 297 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", type(), |
| 298 syncable::MODEL_TYPE_COUNT); | 298 syncable::MODEL_TYPE_COUNT); |
| 299 #define PER_DATA_TYPE_MACRO(type_str) \ | 299 #define PER_DATA_TYPE_MACRO(type_str) \ |
| 300 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "StartFailure", result, \ | 300 UMA_HISTOGRAM_ENUMERATION("Sync." type_str "StartFailure", result, \ |
| 301 MAX_START_RESULT); | 301 MAX_START_RESULT); |
| 302 SYNC_DATA_TYPE_HISTOGRAM(type()); | 302 SYNC_DATA_TYPE_HISTOGRAM(type()); |
| 303 #undef PER_DATA_TYPE_MACRO | 303 #undef PER_DATA_TYPE_MACRO |
| 304 } | 304 } |
| 305 | 305 |
| 306 } // namespace browser_sync | 306 } // namespace browser_sync |
| OLD | NEW |