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 |