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/browsing_data/cookies_tree_model.h" 6 7#include <algorithm> 8#include <functional> 9#include <vector> 10 11#include "base/bind.h" 12#include "base/memory/linked_ptr.h" 13#include "base/strings/string_util.h" 14#include "base/strings/utf_string_conversions.h" 15#include "chrome/browser/browsing_data/browsing_data_cookie_helper.h" 16#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" 17#include "chrome/browser/browsing_data/browsing_data_server_bound_cert_helper.h" 18#include "chrome/browser/content_settings/cookie_settings.h" 19#include "chrome/browser/extensions/extension_service.h" 20#include "chrome/browser/extensions/extension_special_storage_policy.h" 21#include "content/public/common/url_constants.h" 22#include "grit/generated_resources.h" 23#include "grit/theme_resources.h" 24#include "grit/ui_resources.h" 25#include "net/base/registry_controlled_domains/registry_controlled_domain.h" 26#include "net/cookies/canonical_cookie.h" 27#include "net/url_request/url_request_context.h" 28#include "ui/base/l10n/l10n_util.h" 29#include "ui/base/resource/resource_bundle.h" 30#include "ui/gfx/image/image_skia.h" 31 32namespace { 33 34struct NodeTitleComparator { 35 bool operator()(const CookieTreeNode* lhs, const CookieTreeNode* rhs) { 36 return lhs->GetTitle() < rhs->GetTitle(); 37 } 38}; 39 40// Comparison functor, for use in CookieTreeRootNode. 41struct HostNodeComparator { 42 bool operator()(const CookieTreeNode* lhs, const CookieTreeNode* rhs) { 43 // This comparator is only meant to compare CookieTreeHostNode types. Make 44 // sure we check this, as the static cast below is dangerous if we get the 45 // wrong object type. 46 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST, 47 lhs->GetDetailedInfo().node_type); 48 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST, 49 rhs->GetDetailedInfo().node_type); 50 51 const CookieTreeHostNode* ltn = 52 static_cast<const CookieTreeHostNode*>(lhs); 53 const CookieTreeHostNode* rtn = 54 static_cast<const CookieTreeHostNode*>(rhs); 55 56 // We want to order by registry controlled domain, so we would get 57 // google.com, ad.google.com, www.google.com, 58 // microsoft.com, ad.microsoft.com. CanonicalizeHost transforms the origins 59 // into a form like google.com.www so that string comparisons work. 60 return (ltn->canonicalized_host() < 61 rtn->canonicalized_host()); 62 } 63}; 64 65std::string CanonicalizeHost(const GURL& url) { 66 // The canonicalized representation makes the registry controlled domain 67 // come first, and then adds subdomains in reverse order, e.g. 68 // 1.mail.google.com would become google.com.mail.1, and then a standard 69 // string comparison works to order hosts by registry controlled domain 70 // first. Leading dots are ignored, ".google.com" is the same as 71 // "google.com". 72 73 if (url.SchemeIsFile()) { 74 return std::string(chrome::kFileScheme) + 75 content::kStandardSchemeSeparator; 76 } 77 78 std::string host = url.host(); 79 std::string retval = 80 net::registry_controlled_domains::GetDomainAndRegistry( 81 host, 82 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); 83 if (!retval.length()) // Is an IP address or other special origin. 84 return host; 85 86 std::string::size_type position = host.rfind(retval); 87 88 // The host may be the registry controlled domain, in which case fail fast. 89 if (position == 0 || position == std::string::npos) 90 return host; 91 92 // If host is www.google.com, retval will contain google.com at this point. 93 // Start operating to the left of the registry controlled domain, e.g. in 94 // the www.google.com example, start at index 3. 95 --position; 96 97 // If position == 0, that means it's a dot; this will be ignored to treat 98 // ".google.com" the same as "google.com". 99 while (position > 0) { 100 retval += std::string("."); 101 // Copy up to the next dot. host[position] is a dot so start after it. 102 std::string::size_type next_dot = host.rfind(".", position - 1); 103 if (next_dot == std::string::npos) { 104 retval += host.substr(0, position); 105 break; 106 } 107 retval += host.substr(next_dot + 1, position - (next_dot + 1)); 108 position = next_dot; 109 } 110 return retval; 111} 112 113bool TypeIsProtected(CookieTreeNode::DetailedInfo::NodeType type) { 114 switch (type) { 115 case CookieTreeNode::DetailedInfo::TYPE_COOKIE: 116 return false; 117 case CookieTreeNode::DetailedInfo::TYPE_DATABASE: 118 return true; 119 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: 120 return true; 121 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE: 122 return true; 123 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE: 124 return true; 125 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB: 126 return true; 127 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM: 128 return true; 129 case CookieTreeNode::DetailedInfo::TYPE_QUOTA: 130 return false; 131 case CookieTreeNode::DetailedInfo::TYPE_SERVER_BOUND_CERT: 132 return false; 133 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO: 134 return false; 135 default: 136 break; 137 } 138 return false; 139} 140 141// This function returns the local data container associated with a leaf tree 142// node. The app node is assumed to be 3 levels above the leaf because of the 143// following structure: 144// root -> origin -> storage type -> leaf node 145LocalDataContainer* GetLocalDataContainerForNode(CookieTreeNode* node) { 146 CookieTreeHostNode* host = static_cast<CookieTreeHostNode*>( 147 node->parent()->parent()); 148 CHECK_EQ(host->GetDetailedInfo().node_type, 149 CookieTreeNode::DetailedInfo::TYPE_HOST); 150 return node->GetModel()->data_container(); 151} 152 153} // namespace 154 155CookieTreeNode::DetailedInfo::DetailedInfo() 156 : node_type(TYPE_NONE), 157 cookie(NULL), 158 database_info(NULL), 159 local_storage_info(NULL), 160 session_storage_info(NULL), 161 appcache_info(NULL), 162 indexed_db_info(NULL), 163 file_system_info(NULL), 164 quota_info(NULL), 165 server_bound_cert(NULL) {} 166 167CookieTreeNode::DetailedInfo::~DetailedInfo() {} 168 169CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::Init( 170 NodeType type) { 171 DCHECK_EQ(TYPE_NONE, node_type); 172 node_type = type; 173 return *this; 174} 175 176CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitHost() { 177 Init(TYPE_HOST); 178 return *this; 179} 180 181CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitCookie( 182 const net::CanonicalCookie* cookie) { 183 Init(TYPE_COOKIE); 184 this->cookie = cookie; 185 return *this; 186} 187 188CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitDatabase( 189 const BrowsingDataDatabaseHelper::DatabaseInfo* database_info) { 190 Init(TYPE_DATABASE); 191 this->database_info = database_info; 192 origin = database_info->identifier.ToOrigin(); 193 return *this; 194} 195 196CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitLocalStorage( 197 const BrowsingDataLocalStorageHelper::LocalStorageInfo* 198 local_storage_info) { 199 Init(TYPE_LOCAL_STORAGE); 200 this->local_storage_info = local_storage_info; 201 origin = local_storage_info->origin_url; 202 return *this; 203} 204 205CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitSessionStorage( 206 const BrowsingDataLocalStorageHelper::LocalStorageInfo* 207 session_storage_info) { 208 Init(TYPE_SESSION_STORAGE); 209 this->session_storage_info = session_storage_info; 210 origin = session_storage_info->origin_url; 211 return *this; 212} 213 214CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitAppCache( 215 const GURL& origin, 216 const appcache::AppCacheInfo* appcache_info) { 217 Init(TYPE_APPCACHE); 218 this->appcache_info = appcache_info; 219 this->origin = origin; 220 return *this; 221} 222 223CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitIndexedDB( 224 const content::IndexedDBInfo* indexed_db_info) { 225 Init(TYPE_INDEXED_DB); 226 this->indexed_db_info = indexed_db_info; 227 this->origin = indexed_db_info->origin_; 228 return *this; 229} 230 231CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitFileSystem( 232 const BrowsingDataFileSystemHelper::FileSystemInfo* file_system_info) { 233 Init(TYPE_FILE_SYSTEM); 234 this->file_system_info = file_system_info; 235 this->origin = file_system_info->origin; 236 return *this; 237} 238 239CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitQuota( 240 const BrowsingDataQuotaHelper::QuotaInfo* quota_info) { 241 Init(TYPE_QUOTA); 242 this->quota_info = quota_info; 243 return *this; 244} 245 246CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitServerBoundCert( 247 const net::ServerBoundCertStore::ServerBoundCert* server_bound_cert) { 248 Init(TYPE_SERVER_BOUND_CERT); 249 this->server_bound_cert = server_bound_cert; 250 return *this; 251} 252 253CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitFlashLSO( 254 const std::string& flash_lso_domain) { 255 Init(TYPE_FLASH_LSO); 256 this->flash_lso_domain = flash_lso_domain; 257 return *this; 258} 259 260/////////////////////////////////////////////////////////////////////////////// 261// CookieTreeNode, public: 262 263void CookieTreeNode::DeleteStoredObjects() { 264 std::for_each(children().begin(), 265 children().end(), 266 std::mem_fun(&CookieTreeNode::DeleteStoredObjects)); 267} 268 269CookiesTreeModel* CookieTreeNode::GetModel() const { 270 if (parent()) 271 return parent()->GetModel(); 272 else 273 return NULL; 274} 275 276/////////////////////////////////////////////////////////////////////////////// 277// CookieTreeCookieNode, public: 278 279CookieTreeCookieNode::CookieTreeCookieNode( 280 std::list<net::CanonicalCookie>::iterator cookie) 281 : CookieTreeNode(UTF8ToUTF16(cookie->Name())), 282 cookie_(cookie) { 283} 284 285CookieTreeCookieNode::~CookieTreeCookieNode() {} 286 287void CookieTreeCookieNode::DeleteStoredObjects() { 288 LocalDataContainer* container = GetLocalDataContainerForNode(this); 289 CHECK(container); 290 container->cookie_helper_->DeleteCookie(*cookie_); 291 container->cookie_list_.erase(cookie_); 292} 293 294CookieTreeNode::DetailedInfo CookieTreeCookieNode::GetDetailedInfo() const { 295 return DetailedInfo().InitCookie(&*cookie_); 296} 297 298/////////////////////////////////////////////////////////////////////////////// 299// CookieTreeAppCacheNode, public: 300 301CookieTreeAppCacheNode::CookieTreeAppCacheNode( 302 const GURL& origin_url, 303 std::list<appcache::AppCacheInfo>::iterator appcache_info) 304 : CookieTreeNode(UTF8ToUTF16(appcache_info->manifest_url.spec())), 305 origin_url_(origin_url), 306 appcache_info_(appcache_info) { 307} 308 309CookieTreeAppCacheNode::~CookieTreeAppCacheNode() { 310} 311 312void CookieTreeAppCacheNode::DeleteStoredObjects() { 313 LocalDataContainer* container = GetLocalDataContainerForNode(this); 314 315 if (container) { 316 DCHECK(container->appcache_helper_.get()); 317 container->appcache_helper_ 318 ->DeleteAppCacheGroup(appcache_info_->manifest_url); 319 container->appcache_info_[origin_url_].erase(appcache_info_); 320 } 321} 322 323CookieTreeNode::DetailedInfo CookieTreeAppCacheNode::GetDetailedInfo() const { 324 return DetailedInfo().InitAppCache(origin_url_, &*appcache_info_); 325} 326 327/////////////////////////////////////////////////////////////////////////////// 328// CookieTreeDatabaseNode, public: 329 330CookieTreeDatabaseNode::CookieTreeDatabaseNode( 331 std::list<BrowsingDataDatabaseHelper::DatabaseInfo>::iterator database_info) 332 : CookieTreeNode(database_info->database_name.empty() ? 333 l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME) : 334 UTF8ToUTF16(database_info->database_name)), 335 database_info_(database_info) { 336} 337 338CookieTreeDatabaseNode::~CookieTreeDatabaseNode() {} 339 340void CookieTreeDatabaseNode::DeleteStoredObjects() { 341 LocalDataContainer* container = GetLocalDataContainerForNode(this); 342 343 if (container) { 344 container->database_helper_->DeleteDatabase( 345 database_info_->identifier.ToString(), database_info_->database_name); 346 container->database_info_list_.erase(database_info_); 347 } 348} 349 350CookieTreeNode::DetailedInfo CookieTreeDatabaseNode::GetDetailedInfo() const { 351 return DetailedInfo().InitDatabase(&*database_info_); 352} 353 354/////////////////////////////////////////////////////////////////////////////// 355// CookieTreeLocalStorageNode, public: 356 357CookieTreeLocalStorageNode::CookieTreeLocalStorageNode( 358 std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::iterator 359 local_storage_info) 360 : CookieTreeNode(UTF8ToUTF16(local_storage_info->origin_url.spec())), 361 local_storage_info_(local_storage_info) { 362} 363 364CookieTreeLocalStorageNode::~CookieTreeLocalStorageNode() {} 365 366void CookieTreeLocalStorageNode::DeleteStoredObjects() { 367 LocalDataContainer* container = GetLocalDataContainerForNode(this); 368 369 if (container) { 370 container->local_storage_helper_->DeleteOrigin( 371 local_storage_info_->origin_url); 372 container->local_storage_info_list_.erase(local_storage_info_); 373 } 374} 375 376CookieTreeNode::DetailedInfo 377CookieTreeLocalStorageNode::GetDetailedInfo() const { 378 return DetailedInfo().InitLocalStorage( 379 &*local_storage_info_); 380} 381 382/////////////////////////////////////////////////////////////////////////////// 383// CookieTreeSessionStorageNode, public: 384 385CookieTreeSessionStorageNode::CookieTreeSessionStorageNode( 386 std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::iterator 387 session_storage_info) 388 : CookieTreeNode(UTF8ToUTF16(session_storage_info->origin_url.spec())), 389 session_storage_info_(session_storage_info) { 390} 391 392CookieTreeSessionStorageNode::~CookieTreeSessionStorageNode() {} 393 394void CookieTreeSessionStorageNode::DeleteStoredObjects() { 395 LocalDataContainer* container = GetLocalDataContainerForNode(this); 396 397 if (container) { 398 container->session_storage_info_list_.erase(session_storage_info_); 399 } 400} 401 402CookieTreeNode::DetailedInfo 403CookieTreeSessionStorageNode::GetDetailedInfo() const { 404 return DetailedInfo().InitSessionStorage(&*session_storage_info_); 405} 406 407/////////////////////////////////////////////////////////////////////////////// 408// CookieTreeIndexedDBNode, public: 409 410CookieTreeIndexedDBNode::CookieTreeIndexedDBNode( 411 std::list<content::IndexedDBInfo>::iterator 412 indexed_db_info) 413 : CookieTreeNode(UTF8ToUTF16( 414 indexed_db_info->origin_.spec())), 415 indexed_db_info_(indexed_db_info) { 416} 417 418CookieTreeIndexedDBNode::~CookieTreeIndexedDBNode() {} 419 420void CookieTreeIndexedDBNode::DeleteStoredObjects() { 421 LocalDataContainer* container = GetLocalDataContainerForNode(this); 422 423 if (container) { 424 container->indexed_db_helper_->DeleteIndexedDB( 425 indexed_db_info_->origin_); 426 container->indexed_db_info_list_.erase(indexed_db_info_); 427 } 428} 429 430CookieTreeNode::DetailedInfo CookieTreeIndexedDBNode::GetDetailedInfo() const { 431 return DetailedInfo().InitIndexedDB(&*indexed_db_info_); 432} 433 434/////////////////////////////////////////////////////////////////////////////// 435// CookieTreeFileSystemNode, public: 436 437CookieTreeFileSystemNode::CookieTreeFileSystemNode( 438 std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator 439 file_system_info) 440 : CookieTreeNode(UTF8ToUTF16( 441 file_system_info->origin.spec())), 442 file_system_info_(file_system_info) { 443} 444 445CookieTreeFileSystemNode::~CookieTreeFileSystemNode() {} 446 447void CookieTreeFileSystemNode::DeleteStoredObjects() { 448 LocalDataContainer* container = GetLocalDataContainerForNode(this); 449 450 if (container) { 451 container->file_system_helper_->DeleteFileSystemOrigin( 452 file_system_info_->origin); 453 container->file_system_info_list_.erase(file_system_info_); 454 } 455} 456 457CookieTreeNode::DetailedInfo CookieTreeFileSystemNode::GetDetailedInfo() const { 458 return DetailedInfo().InitFileSystem(&*file_system_info_); 459} 460 461/////////////////////////////////////////////////////////////////////////////// 462// CookieTreeQuotaNode, public: 463 464CookieTreeQuotaNode::CookieTreeQuotaNode( 465 std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info) 466 : CookieTreeNode(UTF8ToUTF16(quota_info->host)), 467 quota_info_(quota_info) { 468} 469 470CookieTreeQuotaNode::~CookieTreeQuotaNode() {} 471 472void CookieTreeQuotaNode::DeleteStoredObjects() { 473 // Calling this function may cause unexpected over-quota state of origin. 474 // However, it'll caused no problem, just prevent usage growth of the origin. 475 LocalDataContainer* container = GetModel()->data_container(); 476 477 if (container) { 478 container->quota_helper_->RevokeHostQuota(quota_info_->host); 479 container->quota_info_list_.erase(quota_info_); 480 } 481} 482 483CookieTreeNode::DetailedInfo CookieTreeQuotaNode::GetDetailedInfo() const { 484 return DetailedInfo().InitQuota(&*quota_info_); 485} 486 487/////////////////////////////////////////////////////////////////////////////// 488// CookieTreeServerBoundCertNode, public: 489 490CookieTreeServerBoundCertNode::CookieTreeServerBoundCertNode( 491 net::ServerBoundCertStore::ServerBoundCertList::iterator cert) 492 : CookieTreeNode(ASCIIToUTF16(cert->server_identifier())), 493 server_bound_cert_(cert) { 494} 495 496CookieTreeServerBoundCertNode::~CookieTreeServerBoundCertNode() {} 497 498void CookieTreeServerBoundCertNode::DeleteStoredObjects() { 499 LocalDataContainer* container = GetLocalDataContainerForNode(this); 500 501 if (container) { 502 container->server_bound_cert_helper_->DeleteServerBoundCert( 503 server_bound_cert_->server_identifier()); 504 container->server_bound_cert_list_.erase(server_bound_cert_); 505 } 506} 507 508CookieTreeNode::DetailedInfo 509CookieTreeServerBoundCertNode::GetDetailedInfo() const { 510 return DetailedInfo().InitServerBoundCert(&*server_bound_cert_); 511} 512 513/////////////////////////////////////////////////////////////////////////////// 514// CookieTreeRootNode, public: 515 516CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel* model) 517 : model_(model) { 518} 519 520CookieTreeRootNode::~CookieTreeRootNode() {} 521 522CookieTreeHostNode* CookieTreeRootNode::GetOrCreateHostNode( 523 const GURL& url) { 524 scoped_ptr<CookieTreeHostNode> host_node( 525 new CookieTreeHostNode(url)); 526 527 // First see if there is an existing match. 528 std::vector<CookieTreeNode*>::iterator host_node_iterator = 529 std::lower_bound(children().begin(), children().end(), host_node.get(), 530 HostNodeComparator()); 531 if (host_node_iterator != children().end() && 532 CookieTreeHostNode::TitleForUrl(url) == 533 (*host_node_iterator)->GetTitle()) 534 return static_cast<CookieTreeHostNode*>(*host_node_iterator); 535 // Node doesn't exist, insert the new one into the (ordered) children. 536 DCHECK(model_); 537 model_->Add(this, host_node.get(), 538 (host_node_iterator - children().begin())); 539 return host_node.release(); 540} 541 542CookiesTreeModel* CookieTreeRootNode::GetModel() const { 543 return model_; 544} 545 546CookieTreeNode::DetailedInfo CookieTreeRootNode::GetDetailedInfo() const { 547 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT); 548} 549 550/////////////////////////////////////////////////////////////////////////////// 551// CookieTreeHostNode, public: 552 553// static 554string16 CookieTreeHostNode::TitleForUrl( 555 const GURL& url) { 556 const std::string file_origin_node_name( 557 std::string(chrome::kFileScheme) + content::kStandardSchemeSeparator); 558 return UTF8ToUTF16(url.SchemeIsFile() ? file_origin_node_name : url.host()); 559} 560 561CookieTreeHostNode::CookieTreeHostNode(const GURL& url) 562 : CookieTreeNode(TitleForUrl(url)), 563 cookies_child_(NULL), 564 databases_child_(NULL), 565 local_storages_child_(NULL), 566 session_storages_child_(NULL), 567 appcaches_child_(NULL), 568 indexed_dbs_child_(NULL), 569 file_systems_child_(NULL), 570 quota_child_(NULL), 571 server_bound_certs_child_(NULL), 572 flash_lso_child_(NULL), 573 url_(url), 574 canonicalized_host_(CanonicalizeHost(url)) {} 575 576CookieTreeHostNode::~CookieTreeHostNode() {} 577 578const std::string CookieTreeHostNode::GetHost() const { 579 const std::string file_origin_node_name( 580 std::string(chrome::kFileScheme) + content::kStandardSchemeSeparator); 581 return url_.SchemeIsFile() ? file_origin_node_name : url_.host(); 582} 583 584CookieTreeNode::DetailedInfo CookieTreeHostNode::GetDetailedInfo() const { 585 return DetailedInfo().InitHost(); 586} 587 588CookieTreeCookiesNode* CookieTreeHostNode::GetOrCreateCookiesNode() { 589 if (cookies_child_) 590 return cookies_child_; 591 cookies_child_ = new CookieTreeCookiesNode; 592 AddChildSortedByTitle(cookies_child_); 593 return cookies_child_; 594} 595 596CookieTreeDatabasesNode* CookieTreeHostNode::GetOrCreateDatabasesNode() { 597 if (databases_child_) 598 return databases_child_; 599 databases_child_ = new CookieTreeDatabasesNode; 600 AddChildSortedByTitle(databases_child_); 601 return databases_child_; 602} 603 604CookieTreeLocalStoragesNode* 605 CookieTreeHostNode::GetOrCreateLocalStoragesNode() { 606 if (local_storages_child_) 607 return local_storages_child_; 608 local_storages_child_ = new CookieTreeLocalStoragesNode; 609 AddChildSortedByTitle(local_storages_child_); 610 return local_storages_child_; 611} 612 613CookieTreeSessionStoragesNode* 614 CookieTreeHostNode::GetOrCreateSessionStoragesNode() { 615 if (session_storages_child_) 616 return session_storages_child_; 617 session_storages_child_ = new CookieTreeSessionStoragesNode; 618 AddChildSortedByTitle(session_storages_child_); 619 return session_storages_child_; 620} 621 622CookieTreeAppCachesNode* CookieTreeHostNode::GetOrCreateAppCachesNode() { 623 if (appcaches_child_) 624 return appcaches_child_; 625 appcaches_child_ = new CookieTreeAppCachesNode; 626 AddChildSortedByTitle(appcaches_child_); 627 return appcaches_child_; 628} 629 630CookieTreeIndexedDBsNode* CookieTreeHostNode::GetOrCreateIndexedDBsNode() { 631 if (indexed_dbs_child_) 632 return indexed_dbs_child_; 633 indexed_dbs_child_ = new CookieTreeIndexedDBsNode; 634 AddChildSortedByTitle(indexed_dbs_child_); 635 return indexed_dbs_child_; 636} 637 638CookieTreeFileSystemsNode* CookieTreeHostNode::GetOrCreateFileSystemsNode() { 639 if (file_systems_child_) 640 return file_systems_child_; 641 file_systems_child_ = new CookieTreeFileSystemsNode; 642 AddChildSortedByTitle(file_systems_child_); 643 return file_systems_child_; 644} 645 646CookieTreeQuotaNode* CookieTreeHostNode::UpdateOrCreateQuotaNode( 647 std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info) { 648 if (quota_child_) 649 return quota_child_; 650 quota_child_ = new CookieTreeQuotaNode(quota_info); 651 AddChildSortedByTitle(quota_child_); 652 return quota_child_; 653} 654 655CookieTreeServerBoundCertsNode* 656CookieTreeHostNode::GetOrCreateServerBoundCertsNode() { 657 if (server_bound_certs_child_) 658 return server_bound_certs_child_; 659 server_bound_certs_child_ = new CookieTreeServerBoundCertsNode; 660 AddChildSortedByTitle(server_bound_certs_child_); 661 return server_bound_certs_child_; 662} 663 664CookieTreeFlashLSONode* CookieTreeHostNode::GetOrCreateFlashLSONode( 665 const std::string& domain) { 666 DCHECK_EQ(GetHost(), domain); 667 if (flash_lso_child_) 668 return flash_lso_child_; 669 flash_lso_child_ = new CookieTreeFlashLSONode(domain); 670 AddChildSortedByTitle(flash_lso_child_); 671 return flash_lso_child_; 672} 673 674void CookieTreeHostNode::CreateContentException( 675 CookieSettings* cookie_settings, ContentSetting setting) const { 676 DCHECK(setting == CONTENT_SETTING_ALLOW || 677 setting == CONTENT_SETTING_BLOCK || 678 setting == CONTENT_SETTING_SESSION_ONLY); 679 if (CanCreateContentException()) { 680 cookie_settings->ResetCookieSetting( 681 ContentSettingsPattern::FromURLNoWildcard(url_), 682 ContentSettingsPattern::Wildcard()); 683 cookie_settings->SetCookieSetting( 684 ContentSettingsPattern::FromURL(url_), 685 ContentSettingsPattern::Wildcard(), setting); 686 } 687} 688 689bool CookieTreeHostNode::CanCreateContentException() const { 690 return !url_.SchemeIsFile(); 691} 692 693/////////////////////////////////////////////////////////////////////////////// 694// CookieTreeCookiesNode, public: 695 696CookieTreeCookiesNode::CookieTreeCookiesNode() 697 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES)) { 698} 699 700CookieTreeCookiesNode::~CookieTreeCookiesNode() { 701} 702 703CookieTreeNode::DetailedInfo CookieTreeCookiesNode::GetDetailedInfo() const { 704 return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES); 705} 706 707/////////////////////////////////////////////////////////////////////////////// 708// CookieTreeAppCachesNode, public: 709 710CookieTreeAppCachesNode::CookieTreeAppCachesNode() 711 : CookieTreeNode(l10n_util::GetStringUTF16( 712 IDS_COOKIES_APPLICATION_CACHES)) { 713} 714 715CookieTreeAppCachesNode::~CookieTreeAppCachesNode() {} 716 717CookieTreeNode::DetailedInfo CookieTreeAppCachesNode::GetDetailedInfo() const { 718 return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES); 719} 720 721/////////////////////////////////////////////////////////////////////////////// 722// CookieTreeDatabasesNode, public: 723 724CookieTreeDatabasesNode::CookieTreeDatabasesNode() 725 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES)) { 726} 727 728CookieTreeDatabasesNode::~CookieTreeDatabasesNode() {} 729 730CookieTreeNode::DetailedInfo CookieTreeDatabasesNode::GetDetailedInfo() const { 731 return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES); 732} 733 734/////////////////////////////////////////////////////////////////////////////// 735// CookieTreeLocalStoragesNode, public: 736 737CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode() 738 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE)) { 739} 740 741CookieTreeLocalStoragesNode::~CookieTreeLocalStoragesNode() {} 742 743CookieTreeNode::DetailedInfo 744CookieTreeLocalStoragesNode::GetDetailedInfo() const { 745 return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES); 746} 747 748/////////////////////////////////////////////////////////////////////////////// 749// CookieTreeSessionStoragesNode, public: 750 751CookieTreeSessionStoragesNode::CookieTreeSessionStoragesNode() 752 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE)) { 753} 754 755CookieTreeSessionStoragesNode::~CookieTreeSessionStoragesNode() {} 756 757CookieTreeNode::DetailedInfo 758CookieTreeSessionStoragesNode::GetDetailedInfo() const { 759 return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES); 760} 761 762/////////////////////////////////////////////////////////////////////////////// 763// CookieTreeIndexedDBsNode, public: 764 765CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode() 766 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS)) { 767} 768 769CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {} 770 771CookieTreeNode::DetailedInfo 772CookieTreeIndexedDBsNode::GetDetailedInfo() const { 773 return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS); 774} 775 776/////////////////////////////////////////////////////////////////////////////// 777// CookieTreeFileSystemsNode, public: 778 779CookieTreeFileSystemsNode::CookieTreeFileSystemsNode() 780 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS)) { 781} 782 783CookieTreeFileSystemsNode::~CookieTreeFileSystemsNode() {} 784 785CookieTreeNode::DetailedInfo 786CookieTreeFileSystemsNode::GetDetailedInfo() const { 787 return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS); 788} 789 790/////////////////////////////////////////////////////////////////////////////// 791// CookieTreeServerBoundCertsNode, public: 792 793CookieTreeServerBoundCertsNode::CookieTreeServerBoundCertsNode() 794 : CookieTreeNode( 795 l10n_util::GetStringUTF16(IDS_COOKIES_SERVER_BOUND_CERTS)) { 796} 797 798CookieTreeServerBoundCertsNode::~CookieTreeServerBoundCertsNode() {} 799 800CookieTreeNode::DetailedInfo 801CookieTreeServerBoundCertsNode::GetDetailedInfo() const { 802 return DetailedInfo().Init(DetailedInfo::TYPE_SERVER_BOUND_CERTS); 803} 804 805void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode* new_child) { 806 DCHECK(new_child); 807 std::vector<CookieTreeNode*>::iterator iter = 808 std::lower_bound(children().begin(), children().end(), new_child, 809 NodeTitleComparator()); 810 GetModel()->Add(this, new_child, iter - children().begin()); 811} 812 813/////////////////////////////////////////////////////////////////////////////// 814// CookieTreeFlashLSONode 815CookieTreeFlashLSONode::CookieTreeFlashLSONode( 816 const std::string& domain) 817 : domain_(domain) {} 818CookieTreeFlashLSONode::~CookieTreeFlashLSONode() {} 819 820void CookieTreeFlashLSONode::DeleteStoredObjects() { 821 // We are one level below the host node. 822 CookieTreeHostNode* host = static_cast<CookieTreeHostNode*>(parent()); 823 CHECK_EQ(host->GetDetailedInfo().node_type, 824 CookieTreeNode::DetailedInfo::TYPE_HOST); 825 LocalDataContainer* container = GetModel()->data_container(); 826 CHECK(container); 827 828 container->flash_lso_helper_->DeleteFlashLSOsForSite(domain_); 829} 830 831CookieTreeNode::DetailedInfo CookieTreeFlashLSONode::GetDetailedInfo() const { 832 return DetailedInfo().InitFlashLSO(domain_); 833} 834 835/////////////////////////////////////////////////////////////////////////////// 836// ScopedBatchUpdateNotifier 837CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier( 838 CookiesTreeModel* model, CookieTreeNode* node) 839 : model_(model), node_(node), batch_in_progress_(false) { 840} 841 842CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() { 843 if (batch_in_progress_) { 844 model_->NotifyObserverTreeNodeChanged(node_); 845 model_->NotifyObserverEndBatch(); 846 } 847} 848 849void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() { 850 if (!batch_in_progress_) { 851 model_->NotifyObserverBeginBatch(); 852 batch_in_progress_ = true; 853 } 854} 855 856/////////////////////////////////////////////////////////////////////////////// 857// CookiesTreeModel, public: 858CookiesTreeModel::CookiesTreeModel( 859 LocalDataContainer* data_container, 860 ExtensionSpecialStoragePolicy* special_storage_policy, 861 bool group_by_cookie_source) 862 : ui::TreeNodeModel<CookieTreeNode>(new CookieTreeRootNode(this)), 863 data_container_(data_container), 864 special_storage_policy_(special_storage_policy), 865 group_by_cookie_source_(group_by_cookie_source), 866 batch_update_(0) { 867 data_container_->Init(this); 868} 869 870CookiesTreeModel::~CookiesTreeModel() { 871} 872 873/////////////////////////////////////////////////////////////////////////////// 874// CookiesTreeModel, TreeModel methods (public): 875 876// TreeModel methods: 877// Returns the set of icons for the nodes in the tree. You only need override 878// this if you don't want to use the default folder icons. 879void CookiesTreeModel::GetIcons(std::vector<gfx::ImageSkia>* icons) { 880 icons->push_back(*ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 881 IDR_DEFAULT_FAVICON)); 882 icons->push_back(*ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 883 IDR_COOKIE_ICON)); 884 icons->push_back(*ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 885 IDR_COOKIE_STORAGE_ICON)); 886} 887 888// Returns the index of the icon to use for |node|. Return -1 to use the 889// default icon. The index is relative to the list of icons returned from 890// GetIcons. 891int CookiesTreeModel::GetIconIndex(ui::TreeModelNode* node) { 892 CookieTreeNode* ct_node = static_cast<CookieTreeNode*>(node); 893 switch (ct_node->GetDetailedInfo().node_type) { 894 case CookieTreeNode::DetailedInfo::TYPE_HOST: 895 return ORIGIN; 896 case CookieTreeNode::DetailedInfo::TYPE_COOKIE: 897 return COOKIE; 898 case CookieTreeNode::DetailedInfo::TYPE_DATABASE: 899 return DATABASE; 900 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: 901 return DATABASE; // close enough 902 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE: 903 return DATABASE; // ditto 904 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE: 905 return DATABASE; // ditto 906 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB: 907 return DATABASE; // ditto 908 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM: 909 return DATABASE; // ditto 910 case CookieTreeNode::DetailedInfo::TYPE_QUOTA: 911 return -1; 912 case CookieTreeNode::DetailedInfo::TYPE_SERVER_BOUND_CERT: 913 return COOKIE; // It's kinda like a cookie? 914 default: 915 break; 916 } 917 return -1; 918} 919 920void CookiesTreeModel::DeleteAllStoredObjects() { 921 NotifyObserverBeginBatch(); 922 CookieTreeNode* root = GetRoot(); 923 root->DeleteStoredObjects(); 924 int num_children = root->child_count(); 925 for (int i = num_children - 1; i >= 0; --i) 926 delete Remove(root, root->GetChild(i)); 927 NotifyObserverTreeNodeChanged(root); 928 NotifyObserverEndBatch(); 929} 930 931void CookiesTreeModel::DeleteCookieNode(CookieTreeNode* cookie_node) { 932 if (cookie_node == GetRoot()) 933 return; 934 cookie_node->DeleteStoredObjects(); 935 CookieTreeNode* parent_node = cookie_node->parent(); 936 delete Remove(parent_node, cookie_node); 937 if (parent_node->empty()) 938 DeleteCookieNode(parent_node); 939} 940 941void CookiesTreeModel::UpdateSearchResults(const string16& filter) { 942 CookieTreeNode* root = GetRoot(); 943 ScopedBatchUpdateNotifier notifier(this, root); 944 int num_children = root->child_count(); 945 notifier.StartBatchUpdate(); 946 for (int i = num_children - 1; i >= 0; --i) 947 delete Remove(root, root->GetChild(i)); 948 949 PopulateCookieInfoWithFilter(data_container(), ¬ifier, filter); 950 PopulateDatabaseInfoWithFilter(data_container(), ¬ifier, filter); 951 PopulateLocalStorageInfoWithFilter(data_container(), ¬ifier, filter); 952 PopulateSessionStorageInfoWithFilter(data_container(), ¬ifier, filter); 953 PopulateAppCacheInfoWithFilter(data_container(), ¬ifier, filter); 954 PopulateIndexedDBInfoWithFilter(data_container(), ¬ifier, filter); 955 PopulateFileSystemInfoWithFilter(data_container(), ¬ifier, filter); 956 PopulateQuotaInfoWithFilter(data_container(), ¬ifier, filter); 957 PopulateServerBoundCertInfoWithFilter(data_container(), ¬ifier, filter); 958} 959 960const ExtensionSet* CookiesTreeModel::ExtensionsProtectingNode( 961 const CookieTreeNode& cookie_node) { 962 if (!special_storage_policy_.get()) 963 return NULL; 964 965 CookieTreeNode::DetailedInfo info = cookie_node.GetDetailedInfo(); 966 967 if (!TypeIsProtected(info.node_type)) 968 return NULL; 969 970 DCHECK(!info.origin.is_empty()); 971 return special_storage_policy_->ExtensionsProtectingOrigin(info.origin); 972} 973 974void CookiesTreeModel::AddCookiesTreeObserver(Observer* observer) { 975 cookies_observer_list_.AddObserver(observer); 976 // Call super so that TreeNodeModel can notify, too. 977 ui::TreeNodeModel<CookieTreeNode>::AddObserver(observer); 978} 979 980void CookiesTreeModel::RemoveCookiesTreeObserver(Observer* observer) { 981 cookies_observer_list_.RemoveObserver(observer); 982 // Call super so that TreeNodeModel doesn't have dead pointers. 983 ui::TreeNodeModel<CookieTreeNode>::RemoveObserver(observer); 984} 985 986void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer* container) { 987 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 988 PopulateAppCacheInfoWithFilter(container, ¬ifier, string16()); 989} 990 991void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer* container) { 992 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 993 PopulateCookieInfoWithFilter(container, ¬ifier, string16()); 994} 995 996void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer* container) { 997 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 998 PopulateDatabaseInfoWithFilter(container, ¬ifier, string16()); 999} 1000 1001void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer* container) { 1002 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1003 PopulateLocalStorageInfoWithFilter(container, ¬ifier, string16()); 1004} 1005 1006void CookiesTreeModel::PopulateSessionStorageInfo( 1007 LocalDataContainer* container) { 1008 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1009 PopulateSessionStorageInfoWithFilter(container, ¬ifier, string16()); 1010} 1011 1012void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer* container){ 1013 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1014 PopulateIndexedDBInfoWithFilter(container, ¬ifier, string16()); 1015} 1016 1017void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer* container) { 1018 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1019 PopulateFileSystemInfoWithFilter(container, ¬ifier, string16()); 1020} 1021 1022void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer* container) { 1023 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1024 PopulateQuotaInfoWithFilter(container, ¬ifier, string16()); 1025} 1026 1027void CookiesTreeModel::PopulateServerBoundCertInfo( 1028 LocalDataContainer* container) { 1029 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1030 PopulateServerBoundCertInfoWithFilter(container, ¬ifier, string16()); 1031} 1032 1033void CookiesTreeModel::PopulateFlashLSOInfo( 1034 LocalDataContainer* container) { 1035 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1036 PopulateFlashLSOInfoWithFilter(container, ¬ifier, string16()); 1037} 1038 1039void CookiesTreeModel::PopulateAppCacheInfoWithFilter( 1040 LocalDataContainer* container, 1041 ScopedBatchUpdateNotifier* notifier, 1042 const string16& filter) { 1043 using appcache::AppCacheInfo; 1044 typedef std::map<GURL, std::list<AppCacheInfo> > InfoByOrigin; 1045 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); 1046 1047 if (container->appcache_info_.empty()) 1048 return; 1049 1050 notifier->StartBatchUpdate(); 1051 for (InfoByOrigin::iterator origin = container->appcache_info_.begin(); 1052 origin != container->appcache_info_.end(); ++origin) { 1053 string16 host_node_name = UTF8ToUTF16(origin->first.host()); 1054 if (filter.empty() || 1055 (host_node_name.find(filter) != string16::npos)) { 1056 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin->first); 1057 CookieTreeAppCachesNode* appcaches_node = 1058 host_node->GetOrCreateAppCachesNode(); 1059 1060 for (std::list<AppCacheInfo>::iterator info = origin->second.begin(); 1061 info != origin->second.end(); ++info) { 1062 appcaches_node->AddAppCacheNode( 1063 new CookieTreeAppCacheNode(origin->first, info)); 1064 } 1065 } 1066 } 1067} 1068 1069void CookiesTreeModel::PopulateCookieInfoWithFilter( 1070 LocalDataContainer* container, 1071 ScopedBatchUpdateNotifier* notifier, 1072 const string16& filter) { 1073 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); 1074 1075 notifier->StartBatchUpdate(); 1076 for (CookieList::iterator it = container->cookie_list_.begin(); 1077 it != container->cookie_list_.end(); ++it) { 1078 std::string source_string = it->Source(); 1079 if (source_string.empty() || !group_by_cookie_source_) { 1080 std::string domain = it->Domain(); 1081 if (domain.length() > 1 && domain[0] == '.') 1082 domain = domain.substr(1); 1083 1084 // We treat secure cookies just the same as normal ones. 1085 source_string = std::string(chrome::kHttpScheme) + 1086 content::kStandardSchemeSeparator + domain + "/"; 1087 } 1088 1089 GURL source(source_string); 1090 if (!filter.size() || 1091 (CookieTreeHostNode::TitleForUrl(source).find(filter) != 1092 string16::npos)) { 1093 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(source); 1094 CookieTreeCookiesNode* cookies_node = 1095 host_node->GetOrCreateCookiesNode(); 1096 CookieTreeCookieNode* new_cookie = new CookieTreeCookieNode(it); 1097 cookies_node->AddCookieNode(new_cookie); 1098 } 1099 } 1100} 1101 1102void CookiesTreeModel::PopulateDatabaseInfoWithFilter( 1103 LocalDataContainer* container, 1104 ScopedBatchUpdateNotifier* notifier, 1105 const string16& filter) { 1106 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); 1107 1108 if (container->database_info_list_.empty()) 1109 return; 1110 1111 notifier->StartBatchUpdate(); 1112 for (DatabaseInfoList::iterator database_info = 1113 container->database_info_list_.begin(); 1114 database_info != container->database_info_list_.end(); 1115 ++database_info) { 1116 GURL origin(database_info->identifier.ToOrigin()); 1117 1118 if (!filter.size() || 1119 (CookieTreeHostNode::TitleForUrl(origin).find(filter) != 1120 string16::npos)) { 1121 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); 1122 CookieTreeDatabasesNode* databases_node = 1123 host_node->GetOrCreateDatabasesNode(); 1124 databases_node->AddDatabaseNode( 1125 new CookieTreeDatabaseNode(database_info)); 1126 } 1127 } 1128} 1129 1130void CookiesTreeModel::PopulateLocalStorageInfoWithFilter( 1131 LocalDataContainer* container, 1132 ScopedBatchUpdateNotifier* notifier, 1133 const string16& filter) { 1134 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); 1135 1136 if (container->local_storage_info_list_.empty()) 1137 return; 1138 1139 notifier->StartBatchUpdate(); 1140 for (LocalStorageInfoList::iterator local_storage_info = 1141 container->local_storage_info_list_.begin(); 1142 local_storage_info != container->local_storage_info_list_.end(); 1143 ++local_storage_info) { 1144 const GURL& origin(local_storage_info->origin_url); 1145 1146 if (!filter.size() || 1147 (CookieTreeHostNode::TitleForUrl(origin).find(filter) != 1148 std::string::npos)) { 1149 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); 1150 CookieTreeLocalStoragesNode* local_storages_node = 1151 host_node->GetOrCreateLocalStoragesNode(); 1152 local_storages_node->AddLocalStorageNode( 1153 new CookieTreeLocalStorageNode(local_storage_info)); 1154 } 1155 } 1156} 1157 1158void CookiesTreeModel::PopulateSessionStorageInfoWithFilter( 1159 LocalDataContainer* container, 1160 ScopedBatchUpdateNotifier* notifier, 1161 const string16& filter) { 1162 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); 1163 1164 if (container->session_storage_info_list_.empty()) 1165 return; 1166 1167 notifier->StartBatchUpdate(); 1168 for (LocalStorageInfoList::iterator session_storage_info = 1169 container->session_storage_info_list_.begin(); 1170 session_storage_info != container->session_storage_info_list_.end(); 1171 ++session_storage_info) { 1172 const GURL& origin = session_storage_info->origin_url; 1173 1174 if (!filter.size() || 1175 (CookieTreeHostNode::TitleForUrl(origin).find(filter) != 1176 string16::npos)) { 1177 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); 1178 CookieTreeSessionStoragesNode* session_storages_node = 1179 host_node->GetOrCreateSessionStoragesNode(); 1180 session_storages_node->AddSessionStorageNode( 1181 new CookieTreeSessionStorageNode(session_storage_info)); 1182 } 1183 } 1184} 1185 1186void CookiesTreeModel::PopulateIndexedDBInfoWithFilter( 1187 LocalDataContainer* container, 1188 ScopedBatchUpdateNotifier* notifier, 1189 const string16& filter) { 1190 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); 1191 1192 if (container->indexed_db_info_list_.empty()) 1193 return; 1194 1195 notifier->StartBatchUpdate(); 1196 for (IndexedDBInfoList::iterator indexed_db_info = 1197 container->indexed_db_info_list_.begin(); 1198 indexed_db_info != container->indexed_db_info_list_.end(); 1199 ++indexed_db_info) { 1200 const GURL& origin = indexed_db_info->origin_; 1201 1202 if (!filter.size() || 1203 (CookieTreeHostNode::TitleForUrl(origin).find(filter) != 1204 string16::npos)) { 1205 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); 1206 CookieTreeIndexedDBsNode* indexed_dbs_node = 1207 host_node->GetOrCreateIndexedDBsNode(); 1208 indexed_dbs_node->AddIndexedDBNode( 1209 new CookieTreeIndexedDBNode(indexed_db_info)); 1210 } 1211 } 1212} 1213 1214void CookiesTreeModel::PopulateServerBoundCertInfoWithFilter( 1215 LocalDataContainer* container, 1216 ScopedBatchUpdateNotifier* notifier, 1217 const string16& filter) { 1218 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); 1219 1220 if (container->server_bound_cert_list_.empty()) 1221 return; 1222 1223 notifier->StartBatchUpdate(); 1224 for (ServerBoundCertList::iterator cert_info = 1225 container->server_bound_cert_list_.begin(); 1226 cert_info != container->server_bound_cert_list_.end(); 1227 ++cert_info) { 1228 GURL origin(cert_info->server_identifier()); 1229 if (!origin.is_valid()) { 1230 // Domain Bound Cert. Make a valid URL to satisfy the 1231 // CookieTreeRootNode::GetOrCreateHostNode interface. 1232 origin = GURL(std::string(chrome::kHttpsScheme) + 1233 content::kStandardSchemeSeparator + 1234 cert_info->server_identifier() + "/"); 1235 } 1236 string16 title = CookieTreeHostNode::TitleForUrl(origin); 1237 if (!filter.size() || title.find(filter) != string16::npos) { 1238 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); 1239 CookieTreeServerBoundCertsNode* server_bound_certs_node = 1240 host_node->GetOrCreateServerBoundCertsNode(); 1241 server_bound_certs_node->AddServerBoundCertNode( 1242 new CookieTreeServerBoundCertNode(cert_info)); 1243 } 1244 } 1245} 1246 1247void CookiesTreeModel::PopulateFileSystemInfoWithFilter( 1248 LocalDataContainer* container, 1249 ScopedBatchUpdateNotifier* notifier, 1250 const string16& filter) { 1251 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); 1252 1253 if (container->file_system_info_list_.empty()) 1254 return; 1255 1256 notifier->StartBatchUpdate(); 1257 for (FileSystemInfoList::iterator file_system_info = 1258 container->file_system_info_list_.begin(); 1259 file_system_info != container->file_system_info_list_.end(); 1260 ++file_system_info) { 1261 GURL origin(file_system_info->origin); 1262 1263 if (!filter.size() || 1264 (CookieTreeHostNode::TitleForUrl(origin).find(filter) != 1265 string16::npos)) { 1266 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); 1267 CookieTreeFileSystemsNode* file_systems_node = 1268 host_node->GetOrCreateFileSystemsNode(); 1269 file_systems_node->AddFileSystemNode( 1270 new CookieTreeFileSystemNode(file_system_info)); 1271 } 1272 } 1273} 1274 1275void CookiesTreeModel::PopulateQuotaInfoWithFilter( 1276 LocalDataContainer* container, 1277 ScopedBatchUpdateNotifier* notifier, 1278 const string16& filter) { 1279 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); 1280 1281 if (container->quota_info_list_.empty()) 1282 return; 1283 1284 notifier->StartBatchUpdate(); 1285 for (QuotaInfoList::iterator quota_info = container->quota_info_list_.begin(); 1286 quota_info != container->quota_info_list_.end(); 1287 ++quota_info) { 1288 if (!filter.size() || 1289 (UTF8ToUTF16(quota_info->host).find(filter) != string16::npos)) { 1290 CookieTreeHostNode* host_node = 1291 root->GetOrCreateHostNode(GURL("http://" + quota_info->host)); 1292 host_node->UpdateOrCreateQuotaNode(quota_info); 1293 } 1294 } 1295} 1296 1297void CookiesTreeModel::PopulateFlashLSOInfoWithFilter( 1298 LocalDataContainer* container, 1299 ScopedBatchUpdateNotifier* notifier, 1300 const string16& filter) { 1301 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); 1302 1303 if (container->flash_lso_domain_list_.empty()) 1304 return; 1305 1306 std::string filter_utf8 = UTF16ToUTF8(filter); 1307 notifier->StartBatchUpdate(); 1308 for (std::vector<std::string>::iterator it = 1309 container->flash_lso_domain_list_.begin(); 1310 it != container->flash_lso_domain_list_.end(); ++it) { 1311 if (!filter_utf8.size() || it->find(filter_utf8) != std::string::npos) { 1312 // Create a fake origin for GetOrCreateHostNode(). 1313 GURL origin("http://" + *it); 1314 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); 1315 host_node->GetOrCreateFlashLSONode(*it); 1316 } 1317 } 1318} 1319 1320void CookiesTreeModel::NotifyObserverBeginBatch() { 1321 // Only notify the model once if we're batching in a nested manner. 1322 if (batch_update_++ == 0) { 1323 FOR_EACH_OBSERVER(Observer, 1324 cookies_observer_list_, 1325 TreeModelBeginBatch(this)); 1326 } 1327} 1328 1329void CookiesTreeModel::NotifyObserverEndBatch() { 1330 // Only notify the observers if this is the outermost call to EndBatch() if 1331 // called in a nested manner. 1332 if (--batch_update_ == 0) { 1333 FOR_EACH_OBSERVER(Observer, 1334 cookies_observer_list_, 1335 TreeModelEndBatch(this)); 1336 } 1337} 1338