Home | History | Annotate | Download | only in glue
      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