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 3// found in the LICENSE file. 4 5#include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h" 6 7#include "base/bind.h" 8#include "base/metrics/histogram.h" 9#include "chrome/browser/autofill/personal_data_manager_factory.h" 10#include "chrome/browser/profiles/profile.h" 11#include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h" 12#include "chrome/browser/sync/profile_sync_components_factory.h" 13#include "chrome/browser/webdata/web_data_service_factory.h" 14#include "components/autofill/core/browser/personal_data_manager.h" 15#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" 16#include "content/public/browser/browser_thread.h" 17#include "sync/api/sync_error.h" 18#include "sync/api/syncable_service.h" 19 20using autofill::AutofillWebDataService; 21using content::BrowserThread; 22 23namespace browser_sync { 24 25AutofillProfileDataTypeController::AutofillProfileDataTypeController( 26 ProfileSyncComponentsFactory* profile_sync_factory, 27 Profile* profile) 28 : NonUIDataTypeController( 29 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 30 base::Bind(&ChromeReportUnrecoverableError), 31 profile_sync_factory), 32 profile_(profile), 33 personal_data_(NULL), 34 callback_registered_(false) {} 35 36syncer::ModelType AutofillProfileDataTypeController::type() const { 37 return syncer::AUTOFILL_PROFILE; 38} 39 40syncer::ModelSafeGroup 41 AutofillProfileDataTypeController::model_safe_group() const { 42 return syncer::GROUP_DB; 43} 44 45void AutofillProfileDataTypeController::WebDatabaseLoaded() { 46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 47 OnModelLoaded(); 48} 49 50void AutofillProfileDataTypeController::OnPersonalDataChanged() { 51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 52 DCHECK_EQ(state(), MODEL_STARTING); 53 54 personal_data_->RemoveObserver(this); 55 autofill::AutofillWebDataService* web_data_service = 56 WebDataServiceFactory::GetAutofillWebDataForProfile( 57 profile_, Profile::EXPLICIT_ACCESS).get(); 58 59 if (!web_data_service) 60 return; 61 62 if (web_data_service->IsDatabaseLoaded()) { 63 OnModelLoaded(); 64 } else if (!callback_registered_) { 65 web_data_service->RegisterDBLoadedCallback(base::Bind( 66 &AutofillProfileDataTypeController::WebDatabaseLoaded, this)); 67 callback_registered_ = true; 68 } 69} 70 71AutofillProfileDataTypeController::~AutofillProfileDataTypeController() {} 72 73bool AutofillProfileDataTypeController::PostTaskOnBackendThread( 74 const tracked_objects::Location& from_here, 75 const base::Closure& task) { 76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 77 return BrowserThread::PostTask(BrowserThread::DB, from_here, task); 78} 79 80bool AutofillProfileDataTypeController::StartModels() { 81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 82 DCHECK_EQ(state(), MODEL_STARTING); 83 // Waiting for the personal data is subtle: we do this as the PDM resets 84 // its cache of unique IDs once it gets loaded. If we were to proceed with 85 // association, the local ids in the mappings would wind up colliding. 86 personal_data_ = 87 autofill::PersonalDataManagerFactory::GetForProfile(profile_); 88 if (!personal_data_->IsDataLoaded()) { 89 personal_data_->AddObserver(this); 90 return false; 91 } 92 93 autofill::AutofillWebDataService* web_data_service = 94 WebDataServiceFactory::GetAutofillWebDataForProfile( 95 profile_, Profile::EXPLICIT_ACCESS).get(); 96 97 if (!web_data_service) 98 return false; 99 100 if (web_data_service->IsDatabaseLoaded()) 101 return true; 102 103 if (!callback_registered_) { 104 web_data_service->RegisterDBLoadedCallback(base::Bind( 105 &AutofillProfileDataTypeController::WebDatabaseLoaded, this)); 106 callback_registered_ = true; 107 } 108 109 return false; 110} 111 112void AutofillProfileDataTypeController::StopModels() { 113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 114 personal_data_->RemoveObserver(this); 115} 116 117} // namespace browser_sync 118