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.
5 #include "chrome/browser/browsing_data/cookies_tree_model.h"
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_channel_id_helper.h"
16 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
18 #include "chrome/browser/content_settings/cookie_settings.h"
19 #include "content/public/common/url_constants.h"
20 #include "grit/generated_resources.h"
21 #include "grit/theme_resources.h"
22 #include "grit/ui_resources.h"
23 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
24 #include "net/cookies/canonical_cookie.h"
25 #include "net/url_request/url_request_context.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/image/image_skia.h"
30 #if defined(ENABLE_EXTENSIONS)
31 #include "chrome/browser/extensions/extension_special_storage_policy.h"
32 #include "extensions/common/extension_set.h"
37 struct NodeTitleComparator
{
38 bool operator()(const CookieTreeNode
* lhs
, const CookieTreeNode
* rhs
) {
39 return lhs
->GetTitle() < rhs
->GetTitle();
43 // Comparison functor, for use in CookieTreeRootNode.
44 struct HostNodeComparator
{
45 bool operator()(const CookieTreeNode
* lhs
, const CookieTreeNode
* rhs
) {
46 // This comparator is only meant to compare CookieTreeHostNode types. Make
47 // sure we check this, as the static cast below is dangerous if we get the
49 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST
,
50 lhs
->GetDetailedInfo().node_type
);
51 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST
,
52 rhs
->GetDetailedInfo().node_type
);
54 const CookieTreeHostNode
* ltn
=
55 static_cast<const CookieTreeHostNode
*>(lhs
);
56 const CookieTreeHostNode
* rtn
=
57 static_cast<const CookieTreeHostNode
*>(rhs
);
59 // We want to order by registry controlled domain, so we would get
60 // google.com, ad.google.com, www.google.com,
61 // microsoft.com, ad.microsoft.com. CanonicalizeHost transforms the origins
62 // into a form like google.com.www so that string comparisons work.
63 return (ltn
->canonicalized_host() <
64 rtn
->canonicalized_host());
68 std::string
CanonicalizeHost(const GURL
& url
) {
69 // The canonicalized representation makes the registry controlled domain
70 // come first, and then adds subdomains in reverse order, e.g.
71 // 1.mail.google.com would become google.com.mail.1, and then a standard
72 // string comparison works to order hosts by registry controlled domain
73 // first. Leading dots are ignored, ".google.com" is the same as
76 if (url
.SchemeIsFile()) {
77 return std::string(url::kFileScheme
) +
78 url::kStandardSchemeSeparator
;
81 std::string host
= url
.host();
83 net::registry_controlled_domains::GetDomainAndRegistry(
85 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES
);
86 if (!retval
.length()) // Is an IP address or other special origin.
89 std::string::size_type position
= host
.rfind(retval
);
91 // The host may be the registry controlled domain, in which case fail fast.
92 if (position
== 0 || position
== std::string::npos
)
95 // If host is www.google.com, retval will contain google.com at this point.
96 // Start operating to the left of the registry controlled domain, e.g. in
97 // the www.google.com example, start at index 3.
100 // If position == 0, that means it's a dot; this will be ignored to treat
101 // ".google.com" the same as "google.com".
102 while (position
> 0) {
103 retval
+= std::string(".");
104 // Copy up to the next dot. host[position] is a dot so start after it.
105 std::string::size_type next_dot
= host
.rfind(".", position
- 1);
106 if (next_dot
== std::string::npos
) {
107 retval
+= host
.substr(0, position
);
110 retval
+= host
.substr(next_dot
+ 1, position
- (next_dot
+ 1));
116 #if defined(ENABLE_EXTENSIONS)
117 bool TypeIsProtected(CookieTreeNode::DetailedInfo::NodeType type
) {
119 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
121 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
123 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
125 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
127 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
129 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
131 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
133 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
135 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
137 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO
:
146 // This function returns the local data container associated with a leaf tree
147 // node. The app node is assumed to be 3 levels above the leaf because of the
148 // following structure:
149 // root -> origin -> storage type -> leaf node
150 LocalDataContainer
* GetLocalDataContainerForNode(CookieTreeNode
* node
) {
151 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(
152 node
->parent()->parent());
153 CHECK_EQ(host
->GetDetailedInfo().node_type
,
154 CookieTreeNode::DetailedInfo::TYPE_HOST
);
155 return node
->GetModel()->data_container();
160 CookieTreeNode::DetailedInfo::DetailedInfo()
161 : node_type(TYPE_NONE
),
164 local_storage_info(NULL
),
165 session_storage_info(NULL
),
167 indexed_db_info(NULL
),
168 file_system_info(NULL
),
172 CookieTreeNode::DetailedInfo::~DetailedInfo() {}
174 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::Init(
176 DCHECK_EQ(TYPE_NONE
, node_type
);
181 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitHost() {
186 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitCookie(
187 const net::CanonicalCookie
* cookie
) {
189 this->cookie
= cookie
;
193 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitDatabase(
194 const BrowsingDataDatabaseHelper::DatabaseInfo
* database_info
) {
196 this->database_info
= database_info
;
197 origin
= database_info
->identifier
.ToOrigin();
201 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitLocalStorage(
202 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
203 local_storage_info
) {
204 Init(TYPE_LOCAL_STORAGE
);
205 this->local_storage_info
= local_storage_info
;
206 origin
= local_storage_info
->origin_url
;
210 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitSessionStorage(
211 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
212 session_storage_info
) {
213 Init(TYPE_SESSION_STORAGE
);
214 this->session_storage_info
= session_storage_info
;
215 origin
= session_storage_info
->origin_url
;
219 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitAppCache(
221 const content::AppCacheInfo
* appcache_info
) {
223 this->appcache_info
= appcache_info
;
224 this->origin
= origin
;
228 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitIndexedDB(
229 const content::IndexedDBInfo
* indexed_db_info
) {
230 Init(TYPE_INDEXED_DB
);
231 this->indexed_db_info
= indexed_db_info
;
232 this->origin
= indexed_db_info
->origin_
;
236 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFileSystem(
237 const BrowsingDataFileSystemHelper::FileSystemInfo
* file_system_info
) {
238 Init(TYPE_FILE_SYSTEM
);
239 this->file_system_info
= file_system_info
;
240 this->origin
= file_system_info
->origin
;
244 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitQuota(
245 const BrowsingDataQuotaHelper::QuotaInfo
* quota_info
) {
247 this->quota_info
= quota_info
;
251 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitChannelID(
252 const net::ChannelIDStore::ChannelID
* channel_id
) {
253 Init(TYPE_CHANNEL_ID
);
254 this->channel_id
= channel_id
;
258 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFlashLSO(
259 const std::string
& flash_lso_domain
) {
260 Init(TYPE_FLASH_LSO
);
261 this->flash_lso_domain
= flash_lso_domain
;
265 ///////////////////////////////////////////////////////////////////////////////
266 // CookieTreeNode, public:
268 void CookieTreeNode::DeleteStoredObjects() {
269 std::for_each(children().begin(),
271 std::mem_fun(&CookieTreeNode::DeleteStoredObjects
));
274 CookiesTreeModel
* CookieTreeNode::GetModel() const {
276 return parent()->GetModel();
281 ///////////////////////////////////////////////////////////////////////////////
282 // CookieTreeCookieNode, public:
284 CookieTreeCookieNode::CookieTreeCookieNode(
285 std::list
<net::CanonicalCookie
>::iterator cookie
)
286 : CookieTreeNode(base::UTF8ToUTF16(cookie
->Name())),
290 CookieTreeCookieNode::~CookieTreeCookieNode() {}
292 void CookieTreeCookieNode::DeleteStoredObjects() {
293 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
295 container
->cookie_helper_
->DeleteCookie(*cookie_
);
296 container
->cookie_list_
.erase(cookie_
);
299 CookieTreeNode::DetailedInfo
CookieTreeCookieNode::GetDetailedInfo() const {
300 return DetailedInfo().InitCookie(&*cookie_
);
303 ///////////////////////////////////////////////////////////////////////////////
304 // CookieTreeAppCacheNode, public:
306 CookieTreeAppCacheNode::CookieTreeAppCacheNode(
307 const GURL
& origin_url
,
308 std::list
<content::AppCacheInfo
>::iterator appcache_info
)
309 : CookieTreeNode(base::UTF8ToUTF16(appcache_info
->manifest_url
.spec())),
310 origin_url_(origin_url
),
311 appcache_info_(appcache_info
) {
314 CookieTreeAppCacheNode::~CookieTreeAppCacheNode() {
317 void CookieTreeAppCacheNode::DeleteStoredObjects() {
318 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
321 DCHECK(container
->appcache_helper_
.get());
322 container
->appcache_helper_
323 ->DeleteAppCacheGroup(appcache_info_
->manifest_url
);
324 container
->appcache_info_
[origin_url_
].erase(appcache_info_
);
328 CookieTreeNode::DetailedInfo
CookieTreeAppCacheNode::GetDetailedInfo() const {
329 return DetailedInfo().InitAppCache(origin_url_
, &*appcache_info_
);
332 ///////////////////////////////////////////////////////////////////////////////
333 // CookieTreeDatabaseNode, public:
335 CookieTreeDatabaseNode::CookieTreeDatabaseNode(
336 std::list
<BrowsingDataDatabaseHelper::DatabaseInfo
>::iterator database_info
)
337 : CookieTreeNode(database_info
->database_name
.empty() ?
338 l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME
) :
339 base::UTF8ToUTF16(database_info
->database_name
)),
340 database_info_(database_info
) {
343 CookieTreeDatabaseNode::~CookieTreeDatabaseNode() {}
345 void CookieTreeDatabaseNode::DeleteStoredObjects() {
346 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
349 container
->database_helper_
->DeleteDatabase(
350 database_info_
->identifier
.ToString(), database_info_
->database_name
);
351 container
->database_info_list_
.erase(database_info_
);
355 CookieTreeNode::DetailedInfo
CookieTreeDatabaseNode::GetDetailedInfo() const {
356 return DetailedInfo().InitDatabase(&*database_info_
);
359 ///////////////////////////////////////////////////////////////////////////////
360 // CookieTreeLocalStorageNode, public:
362 CookieTreeLocalStorageNode::CookieTreeLocalStorageNode(
363 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
365 : CookieTreeNode(base::UTF8ToUTF16(local_storage_info
->origin_url
.spec())),
366 local_storage_info_(local_storage_info
) {
369 CookieTreeLocalStorageNode::~CookieTreeLocalStorageNode() {}
371 void CookieTreeLocalStorageNode::DeleteStoredObjects() {
372 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
375 container
->local_storage_helper_
->DeleteOrigin(
376 local_storage_info_
->origin_url
);
377 container
->local_storage_info_list_
.erase(local_storage_info_
);
381 CookieTreeNode::DetailedInfo
382 CookieTreeLocalStorageNode::GetDetailedInfo() const {
383 return DetailedInfo().InitLocalStorage(
384 &*local_storage_info_
);
387 ///////////////////////////////////////////////////////////////////////////////
388 // CookieTreeSessionStorageNode, public:
390 CookieTreeSessionStorageNode::CookieTreeSessionStorageNode(
391 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
392 session_storage_info
)
394 base::UTF8ToUTF16(session_storage_info
->origin_url
.spec())),
395 session_storage_info_(session_storage_info
) {
398 CookieTreeSessionStorageNode::~CookieTreeSessionStorageNode() {}
400 void CookieTreeSessionStorageNode::DeleteStoredObjects() {
401 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
404 // TODO(rsesek): There's no easy way to get the namespace_id for a session
405 // storage, nor is there an easy way to clear session storage just by
406 // origin. This is probably okay since session storage is not persistent.
407 // http://crbug.com/168996
408 container
->session_storage_info_list_
.erase(session_storage_info_
);
412 CookieTreeNode::DetailedInfo
413 CookieTreeSessionStorageNode::GetDetailedInfo() const {
414 return DetailedInfo().InitSessionStorage(&*session_storage_info_
);
417 ///////////////////////////////////////////////////////////////////////////////
418 // CookieTreeIndexedDBNode, public:
420 CookieTreeIndexedDBNode::CookieTreeIndexedDBNode(
421 std::list
<content::IndexedDBInfo
>::iterator
423 : CookieTreeNode(base::UTF8ToUTF16(
424 indexed_db_info
->origin_
.spec())),
425 indexed_db_info_(indexed_db_info
) {
428 CookieTreeIndexedDBNode::~CookieTreeIndexedDBNode() {}
430 void CookieTreeIndexedDBNode::DeleteStoredObjects() {
431 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
434 container
->indexed_db_helper_
->DeleteIndexedDB(
435 indexed_db_info_
->origin_
);
436 container
->indexed_db_info_list_
.erase(indexed_db_info_
);
440 CookieTreeNode::DetailedInfo
CookieTreeIndexedDBNode::GetDetailedInfo() const {
441 return DetailedInfo().InitIndexedDB(&*indexed_db_info_
);
444 ///////////////////////////////////////////////////////////////////////////////
445 // CookieTreeFileSystemNode, public:
447 CookieTreeFileSystemNode::CookieTreeFileSystemNode(
448 std::list
<BrowsingDataFileSystemHelper::FileSystemInfo
>::iterator
450 : CookieTreeNode(base::UTF8ToUTF16(
451 file_system_info
->origin
.spec())),
452 file_system_info_(file_system_info
) {
455 CookieTreeFileSystemNode::~CookieTreeFileSystemNode() {}
457 void CookieTreeFileSystemNode::DeleteStoredObjects() {
458 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
461 container
->file_system_helper_
->DeleteFileSystemOrigin(
462 file_system_info_
->origin
);
463 container
->file_system_info_list_
.erase(file_system_info_
);
467 CookieTreeNode::DetailedInfo
CookieTreeFileSystemNode::GetDetailedInfo() const {
468 return DetailedInfo().InitFileSystem(&*file_system_info_
);
471 ///////////////////////////////////////////////////////////////////////////////
472 // CookieTreeQuotaNode, public:
474 CookieTreeQuotaNode::CookieTreeQuotaNode(
475 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
)
476 : CookieTreeNode(base::UTF8ToUTF16(quota_info
->host
)),
477 quota_info_(quota_info
) {
480 CookieTreeQuotaNode::~CookieTreeQuotaNode() {}
482 void CookieTreeQuotaNode::DeleteStoredObjects() {
483 // Calling this function may cause unexpected over-quota state of origin.
484 // However, it'll caused no problem, just prevent usage growth of the origin.
485 LocalDataContainer
* container
= GetModel()->data_container();
488 container
->quota_helper_
->RevokeHostQuota(quota_info_
->host
);
489 container
->quota_info_list_
.erase(quota_info_
);
493 CookieTreeNode::DetailedInfo
CookieTreeQuotaNode::GetDetailedInfo() const {
494 return DetailedInfo().InitQuota(&*quota_info_
);
497 ///////////////////////////////////////////////////////////////////////////////
498 // CookieTreeChannelIDNode, public:
500 CookieTreeChannelIDNode::CookieTreeChannelIDNode(
501 net::ChannelIDStore::ChannelIDList::iterator channel_id
)
502 : CookieTreeNode(base::ASCIIToUTF16(channel_id
->server_identifier())),
503 channel_id_(channel_id
) {
506 CookieTreeChannelIDNode::~CookieTreeChannelIDNode() {}
508 void CookieTreeChannelIDNode::DeleteStoredObjects() {
509 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
512 container
->channel_id_helper_
->DeleteChannelID(
513 channel_id_
->server_identifier());
514 container
->channel_id_list_
.erase(channel_id_
);
518 CookieTreeNode::DetailedInfo
519 CookieTreeChannelIDNode::GetDetailedInfo() const {
520 return DetailedInfo().InitChannelID(&*channel_id_
);
523 ///////////////////////////////////////////////////////////////////////////////
524 // CookieTreeRootNode, public:
526 CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel
* model
)
530 CookieTreeRootNode::~CookieTreeRootNode() {}
532 CookieTreeHostNode
* CookieTreeRootNode::GetOrCreateHostNode(
534 scoped_ptr
<CookieTreeHostNode
> host_node(
535 new CookieTreeHostNode(url
));
537 // First see if there is an existing match.
538 std::vector
<CookieTreeNode
*>::iterator host_node_iterator
=
539 std::lower_bound(children().begin(), children().end(), host_node
.get(),
540 HostNodeComparator());
541 if (host_node_iterator
!= children().end() &&
542 CookieTreeHostNode::TitleForUrl(url
) ==
543 (*host_node_iterator
)->GetTitle())
544 return static_cast<CookieTreeHostNode
*>(*host_node_iterator
);
545 // Node doesn't exist, insert the new one into the (ordered) children.
547 model_
->Add(this, host_node
.get(),
548 (host_node_iterator
- children().begin()));
549 return host_node
.release();
552 CookiesTreeModel
* CookieTreeRootNode::GetModel() const {
556 CookieTreeNode::DetailedInfo
CookieTreeRootNode::GetDetailedInfo() const {
557 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT
);
560 ///////////////////////////////////////////////////////////////////////////////
561 // CookieTreeHostNode, public:
564 base::string16
CookieTreeHostNode::TitleForUrl(const GURL
& url
) {
565 const std::string
file_origin_node_name(
566 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
567 return base::UTF8ToUTF16(url
.SchemeIsFile() ? file_origin_node_name
571 CookieTreeHostNode::CookieTreeHostNode(const GURL
& url
)
572 : CookieTreeNode(TitleForUrl(url
)),
573 cookies_child_(NULL
),
574 databases_child_(NULL
),
575 local_storages_child_(NULL
),
576 session_storages_child_(NULL
),
577 appcaches_child_(NULL
),
578 indexed_dbs_child_(NULL
),
579 file_systems_child_(NULL
),
581 channel_ids_child_(NULL
),
582 flash_lso_child_(NULL
),
584 canonicalized_host_(CanonicalizeHost(url
)) {}
586 CookieTreeHostNode::~CookieTreeHostNode() {}
588 const std::string
CookieTreeHostNode::GetHost() const {
589 const std::string
file_origin_node_name(
590 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
591 return url_
.SchemeIsFile() ? file_origin_node_name
: url_
.host();
594 CookieTreeNode::DetailedInfo
CookieTreeHostNode::GetDetailedInfo() const {
595 return DetailedInfo().InitHost();
598 CookieTreeCookiesNode
* CookieTreeHostNode::GetOrCreateCookiesNode() {
600 return cookies_child_
;
601 cookies_child_
= new CookieTreeCookiesNode
;
602 AddChildSortedByTitle(cookies_child_
);
603 return cookies_child_
;
606 CookieTreeDatabasesNode
* CookieTreeHostNode::GetOrCreateDatabasesNode() {
607 if (databases_child_
)
608 return databases_child_
;
609 databases_child_
= new CookieTreeDatabasesNode
;
610 AddChildSortedByTitle(databases_child_
);
611 return databases_child_
;
614 CookieTreeLocalStoragesNode
*
615 CookieTreeHostNode::GetOrCreateLocalStoragesNode() {
616 if (local_storages_child_
)
617 return local_storages_child_
;
618 local_storages_child_
= new CookieTreeLocalStoragesNode
;
619 AddChildSortedByTitle(local_storages_child_
);
620 return local_storages_child_
;
623 CookieTreeSessionStoragesNode
*
624 CookieTreeHostNode::GetOrCreateSessionStoragesNode() {
625 if (session_storages_child_
)
626 return session_storages_child_
;
627 session_storages_child_
= new CookieTreeSessionStoragesNode
;
628 AddChildSortedByTitle(session_storages_child_
);
629 return session_storages_child_
;
632 CookieTreeAppCachesNode
* CookieTreeHostNode::GetOrCreateAppCachesNode() {
633 if (appcaches_child_
)
634 return appcaches_child_
;
635 appcaches_child_
= new CookieTreeAppCachesNode
;
636 AddChildSortedByTitle(appcaches_child_
);
637 return appcaches_child_
;
640 CookieTreeIndexedDBsNode
* CookieTreeHostNode::GetOrCreateIndexedDBsNode() {
641 if (indexed_dbs_child_
)
642 return indexed_dbs_child_
;
643 indexed_dbs_child_
= new CookieTreeIndexedDBsNode
;
644 AddChildSortedByTitle(indexed_dbs_child_
);
645 return indexed_dbs_child_
;
648 CookieTreeFileSystemsNode
* CookieTreeHostNode::GetOrCreateFileSystemsNode() {
649 if (file_systems_child_
)
650 return file_systems_child_
;
651 file_systems_child_
= new CookieTreeFileSystemsNode
;
652 AddChildSortedByTitle(file_systems_child_
);
653 return file_systems_child_
;
656 CookieTreeQuotaNode
* CookieTreeHostNode::UpdateOrCreateQuotaNode(
657 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
) {
660 quota_child_
= new CookieTreeQuotaNode(quota_info
);
661 AddChildSortedByTitle(quota_child_
);
665 CookieTreeChannelIDsNode
*
666 CookieTreeHostNode::GetOrCreateChannelIDsNode() {
667 if (channel_ids_child_
)
668 return channel_ids_child_
;
669 channel_ids_child_
= new CookieTreeChannelIDsNode
;
670 AddChildSortedByTitle(channel_ids_child_
);
671 return channel_ids_child_
;
674 CookieTreeFlashLSONode
* CookieTreeHostNode::GetOrCreateFlashLSONode(
675 const std::string
& domain
) {
676 DCHECK_EQ(GetHost(), domain
);
677 if (flash_lso_child_
)
678 return flash_lso_child_
;
679 flash_lso_child_
= new CookieTreeFlashLSONode(domain
);
680 AddChildSortedByTitle(flash_lso_child_
);
681 return flash_lso_child_
;
684 void CookieTreeHostNode::CreateContentException(
685 CookieSettings
* cookie_settings
, ContentSetting setting
) const {
686 DCHECK(setting
== CONTENT_SETTING_ALLOW
||
687 setting
== CONTENT_SETTING_BLOCK
||
688 setting
== CONTENT_SETTING_SESSION_ONLY
);
689 if (CanCreateContentException()) {
690 cookie_settings
->ResetCookieSetting(
691 ContentSettingsPattern::FromURLNoWildcard(url_
),
692 ContentSettingsPattern::Wildcard());
693 cookie_settings
->SetCookieSetting(
694 ContentSettingsPattern::FromURL(url_
),
695 ContentSettingsPattern::Wildcard(), setting
);
699 bool CookieTreeHostNode::CanCreateContentException() const {
700 return !url_
.SchemeIsFile();
703 ///////////////////////////////////////////////////////////////////////////////
704 // CookieTreeCookiesNode, public:
706 CookieTreeCookiesNode::CookieTreeCookiesNode()
707 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES
)) {
710 CookieTreeCookiesNode::~CookieTreeCookiesNode() {
713 CookieTreeNode::DetailedInfo
CookieTreeCookiesNode::GetDetailedInfo() const {
714 return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES
);
717 ///////////////////////////////////////////////////////////////////////////////
718 // CookieTreeAppCachesNode, public:
720 CookieTreeAppCachesNode::CookieTreeAppCachesNode()
721 : CookieTreeNode(l10n_util::GetStringUTF16(
722 IDS_COOKIES_APPLICATION_CACHES
)) {
725 CookieTreeAppCachesNode::~CookieTreeAppCachesNode() {}
727 CookieTreeNode::DetailedInfo
CookieTreeAppCachesNode::GetDetailedInfo() const {
728 return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES
);
731 ///////////////////////////////////////////////////////////////////////////////
732 // CookieTreeDatabasesNode, public:
734 CookieTreeDatabasesNode::CookieTreeDatabasesNode()
735 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES
)) {
738 CookieTreeDatabasesNode::~CookieTreeDatabasesNode() {}
740 CookieTreeNode::DetailedInfo
CookieTreeDatabasesNode::GetDetailedInfo() const {
741 return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES
);
744 ///////////////////////////////////////////////////////////////////////////////
745 // CookieTreeLocalStoragesNode, public:
747 CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode()
748 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE
)) {
751 CookieTreeLocalStoragesNode::~CookieTreeLocalStoragesNode() {}
753 CookieTreeNode::DetailedInfo
754 CookieTreeLocalStoragesNode::GetDetailedInfo() const {
755 return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES
);
758 ///////////////////////////////////////////////////////////////////////////////
759 // CookieTreeSessionStoragesNode, public:
761 CookieTreeSessionStoragesNode::CookieTreeSessionStoragesNode()
762 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE
)) {
765 CookieTreeSessionStoragesNode::~CookieTreeSessionStoragesNode() {}
767 CookieTreeNode::DetailedInfo
768 CookieTreeSessionStoragesNode::GetDetailedInfo() const {
769 return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES
);
772 ///////////////////////////////////////////////////////////////////////////////
773 // CookieTreeIndexedDBsNode, public:
775 CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode()
776 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS
)) {
779 CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {}
781 CookieTreeNode::DetailedInfo
782 CookieTreeIndexedDBsNode::GetDetailedInfo() const {
783 return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS
);
786 ///////////////////////////////////////////////////////////////////////////////
787 // CookieTreeFileSystemsNode, public:
789 CookieTreeFileSystemsNode::CookieTreeFileSystemsNode()
790 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS
)) {
793 CookieTreeFileSystemsNode::~CookieTreeFileSystemsNode() {}
795 CookieTreeNode::DetailedInfo
796 CookieTreeFileSystemsNode::GetDetailedInfo() const {
797 return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS
);
800 ///////////////////////////////////////////////////////////////////////////////
801 // CookieTreeChannelIDsNode, public:
803 CookieTreeChannelIDsNode::CookieTreeChannelIDsNode()
805 l10n_util::GetStringUTF16(IDS_COOKIES_CHANNEL_IDS
)) {
808 CookieTreeChannelIDsNode::~CookieTreeChannelIDsNode() {}
810 CookieTreeNode::DetailedInfo
811 CookieTreeChannelIDsNode::GetDetailedInfo() const {
812 return DetailedInfo().Init(DetailedInfo::TYPE_CHANNEL_IDS
);
815 void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode
* new_child
) {
817 std::vector
<CookieTreeNode
*>::iterator iter
=
818 std::lower_bound(children().begin(), children().end(), new_child
,
819 NodeTitleComparator());
820 GetModel()->Add(this, new_child
, iter
- children().begin());
823 ///////////////////////////////////////////////////////////////////////////////
824 // CookieTreeFlashLSONode
825 CookieTreeFlashLSONode::CookieTreeFlashLSONode(
826 const std::string
& domain
)
828 CookieTreeFlashLSONode::~CookieTreeFlashLSONode() {}
830 void CookieTreeFlashLSONode::DeleteStoredObjects() {
831 // We are one level below the host node.
832 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(parent());
833 CHECK_EQ(host
->GetDetailedInfo().node_type
,
834 CookieTreeNode::DetailedInfo::TYPE_HOST
);
835 LocalDataContainer
* container
= GetModel()->data_container();
838 container
->flash_lso_helper_
->DeleteFlashLSOsForSite(domain_
);
841 CookieTreeNode::DetailedInfo
CookieTreeFlashLSONode::GetDetailedInfo() const {
842 return DetailedInfo().InitFlashLSO(domain_
);
845 ///////////////////////////////////////////////////////////////////////////////
846 // ScopedBatchUpdateNotifier
847 CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier(
848 CookiesTreeModel
* model
, CookieTreeNode
* node
)
849 : model_(model
), node_(node
), batch_in_progress_(false) {
852 CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() {
853 if (batch_in_progress_
) {
854 model_
->NotifyObserverTreeNodeChanged(node_
);
855 model_
->NotifyObserverEndBatch();
859 void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() {
860 if (!batch_in_progress_
) {
861 model_
->NotifyObserverBeginBatch();
862 batch_in_progress_
= true;
866 ///////////////////////////////////////////////////////////////////////////////
867 // CookiesTreeModel, public:
868 CookiesTreeModel::CookiesTreeModel(
869 LocalDataContainer
* data_container
,
870 ExtensionSpecialStoragePolicy
* special_storage_policy
,
871 bool group_by_cookie_source
)
872 : ui::TreeNodeModel
<CookieTreeNode
>(new CookieTreeRootNode(this)),
873 data_container_(data_container
),
874 #if defined(ENABLE_EXTENSIONS)
875 special_storage_policy_(special_storage_policy
),
877 group_by_cookie_source_(group_by_cookie_source
),
879 data_container_
->Init(this);
882 CookiesTreeModel::~CookiesTreeModel() {
885 ///////////////////////////////////////////////////////////////////////////////
886 // CookiesTreeModel, TreeModel methods (public):
888 // TreeModel methods:
889 // Returns the set of icons for the nodes in the tree. You only need override
890 // this if you don't want to use the default folder icons.
891 void CookiesTreeModel::GetIcons(std::vector
<gfx::ImageSkia
>* icons
) {
892 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
893 IDR_DEFAULT_FAVICON
).ToImageSkia());
894 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
895 IDR_COOKIE_ICON
).ToImageSkia());
896 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
897 IDR_COOKIE_STORAGE_ICON
).ToImageSkia());
900 // Returns the index of the icon to use for |node|. Return -1 to use the
901 // default icon. The index is relative to the list of icons returned from
903 int CookiesTreeModel::GetIconIndex(ui::TreeModelNode
* node
) {
904 CookieTreeNode
* ct_node
= static_cast<CookieTreeNode
*>(node
);
905 switch (ct_node
->GetDetailedInfo().node_type
) {
906 case CookieTreeNode::DetailedInfo::TYPE_HOST
:
908 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
910 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
912 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
913 return DATABASE
; // close enough
914 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
915 return DATABASE
; // ditto
916 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
917 return DATABASE
; // ditto
918 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
919 return DATABASE
; // ditto
920 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
921 return DATABASE
; // ditto
922 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
924 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
925 return COOKIE
; // It's kinda like a cookie?
932 void CookiesTreeModel::DeleteAllStoredObjects() {
933 NotifyObserverBeginBatch();
934 CookieTreeNode
* root
= GetRoot();
935 root
->DeleteStoredObjects();
936 int num_children
= root
->child_count();
937 for (int i
= num_children
- 1; i
>= 0; --i
)
938 delete Remove(root
, root
->GetChild(i
));
939 NotifyObserverTreeNodeChanged(root
);
940 NotifyObserverEndBatch();
943 void CookiesTreeModel::DeleteCookieNode(CookieTreeNode
* cookie_node
) {
944 if (cookie_node
== GetRoot())
946 cookie_node
->DeleteStoredObjects();
947 CookieTreeNode
* parent_node
= cookie_node
->parent();
948 delete Remove(parent_node
, cookie_node
);
949 if (parent_node
->empty())
950 DeleteCookieNode(parent_node
);
953 void CookiesTreeModel::UpdateSearchResults(const base::string16
& filter
) {
954 CookieTreeNode
* root
= GetRoot();
955 ScopedBatchUpdateNotifier
notifier(this, root
);
956 int num_children
= root
->child_count();
957 notifier
.StartBatchUpdate();
958 for (int i
= num_children
- 1; i
>= 0; --i
)
959 delete Remove(root
, root
->GetChild(i
));
961 PopulateCookieInfoWithFilter(data_container(), ¬ifier
, filter
);
962 PopulateDatabaseInfoWithFilter(data_container(), ¬ifier
, filter
);
963 PopulateLocalStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
964 PopulateSessionStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
965 PopulateAppCacheInfoWithFilter(data_container(), ¬ifier
, filter
);
966 PopulateIndexedDBInfoWithFilter(data_container(), ¬ifier
, filter
);
967 PopulateFileSystemInfoWithFilter(data_container(), ¬ifier
, filter
);
968 PopulateQuotaInfoWithFilter(data_container(), ¬ifier
, filter
);
969 PopulateChannelIDInfoWithFilter(data_container(), ¬ifier
, filter
);
972 #if defined(ENABLE_EXTENSIONS)
973 const extensions::ExtensionSet
* CookiesTreeModel::ExtensionsProtectingNode(
974 const CookieTreeNode
& cookie_node
) {
975 if (!special_storage_policy_
)
978 CookieTreeNode::DetailedInfo info
= cookie_node
.GetDetailedInfo();
980 if (!TypeIsProtected(info
.node_type
))
983 DCHECK(!info
.origin
.is_empty());
984 return special_storage_policy_
->ExtensionsProtectingOrigin(info
.origin
);
988 void CookiesTreeModel::AddCookiesTreeObserver(Observer
* observer
) {
989 cookies_observer_list_
.AddObserver(observer
);
990 // Call super so that TreeNodeModel can notify, too.
991 ui::TreeNodeModel
<CookieTreeNode
>::AddObserver(observer
);
994 void CookiesTreeModel::RemoveCookiesTreeObserver(Observer
* observer
) {
995 cookies_observer_list_
.RemoveObserver(observer
);
996 // Call super so that TreeNodeModel doesn't have dead pointers.
997 ui::TreeNodeModel
<CookieTreeNode
>::RemoveObserver(observer
);
1000 void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer
* container
) {
1001 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1002 PopulateAppCacheInfoWithFilter(container
, ¬ifier
, base::string16());
1005 void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer
* container
) {
1006 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1007 PopulateCookieInfoWithFilter(container
, ¬ifier
, base::string16());
1010 void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer
* container
) {
1011 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1012 PopulateDatabaseInfoWithFilter(container
, ¬ifier
, base::string16());
1015 void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer
* container
) {
1016 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1017 PopulateLocalStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1020 void CookiesTreeModel::PopulateSessionStorageInfo(
1021 LocalDataContainer
* container
) {
1022 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1023 PopulateSessionStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1026 void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer
* container
) {
1027 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1028 PopulateIndexedDBInfoWithFilter(container
, ¬ifier
, base::string16());
1031 void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer
* container
) {
1032 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1033 PopulateFileSystemInfoWithFilter(container
, ¬ifier
, base::string16());
1036 void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer
* container
) {
1037 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1038 PopulateQuotaInfoWithFilter(container
, ¬ifier
, base::string16());
1041 void CookiesTreeModel::PopulateChannelIDInfo(
1042 LocalDataContainer
* container
) {
1043 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1044 PopulateChannelIDInfoWithFilter(container
, ¬ifier
, base::string16());
1047 void CookiesTreeModel::PopulateFlashLSOInfo(
1048 LocalDataContainer
* container
) {
1049 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1050 PopulateFlashLSOInfoWithFilter(container
, ¬ifier
, base::string16());
1053 void CookiesTreeModel::PopulateAppCacheInfoWithFilter(
1054 LocalDataContainer
* container
,
1055 ScopedBatchUpdateNotifier
* notifier
,
1056 const base::string16
& filter
) {
1057 using content::AppCacheInfo
;
1058 typedef std::map
<GURL
, std::list
<AppCacheInfo
> > InfoByOrigin
;
1059 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1061 if (container
->appcache_info_
.empty())
1064 notifier
->StartBatchUpdate();
1065 for (InfoByOrigin::iterator origin
= container
->appcache_info_
.begin();
1066 origin
!= container
->appcache_info_
.end(); ++origin
) {
1067 base::string16 host_node_name
= base::UTF8ToUTF16(origin
->first
.host());
1068 if (filter
.empty() ||
1069 (host_node_name
.find(filter
) != base::string16::npos
)) {
1070 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
->first
);
1071 CookieTreeAppCachesNode
* appcaches_node
=
1072 host_node
->GetOrCreateAppCachesNode();
1074 for (std::list
<AppCacheInfo
>::iterator info
= origin
->second
.begin();
1075 info
!= origin
->second
.end(); ++info
) {
1076 appcaches_node
->AddAppCacheNode(
1077 new CookieTreeAppCacheNode(origin
->first
, info
));
1083 void CookiesTreeModel::PopulateCookieInfoWithFilter(
1084 LocalDataContainer
* container
,
1085 ScopedBatchUpdateNotifier
* notifier
,
1086 const base::string16
& filter
) {
1087 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1089 notifier
->StartBatchUpdate();
1090 for (CookieList::iterator it
= container
->cookie_list_
.begin();
1091 it
!= container
->cookie_list_
.end(); ++it
) {
1092 std::string source_string
= it
->Source();
1093 if (source_string
.empty() || !group_by_cookie_source_
) {
1094 std::string domain
= it
->Domain();
1095 if (domain
.length() > 1 && domain
[0] == '.')
1096 domain
= domain
.substr(1);
1098 // We treat secure cookies just the same as normal ones.
1099 source_string
= std::string(url::kHttpScheme
) +
1100 url::kStandardSchemeSeparator
+ domain
+ "/";
1103 GURL
source(source_string
);
1104 if (!filter
.size() ||
1105 (CookieTreeHostNode::TitleForUrl(source
).find(filter
) !=
1106 base::string16::npos
)) {
1107 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(source
);
1108 CookieTreeCookiesNode
* cookies_node
=
1109 host_node
->GetOrCreateCookiesNode();
1110 CookieTreeCookieNode
* new_cookie
= new CookieTreeCookieNode(it
);
1111 cookies_node
->AddCookieNode(new_cookie
);
1116 void CookiesTreeModel::PopulateDatabaseInfoWithFilter(
1117 LocalDataContainer
* container
,
1118 ScopedBatchUpdateNotifier
* notifier
,
1119 const base::string16
& filter
) {
1120 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1122 if (container
->database_info_list_
.empty())
1125 notifier
->StartBatchUpdate();
1126 for (DatabaseInfoList::iterator database_info
=
1127 container
->database_info_list_
.begin();
1128 database_info
!= container
->database_info_list_
.end();
1130 GURL
origin(database_info
->identifier
.ToOrigin());
1132 if (!filter
.size() ||
1133 (CookieTreeHostNode::TitleForUrl(origin
).find(filter
) !=
1134 base::string16::npos
)) {
1135 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1136 CookieTreeDatabasesNode
* databases_node
=
1137 host_node
->GetOrCreateDatabasesNode();
1138 databases_node
->AddDatabaseNode(
1139 new CookieTreeDatabaseNode(database_info
));
1144 void CookiesTreeModel::PopulateLocalStorageInfoWithFilter(
1145 LocalDataContainer
* container
,
1146 ScopedBatchUpdateNotifier
* notifier
,
1147 const base::string16
& filter
) {
1148 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1150 if (container
->local_storage_info_list_
.empty())
1153 notifier
->StartBatchUpdate();
1154 for (LocalStorageInfoList::iterator local_storage_info
=
1155 container
->local_storage_info_list_
.begin();
1156 local_storage_info
!= container
->local_storage_info_list_
.end();
1157 ++local_storage_info
) {
1158 const GURL
& origin(local_storage_info
->origin_url
);
1160 if (!filter
.size() ||
1161 (CookieTreeHostNode::TitleForUrl(origin
).find(filter
) !=
1162 std::string::npos
)) {
1163 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1164 CookieTreeLocalStoragesNode
* local_storages_node
=
1165 host_node
->GetOrCreateLocalStoragesNode();
1166 local_storages_node
->AddLocalStorageNode(
1167 new CookieTreeLocalStorageNode(local_storage_info
));
1172 void CookiesTreeModel::PopulateSessionStorageInfoWithFilter(
1173 LocalDataContainer
* container
,
1174 ScopedBatchUpdateNotifier
* notifier
,
1175 const base::string16
& filter
) {
1176 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1178 if (container
->session_storage_info_list_
.empty())
1181 notifier
->StartBatchUpdate();
1182 for (LocalStorageInfoList::iterator session_storage_info
=
1183 container
->session_storage_info_list_
.begin();
1184 session_storage_info
!= container
->session_storage_info_list_
.end();
1185 ++session_storage_info
) {
1186 const GURL
& origin
= session_storage_info
->origin_url
;
1188 if (!filter
.size() ||
1189 (CookieTreeHostNode::TitleForUrl(origin
).find(filter
) !=
1190 base::string16::npos
)) {
1191 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1192 CookieTreeSessionStoragesNode
* session_storages_node
=
1193 host_node
->GetOrCreateSessionStoragesNode();
1194 session_storages_node
->AddSessionStorageNode(
1195 new CookieTreeSessionStorageNode(session_storage_info
));
1200 void CookiesTreeModel::PopulateIndexedDBInfoWithFilter(
1201 LocalDataContainer
* container
,
1202 ScopedBatchUpdateNotifier
* notifier
,
1203 const base::string16
& filter
) {
1204 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1206 if (container
->indexed_db_info_list_
.empty())
1209 notifier
->StartBatchUpdate();
1210 for (IndexedDBInfoList::iterator indexed_db_info
=
1211 container
->indexed_db_info_list_
.begin();
1212 indexed_db_info
!= container
->indexed_db_info_list_
.end();
1213 ++indexed_db_info
) {
1214 const GURL
& origin
= indexed_db_info
->origin_
;
1216 if (!filter
.size() ||
1217 (CookieTreeHostNode::TitleForUrl(origin
).find(filter
) !=
1218 base::string16::npos
)) {
1219 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1220 CookieTreeIndexedDBsNode
* indexed_dbs_node
=
1221 host_node
->GetOrCreateIndexedDBsNode();
1222 indexed_dbs_node
->AddIndexedDBNode(
1223 new CookieTreeIndexedDBNode(indexed_db_info
));
1228 void CookiesTreeModel::PopulateChannelIDInfoWithFilter(
1229 LocalDataContainer
* container
,
1230 ScopedBatchUpdateNotifier
* notifier
,
1231 const base::string16
& filter
) {
1232 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1234 if (container
->channel_id_list_
.empty())
1237 notifier
->StartBatchUpdate();
1238 for (ChannelIDList::iterator channel_id_info
=
1239 container
->channel_id_list_
.begin();
1240 channel_id_info
!= container
->channel_id_list_
.end();
1241 ++channel_id_info
) {
1242 GURL
origin(channel_id_info
->server_identifier());
1243 if (!origin
.is_valid()) {
1244 // Channel ID. Make a valid URL to satisfy the
1245 // CookieTreeRootNode::GetOrCreateHostNode interface.
1246 origin
= GURL(std::string(url::kHttpsScheme
) +
1247 url::kStandardSchemeSeparator
+
1248 channel_id_info
->server_identifier() + "/");
1250 base::string16 title
= CookieTreeHostNode::TitleForUrl(origin
);
1251 if (!filter
.size() || title
.find(filter
) != base::string16::npos
) {
1252 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1253 CookieTreeChannelIDsNode
* channel_ids_node
=
1254 host_node
->GetOrCreateChannelIDsNode();
1255 channel_ids_node
->AddChannelIDNode(
1256 new CookieTreeChannelIDNode(channel_id_info
));
1261 void CookiesTreeModel::PopulateFileSystemInfoWithFilter(
1262 LocalDataContainer
* container
,
1263 ScopedBatchUpdateNotifier
* notifier
,
1264 const base::string16
& filter
) {
1265 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1267 if (container
->file_system_info_list_
.empty())
1270 notifier
->StartBatchUpdate();
1271 for (FileSystemInfoList::iterator file_system_info
=
1272 container
->file_system_info_list_
.begin();
1273 file_system_info
!= container
->file_system_info_list_
.end();
1274 ++file_system_info
) {
1275 GURL
origin(file_system_info
->origin
);
1277 if (!filter
.size() ||
1278 (CookieTreeHostNode::TitleForUrl(origin
).find(filter
) !=
1279 base::string16::npos
)) {
1280 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1281 CookieTreeFileSystemsNode
* file_systems_node
=
1282 host_node
->GetOrCreateFileSystemsNode();
1283 file_systems_node
->AddFileSystemNode(
1284 new CookieTreeFileSystemNode(file_system_info
));
1289 void CookiesTreeModel::PopulateQuotaInfoWithFilter(
1290 LocalDataContainer
* container
,
1291 ScopedBatchUpdateNotifier
* notifier
,
1292 const base::string16
& filter
) {
1293 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1295 if (container
->quota_info_list_
.empty())
1298 notifier
->StartBatchUpdate();
1299 for (QuotaInfoList::iterator quota_info
= container
->quota_info_list_
.begin();
1300 quota_info
!= container
->quota_info_list_
.end();
1302 if (!filter
.size() ||
1303 (base::UTF8ToUTF16(quota_info
->host
).find(filter
) !=
1304 base::string16::npos
)) {
1305 CookieTreeHostNode
* host_node
=
1306 root
->GetOrCreateHostNode(GURL("http://" + quota_info
->host
));
1307 host_node
->UpdateOrCreateQuotaNode(quota_info
);
1312 void CookiesTreeModel::PopulateFlashLSOInfoWithFilter(
1313 LocalDataContainer
* container
,
1314 ScopedBatchUpdateNotifier
* notifier
,
1315 const base::string16
& filter
) {
1316 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1318 if (container
->flash_lso_domain_list_
.empty())
1321 std::string filter_utf8
= base::UTF16ToUTF8(filter
);
1322 notifier
->StartBatchUpdate();
1323 for (std::vector
<std::string
>::iterator it
=
1324 container
->flash_lso_domain_list_
.begin();
1325 it
!= container
->flash_lso_domain_list_
.end(); ++it
) {
1326 if (!filter_utf8
.size() || it
->find(filter_utf8
) != std::string::npos
) {
1327 // Create a fake origin for GetOrCreateHostNode().
1328 GURL
origin("http://" + *it
);
1329 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1330 host_node
->GetOrCreateFlashLSONode(*it
);
1335 void CookiesTreeModel::NotifyObserverBeginBatch() {
1336 // Only notify the model once if we're batching in a nested manner.
1337 if (batch_update_
++ == 0) {
1338 FOR_EACH_OBSERVER(Observer
,
1339 cookies_observer_list_
,
1340 TreeModelBeginBatch(this));
1344 void CookiesTreeModel::NotifyObserverEndBatch() {
1345 // Only notify the observers if this is the outermost call to EndBatch() if
1346 // called in a nested manner.
1347 if (--batch_update_
== 0) {
1348 FOR_EACH_OBSERVER(Observer
,
1349 cookies_observer_list_
,
1350 TreeModelEndBatch(this));