1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_
6 #define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_
8 #include "base/gtest_prod_util.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/timer/elapsed_timer.h"
11 #include "components/autofill/core/common/password_form.h"
12 #include "components/password_manager/core/browser/password_form_manager.h"
13 #include "components/password_manager/core/browser/password_store.h"
14 #include "components/password_manager/core/browser/password_store_change.h"
15 #include "components/password_manager/core/common/password_manager_ui.h"
16 #include "content/public/browser/navigation_details.h"
17 #include "content/public/browser/web_contents_observer.h"
18 #include "content/public/browser/web_contents_user_data.h"
24 class ManagePasswordsIcon
;
26 // Per-tab class to control the Omnibox password icon and bubble.
27 class ManagePasswordsUIController
28 : public content::WebContentsObserver
,
29 public content::WebContentsUserData
<ManagePasswordsUIController
>,
30 public password_manager::PasswordStore::Observer
{
32 virtual ~ManagePasswordsUIController();
34 // Called when the user submits a form containing login information, so we
35 // can handle later requests to save or blacklist that login information.
36 // This stores the provided object in form_manager_ and triggers the UI to
37 // prompt the user about whether they would like to save the password.
38 void OnPasswordSubmitted(
39 scoped_ptr
<password_manager::PasswordFormManager
> form_manager
);
41 // Called when the password will be saved automatically, but we still wish to
42 // visually inform the user that the save has occured.
43 void OnAutomaticPasswordSave(
44 scoped_ptr
<password_manager::PasswordFormManager
> form_manager
);
46 // Called when a form is autofilled with login information, so we can manage
47 // password credentials for the current site which are stored in
48 // |password_form_map|. This stores a copy of |password_form_map| and shows
49 // the manage password icon.
50 void OnPasswordAutofilled(const autofill::PasswordFormMap
& password_form_map
);
52 // Called when a form is _not_ autofilled due to user blacklisting. This
53 // stores a copy of |password_form_map| so that we can offer the user the
54 // ability to reenable the manager for this form.
55 void OnBlacklistBlockedAutofill(
56 const autofill::PasswordFormMap
& password_form_map
);
58 // PasswordStore::Observer implementation.
59 virtual void OnLoginsChanged(
60 const password_manager::PasswordStoreChangeList
& changes
) override
;
62 // Called from the model when the user chooses to save a password; passes the
63 // action off to the FormManager. The controller MUST be in a pending state,
64 // and WILL be in MANAGE_STATE after this method executes.
65 virtual void SavePassword();
67 // Called from the model when the user chooses to never save passwords; passes
68 // the action off to the FormManager. The controller MUST be in a pending
69 // state, and WILL be in BLACKLIST_STATE after this method executes.
70 virtual void NeverSavePassword();
72 // Called from the model when the user chooses to unblacklist the site. The
73 // controller MUST be in BLACKLIST_STATE, and WILL be in MANAGE_STATE after
74 // this method executes.
75 virtual void UnblacklistSite();
77 // Open a new tab, pointing to the password manager settings page.
78 virtual void NavigateToPasswordManagerSettingsPage();
80 virtual const autofill::PasswordForm
& PendingCredentials() const;
82 // Set the state of the Omnibox icon, and possibly show the associated bubble
83 // without user interaction.
84 virtual void UpdateIconAndBubbleState(ManagePasswordsIcon
* icon
);
86 password_manager::ui::State
state() const { return state_
; }
88 // True if a password is sitting around, waiting for a user to decide whether
90 bool PasswordPendingUserDecision() const;
92 const autofill::ConstPasswordFormMap
& best_matches() const {
93 return password_form_map_
;
96 const GURL
& origin() const { return origin_
; }
99 explicit ManagePasswordsUIController(
100 content::WebContents
* web_contents
);
102 // The pieces of saving and blacklisting passwords that interact with
103 // FormManager, split off into internal functions for testing/mocking.
104 virtual void SavePasswordInternal();
105 virtual void NeverSavePasswordInternal();
107 // content::WebContentsObserver:
108 virtual void DidNavigateMainFrame(
109 const content::LoadCommittedDetails
& details
,
110 const content::FrameNavigateParams
& params
) override
;
111 virtual void WasHidden() override
;
113 // We create copies of PasswordForm objects that come in with unclear lifetime
114 // and store them in this vector as well as in |password_form_map_| to ensure
115 // that we destroy them correctly. If |new_password_forms_| gets cleared then
116 // |password_form_map_| is to be cleared too.
117 ScopedVector
<autofill::PasswordForm
> new_password_forms_
;
119 // All previously stored credentials for a specific site.
120 // Protected, not private, so we can mess with the value in
121 // ManagePasswordsUIControllerMock.
122 autofill::ConstPasswordFormMap password_form_map_
;
124 // The current state of the password manager. Protected so we can manipulate
125 // the value in tests.
126 password_manager::ui::State state_
;
128 // Used to measure the amount of time on a page; if it's less than some
129 // reasonable limit, then don't close the bubble upon navigation. We create
130 // (and destroy) the timer in DidNavigateMainFrame.
131 scoped_ptr
<base::ElapsedTimer
> timer_
;
134 friend class content::WebContentsUserData
<ManagePasswordsUIController
>;
136 // Shows the password bubble without user interaction. The controller MUST
137 // be in PENDING_PASSWORD_AND_BUBBLE_STATE.
138 void ShowBubbleWithoutUserInteraction();
140 // Called when a passwordform is autofilled, when a new passwordform is
141 // submitted, or when a navigation occurs to update the visibility of the
142 // manage passwords icon and bubble.
143 void UpdateBubbleAndIconVisibility();
145 // content::WebContentsObserver:
146 virtual void WebContentsDestroyed() override
;
148 // Set by OnPasswordSubmitted() when the user submits a form containing login
149 // information. If the user responds to a subsequent "Do you want to save
150 // this password?" prompt, we ask this object to save or blacklist the
151 // associated login information in Chrome's password store.
152 scoped_ptr
<password_manager::PasswordFormManager
> form_manager_
;
154 // Stores whether autofill was blocked due to a user's decision to blacklist
155 // the current site ("Never save passwords for this site").
156 bool autofill_blocked_
;
158 // The origin of the form we're currently dealing with; we'll use this to
159 // determine which PasswordStore changes we should care about when updating
160 // |password_form_map_|.
163 DISALLOW_COPY_AND_ASSIGN(ManagePasswordsUIController
);
166 #endif // CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_