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