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"
12 #include "base/bind.h"
13 #include "base/memory/linked_ptr.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
18 #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
19 #include "chrome/browser/content_settings/cookie_settings_factory.h"
20 #include "chrome/grit/generated_resources.h"
21 #include "components/content_settings/core/browser/cookie_settings.h"
22 #include "content/public/common/url_constants.h"
23 #include "grit/theme_resources.h"
24 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
25 #include "net/cookies/canonical_cookie.h"
26 #include "net/url_request/url_request_context.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/base/resource/resource_bundle.h"
29 #include "ui/gfx/image/image_skia.h"
30 #include "ui/resources/grit/ui_resources.h"
32 #if defined(ENABLE_EXTENSIONS)
33 #include "chrome/browser/extensions/extension_special_storage_policy.h"
34 #include "extensions/common/extension_set.h"
39 struct NodeTitleComparator
{
40 bool operator()(const CookieTreeNode
* lhs
, const CookieTreeNode
* rhs
) {
41 return lhs
->GetTitle() < rhs
->GetTitle();
45 // Comparison functor, for use in CookieTreeRootNode.
46 struct HostNodeComparator
{
47 bool operator()(const CookieTreeNode
* lhs
, const CookieTreeNode
* rhs
) {
48 // This comparator is only meant to compare CookieTreeHostNode types. Make
49 // sure we check this, as the static cast below is dangerous if we get the
51 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST
,
52 lhs
->GetDetailedInfo().node_type
);
53 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST
,
54 rhs
->GetDetailedInfo().node_type
);
56 const CookieTreeHostNode
* ltn
=
57 static_cast<const CookieTreeHostNode
*>(lhs
);
58 const CookieTreeHostNode
* rtn
=
59 static_cast<const CookieTreeHostNode
*>(rhs
);
61 // We want to order by registry controlled domain, so we would get
62 // google.com, ad.google.com, www.google.com,
63 // microsoft.com, ad.microsoft.com. CanonicalizeHost transforms the origins
64 // into a form like google.com.www so that string comparisons work.
65 return (ltn
->canonicalized_host() <
66 rtn
->canonicalized_host());
70 std::string
CanonicalizeHost(const GURL
& url
) {
71 // The canonicalized representation makes the registry controlled domain
72 // come first, and then adds subdomains in reverse order, e.g.
73 // 1.mail.google.com would become google.com.mail.1, and then a standard
74 // string comparison works to order hosts by registry controlled domain
75 // first. Leading dots are ignored, ".google.com" is the same as
78 if (url
.SchemeIsFile()) {
79 return std::string(url::kFileScheme
) +
80 url::kStandardSchemeSeparator
;
83 std::string host
= url
.host();
85 net::registry_controlled_domains::GetDomainAndRegistry(
87 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES
);
88 if (!retval
.length()) // Is an IP address or other special origin.
91 std::string::size_type position
= host
.rfind(retval
);
93 // The host may be the registry controlled domain, in which case fail fast.
94 if (position
== 0 || position
== std::string::npos
)
97 // If host is www.google.com, retval will contain google.com at this point.
98 // Start operating to the left of the registry controlled domain, e.g. in
99 // the www.google.com example, start at index 3.
102 // If position == 0, that means it's a dot; this will be ignored to treat
103 // ".google.com" the same as "google.com".
104 while (position
> 0) {
105 retval
+= std::string(".");
106 // Copy up to the next dot. host[position] is a dot so start after it.
107 std::string::size_type next_dot
= host
.rfind(".", position
- 1);
108 if (next_dot
== std::string::npos
) {
109 retval
+= host
.substr(0, position
);
112 retval
+= host
.substr(next_dot
+ 1, position
- (next_dot
+ 1));
118 #if defined(ENABLE_EXTENSIONS)
119 bool TypeIsProtected(CookieTreeNode::DetailedInfo::NodeType type
) {
121 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
123 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
125 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
127 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
129 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
131 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
133 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
135 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
137 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
139 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER
:
141 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO
:
150 // This function returns the local data container associated with a leaf tree
151 // node. The app node is assumed to be 3 levels above the leaf because of the
152 // following structure:
153 // root -> origin -> storage type -> leaf node
154 LocalDataContainer
* GetLocalDataContainerForNode(CookieTreeNode
* node
) {
155 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(
156 node
->parent()->parent());
157 CHECK_EQ(host
->GetDetailedInfo().node_type
,
158 CookieTreeNode::DetailedInfo::TYPE_HOST
);
159 return node
->GetModel()->data_container();
164 CookieTreeNode::DetailedInfo::DetailedInfo()
165 : node_type(TYPE_NONE
),
168 local_storage_info(NULL
),
169 session_storage_info(NULL
),
171 indexed_db_info(NULL
),
172 file_system_info(NULL
),
175 service_worker_info(NULL
) {
178 CookieTreeNode::DetailedInfo::~DetailedInfo() {}
180 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::Init(
182 DCHECK_EQ(TYPE_NONE
, node_type
);
187 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitHost() {
192 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitCookie(
193 const net::CanonicalCookie
* cookie
) {
195 this->cookie
= cookie
;
199 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitDatabase(
200 const BrowsingDataDatabaseHelper::DatabaseInfo
* database_info
) {
202 this->database_info
= database_info
;
203 origin
= database_info
->identifier
.ToOrigin();
207 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitLocalStorage(
208 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
209 local_storage_info
) {
210 Init(TYPE_LOCAL_STORAGE
);
211 this->local_storage_info
= local_storage_info
;
212 origin
= local_storage_info
->origin_url
;
216 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitSessionStorage(
217 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
218 session_storage_info
) {
219 Init(TYPE_SESSION_STORAGE
);
220 this->session_storage_info
= session_storage_info
;
221 origin
= session_storage_info
->origin_url
;
225 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitAppCache(
227 const content::AppCacheInfo
* appcache_info
) {
229 this->appcache_info
= appcache_info
;
230 this->origin
= origin
;
234 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitIndexedDB(
235 const content::IndexedDBInfo
* indexed_db_info
) {
236 Init(TYPE_INDEXED_DB
);
237 this->indexed_db_info
= indexed_db_info
;
238 this->origin
= indexed_db_info
->origin_
;
242 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFileSystem(
243 const BrowsingDataFileSystemHelper::FileSystemInfo
* file_system_info
) {
244 Init(TYPE_FILE_SYSTEM
);
245 this->file_system_info
= file_system_info
;
246 this->origin
= file_system_info
->origin
;
250 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitQuota(
251 const BrowsingDataQuotaHelper::QuotaInfo
* quota_info
) {
253 this->quota_info
= quota_info
;
257 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitChannelID(
258 const net::ChannelIDStore::ChannelID
* channel_id
) {
259 Init(TYPE_CHANNEL_ID
);
260 this->channel_id
= channel_id
;
264 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitServiceWorker(
265 const content::ServiceWorkerUsageInfo
* service_worker_info
) {
266 Init(TYPE_SERVICE_WORKER
);
267 this->service_worker_info
= service_worker_info
;
268 this->origin
= service_worker_info
->origin
;
272 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFlashLSO(
273 const std::string
& flash_lso_domain
) {
274 Init(TYPE_FLASH_LSO
);
275 this->flash_lso_domain
= flash_lso_domain
;
279 ///////////////////////////////////////////////////////////////////////////////
280 // CookieTreeNode, public:
282 void CookieTreeNode::DeleteStoredObjects() {
283 std::for_each(children().begin(),
285 std::mem_fun(&CookieTreeNode::DeleteStoredObjects
));
288 CookiesTreeModel
* CookieTreeNode::GetModel() const {
290 return parent()->GetModel();
295 ///////////////////////////////////////////////////////////////////////////////
296 // CookieTreeCookieNode, public:
298 CookieTreeCookieNode::CookieTreeCookieNode(
299 std::list
<net::CanonicalCookie
>::iterator cookie
)
300 : CookieTreeNode(base::UTF8ToUTF16(cookie
->Name())),
304 CookieTreeCookieNode::~CookieTreeCookieNode() {}
306 void CookieTreeCookieNode::DeleteStoredObjects() {
307 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
308 container
->cookie_helper_
->DeleteCookie(*cookie_
);
309 container
->cookie_list_
.erase(cookie_
);
312 CookieTreeNode::DetailedInfo
CookieTreeCookieNode::GetDetailedInfo() const {
313 return DetailedInfo().InitCookie(&*cookie_
);
316 ///////////////////////////////////////////////////////////////////////////////
317 // CookieTreeAppCacheNode, public:
319 CookieTreeAppCacheNode::CookieTreeAppCacheNode(
320 const GURL
& origin_url
,
321 std::list
<content::AppCacheInfo
>::iterator appcache_info
)
322 : CookieTreeNode(base::UTF8ToUTF16(appcache_info
->manifest_url
.spec())),
323 origin_url_(origin_url
),
324 appcache_info_(appcache_info
) {
327 CookieTreeAppCacheNode::~CookieTreeAppCacheNode() {
330 void CookieTreeAppCacheNode::DeleteStoredObjects() {
331 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
334 DCHECK(container
->appcache_helper_
.get());
335 container
->appcache_helper_
336 ->DeleteAppCacheGroup(appcache_info_
->manifest_url
);
337 container
->appcache_info_
[origin_url_
].erase(appcache_info_
);
341 CookieTreeNode::DetailedInfo
CookieTreeAppCacheNode::GetDetailedInfo() const {
342 return DetailedInfo().InitAppCache(origin_url_
, &*appcache_info_
);
345 ///////////////////////////////////////////////////////////////////////////////
346 // CookieTreeDatabaseNode, public:
348 CookieTreeDatabaseNode::CookieTreeDatabaseNode(
349 std::list
<BrowsingDataDatabaseHelper::DatabaseInfo
>::iterator database_info
)
350 : CookieTreeNode(database_info
->database_name
.empty() ?
351 l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME
) :
352 base::UTF8ToUTF16(database_info
->database_name
)),
353 database_info_(database_info
) {
356 CookieTreeDatabaseNode::~CookieTreeDatabaseNode() {}
358 void CookieTreeDatabaseNode::DeleteStoredObjects() {
359 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
362 container
->database_helper_
->DeleteDatabase(
363 database_info_
->identifier
.ToString(), database_info_
->database_name
);
364 container
->database_info_list_
.erase(database_info_
);
368 CookieTreeNode::DetailedInfo
CookieTreeDatabaseNode::GetDetailedInfo() const {
369 return DetailedInfo().InitDatabase(&*database_info_
);
372 ///////////////////////////////////////////////////////////////////////////////
373 // CookieTreeLocalStorageNode, public:
375 CookieTreeLocalStorageNode::CookieTreeLocalStorageNode(
376 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
378 : CookieTreeNode(base::UTF8ToUTF16(local_storage_info
->origin_url
.spec())),
379 local_storage_info_(local_storage_info
) {
382 CookieTreeLocalStorageNode::~CookieTreeLocalStorageNode() {}
384 void CookieTreeLocalStorageNode::DeleteStoredObjects() {
385 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
388 container
->local_storage_helper_
->DeleteOrigin(
389 local_storage_info_
->origin_url
);
390 container
->local_storage_info_list_
.erase(local_storage_info_
);
394 CookieTreeNode::DetailedInfo
395 CookieTreeLocalStorageNode::GetDetailedInfo() const {
396 return DetailedInfo().InitLocalStorage(
397 &*local_storage_info_
);
400 ///////////////////////////////////////////////////////////////////////////////
401 // CookieTreeSessionStorageNode, public:
403 CookieTreeSessionStorageNode::CookieTreeSessionStorageNode(
404 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
405 session_storage_info
)
407 base::UTF8ToUTF16(session_storage_info
->origin_url
.spec())),
408 session_storage_info_(session_storage_info
) {
411 CookieTreeSessionStorageNode::~CookieTreeSessionStorageNode() {}
413 void CookieTreeSessionStorageNode::DeleteStoredObjects() {
414 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
417 // TODO(rsesek): There's no easy way to get the namespace_id for a session
418 // storage, nor is there an easy way to clear session storage just by
419 // origin. This is probably okay since session storage is not persistent.
420 // http://crbug.com/168996
421 container
->session_storage_info_list_
.erase(session_storage_info_
);
425 CookieTreeNode::DetailedInfo
426 CookieTreeSessionStorageNode::GetDetailedInfo() const {
427 return DetailedInfo().InitSessionStorage(&*session_storage_info_
);
430 ///////////////////////////////////////////////////////////////////////////////
431 // CookieTreeIndexedDBNode, public:
433 CookieTreeIndexedDBNode::CookieTreeIndexedDBNode(
434 std::list
<content::IndexedDBInfo
>::iterator
436 : CookieTreeNode(base::UTF8ToUTF16(
437 indexed_db_info
->origin_
.spec())),
438 indexed_db_info_(indexed_db_info
) {
441 CookieTreeIndexedDBNode::~CookieTreeIndexedDBNode() {}
443 void CookieTreeIndexedDBNode::DeleteStoredObjects() {
444 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
447 container
->indexed_db_helper_
->DeleteIndexedDB(
448 indexed_db_info_
->origin_
);
449 container
->indexed_db_info_list_
.erase(indexed_db_info_
);
453 CookieTreeNode::DetailedInfo
CookieTreeIndexedDBNode::GetDetailedInfo() const {
454 return DetailedInfo().InitIndexedDB(&*indexed_db_info_
);
457 ///////////////////////////////////////////////////////////////////////////////
458 // CookieTreeFileSystemNode, public:
460 CookieTreeFileSystemNode::CookieTreeFileSystemNode(
461 std::list
<BrowsingDataFileSystemHelper::FileSystemInfo
>::iterator
463 : CookieTreeNode(base::UTF8ToUTF16(
464 file_system_info
->origin
.spec())),
465 file_system_info_(file_system_info
) {
468 CookieTreeFileSystemNode::~CookieTreeFileSystemNode() {}
470 void CookieTreeFileSystemNode::DeleteStoredObjects() {
471 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
474 container
->file_system_helper_
->DeleteFileSystemOrigin(
475 file_system_info_
->origin
);
476 container
->file_system_info_list_
.erase(file_system_info_
);
480 CookieTreeNode::DetailedInfo
CookieTreeFileSystemNode::GetDetailedInfo() const {
481 return DetailedInfo().InitFileSystem(&*file_system_info_
);
484 ///////////////////////////////////////////////////////////////////////////////
485 // CookieTreeQuotaNode, public:
487 CookieTreeQuotaNode::CookieTreeQuotaNode(
488 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
)
489 : CookieTreeNode(base::UTF8ToUTF16(quota_info
->host
)),
490 quota_info_(quota_info
) {
493 CookieTreeQuotaNode::~CookieTreeQuotaNode() {}
495 void CookieTreeQuotaNode::DeleteStoredObjects() {
496 // Calling this function may cause unexpected over-quota state of origin.
497 // However, it'll caused no problem, just prevent usage growth of the origin.
498 LocalDataContainer
* container
= GetModel()->data_container();
501 container
->quota_helper_
->RevokeHostQuota(quota_info_
->host
);
502 container
->quota_info_list_
.erase(quota_info_
);
506 CookieTreeNode::DetailedInfo
CookieTreeQuotaNode::GetDetailedInfo() const {
507 return DetailedInfo().InitQuota(&*quota_info_
);
510 ///////////////////////////////////////////////////////////////////////////////
511 // CookieTreeChannelIDNode, public:
513 CookieTreeChannelIDNode::CookieTreeChannelIDNode(
514 net::ChannelIDStore::ChannelIDList::iterator channel_id
)
515 : CookieTreeNode(base::ASCIIToUTF16(channel_id
->server_identifier())),
516 channel_id_(channel_id
) {
519 CookieTreeChannelIDNode::~CookieTreeChannelIDNode() {}
521 void CookieTreeChannelIDNode::DeleteStoredObjects() {
522 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
525 container
->channel_id_helper_
->DeleteChannelID(
526 channel_id_
->server_identifier());
527 container
->channel_id_list_
.erase(channel_id_
);
531 CookieTreeNode::DetailedInfo
532 CookieTreeChannelIDNode::GetDetailedInfo() const {
533 return DetailedInfo().InitChannelID(&*channel_id_
);
536 ///////////////////////////////////////////////////////////////////////////////
537 // CookieTreeServiceWorkerNode, public:
539 CookieTreeServiceWorkerNode::CookieTreeServiceWorkerNode(
540 std::list
<content::ServiceWorkerUsageInfo
>::iterator service_worker_info
)
541 : CookieTreeNode(base::UTF8ToUTF16(service_worker_info
->origin
.spec())),
542 service_worker_info_(service_worker_info
) {
545 CookieTreeServiceWorkerNode::~CookieTreeServiceWorkerNode() {
548 void CookieTreeServiceWorkerNode::DeleteStoredObjects() {
549 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
552 container
->service_worker_helper_
->DeleteServiceWorkers(
553 service_worker_info_
->origin
);
554 container
->service_worker_info_list_
.erase(service_worker_info_
);
558 CookieTreeNode::DetailedInfo
CookieTreeServiceWorkerNode::GetDetailedInfo()
560 return DetailedInfo().InitServiceWorker(&*service_worker_info_
);
563 ///////////////////////////////////////////////////////////////////////////////
564 // CookieTreeRootNode, public:
566 CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel
* model
)
570 CookieTreeRootNode::~CookieTreeRootNode() {}
572 CookieTreeHostNode
* CookieTreeRootNode::GetOrCreateHostNode(
574 scoped_ptr
<CookieTreeHostNode
> host_node(
575 new CookieTreeHostNode(url
));
577 // First see if there is an existing match.
578 std::vector
<CookieTreeNode
*>::iterator host_node_iterator
=
579 std::lower_bound(children().begin(), children().end(), host_node
.get(),
580 HostNodeComparator());
581 if (host_node_iterator
!= children().end() &&
582 CookieTreeHostNode::TitleForUrl(url
) ==
583 (*host_node_iterator
)->GetTitle())
584 return static_cast<CookieTreeHostNode
*>(*host_node_iterator
);
585 // Node doesn't exist, insert the new one into the (ordered) children.
587 model_
->Add(this, host_node
.get(),
588 (host_node_iterator
- children().begin()));
589 return host_node
.release();
592 CookiesTreeModel
* CookieTreeRootNode::GetModel() const {
596 CookieTreeNode::DetailedInfo
CookieTreeRootNode::GetDetailedInfo() const {
597 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT
);
600 ///////////////////////////////////////////////////////////////////////////////
601 // CookieTreeHostNode, public:
604 base::string16
CookieTreeHostNode::TitleForUrl(const GURL
& url
) {
605 const std::string
file_origin_node_name(
606 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
607 return base::UTF8ToUTF16(url
.SchemeIsFile() ? file_origin_node_name
611 CookieTreeHostNode::CookieTreeHostNode(const GURL
& url
)
612 : CookieTreeNode(TitleForUrl(url
)),
613 cookies_child_(NULL
),
614 databases_child_(NULL
),
615 local_storages_child_(NULL
),
616 session_storages_child_(NULL
),
617 appcaches_child_(NULL
),
618 indexed_dbs_child_(NULL
),
619 file_systems_child_(NULL
),
621 channel_ids_child_(NULL
),
622 service_workers_child_(NULL
),
623 flash_lso_child_(NULL
),
625 canonicalized_host_(CanonicalizeHost(url
)) {
628 CookieTreeHostNode::~CookieTreeHostNode() {}
630 const std::string
CookieTreeHostNode::GetHost() const {
631 const std::string
file_origin_node_name(
632 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
633 return url_
.SchemeIsFile() ? file_origin_node_name
: url_
.host();
636 CookieTreeNode::DetailedInfo
CookieTreeHostNode::GetDetailedInfo() const {
637 return DetailedInfo().InitHost();
640 CookieTreeCookiesNode
* CookieTreeHostNode::GetOrCreateCookiesNode() {
642 return cookies_child_
;
643 cookies_child_
= new CookieTreeCookiesNode
;
644 AddChildSortedByTitle(cookies_child_
);
645 return cookies_child_
;
648 CookieTreeDatabasesNode
* CookieTreeHostNode::GetOrCreateDatabasesNode() {
649 if (databases_child_
)
650 return databases_child_
;
651 databases_child_
= new CookieTreeDatabasesNode
;
652 AddChildSortedByTitle(databases_child_
);
653 return databases_child_
;
656 CookieTreeLocalStoragesNode
*
657 CookieTreeHostNode::GetOrCreateLocalStoragesNode() {
658 if (local_storages_child_
)
659 return local_storages_child_
;
660 local_storages_child_
= new CookieTreeLocalStoragesNode
;
661 AddChildSortedByTitle(local_storages_child_
);
662 return local_storages_child_
;
665 CookieTreeSessionStoragesNode
*
666 CookieTreeHostNode::GetOrCreateSessionStoragesNode() {
667 if (session_storages_child_
)
668 return session_storages_child_
;
669 session_storages_child_
= new CookieTreeSessionStoragesNode
;
670 AddChildSortedByTitle(session_storages_child_
);
671 return session_storages_child_
;
674 CookieTreeAppCachesNode
* CookieTreeHostNode::GetOrCreateAppCachesNode() {
675 if (appcaches_child_
)
676 return appcaches_child_
;
677 appcaches_child_
= new CookieTreeAppCachesNode
;
678 AddChildSortedByTitle(appcaches_child_
);
679 return appcaches_child_
;
682 CookieTreeIndexedDBsNode
* CookieTreeHostNode::GetOrCreateIndexedDBsNode() {
683 if (indexed_dbs_child_
)
684 return indexed_dbs_child_
;
685 indexed_dbs_child_
= new CookieTreeIndexedDBsNode
;
686 AddChildSortedByTitle(indexed_dbs_child_
);
687 return indexed_dbs_child_
;
690 CookieTreeFileSystemsNode
* CookieTreeHostNode::GetOrCreateFileSystemsNode() {
691 if (file_systems_child_
)
692 return file_systems_child_
;
693 file_systems_child_
= new CookieTreeFileSystemsNode
;
694 AddChildSortedByTitle(file_systems_child_
);
695 return file_systems_child_
;
698 CookieTreeQuotaNode
* CookieTreeHostNode::UpdateOrCreateQuotaNode(
699 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
) {
702 quota_child_
= new CookieTreeQuotaNode(quota_info
);
703 AddChildSortedByTitle(quota_child_
);
707 CookieTreeChannelIDsNode
*
708 CookieTreeHostNode::GetOrCreateChannelIDsNode() {
709 if (channel_ids_child_
)
710 return channel_ids_child_
;
711 channel_ids_child_
= new CookieTreeChannelIDsNode
;
712 AddChildSortedByTitle(channel_ids_child_
);
713 return channel_ids_child_
;
716 CookieTreeServiceWorkersNode
*
717 CookieTreeHostNode::GetOrCreateServiceWorkersNode() {
718 if (service_workers_child_
)
719 return service_workers_child_
;
720 service_workers_child_
= new CookieTreeServiceWorkersNode
;
721 AddChildSortedByTitle(service_workers_child_
);
722 return service_workers_child_
;
725 CookieTreeFlashLSONode
* CookieTreeHostNode::GetOrCreateFlashLSONode(
726 const std::string
& domain
) {
727 DCHECK_EQ(GetHost(), domain
);
728 if (flash_lso_child_
)
729 return flash_lso_child_
;
730 flash_lso_child_
= new CookieTreeFlashLSONode(domain
);
731 AddChildSortedByTitle(flash_lso_child_
);
732 return flash_lso_child_
;
735 void CookieTreeHostNode::CreateContentException(
736 content_settings::CookieSettings
* cookie_settings
,
737 ContentSetting setting
) const {
738 DCHECK(setting
== CONTENT_SETTING_ALLOW
||
739 setting
== CONTENT_SETTING_BLOCK
||
740 setting
== CONTENT_SETTING_SESSION_ONLY
);
741 if (CanCreateContentException()) {
742 cookie_settings
->ResetCookieSetting(
743 ContentSettingsPattern::FromURLNoWildcard(url_
),
744 ContentSettingsPattern::Wildcard());
745 cookie_settings
->SetCookieSetting(
746 ContentSettingsPattern::FromURL(url_
),
747 ContentSettingsPattern::Wildcard(), setting
);
751 bool CookieTreeHostNode::CanCreateContentException() const {
752 return !url_
.SchemeIsFile();
755 ///////////////////////////////////////////////////////////////////////////////
756 // CookieTreeCookiesNode, public:
758 CookieTreeCookiesNode::CookieTreeCookiesNode()
759 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES
)) {
762 CookieTreeCookiesNode::~CookieTreeCookiesNode() {
765 CookieTreeNode::DetailedInfo
CookieTreeCookiesNode::GetDetailedInfo() const {
766 return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES
);
769 ///////////////////////////////////////////////////////////////////////////////
770 // CookieTreeAppCachesNode, public:
772 CookieTreeAppCachesNode::CookieTreeAppCachesNode()
773 : CookieTreeNode(l10n_util::GetStringUTF16(
774 IDS_COOKIES_APPLICATION_CACHES
)) {
777 CookieTreeAppCachesNode::~CookieTreeAppCachesNode() {}
779 CookieTreeNode::DetailedInfo
CookieTreeAppCachesNode::GetDetailedInfo() const {
780 return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES
);
783 ///////////////////////////////////////////////////////////////////////////////
784 // CookieTreeDatabasesNode, public:
786 CookieTreeDatabasesNode::CookieTreeDatabasesNode()
787 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES
)) {
790 CookieTreeDatabasesNode::~CookieTreeDatabasesNode() {}
792 CookieTreeNode::DetailedInfo
CookieTreeDatabasesNode::GetDetailedInfo() const {
793 return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES
);
796 ///////////////////////////////////////////////////////////////////////////////
797 // CookieTreeLocalStoragesNode, public:
799 CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode()
800 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE
)) {
803 CookieTreeLocalStoragesNode::~CookieTreeLocalStoragesNode() {}
805 CookieTreeNode::DetailedInfo
806 CookieTreeLocalStoragesNode::GetDetailedInfo() const {
807 return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES
);
810 ///////////////////////////////////////////////////////////////////////////////
811 // CookieTreeSessionStoragesNode, public:
813 CookieTreeSessionStoragesNode::CookieTreeSessionStoragesNode()
814 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE
)) {
817 CookieTreeSessionStoragesNode::~CookieTreeSessionStoragesNode() {}
819 CookieTreeNode::DetailedInfo
820 CookieTreeSessionStoragesNode::GetDetailedInfo() const {
821 return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES
);
824 ///////////////////////////////////////////////////////////////////////////////
825 // CookieTreeIndexedDBsNode, public:
827 CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode()
828 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS
)) {
831 CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {}
833 CookieTreeNode::DetailedInfo
834 CookieTreeIndexedDBsNode::GetDetailedInfo() const {
835 return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS
);
838 ///////////////////////////////////////////////////////////////////////////////
839 // CookieTreeFileSystemsNode, public:
841 CookieTreeFileSystemsNode::CookieTreeFileSystemsNode()
842 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS
)) {
845 CookieTreeFileSystemsNode::~CookieTreeFileSystemsNode() {}
847 CookieTreeNode::DetailedInfo
848 CookieTreeFileSystemsNode::GetDetailedInfo() const {
849 return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS
);
852 ///////////////////////////////////////////////////////////////////////////////
853 // CookieTreeChannelIDsNode, public:
855 CookieTreeChannelIDsNode::CookieTreeChannelIDsNode()
857 l10n_util::GetStringUTF16(IDS_COOKIES_CHANNEL_IDS
)) {
860 CookieTreeChannelIDsNode::~CookieTreeChannelIDsNode() {}
862 CookieTreeNode::DetailedInfo
863 CookieTreeChannelIDsNode::GetDetailedInfo() const {
864 return DetailedInfo().Init(DetailedInfo::TYPE_CHANNEL_IDS
);
867 void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode
* new_child
) {
869 std::vector
<CookieTreeNode
*>::iterator iter
=
870 std::lower_bound(children().begin(), children().end(), new_child
,
871 NodeTitleComparator());
872 GetModel()->Add(this, new_child
, iter
- children().begin());
875 ///////////////////////////////////////////////////////////////////////////////
876 // CookieTreeServiceWorkersNode, public:
878 CookieTreeServiceWorkersNode::CookieTreeServiceWorkersNode()
879 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SERVICE_WORKERS
)) {
882 CookieTreeServiceWorkersNode::~CookieTreeServiceWorkersNode() {
885 CookieTreeNode::DetailedInfo
CookieTreeServiceWorkersNode::GetDetailedInfo()
887 return DetailedInfo().Init(DetailedInfo::TYPE_SERVICE_WORKERS
);
890 ///////////////////////////////////////////////////////////////////////////////
891 // CookieTreeFlashLSONode
892 CookieTreeFlashLSONode::CookieTreeFlashLSONode(
893 const std::string
& domain
)
895 CookieTreeFlashLSONode::~CookieTreeFlashLSONode() {}
897 void CookieTreeFlashLSONode::DeleteStoredObjects() {
898 // We are one level below the host node.
899 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(parent());
900 CHECK_EQ(host
->GetDetailedInfo().node_type
,
901 CookieTreeNode::DetailedInfo::TYPE_HOST
);
902 LocalDataContainer
* container
= GetModel()->data_container();
903 container
->flash_lso_helper_
->DeleteFlashLSOsForSite(domain_
);
906 CookieTreeNode::DetailedInfo
CookieTreeFlashLSONode::GetDetailedInfo() const {
907 return DetailedInfo().InitFlashLSO(domain_
);
910 ///////////////////////////////////////////////////////////////////////////////
911 // ScopedBatchUpdateNotifier
912 CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier(
913 CookiesTreeModel
* model
, CookieTreeNode
* node
)
914 : model_(model
), node_(node
), batch_in_progress_(false) {
915 model_
->RecordBatchSeen();
918 CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() {
919 if (batch_in_progress_
) {
920 model_
->NotifyObserverTreeNodeChanged(node_
);
921 model_
->NotifyObserverEndBatch();
923 // If no batch started, and this is the last batch, give the model a chance
924 // to send out a final notification.
925 model_
->MaybeNotifyBatchesEnded();
929 void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() {
930 if (!batch_in_progress_
) {
931 model_
->NotifyObserverBeginBatch();
932 batch_in_progress_
= true;
936 ///////////////////////////////////////////////////////////////////////////////
937 // CookiesTreeModel, public:
938 CookiesTreeModel::CookiesTreeModel(
939 LocalDataContainer
* data_container
,
940 ExtensionSpecialStoragePolicy
* special_storage_policy
,
941 bool group_by_cookie_source
)
942 : ui::TreeNodeModel
<CookieTreeNode
>(new CookieTreeRootNode(this)),
943 data_container_(data_container
),
944 #if defined(ENABLE_EXTENSIONS)
945 special_storage_policy_(special_storage_policy
),
947 group_by_cookie_source_(group_by_cookie_source
),
948 batches_expected_(0),
952 data_container_
->Init(this);
955 CookiesTreeModel::~CookiesTreeModel() {
959 int CookiesTreeModel::GetSendForMessageID(const net::CanonicalCookie
& cookie
) {
960 if (cookie
.IsSecure()) {
961 if (cookie
.IsFirstPartyOnly())
962 return IDS_COOKIES_COOKIE_SENDFOR_SECURE_FIRSTPARTY
;
963 return IDS_COOKIES_COOKIE_SENDFOR_SECURE
;
965 if (cookie
.IsFirstPartyOnly())
966 return IDS_COOKIES_COOKIE_SENDFOR_FIRSTPARTY
;
967 return IDS_COOKIES_COOKIE_SENDFOR_ANY
;
970 ///////////////////////////////////////////////////////////////////////////////
971 // CookiesTreeModel, TreeModel methods (public):
973 // TreeModel methods:
974 // Returns the set of icons for the nodes in the tree. You only need override
975 // this if you don't want to use the default folder icons.
976 void CookiesTreeModel::GetIcons(std::vector
<gfx::ImageSkia
>* icons
) {
977 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
978 IDR_DEFAULT_FAVICON
).ToImageSkia());
979 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
980 IDR_COOKIE_ICON
).ToImageSkia());
981 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
982 IDR_COOKIE_STORAGE_ICON
).ToImageSkia());
985 // Returns the index of the icon to use for |node|. Return -1 to use the
986 // default icon. The index is relative to the list of icons returned from
988 int CookiesTreeModel::GetIconIndex(ui::TreeModelNode
* node
) {
989 CookieTreeNode
* ct_node
= static_cast<CookieTreeNode
*>(node
);
990 switch (ct_node
->GetDetailedInfo().node_type
) {
991 case CookieTreeNode::DetailedInfo::TYPE_HOST
:
993 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
995 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
997 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
998 return DATABASE
; // close enough
999 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
1000 return DATABASE
; // ditto
1001 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
1002 return DATABASE
; // ditto
1003 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
1004 return DATABASE
; // ditto
1005 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
1006 return DATABASE
; // ditto
1007 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
1009 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
1010 return COOKIE
; // It's kinda like a cookie?
1011 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER
:
1012 return DATABASE
; // Just like appcache
1019 void CookiesTreeModel::DeleteAllStoredObjects() {
1020 NotifyObserverBeginBatch();
1021 CookieTreeNode
* root
= GetRoot();
1022 root
->DeleteStoredObjects();
1023 int num_children
= root
->child_count();
1024 for (int i
= num_children
- 1; i
>= 0; --i
)
1025 delete Remove(root
, root
->GetChild(i
));
1026 NotifyObserverTreeNodeChanged(root
);
1027 NotifyObserverEndBatch();
1030 void CookiesTreeModel::DeleteCookieNode(CookieTreeNode
* cookie_node
) {
1031 if (cookie_node
== GetRoot())
1033 cookie_node
->DeleteStoredObjects();
1034 CookieTreeNode
* parent_node
= cookie_node
->parent();
1035 delete Remove(parent_node
, cookie_node
);
1036 if (parent_node
->empty())
1037 DeleteCookieNode(parent_node
);
1040 void CookiesTreeModel::UpdateSearchResults(const base::string16
& filter
) {
1041 CookieTreeNode
* root
= GetRoot();
1042 SetBatchExpectation(1, true);
1043 ScopedBatchUpdateNotifier
notifier(this, root
);
1044 int num_children
= root
->child_count();
1045 notifier
.StartBatchUpdate();
1046 for (int i
= num_children
- 1; i
>= 0; --i
)
1047 delete Remove(root
, root
->GetChild(i
));
1049 PopulateCookieInfoWithFilter(data_container(), ¬ifier
, filter
);
1050 PopulateDatabaseInfoWithFilter(data_container(), ¬ifier
, filter
);
1051 PopulateLocalStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
1052 PopulateSessionStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
1053 PopulateAppCacheInfoWithFilter(data_container(), ¬ifier
, filter
);
1054 PopulateIndexedDBInfoWithFilter(data_container(), ¬ifier
, filter
);
1055 PopulateFileSystemInfoWithFilter(data_container(), ¬ifier
, filter
);
1056 PopulateQuotaInfoWithFilter(data_container(), ¬ifier
, filter
);
1057 PopulateChannelIDInfoWithFilter(data_container(), ¬ifier
, filter
);
1058 PopulateServiceWorkerUsageInfoWithFilter(data_container(), ¬ifier
, filter
);
1061 #if defined(ENABLE_EXTENSIONS)
1062 const extensions::ExtensionSet
* CookiesTreeModel::ExtensionsProtectingNode(
1063 const CookieTreeNode
& cookie_node
) {
1064 if (!special_storage_policy_
.get())
1067 CookieTreeNode::DetailedInfo info
= cookie_node
.GetDetailedInfo();
1069 if (!TypeIsProtected(info
.node_type
))
1072 DCHECK(!info
.origin
.is_empty());
1073 return special_storage_policy_
->ExtensionsProtectingOrigin(info
.origin
);
1077 void CookiesTreeModel::AddCookiesTreeObserver(Observer
* observer
) {
1078 cookies_observer_list_
.AddObserver(observer
);
1079 // Call super so that TreeNodeModel can notify, too.
1080 ui::TreeNodeModel
<CookieTreeNode
>::AddObserver(observer
);
1083 void CookiesTreeModel::RemoveCookiesTreeObserver(Observer
* observer
) {
1084 cookies_observer_list_
.RemoveObserver(observer
);
1085 // Call super so that TreeNodeModel doesn't have dead pointers.
1086 ui::TreeNodeModel
<CookieTreeNode
>::RemoveObserver(observer
);
1089 void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer
* container
) {
1090 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1091 PopulateAppCacheInfoWithFilter(container
, ¬ifier
, base::string16());
1094 void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer
* container
) {
1095 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1096 PopulateCookieInfoWithFilter(container
, ¬ifier
, base::string16());
1099 void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer
* container
) {
1100 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1101 PopulateDatabaseInfoWithFilter(container
, ¬ifier
, base::string16());
1104 void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer
* container
) {
1105 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1106 PopulateLocalStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1109 void CookiesTreeModel::PopulateSessionStorageInfo(
1110 LocalDataContainer
* container
) {
1111 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1112 PopulateSessionStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1115 void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer
* container
) {
1116 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1117 PopulateIndexedDBInfoWithFilter(container
, ¬ifier
, base::string16());
1120 void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer
* container
) {
1121 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1122 PopulateFileSystemInfoWithFilter(container
, ¬ifier
, base::string16());
1125 void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer
* container
) {
1126 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1127 PopulateQuotaInfoWithFilter(container
, ¬ifier
, base::string16());
1130 void CookiesTreeModel::PopulateChannelIDInfo(
1131 LocalDataContainer
* container
) {
1132 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1133 PopulateChannelIDInfoWithFilter(container
, ¬ifier
, base::string16());
1136 void CookiesTreeModel::PopulateServiceWorkerUsageInfo(
1137 LocalDataContainer
* container
) {
1138 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1139 PopulateServiceWorkerUsageInfoWithFilter(
1140 container
, ¬ifier
, base::string16());
1143 void CookiesTreeModel::PopulateFlashLSOInfo(
1144 LocalDataContainer
* container
) {
1145 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1146 PopulateFlashLSOInfoWithFilter(container
, ¬ifier
, base::string16());
1149 void CookiesTreeModel::PopulateAppCacheInfoWithFilter(
1150 LocalDataContainer
* container
,
1151 ScopedBatchUpdateNotifier
* notifier
,
1152 const base::string16
& filter
) {
1153 using content::AppCacheInfo
;
1154 typedef std::map
<GURL
, std::list
<AppCacheInfo
> > InfoByOrigin
;
1155 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1157 if (container
->appcache_info_
.empty())
1160 notifier
->StartBatchUpdate();
1161 for (InfoByOrigin::iterator origin
= container
->appcache_info_
.begin();
1162 origin
!= container
->appcache_info_
.end(); ++origin
) {
1163 base::string16 host_node_name
= base::UTF8ToUTF16(origin
->first
.host());
1164 if (filter
.empty() ||
1165 (host_node_name
.find(filter
) != base::string16::npos
)) {
1166 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
->first
);
1167 CookieTreeAppCachesNode
* appcaches_node
=
1168 host_node
->GetOrCreateAppCachesNode();
1170 for (std::list
<AppCacheInfo
>::iterator info
= origin
->second
.begin();
1171 info
!= origin
->second
.end(); ++info
) {
1172 appcaches_node
->AddAppCacheNode(
1173 new CookieTreeAppCacheNode(origin
->first
, info
));
1179 void CookiesTreeModel::PopulateCookieInfoWithFilter(
1180 LocalDataContainer
* container
,
1181 ScopedBatchUpdateNotifier
* notifier
,
1182 const base::string16
& filter
) {
1183 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1185 notifier
->StartBatchUpdate();
1186 for (CookieList::iterator it
= container
->cookie_list_
.begin();
1187 it
!= container
->cookie_list_
.end(); ++it
) {
1188 std::string source_string
= it
->Source();
1189 if (source_string
.empty() || !group_by_cookie_source_
) {
1190 std::string domain
= it
->Domain();
1191 if (domain
.length() > 1 && domain
[0] == '.')
1192 domain
= domain
.substr(1);
1194 // We treat secure cookies just the same as normal ones.
1195 source_string
= std::string(url::kHttpScheme
) +
1196 url::kStandardSchemeSeparator
+ domain
+ "/";
1199 GURL
source(source_string
);
1200 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(source
)
1201 .find(filter
) != base::string16::npos
)) {
1202 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(source
);
1203 CookieTreeCookiesNode
* cookies_node
=
1204 host_node
->GetOrCreateCookiesNode();
1205 CookieTreeCookieNode
* new_cookie
= new CookieTreeCookieNode(it
);
1206 cookies_node
->AddCookieNode(new_cookie
);
1211 void CookiesTreeModel::PopulateDatabaseInfoWithFilter(
1212 LocalDataContainer
* container
,
1213 ScopedBatchUpdateNotifier
* notifier
,
1214 const base::string16
& filter
) {
1215 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1217 if (container
->database_info_list_
.empty())
1220 notifier
->StartBatchUpdate();
1221 for (DatabaseInfoList::iterator database_info
=
1222 container
->database_info_list_
.begin();
1223 database_info
!= container
->database_info_list_
.end();
1225 GURL
origin(database_info
->identifier
.ToOrigin());
1227 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1228 .find(filter
) != base::string16::npos
)) {
1229 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1230 CookieTreeDatabasesNode
* databases_node
=
1231 host_node
->GetOrCreateDatabasesNode();
1232 databases_node
->AddDatabaseNode(
1233 new CookieTreeDatabaseNode(database_info
));
1238 void CookiesTreeModel::PopulateLocalStorageInfoWithFilter(
1239 LocalDataContainer
* container
,
1240 ScopedBatchUpdateNotifier
* notifier
,
1241 const base::string16
& filter
) {
1242 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1244 if (container
->local_storage_info_list_
.empty())
1247 notifier
->StartBatchUpdate();
1248 for (LocalStorageInfoList::iterator local_storage_info
=
1249 container
->local_storage_info_list_
.begin();
1250 local_storage_info
!= container
->local_storage_info_list_
.end();
1251 ++local_storage_info
) {
1252 const GURL
& origin(local_storage_info
->origin_url
);
1254 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1255 .find(filter
) != std::string::npos
)) {
1256 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1257 CookieTreeLocalStoragesNode
* local_storages_node
=
1258 host_node
->GetOrCreateLocalStoragesNode();
1259 local_storages_node
->AddLocalStorageNode(
1260 new CookieTreeLocalStorageNode(local_storage_info
));
1265 void CookiesTreeModel::PopulateSessionStorageInfoWithFilter(
1266 LocalDataContainer
* container
,
1267 ScopedBatchUpdateNotifier
* notifier
,
1268 const base::string16
& filter
) {
1269 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1271 if (container
->session_storage_info_list_
.empty())
1274 notifier
->StartBatchUpdate();
1275 for (LocalStorageInfoList::iterator session_storage_info
=
1276 container
->session_storage_info_list_
.begin();
1277 session_storage_info
!= container
->session_storage_info_list_
.end();
1278 ++session_storage_info
) {
1279 const GURL
& origin
= session_storage_info
->origin_url
;
1281 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1282 .find(filter
) != base::string16::npos
)) {
1283 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1284 CookieTreeSessionStoragesNode
* session_storages_node
=
1285 host_node
->GetOrCreateSessionStoragesNode();
1286 session_storages_node
->AddSessionStorageNode(
1287 new CookieTreeSessionStorageNode(session_storage_info
));
1292 void CookiesTreeModel::PopulateIndexedDBInfoWithFilter(
1293 LocalDataContainer
* container
,
1294 ScopedBatchUpdateNotifier
* notifier
,
1295 const base::string16
& filter
) {
1296 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1298 if (container
->indexed_db_info_list_
.empty())
1301 notifier
->StartBatchUpdate();
1302 for (IndexedDBInfoList::iterator indexed_db_info
=
1303 container
->indexed_db_info_list_
.begin();
1304 indexed_db_info
!= container
->indexed_db_info_list_
.end();
1305 ++indexed_db_info
) {
1306 const GURL
& origin
= indexed_db_info
->origin_
;
1308 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1309 .find(filter
) != base::string16::npos
)) {
1310 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1311 CookieTreeIndexedDBsNode
* indexed_dbs_node
=
1312 host_node
->GetOrCreateIndexedDBsNode();
1313 indexed_dbs_node
->AddIndexedDBNode(
1314 new CookieTreeIndexedDBNode(indexed_db_info
));
1319 void CookiesTreeModel::PopulateChannelIDInfoWithFilter(
1320 LocalDataContainer
* container
,
1321 ScopedBatchUpdateNotifier
* notifier
,
1322 const base::string16
& filter
) {
1323 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1325 if (container
->channel_id_list_
.empty())
1328 notifier
->StartBatchUpdate();
1329 for (ChannelIDList::iterator channel_id_info
=
1330 container
->channel_id_list_
.begin();
1331 channel_id_info
!= container
->channel_id_list_
.end();
1332 ++channel_id_info
) {
1333 GURL
origin(channel_id_info
->server_identifier());
1334 if (!origin
.is_valid()) {
1335 // Channel ID. Make a valid URL to satisfy the
1336 // CookieTreeRootNode::GetOrCreateHostNode interface.
1337 origin
= GURL(std::string(url::kHttpsScheme
) +
1338 url::kStandardSchemeSeparator
+
1339 channel_id_info
->server_identifier() + "/");
1341 base::string16 title
= CookieTreeHostNode::TitleForUrl(origin
);
1342 if (filter
.empty() || title
.find(filter
) != base::string16::npos
) {
1343 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1344 CookieTreeChannelIDsNode
* channel_ids_node
=
1345 host_node
->GetOrCreateChannelIDsNode();
1346 channel_ids_node
->AddChannelIDNode(
1347 new CookieTreeChannelIDNode(channel_id_info
));
1352 void CookiesTreeModel::PopulateServiceWorkerUsageInfoWithFilter(
1353 LocalDataContainer
* container
,
1354 ScopedBatchUpdateNotifier
* notifier
,
1355 const base::string16
& filter
) {
1356 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1358 if (container
->service_worker_info_list_
.empty())
1361 notifier
->StartBatchUpdate();
1362 for (ServiceWorkerUsageInfoList::iterator service_worker_info
=
1363 container
->service_worker_info_list_
.begin();
1364 service_worker_info
!= container
->service_worker_info_list_
.end();
1365 ++service_worker_info
) {
1366 const GURL
& origin
= service_worker_info
->origin
;
1368 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1369 .find(filter
) != base::string16::npos
)) {
1370 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1371 CookieTreeServiceWorkersNode
* service_workers_node
=
1372 host_node
->GetOrCreateServiceWorkersNode();
1373 service_workers_node
->AddServiceWorkerNode(
1374 new CookieTreeServiceWorkerNode(service_worker_info
));
1379 void CookiesTreeModel::PopulateFileSystemInfoWithFilter(
1380 LocalDataContainer
* container
,
1381 ScopedBatchUpdateNotifier
* notifier
,
1382 const base::string16
& filter
) {
1383 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1385 if (container
->file_system_info_list_
.empty())
1388 notifier
->StartBatchUpdate();
1389 for (FileSystemInfoList::iterator file_system_info
=
1390 container
->file_system_info_list_
.begin();
1391 file_system_info
!= container
->file_system_info_list_
.end();
1392 ++file_system_info
) {
1393 GURL
origin(file_system_info
->origin
);
1395 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1396 .find(filter
) != base::string16::npos
)) {
1397 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1398 CookieTreeFileSystemsNode
* file_systems_node
=
1399 host_node
->GetOrCreateFileSystemsNode();
1400 file_systems_node
->AddFileSystemNode(
1401 new CookieTreeFileSystemNode(file_system_info
));
1406 void CookiesTreeModel::PopulateQuotaInfoWithFilter(
1407 LocalDataContainer
* container
,
1408 ScopedBatchUpdateNotifier
* notifier
,
1409 const base::string16
& filter
) {
1410 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1412 if (container
->quota_info_list_
.empty())
1415 notifier
->StartBatchUpdate();
1416 for (QuotaInfoList::iterator quota_info
= container
->quota_info_list_
.begin();
1417 quota_info
!= container
->quota_info_list_
.end();
1419 if (filter
.empty() || (base::UTF8ToUTF16(quota_info
->host
).find(filter
) !=
1420 base::string16::npos
)) {
1421 CookieTreeHostNode
* host_node
=
1422 root
->GetOrCreateHostNode(GURL("http://" + quota_info
->host
));
1423 host_node
->UpdateOrCreateQuotaNode(quota_info
);
1428 void CookiesTreeModel::PopulateFlashLSOInfoWithFilter(
1429 LocalDataContainer
* container
,
1430 ScopedBatchUpdateNotifier
* notifier
,
1431 const base::string16
& filter
) {
1432 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1434 if (container
->flash_lso_domain_list_
.empty())
1437 std::string filter_utf8
= base::UTF16ToUTF8(filter
);
1438 notifier
->StartBatchUpdate();
1439 for (std::vector
<std::string
>::iterator it
=
1440 container
->flash_lso_domain_list_
.begin();
1441 it
!= container
->flash_lso_domain_list_
.end(); ++it
) {
1442 if (filter_utf8
.empty() || it
->find(filter_utf8
) != std::string::npos
) {
1443 // Create a fake origin for GetOrCreateHostNode().
1444 GURL
origin("http://" + *it
);
1445 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1446 host_node
->GetOrCreateFlashLSONode(*it
);
1451 void CookiesTreeModel::SetBatchExpectation(int batches_expected
, bool reset
) {
1452 batches_expected_
= batches_expected
;
1455 batches_started_
= 0;
1458 MaybeNotifyBatchesEnded();
1462 void CookiesTreeModel::RecordBatchSeen() {
1466 void CookiesTreeModel::NotifyObserverBeginBatch() {
1467 // Only notify the model once if we're batching in a nested manner.
1468 if (batches_started_
++ == 0) {
1469 FOR_EACH_OBSERVER(Observer
,
1470 cookies_observer_list_
,
1471 TreeModelBeginBatch(this));
1475 void CookiesTreeModel::NotifyObserverEndBatch() {
1477 MaybeNotifyBatchesEnded();
1480 void CookiesTreeModel::MaybeNotifyBatchesEnded() {
1481 // Only notify the observers if this is the outermost call to EndBatch() if
1482 // called in a nested manner.
1483 if (batches_ended_
== batches_started_
&&
1484 batches_seen_
== batches_expected_
) {
1485 FOR_EACH_OBSERVER(Observer
,
1486 cookies_observer_list_
,
1487 TreeModelEndBatch(this));