File: security_information_view.cc

package info (click to toggle)
chromium 139.0.7258.138-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,120,676 kB
  • sloc: cpp: 35,100,869; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (275 lines) | stat: -rw-r--r-- 11,635 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/page_info/security_information_view.h"

#include <utility>

#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
#include "components/strings/grit/components_branded_strings.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/table_layout.h"
#include "ui/views/view_class_properties.h"

SecurityInformationView::SecurityInformationView(int side_margin) {
  ChromeLayoutProvider* layout_provider = ChromeLayoutProvider::Get();
  const int icon_label_spacing = layout_provider->GetDistanceMetric(
      views::DISTANCE_RELATED_LABEL_HORIZONTAL);
  auto hover_button_insets = layout_provider->GetInsetsMetric(
      ChromeInsetsMetric::INSETS_PAGE_INFO_HOVER_BUTTON);
  // TODO(olesiamarukhno): Unify the column width through all views in the
  // page info (RichHoverButton, PermissionSelectorRow, ChosenObjectView,
  // SecurityInformationView). Currently, it isn't same everywhere and it
  // causes label text next to icon not to be aligned by 1 or 2px.
  views::TableLayout* layout =
      SetLayoutManager(std::make_unique<views::TableLayout>());
  layout->AddPaddingColumn(views::TableLayout::kFixedSize, side_margin)
      .AddColumn(views::LayoutAlignment::kCenter,
                 views::LayoutAlignment::kCenter,
                 views::TableLayout::kFixedSize,
                 views::TableLayout::ColumnSize::kUsePreferred, 0, 0)
      .AddPaddingColumn(views::TableLayout::kFixedSize, icon_label_spacing)
      .AddColumn(views::LayoutAlignment::kStretch,
                 views::LayoutAlignment::kStart, 1.0f,
                 views::TableLayout::ColumnSize::kUsePreferred, 0, 0)
      .AddPaddingColumn(views::TableLayout::kFixedSize, side_margin)
      // Add padding before the title so that it's in the same position as when
      // this control is a hover button.
      .AddPaddingRow(views::TableLayout::kFixedSize, hover_button_insets.top())
      .AddRows(1, views::TableLayout::kFixedSize);

  icon_ = AddChildView(std::make_unique<NonAccessibleImageView>());

  security_summary_label_ =
      AddChildView(std::make_unique<views::StyledLabel>());
  // TODO(olesiamarukhno): Check padding between summary and description
  // labels after more UI is implemented.
  security_summary_label_->SetTextContext(
      views::style::CONTEXT_DIALOG_BODY_TEXT);
  security_summary_label_->SetID(
      PageInfoViewFactory::VIEW_ID_PAGE_INFO_SECURITY_SUMMARY_LABEL);
  security_summary_label_->SetDefaultEnabledColorId(kColorPageInfoForeground);
  // The label defaults to a single line, which would force the dialog wider;
  // instead give it a width that's the minimum we want it to have.  Then the
  // TableLayout will stretch it back out into any additional space available.
  min_label_width_ =
      PageInfoViewFactory::kMinBubbleWidth - side_margin * 2 -
      PageInfoViewFactory::GetConnectionSecureIcon().Size().width() -
      icon_label_spacing;
  security_summary_label_->SizeToFit(min_label_width_);

  auto start_secondary_row = [=, this]() {
    layout->AddRows(1, views::TableLayout::kFixedSize);
    AddChildView(std::make_unique<views::View>());  // Skipping the icon column.
  };

  start_secondary_row();
  security_details_label_ =
      AddChildView(std::make_unique<views::StyledLabel>());
  security_details_label_->SetID(
      PageInfoViewFactory::VIEW_ID_PAGE_INFO_SECURITY_DETAILS_LABEL);
  security_details_label_->SetDefaultTextStyle(views::style::STYLE_BODY_4);
  security_details_label_->SetDefaultEnabledColorId(
      kColorPageInfoSubtitleForeground);
  security_details_label_->SizeToFit(min_label_width_);

  start_secondary_row();
  reset_decisions_label_container_ =
      AddChildView(std::make_unique<views::View>());
  reset_decisions_label_container_->SetLayoutManager(
      std::make_unique<views::BoxLayout>(
          views::BoxLayout::Orientation::kHorizontal));

  start_secondary_row();
  password_reuse_button_container_ =
      AddChildView(std::make_unique<views::View>());

  const int end_padding =
      layout_provider->GetDistanceMetric(views::DISTANCE_CONTROL_LIST_VERTICAL);
  layout->AddPaddingRow(views::TableLayout::kFixedSize, end_padding);
}

