collected_cookies_views.cc revision 2385ea399aae016c0806a4f9ef3c9cfe3d2a39df
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 52using web_modal::WebContentsModalDialogManager; 53 54namespace chrome { 55 56// Declared in browser_dialogs.h so others don't have to depend on our header. 57void ShowCollectedCookiesDialog(content::WebContents* web_contents) { 58 // Deletes itself on close. 59 new CollectedCookiesViews(web_contents); 60} 61 62} // namespace chrome 63 64namespace { 65 66// Spacing between the infobar frame and its contents. 67const int kInfobarVerticalPadding = 3; 68const int kInfobarHorizontalPadding = 8; 69 70// Width of the infobar frame. 71const int kInfobarBorderSize = 1; 72 73// Dimensions of the tree views. 74const int kTreeViewWidth = 400; 75const int kTreeViewHeight = 125; 76 77// The color of the border around the cookies tree view. 78const SkColor kCookiesBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8); 79 80// Spacing constants used with the new dialog style. 81const int kTabbedPaneTopPadding = 14; 82const int kLabelBottomPadding = 17; 83const int kCookieInfoBottomPadding = 4; 84const int kVPanelPadding = 15; 85 86} // namespace 87 88// A custom view that conditionally displays an infobar. 89class 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 194CollectedCookiesViews::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 223string16 CollectedCookiesViews::GetWindowTitle() const { 224 return l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE); 225} 226 227int CollectedCookiesViews::GetDialogButtons() const { 228 return ui::DIALOG_BUTTON_CANCEL; 229} 230 231string16 CollectedCookiesViews::GetDialogButtonLabel( 232 ui::DialogButton button) const { 233 return l10n_util::GetStringUTF16(IDS_CLOSE); 234} 235 236void CollectedCookiesViews::DeleteDelegate() { 237 delete this; 238} 239 240bool 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. 251views::NonClientFrameView* CollectedCookiesViews::CreateNonClientFrameView( 252 views::Widget* widget) { 253 return CreateConstrainedStyleNonClientFrameView( 254 widget, 255 web_contents_->GetBrowserContext()); 256} 257 258ui::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 269void 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 282void CollectedCookiesViews::TabSelectedAt(int index) { 283 EnableControls(); 284 ShowCookieInfo(); 285} 286 287/////////////////////////////////////////////////////////////////////////////// 288// CollectedCookiesViews, views::TreeViewController implementation: 289 290void CollectedCookiesViews::OnTreeViewSelectionChanged( 291 views::TreeView* tree_view) { 292 EnableControls(); 293 ShowCookieInfo(); 294} 295 296/////////////////////////////////////////////////////////////////////////////// 297// CollectedCookiesViews, views::View overrides: 298 299void CollectedCookiesViews::ViewHierarchyChanged( 300 const ViewHierarchyChangedDetails& details) { 301 if (details.is_add && details.child == this) 302 Init(); 303} 304 305//////////////////////////////////////////////////////////////////////////////// 306// CollectedCookiesViews, private: 307 308CollectedCookiesViews::~CollectedCookiesViews() { 309 allowed_cookies_tree_->SetModel(NULL); 310 blocked_cookies_tree_->SetModel(NULL); 311} 312 313void 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 360views::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 418views::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 495views::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 507void 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 534void 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 555void 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 570void 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