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