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 |