summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/autofill/autofill_manager.cc6
-rw-r--r--chrome/browser/autofill/autofill_manager.h4
-rw-r--r--chrome/browser/password_manager/password_form_manager.cc12
-rw-r--r--chrome/browser/password_manager/password_form_manager.h8
-rw-r--r--chrome/browser/password_manager/password_manager.cc32
-rw-r--r--chrome/browser/password_manager/password_manager.h3
-rw-r--r--chrome/browser/password_manager/password_manager_unittest.cc29
-rw-r--r--chrome/browser/ui/browser_window.h16
-rw-r--r--chrome/browser/ui/gtk/browser_window_gtk.cc13
-rw-r--r--chrome/browser/ui/gtk/browser_window_gtk.h4
-rw-r--r--chrome/browser/ui/gtk/password_generation_bubble_gtk.cc11
-rw-r--r--chrome/browser/ui/gtk/password_generation_bubble_gtk.h15
-rw-r--r--chrome/browser/ui/views/frame/browser_view.cc12
-rw-r--r--chrome/browser/ui/views/frame/browser_view.h4
-rw-r--r--chrome/browser/ui/views/password_generation_bubble_view.cc10
-rw-r--r--chrome/browser/ui/views/password_generation_bubble_view.h15
-rw-r--r--chrome/common/autofill_messages.h7
-rw-r--r--chrome/renderer/autofill/password_generation_manager.cc11
-rw-r--r--chrome/renderer/autofill/password_generation_manager_browsertest.cc4
19 files changed, 182 insertions, 34 deletions
diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc
index 146c429..64c4db8 100644
--- a/chrome/browser/autofill/autofill_manager.cc
+++ b/chrome/browser/autofill/autofill_manager.cc
@@ -717,13 +717,15 @@ void AutofillManager::OnHideAutofillPopup() {
external_delegate_->HideAutofillPopup();
}
-void AutofillManager::OnShowPasswordGenerationPopup(const gfx::Rect& bounds) {
+void AutofillManager::OnShowPasswordGenerationPopup(
+ const gfx::Rect& bounds,
+ const webkit::forms::PasswordForm& form) {
#if defined(OS_ANDROID)
NOTIMPLEMENTED();
#else
Browser* browser = browser::FindLastActiveWithProfile(
Profile::FromBrowserContext(web_contents()->GetBrowserContext()));
- browser->window()->ShowPasswordGenerationBubble(bounds);
+ browser->window()->ShowPasswordGenerationBubble(bounds, form);
#endif // #if defined(OS_ANDROID)
}
diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h
index b483097..f70314b6 100644
--- a/chrome/browser/autofill/autofill_manager.h
+++ b/chrome/browser/autofill/autofill_manager.h
@@ -56,6 +56,7 @@ namespace webkit {
namespace forms {
struct FormData;
struct FormField;
+struct PasswordForm;
struct PasswordFormFillData;
}
}
@@ -93,7 +94,8 @@ class AutofillManager : public content::NotificationObserver,
void OnDidFillAutofillFormData(const base::TimeTicks& timestamp);
void OnShowAutofillDialog();
void OnDidPreviewAutofillFormData();
- void OnShowPasswordGenerationPopup(const gfx::Rect& bounds);
+ void OnShowPasswordGenerationPopup(const gfx::Rect& bounds,
+ const webkit::forms::PasswordForm& form);
// Remove the credit card or Autofill profile that matches |unique_id|
// from the database.
diff --git a/chrome/browser/password_manager/password_form_manager.cc b/chrome/browser/password_manager/password_form_manager.cc
index 1e5d20e..13c942d 100644
--- a/chrome/browser/password_manager/password_form_manager.cc
+++ b/chrome/browser/password_manager/password_form_manager.cc
@@ -26,6 +26,7 @@ PasswordFormManager::PasswordFormManager(Profile* profile,
: best_matches_deleter_(&best_matches_),
observed_form_(observed_form),
is_new_login_(true),
+ has_generated_password_(false),
password_manager_(password_manager),
pending_login_query_(0),
preferred_match_(NULL),
@@ -142,6 +143,17 @@ bool PasswordFormManager::IsNewLogin() {
return is_new_login_;
}
+void PasswordFormManager::SetHasGeneratedPassword() {
+ has_generated_password_ = true;
+}
+
+bool PasswordFormManager::HasGeneratedPassword() {
+ // This check is permissive, as the user may have generated a password and
+ // then edited it in the form itself. However, even in this case the user
+ // has already given consent, so we treat these cases the same.
+ return has_generated_password_;
+}
+
bool PasswordFormManager::HasValidPasswordForm() {
DCHECK_EQ(state_, POST_MATCHING_PHASE);
// Non-HTML password forms (primarily HTTP and FTP autentication)
diff --git a/chrome/browser/password_manager/password_form_manager.h b/chrome/browser/password_manager/password_form_manager.h
index 49d44a6..10c0d77 100644
--- a/chrome/browser/password_manager/password_form_manager.h
+++ b/chrome/browser/password_manager/password_form_manager.h
@@ -67,6 +67,11 @@ class PasswordFormManager : public PasswordStoreConsumer {
// login or password field are not considered valid.
bool HasValidPasswordForm();
+ // These functions are used to determine if this form has had it's password
+ // auto generated by the browser.
+ bool HasGeneratedPassword();
+ void SetHasGeneratedPassword();
+
// Determines if we need to autofill given the results of the query.
void OnRequestDone(
int handle, const std::vector<webkit::forms::PasswordForm*>& result);
@@ -196,6 +201,9 @@ class PasswordFormManager : public PasswordStoreConsumer {
// to an existing one.
bool is_new_login_;
+ // Whether this form has an auto generated password.
+ bool has_generated_password_;
+
// PasswordManager owning this.
const PasswordManager* const password_manager_;
diff --git a/chrome/browser/password_manager/password_manager.cc b/chrome/browser/password_manager/password_manager.cc
index cceed28..f83ce24 100644
--- a/chrome/browser/password_manager/password_manager.cc
+++ b/chrome/browser/password_manager/password_manager.cc
@@ -74,6 +74,27 @@ PasswordManager::PasswordManager(WebContents* web_contents,
PasswordManager::~PasswordManager() {
}
+void PasswordManager::SetFormHasGeneratedPassword(const PasswordForm& form) {
+ for (ScopedVector<PasswordFormManager>::iterator iter =
+ pending_login_managers_.begin();
+ iter != pending_login_managers_.end(); ++iter) {
+ if ((*iter)->DoesManage(form)) {
+ (*iter)->SetHasGeneratedPassword();
+ return;
+ }
+ }
+ // If there is no corresponding PasswordFormManager, we create one. This is
+ // not the common case, and should only happen when there is a bug in our
+ // ability to detect forms.
+ bool ssl_valid = (form.origin.SchemeIsSecure() &&
+ !delegate_->DidLastPageLoadEncounterSSLErrors());
+ PasswordFormManager* manager =
+ new PasswordFormManager(delegate_->GetProfile(), this, form, ssl_valid);
+ pending_login_managers_.push_back(manager);
+ manager->SetHasGeneratedPassword();
+ // TODO(gcasto): Add UMA stats to track this.
+}
+
bool PasswordManager::IsSavingEnabled() const {
return IsFillingEnabled() && !delegate_->GetProfile()->IsOffTheRecord();
}
@@ -205,15 +226,16 @@ void PasswordManager::OnPasswordFormsRendered(
return;
}
- // Looks like a successful login attempt. Either show an infobar or update
- // the previously saved login data.
+ // Looks like a successful login attempt. Either show an infobar or
+ // automatically save the login data. We prompt when the user hasn't already
+ // given consent, either through previously accepting the infobar or by having
+ // the browser generate the password.
provisional_save_manager_->SubmitPassed();
- if (provisional_save_manager_->IsNewLogin()) {
+ if (provisional_save_manager_->IsNewLogin() &&
+ !provisional_save_manager_->HasGeneratedPassword()) {
delegate_->AddSavePasswordInfoBarIfPermitted(
provisional_save_manager_.release());
} else {
- // If the save is not a new username entry, then we just want to save this
- // data (since the user already has related data saved), so don't prompt.
provisional_save_manager_->Save();
provisional_save_manager_.reset();
}
diff --git a/chrome/browser/password_manager/password_manager.h b/chrome/browser/password_manager/password_manager.h
index 50379f6..afeab33 100644
--- a/chrome/browser/password_manager/password_manager.h
+++ b/chrome/browser/password_manager/password_manager.h
@@ -53,6 +53,9 @@ class PasswordManager : public LoginModel,
// LoginModel implementation.
virtual void SetObserver(LoginModelObserver* observer) OVERRIDE;
+ // Mark this form as having a generated password.
+ void SetFormHasGeneratedPassword(const webkit::forms::PasswordForm& form);
+
// TODO(isherman): This should not be public, but is currently being used by
// the LoginPrompt code.
// When a form is submitted, we prepare to save the password but wait
diff --git a/chrome/browser/password_manager/password_manager_unittest.cc b/chrome/browser/password_manager/password_manager_unittest.cc
index 25dc33b..58363e8 100644
--- a/chrome/browser/password_manager/password_manager_unittest.cc
+++ b/chrome/browser/password_manager/password_manager_unittest.cc
@@ -136,6 +136,35 @@ TEST_F(PasswordManagerTest, FormSubmitEmptyStore) {
form_to_save->Save();
}
+TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) {
+ // This test is the same FormSubmitEmptyStore, except that it simulates the
+ // user generating the password through the browser.
+ std::vector<PasswordForm*> result; // Empty password store.
+ EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
+ EXPECT_CALL(*store_, GetLogins(_,_))
+ .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0)));
+ std::vector<PasswordForm> observed;
+ PasswordForm form(MakeSimpleForm());
+ observed.push_back(form);
+ manager()->OnPasswordFormsParsed(observed); // The initial load.
+ manager()->OnPasswordFormsRendered(observed); // The initial layout.
+
+ // Simulate the user generating the password and submitting the form.
+ manager()->SetFormHasGeneratedPassword(form);
+ manager()->ProvisionallySavePassword(form);
+
+ // The user should not be presented with an infobar as they have already given
+ // consent. The form should be saved once navigation occurs.
+ EXPECT_CALL(delegate_,
+ AddSavePasswordInfoBarIfPermitted(_)).Times(Exactly(0));
+ EXPECT_CALL(*store_, AddLogin(FormMatches(form)));
+
+ // Now the password manager waits for the navigation to complete.
+ observed.clear();
+ manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
+ manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
+}
+
TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) {
// Same as above, except with an existing form for the same signon realm,
// but different origin. Detailed cases like this are covered by
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 0753c33..7532fedb 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -45,6 +45,11 @@ class Rect;
class Size;
}
+namespace webkit {
+namespace forms {
+struct PasswordForm;
+}
+}
enum DevToolsDockSide {
DEVTOOLS_DOCK_SIDE_BOTTOM = 0,
@@ -363,10 +368,13 @@ class BrowserWindow : public BaseWindow {
// Shows the avatar bubble on the window frame off of the avatar button.
virtual void ShowAvatarBubbleFromAvatarButton() = 0;
- // Show bubble for password generation positioned relative to |rect|. A stub
- // implementation is provided since this feature is currently only available
- // for Windows.
- virtual void ShowPasswordGenerationBubble(const gfx::Rect& rect) {}
+ // Show bubble for password generation positioned relative to |rect|. |form|
+ // is the form that contains the password field that the bubble will be
+ // associated with. A stub implementation is provided since this feature is
+ // currently not available on mac.
+ virtual void ShowPasswordGenerationBubble(
+ const gfx::Rect& rect,
+ const webkit::forms::PasswordForm& form) {}
protected:
friend void browser::CloseAllBrowsers();
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc
index 1bc976a..1c0074e 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_window_gtk.cc
@@ -1288,16 +1288,25 @@ void BrowserWindowGtk::ShowAvatarBubbleFromAvatarButton() {
titlebar_->avatar_button()->ShowAvatarBubble();
}
-void BrowserWindowGtk::ShowPasswordGenerationBubble(const gfx::Rect& rect) {
+void BrowserWindowGtk::ShowPasswordGenerationBubble(
+ const gfx::Rect& rect,
+ const webkit::forms::PasswordForm& form) {
WebContents* web_contents = browser_->GetSelectedWebContents();
if (!web_contents || !web_contents->GetContentNativeView()) {
return;
}
+ TabContentsWrapper* tab_contents =
+ TabContentsWrapper::GetCurrentWrapperForContents(web_contents);
+ if (!tab_contents)
+ return;
+
new PasswordGenerationBubbleGtk(rect,
+ form,
web_contents->GetContentNativeView(),
browser()->profile(),
- web_contents->GetRenderViewHost());
+ web_contents->GetRenderViewHost(),
+ tab_contents->password_manager());
}
void BrowserWindowGtk::ConfirmBrowserCloseWithPendingDownloads() {
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.h b/chrome/browser/ui/gtk/browser_window_gtk.h
index 13e52a9..2e31480 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.h
+++ b/chrome/browser/ui/gtk/browser_window_gtk.h
@@ -169,7 +169,9 @@ class BrowserWindowGtk : public BrowserWindow,
virtual void ShowAvatarBubble(content::WebContents* web_contents,
const gfx::Rect& rect) OVERRIDE;
virtual void ShowAvatarBubbleFromAvatarButton() OVERRIDE;
- virtual void ShowPasswordGenerationBubble(const gfx::Rect& rect) OVERRIDE;
+ virtual void ShowPasswordGenerationBubble(
+ const gfx::Rect& rect,
+ const webkit::forms::PasswordForm& form) OVERRIDE;
// Overridden from NotificationObserver:
virtual void Observe(int type,
diff --git a/chrome/browser/ui/gtk/password_generation_bubble_gtk.cc b/chrome/browser/ui/gtk/password_generation_bubble_gtk.cc
index 2215496..b1a1a1e 100644
--- a/chrome/browser/ui/gtk/password_generation_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/password_generation_bubble_gtk.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/ui/gtk/password_generation_bubble_gtk.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/password_manager/password_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/gtk/bubble/bubble_gtk.h"
@@ -24,10 +25,15 @@ const int kHorizontalSpacing = 4;
PasswordGenerationBubbleGtk::PasswordGenerationBubbleGtk(
const gfx::Rect& anchor_rect,
+ const webkit::forms::PasswordForm& form,
GtkWidget* anchor_widget,
Profile* profile,
- content::RenderViewHost* render_view_host)
- : profile_(profile), render_view_host_(render_view_host) {
+ content::RenderViewHost* render_view_host,
+ PasswordManager* password_manager)
+ : profile_(profile),
+ form_(form),
+ render_view_host_(render_view_host),
+ password_manager_(password_manager) {
// TODO(gcasto): Localize text after we have finalized the UI.
// crbug.com/118062
GtkWidget* content = gtk_vbox_new(FALSE, 5);
@@ -87,6 +93,7 @@ void PasswordGenerationBubbleGtk::OnAcceptClicked(GtkWidget* widget) {
render_view_host_->Send(new AutofillMsg_GeneratedPasswordAccepted(
render_view_host_->GetRoutingID(),
UTF8ToUTF16(gtk_entry_get_text(GTK_ENTRY(text_field_)))));
+ password_manager_->SetFormHasGeneratedPassword(form_);
bubble_->Close();
}
diff --git a/chrome/browser/ui/gtk/password_generation_bubble_gtk.h b/chrome/browser/ui/gtk/password_generation_bubble_gtk.h
index 1de4e2d..d82ba3e 100644
--- a/chrome/browser/ui/gtk/password_generation_bubble_gtk.h
+++ b/chrome/browser/ui/gtk/password_generation_bubble_gtk.h
@@ -11,24 +11,28 @@
#include "chrome/browser/autofill/password_generator.h"
#include "ui/base/gtk/gtk_signal.h"
#include "ui/gfx/rect.h"
+#include "webkit/forms/password_form.h"
namespace content {
class RenderViewHost;
}
class BubbleGtk;
+class PasswordManager;
class Profile;
// PasswordGenerationBubbleGtk is a bubble use to show possible generated
// passwords to users. It is set in page content, anchored at |anchor_rect|.
// If the generated password is accepted by the user, the renderer associated
-// with |render_view_host| is informed of this password.
+// with |render_view_host| and the |password_manager| are informed.
class PasswordGenerationBubbleGtk {
public:
PasswordGenerationBubbleGtk(const gfx::Rect& anchor_rect,
+ const webkit::forms::PasswordForm& form,
GtkWidget* anchor_widget,
Profile* profile,
- content::RenderViewHost* render_view_host);
+ content::RenderViewHost* render_view_host,
+ PasswordManager* password_manager);
virtual ~PasswordGenerationBubbleGtk();
private:
@@ -41,9 +45,16 @@ class PasswordGenerationBubbleGtk {
GtkWidget* text_field_;
Profile* profile_;
+ // Form that contains the password field that we are generating a password
+ // for. Used by the password_manager_.
+ webkit::forms::PasswordForm form_;
+
// RenderViewHost associated with the button that spawned this bubble.
content::RenderViewHost* render_view_host_;
+ // PasswordManager for this tab.
+ PasswordManager* password_manager_;
+
// Class that deals with generating passwords.
autofill::PasswordGenerator password_generator_;
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 3926c7e..f813cc4 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -2401,7 +2401,9 @@ void BrowserView::ShowAvatarBubbleFromAvatarButton() {
button->ShowAvatarBubble();
}
-void BrowserView::ShowPasswordGenerationBubble(const gfx::Rect& rect) {
+void BrowserView::ShowPasswordGenerationBubble(
+ const gfx::Rect& rect,
+ const webkit::forms::PasswordForm& form) {
// Create a rect in the content bounds that the bubble will point to.
gfx::Point origin(rect.origin());
views::View::ConvertPointToScreen(GetTabContentsContainerView(), &origin);
@@ -2409,14 +2411,18 @@ void BrowserView::ShowPasswordGenerationBubble(const gfx::Rect& rect) {
// Create the bubble.
WebContents* web_contents = GetSelectedWebContents();
- if (!web_contents)
+ TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
+ if (!web_contents || !wrapper)
return;
PasswordGenerationBubbleView* bubble =
new PasswordGenerationBubbleView(bounds,
+ form,
this,
web_contents->GetRenderViewHost(),
- browser_.get());
+ browser_.get(),
+ wrapper->password_manager());
+
views::BubbleDelegateView::CreateBubble(bubble);
bubble->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
bubble->Show();
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 1320262..026dd3d 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -317,7 +317,9 @@ class BrowserView : public BrowserWindow,
virtual void ShowAvatarBubble(content::WebContents* web_contents,
const gfx::Rect& rect) OVERRIDE;
virtual void ShowAvatarBubbleFromAvatarButton() OVERRIDE;
- virtual void ShowPasswordGenerationBubble(const gfx::Rect& rect) OVERRIDE;
+ virtual void ShowPasswordGenerationBubble(
+ const gfx::Rect& rect,
+ const webkit::forms::PasswordForm& form) OVERRIDE;
// Overridden from BrowserWindowTesting:
virtual BookmarkBarView* GetBookmarkBarView() const OVERRIDE;
diff --git a/chrome/browser/ui/views/password_generation_bubble_view.cc b/chrome/browser/ui/views/password_generation_bubble_view.cc
index 68750d1..6cffa42 100644
--- a/chrome/browser/ui/views/password_generation_bubble_view.cc
+++ b/chrome/browser/ui/views/password_generation_bubble_view.cc
@@ -6,6 +6,7 @@
#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/password_generator.h"
+#include "chrome/browser/password_manager/password_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/common/autofill_messages.h"
@@ -27,15 +28,19 @@ using views::GridLayout;
PasswordGenerationBubbleView::PasswordGenerationBubbleView(
const gfx::Rect& anchor_rect,
+ const webkit::forms::PasswordForm& form,
views::View* anchor_view,
content::RenderViewHost* render_view_host,
- content::PageNavigator* navigator)
+ content::PageNavigator* navigator,
+ PasswordManager* password_manager)
: BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
accept_button_(NULL),
text_field_(NULL),
anchor_rect_(anchor_rect),
+ form_(form),
render_view_host_(render_view_host),
- navigator_(navigator) {}
+ navigator_(navigator),
+ password_manager_(password_manager) {}
PasswordGenerationBubbleView::~PasswordGenerationBubbleView() {}
@@ -93,6 +98,7 @@ void PasswordGenerationBubbleView::ButtonPressed(views::Button* sender,
if (sender == accept_button_) {
render_view_host_->Send(new AutofillMsg_GeneratedPasswordAccepted(
render_view_host_->GetRoutingID(), text_field_->text()));
+ password_manager_->SetFormHasGeneratedPassword(form_);
StartFade(false);
}
}
diff --git a/chrome/browser/ui/views/password_generation_bubble_view.h b/chrome/browser/ui/views/password_generation_bubble_view.h
index c3e69ba..fb0dd2e 100644
--- a/chrome/browser/ui/views/password_generation_bubble_view.h
+++ b/chrome/browser/ui/views/password_generation_bubble_view.h
@@ -12,6 +12,7 @@
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/link_listener.h"
#include "ui/views/view.h"
+#include "webkit/forms/password_form.h"
namespace content {
class PageNavigator;
@@ -23,18 +24,22 @@ class TextButton;
class Textfield;
}
+class PasswordManager;
+
// PasswordGenerationBubbleView is a bubble used to show possible generated
// passwords to users. It is set in the page content, anchored at |anchor_rect|.
// If the generated password is accepted by the user, the renderer associated
-// with |render_view_host| is informed.
+// with |render_view_host| and the |password_manager| are informed.
class PasswordGenerationBubbleView : public views::BubbleDelegateView,
public views::ButtonListener,
public views::LinkListener {
public:
PasswordGenerationBubbleView(const gfx::Rect& anchor_rect,
+ const webkit::forms::PasswordForm& form,
views::View* anchor_view,
content::RenderViewHost* render_view_host,
- content::PageNavigator* navigator);
+ content::PageNavigator* navigator,
+ PasswordManager* password_manager);
virtual ~PasswordGenerationBubbleView();
private:
@@ -56,6 +61,9 @@ class PasswordGenerationBubbleView : public views::BubbleDelegateView,
// Location that the bubble points to
gfx::Rect anchor_rect_;
+ // The form associated with the password field(s) that we are generated.
+ webkit::forms::PasswordForm form_;
+
// RenderViewHost associated with the button that spawned this bubble.
content::RenderViewHost* render_view_host_;
@@ -63,6 +71,9 @@ class PasswordGenerationBubbleView : public views::BubbleDelegateView,
// within this UI.
content::PageNavigator* navigator_;
+ // PasswordManager associated with this tab.
+ PasswordManager* password_manager_;
+
// Class to generate passwords
autofill::PasswordGenerator password_generator_;
diff --git a/chrome/common/autofill_messages.h b/chrome/common/autofill_messages.h
index fa17176..a2c7fba 100644
--- a/chrome/common/autofill_messages.h
+++ b/chrome/common/autofill_messages.h
@@ -199,9 +199,10 @@ IPC_MESSAGE_ROUTED0(AutofillHostMsg_HideAutofillPopup)
// Instructs the browser to show the password generation bubble at the
// specified location. This location should be specified in the renderers
-// coordinate system.
-IPC_MESSAGE_ROUTED1(AutofillHostMsg_ShowPasswordGenerationPopup,
- gfx::Rect /* source location */)
+// coordinate system. Form is the form associated with the password field.
+IPC_MESSAGE_ROUTED2(AutofillHostMsg_ShowPasswordGenerationPopup,
+ gfx::Rect /* source location */,
+ webkit::forms::PasswordForm)
// Instruct the browser that a password mapping has been found for a field.
IPC_MESSAGE_ROUTED2(AutofillHostMsg_AddPasswordFormMapping,
diff --git a/chrome/renderer/autofill/password_generation_manager.cc b/chrome/renderer/autofill/password_generation_manager.cc
index 65d9603..b4bc16f 100644
--- a/chrome/renderer/autofill/password_generation_manager.cc
+++ b/chrome/renderer/autofill/password_generation_manager.cc
@@ -80,8 +80,15 @@ void PasswordGenerationManager::FocusedNodeChanged(
if (!input_element.isNull() &&
account_creation_elements_.first == input_element) {
gfx::Rect rect(input_element.boundsInViewportSpace());
- Send(new AutofillHostMsg_ShowPasswordGenerationPopup(routing_id(),
- rect));
+ webkit::forms::PasswordForm* password_form(
+ webkit::forms::PasswordFormDomManager::CreatePasswordForm(
+ input_element.form()));
+
+ if (password_form) {
+ Send(new AutofillHostMsg_ShowPasswordGenerationPopup(routing_id(),
+ rect,
+ *password_form));
+ }
}
}
diff --git a/chrome/renderer/autofill/password_generation_manager_browsertest.cc b/chrome/renderer/autofill/password_generation_manager_browsertest.cc
index 12a5158..ce9367f 100644
--- a/chrome/renderer/autofill/password_generation_manager_browsertest.cc
+++ b/chrome/renderer/autofill/password_generation_manager_browsertest.cc
@@ -73,14 +73,14 @@ class PasswordGenerationManagerTest : public ChromeRenderViewTest {
};
const char kSigninFormHTML[] =
- "<FORM name = 'blah' action = 'www.random.com/'> "
+ "<FORM name = 'blah' action = 'http://www.random.com/'> "
" <INPUT type = 'text' id = 'username'/> "
" <INPUT type = 'password' id = 'password'/> "
" <INPUT type = 'submit' value = 'LOGIN' />"
"</FORM>";
const char kAccountCreationFormHTML[] =
- "<FORM name = 'blah' action = 'www.random.com/'> "
+ "<FORM name = 'blah' action = 'http://www.random.com/'> "
" <INPUT type = 'text' id = 'username'/> "
" <INPUT type = 'password' id = 'first_password'/> "
" <INPUT type = 'password' id = 'second_password'/> "