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/memory/scoped_vector.h"
9 #include "base/timer/elapsed_timer.h"
10 #include "chrome/browser/ui/passwords/manage_passwords_state.h"
11 #include "components/autofill/core/common/password_form.h"
12 #include "components/password_manager/core/browser/password_store.h"
13 #include "components/password_manager/core/common/password_manager_ui.h"
14 #include "content/public/browser/web_contents_observer.h"
15 #include "content/public/browser/web_contents_user_data.h"
21 namespace password_manager
{
22 enum class CredentialType
: unsigned int;
23 struct CredentialInfo
;
24 class PasswordFormManager
;
27 class ManagePasswordsIcon
;
29 // Per-tab class to control the Omnibox password icon and bubble.
30 class ManagePasswordsUIController
31 : public content::WebContentsObserver
,
32 public content::WebContentsUserData
<ManagePasswordsUIController
>,
33 public password_manager::PasswordStore::Observer
{
35 ~ManagePasswordsUIController() override
;
37 // Called when the user submits a form containing login information, so we
38 // can handle later requests to save or blacklist that login information.
39 // This stores the provided object and triggers the UI to prompt the user
40 // about whether they would like to save the password.
41 void OnPasswordSubmitted(
42 scoped_ptr
<password_manager::PasswordFormManager
> form_manager
);
44 // Called when the site asks user to choose from credentials. This triggers
45 // the UI to prompt the user. |local_credentials| and |federated_credentials|
46 // shouldn't both be empty.
47 bool OnChooseCredentials(
48 ScopedVector
<autofill::PasswordForm
> local_credentials
,
49 ScopedVector
<autofill::PasswordForm
> federated_credentials
,
51 base::Callback
<void(const password_manager::CredentialInfo
&)> callback
);
53 // Called when user is auto signed in to the site. |local_forms[0]| contains
54 // the credential returned to the site.
55 void OnAutoSignin(ScopedVector
<autofill::PasswordForm
> local_forms
);
57 // Called when the password will be saved automatically, but we still wish to
58 // visually inform the user that the save has occured.
59 void OnAutomaticPasswordSave(
60 scoped_ptr
<password_manager::PasswordFormManager
> form_manager
);
62 // Called when a form is autofilled with login information, so we can manage
63 // password credentials for the current site which are stored in
64 // |password_form_map|. This stores a copy of |password_form_map| and shows
65 // the manage password icon.
66 void OnPasswordAutofilled(const autofill::PasswordFormMap
& password_form_map
);
68 // Called when a form is _not_ autofilled due to user blacklisting. This
69 // stores a copy of |password_form_map| so that we can offer the user the
70 // ability to reenable the manager for this form.
71 void OnBlacklistBlockedAutofill(
72 const autofill::PasswordFormMap
& password_form_map
);
74 // PasswordStore::Observer implementation.
76 const password_manager::PasswordStoreChangeList
& changes
) override
;
78 // Called from the model when the user chooses to save a password; passes the
79 // action off to the FormManager. The controller MUST be in a pending state,
80 // and WILL be in MANAGE_STATE after this method executes.
81 virtual void SavePassword();
83 // Called from the model when the user chooses a credential.
84 // The controller MUST be in a pending credentials state.
85 virtual void ChooseCredential(
86 const autofill::PasswordForm
& form
,
87 password_manager::CredentialType credential_type
);
89 // Called from the model when the user chooses to never save passwords; passes
90 // the action off to the FormManager. The controller MUST be in a pending
91 // state, and WILL be in BLACKLIST_STATE after this method executes.
92 virtual void NeverSavePassword();
94 // Called from the model when the user chooses to unblacklist the site. The
95 // controller MUST be in BLACKLIST_STATE, and WILL be in MANAGE_STATE after
96 // this method executes. The method removes the first form of
97 // GetCurrentForms() which should be the blacklisted one.
98 virtual void UnblacklistSite();
100 // Called from the model. The controller should switch to MANAGE_STATE and pop
102 virtual void ManageAccounts();
104 // Open a new tab, pointing to the password manager settings page.
105 virtual void NavigateToPasswordManagerSettingsPage();
107 virtual const autofill::PasswordForm
& PendingPassword() const;
109 // Set the state of the Omnibox icon, and possibly show the associated bubble
110 // without user interaction.
111 virtual void UpdateIconAndBubbleState(ManagePasswordsIcon
* icon
);
113 // Called from the model when the bubble is displayed.
114 void OnBubbleShown();
116 // Called from the model when the bubble is hidden.
117 void OnBubbleHidden();
119 password_manager::ui::State
state() const { return passwords_data_
.state(); }
121 // True if a password is sitting around, waiting for a user to decide whether
122 // or not to save it.
123 bool PasswordPendingUserDecision() const {
124 return state() == password_manager::ui::PENDING_PASSWORD_STATE
;
127 const GURL
& origin() const { return passwords_data_
.origin(); }
129 bool IsAutomaticallyOpeningBubble() const { return should_pop_up_bubble_
; }
131 // Current local forms.
132 const std::vector
<const autofill::PasswordForm
*>& GetCurrentForms() const {
133 return passwords_data_
.GetCurrentForms();
136 // Current federated forms.
137 const std::vector
<const autofill::PasswordForm
*>& GetFederatedForms() const {
138 return passwords_data_
.federated_credentials_forms();
142 explicit ManagePasswordsUIController(
143 content::WebContents
* web_contents
);
145 // The pieces of saving and blacklisting passwords that interact with
146 // FormManager, split off into internal functions for testing/mocking.
147 virtual void SavePasswordInternal();
148 virtual void NeverSavePasswordInternal();
150 // Called when a PasswordForm is autofilled, when a new PasswordForm is
151 // submitted, or when a navigation occurs to update the visibility of the
152 // manage passwords icon and bubble.
153 virtual void UpdateBubbleAndIconVisibility();
155 // Returns the time elapsed since |timer_| was initialized,
156 // or base::TimeDelta::Max() if |timer_| was not initialized.
157 virtual base::TimeDelta
Elapsed() const;
159 // Overwrites the client for |passwords_data_|.
160 void set_client(password_manager::PasswordManagerClient
* client
) {
161 passwords_data_
.set_client(client
);
164 // content::WebContentsObserver:
165 void DidNavigateMainFrame(
166 const content::LoadCommittedDetails
& details
,
167 const content::FrameNavigateParams
& params
) override
;
168 void WasHidden() override
;
171 friend class content::WebContentsUserData
<ManagePasswordsUIController
>;
173 // Shows the password bubble without user interaction.
174 void ShowBubbleWithoutUserInteraction();
176 // content::WebContentsObserver:
177 void WebContentsDestroyed() override
;
179 // Shows infobar which allows user to choose credentials. Placing this
180 // code to separate method allows mocking.
181 virtual void UpdateAndroidAccountChooserInfoBarVisibility();
183 // The wrapper around current state and data.
184 ManagePasswordsState passwords_data_
;
186 // Used to measure the amount of time on a page; if it's less than some
187 // reasonable limit, then don't close the bubble upon navigation. We create
188 // (and destroy) the timer in DidNavigateMainFrame.
189 scoped_ptr
<base::ElapsedTimer
> timer_
;
191 // Contains true if the bubble is to be popped up in the next call to
192 // UpdateBubbleAndIconVisibility().
193 bool should_pop_up_bubble_
;
195 DISALLOW_COPY_AND_ASSIGN(ManagePasswordsUIController
);
198 #endif // CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_