Chromium Code Reviews| Index: components/autofill/core/browser/autofill_external_delegate.cc |
| diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc |
| index 95cf8a14a1aff8ea0f06f75969d6685ee4919d12..8972de3cf6287732bbd248a3276d6f6a6391504d 100644 |
| --- a/components/autofill/core/browser/autofill_external_delegate.cc |
| +++ b/components/autofill/core/browser/autofill_external_delegate.cc |
| @@ -4,6 +4,7 @@ |
| #include "components/autofill/core/browser/autofill_external_delegate.h" |
| +#include "base/message_loop/message_loop.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "components/autofill/core/browser/autocomplete_history_manager.h" |
| #include "components/autofill/core/browser/autofill_driver.h" |
| @@ -14,9 +15,8 @@ |
| namespace autofill { |
| -AutofillExternalDelegate::AutofillExternalDelegate( |
| - AutofillManager* manager, |
| - AutofillDriver* driver) |
| +AutofillExternalDelegate::AutofillExternalDelegate(AutofillManager* manager, |
| + AutofillDriver* driver) |
| : manager_(manager), |
| driver_(driver), |
| query_id_(0), |
| @@ -91,6 +91,18 @@ void AutofillExternalDelegate::OnSuggestionsReturned( |
| // updated to match. |
| InsertDataListValues(&values, &labels, &icons, &ids); |
| +#if defined(OS_MACOSX) |
| + if (values.empty() && |
| + manager_->ShouldShowAccessAddressBookSuggestion(query_form_, |
| + query_field_)) { |
| + values.push_back( |
| + l10n_util::GetStringUTF16(IDS_AUTOFILL_ACCESS_MAC_CONTACTS)); |
| + labels.push_back(base::string16()); |
| + icons.push_back(base::string16()); |
| + ids.push_back(POPUP_ITEM_ID_MAC_ACCESS_CONTACTS); |
| + } |
| +#endif |
| + |
| if (values.empty()) { |
| // No suggestions, any popup currently showing is obsolete. |
| manager_->delegate()->HideAutofillPopup(); |
| @@ -157,6 +169,38 @@ void AutofillExternalDelegate::DidAcceptSuggestion(const base::string16& value, |
| } else if (identifier == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY) { |
| // User selected an Autocomplete, so we fill directly. |
| driver_->RendererShouldFillFieldWithValue(value); |
| + } else if (identifier == POPUP_ITEM_ID_MAC_ACCESS_CONTACTS) { |
| +#if defined(OS_MACOSX) |
| + // User wants to give Chrome access to user's address book. |
| + manager_->AccessAddressBook(); |
| + |
| + // There is no deterministic method for deciding whether a blocking dialog |
| + // was presented. The following comments and code assume that a blocking |
| + // dialog was presented, but still behave correctly if no dialog was |
| + // presented. |
| + |
| + // A blocking dialog was presented, and the user has already responded to |
| + // the dialog. The presentation of the dialog added an NSEvent to the |
| + // NSRunLoop which will cause all windows to lose focus. When the NSEvent |
| + // is processed, it will be sent to the renderer which will cause the text |
| + // field to lose focus. This returns an IPC to Chrome which will dismiss |
| + // the autofill popup. We post a task which we expect to run after the |
| + // NSEvent has been processed by the NSRunLoop. It pings the renderer, |
| + // which returns an IPC acknowledging the ping. At that time, redisplay |
| + // the popup. FIFO processing of IPCs ensures that all side effects of the |
| + // NSEvent will have been processed. |
| + |
| + // 10ms sits nicely under the 16ms threshold for 60 fps, and likely gives |
| + // the NSApplication run loop sufficient time to process the NSEvent. In |
| + // testing, a delay of 0ms was always sufficient. |
| + base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); |
| + base::MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + base::Bind(&AutofillExternalDelegate::PingRenderer, GetWeakPtr()), |
| + delay); |
| +#else |
| + NOTREACHED(); |
| +#endif |
| } else { |
| FillAutofillFormData(identifier, false); |
| } |
| @@ -186,6 +230,15 @@ void AutofillExternalDelegate::Reset() { |
| manager_->delegate()->HideAutofillPopup(); |
| } |
| +void AutofillExternalDelegate::OnPingAck() { |
| + // Reissues the most recent query, which will reopen the autofill popup. |
|
Ilya Sherman
2014/05/29 20:35:08
nit: "Reissues" -> "Reissue"
erikchen
2014/05/29 20:47:27
Done.
|
| + manager_->OnQueryFormFieldAutofill(query_id_, |
| + query_form_, |
| + query_field_, |
| + element_bounds_, |
| + display_warning_if_disabled_); |
| +} |
| + |
| base::WeakPtr<AutofillExternalDelegate> AutofillExternalDelegate::GetWeakPtr() { |
| return weak_ptr_factory_.GetWeakPtr(); |
| } |
| @@ -308,4 +361,10 @@ void AutofillExternalDelegate::InsertDataListValues( |
| POPUP_ITEM_ID_DATALIST_ENTRY); |
| } |
| +#if defined(OS_MACOSX) |
| +void AutofillExternalDelegate::PingRenderer() { |
| + driver_->PingRenderer(); |
| +} |
| +#endif |
| + |
| } // namespace autofill |