OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" | 5 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" |
6 | 6 |
| 7 #include "base/auto_reset.h" |
7 #include "chrome/app/chrome_command_ids.h" | 8 #include "chrome/app/chrome_command_ids.h" |
8 #include "chrome/browser/browsing_data/browsing_data_helper.h" | 9 #include "chrome/browser/browsing_data/browsing_data_helper.h" |
9 #include "chrome/browser/password_manager/chrome_password_manager_client.h" | 10 #include "chrome/browser/password_manager/chrome_password_manager_client.h" |
10 #include "chrome/browser/password_manager/password_store_factory.h" | 11 #include "chrome/browser/password_manager/password_store_factory.h" |
11 #include "chrome/browser/ui/browser_command_controller.h" | 12 #include "chrome/browser/ui/browser_command_controller.h" |
12 #include "chrome/browser/ui/browser_finder.h" | 13 #include "chrome/browser/ui/browser_finder.h" |
13 #include "chrome/browser/ui/browser_window.h" | 14 #include "chrome/browser/ui/browser_window.h" |
14 #include "chrome/browser/ui/chrome_pages.h" | 15 #include "chrome/browser/ui/chrome_pages.h" |
15 #include "chrome/browser/ui/location_bar/location_bar.h" | 16 #include "chrome/browser/ui/location_bar/location_bar.h" |
16 #include "chrome/browser/ui/passwords/manage_passwords_icon.h" | 17 #include "chrome/browser/ui/passwords/manage_passwords_icon.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 } | 61 } |
61 | 62 |
62 } // namespace | 63 } // namespace |
63 | 64 |
64 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ManagePasswordsUIController); | 65 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ManagePasswordsUIController); |
65 | 66 |
66 ManagePasswordsUIController::ManagePasswordsUIController( | 67 ManagePasswordsUIController::ManagePasswordsUIController( |
67 content::WebContents* web_contents) | 68 content::WebContents* web_contents) |
68 : content::WebContentsObserver(web_contents), | 69 : content::WebContentsObserver(web_contents), |
69 state_(password_manager::ui::INACTIVE_STATE), | 70 state_(password_manager::ui::INACTIVE_STATE), |
70 bubble_shown_(false) { | 71 should_pop_up_bubble_(false) { |
71 password_manager::PasswordStore* password_store = | 72 password_manager::PasswordStore* password_store = |
72 GetPasswordStore(web_contents); | 73 GetPasswordStore(web_contents); |
73 if (password_store) | 74 if (password_store) |
74 password_store->AddObserver(this); | 75 password_store->AddObserver(this); |
75 } | 76 } |
76 | 77 |
77 ManagePasswordsUIController::~ManagePasswordsUIController() {} | 78 ManagePasswordsUIController::~ManagePasswordsUIController() {} |
78 | 79 |
79 void ManagePasswordsUIController::UpdateBubbleAndIconVisibility() { | 80 void ManagePasswordsUIController::UpdateBubbleAndIconVisibility() { |
80 bubble_shown_ = false; | |
81 // If we're not on a "webby" URL (e.g. "chrome://sign-in"), we shouldn't | 81 // If we're not on a "webby" URL (e.g. "chrome://sign-in"), we shouldn't |
82 // display either the bubble or the icon. | 82 // display either the bubble or the icon. |
83 if (!BrowsingDataHelper::IsWebScheme( | 83 if (!BrowsingDataHelper::IsWebScheme( |
84 web_contents()->GetLastCommittedURL().scheme())) { | 84 web_contents()->GetLastCommittedURL().scheme())) { |
85 SetState(password_manager::ui::INACTIVE_STATE); | 85 SetState(password_manager::ui::INACTIVE_STATE); |
86 } | 86 } |
87 | 87 |
88 #if !defined(OS_ANDROID) | 88 #if !defined(OS_ANDROID) |
89 Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); | 89 Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); |
90 if (!browser) | 90 if (!browser) |
91 return; | 91 return; |
92 LocationBar* location_bar = browser->window()->GetLocationBar(); | 92 LocationBar* location_bar = browser->window()->GetLocationBar(); |
93 DCHECK(location_bar); | 93 DCHECK(location_bar); |
94 location_bar->UpdateManagePasswordsIconAndBubble(); | 94 location_bar->UpdateManagePasswordsIconAndBubble(); |
95 #endif | 95 #endif |
96 } | 96 } |
97 | 97 |
98 base::TimeDelta ManagePasswordsUIController::Elapsed() const { | 98 base::TimeDelta ManagePasswordsUIController::Elapsed() const { |
99 return timer_ ? timer_->Elapsed() : base::TimeDelta::Max(); | 99 return timer_ ? timer_->Elapsed() : base::TimeDelta::Max(); |
100 } | 100 } |
101 | 101 |
102 void ManagePasswordsUIController::OnAskToReportURL(const GURL& url) { | 102 void ManagePasswordsUIController::OnAskToReportURL(const GURL& url) { |
103 origin_ = url; | 103 origin_ = url; |
104 SetState(password_manager::ui::ASK_USER_REPORT_URL_STATE); | 104 SetState(password_manager::ui:: |
| 105 ASK_USER_REPORT_URL_BUBBLE_SHOWN_BEFORE_TRANSITION_STATE); |
| 106 base::AutoReset<bool> resetter(&should_pop_up_bubble_, true); |
105 UpdateBubbleAndIconVisibility(); | 107 UpdateBubbleAndIconVisibility(); |
106 } | 108 } |
107 | 109 |
108 void ManagePasswordsUIController::OnPasswordSubmitted( | 110 void ManagePasswordsUIController::OnPasswordSubmitted( |
109 scoped_ptr<PasswordFormManager> form_manager) { | 111 scoped_ptr<PasswordFormManager> form_manager) { |
110 form_manager_ = form_manager.Pass(); | 112 form_manager_ = form_manager.Pass(); |
111 password_form_map_ = ConstifyMap(form_manager_->best_matches()); | 113 password_form_map_ = ConstifyMap(form_manager_->best_matches()); |
112 origin_ = PendingPassword().origin; | 114 origin_ = PendingPassword().origin; |
113 SetState(password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE); | 115 SetState(password_manager::ui::PENDING_PASSWORD_STATE); |
114 timer_.reset(new base::ElapsedTimer()); | 116 timer_.reset(new base::ElapsedTimer); |
| 117 base::AutoReset<bool> resetter(&should_pop_up_bubble_, true); |
115 UpdateBubbleAndIconVisibility(); | 118 UpdateBubbleAndIconVisibility(); |
116 } | 119 } |
117 | 120 |
118 bool ManagePasswordsUIController::OnChooseCredentials( | 121 bool ManagePasswordsUIController::OnChooseCredentials( |
119 ScopedVector<autofill::PasswordForm> local_credentials, | 122 ScopedVector<autofill::PasswordForm> local_credentials, |
120 ScopedVector<autofill::PasswordForm> federated_credentials, | 123 ScopedVector<autofill::PasswordForm> federated_credentials, |
121 const GURL& origin, | 124 const GURL& origin, |
122 base::Callback<void(const password_manager::CredentialInfo&)> callback) { | 125 base::Callback<void(const password_manager::CredentialInfo&)> callback) { |
123 DCHECK(!local_credentials.empty() || !federated_credentials.empty()); | 126 DCHECK(!local_credentials.empty() || !federated_credentials.empty()); |
124 form_manager_.reset(); | 127 form_manager_.reset(); |
125 origin_ = origin; | 128 origin_ = origin; |
126 local_credentials_forms_.swap(local_credentials); | 129 local_credentials_forms_.swap(local_credentials); |
127 federated_credentials_forms_.swap(federated_credentials); | 130 federated_credentials_forms_.swap(federated_credentials); |
128 // The map is useless because usernames may overlap. | 131 // The map is useless because usernames may overlap. |
129 password_form_map_.clear(); | 132 password_form_map_.clear(); |
130 SetState(password_manager::ui::CREDENTIAL_REQUEST_AND_BUBBLE_STATE); | 133 SetState(password_manager::ui::CREDENTIAL_REQUEST_STATE); |
| 134 base::AutoReset<bool> resetter(&should_pop_up_bubble_, true); |
131 UpdateBubbleAndIconVisibility(); | 135 UpdateBubbleAndIconVisibility(); |
132 if (bubble_shown_) | 136 if (!should_pop_up_bubble_) { |
133 credentials_callback_ = callback; | 137 credentials_callback_ = callback; |
134 return bubble_shown_; | 138 return true; |
| 139 } |
| 140 return false; |
135 } | 141 } |
136 | 142 |
137 void ManagePasswordsUIController::OnAutomaticPasswordSave( | 143 void ManagePasswordsUIController::OnAutomaticPasswordSave( |
138 scoped_ptr<PasswordFormManager> form_manager) { | 144 scoped_ptr<PasswordFormManager> form_manager) { |
139 form_manager_ = form_manager.Pass(); | 145 form_manager_ = form_manager.Pass(); |
140 password_form_map_ = ConstifyMap(form_manager_->best_matches()); | 146 password_form_map_ = ConstifyMap(form_manager_->best_matches()); |
141 password_form_map_[form_manager_->associated_username()] = | 147 password_form_map_[form_manager_->associated_username()] = |
142 &form_manager_->pending_credentials(); | 148 &form_manager_->pending_credentials(); |
143 origin_ = form_manager_->pending_credentials().origin; | 149 origin_ = form_manager_->pending_credentials().origin; |
144 SetState(password_manager::ui::CONFIRMATION_STATE); | 150 SetState(password_manager::ui::CONFIRMATION_STATE); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 void ManagePasswordsUIController::SavePassword() { | 213 void ManagePasswordsUIController::SavePassword() { |
208 DCHECK(PasswordPendingUserDecision()); | 214 DCHECK(PasswordPendingUserDecision()); |
209 SavePasswordInternal(); | 215 SavePasswordInternal(); |
210 SetState(password_manager::ui::MANAGE_STATE); | 216 SetState(password_manager::ui::MANAGE_STATE); |
211 UpdateBubbleAndIconVisibility(); | 217 UpdateBubbleAndIconVisibility(); |
212 } | 218 } |
213 | 219 |
214 void ManagePasswordsUIController::ChooseCredential( | 220 void ManagePasswordsUIController::ChooseCredential( |
215 const autofill::PasswordForm& form, | 221 const autofill::PasswordForm& form, |
216 password_manager::CredentialType credential_type) { | 222 password_manager::CredentialType credential_type) { |
217 DCHECK(password_manager::ui::IsCredentialsState(state_)); | 223 DCHECK_EQ(password_manager::ui::CREDENTIAL_REQUEST_STATE, state_); |
218 DCHECK(!credentials_callback_.is_null()); | 224 DCHECK(!credentials_callback_.is_null()); |
219 password_manager::CredentialInfo info = | 225 password_manager::CredentialInfo info = |
220 password_manager::CredentialInfo(form, credential_type); | 226 password_manager::CredentialInfo(form, credential_type); |
221 credentials_callback_.Run(info); | 227 credentials_callback_.Run(info); |
222 SetState(password_manager::ui::INACTIVE_STATE); | 228 credentials_callback_.Reset(); |
223 UpdateBubbleAndIconVisibility(); | |
224 } | 229 } |
225 | 230 |
226 void ManagePasswordsUIController::SavePasswordInternal() { | 231 void ManagePasswordsUIController::SavePasswordInternal() { |
227 DCHECK(form_manager_.get()); | 232 DCHECK(form_manager_.get()); |
228 form_manager_->Save(); | 233 form_manager_->Save(); |
229 } | 234 } |
230 | 235 |
231 void ManagePasswordsUIController::NeverSavePassword() { | 236 void ManagePasswordsUIController::NeverSavePassword() { |
232 DCHECK(PasswordPendingUserDecision()); | 237 DCHECK(PasswordPendingUserDecision()); |
233 NeverSavePasswordInternal(); | 238 NeverSavePasswordInternal(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 } | 312 } |
308 | 313 |
309 const autofill::PasswordForm& ManagePasswordsUIController:: | 314 const autofill::PasswordForm& ManagePasswordsUIController:: |
310 PendingPassword() const { | 315 PendingPassword() const { |
311 DCHECK(form_manager_); | 316 DCHECK(form_manager_); |
312 return form_manager_->pending_credentials(); | 317 return form_manager_->pending_credentials(); |
313 } | 318 } |
314 | 319 |
315 void ManagePasswordsUIController::UpdateIconAndBubbleState( | 320 void ManagePasswordsUIController::UpdateIconAndBubbleState( |
316 ManagePasswordsIcon* icon) { | 321 ManagePasswordsIcon* icon) { |
317 if (password_manager::ui::IsAutomaticDisplayState(state_)) { | 322 if (should_pop_up_bubble_) { |
318 // We must display the icon before showing the bubble, as the bubble would | 323 // We must display the icon before showing the bubble, as the bubble would |
319 // be otherwise unanchored. However, we can't change the controller's state | 324 // be otherwise unanchored. |
320 // until _after_ the bubble is shown, as our metrics depend on the seeing | 325 icon->SetState(state_); |
321 // the original state to determine if the bubble opened automagically or via | |
322 // user action. | |
323 password_manager::ui::State end_state = | |
324 GetEndStateForAutomaticState(state_); | |
325 icon->SetState(end_state); | |
326 ShowBubbleWithoutUserInteraction(); | 326 ShowBubbleWithoutUserInteraction(); |
327 SetState(end_state); | |
328 } else { | 327 } else { |
329 icon->SetState(state_); | 328 icon->SetState(state_); |
330 } | 329 } |
331 } | 330 } |
332 | 331 |
333 void ManagePasswordsUIController::OnBubbleShown() { | 332 void ManagePasswordsUIController::OnBubbleShown() { |
334 bubble_shown_ = true; | 333 should_pop_up_bubble_ = false; |
| 334 } |
| 335 |
| 336 void ManagePasswordsUIController::OnBubbleHidden() { |
| 337 password_manager::ui::State next_state = state_; |
| 338 if (state_ == password_manager::ui::CREDENTIAL_REQUEST_STATE) |
| 339 next_state = password_manager::ui::INACTIVE_STATE; |
| 340 else if (state_ == password_manager::ui::CONFIRMATION_STATE) |
| 341 next_state = password_manager::ui::MANAGE_STATE; |
| 342 |
| 343 if (next_state != state_) { |
| 344 SetState(next_state); |
| 345 UpdateBubbleAndIconVisibility(); |
| 346 } |
335 } | 347 } |
336 | 348 |
337 void ManagePasswordsUIController::ShowBubbleWithoutUserInteraction() { | 349 void ManagePasswordsUIController::ShowBubbleWithoutUserInteraction() { |
338 DCHECK(password_manager::ui::IsAutomaticDisplayState(state_)); | 350 DCHECK(should_pop_up_bubble_); |
339 #if !defined(OS_ANDROID) | 351 #if !defined(OS_ANDROID) |
340 Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); | 352 Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); |
341 if (!browser || browser->toolbar_model()->input_in_progress()) | 353 if (!browser || browser->toolbar_model()->input_in_progress()) |
342 return; | 354 return; |
343 if (state_ == password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE && | |
344 !password_bubble_experiment::ShouldShowBubble( | |
345 browser->profile()->GetPrefs())) | |
346 return; | |
347 CommandUpdater* updater = browser->command_controller()->command_updater(); | 355 CommandUpdater* updater = browser->command_controller()->command_updater(); |
348 updater->ExecuteCommand(IDC_MANAGE_PASSWORDS_FOR_PAGE); | 356 updater->ExecuteCommand(IDC_MANAGE_PASSWORDS_FOR_PAGE); |
349 #endif | 357 #endif |
350 } | 358 } |
351 | 359 |
352 bool ManagePasswordsUIController::PasswordPendingUserDecision() const { | 360 bool ManagePasswordsUIController::PasswordPendingUserDecision() const { |
353 return password_manager::ui::IsPendingState(state_); | 361 return state_ == password_manager::ui::PENDING_PASSWORD_STATE; |
354 } | 362 } |
355 | 363 |
356 void ManagePasswordsUIController::WebContentsDestroyed() { | 364 void ManagePasswordsUIController::WebContentsDestroyed() { |
357 password_manager::PasswordStore* password_store = | 365 password_manager::PasswordStore* password_store = |
358 GetPasswordStore(web_contents()); | 366 GetPasswordStore(web_contents()); |
359 if (password_store) | 367 if (password_store) |
360 password_store->RemoveObserver(this); | 368 password_store->RemoveObserver(this); |
361 } | 369 } |
OLD | NEW |