Commit 97183058 authored by csharp@chromium.org's avatar csharp@chromium.org

Setting up external delegate calls to allow a future delegate to handle autofill

The external delegate IPC calls in autofill_agent are setup so that a future 
change that adds an external delegate should already have its code called at the
correct times and with the correct values.

BUG=51644
TEST=


Review URL: http://codereview.chromium.org/8490017

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110506 0039d316-1c4b-4281-b951-d872f2087c98
parent ea5419c7
......@@ -219,6 +219,11 @@ void AutocompleteHistoryManager::OnWebDataServiceRequestDone(
SendSuggestions(&suggestions);
}
void AutocompleteHistoryManager::SetExternalDelegate(
AutofillExternalDelegate* delegate) {
external_delegate_ = delegate;
}
AutocompleteHistoryManager::AutocompleteHistoryManager(
TabContents* tab_contents,
Profile* profile,
......@@ -271,15 +276,15 @@ void AutocompleteHistoryManager::SendSuggestions(
autofill_labels_,
autofill_icons_,
autofill_unique_ids_);
} else {
Send(new AutofillMsg_SuggestionsReturned(routing_id(),
query_id_,
autofill_values_,
autofill_labels_,
autofill_icons_,
autofill_unique_ids_));
}
Send(new AutofillMsg_SuggestionsReturned(routing_id(),
query_id_,
autofill_values_,
autofill_labels_,
autofill_icons_,
autofill_unique_ids_));
query_id_ = 0;
autofill_values_.clear();
autofill_labels_.clear();
......
......@@ -49,9 +49,7 @@ class AutocompleteHistoryManager : public TabContentsObserver,
void OnFormSubmitted(const webkit_glue::FormData& form);
// Sets our external delegate.
void SetExternalDelegate(AutofillExternalDelegate* delegate) {
external_delegate_ = delegate;
}
void SetExternalDelegate(AutofillExternalDelegate* delegate);
protected:
friend class AutocompleteHistoryManagerTest;
......
......@@ -19,6 +19,7 @@
#include "content/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect.h"
#include "webkit/glue/form_data.h"
using content::BrowserThread;
......@@ -146,7 +147,8 @@ class MockAutofillExternalDelegate : public AutofillExternalDelegate {
virtual void OnQuery(int query_id,
const webkit_glue::FormData& form,
const webkit_glue::FormField& field) {}
const webkit_glue::FormField& field,
const gfx::Rect& bounds) OVERRIDE {}
MOCK_METHOD5(OnSuggestionsReturned,
void(int query_id,
const std::vector<string16>& autofill_values,
......@@ -154,6 +156,8 @@ class MockAutofillExternalDelegate : public AutofillExternalDelegate {
const std::vector<string16>& autofill_icons,
const std::vector<int>& autofill_unique_ids));
virtual void HideAutofillPopup() OVERRIDE {}
private:
DISALLOW_COPY_AND_ASSIGN(MockAutofillExternalDelegate);
};
......@@ -186,4 +190,3 @@ TEST_F(AutocompleteHistoryManagerTest, ExternalDelegate) {
// Should trigger a call to OnSuggestionsReturned, verified by the mock.
autocomplete_history_manager.SendSuggestions(NULL);
}
......@@ -13,6 +13,10 @@
class AutofillManager;
class TabContentsWrapper;
namespace gfx {
class Rect;
}
namespace webkit_glue {
struct FormData;
struct FormField;
......@@ -30,14 +34,19 @@ class AutofillExternalDelegate {
void SelectAutofillSuggestionAtIndex(int listIndex);
// Records and associates a query_id with web form data. Called
// when the renderer posts an Autofill query to the browser.
// when the renderer posts an Autofill query to the browser. |bounds|
// is window relative.
virtual void OnQuery(int query_id,
const webkit_glue::FormData& form,
const webkit_glue::FormField& field) = 0;
const webkit_glue::FormField& field,
const gfx::Rect& bounds) = 0;
// Records query results. Displays them to the user with an external
// Autofill popup that lives completely in the browser. Called when
// an Autofill query result is available.
// TODO(csharp): This should contain the logic found in
// AutofillAgent::OnSuggestionsReturned.
// See http://crbug.com/51644
virtual void OnSuggestionsReturned(
int query_id,
const std::vector<string16>& autofill_values,
......@@ -45,6 +54,9 @@ class AutofillExternalDelegate {
const std::vector<string16>& autofill_icons,
const std::vector<int>& autofill_unique_ids) = 0;
// Hide the Autofill poup.
virtual void HideAutofillPopup() = 0;
// Platforms that wish to implement an external Autofill delegate
// MUST implement this. The 1st arg is the tab contents that owns
// this delegate; the second is the Autofill manager owned by the
......
......@@ -52,6 +52,7 @@
#include "grit/generated_resources.h"
#include "ipc/ipc_message_macros.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/rect.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_data_predictions.h"
#include "webkit/glue/form_field.h"
......@@ -311,6 +312,8 @@ bool AutofillManager::OnMessageReceived(const IPC::Message& message) {
OnDidFillAutofillFormData)
IPC_MESSAGE_HANDLER(AutofillHostMsg_DidShowAutofillSuggestions,
OnDidShowAutofillSuggestions)
IPC_MESSAGE_HANDLER(AutofillHostMsg_HideAutofillPopup,
OnHideAutofillPopup)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
......@@ -439,14 +442,16 @@ void AutofillManager::OnTextFieldDidChange(const FormData& form,
void AutofillManager::OnQueryFormFieldAutofill(int query_id,
const FormData& form,
const FormField& field) {
const FormField& field,
const gfx::Rect& bounding_box) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
std::vector<int> unique_ids;
if (external_delegate_)
external_delegate_->OnQuery(query_id, form, field);
if (external_delegate_) {
external_delegate_->OnQuery(query_id, form, field, bounding_box);
}
RenderViewHost* host = NULL;
FormStructure* form_structure = NULL;
......@@ -673,6 +678,11 @@ void AutofillManager::OnDidShowAutofillSuggestions(bool is_new_popup) {
}
}
void AutofillManager::OnHideAutofillPopup() {
if (external_delegate_)
external_delegate_->HideAutofillPopup();
}
void AutofillManager::OnLoadedServerPredictions(
const std::string& response_xml) {
// Parse and store the server predictions.
......
......@@ -36,6 +36,10 @@ class TabContentsWrapper;
struct ViewHostMsg_FrameNavigate_Params;
namespace gfx {
class Rect;
};
namespace IPC {
class Message;
}
......@@ -143,9 +147,12 @@ class AutofillManager : public TabContentsObserver,
void OnTextFieldDidChange(const webkit_glue::FormData& form,
const webkit_glue::FormField& field,
const base::TimeTicks& timestamp);
// The |bounding_box| is a window relative value.
void OnQueryFormFieldAutofill(int query_id,
const webkit_glue::FormData& form,
const webkit_glue::FormField& field);
const webkit_glue::FormField& field,
const gfx::Rect& bounding_box);
void OnFillAutofillFormData(int query_id,
const webkit_glue::FormData& form,
const webkit_glue::FormField& field,
......@@ -154,6 +161,7 @@ class AutofillManager : public TabContentsObserver,
void OnDidPreviewAutofillFormData();
void OnDidFillAutofillFormData(const base::TimeTicks& timestamp);
void OnDidShowAutofillSuggestions(bool is_new_popup);
void OnHideAutofillPopup();
// Fills |host| with the RenderViewHost for this tab.
// Returns false if Autofill is disabled or if the host is unavailable.
......
......@@ -38,6 +38,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/rect.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_field.h"
......@@ -567,7 +568,10 @@ class AutofillManagerTest : public TabContentsWrapperTestHarness {
void GetAutofillSuggestions(int query_id,
const webkit_glue::FormData& form,
const webkit_glue::FormField& field) {
autofill_manager_->OnQueryFormFieldAutofill(query_id, form, field);
autofill_manager_->OnQueryFormFieldAutofill(query_id,
form,
field,
gfx::Rect());
}
void GetAutofillSuggestions(const webkit_glue::FormData& form,
......@@ -2863,15 +2867,18 @@ class MockAutofillExternalDelegate : public AutofillExternalDelegate {
: AutofillExternalDelegate(wrapper) {}
virtual ~MockAutofillExternalDelegate() {}
MOCK_METHOD3(OnQuery, void(int query_id,
MOCK_METHOD4(OnQuery, void(int query_id,
const webkit_glue::FormData& form,
const webkit_glue::FormField& field));
const webkit_glue::FormField& field,
const gfx::Rect& bounds));
virtual void OnSuggestionsReturned(
int query_id,
const std::vector<string16>& autofill_values,
const std::vector<string16>& autofill_labels,
const std::vector<string16>& autofill_icons,
const std::vector<int>& autofill_unique_ids) {}
const std::vector<int>& autofill_unique_ids) OVERRIDE {}
virtual void HideAutofillPopup() OVERRIDE {}
private:
DISALLOW_COPY_AND_ASSIGN(MockAutofillExternalDelegate);
......@@ -2882,7 +2889,7 @@ class MockAutofillExternalDelegate : public AutofillExternalDelegate {
// Test our external delegate is called at the right time.
TEST_F(AutofillManagerTest, TestExternalDelegate) {
MockAutofillExternalDelegate external_delegate(contents_wrapper());
EXPECT_CALL(external_delegate, OnQuery(_, _, _));
EXPECT_CALL(external_delegate, OnQuery(_, _, _, _));
autofill_manager_->SetExternalDelegate(&external_delegate);
FormData form;
......
......@@ -22,6 +22,7 @@
#include "content/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_field.h"
......@@ -976,12 +977,12 @@ TEST_F(AutofillMetricsTest, AddressSuggestionsCount) {
LogAddressSuggestionsCount(2)).Times(1);
// Simulate activating the autofill popup for the phone field.
autofill_manager_->OnQueryFormFieldAutofill(0, form, field);
autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect());
// Simulate activating the autofill popup for the email field after typing.
// No new metric should be logged, since we're still on the same page.
autofill_test::CreateTestFormField("Email", "email", "b", "email", &field);
autofill_manager_->OnQueryFormFieldAutofill(0, form, field);
autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect());
// Reset the autofill manager state.
autofill_manager_->Reset();
......@@ -993,7 +994,7 @@ TEST_F(AutofillMetricsTest, AddressSuggestionsCount) {
LogAddressSuggestionsCount(1)).Times(1);
// Simulate activating the autofill popup for the email field after typing.
autofill_manager_->OnQueryFormFieldAutofill(0, form, field);
autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect());
// Reset the autofill manager state again.
autofill_manager_->Reset();
......@@ -1006,7 +1007,7 @@ TEST_F(AutofillMetricsTest, AddressSuggestionsCount) {
// Simulate activating the autofill popup for the email field after typing.
form.fields[0].is_autofilled = true;
autofill_manager_->OnQueryFormFieldAutofill(0, form, field);
autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::Rect());
}
// Test that we log whether Autofill is enabled when filling a form.
......
......@@ -10,6 +10,7 @@
#include "content/public/common/webkit_param_traits.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_utils.h"
#include "ui/gfx/rect.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_data_predictions.h"
#include "webkit/glue/form_field.h"
......@@ -122,10 +123,11 @@ IPC_MESSAGE_ROUTED3(AutofillHostMsg_TextFieldDidChange,
base::TimeTicks /* timestamp */)
// Queries the browser for Autofill suggestions for a form input field.
IPC_MESSAGE_ROUTED3(AutofillHostMsg_QueryFormFieldAutofill,
IPC_MESSAGE_ROUTED4(AutofillHostMsg_QueryFormFieldAutofill,
int /* id of this message */,
webkit_glue::FormData /* the form */,
webkit_glue::FormField /* the form field */)
webkit_glue::FormField /* the form field */,
gfx::Rect /* input field bounds, window-relative */)
// Sent when the popup with Autofill suggestions for a form is shown.
IPC_MESSAGE_ROUTED1(AutofillHostMsg_DidShowAutofillSuggestions,
......@@ -155,4 +157,5 @@ IPC_MESSAGE_ROUTED2(AutofillHostMsg_RemoveAutocompleteEntry,
// Instructs the browser to show the Autofill dialog.
IPC_MESSAGE_ROUTED0(AutofillHostMsg_ShowAutofillDialog)
// Instructs the browser to hide the Autofill popup.
IPC_MESSAGE_ROUTED0(AutofillHostMsg_HideAutofillPopup)
......@@ -19,6 +19,7 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "ui/base/keycodes/keyboard_codes.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -124,6 +125,8 @@ bool AutofillAgent::InputElementClicked(const WebInputElement& element,
}
bool AutofillAgent::InputElementLostFocus() {
Send(new AutofillHostMsg_HideAutofillPopup(routing_id()));
return false;
}
......@@ -414,8 +417,13 @@ void AutofillAgent::QueryAutofillSuggestions(const WebInputElement& element,
WebFormControlElementToFormField(element, EXTRACT_VALUE, &field);
}
// TODO(csharp): Stop using the hardcoded value once the WebKit change to
// expose the position lands.
// gfx::Rect bounding_box(autofill_query_element_.boundsInRootViewSpace());
gfx::Rect bounding_box(26, 51, 155, 22);
Send(new AutofillHostMsg_QueryFormFieldAutofill(
routing_id(), autofill_query_id_, form, field));
routing_id(), autofill_query_id_, form, field, bounding_box));
}
void AutofillAgent::FillAutofillFormData(const WebNode& node,
......
......@@ -101,7 +101,7 @@ class AutofillAgent : public content::RenderViewObserver,
void OnFieldTypePredictionsAvailable(
const std::vector<webkit_glue::FormDataPredictions>& forms);
// For external Autofill selection.
// For external Autofill selection.
void OnSelectAutofillSuggestionAtIndex(int listIndex);
// Called in a posted task by textFieldDidChange() to work-around a WebKit bug
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment