1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/password_change_processor.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <string> 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/password_store.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/password_store_change.h" 1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/password_model_associator.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/profile_sync_service.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/protocol/password_specifics.pb.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_details.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_source.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/password_form.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync { 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPasswordChangeProcessor::PasswordChangeProcessor( 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordModelAssociator* model_associator, 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordStore* password_store, 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UnrecoverableErrorHandler* error_handler) 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : ChangeProcessor(error_handler), 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_associator_(model_associator), 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch password_store_(password_store), 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observing_(false), 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch expected_loop_(MessageLoop::current()) { 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(model_associator); 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(error_handler); 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX) 36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StartObserving(); 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochPasswordChangeProcessor::~PasswordChangeProcessor() { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(expected_loop_ == MessageLoop::current()); 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PasswordChangeProcessor::Observe(NotificationType type, 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationDetails& details) { 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(expected_loop_ == MessageLoop::current()); 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(NotificationType::LOGINS_CHANGED == type); 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!observing_) 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(running()); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::WriteTransaction trans(share_handle()); 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::ReadNode password_root(&trans); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!password_root.InitByTagLookup(kPasswordTag)) { 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_handler()->OnUnrecoverableError(FROM_HERE, 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Server did not create the top-level password node. " 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "We might be running against an out-of-date server."); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordStoreChangeList* changes = 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<PasswordStoreChangeList>(details).ptr(); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (PasswordStoreChangeList::iterator change = changes->begin(); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch change != changes->end(); ++change) { 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string tag = PasswordModelAssociator::MakeTag(change->form()); 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (change->type()) { 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case PasswordStoreChange::ADD: { 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::WriteNode sync_node(&trans); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!sync_node.InitUniqueByCreation(syncable::PASSWORDS, 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch password_root, tag)) { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_handler()->OnUnrecoverableError(FROM_HERE, 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Failed to create password sync node."); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordModelAssociator::WriteToSyncNode(change->form(), &sync_node); 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_associator_->Associate(&tag, sync_node.GetId()); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case PasswordStoreChange::UPDATE: { 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::WriteNode sync_node(&trans); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int64 sync_id = model_associator_->GetSyncIdFromChromeId(tag); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sync_api::kInvalidId == sync_id) { 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_handler()->OnUnrecoverableError(FROM_HERE, 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Unexpected notification for: "); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!sync_node.InitByIdLookup(sync_id)) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_handler()->OnUnrecoverableError(FROM_HERE, 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Password node lookup failed."); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordModelAssociator::WriteToSyncNode(change->form(), &sync_node); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case PasswordStoreChange::REMOVE: { 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::WriteNode sync_node(&trans); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int64 sync_id = model_associator_->GetSyncIdFromChromeId(tag); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sync_api::kInvalidId == sync_id) { 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_handler()->OnUnrecoverableError(FROM_HERE, 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Unexpected notification"); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!sync_node.InitByIdLookup(sync_id)) { 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_handler()->OnUnrecoverableError(FROM_HERE, 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Password node lookup failed."); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_associator_->Disassociate(sync_node.GetId()); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_node.Remove(); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PasswordChangeProcessor::ApplyChangesFromSyncModel( 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sync_api::BaseTransaction* trans, 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sync_api::SyncManager::ChangeRecord* changes, 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int change_count) { 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(expected_loop_ == MessageLoop::current()); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!running()) 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::ReadNode password_root(trans); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!password_root.InitByTagLookup(kPasswordTag)) { 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_handler()->OnUnrecoverableError(FROM_HERE, 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Password root node lookup failed."); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(deleted_passwords_.empty() && new_passwords_.empty() && 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen updated_passwords_.empty()); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < change_count; ++i) { 1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE == 1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick changes[i].action) { 1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(changes[i].specifics.HasExtension(sync_pb::password)) 1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << "Password specifics data not present on delete!"; 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(changes[i].extra.get()); 1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sync_api::SyncManager::ExtraPasswordChangeRecordData* extra = 151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen changes[i].extra.get(); 1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const sync_pb::PasswordSpecificsData& password = extra->unencrypted(); 1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick webkit_glue::PasswordForm form; 1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PasswordModelAssociator::CopyPassword(password, &form); 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen deleted_passwords_.push_back(form); 1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model_associator_->Disassociate(changes[i].id); 1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick continue; 1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::ReadNode sync_node(trans); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!sync_node.InitByIdLookup(changes[i].id)) { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_handler()->OnUnrecoverableError(FROM_HERE, 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Password node lookup failed."); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check that the changed node is a child of the passwords folder. 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(password_root.GetId() == sync_node.GetParentId()); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(syncable::PASSWORDS == sync_node.GetModelType()); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sync_pb::PasswordSpecificsData& password_data = 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_node.GetPasswordSpecifics(); 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch webkit_glue::PasswordForm password; 1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PasswordModelAssociator::CopyPassword(password_data, &password); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sync_api::SyncManager::ChangeRecord::ACTION_ADD == changes[i].action) { 1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string tag(PasswordModelAssociator::MakeTag(password)); 1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model_associator_->Associate(&tag, sync_node.GetId()); 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new_passwords_.push_back(password); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(sync_api::SyncManager::ChangeRecord::ACTION_UPDATE == 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch changes[i].action); 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen updated_passwords_.push_back(password); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PasswordChangeProcessor::CommitChangesFromSyncModel() { 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(expected_loop_ == MessageLoop::current()); 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!running()) 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StopObserving(); 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!model_associator_->WriteToPasswordStore(&new_passwords_, 195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &updated_passwords_, 196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &deleted_passwords_)) { 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_handler()->OnUnrecoverableError(FROM_HERE, "Error writing passwords"); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen deleted_passwords_.clear(); 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new_passwords_.clear(); 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen updated_passwords_.clear(); 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StartObserving(); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PasswordChangeProcessor::StartImpl(Profile* profile) { 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(expected_loop_ == MessageLoop::current()); 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observing_ = true; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PasswordChangeProcessor::StopImpl() { 214731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observing_ = false; 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PasswordChangeProcessor::StartObserving() { 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(expected_loop_ == MessageLoop::current()); 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch notification_registrar_.Add(this, 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::LOGINS_CHANGED, 223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Source<PasswordStore>(password_store_)); 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PasswordChangeProcessor::StopObserving() { 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(expected_loop_ == MessageLoop::current()); 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch notification_registrar_.Remove(this, 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::LOGINS_CHANGED, 230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Source<PasswordStore>(password_store_)); 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace browser_sync 234