Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / ui / views / collected_cookies_views.cc
blob902cdc6eb9f8b370a8350ecca4fe0d35c9e7c087
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.
5 #include "chrome/browser/ui/views/collected_cookies_views.h"
7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
9 #include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h"
10 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
11 #include "chrome/browser/browsing_data/browsing_data_database_helper.h"
12 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
13 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
14 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
15 #include "chrome/browser/browsing_data/cookies_tree_model.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/content_settings/cookie_settings.h"
18 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
19 #include "chrome/browser/infobars/infobar_service.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
22 #include "chrome/browser/ui/views/cookie_info_view.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/grit/generated_resources.h"
25 #include "chrome/grit/locale_settings.h"
26 #include "components/constrained_window/constrained_window_views.h"
27 #include "content/public/browser/notification_details.h"
28 #include "content/public/browser/notification_source.h"
29 #include "content/public/browser/web_contents.h"
30 #include "grit/theme_resources.h"
31 #include "net/cookies/canonical_cookie.h"
32 #include "ui/base/l10n/l10n_util.h"
33 #include "ui/base/resource/resource_bundle.h"
34 #include "ui/gfx/color_utils.h"
35 #include "ui/views/border.h"
36 #include "ui/views/controls/button/label_button.h"
37 #include "ui/views/controls/image_view.h"
38 #include "ui/views/controls/label.h"
39 #include "ui/views/controls/scroll_view.h"
40 #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
41 #include "ui/views/controls/tree/tree_view.h"
42 #include "ui/views/layout/box_layout.h"
43 #include "ui/views/layout/grid_layout.h"
44 #include "ui/views/layout/layout_constants.h"
45 #include "ui/views/widget/widget.h"
47 namespace {
49 // Spacing between the infobar frame and its contents.
50 const int kInfobarVerticalPadding = 3;
51 const int kInfobarHorizontalPadding = 8;
53 // Width of the infobar frame.
54 const int kInfobarBorderSize = 1;
56 // Dimensions of the tree views.
57 const int kTreeViewWidth = 400;
58 const int kTreeViewHeight = 125;
60 // The color of the border around the cookies tree view.
61 const SkColor kCookiesBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8);
63 // Spacing constants used with the new dialog style.
64 const int kTabbedPaneTopPadding = 14;
65 const int kLabelBottomPadding = 17;
66 const int kCookieInfoBottomPadding = 4;
67 const int kVPanelPadding = 15;
69 } // namespace
71 // A custom view that conditionally displays an infobar.
72 class InfobarView : public views::View {
73 public:
74 InfobarView() {
75 content_ = new views::View;
76 SkColor border_color = SK_ColorGRAY;
77 content_->SetBorder(
78 views::Border::CreateSolidBorder(kInfobarBorderSize, border_color));
80 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
81 info_image_ = new views::ImageView();
82 info_image_->SetImage(rb.GetImageSkiaNamed(IDR_INFO));
83 label_ = new views::Label();
85 ~InfobarView() override {}
87 // Update the visibility of the infobar. If |is_visible| is true, a rule for
88 // |setting| on |domain_name| was created.
89 void UpdateVisibility(bool is_visible,
90 ContentSetting setting,
91 const base::string16& domain_name) {
92 if (!is_visible) {
93 SetVisible(false);
94 return;
97 base::string16 label;
98 switch (setting) {
99 case CONTENT_SETTING_BLOCK:
100 label = l10n_util::GetStringFUTF16(
101 IDS_COLLECTED_COOKIES_BLOCK_RULE_CREATED, domain_name);
102 break;
104 case CONTENT_SETTING_ALLOW:
105 label = l10n_util::GetStringFUTF16(
106 IDS_COLLECTED_COOKIES_ALLOW_RULE_CREATED, domain_name);
107 break;
109 case CONTENT_SETTING_SESSION_ONLY:
110 label = l10n_util::GetStringFUTF16(
111 IDS_COLLECTED_COOKIES_SESSION_RULE_CREATED, domain_name);
112 break;
114 default:
115 NOTREACHED();
117 label_->SetText(label);
118 content_->Layout();
119 SetVisible(true);
122 private:
123 // Initialize contents and layout.
124 void Init() {
125 AddChildView(content_);
126 content_->SetLayoutManager(
127 new views::BoxLayout(views::BoxLayout::kHorizontal,
128 kInfobarHorizontalPadding,
129 kInfobarVerticalPadding,
130 views::kRelatedControlSmallHorizontalSpacing));
131 content_->AddChildView(info_image_);
132 content_->AddChildView(label_);
133 UpdateVisibility(false, CONTENT_SETTING_BLOCK, base::string16());
136 // views::View overrides.
137 gfx::Size GetPreferredSize() const override {
138 if (!visible())
139 return gfx::Size();
141 // Add space around the banner.
142 gfx::Size size(content_->GetPreferredSize());
143 size.Enlarge(0, 2 * views::kRelatedControlVerticalSpacing);
144 return size;
147 void Layout() override {
148 content_->SetBounds(
149 0, views::kRelatedControlVerticalSpacing,
150 width(), height() - views::kRelatedControlVerticalSpacing);
153 void ViewHierarchyChanged(
154 const ViewHierarchyChangedDetails& details) override {
155 if (details.is_add && details.child == this)
156 Init();
159 // Holds the info icon image and text label and renders the border.
160 views::View* content_;
161 // Info icon image.
162 views::ImageView* info_image_;
163 // The label responsible for rendering the text.
164 views::Label* label_;
166 DISALLOW_COPY_AND_ASSIGN(InfobarView);
169 ///////////////////////////////////////////////////////////////////////////////
170 // CollectedCookiesViews, public:
172 CollectedCookiesViews::CollectedCookiesViews(content::WebContents* web_contents)
173 : web_contents_(web_contents),
174 allowed_label_(NULL),
175 blocked_label_(NULL),
176 allowed_cookies_tree_(NULL),
177 blocked_cookies_tree_(NULL),
178 block_allowed_button_(NULL),
179 delete_allowed_button_(NULL),
180 allow_blocked_button_(NULL),
181 for_session_blocked_button_(NULL),
182 cookie_info_view_(NULL),
183 infobar_(NULL),
184 status_changed_(false) {
185 TabSpecificContentSettings* content_settings =
186 TabSpecificContentSettings::FromWebContents(web_contents);
187 registrar_.Add(this, chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN,
188 content::Source<TabSpecificContentSettings>(content_settings));
189 constrained_window::ShowWebModalDialogViews(this, web_contents);
192 ///////////////////////////////////////////////////////////////////////////////
193 // CollectedCookiesViews, views::DialogDelegate implementation:
195 base::string16 CollectedCookiesViews::GetWindowTitle() const {
196 return l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE);
199 int CollectedCookiesViews::GetDialogButtons() const {
200 return ui::DIALOG_BUTTON_CANCEL;
203 base::string16 CollectedCookiesViews::GetDialogButtonLabel(
204 ui::DialogButton button) const {
205 return l10n_util::GetStringUTF16(IDS_CLOSE);
208 bool CollectedCookiesViews::Cancel() {
209 // If the user closes our parent tab while we're still open, this method will
210 // (eventually) be called in response to a WebContentsDestroyed() call from
211 // the WebContentsImpl to its observers. But since the InfoBarService is also
212 // torn down in response to WebContentsDestroyed(), it may already be null.
213 // Since the tab is going away anyway, we can just omit showing an infobar,
214 // which prevents any attempt to access a null InfoBarService.
215 if (status_changed_ && !web_contents_->IsBeingDestroyed()) {
216 CollectedCookiesInfoBarDelegate::Create(
217 InfoBarService::FromWebContents(web_contents_));
219 return true;
222 ui::ModalType CollectedCookiesViews::GetModalType() const {
223 return ui::MODAL_TYPE_CHILD;
226 ///////////////////////////////////////////////////////////////////////////////
227 // CollectedCookiesViews, views::ButtonListener implementation:
229 void CollectedCookiesViews::ButtonPressed(views::Button* sender,
230 const ui::Event& event) {
231 if (sender == block_allowed_button_) {
232 AddContentException(allowed_cookies_tree_, CONTENT_SETTING_BLOCK);
233 } else if (sender == delete_allowed_button_) {
234 allowed_cookies_tree_model_->DeleteCookieNode(
235 static_cast<CookieTreeNode*>(allowed_cookies_tree_->GetSelectedNode()));
236 } else if (sender == allow_blocked_button_) {
237 AddContentException(blocked_cookies_tree_, CONTENT_SETTING_ALLOW);
238 } else if (sender == for_session_blocked_button_) {
239 AddContentException(blocked_cookies_tree_, CONTENT_SETTING_SESSION_ONLY);
243 ///////////////////////////////////////////////////////////////////////////////
244 // CollectedCookiesViews, views::TabbedPaneListener implementation:
246 void CollectedCookiesViews::TabSelectedAt(int index) {
247 EnableControls();
248 ShowCookieInfo();
251 ///////////////////////////////////////////////////////////////////////////////
252 // CollectedCookiesViews, views::TreeViewController implementation:
254 void CollectedCookiesViews::OnTreeViewSelectionChanged(
255 views::TreeView* tree_view) {
256 EnableControls();
257 ShowCookieInfo();
260 ///////////////////////////////////////////////////////////////////////////////
261 // CollectedCookiesViews, views::View overrides:
263 gfx::Size CollectedCookiesViews::GetMinimumSize() const {
264 // Allow UpdateWebContentsModalDialogPosition to clamp the dialog width.
265 return gfx::Size(0, View::GetMinimumSize().height());
268 void CollectedCookiesViews::ViewHierarchyChanged(
269 const ViewHierarchyChangedDetails& details) {
270 views::DialogDelegateView::ViewHierarchyChanged(details);
271 if (details.is_add && details.child == this)
272 Init();
275 ////////////////////////////////////////////////////////////////////////////////
276 // CollectedCookiesViews, private:
278 CollectedCookiesViews::~CollectedCookiesViews() {
279 allowed_cookies_tree_->SetModel(NULL);
280 blocked_cookies_tree_->SetModel(NULL);
283 void CollectedCookiesViews::Init() {
284 using views::GridLayout;
286 GridLayout* layout = GridLayout::CreatePanel(this);
287 SetLayoutManager(layout);
289 const int single_column_layout_id = 0;
290 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
291 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
292 GridLayout::USE_PREF, 0, 0);
294 layout->StartRow(0, single_column_layout_id);
295 views::TabbedPane* tabbed_pane = new views::TabbedPane();
296 layout->SetInsets(gfx::Insets(kTabbedPaneTopPadding, 0, 0, 0));
298 layout->AddView(tabbed_pane);
299 // NOTE: Panes must be added after |tabbed_pane| has been added to its parent.
300 base::string16 label_allowed = l10n_util::GetStringUTF16(
301 IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_TAB_LABEL);
302 base::string16 label_blocked = l10n_util::GetStringUTF16(
303 IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_TAB_LABEL);
304 tabbed_pane->AddTab(label_allowed, CreateAllowedPane());
305 tabbed_pane->AddTab(label_blocked, CreateBlockedPane());
306 tabbed_pane->SelectTabAt(0);
307 tabbed_pane->set_listener(this);
308 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
310 layout->StartRow(0, single_column_layout_id);
311 cookie_info_view_ = new CookieInfoView();
312 layout->AddView(cookie_info_view_);
313 layout->AddPaddingRow(0, kCookieInfoBottomPadding);
315 layout->StartRow(0, single_column_layout_id);
316 infobar_ = new InfobarView();
317 layout->AddView(infobar_);
319 EnableControls();
320 ShowCookieInfo();
323 views::View* CollectedCookiesViews::CreateAllowedPane() {
324 TabSpecificContentSettings* content_settings =
325 TabSpecificContentSettings::FromWebContents(web_contents_);
327 // Create the controls that go into the pane.
328 allowed_label_ = new views::Label(l10n_util::GetStringUTF16(
329 IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL));
331 allowed_cookies_tree_model_ =
332 content_settings->CreateAllowedCookiesTreeModel();
333 allowed_cookies_tree_ = new views::TreeView();
334 allowed_cookies_tree_->SetModel(allowed_cookies_tree_model_.get());
335 allowed_cookies_tree_->SetRootShown(false);
336 allowed_cookies_tree_->SetEditable(false);
337 allowed_cookies_tree_->set_auto_expand_children(true);
338 allowed_cookies_tree_->SetController(this);
340 block_allowed_button_ = new views::LabelButton(this,
341 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_BLOCK_BUTTON));
342 block_allowed_button_->SetStyle(views::Button::STYLE_BUTTON);
344 delete_allowed_button_ = new views::LabelButton(this,
345 l10n_util::GetStringUTF16(IDS_COOKIES_REMOVE_LABEL));
346 delete_allowed_button_->SetStyle(views::Button::STYLE_BUTTON);
348 // Create the view that holds all the controls together. This will be the
349 // pane added to the tabbed pane.
350 using views::GridLayout;
352 views::View* pane = new views::View();
353 GridLayout* layout = GridLayout::CreatePanel(pane);
354 layout->SetInsets(kVPanelPadding, views::kButtonHEdgeMarginNew,
355 kVPanelPadding, views::kButtonHEdgeMarginNew);
356 pane->SetLayoutManager(layout);
358 const int single_column_layout_id = 0;
359 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
360 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
361 GridLayout::USE_PREF, 0, 0);
363 const int three_columns_layout_id = 1;
364 column_set = layout->AddColumnSet(three_columns_layout_id);
365 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
366 GridLayout::USE_PREF, 0, 0);
367 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
368 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
369 GridLayout::USE_PREF, 0, 0);
371 layout->StartRow(0, single_column_layout_id);
372 layout->AddView(allowed_label_);
373 layout->AddPaddingRow(0, kLabelBottomPadding);
375 layout->StartRow(1, single_column_layout_id);
376 layout->AddView(CreateScrollView(allowed_cookies_tree_), 1, 1,
377 GridLayout::FILL, GridLayout::FILL, kTreeViewWidth,
378 kTreeViewHeight);
379 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
381 layout->StartRow(0, three_columns_layout_id);
382 layout->AddView(block_allowed_button_);
383 layout->AddView(delete_allowed_button_);
385 return pane;
388 views::View* CollectedCookiesViews::CreateBlockedPane() {
389 TabSpecificContentSettings* content_settings =
390 TabSpecificContentSettings::FromWebContents(web_contents_);
392 Profile* profile =
393 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
394 PrefService* prefs = profile->GetPrefs();
396 // Create the controls that go into the pane.
397 blocked_label_ = new views::Label(
398 l10n_util::GetStringUTF16(
399 prefs->GetBoolean(prefs::kBlockThirdPartyCookies) ?
400 IDS_COLLECTED_COOKIES_BLOCKED_THIRD_PARTY_BLOCKING_ENABLED :
401 IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_LABEL));
402 blocked_label_->SetMultiLine(true);
403 blocked_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
404 blocked_label_->SizeToFit(kTreeViewWidth);
405 blocked_cookies_tree_model_ =
406 content_settings->CreateBlockedCookiesTreeModel();
407 blocked_cookies_tree_ = new views::TreeView();
408 blocked_cookies_tree_->SetModel(blocked_cookies_tree_model_.get());
409 blocked_cookies_tree_->SetRootShown(false);
410 blocked_cookies_tree_->SetEditable(false);
411 blocked_cookies_tree_->set_auto_expand_children(true);
412 blocked_cookies_tree_->SetController(this);
414 allow_blocked_button_ = new views::LabelButton(this,
415 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOW_BUTTON));
416 allow_blocked_button_->SetStyle(views::Button::STYLE_BUTTON);
417 for_session_blocked_button_ = new views::LabelButton(this,
418 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_SESSION_ONLY_BUTTON));
419 for_session_blocked_button_->SetStyle(views::Button::STYLE_BUTTON);
421 // Create the view that holds all the controls together. This will be the
422 // pane added to the tabbed pane.
423 using views::GridLayout;
425 views::View* pane = new views::View();
426 GridLayout* layout = GridLayout::CreatePanel(pane);
427 layout->SetInsets(kVPanelPadding, views::kButtonHEdgeMarginNew,
428 kVPanelPadding, views::kButtonHEdgeMarginNew);
429 pane->SetLayoutManager(layout);
431 const int single_column_layout_id = 0;
432 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
433 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
434 GridLayout::USE_PREF, 0, 0);
436 const int three_columns_layout_id = 1;
437 column_set = layout->AddColumnSet(three_columns_layout_id);
438 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
439 GridLayout::USE_PREF, 0, 0);
440 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
441 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
442 GridLayout::USE_PREF, 0, 0);
444 layout->StartRow(0, single_column_layout_id);
445 layout->AddView(blocked_label_, 1, 1, GridLayout::FILL, GridLayout::FILL);
446 layout->AddPaddingRow(0, kLabelBottomPadding);
448 layout->StartRow(1, single_column_layout_id);
449 layout->AddView(
450 CreateScrollView(blocked_cookies_tree_), 1, 1,
451 GridLayout::FILL, GridLayout::FILL, kTreeViewWidth, kTreeViewHeight);
452 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
454 layout->StartRow(0, three_columns_layout_id);
455 layout->AddView(allow_blocked_button_);
456 layout->AddView(for_session_blocked_button_);
458 return pane;
461 views::View* CollectedCookiesViews::CreateScrollView(views::TreeView* pane) {
462 views::ScrollView* scroll_view = new views::ScrollView();
463 scroll_view->SetContents(pane);
464 scroll_view->SetBorder(
465 views::Border::CreateSolidBorder(1, kCookiesBorderColor));
466 return scroll_view;
469 void CollectedCookiesViews::EnableControls() {
470 bool enable_allowed_buttons = false;
471 ui::TreeModelNode* node = allowed_cookies_tree_->GetSelectedNode();
472 if (node) {
473 CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
474 if (cookie_node->GetDetailedInfo().node_type ==
475 CookieTreeNode::DetailedInfo::TYPE_HOST) {
476 enable_allowed_buttons = static_cast<CookieTreeHostNode*>(
477 cookie_node)->CanCreateContentException();
480 block_allowed_button_->SetEnabled(enable_allowed_buttons);
481 delete_allowed_button_->SetEnabled(node != NULL);
483 bool enable_blocked_buttons = false;
484 node = blocked_cookies_tree_->GetSelectedNode();
485 if (node) {
486 CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
487 if (cookie_node->GetDetailedInfo().node_type ==
488 CookieTreeNode::DetailedInfo::TYPE_HOST) {
489 enable_blocked_buttons = static_cast<CookieTreeHostNode*>(
490 cookie_node)->CanCreateContentException();
493 allow_blocked_button_->SetEnabled(enable_blocked_buttons);
494 for_session_blocked_button_->SetEnabled(enable_blocked_buttons);
497 void CollectedCookiesViews::ShowCookieInfo() {
498 ui::TreeModelNode* node = allowed_cookies_tree_->GetSelectedNode();
499 if (!node)
500 node = blocked_cookies_tree_->GetSelectedNode();
502 if (node) {
503 CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
504 const CookieTreeNode::DetailedInfo detailed_info =
505 cookie_node->GetDetailedInfo();
507 if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) {
508 cookie_info_view_->SetCookie(detailed_info.cookie->Domain(),
509 *detailed_info.cookie);
510 } else {
511 cookie_info_view_->ClearCookieDisplay();
513 } else {
514 cookie_info_view_->ClearCookieDisplay();
518 void CollectedCookiesViews::AddContentException(views::TreeView* tree_view,
519 ContentSetting setting) {
520 CookieTreeHostNode* host_node =
521 static_cast<CookieTreeHostNode*>(tree_view->GetSelectedNode());
522 Profile* profile =
523 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
524 host_node->CreateContentException(
525 CookieSettings::Factory::GetForProfile(profile).get(), setting);
526 infobar_->UpdateVisibility(true, setting, host_node->GetTitle());
527 status_changed_ = true;
530 ///////////////////////////////////////////////////////////////////////////////
531 // CollectedCookiesViews, content::NotificationObserver implementation:
533 void CollectedCookiesViews::Observe(
534 int type,
535 const content::NotificationSource& source,
536 const content::NotificationDetails& details) {
537 DCHECK_EQ(chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN, type);
538 GetWidget()->Close();