| 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/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/metrics/histogram.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 9 #include "components/autofill/core/browser/autocomplete_history_manager.h" | 10 #include "components/autofill/core/browser/autocomplete_history_manager.h" |
| 10 #include "components/autofill/core/browser/autofill_driver.h" | 11 #include "components/autofill/core/browser/autofill_driver.h" |
| 11 #include "components/autofill/core/browser/autofill_manager.h" | 12 #include "components/autofill/core/browser/autofill_manager.h" |
| 12 #include "components/autofill/core/browser/popup_item_ids.h" | 13 #include "components/autofill/core/browser/popup_item_ids.h" |
| 13 #include "grit/components_strings.h" | 14 #include "grit/components_strings.h" |
| 14 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
| 15 | 16 |
| 17 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 18 namespace { |
| 19 |
| 20 enum AccessAddressBookEventType { |
| 21 // An Autofill entry was shown that prompts the user to give Chrome access to |
| 22 // the user's Address Book. |
| 23 SHOWED_ACCESS_ADDRESS_BOOK_ENTRY = 0, |
| 24 |
| 25 // The user selected the Autofill entry which prompts Chrome to access the |
| 26 // user's Address Book. |
| 27 SELECTED_ACCESS_ADDRESS_BOOK_ENTRY = 1, |
| 28 |
| 29 // Always keep this at the end. |
| 30 ACCESS_ADDRESS_BOOK_ENTRY_MAX, |
| 31 }; |
| 32 |
| 33 // Emits an entry for the histogram. |
| 34 void EmitHistogram(AccessAddressBookEventType type) { |
| 35 UMA_HISTOGRAM_ENUMERATION( |
| 36 "Autofill.MacAddressBook", type, ACCESS_ADDRESS_BOOK_ENTRY_MAX); |
| 37 } |
| 38 |
| 39 } // namespace |
| 40 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 41 |
| 16 namespace autofill { | 42 namespace autofill { |
| 17 | 43 |
| 18 AutofillExternalDelegate::AutofillExternalDelegate(AutofillManager* manager, | 44 AutofillExternalDelegate::AutofillExternalDelegate(AutofillManager* manager, |
| 19 AutofillDriver* driver) | 45 AutofillDriver* driver) |
| 20 : manager_(manager), | 46 : manager_(manager), |
| 21 driver_(driver), | 47 driver_(driver), |
| 22 query_id_(0), | 48 query_id_(0), |
| 23 display_warning_if_disabled_(false), | 49 display_warning_if_disabled_(false), |
| 24 has_suggestion_(false), | 50 has_suggestion_(false), |
| 25 has_shown_popup_for_current_edit_(false), | 51 has_shown_popup_for_current_edit_(false), |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 // updated to match. | 117 // updated to match. |
| 92 InsertDataListValues(&values, &labels, &icons, &ids); | 118 InsertDataListValues(&values, &labels, &icons, &ids); |
| 93 | 119 |
| 94 #if defined(OS_MACOSX) && !defined(OS_IOS) | 120 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 95 if (values.empty() && | 121 if (values.empty() && |
| 96 manager_->ShouldShowAccessAddressBookSuggestion(query_form_, | 122 manager_->ShouldShowAccessAddressBookSuggestion(query_form_, |
| 97 query_field_)) { | 123 query_field_)) { |
| 98 values.push_back( | 124 values.push_back( |
| 99 l10n_util::GetStringUTF16(IDS_AUTOFILL_ACCESS_MAC_CONTACTS)); | 125 l10n_util::GetStringUTF16(IDS_AUTOFILL_ACCESS_MAC_CONTACTS)); |
| 100 labels.push_back(base::string16()); | 126 labels.push_back(base::string16()); |
| 101 icons.push_back(base::string16()); | 127 icons.push_back(base::ASCIIToUTF16("macContactsIcon")); |
| 102 ids.push_back(POPUP_ITEM_ID_MAC_ACCESS_CONTACTS); | 128 ids.push_back(POPUP_ITEM_ID_MAC_ACCESS_CONTACTS); |
| 129 |
| 130 EmitHistogram(SHOWED_ACCESS_ADDRESS_BOOK_ENTRY); |
| 103 } | 131 } |
| 104 #endif | 132 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 105 | 133 |
| 106 if (values.empty()) { | 134 if (values.empty()) { |
| 107 // No suggestions, any popup currently showing is obsolete. | 135 // No suggestions, any popup currently showing is obsolete. |
| 108 manager_->delegate()->HideAutofillPopup(); | 136 manager_->delegate()->HideAutofillPopup(); |
| 109 return; | 137 return; |
| 110 } | 138 } |
| 111 | 139 |
| 112 // Send to display. | 140 // Send to display. |
| 113 if (query_field_.is_focusable) { | 141 if (query_field_.is_focusable) { |
| 114 manager_->delegate()->ShowAutofillPopup( | 142 manager_->delegate()->ShowAutofillPopup( |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 driver_->RendererShouldClearFilledForm(); | 192 driver_->RendererShouldClearFilledForm(); |
| 165 } else if (identifier == POPUP_ITEM_ID_PASSWORD_ENTRY) { | 193 } else if (identifier == POPUP_ITEM_ID_PASSWORD_ENTRY) { |
| 166 NOTREACHED(); // Should be handled elsewhere. | 194 NOTREACHED(); // Should be handled elsewhere. |
| 167 } else if (identifier == POPUP_ITEM_ID_DATALIST_ENTRY) { | 195 } else if (identifier == POPUP_ITEM_ID_DATALIST_ENTRY) { |
| 168 driver_->RendererShouldAcceptDataListSuggestion(value); | 196 driver_->RendererShouldAcceptDataListSuggestion(value); |
| 169 } else if (identifier == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY) { | 197 } else if (identifier == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY) { |
| 170 // User selected an Autocomplete, so we fill directly. | 198 // User selected an Autocomplete, so we fill directly. |
| 171 driver_->RendererShouldFillFieldWithValue(value); | 199 driver_->RendererShouldFillFieldWithValue(value); |
| 172 } else if (identifier == POPUP_ITEM_ID_MAC_ACCESS_CONTACTS) { | 200 } else if (identifier == POPUP_ITEM_ID_MAC_ACCESS_CONTACTS) { |
| 173 #if defined(OS_MACOSX) && !defined(OS_IOS) | 201 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 202 EmitHistogram(SELECTED_ACCESS_ADDRESS_BOOK_ENTRY); |
| 203 |
| 174 // User wants to give Chrome access to user's address book. | 204 // User wants to give Chrome access to user's address book. |
| 175 manager_->AccessAddressBook(); | 205 manager_->AccessAddressBook(); |
| 176 | 206 |
| 177 // There is no deterministic method for deciding whether a blocking dialog | 207 // There is no deterministic method for deciding whether a blocking dialog |
| 178 // was presented. The following comments and code assume that a blocking | 208 // was presented. The following comments and code assume that a blocking |
| 179 // dialog was presented, but still behave correctly if no dialog was | 209 // dialog was presented, but still behave correctly if no dialog was |
| 180 // presented. | 210 // presented. |
| 181 | 211 |
| 182 // A blocking dialog was presented, and the user has already responded to | 212 // A blocking dialog was presented, and the user has already responded to |
| 183 // the dialog. The presentation of the dialog added an NSEvent to the | 213 // the dialog. The presentation of the dialog added an NSEvent to the |
| 184 // NSRunLoop which will cause all windows to lose focus. When the NSEvent | 214 // NSRunLoop which will cause all windows to lose focus. When the NSEvent |
| 185 // is processed, it will be sent to the renderer which will cause the text | 215 // is processed, it will be sent to the renderer which will cause the text |
| 186 // field to lose focus. This returns an IPC to Chrome which will dismiss | 216 // field to lose focus. This returns an IPC to Chrome which will dismiss |
| 187 // the autofill popup. We post a task which we expect to run after the | 217 // the Autofill popup. We post a task which we expect to run after the |
| 188 // NSEvent has been processed by the NSRunLoop. It pings the renderer, | 218 // NSEvent has been processed by the NSRunLoop. It pings the renderer, |
| 189 // which returns an IPC acknowledging the ping. At that time, redisplay | 219 // which returns an IPC acknowledging the ping. At that time, redisplay |
| 190 // the popup. FIFO processing of IPCs ensures that all side effects of the | 220 // the popup. FIFO processing of IPCs ensures that all side effects of the |
| 191 // NSEvent will have been processed. | 221 // NSEvent will have been processed. |
| 192 | 222 |
| 193 // 10ms sits nicely under the 16ms threshold for 60 fps, and likely gives | 223 // 10ms sits nicely under the 16ms threshold for 60 fps, and likely gives |
| 194 // the NSApplication run loop sufficient time to process the NSEvent. In | 224 // the NSApplication run loop sufficient time to process the NSEvent. In |
| 195 // testing, a delay of 0ms was always sufficient. | 225 // testing, a delay of 0ms was always sufficient. |
| 196 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | 226 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); |
| 197 base::MessageLoop::current()->PostDelayedTask( | 227 base::MessageLoop::current()->PostDelayedTask( |
| 198 FROM_HERE, | 228 FROM_HERE, |
| 199 base::Bind(&AutofillExternalDelegate::PingRenderer, GetWeakPtr()), | 229 base::Bind(&AutofillExternalDelegate::PingRenderer, GetWeakPtr()), |
| 200 delay); | 230 delay); |
| 201 #else | 231 #else |
| 202 NOTREACHED(); | 232 NOTREACHED(); |
| 203 #endif | 233 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 204 } else { | 234 } else { |
| 205 FillAutofillFormData(identifier, false); | 235 FillAutofillFormData(identifier, false); |
| 206 } | 236 } |
| 207 | 237 |
| 208 manager_->delegate()->HideAutofillPopup(); | 238 manager_->delegate()->HideAutofillPopup(); |
| 209 } | 239 } |
| 210 | 240 |
| 211 void AutofillExternalDelegate::RemoveSuggestion(const base::string16& value, | 241 void AutofillExternalDelegate::RemoveSuggestion(const base::string16& value, |
| 212 int identifier) { | 242 int identifier) { |
| 213 if (identifier > 0) | 243 if (identifier > 0) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 224 | 254 |
| 225 void AutofillExternalDelegate::ClearPreviewedForm() { | 255 void AutofillExternalDelegate::ClearPreviewedForm() { |
| 226 driver_->RendererShouldClearPreviewedForm(); | 256 driver_->RendererShouldClearPreviewedForm(); |
| 227 } | 257 } |
| 228 | 258 |
| 229 void AutofillExternalDelegate::Reset() { | 259 void AutofillExternalDelegate::Reset() { |
| 230 manager_->delegate()->HideAutofillPopup(); | 260 manager_->delegate()->HideAutofillPopup(); |
| 231 } | 261 } |
| 232 | 262 |
| 233 void AutofillExternalDelegate::OnPingAck() { | 263 void AutofillExternalDelegate::OnPingAck() { |
| 234 // Reissue the most recent query, which will reopen the autofill popup. | 264 // Reissue the most recent query, which will reopen the Autofill popup. |
| 235 manager_->OnQueryFormFieldAutofill(query_id_, | 265 manager_->OnQueryFormFieldAutofill(query_id_, |
| 236 query_form_, | 266 query_form_, |
| 237 query_field_, | 267 query_field_, |
| 238 element_bounds_, | 268 element_bounds_, |
| 239 display_warning_if_disabled_); | 269 display_warning_if_disabled_); |
| 240 } | 270 } |
| 241 | 271 |
| 242 base::WeakPtr<AutofillExternalDelegate> AutofillExternalDelegate::GetWeakPtr() { | 272 base::WeakPtr<AutofillExternalDelegate> AutofillExternalDelegate::GetWeakPtr() { |
| 243 return weak_ptr_factory_.GetWeakPtr(); | 273 return weak_ptr_factory_.GetWeakPtr(); |
| 244 } | 274 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 265 void AutofillExternalDelegate::ApplyAutofillWarnings( | 295 void AutofillExternalDelegate::ApplyAutofillWarnings( |
| 266 std::vector<base::string16>* values, | 296 std::vector<base::string16>* values, |
| 267 std::vector<base::string16>* labels, | 297 std::vector<base::string16>* labels, |
| 268 std::vector<base::string16>* icons, | 298 std::vector<base::string16>* icons, |
| 269 std::vector<int>* unique_ids) { | 299 std::vector<int>* unique_ids) { |
| 270 if (!query_field_.should_autocomplete) { | 300 if (!query_field_.should_autocomplete) { |
| 271 // Autofill is disabled. If there were some profile or credit card | 301 // Autofill is disabled. If there were some profile or credit card |
| 272 // suggestions to show, show a warning instead. Otherwise, clear out the | 302 // suggestions to show, show a warning instead. Otherwise, clear out the |
| 273 // list of suggestions. | 303 // list of suggestions. |
| 274 if (!unique_ids->empty() && (*unique_ids)[0] > 0) { | 304 if (!unique_ids->empty() && (*unique_ids)[0] > 0) { |
| 275 // If autofill is disabled and we had suggestions, show a warning instead. | 305 // If Autofill is disabled and we had suggestions, show a warning instead. |
| 276 values->assign( | 306 values->assign( |
| 277 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED)); | 307 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED)); |
| 278 labels->assign(1, base::string16()); | 308 labels->assign(1, base::string16()); |
| 279 icons->assign(1, base::string16()); | 309 icons->assign(1, base::string16()); |
| 280 unique_ids->assign(1, POPUP_ITEM_ID_WARNING_MESSAGE); | 310 unique_ids->assign(1, POPUP_ITEM_ID_WARNING_MESSAGE); |
| 281 } else { | 311 } else { |
| 282 values->clear(); | 312 values->clear(); |
| 283 labels->clear(); | 313 labels->clear(); |
| 284 icons->clear(); | 314 icons->clear(); |
| 285 unique_ids->clear(); | 315 unique_ids->clear(); |
| 286 } | 316 } |
| 287 } else if (unique_ids->size() > 1 && | 317 } else if (unique_ids->size() > 1 && |
| 288 (*unique_ids)[0] == POPUP_ITEM_ID_WARNING_MESSAGE) { | 318 (*unique_ids)[0] == POPUP_ITEM_ID_WARNING_MESSAGE) { |
| 289 // If we received a warning instead of suggestions from autofill but regular | 319 // If we received a warning instead of suggestions from Autofill but regular |
| 290 // suggestions from autocomplete, don't show the autofill warning. | 320 // suggestions from autocomplete, don't show the Autofill warning. |
| 291 values->erase(values->begin()); | 321 values->erase(values->begin()); |
| 292 labels->erase(labels->begin()); | 322 labels->erase(labels->begin()); |
| 293 icons->erase(icons->begin()); | 323 icons->erase(icons->begin()); |
| 294 unique_ids->erase(unique_ids->begin()); | 324 unique_ids->erase(unique_ids->begin()); |
| 295 } | 325 } |
| 296 | 326 |
| 297 // If we were about to show a warning and we shouldn't, don't. | 327 // If we were about to show a warning and we shouldn't, don't. |
| 298 if (!unique_ids->empty() && | 328 if (!unique_ids->empty() && |
| 299 (*unique_ids)[0] == POPUP_ITEM_ID_WARNING_MESSAGE && | 329 (*unique_ids)[0] == POPUP_ITEM_ID_WARNING_MESSAGE && |
| 300 !display_warning_if_disabled_) { | 330 !display_warning_if_disabled_) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 base::string16()); | 388 base::string16()); |
| 359 unique_ids->insert(unique_ids->begin(), | 389 unique_ids->insert(unique_ids->begin(), |
| 360 data_list_values_.size(), | 390 data_list_values_.size(), |
| 361 POPUP_ITEM_ID_DATALIST_ENTRY); | 391 POPUP_ITEM_ID_DATALIST_ENTRY); |
| 362 } | 392 } |
| 363 | 393 |
| 364 #if defined(OS_MACOSX) && !defined(OS_IOS) | 394 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 365 void AutofillExternalDelegate::PingRenderer() { | 395 void AutofillExternalDelegate::PingRenderer() { |
| 366 driver_->PingRenderer(); | 396 driver_->PingRenderer(); |
| 367 } | 397 } |
| 368 #endif | 398 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 369 | 399 |
| 370 } // namespace autofill | 400 } // namespace autofill |
| OLD | NEW |