| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/autofill/core/browser/autofill_external_delegate.h" | 5 #include "components/autofill/core/browser/autofill_external_delegate.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 query_field_ = field; | 83 query_field_ = field; |
| 84 display_warning_if_disabled_ = display_warning_if_disabled; | 84 display_warning_if_disabled_ = display_warning_if_disabled; |
| 85 query_id_ = query_id; | 85 query_id_ = query_id; |
| 86 element_bounds_ = element_bounds; | 86 element_bounds_ = element_bounds; |
| 87 should_show_scan_credit_card_ = | 87 should_show_scan_credit_card_ = |
| 88 manager_->ShouldShowScanCreditCard(query_form_, query_field_); | 88 manager_->ShouldShowScanCreditCard(query_form_, query_field_); |
| 89 } | 89 } |
| 90 | 90 |
| 91 void AutofillExternalDelegate::OnSuggestionsReturned( | 91 void AutofillExternalDelegate::OnSuggestionsReturned( |
| 92 int query_id, | 92 int query_id, |
| 93 const std::vector<base::string16>& suggested_values, | 93 const std::vector<Suggestion>& input_suggestions) { |
| 94 const std::vector<base::string16>& suggested_labels, | |
| 95 const std::vector<base::string16>& suggested_icons, | |
| 96 const std::vector<int>& suggested_unique_ids) { | |
| 97 if (query_id != query_id_) | 94 if (query_id != query_id_) |
| 98 return; | 95 return; |
| 99 | 96 |
| 100 std::vector<base::string16> values(suggested_values); | 97 std::vector<Suggestion> suggestions(input_suggestions); |
| 101 std::vector<base::string16> labels(suggested_labels); | |
| 102 std::vector<base::string16> icons(suggested_icons); | |
| 103 std::vector<int> ids(suggested_unique_ids); | |
| 104 | 98 |
| 105 // Add or hide warnings as appropriate. | 99 // Add or hide warnings as appropriate. |
| 106 ApplyAutofillWarnings(&values, &labels, &icons, &ids); | 100 ApplyAutofillWarnings(&suggestions); |
| 107 | 101 |
| 108 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 102 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 109 switches::kEnableWalletCardImport)) { | 103 switches::kEnableWalletCardImport)) { |
| 110 // For now, add a fake masked card. | 104 // For now, add a fake masked card. |
| 111 values.push_back(base::ASCIIToUTF16("Visa - 1111")); | 105 suggestions.push_back(Suggestion( |
| 112 labels.push_back(base::ASCIIToUTF16("[tap to unlock]")); | 106 "Visa - 1111", "[tap to unlock]", "", |
| 113 icons.push_back(base::string16()); | 107 POPUP_ITEM_ID_FAKE_MASKED_INSTRUMENT)); |
| 114 ids.push_back(POPUP_ITEM_ID_FAKE_MASKED_INSTRUMENT); | |
| 115 } | 108 } |
| 116 | 109 |
| 117 // Add a separator to go between the values and menu items. | 110 // Add a separator to go between the values and menu items. |
| 118 values.push_back(base::string16()); | 111 suggestions.push_back(Suggestion()); |
| 119 labels.push_back(base::string16()); | 112 suggestions.back().frontend_id = POPUP_ITEM_ID_SEPARATOR; |
| 120 icons.push_back(base::string16()); | |
| 121 ids.push_back(POPUP_ITEM_ID_SEPARATOR); | |
| 122 | 113 |
| 123 if (should_show_scan_credit_card_) { | 114 if (should_show_scan_credit_card_) { |
| 124 values.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_SCAN_CREDIT_CARD)); | 115 Suggestion scan_credit_card( |
| 125 labels.push_back(base::string16()); | 116 l10n_util::GetStringUTF16(IDS_AUTOFILL_SCAN_CREDIT_CARD)); |
| 126 icons.push_back(base::ASCIIToUTF16("scanCreditCardIcon")); | 117 scan_credit_card.frontend_id = POPUP_ITEM_ID_SCAN_CREDIT_CARD; |
| 127 ids.push_back(POPUP_ITEM_ID_SCAN_CREDIT_CARD); | 118 scan_credit_card.icon = base::ASCIIToUTF16("scanCreditCardIcon"); |
| 119 suggestions.push_back(scan_credit_card); |
| 128 | 120 |
| 129 if (!has_shown_popup_for_current_edit_) { | 121 if (!has_shown_popup_for_current_edit_) { |
| 130 AutofillMetrics::LogScanCreditCardPromptMetric( | 122 AutofillMetrics::LogScanCreditCardPromptMetric( |
| 131 AutofillMetrics::SCAN_CARD_ITEM_SHOWN); | 123 AutofillMetrics::SCAN_CARD_ITEM_SHOWN); |
| 132 } | 124 } |
| 133 } | 125 } |
| 134 | 126 |
| 135 // Only include "Autofill Options" special menu item if we have Autofill | 127 // Only include "Autofill Options" special menu item if we have Autofill |
| 136 // suggestions. | 128 // suggestions. |
| 137 has_suggestion_ = false; | 129 has_suggestion_ = false; |
| 138 for (size_t i = 0; i < ids.size(); ++i) { | 130 for (size_t i = 0; i < suggestions.size(); ++i) { |
| 139 if (ids[i] > 0) { | 131 if (suggestions[i].frontend_id > 0) { |
| 140 has_suggestion_ = true; | 132 has_suggestion_ = true; |
| 141 break; | 133 break; |
| 142 } | 134 } |
| 143 } | 135 } |
| 144 | 136 |
| 145 if (has_suggestion_) | 137 if (has_suggestion_) |
| 146 ApplyAutofillOptions(&values, &labels, &icons, &ids); | 138 ApplyAutofillOptions(&suggestions); |
| 147 | 139 |
| 148 // Remove the separator if it is the last element. | 140 // Remove the separator if it is the last element. |
| 149 DCHECK_GT(ids.size(), 0U); | 141 DCHECK_GT(suggestions.size(), 0U); |
| 150 if (ids.back() == POPUP_ITEM_ID_SEPARATOR) { | 142 if (suggestions.back().frontend_id == POPUP_ITEM_ID_SEPARATOR) |
| 151 values.pop_back(); | 143 suggestions.pop_back(); |
| 152 labels.pop_back(); | |
| 153 icons.pop_back(); | |
| 154 ids.pop_back(); | |
| 155 } | |
| 156 | 144 |
| 157 // If anything else is added to modify the values after inserting the data | 145 // If anything else is added to modify the values after inserting the data |
| 158 // list, AutofillPopupControllerImpl::UpdateDataListValues will need to be | 146 // list, AutofillPopupControllerImpl::UpdateDataListValues will need to be |
| 159 // updated to match. | 147 // updated to match. |
| 160 InsertDataListValues(&values, &labels, &icons, &ids); | 148 InsertDataListValues(&suggestions); |
| 161 | 149 |
| 162 #if defined(OS_MACOSX) && !defined(OS_IOS) | 150 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 163 if (values.empty() && | 151 if (suggestions.empty() && |
| 164 manager_->ShouldShowAccessAddressBookSuggestion(query_form_, | 152 manager_->ShouldShowAccessAddressBookSuggestion(query_form_, |
| 165 query_field_)) { | 153 query_field_)) { |
| 166 values.push_back( | 154 Suggestion mac_contacts( |
| 167 l10n_util::GetStringUTF16(IDS_AUTOFILL_ACCESS_MAC_CONTACTS)); | 155 l10n_util::GetStringUTF16(IDS_AUTOFILL_ACCESS_MAC_CONTACTS)); |
| 168 labels.push_back(base::string16()); | 156 mac_contacts.icon = base::ASCIIToUTF16("macContactsIcon"); |
| 169 icons.push_back(base::ASCIIToUTF16("macContactsIcon")); | 157 mac_contacts.frontend_id = POPUP_ITEM_ID_MAC_ACCESS_CONTACTS; |
| 170 ids.push_back(POPUP_ITEM_ID_MAC_ACCESS_CONTACTS); | |
| 171 | 158 |
| 172 if (!has_shown_address_book_prompt) { | 159 if (!has_shown_address_book_prompt) { |
| 173 has_shown_address_book_prompt = true; | 160 has_shown_address_book_prompt = true; |
| 174 EmitHistogram(SHOWED_ACCESS_ADDRESS_BOOK_ENTRY); | 161 EmitHistogram(SHOWED_ACCESS_ADDRESS_BOOK_ENTRY); |
| 175 manager_->ShowedAccessAddressBookPrompt(); | 162 manager_->ShowedAccessAddressBookPrompt(); |
| 176 } | 163 } |
| 177 } | 164 } |
| 178 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 165 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 179 | 166 |
| 180 if (values.empty()) { | 167 if (suggestions.empty()) { |
| 181 // No suggestions, any popup currently showing is obsolete. | 168 // No suggestions, any popup currently showing is obsolete. |
| 182 manager_->client()->HideAutofillPopup(); | 169 manager_->client()->HideAutofillPopup(); |
| 183 return; | 170 return; |
| 184 } | 171 } |
| 185 | 172 |
| 186 // Send to display. | 173 // Send to display. |
| 187 if (query_field_.is_focusable) { | 174 if (query_field_.is_focusable) { |
| 188 manager_->client()->ShowAutofillPopup(element_bounds_, | 175 manager_->client()->ShowAutofillPopup(element_bounds_, |
| 189 query_field_.text_direction, | 176 query_field_.text_direction, |
| 190 values, | 177 suggestions, |
| 191 labels, | |
| 192 icons, | |
| 193 ids, | |
| 194 GetWeakPtr()); | 178 GetWeakPtr()); |
| 195 } | 179 } |
| 196 } | 180 } |
| 197 | 181 |
| 198 void AutofillExternalDelegate::SetCurrentDataListValues( | 182 void AutofillExternalDelegate::SetCurrentDataListValues( |
| 199 const std::vector<base::string16>& data_list_values, | 183 const std::vector<base::string16>& data_list_values, |
| 200 const std::vector<base::string16>& data_list_labels) { | 184 const std::vector<base::string16>& data_list_labels) { |
| 201 data_list_values_ = data_list_values; | 185 data_list_values_ = data_list_values; |
| 202 data_list_labels_ = data_list_labels; | 186 data_list_labels_ = data_list_labels; |
| 203 | 187 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 DCHECK(driver_->RendererIsAvailable()); | 338 DCHECK(driver_->RendererIsAvailable()); |
| 355 // Fill the values for the whole form. | 339 // Fill the values for the whole form. |
| 356 manager_->FillOrPreviewForm(renderer_action, | 340 manager_->FillOrPreviewForm(renderer_action, |
| 357 query_id_, | 341 query_id_, |
| 358 query_form_, | 342 query_form_, |
| 359 query_field_, | 343 query_field_, |
| 360 unique_id); | 344 unique_id); |
| 361 } | 345 } |
| 362 | 346 |
| 363 void AutofillExternalDelegate::ApplyAutofillWarnings( | 347 void AutofillExternalDelegate::ApplyAutofillWarnings( |
| 364 std::vector<base::string16>* values, | 348 std::vector<Suggestion>* suggestions) { |
| 365 std::vector<base::string16>* labels, | |
| 366 std::vector<base::string16>* icons, | |
| 367 std::vector<int>* unique_ids) { | |
| 368 if (!ShouldAutofill(query_field_)) { | 349 if (!ShouldAutofill(query_field_)) { |
| 369 // Autofill is disabled. If there were some profile or credit card | 350 // Autofill is disabled. If there were some profile or credit card |
| 370 // suggestions to show, show a warning instead. Otherwise, clear out the | 351 // suggestions to show, show a warning instead. Otherwise, clear out the |
| 371 // list of suggestions. | 352 // list of suggestions. |
| 372 if (!unique_ids->empty() && (*unique_ids)[0] > 0) { | 353 if (!suggestions->empty() && (*suggestions)[0].frontend_id > 0) { |
| 373 // If Autofill is disabled and we had suggestions, show a warning instead. | 354 // If Autofill is disabled and we had suggestions, show a warning instead. |
| 374 values->assign( | 355 suggestions->assign(1, Suggestion( |
| 375 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED)); | 356 l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED))); |
| 376 labels->assign(1, base::string16()); | 357 (*suggestions)[0].frontend_id = POPUP_ITEM_ID_WARNING_MESSAGE; |
| 377 icons->assign(1, base::string16()); | |
| 378 unique_ids->assign(1, POPUP_ITEM_ID_WARNING_MESSAGE); | |
| 379 } else { | 358 } else { |
| 380 values->clear(); | 359 suggestions->clear(); |
| 381 labels->clear(); | |
| 382 icons->clear(); | |
| 383 unique_ids->clear(); | |
| 384 } | 360 } |
| 385 } else if (unique_ids->size() > 1 && | 361 } else if (suggestions->size() > 1 && |
| 386 (*unique_ids)[0] == POPUP_ITEM_ID_WARNING_MESSAGE) { | 362 (*suggestions)[0].frontend_id == POPUP_ITEM_ID_WARNING_MESSAGE) { |
| 387 // If we received a warning instead of suggestions from Autofill but regular | 363 // If we received a warning instead of suggestions from Autofill but regular |
| 388 // suggestions from autocomplete, don't show the Autofill warning. | 364 // suggestions from autocomplete, don't show the Autofill warning. |
| 389 values->erase(values->begin()); | 365 suggestions->erase(suggestions->begin()); |
| 390 labels->erase(labels->begin()); | |
| 391 icons->erase(icons->begin()); | |
| 392 unique_ids->erase(unique_ids->begin()); | |
| 393 } | 366 } |
| 394 | 367 |
| 395 // If we were about to show a warning and we shouldn't, don't. | 368 // If we were about to show a warning and we shouldn't, don't. |
| 396 if (!unique_ids->empty() && | 369 if (!suggestions->empty() && |
| 397 (*unique_ids)[0] == POPUP_ITEM_ID_WARNING_MESSAGE && | 370 (*suggestions)[0].frontend_id == POPUP_ITEM_ID_WARNING_MESSAGE && |
| 398 !display_warning_if_disabled_) { | 371 !display_warning_if_disabled_) { |
| 399 values->clear(); | 372 suggestions->clear(); |
| 400 labels->clear(); | |
| 401 icons->clear(); | |
| 402 unique_ids->clear(); | |
| 403 } | 373 } |
| 404 } | 374 } |
| 405 | 375 |
| 406 void AutofillExternalDelegate::ApplyAutofillOptions( | 376 void AutofillExternalDelegate::ApplyAutofillOptions( |
| 407 std::vector<base::string16>* values, | 377 std::vector<Suggestion>* suggestions) { |
| 408 std::vector<base::string16>* labels, | |
| 409 std::vector<base::string16>* icons, | |
| 410 std::vector<int>* unique_ids) { | |
| 411 // The form has been auto-filled, so give the user the chance to clear the | 378 // The form has been auto-filled, so give the user the chance to clear the |
| 412 // form. Append the 'Clear form' menu item. | 379 // form. Append the 'Clear form' menu item. |
| 413 if (query_field_.is_autofilled) { | 380 if (query_field_.is_autofilled) { |
| 414 values->push_back( | 381 suggestions->push_back(Suggestion( |
| 415 l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM)); | 382 l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM))); |
| 416 labels->push_back(base::string16()); | 383 suggestions->back().frontend_id = POPUP_ITEM_ID_CLEAR_FORM; |
| 417 icons->push_back(base::string16()); | |
| 418 unique_ids->push_back(POPUP_ITEM_ID_CLEAR_FORM); | |
| 419 } | 384 } |
| 420 | 385 |
| 421 // Append the 'Chrome Autofill options' menu item; | 386 // Append the 'Chrome Autofill options' menu item; |
| 422 values->push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_POPUP)); | 387 suggestions->push_back(Suggestion( |
| 423 labels->push_back(base::string16()); | 388 l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_POPUP))); |
| 424 icons->push_back(base::string16()); | 389 suggestions->back().frontend_id = POPUP_ITEM_ID_AUTOFILL_OPTIONS; |
| 425 unique_ids->push_back(POPUP_ITEM_ID_AUTOFILL_OPTIONS); | |
| 426 } | 390 } |
| 427 | 391 |
| 428 void AutofillExternalDelegate::InsertDataListValues( | 392 void AutofillExternalDelegate::InsertDataListValues( |
| 429 std::vector<base::string16>* values, | 393 std::vector<Suggestion>* suggestions) { |
| 430 std::vector<base::string16>* labels, | |
| 431 std::vector<base::string16>* icons, | |
| 432 std::vector<int>* unique_ids) { | |
| 433 if (data_list_values_.empty()) | 394 if (data_list_values_.empty()) |
| 434 return; | 395 return; |
| 435 | 396 |
| 436 // Insert the separator between the datalist and Autofill values (if there | 397 // Insert the separator between the datalist and Autofill values (if there |
| 437 // are any). | 398 // are any). |
| 438 if (!values->empty()) { | 399 if (!suggestions->empty()) { |
| 439 values->insert(values->begin(), base::string16()); | 400 suggestions->insert(suggestions->begin(), Suggestion()); |
| 440 labels->insert(labels->begin(), base::string16()); | 401 (*suggestions)[0].frontend_id = POPUP_ITEM_ID_SEPARATOR; |
| 441 icons->insert(icons->begin(), base::string16()); | |
| 442 unique_ids->insert(unique_ids->begin(), POPUP_ITEM_ID_SEPARATOR); | |
| 443 } | 402 } |
| 444 | 403 |
| 445 // Insert the datalist elements. | 404 // Insert the datalist elements at the beginning. |
| 446 values->insert(values->begin(), | 405 suggestions->insert(suggestions->begin(), data_list_values_.size(), |
| 447 data_list_values_.begin(), | 406 Suggestion()); |
| 448 data_list_values_.end()); | 407 for (size_t i = 0; i < data_list_values_.size(); i++) { |
| 449 labels->insert(labels->begin(), | 408 (*suggestions)[i].value = data_list_values_[i]; |
| 450 data_list_labels_.begin(), | 409 (*suggestions)[i].label = data_list_labels_[i]; |
| 451 data_list_labels_.end()); | 410 (*suggestions)[i].frontend_id = POPUP_ITEM_ID_DATALIST_ENTRY; |
| 452 | 411 } |
| 453 // Set the values that all datalist elements share. | |
| 454 icons->insert(icons->begin(), | |
| 455 data_list_values_.size(), | |
| 456 base::string16()); | |
| 457 unique_ids->insert(unique_ids->begin(), | |
| 458 data_list_values_.size(), | |
| 459 POPUP_ITEM_ID_DATALIST_ENTRY); | |
| 460 } | 412 } |
| 461 | 413 |
| 462 #if defined(OS_MACOSX) && !defined(OS_IOS) | 414 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 463 void AutofillExternalDelegate::PingRenderer() { | 415 void AutofillExternalDelegate::PingRenderer() { |
| 464 driver_->PingRenderer(); | 416 driver_->PingRenderer(); |
| 465 } | 417 } |
| 466 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 418 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 467 | 419 |
| 468 } // namespace autofill | 420 } // namespace autofill |
| OLD | NEW |