SecurityInformationView::~SecurityInformationView() = default;

void SecurityInformationView::SetIcon(const ui::ImageModel& image_icon) {
  icon_->SetImage(image_icon);
}

void SecurityInformationView::SetSummary(const std::u16string& summary_text,
                                         int text_style) {
  security_summary_label_->SetText(summary_text);
  security_summary_label_->SetDefaultTextStyle(text_style);
}

void SecurityInformationView::SetDetailsWithLearnMore(
    const std::u16string& details_text,
    views::Link::ClickedCallback security_details_callback) {
  std::vector<std::u16string> subst;
  subst.push_back(details_text);
  subst.push_back(l10n_util::GetStringUTF16(IDS_LEARN_MORE));

  std::vector<size_t> offsets;

  std::u16string text =
      base::ReplaceStringPlaceholders(u"$1 $2", subst, &offsets);
  security_details_label_->SetText(text);
  gfx::Range details_range(offsets[1], text.length());

  views::StyledLabel::RangeStyleInfo link_style =
      views::StyledLabel::RangeStyleInfo::CreateForLink(
          security_details_callback);

  security_details_label_->AddStyleRange(details_range, link_style);
}

void SecurityInformationView::SetDetails(const std::u16string& details_text) {
  security_details_label_->SetText(details_text);
}

void SecurityInformationView::AddResetDecisionsLabel(
    base::RepeatingClosure reset_decisions_callback) {
  if (!reset_decisions_label_container_->children().empty()) {
    // Ensure all old content is removed from the container before re-adding it.
    reset_decisions_label_container_->RemoveAllChildViews();
  }

  std::vector<std::u16string> subst;
  subst.push_back(
      l10n_util::GetStringUTF16(IDS_PAGE_INFO_INVALID_CERTIFICATE_DESCRIPTION));
  subst.push_back(l10n_util::GetStringUTF16(
      IDS_PAGE_INFO_RESET_INVALID_CERTIFICATE_DECISIONS_BUTTON));

  std::vector<size_t> offsets;

  std::u16string text =
      base::ReplaceStringPlaceholders(u"$1 $2", subst, &offsets);
  views::StyledLabel* reset_cert_decisions_label =
      reset_decisions_label_container_->AddChildView(
          std::make_unique<views::StyledLabel>());
  reset_cert_decisions_label->SetID(
      PageInfoViewFactory::VIEW_ID_PAGE_INFO_RESET_DECISIONS_LABEL);
  reset_cert_decisions_label->SetDefaultTextStyle(views::style::STYLE_BODY_4);
  reset_cert_decisions_label->SetDefaultEnabledColorId(
      kColorPageInfoSubtitleForeground);
  reset_cert_decisions_label->SetText(text);
  gfx::Range link_range(offsets[1], text.length());

  views::StyledLabel::RangeStyleInfo link_style =
      views::StyledLabel::RangeStyleInfo::CreateForLink(
          reset_decisions_callback);

  reset_cert_decisions_label->AddStyleRange(link_range, link_style);
  // Adjust this label's width to the width of the label above.
  reset_cert_decisions_label->SizeToFit(security_details_label_->width());

  // Now that it contains a label, the container needs padding at the top.
  const int between_paragraphs_distance =
      ChromeLayoutProvider::Get()->GetDistanceMetric(
          views::DISTANCE_RELATED_CONTROL_VERTICAL);
  reset_decisions_label_container_->SetBorder(views::CreateEmptyBorder(
      gfx::Insets::TLBR(between_paragraphs_distance, 0, 0, 0)));

  InvalidateLayout();
}

