Home | History | Annotate | Download | only in views
      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/constrained_window_views.h"
     24 #include "chrome/browser/ui/views/cookie_info_view.h"
     25 #include "chrome/common/pref_names.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 "content/public/browser/web_contents_view.h"
     32 #include "grit/generated_resources.h"
     33 #include "grit/locale_settings.h"
     34 #include "grit/theme_resources.h"
     35 #include "net/cookies/canonical_cookie.h"
     36 #include "ui/base/l10n/l10n_util.h"
     37 #include "ui/base/resource/resource_bundle.h"
     38 #include "ui/gfx/color_utils.h"
     39 #include "ui/views/border.h"
     40 #include "ui/views/controls/button/label_button.h"
     41 #include "ui/views/controls/image_view.h"
     42 #include "ui/views/controls/label.h"
     43 #include "ui/views/controls/scroll_view.h"
     44 #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
     45 #include "ui/views/controls/tree/tree_view.h"
     46 #include "ui/views/layout/box_layout.h"
     47 #include "ui/views/layout/grid_layout.h"
     48 #include "ui/views/layout/layout_constants.h"
     49 #include "ui/views/widget/widget.h"
     50 #include "ui/views/window/dialog_delegate.h"
     51 
     52 using web_modal::WebContentsModalDialogManager;
     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     views::Border* border = views::Border::CreateSolidBorder(
     99         kInfobarBorderSize, border_color);
    100     content_->set_border(border);
    101 
    102     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    103     info_image_ = new views::ImageView();
    104     info_image_->SetImage(rb.GetImageSkiaNamed(IDR_INFO));
    105     label_ = new views::Label();
    106   }
    107   virtual ~InfobarView() {}
    108 
    109   // Update the visibility of the infobar. If |is_visible| is true, a rule for
    110   // |setting| on |domain_name| was created.
    111   void UpdateVisibility(bool is_visible,
    112                         ContentSetting setting,
    113                         const string16& domain_name) {
    114     if (!is_visible) {
    115       SetVisible(false);
    116       return;
    117     }
    118 
    119     string16 label;
    120     switch (setting) {
    121       case CONTENT_SETTING_BLOCK:
    122         label = l10n_util::GetStringFUTF16(
    123             IDS_COLLECTED_COOKIES_BLOCK_RULE_CREATED, domain_name);
    124         break;
    125 
    126       case CONTENT_SETTING_ALLOW:
    127         label = l10n_util::GetStringFUTF16(
    128             IDS_COLLECTED_COOKIES_ALLOW_RULE_CREATED, domain_name);
    129         break;
    130 
    131       case CONTENT_SETTING_SESSION_ONLY:
    132         label = l10n_util::GetStringFUTF16(
    133             IDS_COLLECTED_COOKIES_SESSION_RULE_CREATED, domain_name);
    134         break;
    135 
    136       default:
    137         NOTREACHED();
    138     }
    139     label_->SetText(label);
    140     content_->Layout();
    141     SetVisible(true);
    142   }
    143 
    144  private:
    145   // Initialize contents and layout.
    146   void Init() {
    147     AddChildView(content_);
    148     content_->SetLayoutManager(
    149         new views::BoxLayout(views::BoxLayout::kHorizontal,
    150                              kInfobarHorizontalPadding,
    151                              kInfobarVerticalPadding,
    152                              views::kRelatedControlSmallHorizontalSpacing));
    153     content_->AddChildView(info_image_);
    154     content_->AddChildView(label_);
    155     UpdateVisibility(false, CONTENT_SETTING_BLOCK, string16());
    156   }
    157 
    158   // views::View overrides.
    159   virtual gfx::Size GetPreferredSize() OVERRIDE {
    160     if (!visible())
    161       return gfx::Size();
    162 
    163     // Add space around the banner.
    164     gfx::Size size(content_->GetPreferredSize());
    165     size.Enlarge(0, 2 * views::kRelatedControlVerticalSpacing);
    166     return size;
    167   }
    168 
    169   virtual void Layout() OVERRIDE {
    170     content_->SetBounds(
    171         0, views::kRelatedControlVerticalSpacing,
    172         width(), height() - views::kRelatedControlVerticalSpacing);
    173   }
    174 
    175   virtual void ViewHierarchyChanged(
    176       const ViewHierarchyChangedDetails& details) OVERRIDE {
    177     if (details.is_add && details.child == this)
    178       Init();
    179   }
    180 
    181   // Holds the info icon image and text label and renders the border.
    182   views::View* content_;
    183   // Info icon image.
    184   views::ImageView* info_image_;
    185   // The label responsible for rendering the text.
    186   views::Label* label_;
    187 
    188   DISALLOW_COPY_AND_ASSIGN(InfobarView);
    189 };
    190 
    191 ///////////////////////////////////////////////////////////////////////////////
    192 // CollectedCookiesViews, public:
    193 
    194 CollectedCookiesViews::CollectedCookiesViews(content::WebContents* web_contents)
    195     : web_contents_(web_contents),
    196       allowed_label_(NULL),
    197       blocked_label_(NULL),
    198       allowed_cookies_tree_(NULL),
    199       blocked_cookies_tree_(NULL),
    200       block_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   window_ = CreateWebContentsModalDialogViews(
    213       this,
    214       web_contents->GetView()->GetNativeView(),
    215       web_contents_modal_dialog_manager->delegate()->
    216           GetWebContentsModalDialogHost());
    217   web_contents_modal_dialog_manager->ShowDialog(window_->GetNativeView());
    218 }
    219 
    220 ///////////////////////////////////////////////////////////////////////////////
    221 // CollectedCookiesViews, views::DialogDelegate implementation:
    222 
    223 string16 CollectedCookiesViews::GetWindowTitle() const {
    224   return l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE);
    225 }
    226 
    227 int CollectedCookiesViews::GetDialogButtons() const {
    228   return ui::DIALOG_BUTTON_CANCEL;
    229 }
    230 
    231 string16 CollectedCookiesViews::GetDialogButtonLabel(
    232     ui::DialogButton button) const {
    233   return l10n_util::GetStringUTF16(IDS_CLOSE);
    234 }
    235 
    236 void CollectedCookiesViews::DeleteDelegate() {
    237   delete this;
    238 }
    239 
    240 bool CollectedCookiesViews::Cancel() {
    241   if (status_changed_) {
    242     CollectedCookiesInfoBarDelegate::Create(
    243         InfoBarService::FromWebContents(web_contents_));
    244   }
    245 
    246   return true;
    247 }
    248 
    249 // TODO(wittman): Remove this override once we move to the new style frame view
    250 // on all dialogs.
    251 views::NonClientFrameView* CollectedCookiesViews::CreateNonClientFrameView(
    252     views::Widget* widget) {
    253   return CreateConstrainedStyleNonClientFrameView(
    254       widget,
    255       web_contents_->GetBrowserContext());
    256 }
    257 
    258 ui::ModalType CollectedCookiesViews::GetModalType() const {
    259 #if defined(USE_ASH)
    260   return ui::MODAL_TYPE_CHILD;
    261 #else
    262   return views::WidgetDelegate::GetModalType();
    263 #endif
    264 }
    265 
    266 ///////////////////////////////////////////////////////////////////////////////
    267 // CollectedCookiesViews, views::ButtonListener implementation:
    268 
    269 void CollectedCookiesViews::ButtonPressed(views::Button* sender,
    270                                           const ui::Event& event) {
    271   if (sender == block_allowed_button_)
    272     AddContentException(allowed_cookies_tree_, CONTENT_SETTING_BLOCK);
    273   else if (sender == allow_blocked_button_)
    274     AddContentException(blocked_cookies_tree_, CONTENT_SETTING_ALLOW);
    275   else if (sender == for_session_blocked_button_)
    276     AddContentException(blocked_cookies_tree_, CONTENT_SETTING_SESSION_ONLY);
    277 }
    278 
    279 ///////////////////////////////////////////////////////////////////////////////
    280 // CollectedCookiesViews, views::TabbedPaneListener implementation:
    281 
    282 void CollectedCookiesViews::TabSelectedAt(int index) {
    283   EnableControls();
    284   ShowCookieInfo();
    285 }
    286 
    287 ///////////////////////////////////////////////////////////////////////////////
    288 // CollectedCookiesViews, views::TreeViewController implementation:
    289 
    290 void CollectedCookiesViews::OnTreeViewSelectionChanged(
    291     views::TreeView* tree_view) {
    292   EnableControls();
    293   ShowCookieInfo();
    294 }
    295 
    296 ///////////////////////////////////////////////////////////////////////////////
    297 // CollectedCookiesViews, views::View overrides:
    298 
    299 void CollectedCookiesViews::ViewHierarchyChanged(
    300     const ViewHierarchyChangedDetails& details) {
    301   if (details.is_add && details.child == this)
    302     Init();
    303 }
    304 
    305 ////////////////////////////////////////////////////////////////////////////////
    306 // CollectedCookiesViews, private:
    307 
    308 CollectedCookiesViews::~CollectedCookiesViews() {
    309   allowed_cookies_tree_->SetModel(NULL);
    310   blocked_cookies_tree_->SetModel(NULL);
    311 }
    312 
    313 void CollectedCookiesViews::Init() {
    314   using views::GridLayout;
    315 
    316   GridLayout* layout = GridLayout::CreatePanel(this);
    317   SetLayoutManager(layout);
    318 
    319   const int single_column_layout_id = 0;
    320   views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
    321   column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
    322                         GridLayout::USE_PREF, 0, 0);
    323 
    324   layout->StartRow(0, single_column_layout_id);
    325   views::TabbedPane* tabbed_pane = NULL;
    326   if (DialogDelegate::UseNewStyle()) {
    327     tabbed_pane = new views::TabbedPane(false);
    328     layout->SetInsets(gfx::Insets(kTabbedPaneTopPadding, 0, 0, 0));
    329   } else {
    330     tabbed_pane = new views::TabbedPane(true);
    331   }
    332 
    333   layout->AddView(tabbed_pane);
    334   // NOTE: Panes must be added after |tabbed_pane| has been added to its parent.
    335   string16 label_allowed = l10n_util::GetStringUTF16(
    336       IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_TAB_LABEL);
    337   string16 label_blocked = l10n_util::GetStringUTF16(
    338       IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_TAB_LABEL);
    339   tabbed_pane->AddTab(label_allowed, CreateAllowedPane());
    340   tabbed_pane->AddTab(label_blocked, CreateBlockedPane());
    341   tabbed_pane->SelectTabAt(0);
    342   tabbed_pane->set_listener(this);
    343   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    344 
    345   layout->StartRow(0, single_column_layout_id);
    346   cookie_info_view_ = new CookieInfoView();
    347   layout->AddView(cookie_info_view_);
    348   layout->AddPaddingRow(0, DialogDelegate::UseNewStyle() ?
    349                            kCookieInfoBottomPadding :
    350                            views::kRelatedControlVerticalSpacing);
    351 
    352   layout->StartRow(0, single_column_layout_id);
    353   infobar_ = new InfobarView();
    354   layout->AddView(infobar_);
    355 
    356   EnableControls();
    357   ShowCookieInfo();
    358 }
    359 
    360 views::View* CollectedCookiesViews::CreateAllowedPane() {
    361   TabSpecificContentSettings* content_settings =
    362       TabSpecificContentSettings::FromWebContents(web_contents_);
    363 
    364   // Create the controls that go into the pane.
    365   allowed_label_ = new views::Label(l10n_util::GetStringUTF16(
    366       IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL));
    367 
    368   const LocalSharedObjectsContainer& allowed_data =
    369       content_settings->allowed_local_shared_objects();
    370   allowed_cookies_tree_model_ = allowed_data.CreateCookiesTreeModel();
    371   allowed_cookies_tree_ = new views::TreeView();
    372   allowed_cookies_tree_->SetModel(allowed_cookies_tree_model_.get());
    373   allowed_cookies_tree_->SetRootShown(false);
    374   allowed_cookies_tree_->SetEditable(false);
    375   allowed_cookies_tree_->set_auto_expand_children(true);
    376   allowed_cookies_tree_->SetController(this);
    377 
    378   block_allowed_button_ = new views::LabelButton(this,
    379       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_BLOCK_BUTTON));
    380   block_allowed_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
    381 
    382   // Create the view that holds all the controls together.  This will be the
    383   // pane added to the tabbed pane.
    384   using views::GridLayout;
    385 
    386   views::View* pane = new views::View();
    387   GridLayout* layout = GridLayout::CreatePanel(pane);
    388   if (DialogDelegate::UseNewStyle()) {
    389     layout->SetInsets(kVPanelPadding, views::kButtonHEdgeMarginNew,
    390                       kVPanelPadding, views::kButtonHEdgeMarginNew);
    391   }
    392   pane->SetLayoutManager(layout);
    393 
    394   const int single_column_layout_id = 0;
    395   views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
    396   column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
    397                         GridLayout::USE_PREF, 0, 0);
    398 
    399   layout->StartRow(0, single_column_layout_id);
    400   layout->AddView(allowed_label_);
    401   layout->AddPaddingRow(0, DialogDelegate::UseNewStyle() ?
    402                            kLabelBottomPadding :
    403                            views::kRelatedControlVerticalSpacing);
    404 
    405   layout->StartRow(1, single_column_layout_id);
    406   layout->AddView(CreateScrollView(allowed_cookies_tree_), 1, 1,
    407                   GridLayout::FILL, GridLayout::FILL, kTreeViewWidth,
    408                   kTreeViewHeight);
    409   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    410 
    411   layout->StartRow(0, single_column_layout_id);
    412   layout->AddView(block_allowed_button_, 1, 1, GridLayout::LEADING,
    413                   GridLayout::CENTER);
    414 
    415   return pane;
    416 }
    417 
    418 views::View* CollectedCookiesViews::CreateBlockedPane() {
    419   TabSpecificContentSettings* content_settings =
    420       TabSpecificContentSettings::FromWebContents(web_contents_);
    421 
    422   Profile* profile =
    423       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
    424   PrefService* prefs = profile->GetPrefs();
    425 
    426   // Create the controls that go into the pane.
    427   blocked_label_ = new views::Label(
    428       l10n_util::GetStringUTF16(
    429           prefs->GetBoolean(prefs::kBlockThirdPartyCookies) ?
    430               IDS_COLLECTED_COOKIES_BLOCKED_THIRD_PARTY_BLOCKING_ENABLED :
    431               IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_LABEL));
    432   blocked_label_->SetMultiLine(true);
    433   blocked_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    434   const LocalSharedObjectsContainer& blocked_data =
    435       content_settings->blocked_local_shared_objects();
    436   blocked_cookies_tree_model_ = blocked_data.CreateCookiesTreeModel();
    437   blocked_cookies_tree_ = new views::TreeView();
    438   blocked_cookies_tree_->SetModel(blocked_cookies_tree_model_.get());
    439   blocked_cookies_tree_->SetRootShown(false);
    440   blocked_cookies_tree_->SetEditable(false);
    441   blocked_cookies_tree_->set_auto_expand_children(true);
    442   blocked_cookies_tree_->SetController(this);
    443 
    444   allow_blocked_button_ = new views::LabelButton(this,
    445       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOW_BUTTON));
    446   allow_blocked_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
    447   for_session_blocked_button_ = new views::LabelButton(this,
    448       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_SESSION_ONLY_BUTTON));
    449   for_session_blocked_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
    450 
    451   // Create the view that holds all the controls together.  This will be the
    452   // pane added to the tabbed pane.
    453   using views::GridLayout;
    454 
    455   views::View* pane = new views::View();
    456   GridLayout* layout = GridLayout::CreatePanel(pane);
    457   if (DialogDelegate::UseNewStyle()) {
    458     layout->SetInsets(kVPanelPadding, views::kButtonHEdgeMarginNew,
    459                       kVPanelPadding, views::kButtonHEdgeMarginNew);
    460   }
    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, DialogDelegate::UseNewStyle() ?
    479                            kLabelBottomPadding :
    480                            views::kRelatedControlVerticalSpacing);
    481 
    482   layout->StartRow(1, single_column_layout_id);
    483   layout->AddView(
    484       CreateScrollView(blocked_cookies_tree_), 1, 1,
    485       GridLayout::FILL, GridLayout::FILL, kTreeViewWidth, kTreeViewHeight);
    486   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    487 
    488   layout->StartRow(0, three_columns_layout_id);
    489   layout->AddView(allow_blocked_button_);
    490   layout->AddView(for_session_blocked_button_);
    491 
    492   return pane;
    493 }
    494 
    495 views::View* CollectedCookiesViews::CreateScrollView(views::TreeView* pane) {
    496   if (DialogDelegate::UseNewStyle()) {
    497     views::ScrollView* scroll_view = new views::ScrollView();
    498     scroll_view->SetContents(pane);
    499     scroll_view->set_border(
    500         views::Border::CreateSolidBorder(1, kCookiesBorderColor));
    501     return scroll_view;
    502   } else {
    503     return pane->CreateParentIfNecessary();
    504   }
    505 }
    506 
    507 void CollectedCookiesViews::EnableControls() {
    508   bool enable_allowed_buttons = false;
    509   ui::TreeModelNode* node = allowed_cookies_tree_->GetSelectedNode();
    510   if (node) {
    511     CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
    512     if (cookie_node->GetDetailedInfo().node_type ==
    513         CookieTreeNode::DetailedInfo::TYPE_HOST) {
    514       enable_allowed_buttons = static_cast<CookieTreeHostNode*>(
    515           cookie_node)->CanCreateContentException();
    516     }
    517   }
    518   block_allowed_button_->SetEnabled(enable_allowed_buttons);
    519 
    520   bool enable_blocked_buttons = false;
    521   node = blocked_cookies_tree_->GetSelectedNode();
    522   if (node) {
    523     CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
    524     if (cookie_node->GetDetailedInfo().node_type ==
    525         CookieTreeNode::DetailedInfo::TYPE_HOST) {
    526       enable_blocked_buttons = static_cast<CookieTreeHostNode*>(
    527           cookie_node)->CanCreateContentException();
    528     }
    529   }
    530   allow_blocked_button_->SetEnabled(enable_blocked_buttons);
    531   for_session_blocked_button_->SetEnabled(enable_blocked_buttons);
    532 }
    533 
    534 void CollectedCookiesViews::ShowCookieInfo() {
    535   ui::TreeModelNode* node = allowed_cookies_tree_->GetSelectedNode();
    536   if (!node)
    537     node = blocked_cookies_tree_->GetSelectedNode();
    538 
    539   if (node) {
    540     CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node);
    541     const CookieTreeNode::DetailedInfo detailed_info =
    542         cookie_node->GetDetailedInfo();
    543 
    544     if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) {
    545       cookie_info_view_->SetCookie(detailed_info.cookie->Domain(),
    546                                    *detailed_info.cookie);
    547     } else {
    548       cookie_info_view_->ClearCookieDisplay();
    549     }
    550   } else {
    551     cookie_info_view_->ClearCookieDisplay();
    552   }
    553 }
    554 
    555 void CollectedCookiesViews::AddContentException(views::TreeView* tree_view,
    556                                                 ContentSetting setting) {
    557   CookieTreeHostNode* host_node =
    558       static_cast<CookieTreeHostNode*>(tree_view->GetSelectedNode());
    559   Profile* profile =
    560       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
    561   host_node->CreateContentException(
    562       CookieSettings::Factory::GetForProfile(profile).get(), setting);
    563   infobar_->UpdateVisibility(true, setting, host_node->GetTitle());
    564   status_changed_ = true;
    565 }
    566 
    567 ///////////////////////////////////////////////////////////////////////////////
    568 // CollectedCookiesViews, content::NotificationObserver implementation:
    569 
    570 void CollectedCookiesViews::Observe(
    571     int type,
    572     const content::NotificationSource& source,
    573     const content::NotificationDetails& details) {
    574   DCHECK_EQ(chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN, type);
    575   window_->Close();
    576 }
    577