1 // Copyright 2020 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.
4 
5 #include "chrome/browser/ui/passwords/bubble_controllers/items_bubble_controller.h"
6 
7 #include "chrome/browser/favicon/favicon_service_factory.h"
8 #include "chrome/browser/password_manager/password_store_utils.h"
9 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
10 #include "chrome/browser/ui/passwords/passwords_model_delegate.h"
11 #include "chrome/grit/generated_resources.h"
12 #include "components/favicon/core/favicon_util.h"
13 #include "components/password_manager/core/browser/password_form.h"
14 #include "components/password_manager/core/browser/password_form_metrics_recorder.h"
15 #include "components/password_manager/core/browser/password_store.h"
16 #include "content/public/browser/web_contents.h"
17 #include "ui/base/l10n/l10n_util.h"
18 
19 namespace metrics_util = password_manager::metrics_util;
20 
21 namespace {
22 
DeepCopyForms(const std::vector<std::unique_ptr<password_manager::PasswordForm>> & forms)23 std::vector<password_manager::PasswordForm> DeepCopyForms(
24     const std::vector<std::unique_ptr<password_manager::PasswordForm>>& forms) {
25   std::vector<password_manager::PasswordForm> result;
26   result.reserve(forms.size());
27   std::transform(
28       forms.begin(), forms.end(), std::back_inserter(result),
29       [](const std::unique_ptr<password_manager::PasswordForm>& form) {
30         return *form;
31       });
32   return result;
33 }
34 
35 }  // namespace
36 
ItemsBubbleController(base::WeakPtr<PasswordsModelDelegate> delegate)37 ItemsBubbleController::ItemsBubbleController(
38     base::WeakPtr<PasswordsModelDelegate> delegate)
39     : PasswordBubbleControllerBase(
40           std::move(delegate),
41           /*display_disposition=*/metrics_util::MANUAL_MANAGE_PASSWORDS),
42       local_credentials_(DeepCopyForms(delegate_->GetCurrentForms())),
43       title_(
44           GetManagePasswordsDialogTitleText(GetWebContents()->GetVisibleURL(),
45                                             delegate_->GetOrigin(),
46                                             !local_credentials_.empty())) {}
47 
~ItemsBubbleController()48 ItemsBubbleController::~ItemsBubbleController() {
49   if (!interaction_reported_)
50     OnBubbleClosing();
51 }
52 
OnManageClicked(password_manager::ManagePasswordsReferrer referrer)53 void ItemsBubbleController::OnManageClicked(
54     password_manager::ManagePasswordsReferrer referrer) {
55   dismissal_reason_ = metrics_util::CLICKED_MANAGE;
56   if (delegate_)
57     delegate_->NavigateToPasswordManagerSettingsPage(referrer);
58 }
59 
OnPasswordAction(const password_manager::PasswordForm & password_form,PasswordAction action)60 void ItemsBubbleController::OnPasswordAction(
61     const password_manager::PasswordForm& password_form,
62     PasswordAction action) {
63   Profile* profile = GetProfile();
64   if (!profile)
65     return;
66   password_manager::PasswordStore* password_store =
67       GetPasswordStore(profile, password_form.IsUsingAccountStore()).get();
68 
69   DCHECK(password_store);
70   if (action == PasswordAction::kRemovePassword)
71     password_store->RemoveLogin(password_form);
72   else
73     password_store->AddLogin(password_form);
74 }
75 
RequestFavicon(base::OnceCallback<void (const gfx::Image &)> favicon_ready_callback)76 void ItemsBubbleController::RequestFavicon(
77     base::OnceCallback<void(const gfx::Image&)> favicon_ready_callback) {
78   favicon::FaviconService* favicon_service =
79       FaviconServiceFactory::GetForProfile(GetProfile(),
80                                            ServiceAccessType::EXPLICIT_ACCESS);
81   favicon::GetFaviconImageForPageURL(
82       favicon_service, GetWebContents()->GetVisibleURL(),
83       favicon_base::IconType::kFavicon,
84       base::BindOnce(&ItemsBubbleController::OnFaviconReady,
85                      base::Unretained(this), std::move(favicon_ready_callback)),
86       &favicon_tracker_);
87 }
88 
OnFaviconReady(base::OnceCallback<void (const gfx::Image &)> favicon_ready_callback,const favicon_base::FaviconImageResult & result)89 void ItemsBubbleController::OnFaviconReady(
90     base::OnceCallback<void(const gfx::Image&)> favicon_ready_callback,
91     const favicon_base::FaviconImageResult& result) {
92   std::move(favicon_ready_callback).Run(result.image);
93 }
94 
ReportInteractions()95 void ItemsBubbleController::ReportInteractions() {
96   metrics_util::LogGeneralUIDismissalReason(dismissal_reason_);
97   // Record UKM statistics on dismissal reason.
98   if (metrics_recorder_)
99     metrics_recorder_->RecordUIDismissalReason(dismissal_reason_);
100 }
101 
GetTitle() const102 base::string16 ItemsBubbleController::GetTitle() const {
103   return title_;
104 }
105