1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be
3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file.
4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/sync/glue/autofill_profile_change_processor.h"
6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <string>
8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <vector>
9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/string_util.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/utf_string_conversions.h"
12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/autofill/autofill_profile.h"
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/autofill/personal_data_manager.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/sync/engine/syncapi.h"
15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/sync/glue/autofill_profile_model_associator.h"
16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/sync/glue/change_processor.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/sync/glue/do_optimistic_refresh_task.h"
18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/sync/unrecoverable_error_handler.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/webdata/autofill_change.h"
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/webdata/web_database.h"
21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/guid.h"
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_registrar.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace browser_sync {
27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
28dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAutofillProfileChangeProcessor::AutofillProfileChangeProcessor(
29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      AutofillProfileModelAssociator *model_associator,
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      WebDatabase* web_database,
31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      PersonalDataManager* personal_data_manager,
32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      UnrecoverableErrorHandler* error_handler)
33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      : ChangeProcessor(error_handler),
34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        model_associator_(model_associator),
35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        observing_(false),
36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        web_database_(web_database),
37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        personal_data_(personal_data_manager) {
38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(model_associator);
39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(web_database);
40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(error_handler);
41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(personal_data_manager);
42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartObserving();
45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
47dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAutofillProfileChangeProcessor::~AutofillProfileChangeProcessor() {}
48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
49dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAutofillProfileChangeProcessor::ScopedStopObserving::ScopedStopObserving(
50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    AutofillProfileChangeProcessor* processor) {
51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  processor_ = processor;
52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  processor_->StopObserving();
53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
55dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAutofillProfileChangeProcessor::ScopedStopObserving::~ScopedStopObserving() {
56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  processor_->StartObserving();
57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::ApplyChangesFromSyncModel(
60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const sync_api::BaseTransaction *write_trans,
61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const sync_api::SyncManager::ChangeRecord* changes,
62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    int change_count) {
63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ScopedStopObserving observer(this);
65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  sync_api::ReadNode autofill_profile_root(write_trans);
67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!autofill_profile_root.InitByTagLookup(kAutofillProfileTag)) {
68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    error_handler()->OnUnrecoverableError(FROM_HERE,
69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "Autofill Profile root node lookup failed");
70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (int i = 0; i < change_count; ++i) {
74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE ==
75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        changes[i].action) {
76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      DCHECK(changes[i].specifics.HasExtension(
77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          sync_pb::autofill_profile));
78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      const sync_pb::AutofillProfileSpecifics& specifics =
80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          changes[i].specifics.GetExtension(sync_pb::autofill_profile);
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      autofill_changes_.push_back(AutofillProfileChangeRecord(changes[i].action,
83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          changes[i].id,
84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          specifics));
85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      continue;
86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // If it is not a delete.
89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    sync_api::ReadNode sync_node(write_trans);
90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (!sync_node.InitByIdLookup(changes[i].id)) {
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      LOG(ERROR) << "Could not find the id in sync db " << changes[i].id;
92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      continue;
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const sync_pb::AutofillProfileSpecifics& autofill(
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        sync_node.GetAutofillProfileSpecifics());
97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    autofill_changes_.push_back(AutofillProfileChangeRecord(changes[i].action,
99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        changes[i].id,
100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        autofill));
101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::Observe(NotificationType type,
105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const NotificationSource& source,
106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const NotificationDetails& details) {
107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK_EQ(type.value, NotificationType::AUTOFILL_PROFILE_CHANGED);
108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  WebDataService* wds = Source<WebDataService>(source).ptr();
109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!wds || wds->GetDatabase() != web_database_)
111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  sync_api::WriteTransaction trans(share_handle());
114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  sync_api::ReadNode autofill_root(&trans);
115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!autofill_root.InitByTagLookup(kAutofillProfileTag)) {
116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    error_handler()->OnUnrecoverableError(FROM_HERE,
117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        "Server did not create a tolp level node");
118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  AutofillProfileChange* change = Details<AutofillProfileChange>(details).ptr();
122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ActOnChange(change, &trans, autofill_root);
124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::ActOnChange(
127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen     AutofillProfileChange* change,
128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen     sync_api::WriteTransaction* trans,
129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen     sync_api::ReadNode& autofill_root) {
130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(change->type() == AutofillProfileChange::REMOVE || change->profile());
131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  switch (change->type()) {
132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    case AutofillProfileChange::ADD: {
133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      AddAutofillProfileSyncNode(trans, autofill_root, *(change->profile()));
134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      break;
135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    case AutofillProfileChange::UPDATE: {
137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      int64 sync_id = model_associator_->GetSyncIdFromChromeId(change->key());
138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (sync_api::kInvalidId == sync_id) {
139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(ERROR) << "Sync id is not found for " << change->key();
140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        break;
141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      sync_api::WriteNode node(trans);
143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (!node.InitByIdLookup(sync_id)) {
144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(ERROR) << "Could not find sync node for id " << sync_id;
145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        break;
146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      WriteAutofillProfile(*(change->profile()), &node);
149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      break;
150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    case AutofillProfileChange::REMOVE: {
152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      int64 sync_id = model_associator_->GetSyncIdFromChromeId(change->key());
153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (sync_api::kInvalidId == sync_id) {
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(ERROR) << "Sync id is not found for " << change->key();
155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        break;
156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      sync_api::WriteNode node(trans);
158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (!node.InitByIdLookup(sync_id)) {
159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(ERROR) << "Could not find sync node for id " << sync_id;
160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        break;
161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      node.Remove();
163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      model_associator_->Disassociate(sync_id);
164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      break;
165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    default:
167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      NOTREACHED();
168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::CommitChangesFromSyncModel() {
172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
174dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!running())
175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
177dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ScopedStopObserving observer(this);
178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
179dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (unsigned int i = 0;i < autofill_changes_.size(); ++i) {
180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE ==
181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        autofill_changes_[i].action_) {
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!web_database_->GetAutofillTable()->RemoveAutofillProfile(
183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          autofill_changes_[i].profile_specifics_.guid())) {
184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(ERROR) << "could not delete the profile " <<
185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen           autofill_changes_[i].profile_specifics_.guid();
186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        continue;
187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        continue;
189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Now for updates and adds.
192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ApplyAutofillProfileChange(autofill_changes_[i].action_,
193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        autofill_changes_[i].profile_specifics_,
194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        autofill_changes_[i].id_);
195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  autofill_changes_.clear();
198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  PostOptimisticRefreshTask();
200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::PostOptimisticRefreshTask() {
203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      new DoOptimisticRefreshForAutofill(
205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen           personal_data_));
206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::ApplyAutofillProfileChange(
209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    sync_api::SyncManager::ChangeRecord::Action action,
210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const sync_pb::AutofillProfileSpecifics& profile_specifics,
211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    int64 sync_id) {
212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK_NE(sync_api::SyncManager::ChangeRecord::ACTION_DELETE, action);
214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  switch (action) {
215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    case sync_api::SyncManager::ChangeRecord::ACTION_ADD: {
216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (guid::IsValidGUID(profile_specifics.guid()) == false) {
217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        NOTREACHED() << "Guid from the server is invalid " <<
218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            profile_specifics.guid();
219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        return;
220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      AutofillProfile p(profile_specifics.guid());
222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      AutofillProfileModelAssociator::OverwriteProfileWithServerData(&p,
223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          profile_specifics);
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!web_database_->GetAutofillTable()->AddAutofillProfile(p)) {
225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(ERROR) << "could not add autofill profile for guid " << p.guid();
226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        break;
227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // Now that the node has been succesfully created we can associate it.
230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      std::string guid = p.guid();
231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      model_associator_->Associate(&guid, sync_id);
232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      break;
233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    case sync_api::SyncManager::ChangeRecord::ACTION_UPDATE: {
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      AutofillProfile *p;
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!web_database_->GetAutofillTable()->GetAutofillProfile(
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          profile_specifics.guid(), &p)) {
238dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(ERROR) << "Could not find the autofill profile to update for " <<
239dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            profile_specifics.guid();
240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        break;
241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      scoped_ptr<AutofillProfile> autofill_pointer(p);
243dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      AutofillProfileModelAssociator::OverwriteProfileWithServerData(
244dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          autofill_pointer.get(),
245dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          profile_specifics);
246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!web_database_->GetAutofillTable()->UpdateAutofillProfile(
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          *(autofill_pointer.get()))) {
249dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(ERROR) << "Could not update autofill profile for " <<
250dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            profile_specifics.guid();
251dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        break;
252dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      break;
254dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
255dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    default: {
256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      NOTREACHED();
257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      break;
258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
259dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
260dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
261dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
262dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::RemoveSyncNode(const std::string& guid,
263dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    sync_api::WriteTransaction* trans) {
264dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  sync_api::WriteNode node(trans);
265dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  int64 sync_id = model_associator_->GetSyncIdFromChromeId(guid);
266dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (sync_api::kInvalidId == sync_id) {
267dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    LOG(ERROR) << "Could not find the node in associator " << guid;
268dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
269dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
270dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
271dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!node.InitByIdLookup(sync_id)) {
272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    LOG(ERROR) << "Could not find the sync node for " << guid;
273dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
274dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
275dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
276dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  model_associator_->Disassociate(sync_id);
277dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  node.Remove();
278dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
279dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
280dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::AddAutofillProfileSyncNode(
281dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    sync_api::WriteTransaction* trans,
282dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    sync_api::BaseNode& autofill_profile_root,
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const AutofillProfile& profile) {
284dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
285dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string guid = profile.guid();
286dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
287dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (guid::IsValidGUID(guid) == false) {
288dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    DCHECK(false) << "Guid set on the profile is invalid " << guid;
289dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
290dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
291dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
292dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  sync_api::WriteNode node(trans);
293dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!node.InitUniqueByCreation(syncable::AUTOFILL_PROFILE,
294dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      autofill_profile_root,
295dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      profile.guid())) {
296dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    LOG(ERROR) << "could not create a sync node ";
297dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
298dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
299dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
300dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  node.SetTitle(UTF8ToWide(profile.guid()));
301dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
302dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  WriteAutofillProfile(profile, &node);
303dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
304dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  model_associator_->Associate(&guid, node.GetId());
305dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
306dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
307dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::StartObserving() {
308dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
309dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  notification_registrar_.Add(this,
310dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      NotificationType::AUTOFILL_PROFILE_CHANGED,
311dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      NotificationService::AllSources());
312dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
313dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
314dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::StopObserving() {
315dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
316dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  notification_registrar_.RemoveAll();
317dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
318dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
319dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillProfileChangeProcessor::WriteAutofillProfile(
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const AutofillProfile& profile,
321dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    sync_api::WriteNode* node) {
322dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  sync_pb::AutofillProfileSpecifics specifics;
323dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
324dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // This would get compiled out in official builds. The caller is expected to
325dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // pass in a valid profile object with valid guid.(i.e., the caller might
326dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // have to a DCHECK and log before calling. Having to check in 2 places is
327dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // not optimal.)
328dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(guid::IsValidGUID(profile.guid()));
329dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
330dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  specifics.set_guid(profile.guid());
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_name_first(UTF16ToUTF8(profile.GetInfo(NAME_FIRST)));
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_name_middle(UTF16ToUTF8(profile.GetInfo(NAME_MIDDLE)));
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_name_last(UTF16ToUTF8(profile.GetInfo(NAME_LAST)));
334dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  specifics.set_address_home_line1(
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_LINE1)));
336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  specifics.set_address_home_line2(
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_LINE2)));
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_address_home_city(UTF16ToUTF8(profile.GetInfo(
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ADDRESS_HOME_CITY)));
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_address_home_state(UTF16ToUTF8(profile.GetInfo(
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ADDRESS_HOME_STATE)));
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_address_home_country(UTF16ToUTF8(profile.GetInfo(
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ADDRESS_HOME_COUNTRY)));
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_address_home_zip(UTF16ToUTF8(profile.GetInfo(
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ADDRESS_HOME_ZIP)));
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_email_address(UTF16ToUTF8(profile.GetInfo(EMAIL_ADDRESS)));
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_company_name(UTF16ToUTF8(profile.GetInfo(COMPANY_NAME)));
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_phone_fax_whole_number(UTF16ToUTF8(profile.GetInfo(
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PHONE_FAX_WHOLE_NUMBER)));
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  specifics.set_phone_home_whole_number(UTF16ToUTF8(profile.GetInfo(
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PHONE_HOME_WHOLE_NUMBER)));
352dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  node->SetAutofillProfileSpecifics(specifics);
353dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
354dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}  // namespace browser_sync
356