Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / collected_cookies_views.cc
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/collected_cookies_views.h"
6
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_cookie_helper.h"
10 #include "chrome/browser/browsing_data/browsing_data_database_helper.h"
11 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
12 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
13 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
14 #include "chrome/browser/browsing_data/browsing_data_server_bound_cert_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/local_shared_objects_container.h"
19 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
20 #include "chrome/browser/infobars/infobar_service.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
23 #include "chrome/browser/ui/views/cookie_info_view.h"
24 #include "chrome/common/pref_names.h"
25 #include "components/web_modal/web_contents_modal_dialog_host.h"
26 #include "components/web_modal/web_contents_modal_dialog_manager.h"
27 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
28 #include "content/public/browser/notification_details.h"
29 #include "content/public/browser/notification_source.h"
30 #include "content/public/browser/web_contents.h"
31 #include "grit/generated_resources.h"
32 #include "grit/locale_settings.h"
33 #include "grit/theme_resources.h"
34 #include "net/cookies/canonical_cookie.h"
35 #include "ui/base/l10n/l10n_util.h"
36 #include "ui/base/resource/resource_bundle.h"
37 #include "ui/gfx/color_utils.h"
38 #include "ui/views/border.h"
39 #include "ui/views/controls/button/label_button.h"
40 #include "ui/views/controls/image_view.h"
41 #include "ui/views/controls/label.h"
42 #include "ui/views/controls/scroll_view.h"
43 #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
44 #include "ui/views/controls/tree/tree_view.h"
45 #include "ui/views/layout/box_layout.h"
46 #include "ui/views/layout/grid_layout.h"
47 #include "ui/views/layout/layout_constants.h"
48 #include "ui/views/widget/widget.h"
49 #include "ui/views/window/dialog_delegate.h"
50
51 using web_modal::WebContentsModalDialogManager;
52 using web_modal::WebContentsModalDialogManagerDelegate;
53
54 namespace chrome {
55
56 // Declared in browser_dialogs.h so others don't have to depend on our header.
57 void ShowCollectedCookiesDialog(content::WebContents* web_contents) {
58   // Deletes itself on close.
59   new CollectedCookiesViews(web_contents);
60 }
61
62 }  // namespace chrome
63
64 namespace {
65
66 // Spacing between the infobar frame and its contents.
67 const int kInfobarVerticalPadding = 3;
68 const int kInfobarHorizontalPadding = 8;
69
70 // Width of the infobar frame.
71 const int kInfobarBorderSize = 1;
72
73 // Dimensions of the tree views.
74 const int kTreeViewWidth = 400;
75 const int kTreeViewHeight = 125;
76
77 // The color of the border around the cookies tree view.
78 const SkColor kCookiesBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8);
79
80 // Spacing constants used with the new dialog style.
81 const int kTabbedPaneTopPadding = 14;
82 const int kLabelBottomPadding = 17;
83 const int kCookieInfoBottomPadding = 4;
84 const int kVPanelPadding = 15;
85
86 }  // namespace
87
88 // A custom view that conditionally displays an infobar.
89 class InfobarView : public views::View {
90  public:
91   InfobarView() {
92     content_ = new views::View;
93 #if defined(USE_AURA) || !defined(OS_WIN)
94     SkColor border_color = SK_ColorGRAY;
95 #else
96     SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW);
97 #endif
98     content_->SetBorder(
99         views::Border::CreateSolidBorder(kInfobarBorderSize, border_color));
100
101     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
102     info_image_ = new views::ImageView();
103     info_image_->SetImage(rb.GetImageSkiaNamed(IDR_INFO));
104     label_ = new views::Label();
105   }
106   virtual ~InfobarView() {}
107
108   // Update the visibility of the infobar. If |is_visible| is true, a rule for
109   // |setting| on |domain_name| was created.
110   void UpdateVisibility(bool is_visible,
111                         ContentSetting setting,
112                         const base::string16& domain_name) {
113     if (!is_visible) {
114       SetVisible(false);
115       return;
116     }
117
118     base::string16 label;
119     switch (setting) {
120       case CONTENT_SETTING_BLOCK:
121         label = l10n_util::GetStringFUTF16(
122             IDS_COLLECTED_COOKIES_BLOCK_RULE_CREATED, domain_name);
123         break;
124
125       case CONTENT_SETTING_ALLOW:
126         label = l10n_util::GetStringFUTF16(
127             IDS_COLLECTED_COOKIES_ALLOW_RULE_CREATED, domain_name);
128         break;
129
130       case CONTENT_SETTING_SESSION_ONLY:
131         label = l10n_util::GetStringFUTF16(
132             IDS_COLLECTED_COOKIES_SESSION_RULE_CREATED, domain_name);
133         break;
134
135       default:
136         NOTREACHED();
137     }
138     label_->SetText(label);
139     content_->Layout();
140     SetVisible(true);
141   }
142
143  private:
144   // Initialize contents and layout.
145   void Init() {
146     AddChildView(content_);
147     content_->SetLayoutManager(
148         new views::BoxLayout(views::BoxLayout::kHorizontal,
149                              kInfobarHorizontalPadding,
150                              kInfobarVerticalPadding,
151                              views::kRelatedControlSmallHorizontalSpacing));
152     content_->AddChildView(info_image_);
153     content_->AddChildView(label_);
154     UpdateVisibility(false, CONTENT_SETTING_BLOCK, base::string16());
155   }
156
157   // views::View overrides.
158   virtual gfx::Size GetPreferredSize() OVERRIDE {
159     if (!visible())
160       return gfx::Size();
161
162     // Add space around the banner.
163     gfx::Size size(content_->GetPreferredSize());
164     size.Enlarge(0, 2 * views::kRelatedControlVerticalSpacing);
165     return size;
166   }
167
168   virtual void Layout() OVERRIDE {
169     content_->SetBounds(
170         0, views::kRelatedControlVerticalSpacing,
171         width(), height() - views::kRelatedControlVerticalSpacing);
172   }
173
174   virtual void ViewHierarchyChanged(
175       const ViewHierarchyChangedDetails& details) OVERRIDE {
176     if (details.is_add && details.child == this)
177       Init();
178   }
179
180   // Holds the info icon image and text label and renders the border.
181   views::View* content_;
182   // Info icon image.
183   views::ImageView* info_image_;
184   // The label responsible for rendering the text.
185   views::Label* label_;
186
187   DISALLOW_COPY_AND_ASSIGN(InfobarView);
188 };
189
190 ///////////////////////////////////////////////////////////////////////////////
191 // CollectedCookiesViews, public:
192
193 CollectedCookiesViews::CollectedCookiesViews(content::WebContents* web_contents)
194     : web_contents_(web_contents),
195       allowed_label_(NULL),
196       blocked_label_(NULL),
197       allowed_cookies_tree_(NULL),
198       blocked_cookies_tree_(NULL),
199       block_allowed_button_(NULL),
200       delete_allowed_button_(NULL),
201       allow_blocked_button_(NULL),
202       for_session_blocked_button_(NULL),
203       cookie_info_view_(NULL),
204       infobar_(NULL),
205       status_changed_(false) {
206   TabSpecificContentSettings* content_settings =
207       TabSpecificContentSettings::FromWebContents(web_contents);
208   registrar_.Add(this, chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN,
209                  content::Source<TabSpecificContentSettings>(content_settings));
210   WebContentsModalDialogManager* web_contents_modal_dialog_manager =
211       WebContentsModalDialogManager::FromWebContents(web_contents);
212   WebContentsModalDialogManagerDelegate* modal_delegate =
213       web_contents_modal_dialog_manager->delegate();
214   DCHECK(modal_delegate);
215   window_ = views::Widget::CreateWindowAsFramelessChild(
216       this, modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
217   web_contents_modal_dialog_manager->ShowModalDialog(
218       window_->GetNativeView());
219 }
220
221 ///////////////////////////////////////////////////////////////////////////////
222 // CollectedCookiesViews, views::DialogDelegate implementation:
223
224 base::string16 CollectedCookiesViews::GetWindowTitle() const {
225   return l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE);
226 }
227
228 int CollectedCookiesViews::GetDialogButtons() const {
229   return ui::DIALOG_BUTTON_CANCEL;
230 }
231
232 base::string16 CollectedCookiesViews::GetDialogButtonLabel(
233     ui::DialogButton button) const {
234   return l10n_util::GetStringUTF16(IDS_CLOSE);
235 }
236
237 void CollectedCookiesViews::DeleteDelegate() {
238   delete this;
239 }
240
241 bool CollectedCookiesViews::Cancel() {
242   if (status_changed_) {
243     CollectedCookiesInfoBarDelegate::Create(
244         InfoBarService::FromWebContents(web_contents_));
245   }
246
247   return true;
248 }
249
250 ui::ModalType CollectedCookiesViews::GetModalType() const {
251 #if defined(USE_ASH)
252   return ui::MODAL_TYPE_CHILD;
253 #else
254   return views::WidgetDelegate::GetModalType();
255 #endif
256 }
257
258 ///////////////////////////////////////////////////////////////////////////////
259 // CollectedCookiesViews, views::ButtonListener implementation:
260
261 void CollectedCookiesViews::ButtonPressed(views::Button* sender,
262                                           const ui::Event& event) {
263   if (sender == block_allowed_button_) {
264     AddContentException(allowed_cookies_tree_, CONTENT_SETTING_BLOCK);
265   } else if (sender == delete_allowed_button_) {
266     allowed_cookies_tree_model_->DeleteCookieNode(
267         static_cast<CookieTreeNode*>(allowed_cookies_tree_->GetSelectedNode()));
268   } else if (sender == allow_blocked_button_) {
269     AddContentException(blocked_cookies_tree_, CONTENT_SETTING_ALLOW);
270   } else if (sender == for_session_blocked_button_) {
271     AddContentException(blocked_cookies_tree_, CONTENT_SETTING_SESSION_ONLY);
272   }
273 }
274
275 ///////////////////////////////////////////////////////////////////////////////
276 // CollectedCookiesViews, views::TabbedPaneListener implementation:
277
278 void CollectedCookiesViews::TabSelectedAt(int index) {
279   EnableControls();
280   ShowCookieInfo();
281 }
282
283 ///////////////////////////////////////////////////////////////////////////////
284 // CollectedCookiesViews, views::TreeViewController implementation:
285
286 void CollectedCookiesViews::OnTreeViewSelectionChanged(
287     views::TreeView* tree_view) {
288   EnableControls();
289   ShowCookieInfo();
290 }
291
292 ///////////////////////////////////////////////////////////////////////////////
293 // CollectedCookiesViews, views::View overrides:
294
295 gfx::Size CollectedCookiesViews::GetMinimumSize() {
296   // Allow UpdateWebContentsModalDialogPosition to clamp the dialog width.
297   return gfx::Size(0, View::GetMinimumSize().height());
298 }
299
300 void CollectedCookiesViews::ViewHierarchyChanged(
301     const ViewHierarchyChangedDetails& details) {
302   if (details.is_add && details.child == this)
303     Init();
304 }
305
306 ////////////////////////////////////////////////////////////////////////////////
307 // CollectedCookiesViews, private:
308
309 CollectedCookiesViews::~CollectedCookiesViews() {
310   allowed_cookies_tree_->SetModel(NULL);
311   blocked_cookies_tree_->SetModel(NULL);
312 }
313
314 void CollectedCookiesViews::Init() {
315   using views::GridLayout;
316
317   GridLayout* layout = GridLayout::CreatePanel(this);
318   SetLayoutManager(layout);
319
320   const int single_column_layout_id = 0;
321   views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
322   column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
323                         GridLayout::USE_PREF, 0, 0);
324
325   layout->StartRow(0, single_column_layout_id);
326   views::TabbedPane* tabbed_pane = new views::TabbedPane();
327   layout->SetInsets(gfx::Insets(kTabbedPaneTopPadding, 0, 0, 0));
328
329   layout->AddView(tabbed_pane);
330   // NOTE: Panes must be added after |tabbed_pane| has been added to its parent.
331   base::string16 label_allowed = l10n_util::GetStringUTF16(
332       IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_TAB_LABEL);
333   base::string16 label_blocked = l10n_util::GetStringUTF16(
334       IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_TAB_LABEL);
335   tabbed_pane->AddTab(label_allowed, CreateAllowedPane());
336   tabbed_pane->AddTab(label_blocked, CreateBlockedPane());
337   tabbed_pane->SelectTabAt(0);
338   tabbed_pane->set_listener(this);
339   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
340
341   layout->StartRow(0, single_column_layout_id);
342   cookie_info_view_ = new CookieInfoView();
343   layout->AddView(cookie_info_view_);
344   layout->AddPaddingRow(0, kCookieInfoBottomPadding);
345
346   layout->StartRow(0, single_column_layout_id);
347   infobar_ = new InfobarView();
348   layout->AddView(infobar_);
349
350   EnableControls();
351   ShowCookieInfo();
352 }
353
354 views::View* CollectedCookiesViews::CreateAllowedPane() {
355   TabSpecificContentSettings* content_settings =
356       TabSpecificContentSettings::FromWebContents(web_contents_);
357
358   // Create the controls that go into the pane.
359   allowed_label_ = new views::Label(l10n_util::GetStringUTF16(
360       IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL));
361
362   const LocalSharedObjectsContainer& allowed_data =
363       content_settings->allowed_local_shared_objects();
364   allowed_cookies_tree_model_ = allowed_data.CreateCookiesTreeModel();
365   allowed_cookies_tree_ = new views::TreeView();
366   allowed_cookies_tree_->SetModel(allowed_cookies_tree_model_.get());
367   allowed_cookies_tree_->SetRootShown(false);
368   allowed_cookies_tree_->SetEditable(false);
369   allowed_cookies_tree_->set_auto_expand_children(true);
370   allowed_cookies_tree_->SetController(this);
371
372   block_allowed_button_ = new views::LabelButton(this,
373       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_BLOCK_BUTTON));
374   block_allowed_button_->SetStyle(views::Button::STYLE_BUTTON);
375
376   delete_allowed_button_ = new views::LabelButton(this,
377       l10n_util::GetStringUTF16(IDS_COOKIES_REMOVE_LABEL));
378   delete_allowed_button_->SetStyle(views::Button::STYLE_BUTTON);
379
380   // Create the view that holds all the controls together.  This will be the
381   // pane added to the tabbed pane.
382   using views::GridLayout;
383
384   views::View* pane = new views::View();
385   GridLayout* layout = GridLayout::CreatePanel(pane);
386   layout->SetInsets(kVPanelPadding, views::kButtonHEdgeMarginNew,
387                     kVPanelPadding, views::kButtonHEdgeMarginNew);
388   pane->SetLayoutManager(layout);
389
390   const int single_column_layout_id = 0;
391   views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
392   column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
393                         GridLayout::USE_PREF, 0, 0);
394
395   const int three_columns_layout_id = 1;
396   column_set = layout->AddColumnSet(three_columns_layout_id);
397   column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
398                         GridLayout::USE_PREF, 0, 0);
399   column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
400   column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
401                         GridLayout::USE_PREF, 0, 0);
402
403   layout->StartRow(0, single_column_layout_id);
404   layout->AddView(allowed_label_);
405   layout->AddPaddingRow(0, kLabelBottomPadding);
406
407   layout->StartRow(1, single_column_layout_id);
408   layout->AddView(CreateScrollView(allowed_cookies_tree_), 1, 1,
409                   GridLayout::FILL, GridLayout::FILL, kTreeViewWidth,
410                   kTreeViewHeight);
411   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
412
413   layout->StartRow(0, three_columns_layout_id);
414   layout->AddView(block_allowed_button_);
415   layout->AddView(delete_allowed_button_);
416
417   return pane;
418 }
419
420 views::View* CollectedCookiesViews::CreateBlockedPane() {
421   TabSpecificContentSettings* content_settings =
422       TabSpecificContentSettings::FromWebContents(web_contents_);
423
424   Profile* profile =
425       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
426   PrefService* prefs = profile->GetPrefs();
427
428   // Create the controls that go into the pane.
429   blocked_label_ = new views::Label(
430       l10n_util::GetStringUTF16(
431           prefs->GetBoolean(prefs::kBlockThirdPartyCookies) ?
432               IDS_COLLECTED_COOKIES_BLOCKED_THIRD_PARTY_BLOCKING_ENABLED :
433               IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_LABEL));
434   blocked_label_->SetMultiLine(true);
435   blocked_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
436   const LocalSharedObjectsContainer& blocked_data =
437       content_settings->blocked_local_shared_objects();
438   blocked_cookies_tree_model_ = blocked_data.CreateCookiesTreeModel();
439   blocked_cookies_tree_ = new views::TreeView();
440   blocked_cookies_tree_->SetModel(blocked_cookies_tree_model_.get());
441   blocked_cookies_tree_->SetRootShown(false);
442   blocked_cookies_tree_->SetEditable(false);
443   blocked_cookies_tree_->set_auto_expand_children(true);
444   blocked_cookies_tree_->SetController(this);
445
446   allow_blocked_button_ = new views::LabelButton(this,
447       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOW_BUTTON));
448   allow_blocked_button_->SetStyle(views::Button::STYLE_BUTTON);
449   for_session_blocked_button_ = new views::LabelButton(this,
450       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_SESSION_ONLY_BUTTON));
451   for_session_blocked_button_->SetStyle(views::Button::STYLE_BUTTON);
452
453   // Create the view that holds all the controls together.  This will be the
454   // pane added to the tabbed pane.
455   using views::GridLayout;
456
457   views::View* pane = new views::View();
458   GridLayout* layout = GridLayout::CreatePanel(pane);
459   layout->SetInsets(kVPanelPadding, views::kButtonHEdgeMarginNew,
460                     kVPanelPadding, views::kButtonHEdgeMarginNew);
461   pane->SetLayoutManager(layout);
462
463   const int single_column_layout_id = 0;
464   views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
465   column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
466                         GridLayout::USE_PREF, 0, 0);
467
468   const int three_columns_layout_id = 1;
469   column_set = layout->AddColumnSet(three_columns_layout_id);
470   column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
471                         GridLayout::USE_PREF, 0, 0);
472   column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
473   column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
474                         GridLayout::USE_PREF, 0, 0);
475
476   layout->StartRow(0, single_column_layout_id);
477   layout->AddView(blocked_label_, 1, 1, GridLayout::FILL, GridLayout::FILL);
478   layout->AddPaddingRow(0, kLabelBottomPadding);
479
480   layout->StartRow(1, single_column_layout_id);
481   layout->AddView(
482       CreateScrollView(blocked_cookies_tree_), 1, 1,
483       GridLayout::FILL, GridLayout::FILL, kTreeViewWidth, kTreeViewHeight);
484   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
485
486   layout->StartRow(0, three_columns_layout_id);
487   layout->AddView(allow_blocked_button_);
488   layout->AddView(for_session_blocked_button_);
489
490   return pane;
491 }
492
493 views::View* CollectedCookiesViews::CreateScrollView(views::TreeView* pane) {
494   views::ScrollView* scroll_view = new views::ScrollView();
495   scroll_view->SetContents(pane);
496   scroll_view->SetBorder(
497       views::Border::CreateSolidBorder(1, kCookiesBorderColor));
498   return scroll_view;
499 }
500
501 void CollectedCookiesViews::EnableControls() {
502   bool enable_allowed_buttons = false;
503   ui::TreeModelNode* node = allowed_cookies_tree_->GetSelectedNode();
504   if (node) {
505     CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
506     if (cookie_node->GetDetailedInfo().node_type ==
507         CookieTreeNode::DetailedInfo::TYPE_HOST) {
508       enable_allowed_buttons = static_cast<CookieTreeHostNode*>(
509           cookie_node)->CanCreateContentException();
510     }
511   }
512   block_allowed_button_->SetEnabled(enable_allowed_buttons);
513   delete_allowed_button_->SetEnabled(node != NULL);
514
515   bool enable_blocked_buttons = false;
516   node = blocked_cookies_tree_->GetSelectedNode();
517   if (node) {
518     CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
519     if (cookie_node->GetDetailedInfo().node_type ==
520         CookieTreeNode::DetailedInfo::TYPE_HOST) {
521       enable_blocked_buttons = static_cast<CookieTreeHostNode*>(
522           cookie_node)->CanCreateContentException();
523     }
524   }
525   allow_blocked_button_->SetEnabled(enable_blocked_buttons);
526   for_session_blocked_button_->SetEnabled(enable_blocked_buttons);
527 }
528
529 void CollectedCookiesViews::ShowCookieInfo() {
530   ui::TreeModelNode* node = allowed_cookies_tree_->GetSelectedNode();
531   if (!node)
532     node = blocked_cookies_tree_->GetSelectedNode();
533
534   if (node) {
535     CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
536     const CookieTreeNode::DetailedInfo detailed_info =
537         cookie_node->GetDetailedInfo();
538
539     if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) {
540       cookie_info_view_->SetCookie(detailed_info.cookie->Domain(),
541                                    *detailed_info.cookie);
542     } else {
543       cookie_info_view_->ClearCookieDisplay();
544     }
545   } else {
546     cookie_info_view_->ClearCookieDisplay();
547   }
548 }
549
550 void CollectedCookiesViews::AddContentException(views::TreeView* tree_view,
551                                                 ContentSetting setting) {
552   CookieTreeHostNode* host_node =
553       static_cast<CookieTreeHostNode*>(tree_view->GetSelectedNode());
554   Profile* profile =
555       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
556   host_node->CreateContentException(
557       CookieSettings::Factory::GetForProfile(profile).get(), setting);
558   infobar_->UpdateVisibility(true, setting, host_node->GetTitle());
559   status_changed_ = true;
560 }
561
562 ///////////////////////////////////////////////////////////////////////////////
563 // CollectedCookiesViews, content::NotificationObserver implementation:
564
565 void CollectedCookiesViews::Observe(
566     int type,
567     const content::NotificationSource& source,
568     const content::NotificationDetails& details) {
569   DCHECK_EQ(chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN, type);
570   window_->Close();
571 }