Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: chrome/browser/autofill/autocheckout_manager.cc

Issue 12434004: Move remaining Autofill code to //components/autofill. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix long lines Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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/autofill/autocheckout_manager.h"
6
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/autofill/autofill_country.h"
11 #include "chrome/browser/autofill/autofill_field.h"
12 #include "chrome/browser/autofill/autofill_manager.h"
13 #include "chrome/browser/autofill/autofill_profile.h"
14 #include "chrome/browser/autofill/credit_card.h"
15 #include "chrome/browser/autofill/field_types.h"
16 #include "chrome/browser/autofill/form_structure.h"
17 #include "components/autofill/common/autocheckout_status.h"
18 #include "components/autofill/common/autofill_messages.h"
19 #include "components/autofill/common/form_data.h"
20 #include "components/autofill/common/form_field_data.h"
21 #include "components/autofill/common/web_element_descriptor.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "content/public/browser/web_contents.h"
24 #include "content/public/common/ssl_status.h"
25 #include "googleurl/src/gurl.h"
26 #include "ui/gfx/rect.h"
27
28 using content::RenderViewHost;
29 using content::SSLStatus;
30 using content::WebContents;
31
32 namespace {
33
34 // Build FormFieldData based on the supplied |autocomplete_attribute|. Will
35 // fill rest of properties with default values.
36 FormFieldData BuildField(const std::string& autocomplete_attribute) {
37 FormFieldData field;
38 field.name = string16();
39 field.value = string16();
40 field.autocomplete_attribute = autocomplete_attribute;
41 field.form_control_type = "text";
42 return field;
43 }
44
45 // Build Autocheckout specific form data to be consumed by
46 // AutofillDialogController to show the Autocheckout specific UI.
47 FormData BuildAutocheckoutFormData() {
48 FormData formdata;
49 formdata.fields.push_back(BuildField("name"));
50 formdata.fields.push_back(BuildField("tel"));
51 formdata.fields.push_back(BuildField("email"));
52 formdata.fields.push_back(BuildField("cc-name"));
53 formdata.fields.push_back(BuildField("cc-number"));
54 formdata.fields.push_back(BuildField("cc-exp-month"));
55 formdata.fields.push_back(BuildField("cc-exp-year"));
56 formdata.fields.push_back(BuildField("cc-csc"));
57 formdata.fields.push_back(BuildField("billing street-address"));
58 formdata.fields.push_back(BuildField("billing locality"));
59 formdata.fields.push_back(BuildField("billing region"));
60 formdata.fields.push_back(BuildField("billing country"));
61 formdata.fields.push_back(BuildField("billing postal-code"));
62 formdata.fields.push_back(BuildField("shipping street-address"));
63 formdata.fields.push_back(BuildField("shipping locality"));
64 formdata.fields.push_back(BuildField("shipping region"));
65 formdata.fields.push_back(BuildField("shipping country"));
66 formdata.fields.push_back(BuildField("shipping postal-code"));
67 return formdata;
68 }
69
70 } // namespace
71
72 namespace autofill {
73
74 AutocheckoutManager::AutocheckoutManager(AutofillManager* autofill_manager)
75 : autofill_manager_(autofill_manager),
76 autocheckout_bubble_shown_(false),
77 in_autocheckout_flow_(false),
78 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
79 }
80
81 AutocheckoutManager::~AutocheckoutManager() {
82 }
83
84 void AutocheckoutManager::FillForms() {
85 // |page_meta_data_| should have been set by OnLoadedPageMetaData.
86 DCHECK(page_meta_data_);
87
88 // Fill the forms on the page with data given by user.
89 std::vector<FormData> filled_forms;
90 const std::vector<FormStructure*>& form_structures =
91 autofill_manager_->GetFormStructures();
92 for (std::vector<FormStructure*>::const_iterator iter =
93 form_structures.begin(); iter != form_structures.end(); ++iter) {
94 const FormStructure& form_structure = **iter;
95 FormData form = form_structure.ToFormData();
96 DCHECK_EQ(form_structure.field_count(), form.fields.size());
97
98 for (size_t i = 0; i < form_structure.field_count(); ++i) {
99 const AutofillField* field = form_structure.field(i);
100 SetValue(*field, &form.fields[i]);
101 }
102
103 filled_forms.push_back(form);
104 }
105
106 // Send filled forms along with proceed descriptor to renderer.
107 RenderViewHost* host =
108 autofill_manager_->GetWebContents()->GetRenderViewHost();
109 if (!host)
110 return;
111
112 host->Send(new AutofillMsg_FillFormsAndClick(
113 host->GetRoutingID(),
114 filled_forms,
115 page_meta_data_->IsEndOfAutofillableFlow() ?
116 WebElementDescriptor() :
117 *page_meta_data_->proceed_element_descriptor));
118 }
119
120 void AutocheckoutManager::OnLoadedPageMetaData(
121 scoped_ptr<AutocheckoutPageMetaData> page_meta_data) {
122 scoped_ptr<AutocheckoutPageMetaData> old_meta_data =
123 page_meta_data_.Pass();
124 page_meta_data_ = page_meta_data.Pass();
125
126 // On the first page of an Autocheckout flow, when this function is called the
127 // user won't have opted into the flow yet.
128 if (!in_autocheckout_flow_)
129 return;
130
131 // Missing Autofill server results.
132 if (!page_meta_data_) {
133 in_autocheckout_flow_ = false;
134 } else if (page_meta_data_->IsStartOfAutofillableFlow()) {
135 // Not possible unless Autocheckout failed to proceed.
136 in_autocheckout_flow_ = false;
137 } else if (!page_meta_data_->IsInAutofillableFlow()) {
138 // Missing Autocheckout meta data in the Autofill server results.
139 in_autocheckout_flow_ = false;
140 } else if (!page_meta_data_->proceed_element_descriptor &&
141 !page_meta_data_->IsEndOfAutofillableFlow()) {
142 // Missing Autocheckout proceed data in meta data in the Autofill server
143 // results.
144 in_autocheckout_flow_ = false;
145 } else if (page_meta_data_->current_page_number <=
146 old_meta_data->current_page_number) {
147 // Not possible unless Autocheckout failed to proceed.
148 in_autocheckout_flow_ = false;
149 }
150
151 // Encountered an error during the Autocheckout flow.
152 if (!in_autocheckout_flow_) {
153 // TODO(ahutter): SendAutocheckoutStatus of the error.
154 autofill_manager_->delegate()->OnAutocheckoutError();
155 return;
156 }
157
158 // Add 1.0 since page numbers are 0-indexed.
159 autofill_manager_->delegate()->UpdateProgressBar(
160 (1.0 + page_meta_data_->current_page_number) /
161 page_meta_data_->total_pages);
162 FillForms();
163 // If the current page is the last page in the flow, close the dialog.
164 if (page_meta_data_->IsEndOfAutofillableFlow()) {
165 // TODO(ahutter): SendAutocheckoutStatus of SUCCESS.
166 autofill_manager_->delegate()->HideRequestAutocompleteDialog();
167 in_autocheckout_flow_ = false;
168 }
169 }
170
171 void AutocheckoutManager::OnFormsSeen() {
172 autocheckout_bubble_shown_ = false;
173 }
174
175 bool AutocheckoutManager::MaybeShowAutocheckoutBubble(
176 const GURL& frame_url,
177 const content::SSLStatus& ssl_status,
178 const gfx::NativeView& native_view,
179 const gfx::RectF& bounding_box) {
180 if (autocheckout_bubble_shown_)
181 return false;
182
183 base::Closure callback = base::Bind(
184 &AutocheckoutManager::ShowAutocheckoutDialog,
185 weak_ptr_factory_.GetWeakPtr(),
186 frame_url,
187 ssl_status);
188 autofill_manager_->delegate()->ShowAutocheckoutBubble(
189 bounding_box,
190 native_view,
191 callback);
192 autocheckout_bubble_shown_ = true;
193 return true;
194 }
195
196 void AutocheckoutManager::ShowAutocheckoutDialog(
197 const GURL& frame_url,
198 const SSLStatus& ssl_status) {
199 base::Callback<void(const FormStructure*)> callback =
200 base::Bind(&AutocheckoutManager::ReturnAutocheckoutData,
201 weak_ptr_factory_.GetWeakPtr());
202 autofill_manager_->ShowRequestAutocompleteDialog(
203 BuildAutocheckoutFormData(), frame_url, ssl_status,
204 DIALOG_TYPE_AUTOCHECKOUT, callback);
205 }
206
207 bool AutocheckoutManager::IsStartOfAutofillableFlow() const {
208 return page_meta_data_ && page_meta_data_->IsStartOfAutofillableFlow();
209 }
210
211 bool AutocheckoutManager::IsInAutofillableFlow() const {
212 return page_meta_data_ && page_meta_data_->IsInAutofillableFlow();
213 }
214
215 void AutocheckoutManager::ReturnAutocheckoutData(const FormStructure* result) {
216 if (!result)
217 return;
218
219 in_autocheckout_flow_ = true;
220
221 profile_.reset(new AutofillProfile());
222 credit_card_.reset(new CreditCard());
223
224 for (size_t i = 0; i < result->field_count(); ++i) {
225 AutofillFieldType type = result->field(i)->type();
226 if (type == CREDIT_CARD_VERIFICATION_CODE) {
227 // TODO(ramankk): CVV is not handled by CreditCard, not sure how to
228 // handle it yet.
229 cvv_ = result->field(i)->value;
230 continue;
231 }
232 if (AutofillType(type).group() == AutofillType::CREDIT_CARD) {
233 credit_card_->SetRawInfo(result->field(i)->type(),
234 result->field(i)->value);
235 } else {
236 profile_->SetRawInfo(result->field(i)->type(), result->field(i)->value);
237 }
238 }
239
240 // Add 1.0 since page numbers are 0-indexed.
241 autofill_manager_->delegate()->UpdateProgressBar(
242 (1.0 + page_meta_data_->current_page_number) /
243 page_meta_data_->total_pages);
244 FillForms();
245 }
246
247 void AutocheckoutManager::SetValue(const AutofillField& field,
248 FormFieldData* field_to_fill) {
249 AutofillFieldType type = field.type();
250
251 if (type == FIELD_WITH_DEFAULT_VALUE) {
252 DCHECK(field.is_checkable);
253 // For a form with radio buttons, like:
254 // <form>
255 // <input type="radio" name="sex" value="male">Male<br>
256 // <input type="radio" name="sex" value="female">Female
257 // </form>
258 // If the default value specified at the server is "female", then
259 // Autofill server responds back with following field mappings
260 // (fieldtype: FIELD_WITH_DEFAULT_VALUE, value: "female")
261 // (fieldtype: FIELD_WITH_DEFAULT_VALUE, value: "female")
262 // Note that, the field mapping is repeated twice to respond to both the
263 // input elements with the same name/signature in the form.
264 string16 default_value = UTF8ToUTF16(field.default_value());
265 // Mark the field checked if server says the default value of the field
266 // to be this field's value.
267 field_to_fill->is_checked = (field.value == default_value);
268 return;
269 }
270
271 // Handle verification code directly.
272 if (type == CREDIT_CARD_VERIFICATION_CODE) {
273 field_to_fill->value = cvv_;
274 return;
275 }
276
277 // TODO(ramankk): Handle variants in a better fashion, need to distinguish
278 // between shipping and billing address.
279 if (AutofillType(type).group() == AutofillType::CREDIT_CARD)
280 credit_card_->FillFormField(field, 0, field_to_fill);
281 else
282 profile_->FillFormField(field, 0, field_to_fill);
283 }
284
285 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/browser/autofill/autocheckout_manager.h ('k') | chrome/browser/autofill/autocheckout_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698