Index: chrome/browser/sync/glue/autofill_profile_data_type_controller.cc |
diff --git a/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc b/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc |
index a731eeada4e5e3b7f88115461bd7a9d8ac5436b3..ee1a29ccdaab3d6492702660196942806604cdd9 100644 |
--- a/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc |
+++ b/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc |
@@ -5,32 +5,125 @@ |
#include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h" |
#include "base/metrics/histogram.h" |
+#include "base/task.h" |
+#include "chrome/browser/autofill/personal_data_manager.h" |
+#include "chrome/browser/autofill/personal_data_manager_factory.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/sync/api/sync_error.h" |
+#include "chrome/browser/sync/api/syncable_service.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 "chrome/common/chrome_notification_types.h" |
+#include "content/browser/browser_thread.h" |
+#include "content/common/notification_service.h" |
+#include "content/common/notification_source.h" |
namespace browser_sync { |
AutofillProfileDataTypeController::AutofillProfileDataTypeController( |
ProfileSyncFactory* profile_sync_factory, |
Profile* profile) |
- : AutofillDataTypeController(profile_sync_factory, profile) {} |
+ : NewNonFrontendDataTypeController(profile_sync_factory, profile), |
+ personal_data_(NULL) { |
+} |
AutofillProfileDataTypeController::~AutofillProfileDataTypeController() {} |
+bool AutofillProfileDataTypeController::StartModels() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ 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_ = PersonalDataManagerFactory::GetForProfile(profile()); |
+ if (!personal_data_->IsDataLoaded()) { |
+ personal_data_->SetObserver(this); |
+ return false; |
+ } |
+ |
+ web_data_service_ = profile()->GetWebDataService(Profile::IMPLICIT_ACCESS); |
+ if (web_data_service_.get() && web_data_service_->IsDatabaseLoaded()) { |
+ return true; |
+ } else { |
+ notification_registrar_.Add(this, chrome::NOTIFICATION_WEB_DATABASE_LOADED, |
+ NotificationService::AllSources()); |
+ return false; |
+ } |
+} |
+ |
+void AutofillProfileDataTypeController::OnPersonalDataChanged() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK_EQ(state(), MODEL_STARTING); |
+ personal_data_->RemoveObserver(this); |
+ web_data_service_ = profile()->GetWebDataService(Profile::IMPLICIT_ACCESS); |
+ if (web_data_service_.get() && web_data_service_->IsDatabaseLoaded()) { |
+ set_state(ASSOCIATING); |
+ if (!StartAssociationAsync()) { |
+ SyncError error(FROM_HERE, |
+ "Failed to post association task.", |
+ type()); |
+ StartDoneImpl(ASSOCIATION_FAILED, NOT_RUNNING, error); |
+ } |
+ } else { |
+ notification_registrar_.Add(this, chrome::NOTIFICATION_WEB_DATABASE_LOADED, |
+ NotificationService::AllSources()); |
+ } |
+} |
+ |
+void AutofillProfileDataTypeController::Observe( |
+ int notification_type, |
+ const NotificationSource& source, |
+ const NotificationDetails& details) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK_EQ(state(), MODEL_STARTING); |
+ notification_registrar_.RemoveAll(); |
+ set_state(ASSOCIATING); |
+ if (!StartAssociationAsync()) { |
+ SyncError error(FROM_HERE, |
+ "Failed to post association task.", |
+ type()); |
+ StartDoneImpl(ASSOCIATION_FAILED, NOT_RUNNING, error); |
+ } |
+} |
+ |
+bool AutofillProfileDataTypeController::StartAssociationAsync() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK_EQ(state(), ASSOCIATING); |
+ return BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, |
+ base::Bind(&AutofillProfileDataTypeController::StartAssociation, |
+ this)); |
+} |
+ |
+SyncableService* AutofillProfileDataTypeController::GetSyncableService() const { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
+ return profile_sync_factory()->CreateAutofillProfileSyncComponents( |
+ profile_sync_service(), |
+ web_data_service_->GetDatabase()); |
+} |
+ |
+bool AutofillProfileDataTypeController::StopLocalServiceAsync() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ return BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, |
+ base::Bind( |
+ &AutofillProfileDataTypeController::StopLocalService, |
+ local_service(), type())); |
+} |
+ |
+void AutofillProfileDataTypeController::StopModels() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK(state() == STOPPING || state() == NOT_RUNNING); |
+ notification_registrar_.RemoveAll(); |
+ personal_data_->RemoveObserver(this); |
+} |
+ |
syncable::ModelType AutofillProfileDataTypeController::type() const { |
return syncable::AUTOFILL_PROFILE; |
} |
-void AutofillProfileDataTypeController::CreateSyncComponents() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
- ProfileSyncFactory::SyncComponents sync_components = |
- profile_sync_factory()-> |
- CreateAutofillProfileSyncComponents( |
- profile_sync_service(), |
- web_data_service()->GetDatabase(), |
- this); |
- set_model_associator(sync_components.model_associator); |
- set_change_processor(sync_components.change_processor); |
+browser_sync::ModelSafeGroup |
+ AutofillProfileDataTypeController::model_safe_group() const { |
+ return browser_sync::GROUP_DB; |
} |
void AutofillProfileDataTypeController::RecordUnrecoverableError( |