| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_bubble_model.h" | 5 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 const std::vector<std::unique_ptr<autofill::PasswordForm>>& forms) { | 54 const std::vector<std::unique_ptr<autofill::PasswordForm>>& forms) { |
| 55 std::vector<autofill::PasswordForm> result; | 55 std::vector<autofill::PasswordForm> result; |
| 56 result.reserve(forms.size()); | 56 result.reserve(forms.size()); |
| 57 std::transform(forms.begin(), forms.end(), std::back_inserter(result), | 57 std::transform(forms.begin(), forms.end(), std::back_inserter(result), |
| 58 [](const std::unique_ptr<autofill::PasswordForm>& form) { | 58 [](const std::unique_ptr<autofill::PasswordForm>& form) { |
| 59 return *form; | 59 return *form; |
| 60 }); | 60 }); |
| 61 return result; | 61 return result; |
| 62 } | 62 } |
| 63 | 63 |
| 64 password_bubble_experiment::SmartLockBranding GetSmartLockBrandingState( | 64 bool IsSmartLockUser(Profile* profile) { |
| 65 Profile* profile) { | |
| 66 const browser_sync::ProfileSyncService* sync_service = | 65 const browser_sync::ProfileSyncService* sync_service = |
| 67 ProfileSyncServiceFactory::GetForProfile(profile); | 66 ProfileSyncServiceFactory::GetForProfile(profile); |
| 68 return password_bubble_experiment::GetSmartLockBrandingState(sync_service); | 67 return password_bubble_experiment::IsSmartLockUser(sync_service); |
| 69 } | 68 } |
| 70 | 69 |
| 71 } // namespace | 70 } // namespace |
| 72 | 71 |
| 73 // Class responsible for collecting and reporting all the runtime interactions | 72 // Class responsible for collecting and reporting all the runtime interactions |
| 74 // with the bubble. | 73 // with the bubble. |
| 75 class ManagePasswordsBubbleModel::InteractionKeeper { | 74 class ManagePasswordsBubbleModel::InteractionKeeper { |
| 76 public: | 75 public: |
| 77 InteractionKeeper( | 76 InteractionKeeper( |
| 78 password_manager::InteractionsStats stats, | 77 password_manager::InteractionsStats stats, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 sign_in_promo_dismissal_reason_(metrics_util::CHROME_SIGNIN_DISMISSED), | 143 sign_in_promo_dismissal_reason_(metrics_util::CHROME_SIGNIN_DISMISSED), |
| 145 interaction_stats_(std::move(stats)), | 144 interaction_stats_(std::move(stats)), |
| 146 clock_(new base::DefaultClock), | 145 clock_(new base::DefaultClock), |
| 147 sign_in_promo_shown_count(0) {} | 146 sign_in_promo_shown_count(0) {} |
| 148 | 147 |
| 149 void ManagePasswordsBubbleModel::InteractionKeeper::ReportInteractions( | 148 void ManagePasswordsBubbleModel::InteractionKeeper::ReportInteractions( |
| 150 const ManagePasswordsBubbleModel* model) { | 149 const ManagePasswordsBubbleModel* model) { |
| 151 if (model->state() == password_manager::ui::PENDING_PASSWORD_STATE) { | 150 if (model->state() == password_manager::ui::PENDING_PASSWORD_STATE) { |
| 152 Profile* profile = model->GetProfile(); | 151 Profile* profile = model->GetProfile(); |
| 153 if (profile) { | 152 if (profile) { |
| 154 if (GetSmartLockBrandingState(profile) == | |
| 155 password_bubble_experiment::SmartLockBranding::FULL) { | |
| 156 password_bubble_experiment::RecordSavePromptFirstRunExperienceWasShown( | |
| 157 profile->GetPrefs()); | |
| 158 } | |
| 159 if (dismissal_reason_ == metrics_util::NO_DIRECT_INTERACTION && | 153 if (dismissal_reason_ == metrics_util::NO_DIRECT_INTERACTION && |
| 160 display_disposition_ == | 154 display_disposition_ == |
| 161 metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING) { | 155 metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING) { |
| 162 if (interaction_stats_.dismissal_count < | 156 if (interaction_stats_.dismissal_count < |
| 163 std::numeric_limits<decltype( | 157 std::numeric_limits<decltype( |
| 164 interaction_stats_.dismissal_count)>::max()) | 158 interaction_stats_.dismissal_count)>::max()) |
| 165 interaction_stats_.dismissal_count++; | 159 interaction_stats_.dismissal_count++; |
| 166 interaction_stats_.update_time = clock_->Now(); | 160 interaction_stats_.update_time = clock_->Now(); |
| 167 password_manager::PasswordStore* password_store = | 161 password_manager::PasswordStore* password_store = |
| 168 PasswordStoreFactory::GetForProfile( | 162 PasswordStoreFactory::GetForProfile( |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 } else if (state_ == password_manager::ui::MANAGE_STATE) { | 242 } else if (state_ == password_manager::ui::MANAGE_STATE) { |
| 249 local_credentials_ = DeepCopyForms(delegate_->GetCurrentForms()); | 243 local_credentials_ = DeepCopyForms(delegate_->GetCurrentForms()); |
| 250 UpdateManageStateTitle(); | 244 UpdateManageStateTitle(); |
| 251 manage_link_ = | 245 manage_link_ = |
| 252 l10n_util::GetStringUTF16(IDS_OPTIONS_PASSWORDS_MANAGE_PASSWORDS_LINK); | 246 l10n_util::GetStringUTF16(IDS_OPTIONS_PASSWORDS_MANAGE_PASSWORDS_LINK); |
| 253 } | 247 } |
| 254 | 248 |
| 255 if (state_ == password_manager::ui::CONFIRMATION_STATE) { | 249 if (state_ == password_manager::ui::CONFIRMATION_STATE) { |
| 256 base::string16 save_confirmation_link = | 250 base::string16 save_confirmation_link = |
| 257 l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_LINK); | 251 l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_LINK); |
| 258 int confirmation_text_id = IDS_MANAGE_PASSWORDS_CONFIRM_GENERATED_TEXT; | |
| 259 if (GetSmartLockBrandingState(GetProfile()) == | |
| 260 password_bubble_experiment::SmartLockBranding::FULL) { | |
| 261 std::string management_hostname = | |
| 262 GURL(password_manager::kPasswordManagerAccountDashboardURL).host(); | |
| 263 save_confirmation_link = base::UTF8ToUTF16(management_hostname); | |
| 264 confirmation_text_id = | |
| 265 IDS_MANAGE_PASSWORDS_CONFIRM_GENERATED_SMART_LOCK_TEXT; | |
| 266 } | |
| 267 | |
| 268 size_t offset; | 252 size_t offset; |
| 269 save_confirmation_text_ = | 253 save_confirmation_text_ = |
| 270 l10n_util::GetStringFUTF16( | 254 l10n_util::GetStringFUTF16(IDS_MANAGE_PASSWORDS_CONFIRM_GENERATED_TEXT, |
| 271 confirmation_text_id, save_confirmation_link, &offset); | 255 save_confirmation_link, &offset); |
| 272 save_confirmation_link_range_ = | 256 save_confirmation_link_range_ = |
| 273 gfx::Range(offset, offset + save_confirmation_link.length()); | 257 gfx::Range(offset, offset + save_confirmation_link.length()); |
| 274 } | 258 } |
| 275 | 259 |
| 276 password_manager::metrics_util::UIDisplayDisposition display_disposition = | 260 password_manager::metrics_util::UIDisplayDisposition display_disposition = |
| 277 metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING; | 261 metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING; |
| 278 if (display_reason == USER_ACTION) { | 262 if (display_reason == USER_ACTION) { |
| 279 switch (state_) { | 263 switch (state_) { |
| 280 case password_manager::ui::PENDING_PASSWORD_STATE: | 264 case password_manager::ui::PENDING_PASSWORD_STATE: |
| 281 display_disposition = metrics_util::MANUAL_WITH_PASSWORD_PENDING; | 265 display_disposition = metrics_util::MANUAL_WITH_PASSWORD_PENDING; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 } | 352 } |
| 369 | 353 |
| 370 // TODO(gcasto): Is it worth having this be separate from OnDoneClicked()? | 354 // TODO(gcasto): Is it worth having this be separate from OnDoneClicked()? |
| 371 // User intent is pretty similar in both cases. | 355 // User intent is pretty similar in both cases. |
| 372 void ManagePasswordsBubbleModel::OnOKClicked() { | 356 void ManagePasswordsBubbleModel::OnOKClicked() { |
| 373 interaction_keeper_->set_dismissal_reason(metrics_util::CLICKED_OK); | 357 interaction_keeper_->set_dismissal_reason(metrics_util::CLICKED_OK); |
| 374 } | 358 } |
| 375 | 359 |
| 376 void ManagePasswordsBubbleModel::OnManageLinkClicked() { | 360 void ManagePasswordsBubbleModel::OnManageLinkClicked() { |
| 377 interaction_keeper_->set_dismissal_reason(metrics_util::CLICKED_MANAGE); | 361 interaction_keeper_->set_dismissal_reason(metrics_util::CLICKED_MANAGE); |
| 378 if (GetSmartLockBrandingState(GetProfile()) == | 362 delegate_->NavigateToPasswordManagerSettingsPage(); |
| 379 password_bubble_experiment::SmartLockBranding::FULL) { | |
| 380 delegate_->NavigateToExternalPasswordManager(); | |
| 381 } else { | |
| 382 delegate_->NavigateToPasswordManagerSettingsPage(); | |
| 383 } | |
| 384 } | 363 } |
| 385 | 364 |
| 386 void ManagePasswordsBubbleModel::OnBrandLinkClicked() { | 365 void ManagePasswordsBubbleModel::OnBrandLinkClicked() { |
| 387 interaction_keeper_->set_dismissal_reason(metrics_util::CLICKED_BRAND_NAME); | 366 interaction_keeper_->set_dismissal_reason(metrics_util::CLICKED_BRAND_NAME); |
| 388 delegate_->NavigateToSmartLockHelpPage(); | 367 delegate_->NavigateToSmartLockHelpPage(); |
| 389 } | 368 } |
| 390 | 369 |
| 391 void ManagePasswordsBubbleModel::OnAutoSignInToastTimeout() { | 370 void ManagePasswordsBubbleModel::OnAutoSignInToastTimeout() { |
| 392 interaction_keeper_->set_dismissal_reason( | 371 interaction_keeper_->set_dismissal_reason( |
| 393 metrics_util::AUTO_SIGNIN_TOAST_TIMEOUT); | 372 metrics_util::AUTO_SIGNIN_TOAST_TIMEOUT); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 | 409 |
| 431 content::WebContents* ManagePasswordsBubbleModel::GetWebContents() const { | 410 content::WebContents* ManagePasswordsBubbleModel::GetWebContents() const { |
| 432 return delegate_ ? delegate_->GetWebContents() : nullptr; | 411 return delegate_ ? delegate_->GetWebContents() : nullptr; |
| 433 } | 412 } |
| 434 | 413 |
| 435 bool ManagePasswordsBubbleModel::ShouldShowMultipleAccountUpdateUI() const { | 414 bool ManagePasswordsBubbleModel::ShouldShowMultipleAccountUpdateUI() const { |
| 436 return state_ == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE && | 415 return state_ == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE && |
| 437 local_credentials_.size() > 1 && !password_overridden_; | 416 local_credentials_.size() > 1 && !password_overridden_; |
| 438 } | 417 } |
| 439 | 418 |
| 440 bool ManagePasswordsBubbleModel::ShouldShowGoogleSmartLockWelcome() const { | |
| 441 Profile* profile = GetProfile(); | |
| 442 if (GetSmartLockBrandingState(profile) == | |
| 443 password_bubble_experiment::SmartLockBranding::FULL) { | |
| 444 PrefService* prefs = profile->GetPrefs(); | |
| 445 return !prefs->GetBoolean( | |
| 446 password_manager::prefs::kWasSavePrompFirstRunExperienceShown); | |
| 447 } | |
| 448 return false; | |
| 449 } | |
| 450 | |
| 451 bool ManagePasswordsBubbleModel::ReplaceToShowSignInPromoIfNeeded() { | 419 bool ManagePasswordsBubbleModel::ReplaceToShowSignInPromoIfNeeded() { |
| 452 DCHECK_EQ(password_manager::ui::PENDING_PASSWORD_STATE, state_); | 420 DCHECK_EQ(password_manager::ui::PENDING_PASSWORD_STATE, state_); |
| 453 PrefService* prefs = GetProfile()->GetPrefs(); | 421 PrefService* prefs = GetProfile()->GetPrefs(); |
| 454 const browser_sync::ProfileSyncService* sync_service = | 422 const browser_sync::ProfileSyncService* sync_service = |
| 455 ProfileSyncServiceFactory::GetForProfile(GetProfile()); | 423 ProfileSyncServiceFactory::GetForProfile(GetProfile()); |
| 456 if (password_bubble_experiment::ShouldShowChromeSignInPasswordPromo( | 424 if (password_bubble_experiment::ShouldShowChromeSignInPasswordPromo( |
| 457 prefs, sync_service)) { | 425 prefs, sync_service)) { |
| 458 interaction_keeper_->ReportInteractions(this); | 426 interaction_keeper_->ReportInteractions(this); |
| 459 title_brand_link_range_ = gfx::Range(); | 427 title_brand_link_range_ = gfx::Range(); |
| 460 title_ = l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SIGNIN_PROMO_TITLE); | 428 title_ = l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SIGNIN_PROMO_TITLE); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 477 | 445 |
| 478 void ManagePasswordsBubbleModel::UpdatePendingStateTitle() { | 446 void ManagePasswordsBubbleModel::UpdatePendingStateTitle() { |
| 479 title_brand_link_range_ = gfx::Range(); | 447 title_brand_link_range_ = gfx::Range(); |
| 480 PasswordTitleType type = | 448 PasswordTitleType type = |
| 481 state_ == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE | 449 state_ == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE |
| 482 ? PasswordTitleType::UPDATE_PASSWORD | 450 ? PasswordTitleType::UPDATE_PASSWORD |
| 483 : (pending_password_.federation_origin.unique() | 451 : (pending_password_.federation_origin.unique() |
| 484 ? PasswordTitleType::SAVE_PASSWORD | 452 ? PasswordTitleType::SAVE_PASSWORD |
| 485 : PasswordTitleType::SAVE_ACCOUNT); | 453 : PasswordTitleType::SAVE_ACCOUNT); |
| 486 GetSavePasswordDialogTitleTextAndLinkRange( | 454 GetSavePasswordDialogTitleTextAndLinkRange( |
| 487 GetWebContents()->GetVisibleURL(), origin_, | 455 GetWebContents()->GetVisibleURL(), origin_, IsSmartLockUser(GetProfile()), |
| 488 GetSmartLockBrandingState(GetProfile()) != | |
| 489 password_bubble_experiment::SmartLockBranding::NONE, | |
| 490 type, &title_, &title_brand_link_range_); | 456 type, &title_, &title_brand_link_range_); |
| 491 } | 457 } |
| 492 | 458 |
| 493 void ManagePasswordsBubbleModel::UpdateManageStateTitle() { | 459 void ManagePasswordsBubbleModel::UpdateManageStateTitle() { |
| 494 GetManagePasswordsDialogTitleText(GetWebContents()->GetVisibleURL(), origin_, | 460 GetManagePasswordsDialogTitleText(GetWebContents()->GetVisibleURL(), origin_, |
| 495 &title_); | 461 &title_); |
| 496 } | 462 } |
| 497 | 463 |
| 498 metrics_util::UpdatePasswordSubmissionEvent | 464 metrics_util::UpdatePasswordSubmissionEvent |
| 499 ManagePasswordsBubbleModel::GetUpdateDismissalReason( | 465 ManagePasswordsBubbleModel::GetUpdateDismissalReason( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 518 return metrics_util::NO_UPDATE_SUBMISSION; | 484 return metrics_util::NO_UPDATE_SUBMISSION; |
| 519 } | 485 } |
| 520 if (state_ != password_manager::ui::PENDING_PASSWORD_UPDATE_STATE) | 486 if (state_ != password_manager::ui::PENDING_PASSWORD_UPDATE_STATE) |
| 521 return metrics_util::NO_UPDATE_SUBMISSION; | 487 return metrics_util::NO_UPDATE_SUBMISSION; |
| 522 if (password_overridden_) | 488 if (password_overridden_) |
| 523 return update_events[3][behavior]; | 489 return update_events[3][behavior]; |
| 524 if (ShouldShowMultipleAccountUpdateUI()) | 490 if (ShouldShowMultipleAccountUpdateUI()) |
| 525 return update_events[2][behavior]; | 491 return update_events[2][behavior]; |
| 526 return update_events[1][behavior]; | 492 return update_events[1][behavior]; |
| 527 } | 493 } |
| OLD | NEW |