Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(792)

Side by Side Diff: chrome/browser/ui/views/page_info/page_info_popup_view.cc

Issue 2797923003: Rename PageInfoPopupView to PageInfoBubbleView. (Closed)
Patch Set: Two more words. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/views/page_info/page_info_popup_view.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10 #include <vector>
11
12 #include "base/i18n/rtl.h"
13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/strings/string16.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "chrome/browser/certificate_viewer.h"
19 #include "chrome/browser/infobars/infobar_service.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_dialogs.h"
23 #include "chrome/browser/ui/layout_constants.h"
24 #include "chrome/browser/ui/page_info/page_info.h"
25 #include "chrome/browser/ui/views/collected_cookies_views.h"
26 #include "chrome/browser/ui/views/harmony/chrome_typography.h"
27 #include "chrome/browser/ui/views/harmony/layout_delegate.h"
28 #include "chrome/browser/ui/views/page_info/chosen_object_row.h"
29 #include "chrome/browser/ui/views/page_info/non_accessible_image_view.h"
30 #include "chrome/browser/ui/views/page_info/permission_selector_row.h"
31 #include "chrome/common/url_constants.h"
32 #include "chrome/grit/chromium_strings.h"
33 #include "chrome/grit/generated_resources.h"
34 #include "chrome/grit/theme_resources.h"
35 #include "components/content_settings/core/common/content_settings_types.h"
36 #include "components/strings/grit/components_chromium_strings.h"
37 #include "components/strings/grit/components_strings.h"
38 #include "content/public/browser/browser_thread.h"
39 #include "extensions/common/constants.h"
40 #include "ui/base/l10n/l10n_util.h"
41 #include "ui/base/material_design/material_design_controller.h"
42 #include "ui/base/models/simple_menu_model.h"
43 #include "ui/base/resource/resource_bundle.h"
44 #include "ui/gfx/canvas.h"
45 #include "ui/gfx/font_list.h"
46 #include "ui/gfx/geometry/insets.h"
47 #include "ui/gfx/image/image.h"
48 #include "ui/resources/grit/ui_resources.h"
49 #include "ui/views/border.h"
50 #include "ui/views/controls/button/image_button.h"
51 #include "ui/views/controls/button/md_text_button.h"
52 #include "ui/views/controls/image_view.h"
53 #include "ui/views/controls/label.h"
54 #include "ui/views/controls/link.h"
55 #include "ui/views/controls/styled_label.h"
56 #include "ui/views/layout/box_layout.h"
57 #include "ui/views/layout/grid_layout.h"
58 #include "ui/views/layout/layout_manager.h"
59 #include "ui/views/view.h"
60 #include "ui/views/widget/widget.h"
61 #include "url/gurl.h"
62
63 namespace {
64
65 // NOTE(jdonnelly): This use of this process-wide variable assumes that there's
66 // never more than one page info popup shown and that it's associated
67 // with the current window. If this assumption fails in the future, we'll need
68 // to return a weak pointer from ShowPopup so callers can associate it with the
69 // current window (or other context) and check if the popup they care about is
70 // showing.
71 PageInfoPopupView::PopupType g_shown_popup_type = PageInfoPopupView::POPUP_NONE;
72
73 // General constants -----------------------------------------------------------
74
75 // Popup width constraints.
76 const int kMinPopupWidth = 320;
77 const int kMaxPopupWidth = 1000;
78
79 // Security Section (PopupHeaderView) ------------------------------------------
80
81 // Margin and padding values for the |PopupHeaderView|.
82 const int kHeaderMarginBottom = 10;
83 const int kHeaderPaddingBottom = 13;
84
85 // Spacing between labels in the header.
86 const int kHeaderLabelSpacing = 4;
87
88 // Site Settings Section -------------------------------------------------------
89
90 // Spacing above and below the cookies view.
91 const int kCookiesViewVerticalPadding = 6;
92
93 // Spacing between a permission image and the text.
94 const int kPermissionImageSpacing = 6;
95
96 // Spacing between rows in the site settings section
97 const int kPermissionsVerticalSpacing = 12;
98
99 // Spacing between the label and the menu.
100 const int kPermissionMenuSpacing = 16;
101
102 // Button/styled label/link IDs ------------------------------------------------
103 const int BUTTON_CLOSE = 1337;
104 const int STYLED_LABEL_SECURITY_DETAILS = 1338;
105 const int STYLED_LABEL_RESET_CERTIFICATE_DECISIONS = 1339;
106 const int LINK_COOKIE_DIALOG = 1340;
107 const int LINK_SITE_SETTINGS = 1341;
108
109 // The default, ui::kTitleFontSizeDelta, is too large for the page info
110 // bubble (e.g. +3). Use +1 to obtain a smaller font.
111 constexpr int kSummaryFontSizeDelta = 1;
112
113 // Adds a ColumnSet on |layout| with a single View column and padding columns
114 // on either side of it with |margin| width.
115 void AddColumnWithSideMargin(views::GridLayout* layout, int margin, int id) {
116 views::ColumnSet* column_set = layout->AddColumnSet(id);
117 column_set->AddPaddingColumn(0, margin);
118 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
119 views::GridLayout::USE_PREF, 0, 0);
120 column_set->AddPaddingColumn(0, margin);
121 }
122
123 } // namespace
124
125 // |PopupHeaderView| is the UI element (view) that represents the header of the
126 // |PageInfoPopupView|. The header shows the status of the site's
127 // identity check and the name of the site's identity.
128 class PopupHeaderView : public views::View {
129 public:
130 PopupHeaderView(views::ButtonListener* button_listener,
131 views::StyledLabelListener* styled_label_listener,
132 int side_margin);
133 ~PopupHeaderView() override;
134
135 // Sets the security summary for the current page.
136 void SetSummary(const base::string16& summary_text);
137
138 // Sets the security details for the current page.
139 void SetDetails(const base::string16& details_text);
140
141 void AddResetDecisionsLabel();
142
143 private:
144 // The listener for the styled labels in this view.
145 views::StyledLabelListener* styled_label_listener_;
146
147 // The label that displays the status of the identity check for this site.
148 // Includes a link to open the Chrome Help Center article about connection
149 // security.
150 views::StyledLabel* details_label_;
151
152 // A container for the styled label with a link for resetting cert decisions.
153 // This is only shown sometimes, so we use a container to keep track of
154 // where to place it (if needed).
155 views::View* reset_decisions_label_container_;
156 views::StyledLabel* reset_decisions_label_;
157
158 DISALLOW_COPY_AND_ASSIGN(PopupHeaderView);
159 };
160
161 // The regular PageInfoPopupView is not supported for internal Chrome pages and
162 // extension pages. Instead of the |PageInfoPopupView|, the
163 // |InternalPageInfoPopupView| is displayed.
164 class InternalPageInfoPopupView : public views::BubbleDialogDelegateView {
165 public:
166 // If |anchor_view| is nullptr, or has no Widget, |parent_window| may be
167 // provided to ensure this bubble is closed when the parent closes.
168 InternalPageInfoPopupView(views::View* anchor_view,
169 gfx::NativeView parent_window,
170 const GURL& url);
171 ~InternalPageInfoPopupView() override;
172
173 // views::BubbleDialogDelegateView:
174 void OnWidgetDestroying(views::Widget* widget) override;
175 int GetDialogButtons() const override;
176
177 private:
178 friend class PageInfoPopupView;
179
180 // Used around icon and inside bubble border.
181 static constexpr int kSpacing = 12;
182
183 DISALLOW_COPY_AND_ASSIGN(InternalPageInfoPopupView);
184 };
185
186 ////////////////////////////////////////////////////////////////////////////////
187 // Popup Header
188 ////////////////////////////////////////////////////////////////////////////////
189
190 PopupHeaderView::PopupHeaderView(
191 views::ButtonListener* button_listener,
192 views::StyledLabelListener* styled_label_listener,
193 int side_margin)
194 : styled_label_listener_(styled_label_listener),
195 details_label_(nullptr),
196 reset_decisions_label_container_(nullptr),
197 reset_decisions_label_(nullptr) {
198 views::GridLayout* layout = new views::GridLayout(this);
199 SetLayoutManager(layout);
200
201 const int label_column_status = 1;
202 AddColumnWithSideMargin(layout, side_margin, label_column_status);
203 layout->AddPaddingRow(0, kHeaderLabelSpacing);
204
205 layout->StartRow(0, label_column_status);
206 details_label_ =
207 new views::StyledLabel(base::string16(), styled_label_listener);
208 details_label_->set_id(STYLED_LABEL_SECURITY_DETAILS);
209 layout->AddView(details_label_, 1, 1, views::GridLayout::FILL,
210 views::GridLayout::LEADING);
211
212 layout->StartRow(0, label_column_status);
213 reset_decisions_label_container_ = new views::View();
214 reset_decisions_label_container_->SetLayoutManager(
215 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
216 layout->AddView(reset_decisions_label_container_, 1, 1,
217 views::GridLayout::FILL, views::GridLayout::LEADING);
218
219 layout->AddPaddingRow(1, kHeaderPaddingBottom);
220 }
221
222 PopupHeaderView::~PopupHeaderView() {}
223
224 void PopupHeaderView::SetDetails(const base::string16& details_text) {
225 std::vector<base::string16> subst;
226 subst.push_back(details_text);
227 subst.push_back(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
228
229 std::vector<size_t> offsets;
230
231 base::string16 text = base::ReplaceStringPlaceholders(
232 base::ASCIIToUTF16("$1 $2"), subst, &offsets);
233 details_label_->SetText(text);
234 gfx::Range details_range(offsets[1], text.length());
235
236 views::StyledLabel::RangeStyleInfo link_style =
237 views::StyledLabel::RangeStyleInfo::CreateForLink();
238 if (!ui::MaterialDesignController::IsSecondaryUiMaterial())
239 link_style.font_style |= gfx::Font::FontStyle::UNDERLINE;
240 link_style.disable_line_wrapping = false;
241
242 details_label_->AddStyleRange(details_range, link_style);
243 }
244
245 void PopupHeaderView::AddResetDecisionsLabel() {
246 std::vector<base::string16> subst;
247 subst.push_back(
248 l10n_util::GetStringUTF16(IDS_PAGEINFO_INVALID_CERTIFICATE_DESCRIPTION));
249 subst.push_back(l10n_util::GetStringUTF16(
250 IDS_PAGEINFO_RESET_INVALID_CERTIFICATE_DECISIONS_BUTTON));
251
252 std::vector<size_t> offsets;
253
254 base::string16 text = base::ReplaceStringPlaceholders(
255 base::ASCIIToUTF16("$1 $2"), subst, &offsets);
256 reset_decisions_label_ = new views::StyledLabel(text, styled_label_listener_);
257 reset_decisions_label_->set_id(STYLED_LABEL_RESET_CERTIFICATE_DECISIONS);
258 gfx::Range link_range(offsets[1], text.length());
259
260 views::StyledLabel::RangeStyleInfo link_style =
261 views::StyledLabel::RangeStyleInfo::CreateForLink();
262 if (!ui::MaterialDesignController::IsSecondaryUiMaterial())
263 link_style.font_style |= gfx::Font::FontStyle::UNDERLINE;
264 link_style.disable_line_wrapping = false;
265
266 reset_decisions_label_->AddStyleRange(link_range, link_style);
267 // Fit the styled label to occupy available width.
268 reset_decisions_label_->SizeToFit(0);
269 reset_decisions_label_container_->AddChildView(reset_decisions_label_);
270
271 // Now that it contains a label, the container needs padding at the top.
272 reset_decisions_label_container_->SetBorder(
273 views::CreateEmptyBorder(8, 0, 0, 0));
274
275 InvalidateLayout();
276 }
277
278 ////////////////////////////////////////////////////////////////////////////////
279 // InternalPageInfoPopupView
280 ////////////////////////////////////////////////////////////////////////////////
281
282 InternalPageInfoPopupView::InternalPageInfoPopupView(
283 views::View* anchor_view,
284 gfx::NativeView parent_window,
285 const GURL& url)
286 : BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT) {
287 g_shown_popup_type = PageInfoPopupView::POPUP_INTERNAL_PAGE;
288 set_parent_window(parent_window);
289
290 int text = IDS_PAGE_INFO_INTERNAL_PAGE;
291 int icon = IDR_PRODUCT_LOGO_16;
292 if (url.SchemeIs(extensions::kExtensionScheme)) {
293 text = IDS_PAGE_INFO_EXTENSION_PAGE;
294 icon = IDR_PLUGINS_FAVICON;
295 } else if (url.SchemeIs(content::kViewSourceScheme)) {
296 text = IDS_PAGE_INFO_VIEW_SOURCE_PAGE;
297 // view-source scheme uses the same icon as chrome:// pages.
298 icon = IDR_PRODUCT_LOGO_16;
299 } else if (!url.SchemeIs(content::kChromeUIScheme) &&
300 !url.SchemeIs(content::kChromeDevToolsScheme)) {
301 NOTREACHED();
302 }
303
304 // Compensate for built-in vertical padding in the anchor view's image.
305 set_anchor_view_insets(gfx::Insets(
306 GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
307
308 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, kSpacing,
309 kSpacing, kSpacing));
310 set_margins(gfx::Insets());
311 if (LayoutDelegate::Get()->ShouldShowWindowIcon()) {
312 views::ImageView* icon_view = new NonAccessibleImageView();
313 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
314 icon_view->SetImage(rb.GetImageSkiaNamed(icon));
315 AddChildView(icon_view);
316 }
317
318 views::Label* label = new views::Label(l10n_util::GetStringUTF16(text));
319 label->SetMultiLine(true);
320 label->SetAllowCharacterBreak(true);
321 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
322 AddChildView(label);
323
324 views::BubbleDialogDelegateView::CreateBubble(this);
325 }
326
327 InternalPageInfoPopupView::~InternalPageInfoPopupView() {}
328
329 void InternalPageInfoPopupView::OnWidgetDestroying(views::Widget* widget) {
330 g_shown_popup_type = PageInfoPopupView::POPUP_NONE;
331 }
332
333 int InternalPageInfoPopupView::GetDialogButtons() const {
334 return ui::DIALOG_BUTTON_NONE;
335 }
336
337 ////////////////////////////////////////////////////////////////////////////////
338 // PageInfoPopupView
339 ////////////////////////////////////////////////////////////////////////////////
340
341 PageInfoPopupView::~PageInfoPopupView() {}
342
343 // static
344 void PageInfoPopupView::ShowPopup(
345 views::View* anchor_view,
346 const gfx::Rect& anchor_rect,
347 Profile* profile,
348 content::WebContents* web_contents,
349 const GURL& url,
350 const security_state::SecurityInfo& security_info) {
351 gfx::NativeView parent_window =
352 anchor_view ? nullptr : web_contents->GetNativeView();
353 if (url.SchemeIs(content::kChromeUIScheme) ||
354 url.SchemeIs(content::kChromeDevToolsScheme) ||
355 url.SchemeIs(extensions::kExtensionScheme) ||
356 url.SchemeIs(content::kViewSourceScheme)) {
357 // Use the concrete type so that |SetAnchorRect| can be called as a friend.
358 InternalPageInfoPopupView* popup =
359 new InternalPageInfoPopupView(anchor_view, parent_window, url);
360 if (!anchor_view)
361 popup->SetAnchorRect(anchor_rect);
362 popup->GetWidget()->Show();
363 return;
364 }
365 PageInfoPopupView* popup = new PageInfoPopupView(
366 anchor_view, parent_window, profile, web_contents, url, security_info);
367 if (!anchor_view)
368 popup->SetAnchorRect(anchor_rect);
369 popup->GetWidget()->Show();
370 }
371
372 // static
373 PageInfoPopupView::PopupType PageInfoPopupView::GetShownPopupType() {
374 return g_shown_popup_type;
375 }
376
377 PageInfoPopupView::PageInfoPopupView(
378 views::View* anchor_view,
379 gfx::NativeView parent_window,
380 Profile* profile,
381 content::WebContents* web_contents,
382 const GURL& url,
383 const security_state::SecurityInfo& security_info)
384 : content::WebContentsObserver(web_contents),
385 BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
386 profile_(profile),
387 header_(nullptr),
388 separator_(nullptr),
389 site_settings_view_(nullptr),
390 cookies_view_(nullptr),
391 cookie_dialog_link_(nullptr),
392 permissions_view_(nullptr),
393 weak_factory_(this) {
394 g_shown_popup_type = POPUP_PAGE_INFO;
395 set_parent_window(parent_window);
396
397 // Compensate for built-in vertical padding in the anchor view's image.
398 set_anchor_view_insets(gfx::Insets(
399 GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
400
401 // Capture the default bubble margin, and move it to the Layout classes. This
402 // is necessary so that the views::Separator can extend the full width of the
403 // bubble.
404 const int side_margin = margins().left();
405 DCHECK_EQ(margins().left(), margins().right());
406
407 // Also remove the top margin from the client area so there is less space
408 // below the dialog title.
409 set_margins(gfx::Insets(0, 0, margins().bottom(), 0));
410
411 views::GridLayout* layout = new views::GridLayout(this);
412 SetLayoutManager(layout);
413
414 // Use a single ColumnSet here. Otherwise the preferred width doesn't properly
415 // propagate up to the dialog width.
416 const int content_column = 0;
417 views::ColumnSet* column_set = layout->AddColumnSet(content_column);
418 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
419 views::GridLayout::USE_PREF, 0, 0);
420
421 header_ = new PopupHeaderView(this, this, side_margin);
422 layout->StartRow(1, content_column);
423 layout->AddView(header_);
424
425 layout->StartRow(0, content_column);
426 separator_ = new views::Separator();
427 layout->AddView(separator_);
428
429 layout->AddPaddingRow(1, kHeaderMarginBottom);
430 layout->StartRow(1, content_column);
431
432 site_settings_view_ = CreateSiteSettingsView(side_margin);
433 layout->AddView(site_settings_view_);
434
435 if (!ui::MaterialDesignController::IsSecondaryUiMaterial()) {
436 // In non-material, titles are inset from the dialog margin. Ensure the
437 // horizontal insets match.
438 set_title_margins(
439 gfx::Insets(LayoutDelegate::Get()->GetMetric(
440 LayoutDelegate::Metric::PANEL_CONTENT_MARGIN),
441 side_margin, 0, side_margin));
442 }
443 views::BubbleDialogDelegateView::CreateBubble(this);
444
445 presenter_.reset(new PageInfo(
446 this, profile, TabSpecificContentSettings::FromWebContents(web_contents),
447 web_contents, url, security_info));
448 }
449
450 void PageInfoPopupView::RenderFrameDeleted(
451 content::RenderFrameHost* render_frame_host) {
452 if (render_frame_host == web_contents()->GetMainFrame())
453 GetWidget()->Close();
454 }
455
456 void PageInfoPopupView::WebContentsDestroyed() {
457 weak_factory_.InvalidateWeakPtrs();
458 }
459
460 void PageInfoPopupView::OnPermissionChanged(
461 const PageInfoUI::PermissionInfo& permission) {
462 presenter_->OnSitePermissionChanged(permission.type, permission.setting);
463 // The menu buttons for the permissions might have longer strings now, so we
464 // need to layout and size the whole bubble.
465 Layout();
466 SizeToContents();
467 }
468
469 void PageInfoPopupView::OnChosenObjectDeleted(
470 const PageInfoUI::ChosenObjectInfo& info) {
471 presenter_->OnSiteChosenObjectDeleted(info.ui_info, *info.object);
472 }
473
474 base::string16 PageInfoPopupView::GetWindowTitle() const {
475 return summary_text_;
476 }
477
478 bool PageInfoPopupView::ShouldShowCloseButton() const {
479 return true;
480 }
481
482 void PageInfoPopupView::OnWidgetDestroying(views::Widget* widget) {
483 g_shown_popup_type = POPUP_NONE;
484 presenter_->OnUIClosing();
485 }
486
487 int PageInfoPopupView::GetDialogButtons() const {
488 return ui::DIALOG_BUTTON_NONE;
489 }
490
491 const gfx::FontList& PageInfoPopupView::GetTitleFontList() const {
492 return ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
493 kSummaryFontSizeDelta);
494 }
495
496 void PageInfoPopupView::ButtonPressed(views::Button* button,
497 const ui::Event& event) {
498 DCHECK_EQ(BUTTON_CLOSE, button->id());
499 GetWidget()->Close();
500 }
501
502 void PageInfoPopupView::LinkClicked(views::Link* source, int event_flags) {
503 // The popup closes automatically when the collected cookies dialog or the
504 // certificate viewer opens. So delay handling of the link clicked to avoid
505 // a crash in the base class which needs to complete the mouse event handling.
506 content::BrowserThread::PostTask(
507 content::BrowserThread::UI, FROM_HERE,
508 base::Bind(&PageInfoPopupView::HandleLinkClickedAsync,
509 weak_factory_.GetWeakPtr(), source));
510 }
511
512 gfx::Size PageInfoPopupView::GetPreferredSize() const {
513 if (header_ == nullptr && site_settings_view_ == nullptr)
514 return views::View::GetPreferredSize();
515
516 int height = 0;
517 if (header_)
518 height += header_->GetPreferredSize().height() + kHeaderMarginBottom;
519 if (separator_)
520 height += separator_->GetPreferredSize().height();
521
522 if (site_settings_view_)
523 height += site_settings_view_->GetPreferredSize().height();
524
525 int width = kMinPopupWidth;
526 if (site_settings_view_)
527 width = std::max(width, site_settings_view_->GetPreferredSize().width());
528 width = std::min(width, kMaxPopupWidth);
529 return gfx::Size(width, height);
530 }
531
532 void PageInfoPopupView::SetCookieInfo(const CookieInfoList& cookie_info_list) {
533 // |cookie_info_list| should only ever have 2 items: first- and third-party
534 // cookies.
535 DCHECK_EQ(cookie_info_list.size(), 2u);
536 int total_allowed = 0;
537 for (const auto& i : cookie_info_list)
538 total_allowed += i.allowed;
539 base::string16 label_text = l10n_util::GetPluralStringFUTF16(
540 IDS_PAGE_INFO_NUM_COOKIES, total_allowed);
541
542 if (!cookie_dialog_link_) {
543 cookie_dialog_link_ = new views::Link(label_text);
544 cookie_dialog_link_->set_id(LINK_COOKIE_DIALOG);
545 cookie_dialog_link_->set_listener(this);
546 } else {
547 cookie_dialog_link_->SetText(label_text);
548 }
549
550 views::GridLayout* layout =
551 static_cast<views::GridLayout*>(cookies_view_->GetLayoutManager());
552 if (!layout) {
553 layout = new views::GridLayout(cookies_view_);
554 cookies_view_->SetLayoutManager(layout);
555
556 const int cookies_view_column = 0;
557 views::ColumnSet* column_set = layout->AddColumnSet(cookies_view_column);
558 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
559 views::GridLayout::FIXED, kPermissionIconColumnWidth,
560 0);
561 column_set->AddPaddingColumn(0, kPermissionImageSpacing);
562 column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL,
563 0, views::GridLayout::USE_PREF, 0, 0);
564
565 layout->AddPaddingRow(0, kCookiesViewVerticalPadding);
566
567 layout->StartRow(1, cookies_view_column);
568 PageInfoUI::PermissionInfo info;
569 info.type = CONTENT_SETTINGS_TYPE_COOKIES;
570 info.setting = CONTENT_SETTING_ALLOW;
571 info.is_incognito =
572 Profile::FromBrowserContext(web_contents()->GetBrowserContext())
573 ->IsOffTheRecord();
574 views::ImageView* icon = new NonAccessibleImageView();
575 const gfx::Image& image = PageInfoUI::GetPermissionIcon(info);
576 icon->SetImage(image.ToImageSkia());
577 layout->AddView(
578 icon, 1, 2, views::GridLayout::FILL,
579 // TODO: The vertical alignment may change to CENTER once Harmony is
580 // implemented. See https://crbug.com/512442#c48
581 views::GridLayout::LEADING);
582
583 views::Label* cookies_label = new views::Label(
584 l10n_util::GetStringUTF16(IDS_PAGE_INFO_TITLE_SITE_DATA),
585 CONTEXT_BODY_TEXT_LARGE);
586 layout->AddView(cookies_label);
587 layout->StartRow(1, cookies_view_column);
588 layout->SkipColumns(1);
589
590 layout->AddView(cookie_dialog_link_);
591
592 layout->AddPaddingRow(0, kCookiesViewVerticalPadding);
593 }
594
595 layout->Layout(cookies_view_);
596 SizeToContents();
597 }
598
599 void PageInfoPopupView::SetPermissionInfo(
600 const PermissionInfoList& permission_info_list,
601 ChosenObjectInfoList chosen_object_info_list) {
602 // When a permission is changed, PageInfo::OnSitePermissionChanged()
603 // calls this method with updated permissions. However, PermissionSelectorRow
604 // will have already updated its state, so it's already reflected in the UI.
605 // In addition, if a permission is set to the default setting, PageInfo
606 // removes it from |permission_info_list|, but the button should remain.
607 if (permissions_view_)
608 return;
609
610 permissions_view_ = new views::View();
611 views::GridLayout* layout = new views::GridLayout(permissions_view_);
612 permissions_view_->SetLayoutManager(layout);
613
614 site_settings_view_->AddChildView(permissions_view_);
615
616 const int content_column = 0;
617 views::ColumnSet* column_set = layout->AddColumnSet(content_column);
618 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
619 views::GridLayout::USE_PREF, 0, 0);
620 const int permissions_column = 1;
621 views::ColumnSet* permissions_set = layout->AddColumnSet(permissions_column);
622 permissions_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
623 0, views::GridLayout::FIXED,
624 kPermissionIconColumnWidth, 0);
625 permissions_set->AddPaddingColumn(0, kPermissionIconMarginLeft);
626 permissions_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
627 0, views::GridLayout::USE_PREF, 0, 0);
628 permissions_set->AddPaddingColumn(1, kPermissionMenuSpacing);
629 permissions_set->AddColumn(views::GridLayout::TRAILING,
630 views::GridLayout::FILL, 0,
631 views::GridLayout::USE_PREF, 0, 0);
632 for (const auto& permission : permission_info_list) {
633 layout->StartRow(1, permissions_column);
634 std::unique_ptr<PermissionSelectorRow> selector =
635 base::MakeUnique<PermissionSelectorRow>(
636 profile_,
637 web_contents() ? web_contents()->GetVisibleURL()
638 : GURL::EmptyGURL(),
639 permission, layout);
640 selector->AddObserver(this);
641 layout->AddPaddingRow(1, kPermissionsVerticalSpacing);
642 selector_rows_.push_back(std::move(selector));
643 }
644
645 for (auto& object : chosen_object_info_list) {
646 layout->StartRow(1, content_column);
647 // The view takes ownership of the object info.
648 auto* object_view = new ChosenObjectRow(std::move(object));
649 object_view->AddObserver(this);
650 layout->AddView(object_view, 1, 1, views::GridLayout::LEADING,
651 views::GridLayout::CENTER);
652 layout->AddPaddingRow(1, kPermissionsVerticalSpacing);
653 }
654
655 layout->Layout(permissions_view_);
656
657 // Add site settings link.
658 views::Link* site_settings_link = new views::Link(
659 l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_SETTINGS_LINK));
660 site_settings_link->set_id(LINK_SITE_SETTINGS);
661 site_settings_link->set_listener(this);
662 views::View* link_section = new views::View();
663 const int kLinkMarginTop = 4;
664 link_section->SetLayoutManager(new views::BoxLayout(
665 views::BoxLayout::kHorizontal, 0, kLinkMarginTop, 0));
666 link_section->AddChildView(site_settings_link);
667 site_settings_view_->AddChildView(link_section);
668
669 SizeToContents();
670 }
671
672 void PageInfoPopupView::SetIdentityInfo(const IdentityInfo& identity_info) {
673 std::unique_ptr<PageInfoUI::SecurityDescription> security_description =
674 identity_info.GetSecurityDescription();
675
676 summary_text_ = security_description->summary;
677 GetWidget()->UpdateWindowTitle();
678
679 if (identity_info.certificate) {
680 certificate_ = identity_info.certificate;
681
682 if (identity_info.show_ssl_decision_revoke_button)
683 header_->AddResetDecisionsLabel();
684 }
685
686 header_->SetDetails(security_description->details);
687
688 Layout();
689 SizeToContents();
690 }
691
692 views::View* PageInfoPopupView::CreateSiteSettingsView(int side_margin) {
693 views::View* site_settings_view = new views::View();
694 views::BoxLayout* box_layout =
695 new views::BoxLayout(views::BoxLayout::kVertical, side_margin, 0, 0);
696 site_settings_view->SetLayoutManager(box_layout);
697 box_layout->set_cross_axis_alignment(
698 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
699
700 // Add cookies view.
701 cookies_view_ = new views::View();
702 site_settings_view->AddChildView(cookies_view_);
703
704 return site_settings_view;
705 }
706
707 void PageInfoPopupView::HandleLinkClickedAsync(views::Link* source) {
708 // Both switch cases require accessing web_contents(), so we check it here.
709 if (web_contents() == nullptr || web_contents()->IsBeingDestroyed())
710 return;
711 switch (source->id()) {
712 case LINK_SITE_SETTINGS:
713 // TODO(crbug.com/655876): This opens the general Content Settings pane,
714 // which is OK for now. But on Android, it opens a page specific to a
715 // given origin that shows all of the settings for that origin. If/when
716 // that's available on desktop we should link to that here, too.
717 web_contents()->OpenURL(content::OpenURLParams(
718 GURL(chrome::kChromeUIContentSettingsURL), content::Referrer(),
719 WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
720 false));
721 presenter_->RecordPageInfoAction(
722 PageInfo::PAGE_INFO_SITE_SETTINGS_OPENED);
723 break;
724 case LINK_COOKIE_DIALOG:
725 // Count how often the Collected Cookies dialog is opened.
726 presenter_->RecordPageInfoAction(
727 PageInfo::PAGE_INFO_COOKIES_DIALOG_OPENED);
728 new CollectedCookiesViews(web_contents());
729 break;
730 default:
731 NOTREACHED();
732 }
733 }
734
735 void PageInfoPopupView::StyledLabelLinkClicked(views::StyledLabel* label,
736 const gfx::Range& range,
737 int event_flags) {
738 switch (label->id()) {
739 case STYLED_LABEL_SECURITY_DETAILS:
740 web_contents()->OpenURL(content::OpenURLParams(
741 GURL(chrome::kPageInfoHelpCenterURL), content::Referrer(),
742 WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
743 false));
744 presenter_->RecordPageInfoAction(
745 PageInfo::PAGE_INFO_CONNECTION_HELP_OPENED);
746 break;
747 case STYLED_LABEL_RESET_CERTIFICATE_DECISIONS:
748 presenter_->OnRevokeSSLErrorBypassButtonPressed();
749 GetWidget()->Close();
750 break;
751 default:
752 NOTREACHED();
753 }
754 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698