password_data_type_controller.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2010 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 "base/histogram.h" 6#include "base/logging.h" 7#include "base/task.h" 8#include "base/time.h" 9#include "chrome/browser/chrome_thread.h" 10#include "chrome/browser/password_manager/password_store.h" 11#include "chrome/browser/profile.h" 12#include "chrome/browser/sync/glue/password_change_processor.h" 13#include "chrome/browser/sync/glue/password_data_type_controller.h" 14#include "chrome/browser/sync/glue/password_model_associator.h" 15#include "chrome/browser/sync/profile_sync_service.h" 16#include "chrome/browser/sync/profile_sync_factory.h" 17 18namespace browser_sync { 19 20PasswordDataTypeController::PasswordDataTypeController( 21 ProfileSyncFactory* profile_sync_factory, 22 Profile* profile, 23 ProfileSyncService* sync_service) 24 : profile_sync_factory_(profile_sync_factory), 25 profile_(profile), 26 sync_service_(sync_service), 27 state_(NOT_RUNNING) { 28 DCHECK(profile_sync_factory); 29 DCHECK(profile); 30 DCHECK(sync_service); 31} 32 33PasswordDataTypeController::~PasswordDataTypeController() { 34} 35 36void PasswordDataTypeController::Start(StartCallback* start_callback) { 37 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 38 DCHECK(start_callback); 39 if (state_ != NOT_RUNNING) { 40 start_callback->Run(BUSY); 41 delete start_callback; 42 return; 43 } 44 45 if (!sync_service_->IsCryptographerReady()) { 46 start_callback->Run(NEEDS_CRYPTO); 47 delete start_callback; 48 return; 49 } 50 51 start_callback_.reset(start_callback); 52 53 set_state(ASSOCIATING); 54 password_store_ = profile_->GetPasswordStore(Profile::EXPLICIT_ACCESS); 55 DCHECK(password_store_.get()); 56 password_store_->ScheduleTask( 57 NewRunnableMethod(this, &PasswordDataTypeController::StartImpl)); 58} 59 60void PasswordDataTypeController::Stop() { 61 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 62 63 if (change_processor_ != NULL) 64 sync_service_->DeactivateDataType(this, change_processor_.get()); 65 66 if (model_associator_ != NULL) 67 model_associator_->DisassociateModels(); 68 69 set_state(NOT_RUNNING); 70 DCHECK(password_store_.get()); 71 password_store_->ScheduleTask( 72 NewRunnableMethod(this, &PasswordDataTypeController::StopImpl)); 73} 74 75void PasswordDataTypeController::StartImpl() { 76 // No additional services need to be started before we can proceed 77 // with model association. 78 ProfileSyncFactory::SyncComponents sync_components = 79 profile_sync_factory_->CreatePasswordSyncComponents( 80 sync_service_, 81 password_store_.get(), 82 this); 83 model_associator_.reset(sync_components.model_associator); 84 change_processor_.reset(sync_components.change_processor); 85 86 bool sync_has_nodes = false; 87 if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { 88 StartFailed(UNRECOVERABLE_ERROR); 89 return; 90 } 91 92 base::TimeTicks start_time = base::TimeTicks::Now(); 93 bool merge_success = model_associator_->AssociateModels(); 94 UMA_HISTOGRAM_TIMES("Sync.PasswordAssociationTime", 95 base::TimeTicks::Now() - start_time); 96 if (!merge_success) { 97 StartFailed(ASSOCIATION_FAILED); 98 return; 99 } 100 101 sync_service_->ActivateDataType(this, change_processor_.get()); 102 StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, RUNNING); 103} 104 105void PasswordDataTypeController::StartDone( 106 DataTypeController::StartResult result, 107 DataTypeController::State new_state) { 108 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, 109 NewRunnableMethod( 110 this, 111 &PasswordDataTypeController::StartDoneImpl, 112 result, 113 new_state)); 114} 115 116void PasswordDataTypeController::StartDoneImpl( 117 DataTypeController::StartResult result, 118 DataTypeController::State new_state) { 119 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 120 set_state(new_state); 121 start_callback_->Run(result); 122 start_callback_.reset(); 123} 124 125void PasswordDataTypeController::StopImpl() { 126 change_processor_.reset(); 127 model_associator_.reset(); 128 129 state_ = NOT_RUNNING; 130} 131 132void PasswordDataTypeController::StartFailed(StartResult result) { 133 change_processor_.reset(); 134 model_associator_.reset(); 135 StartDone(result, NOT_RUNNING); 136} 137 138void PasswordDataTypeController::OnUnrecoverableError( 139 const tracked_objects::Location& from_here, const std::string& message) { 140 ChromeThread::PostTask( 141 ChromeThread::UI, FROM_HERE, 142 NewRunnableMethod(this, 143 &PasswordDataTypeController::OnUnrecoverableErrorImpl, 144 from_here, message)); 145} 146 147void PasswordDataTypeController::OnUnrecoverableErrorImpl( 148 const tracked_objects::Location& from_here, 149 const std::string& message) { 150 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 151 sync_service_->OnUnrecoverableError(from_here, message); 152} 153 154} // namespace browser_sync 155