| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h" |
| |
| #include "base/bind.h" |
| #include "base/metrics/histogram.h" |
| #include "chrome/browser/autofill/personal_data_manager_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/sync/profile_sync_components_factory.h" |
| #include "chrome/browser/sync/profile_sync_service.h" |
| #include "chrome/browser/webdata/web_data_service_factory.h" |
| #include "components/autofill/core/browser/personal_data_manager.h" |
| #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "sync/api/sync_error.h" |
| #include "sync/api/syncable_service.h" |
| |
| using autofill::AutofillWebDataService; |
| using content::BrowserThread; |
| |
| namespace browser_sync { |
| |
| AutofillProfileDataTypeController::AutofillProfileDataTypeController( |
| ProfileSyncComponentsFactory* profile_sync_factory, |
| Profile* profile, |
| ProfileSyncService* sync_service) |
| : NonUIDataTypeController(profile_sync_factory, |
| profile, |
| sync_service), |
| personal_data_(NULL), |
| callback_registered_(false) {} |
| |
| syncer::ModelType AutofillProfileDataTypeController::type() const { |
| return syncer::AUTOFILL_PROFILE; |
| } |
| |
| syncer::ModelSafeGroup |
| AutofillProfileDataTypeController::model_safe_group() const { |
| return syncer::GROUP_DB; |
| } |
| |
| void AutofillProfileDataTypeController::WebDatabaseLoaded() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| OnModelLoaded(); |
| } |
| |
| void AutofillProfileDataTypeController::OnPersonalDataChanged() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| DCHECK_EQ(state(), MODEL_STARTING); |
| |
| personal_data_->RemoveObserver(this); |
| autofill::AutofillWebDataService* web_data_service = |
| WebDataServiceFactory::GetAutofillWebDataForProfile( |
| profile(), Profile::EXPLICIT_ACCESS).get(); |
| |
| if (!web_data_service) |
| return; |
| |
| if (web_data_service->IsDatabaseLoaded()) { |
| OnModelLoaded(); |
| } else if (!callback_registered_) { |
| web_data_service->RegisterDBLoadedCallback(base::Bind( |
| &AutofillProfileDataTypeController::WebDatabaseLoaded, this)); |
| callback_registered_ = true; |
| } |
| } |
| |
| AutofillProfileDataTypeController::~AutofillProfileDataTypeController() {} |
| |
| bool AutofillProfileDataTypeController::PostTaskOnBackendThread( |
| const tracked_objects::Location& from_here, |
| const base::Closure& task) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| return BrowserThread::PostTask(BrowserThread::DB, from_here, task); |
| } |
| |
| 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_ = |
| autofill::PersonalDataManagerFactory::GetForProfile(profile()); |
| if (!personal_data_->IsDataLoaded()) { |
| personal_data_->AddObserver(this); |
| return false; |
| } |
| |
| autofill::AutofillWebDataService* web_data_service = |
| WebDataServiceFactory::GetAutofillWebDataForProfile( |
| profile(), Profile::EXPLICIT_ACCESS).get(); |
| |
| if (!web_data_service) |
| return false; |
| |
| if (web_data_service->IsDatabaseLoaded()) |
| return true; |
| |
| if (!callback_registered_) { |
| web_data_service->RegisterDBLoadedCallback(base::Bind( |
| &AutofillProfileDataTypeController::WebDatabaseLoaded, this)); |
| callback_registered_ = true; |
| } |
| |
| return false; |
| } |
| |
| void AutofillProfileDataTypeController::StopModels() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| personal_data_->RemoveObserver(this); |
| } |
| |
| } // namepsace browser_sync |