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 32 namespace { 33 34 struct 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. 41 struct 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 65 std::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 113 bool 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 145 LocalDataContainer* 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 155 CookieTreeNode::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 167 CookieTreeNode::DetailedInfo::~DetailedInfo() {} 168 169 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::Init( 170 NodeType type) { 171 DCHECK_EQ(TYPE_NONE, node_type); 172 node_type = type; 173 return *this; 174 } 175 176 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitHost() { 177 Init(TYPE_HOST); 178 return *this; 179 } 180 181 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitCookie( 182 const net::CanonicalCookie* cookie) { 183 Init(TYPE_COOKIE); 184 this->cookie = cookie; 185 return *this; 186 } 187 188 CookieTreeNode::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 196 CookieTreeNode::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 205 CookieTreeNode::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 214 CookieTreeNode::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 223 CookieTreeNode::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 231 CookieTreeNode::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 239 CookieTreeNode::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 246 CookieTreeNode::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 253 CookieTreeNode::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 263 void CookieTreeNode::DeleteStoredObjects() { 264 std::for_each(children().begin(), 265 children().end(), 266 std::mem_fun(&CookieTreeNode::DeleteStoredObjects)); 267 } 268 269 CookiesTreeModel* CookieTreeNode::GetModel() const { 270 if (parent()) 271 return parent()->GetModel(); 272 else 273 return NULL; 274 } 275 276 /////////////////////////////////////////////////////////////////////////////// 277 // CookieTreeCookieNode, public: 278 279 CookieTreeCookieNode::CookieTreeCookieNode( 280 std::list<net::CanonicalCookie>::iterator cookie) 281 : CookieTreeNode(UTF8ToUTF16(cookie->Name())), 282 cookie_(cookie) { 283 } 284 285 CookieTreeCookieNode::~CookieTreeCookieNode() {} 286 287 void CookieTreeCookieNode::DeleteStoredObjects() { 288 LocalDataContainer* container = GetLocalDataContainerForNode(this); 289 CHECK(container); 290 container->cookie_helper_->DeleteCookie(*cookie_); 291 container->cookie_list_.erase(cookie_); 292 } 293 294 CookieTreeNode::DetailedInfo CookieTreeCookieNode::GetDetailedInfo() const { 295 return DetailedInfo().InitCookie(&*cookie_); 296 } 297 298 /////////////////////////////////////////////////////////////////////////////// 299 // CookieTreeAppCacheNode, public: 300 301 CookieTreeAppCacheNode::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 309 CookieTreeAppCacheNode::~CookieTreeAppCacheNode() { 310 } 311 312 void 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 323 CookieTreeNode::DetailedInfo CookieTreeAppCacheNode::GetDetailedInfo() const { 324 return DetailedInfo().InitAppCache(origin_url_, &*appcache_info_); 325 } 326 327 /////////////////////////////////////////////////////////////////////////////// 328 // CookieTreeDatabaseNode, public: 329 330 CookieTreeDatabaseNode::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 338 CookieTreeDatabaseNode::~CookieTreeDatabaseNode() {} 339 340 void 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 350 CookieTreeNode::DetailedInfo CookieTreeDatabaseNode::GetDetailedInfo() const { 351 return DetailedInfo().InitDatabase(&*database_info_); 352 } 353 354 /////////////////////////////////////////////////////////////////////////////// 355 // CookieTreeLocalStorageNode, public: 356 357 CookieTreeLocalStorageNode::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 364 CookieTreeLocalStorageNode::~CookieTreeLocalStorageNode() {} 365 366 void 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 376 CookieTreeNode::DetailedInfo 377 CookieTreeLocalStorageNode::GetDetailedInfo() const { 378 return DetailedInfo().InitLocalStorage( 379 &*local_storage_info_); 380 } 381 382 /////////////////////////////////////////////////////////////////////////////// 383 // CookieTreeSessionStorageNode, public: 384 385 CookieTreeSessionStorageNode::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 392 CookieTreeSessionStorageNode::~CookieTreeSessionStorageNode() {} 393 394 void CookieTreeSessionStorageNode::DeleteStoredObjects() { 395 LocalDataContainer* container = GetLocalDataContainerForNode(this); 396 397 if (container) { 398 container->session_storage_info_list_.erase(session_storage_info_); 399 } 400 } 401 402 CookieTreeNode::DetailedInfo 403 CookieTreeSessionStorageNode::GetDetailedInfo() const { 404 return DetailedInfo().InitSessionStorage(&*session_storage_info_); 405 } 406 407 /////////////////////////////////////////////////////////////////////////////// 408 // CookieTreeIndexedDBNode, public: 409 410 CookieTreeIndexedDBNode::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 418 CookieTreeIndexedDBNode::~CookieTreeIndexedDBNode() {} 419 420 void 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 430 CookieTreeNode::DetailedInfo CookieTreeIndexedDBNode::GetDetailedInfo() const { 431 return DetailedInfo().InitIndexedDB(&*indexed_db_info_); 432 } 433 434 /////////////////////////////////////////////////////////////////////////////// 435 // CookieTreeFileSystemNode, public: 436 437 CookieTreeFileSystemNode::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 445 CookieTreeFileSystemNode::~CookieTreeFileSystemNode() {} 446 447 void 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 457 CookieTreeNode::DetailedInfo CookieTreeFileSystemNode::GetDetailedInfo() const { 458 return DetailedInfo().InitFileSystem(&*file_system_info_); 459 } 460 461 /////////////////////////////////////////////////////////////////////////////// 462 // CookieTreeQuotaNode, public: 463 464 CookieTreeQuotaNode::CookieTreeQuotaNode( 465 std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info) 466 : CookieTreeNode(UTF8ToUTF16(quota_info->host)), 467 quota_info_(quota_info) { 468 } 469 470 CookieTreeQuotaNode::~CookieTreeQuotaNode() {} 471 472 void 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 483 CookieTreeNode::DetailedInfo CookieTreeQuotaNode::GetDetailedInfo() const { 484 return DetailedInfo().InitQuota(&*quota_info_); 485 } 486 487 /////////////////////////////////////////////////////////////////////////////// 488 // CookieTreeServerBoundCertNode, public: 489 490 CookieTreeServerBoundCertNode::CookieTreeServerBoundCertNode( 491 net::ServerBoundCertStore::ServerBoundCertList::iterator cert) 492 : CookieTreeNode(ASCIIToUTF16(cert->server_identifier())), 493 server_bound_cert_(cert) { 494 } 495 496 CookieTreeServerBoundCertNode::~CookieTreeServerBoundCertNode() {} 497 498 void 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 508 CookieTreeNode::DetailedInfo 509 CookieTreeServerBoundCertNode::GetDetailedInfo() const { 510 return DetailedInfo().InitServerBoundCert(&*server_bound_cert_); 511 } 512 513 /////////////////////////////////////////////////////////////////////////////// 514 // CookieTreeRootNode, public: 515 516 CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel* model) 517 : model_(model) { 518 } 519 520 CookieTreeRootNode::~CookieTreeRootNode() {} 521 522 CookieTreeHostNode* 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 542 CookiesTreeModel* CookieTreeRootNode::GetModel() const { 543 return model_; 544 } 545 546 CookieTreeNode::DetailedInfo CookieTreeRootNode::GetDetailedInfo() const { 547 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT); 548 } 549 550 /////////////////////////////////////////////////////////////////////////////// 551 // CookieTreeHostNode, public: 552 553 // static 554 string16 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 561 CookieTreeHostNode::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 576 CookieTreeHostNode::~CookieTreeHostNode() {} 577 578 const 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 584 CookieTreeNode::DetailedInfo CookieTreeHostNode::GetDetailedInfo() const { 585 return DetailedInfo().InitHost(); 586 } 587 588 CookieTreeCookiesNode* 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 596 CookieTreeDatabasesNode* 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 604 CookieTreeLocalStoragesNode* 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 613 CookieTreeSessionStoragesNode* 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 622 CookieTreeAppCachesNode* 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 630 CookieTreeIndexedDBsNode* 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 638 CookieTreeFileSystemsNode* 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 646 CookieTreeQuotaNode* 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 655 CookieTreeServerBoundCertsNode* 656 CookieTreeHostNode::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 664 CookieTreeFlashLSONode* 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 674 void 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 689 bool CookieTreeHostNode::CanCreateContentException() const { 690 return !url_.SchemeIsFile(); 691 } 692 693 /////////////////////////////////////////////////////////////////////////////// 694 // CookieTreeCookiesNode, public: 695 696 CookieTreeCookiesNode::CookieTreeCookiesNode() 697 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES)) { 698 } 699 700 CookieTreeCookiesNode::~CookieTreeCookiesNode() { 701 } 702 703 CookieTreeNode::DetailedInfo CookieTreeCookiesNode::GetDetailedInfo() const { 704 return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES); 705 } 706 707 /////////////////////////////////////////////////////////////////////////////// 708 // CookieTreeAppCachesNode, public: 709 710 CookieTreeAppCachesNode::CookieTreeAppCachesNode() 711 : CookieTreeNode(l10n_util::GetStringUTF16( 712 IDS_COOKIES_APPLICATION_CACHES)) { 713 } 714 715 CookieTreeAppCachesNode::~CookieTreeAppCachesNode() {} 716 717 CookieTreeNode::DetailedInfo CookieTreeAppCachesNode::GetDetailedInfo() const { 718 return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES); 719 } 720 721 /////////////////////////////////////////////////////////////////////////////// 722 // CookieTreeDatabasesNode, public: 723 724 CookieTreeDatabasesNode::CookieTreeDatabasesNode() 725 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES)) { 726 } 727 728 CookieTreeDatabasesNode::~CookieTreeDatabasesNode() {} 729 730 CookieTreeNode::DetailedInfo CookieTreeDatabasesNode::GetDetailedInfo() const { 731 return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES); 732 } 733 734 /////////////////////////////////////////////////////////////////////////////// 735 // CookieTreeLocalStoragesNode, public: 736 737 CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode() 738 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE)) { 739 } 740 741 CookieTreeLocalStoragesNode::~CookieTreeLocalStoragesNode() {} 742 743 CookieTreeNode::DetailedInfo 744 CookieTreeLocalStoragesNode::GetDetailedInfo() const { 745 return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES); 746 } 747 748 /////////////////////////////////////////////////////////////////////////////// 749 // CookieTreeSessionStoragesNode, public: 750 751 CookieTreeSessionStoragesNode::CookieTreeSessionStoragesNode() 752 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE)) { 753 } 754 755 CookieTreeSessionStoragesNode::~CookieTreeSessionStoragesNode() {} 756 757 CookieTreeNode::DetailedInfo 758 CookieTreeSessionStoragesNode::GetDetailedInfo() const { 759 return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES); 760 } 761 762 /////////////////////////////////////////////////////////////////////////////// 763 // CookieTreeIndexedDBsNode, public: 764 765 CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode() 766 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS)) { 767 } 768 769 CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {} 770 771 CookieTreeNode::DetailedInfo 772 CookieTreeIndexedDBsNode::GetDetailedInfo() const { 773 return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS); 774 } 775 776 /////////////////////////////////////////////////////////////////////////////// 777 // CookieTreeFileSystemsNode, public: 778 779 CookieTreeFileSystemsNode::CookieTreeFileSystemsNode() 780 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS)) { 781 } 782 783 CookieTreeFileSystemsNode::~CookieTreeFileSystemsNode() {} 784 785 CookieTreeNode::DetailedInfo 786 CookieTreeFileSystemsNode::GetDetailedInfo() const { 787 return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS); 788 } 789 790 /////////////////////////////////////////////////////////////////////////////// 791 // CookieTreeServerBoundCertsNode, public: 792 793 CookieTreeServerBoundCertsNode::CookieTreeServerBoundCertsNode() 794 : CookieTreeNode( 795 l10n_util::GetStringUTF16(IDS_COOKIES_SERVER_BOUND_CERTS)) { 796 } 797 798 CookieTreeServerBoundCertsNode::~CookieTreeServerBoundCertsNode() {} 799 800 CookieTreeNode::DetailedInfo 801 CookieTreeServerBoundCertsNode::GetDetailedInfo() const { 802 return DetailedInfo().Init(DetailedInfo::TYPE_SERVER_BOUND_CERTS); 803 } 804 805 void 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 815 CookieTreeFlashLSONode::CookieTreeFlashLSONode( 816 const std::string& domain) 817 : domain_(domain) {} 818 CookieTreeFlashLSONode::~CookieTreeFlashLSONode() {} 819 820 void 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 831 CookieTreeNode::DetailedInfo CookieTreeFlashLSONode::GetDetailedInfo() const { 832 return DetailedInfo().InitFlashLSO(domain_); 833 } 834 835 /////////////////////////////////////////////////////////////////////////////// 836 // ScopedBatchUpdateNotifier 837 CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier( 838 CookiesTreeModel* model, CookieTreeNode* node) 839 : model_(model), node_(node), batch_in_progress_(false) { 840 } 841 842 CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() { 843 if (batch_in_progress_) { 844 model_->NotifyObserverTreeNodeChanged(node_); 845 model_->NotifyObserverEndBatch(); 846 } 847 } 848 849 void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() { 850 if (!batch_in_progress_) { 851 model_->NotifyObserverBeginBatch(); 852 batch_in_progress_ = true; 853 } 854 } 855 856 /////////////////////////////////////////////////////////////////////////////// 857 // CookiesTreeModel, public: 858 CookiesTreeModel::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 870 CookiesTreeModel::~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. 879 void 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. 891 int 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 920 void 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 931 void 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 941 void 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 960 const 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 974 void 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 980 void 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 986 void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer* container) { 987 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 988 PopulateAppCacheInfoWithFilter(container, ¬ifier, string16()); 989 } 990 991 void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer* container) { 992 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 993 PopulateCookieInfoWithFilter(container, ¬ifier, string16()); 994 } 995 996 void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer* container) { 997 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 998 PopulateDatabaseInfoWithFilter(container, ¬ifier, string16()); 999 } 1000 1001 void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer* container) { 1002 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1003 PopulateLocalStorageInfoWithFilter(container, ¬ifier, string16()); 1004 } 1005 1006 void CookiesTreeModel::PopulateSessionStorageInfo( 1007 LocalDataContainer* container) { 1008 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1009 PopulateSessionStorageInfoWithFilter(container, ¬ifier, string16()); 1010 } 1011 1012 void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer* container){ 1013 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1014 PopulateIndexedDBInfoWithFilter(container, ¬ifier, string16()); 1015 } 1016 1017 void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer* container) { 1018 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1019 PopulateFileSystemInfoWithFilter(container, ¬ifier, string16()); 1020 } 1021 1022 void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer* container) { 1023 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1024 PopulateQuotaInfoWithFilter(container, ¬ifier, string16()); 1025 } 1026 1027 void CookiesTreeModel::PopulateServerBoundCertInfo( 1028 LocalDataContainer* container) { 1029 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1030 PopulateServerBoundCertInfoWithFilter(container, ¬ifier, string16()); 1031 } 1032 1033 void CookiesTreeModel::PopulateFlashLSOInfo( 1034 LocalDataContainer* container) { 1035 ScopedBatchUpdateNotifier notifier(this, GetRoot()); 1036 PopulateFlashLSOInfoWithFilter(container, ¬ifier, string16()); 1037 } 1038 1039 void 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 1069 void 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 1102 void 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 1130 void 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 1158 void 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 1186 void 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 1214 void 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 1247 void 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 1275 void 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 1297 void 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 1320 void 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 1329 void 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