void SecurityInformationView::AddPasswordReuseButtons(
    PageInfo::SafeBrowsingStatus safe_browsing_status,
    views::Button::PressedCallback change_password_callback,
    views::Button::PressedCallback password_reuse_callback) {
  if (!password_reuse_button_container_->children().empty()) {
    // Ensure all old content is removed from the container before re-adding it.
    password_reuse_button_container_->RemoveAllChildViews();
  }

  int change_password_template = 0;
  switch (safe_browsing_status) {
    case PageInfo::SafeBrowsingStatus::
        SAFE_BROWSING_STATUS_SAVED_PASSWORD_REUSE:
      change_password_template = IDS_PAGE_INFO_CHECK_PASSWORDS_BUTTON;
      break;
    case PageInfo::SafeBrowsingStatus::
        SAFE_BROWSING_STATUS_ENTERPRISE_PASSWORD_REUSE:
      change_password_template = IDS_PAGE_INFO_CHANGE_PASSWORD_BUTTON;
      break;
    case PageInfo::SafeBrowsingStatus::
        SAFE_BROWSING_STATUS_SIGNED_IN_NON_SYNC_PASSWORD_REUSE:
    case PageInfo::SafeBrowsingStatus::
        SAFE_BROWSING_STATUS_SIGNED_IN_SYNC_PASSWORD_REUSE:
      change_password_template = IDS_PAGE_INFO_PROTECT_ACCOUNT_BUTTON;
      break;
    default:
      NOTREACHED();
  }

  std::unique_ptr<views::MdTextButton> change_password_button;
  if (change_password_template) {
    change_password_button = std::make_unique<views::MdTextButton>(
        std::move(change_password_callback),
        l10n_util::GetStringUTF16(change_password_template));
    change_password_button->SetStyle(ui::ButtonStyle::kProminent);
    change_password_button->SetID(
        PageInfoViewFactory::VIEW_ID_PAGE_INFO_BUTTON_CHANGE_PASSWORD);
  }
  auto allowlist_password_reuse_button = std::make_unique<views::MdTextButton>(
      std::move(password_reuse_callback),
      l10n_util::GetStringUTF16(IDS_PAGE_INFO_ALLOWLIST_PASSWORD_REUSE_BUTTON));
  allowlist_password_reuse_button->SetID(
      PageInfoViewFactory::VIEW_ID_PAGE_INFO_BUTTON_ALLOWLIST_PASSWORD_REUSE);

  int kSpacingBetweenButtons = 8;
  // TODO(crbug.com/40800258): Fix alignment if the buttons don't fit in one
  // row.
  auto layout = std::make_unique<views::BoxLayout>(
      views::BoxLayout::Orientation::kHorizontal, gfx::Insets(),
      kSpacingBetweenButtons);
  // Make buttons left-aligned. For RTL languages, buttons will automatically
  // become right-aligned.
  layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart);
  password_reuse_button_container_->SetLayoutManager(std::move(layout));

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
  if (change_password_button) {
    password_reuse_button_container_->AddChildView(
        std::move(change_password_button));
  }
  password_reuse_button_container_->AddChildView(
      std::move(allowlist_password_reuse_button));
#else
  password_reuse_button_container_->AddChildView(
      std::move(allowlist_password_reuse_button));
  if (change_password_button) {
    password_reuse_button_container_->AddChildView(
        std::move(change_password_button));
  }
#endif

  // Add padding at the top.
  password_reuse_button_container_->SetBorder(
      views::CreateEmptyBorder(gfx::Insets::TLBR(8, 0, 0, 0)));
  int w = password_reuse_button_container_->GetPreferredSize().width();
  if (w > min_label_width_) {
    AdjustContentWidth(w);
  }

  InvalidateLayout();
}

void SecurityInformationView::AdjustContentWidth(int w) {
  security_summary_label_->SizeToFit(w);
  security_details_label_->SizeToFit(w);
}

BEGIN_METADATA(SecurityInformationView)
END_METADATA