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

Unified Diff: chrome/browser/sync/glue/autofill_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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/sync/glue/autofill_data_type_controller.cc
diff --git a/chrome/browser/sync/glue/autofill_data_type_controller.cc b/chrome/browser/sync/glue/autofill_data_type_controller.cc
index fa5dde46e4ccbaaf2778ecafc79a77a26585f909..a4f0e665e1c974c7068ad69e0e73dbdf656e64f2 100644
--- a/chrome/browser/sync/glue/autofill_data_type_controller.cc
+++ b/chrome/browser/sync/glue/autofill_data_type_controller.cc
@@ -4,165 +4,118 @@
#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
-#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/task.h"
-#include "base/time.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/glue/autofill_change_processor.h"
-#include "chrome/browser/sync/glue/autofill_model_associator.h"
#include "chrome/browser/sync/profile_sync_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/webdata/web_data_service.h"
#include "content/browser/browser_thread.h"
#include "content/common/notification_service.h"
+#include "content/common/notification_source.h"
+#include "content/common/notification_type.h"
namespace browser_sync {
AutofillDataTypeController::AutofillDataTypeController(
ProfileSyncFactory* profile_sync_factory,
- Profile* profile,
- ProfileSyncService* sync_service)
- : profile_sync_factory_(profile_sync_factory),
- profile_(profile),
- sync_service_(sync_service),
- state_(NOT_RUNNING),
- personal_data_(NULL),
- abort_association_(false),
- abort_association_complete_(false, false),
- datatype_stopped_(false, false) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(profile_sync_factory);
- DCHECK(profile);
- DCHECK(sync_service);
+ Profile* profile)
+ : NonFrontendDataTypeController(profile_sync_factory,
+ profile),
+ personal_data_(NULL) {
}
AutofillDataTypeController::~AutofillDataTypeController() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // TODO(zea): remove once crbug.com/61804 is resolved.
- CHECK_EQ(state_, NOT_RUNNING) << "AutofillDataTypeController destroyed "
- << "without being stopped.";
- CHECK(!change_processor_.get()) << "AutofillDataTypeController destroyed "
- << "while holding a change processor.";
}
-void AutofillDataTypeController::Start(StartCallback* start_callback) {
- VLOG(1) << "Starting autofill data controller.";
+bool AutofillDataTypeController::StartModels() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(start_callback);
- if (state() != NOT_RUNNING) {
- start_callback->Run(BUSY, FROM_HERE);
- delete start_callback;
- return;
- }
-
- start_callback_.reset(start_callback);
- abort_association_ = false;
-
+ DCHECK_EQ(state(), MODEL_STARTING);
// Waiting for the personal data is subtle: we do this as the PDM resets
// its cache of unique IDs once it gets loaded. If we were to proceed with
// association, the local ids in the mappings would wind up colliding.
- personal_data_ = profile_->GetPersonalDataManager();
+ personal_data_ = profile()->GetPersonalDataManager();
if (!personal_data_->IsDataLoaded()) {
- set_state(MODEL_STARTING);
personal_data_->SetObserver(this);
- return;
+ return false;
}
- ContinueStartAfterPersonalDataLoaded();
-}
-
-void AutofillDataTypeController::ContinueStartAfterPersonalDataLoaded() {
- web_data_service_ = profile_->GetWebDataService(Profile::IMPLICIT_ACCESS);
+ web_data_service_ = profile()->GetWebDataService(Profile::IMPLICIT_ACCESS);
if (web_data_service_.get() && web_data_service_->IsDatabaseLoaded()) {
- set_state(ASSOCIATING);
- BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
- NewRunnableMethod(
- this,
- &AutofillDataTypeController::StartImpl));
+ return true;
} else {
- set_state(MODEL_STARTING);
notification_registrar_.Add(this, NotificationType::WEB_DATABASE_LOADED,
NotificationService::AllSources());
+ return false;
}
}
void AutofillDataTypeController::OnPersonalDataLoaded() {
- DCHECK_EQ(state_, MODEL_STARTING);
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_EQ(state(), MODEL_STARTING);
personal_data_->RemoveObserver(this);
- ContinueStartAfterPersonalDataLoaded();
+ web_data_service_ = profile()->GetWebDataService(Profile::IMPLICIT_ACCESS);
+ if (web_data_service_.get() && web_data_service_->IsDatabaseLoaded()) {
+ set_state(ASSOCIATING);
+ if (!StartAssociationAsync()) {
+ StartDoneImpl(ASSOCIATION_FAILED, NOT_RUNNING, FROM_HERE);
+ }
+ } else {
+ notification_registrar_.Add(this, NotificationType::WEB_DATABASE_LOADED,
+ NotificationService::AllSources());
+ }
}
void AutofillDataTypeController::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
- VLOG(1) << "Web database loaded observed.";
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_EQ(state(), MODEL_STARTING);
notification_registrar_.RemoveAll();
set_state(ASSOCIATING);
- BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
- NewRunnableMethod(
- this,
- &AutofillDataTypeController::StartImpl));
+ if (!StartAssociationAsync()) {
+ StartDoneImpl(ASSOCIATION_FAILED, NOT_RUNNING, FROM_HERE);
+ }
}
-// TODO(sync): Blocking the UI thread at shutdown is bad. If we had a way of
-// distinguishing chrome shutdown from sync shutdown, we should be able to avoid
-// this (http://crbug.com/55662). Further, all this functionality should be
-// abstracted to a higher layer, where we could ensure all datatypes are doing
-// the same thing (http://crbug.com/76232).
-void AutofillDataTypeController::Stop() {
- VLOG(1) << "Stopping autofill data type controller.";
+bool AutofillDataTypeController::StartAssociationAsync() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_EQ(state(), ASSOCIATING);
+ return BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &AutofillDataTypeController::StartAssociation));
+}
- // If Stop() is called while Start() is waiting for association to
- // complete, we need to abort the association and wait for the DB
- // thread to finish the StartImpl() task.
- if (state_ == ASSOCIATING) {
- {
- base::AutoLock lock(abort_association_lock_);
- abort_association_ = true;
- if (model_associator_.get())
- model_associator_->AbortAssociation();
- }
- // Wait for the model association to abort.
- abort_association_complete_.Wait();
- StartDoneImpl(ABORTED, STOPPING, FROM_HERE);
- }
-
- // If Stop() is called while Start() is waiting for the personal
- // data manager or web data service to load, abort the start.
- if (state_ == MODEL_STARTING)
- StartDoneImpl(ABORTED, STOPPING, FROM_HERE);
-
- DCHECK(!start_callback_.get());
-
- // Deactivate the change processor on the UI thread. We dont want to listen
- // for any more changes or process them from server.
+void AutofillDataTypeController::CreateSyncComponents() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK_EQ(state(), ASSOCIATING);
+ ProfileSyncFactory::SyncComponents sync_components =
+ profile_sync_factory()->
+ CreateAutofillSyncComponents(
+ profile_sync_service(),
+ web_data_service_->GetDatabase(),
+ personal_data_,
+ this);
+ set_model_associator(sync_components.model_associator);
+ set_change_processor(sync_components.change_processor);
+}
+
+void AutofillDataTypeController::StopModels() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(state() == STOPPING || state() == NOT_RUNNING);
notification_registrar_.RemoveAll();
personal_data_->RemoveObserver(this);
- if (change_processor_ != NULL && change_processor_->IsRunning())
- sync_service_->DeactivateDataType(this, change_processor_.get());
-
- set_state(NOT_RUNNING);
- if (BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
- NewRunnableMethod(
- this,
- &AutofillDataTypeController::StopImpl))) {
- // We need to ensure the data type has fully stoppped before continuing. In
- // particular, during shutdown we may attempt to destroy the
- // profile_sync_service before we've removed its observers (BUG 61804).
- datatype_stopped_.Wait();
- } else if (change_processor_.get()) {
- // TODO(zea): remove once crbug.com/61804 is resolved.
- LOG(FATAL) << "AutofillDataTypeController::Stop() called after DB thread"
- << " killed.";
- }
- CHECK(!change_processor_.get()) << "AutofillChangeProcessor not released.";
}
-bool AutofillDataTypeController::enabled() {
- return true;
+bool AutofillDataTypeController::StopAssociationAsync() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_EQ(state(), STOPPING);
+ return BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &AutofillDataTypeController::StopAssociation));
}
syncable::ModelType AutofillDataTypeController::type() const {
@@ -174,150 +127,31 @@ browser_sync::ModelSafeGroup AutofillDataTypeController::model_safe_group()
return browser_sync::GROUP_DB;
}
-std::string AutofillDataTypeController::name() const {
- // For logging only.
- return "autofill";
-}
-
-DataTypeController::State AutofillDataTypeController::state() const {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- return state_;
-}
-
-ProfileSyncFactory::SyncComponents
- AutofillDataTypeController::CreateSyncComponents(
- ProfileSyncService* profile_sync_service,
- WebDatabase* web_database,
- PersonalDataManager* personal_data,
- browser_sync::UnrecoverableErrorHandler* error_handler) {
- return profile_sync_factory_->CreateAutofillSyncComponents(
- profile_sync_service,
- web_database,
- personal_data,
- this);
-}
-
-void AutofillDataTypeController::StartImpl() {
- VLOG(1) << "Autofill data type controller StartImpl called.";
+void AutofillDataTypeController::RecordUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- // No additional services need to be started before we can proceed
- // with model association.
- {
- base::AutoLock lock(abort_association_lock_);
- if (abort_association_) {
- abort_association_complete_.Signal();
- return;
- }
- ProfileSyncFactory::SyncComponents sync_components =
- CreateSyncComponents(
- sync_service_,
- web_data_service_->GetDatabase(),
- profile_->GetPersonalDataManager(),
- this);
- model_associator_.reset(sync_components.model_associator);
- change_processor_.reset(sync_components.change_processor);
- }
-
- if (!model_associator_->CryptoReadyIfNecessary()) {
- StartFailed(NEEDS_CRYPTO);
- return;
- }
-
- bool sync_has_nodes = false;
- if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) {
- StartFailed(UNRECOVERABLE_ERROR);
- return;
- }
-
- base::TimeTicks start_time = base::TimeTicks::Now();
- bool merge_success = model_associator_->AssociateModels();
- UMA_HISTOGRAM_TIMES("Sync.AutofillAssociationTime",
- base::TimeTicks::Now() - start_time);
- VLOG(1) << "Autofill association time: " <<
- (base::TimeTicks::Now() - start_time).InSeconds();
- if (!merge_success) {
- StartFailed(ASSOCIATION_FAILED);
- return;
- }
-
- sync_service_->ActivateDataType(this, change_processor_.get());
- StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, RUNNING);
+ UMA_HISTOGRAM_COUNTS("Sync.AutofillRunFailures", 1);
}
-void AutofillDataTypeController::StartDone(
- DataTypeController::StartResult result,
- DataTypeController::State new_state) {
- VLOG(1) << "Autofill data type controller StartDone called.";
+void AutofillDataTypeController::RecordAssociationTime(base::TimeDelta time) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
-
- abort_association_complete_.Signal();
- base::AutoLock lock(abort_association_lock_);
- if (!abort_association_) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- this,
- &AutofillDataTypeController::StartDoneImpl,
- result,
- new_state,
- FROM_HERE));
- }
+ UMA_HISTOGRAM_TIMES("Sync.AutofillAssociationTime", time);
}
-void AutofillDataTypeController::StartDoneImpl(
- DataTypeController::StartResult result,
- DataTypeController::State new_state,
- const tracked_objects::Location& location) {
- VLOG(1) << "Autofill data type controller StartDoneImpl called.";
+void AutofillDataTypeController::RecordStartFailure(StartResult result) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- set_state(new_state);
- start_callback_->Run(result, location);
- start_callback_.reset();
-
- if (result == UNRECOVERABLE_ERROR || result == ASSOCIATION_FAILED) {
- UMA_HISTOGRAM_ENUMERATION("Sync.AutofillStartFailures",
- result,
- MAX_START_RESULT);
- }
+ UMA_HISTOGRAM_ENUMERATION("Sync.AutofillStartFailures",
+ result,
+ MAX_START_RESULT);
}
-void AutofillDataTypeController::StopImpl() {
- VLOG(1) << "Autofill data type controller StopImpl called.";
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
-
- if (model_associator_ != NULL)
- model_associator_->DisassociateModels();
-
- change_processor_.reset();
- model_associator_.reset();
-
- datatype_stopped_.Signal();
+PersonalDataManager* AutofillDataTypeController::personal_data() const {
+ return personal_data_;
}
-void AutofillDataTypeController::StartFailed(StartResult result) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- change_processor_.reset();
- model_associator_.reset();
- StartDone(result, NOT_RUNNING);
-}
-
-void AutofillDataTypeController::OnUnrecoverableError(
- const tracked_objects::Location& from_here,
- const std::string& message) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this,
- &AutofillDataTypeController::OnUnrecoverableErrorImpl,
- from_here, message));
- UMA_HISTOGRAM_COUNTS("Sync.AutofillRunFailures", 1);
-}
-
-void AutofillDataTypeController::OnUnrecoverableErrorImpl(
- const tracked_objects::Location& from_here,
- const std::string& message) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- sync_service_->OnUnrecoverableError(from_here, message);
+WebDataService* AutofillDataTypeController::web_data_service() const {
+ return web_data_service_;
}
} // namespace browser_sync

Powered by Google App Engine
This is Rietveld 408576698