Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: chrome/browser/sync/glue/password_data_type_controller.cc

Issue 6811003: [Sync] Make generic non-frontend thread datatype controller. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Copy paste :( Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/password_data_type_controller.h" 5 #include "chrome/browser/sync/glue/password_data_type_controller.h"
6 6
7 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "base/logging.h"
9 #include "base/task.h" 8 #include "base/task.h"
10 #include "base/time.h"
11 #include "chrome/browser/password_manager/password_store.h" 9 #include "chrome/browser/password_manager/password_store.h"
12 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/sync/glue/password_change_processor.h" 11 #include "chrome/browser/sync/profile_sync_factory.h"
14 #include "chrome/browser/sync/glue/password_model_associator.h"
15 #include "chrome/browser/sync/profile_sync_service.h" 12 #include "chrome/browser/sync/profile_sync_service.h"
16 #include "chrome/browser/sync/profile_sync_factory.h" 13 #include "chrome/browser/webdata/web_data_service.h"
17 #include "content/browser/browser_thread.h" 14 #include "content/browser/browser_thread.h"
18 15
19 namespace browser_sync { 16 namespace browser_sync {
20 17
21 PasswordDataTypeController::PasswordDataTypeController( 18 PasswordDataTypeController::PasswordDataTypeController(
22 ProfileSyncFactory* profile_sync_factory, 19 ProfileSyncFactory* profile_sync_factory,
23 Profile* profile, 20 Profile* profile)
24 ProfileSyncService* sync_service) 21 : NonFrontendDataTypeController(profile_sync_factory,
25 : profile_sync_factory_(profile_sync_factory), 22 profile) {
26 profile_(profile),
27 sync_service_(sync_service),
28 state_(NOT_RUNNING),
29 abort_association_(false),
30 abort_association_complete_(false, false),
31 datatype_stopped_(false, false) {
32 DCHECK(profile_sync_factory);
33 DCHECK(profile);
34 DCHECK(sync_service);
35 } 23 }
36 24
37 PasswordDataTypeController::~PasswordDataTypeController() { 25 PasswordDataTypeController::~PasswordDataTypeController() {
38 } 26 }
39 27
40 void PasswordDataTypeController::Start(StartCallback* start_callback) { 28 bool PasswordDataTypeController::StartModels() {
41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 29 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
42 DCHECK(start_callback); 30 DCHECK_EQ(state(), MODEL_STARTING);
43 if (state_ != NOT_RUNNING) { 31 password_store_ = profile()->GetPasswordStore(Profile::EXPLICIT_ACCESS);
44 start_callback->Run(BUSY, FROM_HERE);
45 delete start_callback;
46 return;
47 }
48
49 password_store_ = profile_->GetPasswordStore(Profile::EXPLICIT_ACCESS);
50 if (!password_store_.get()) { 32 if (!password_store_.get()) {
51 LOG(ERROR) << "PasswordStore not initialized, password datatype controller" 33 LOG(ERROR) << "PasswordStore not initialized, password datatype controller"
52 << " aborting."; 34 << " aborting.";
53 state_ = NOT_RUNNING; 35 StartDoneImpl(ABORTED, NOT_RUNNING, FROM_HERE);
54 start_callback->Run(ABORTED, FROM_HERE); 36 return false;
55 delete start_callback;
56 return;
57 } 37 }
58
59 start_callback_.reset(start_callback);
60 abort_association_ = false;
61 set_state(ASSOCIATING);
62 password_store_->ScheduleTask(
63 NewRunnableMethod(this, &PasswordDataTypeController::StartImpl));
64 }
65
66 // TODO(sync): Blocking the UI thread at shutdown is bad. If we had a way of
67 // distinguishing chrome shutdown from sync shutdown, we should be able to avoid
68 // this (http://crbug.com/55662). Further, all this functionality should be
69 // abstracted to a higher layer, where we could ensure all datatypes are doing
70 // the same thing (http://crbug.com/76232).
71 void PasswordDataTypeController::Stop() {
72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
73
74 // If Stop() is called while Start() is waiting for association to
75 // complete, we need to abort the association and wait for the PASSWORD
76 // thread to finish the StartImpl() task.
77 if (state_ == ASSOCIATING) {
78 {
79 base::AutoLock lock(abort_association_lock_);
80 abort_association_ = true;
81 if (model_associator_.get())
82 model_associator_->AbortAssociation();
83 }
84 // Wait for the model association to abort.
85 abort_association_complete_.Wait();
86 StartDoneImpl(ABORTED, STOPPING);
87 }
88
89 // If Stop() is called while Start() is waiting for another service to load,
90 // abort the start.
91 if (state_ == MODEL_STARTING)
92 StartDoneImpl(ABORTED, STOPPING);
93
94 DCHECK(!start_callback_.get());
95
96 if (change_processor_ != NULL)
97 sync_service_->DeactivateDataType(this, change_processor_.get());
98
99 set_state(NOT_RUNNING);
100 DCHECK(password_store_.get());
101 password_store_->ScheduleTask(
102 NewRunnableMethod(this, &PasswordDataTypeController::StopImpl));
103 datatype_stopped_.Wait();
104 }
105
106 bool PasswordDataTypeController::enabled() {
107 return true; 38 return true;
108 } 39 }
109 40
41 bool PasswordDataTypeController::StartAssociationAsync() {
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
43 DCHECK_EQ(state(), ASSOCIATING);
44 DCHECK(password_store_.get());
45 password_store_->ScheduleTask(
46 NewRunnableMethod(this, &PasswordDataTypeController::StartAssociation));
47 return true;
48 }
49
50 void PasswordDataTypeController::CreateSyncComponents() {
51 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
52 DCHECK_EQ(state(), ASSOCIATING);
53 ProfileSyncFactory::SyncComponents sync_components =
54 profile_sync_factory()->CreatePasswordSyncComponents(
55 profile_sync_service(),
56 password_store_.get(),
57 this);
58 set_model_associator(sync_components.model_associator);
59 set_change_processor(sync_components.change_processor);
60 }
61
62 bool PasswordDataTypeController::StopAssociationAsync() {
63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
64 DCHECK_EQ(state(), STOPPING);
65 DCHECK(password_store_.get());
66 password_store_->ScheduleTask(
67 NewRunnableMethod(this, &PasswordDataTypeController::StopAssociation));
68 return true;
69 }
70
110 syncable::ModelType PasswordDataTypeController::type() const { 71 syncable::ModelType PasswordDataTypeController::type() const {
111 return syncable::PASSWORDS; 72 return syncable::PASSWORDS;
112 } 73 }
113 74
114 browser_sync::ModelSafeGroup PasswordDataTypeController::model_safe_group() 75 browser_sync::ModelSafeGroup PasswordDataTypeController::model_safe_group()
115 const { 76 const {
116 return browser_sync::GROUP_PASSWORD; 77 return browser_sync::GROUP_PASSWORD;
117 } 78 }
118 79
119 std::string PasswordDataTypeController::name() const { 80 void PasswordDataTypeController::RecordUnrecoverableError(
120 // For logging only. 81 const tracked_objects::Location& from_here,
121 return "password"; 82 const std::string& message) {
83 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
84 UMA_HISTOGRAM_COUNTS("Sync.PasswordRunFailures", 1);
122 } 85 }
123 86
124 DataTypeController::State PasswordDataTypeController::state() const { 87 void PasswordDataTypeController::RecordAssociationTime(base::TimeDelta time) {
125 return state_; 88 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
89 UMA_HISTOGRAM_TIMES("Sync.PasswordAssociationTime", time);
126 } 90 }
127 91
128 void PasswordDataTypeController::StartImpl() { 92 void PasswordDataTypeController::RecordStartFailure(StartResult result) {
129 // No additional services need to be started before we can proceed
130 // with model association.
131 {
132 base::AutoLock lock(abort_association_lock_);
133 if (abort_association_) {
134 abort_association_complete_.Signal();
135 return;
136 }
137 ProfileSyncFactory::SyncComponents sync_components =
138 profile_sync_factory_->CreatePasswordSyncComponents(
139 sync_service_,
140 password_store_.get(),
141 this);
142 model_associator_.reset(sync_components.model_associator);
143 change_processor_.reset(sync_components.change_processor);
144 }
145
146 if (!model_associator_->CryptoReadyIfNecessary()) {
147 StartFailed(NEEDS_CRYPTO);
148 return;
149 }
150
151 bool sync_has_nodes = false;
152 if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) {
153 StartFailed(UNRECOVERABLE_ERROR);
154 return;
155 }
156
157 base::TimeTicks start_time = base::TimeTicks::Now();
158 bool merge_success = model_associator_->AssociateModels();
159 UMA_HISTOGRAM_TIMES("Sync.PasswordAssociationTime",
160 base::TimeTicks::Now() - start_time);
161 if (!merge_success) {
162 StartFailed(ASSOCIATION_FAILED);
163 return;
164 }
165
166 sync_service_->ActivateDataType(this, change_processor_.get());
167 StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, RUNNING);
168 }
169
170 void PasswordDataTypeController::StartDone(
171 DataTypeController::StartResult result,
172 DataTypeController::State new_state) {
173 abort_association_complete_.Signal();
174 base::AutoLock lock(abort_association_lock_);
175 if (!abort_association_) {
176 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
177 NewRunnableMethod(
178 this,
179 &PasswordDataTypeController::StartDoneImpl,
180 result,
181 new_state));
182 }
183 }
184
185 void PasswordDataTypeController::StartDoneImpl(
186 DataTypeController::StartResult result,
187 DataTypeController::State new_state) {
188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
189 set_state(new_state); 94 UMA_HISTOGRAM_ENUMERATION("Sync.PasswordStartFailures",
190 start_callback_->Run(result, FROM_HERE); 95 result,
191 start_callback_.reset(); 96 MAX_START_RESULT);
192 }
193
194 void PasswordDataTypeController::StopImpl() {
195 if (model_associator_ != NULL)
196 model_associator_->DisassociateModels();
197
198 change_processor_.reset();
199 model_associator_.reset();
200
201 datatype_stopped_.Signal();
202 }
203
204 void PasswordDataTypeController::StartFailed(StartResult result) {
205 change_processor_.reset();
206 model_associator_.reset();
207 StartDone(result, NOT_RUNNING);
208 }
209
210 void PasswordDataTypeController::OnUnrecoverableError(
211 const tracked_objects::Location& from_here, const std::string& message) {
212 BrowserThread::PostTask(
213 BrowserThread::UI, FROM_HERE,
214 NewRunnableMethod(this,
215 &PasswordDataTypeController::OnUnrecoverableErrorImpl,
216 from_here, message));
217 }
218
219 void PasswordDataTypeController::OnUnrecoverableErrorImpl(
220 const tracked_objects::Location& from_here,
221 const std::string& message) {
222 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
223 sync_service_->OnUnrecoverableError(from_here, message);
224 } 97 }
225 98
226 } // namespace browser_sync 99 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/password_data_type_controller.h ('k') | chrome/browser/sync/glue/typed_url_data_type_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698