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 // When creating a cookie tree node from a cookie, strip the port of the
119 // cookie source and treat all non-file:// URLs as http://.
120 GURL
CanonicalizeCookieSource(const net::CanonicalCookie
& cookie
) {
121 GURL url
= cookie
.Source();
122 if (url
.SchemeIsFile())
125 url::Replacements
<char> replacements
;
126 replacements
.ClearPort();
127 if (url
.SchemeIsCryptographic())
128 replacements
.SetScheme("http", url::Component(0, 4));
130 return url
.GetOrigin().ReplaceComponents(replacements
);
133 #if defined(ENABLE_EXTENSIONS)
134 bool TypeIsProtected(CookieTreeNode::DetailedInfo::NodeType type
) {
136 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
138 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
140 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
142 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
144 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
146 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
148 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
150 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
152 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
154 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER
:
156 case CookieTreeNode::DetailedInfo::TYPE_CACHE_STORAGE
:
158 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO
:
167 // This function returns the local data container associated with a leaf tree
168 // node. The app node is assumed to be 3 levels above the leaf because of the
169 // following structure:
170 // root -> origin -> storage type -> leaf node
171 LocalDataContainer
* GetLocalDataContainerForNode(CookieTreeNode
* node
) {
172 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(
173 node
->parent()->parent());
174 CHECK_EQ(host
->GetDetailedInfo().node_type
,
175 CookieTreeNode::DetailedInfo::TYPE_HOST
);
176 return node
->GetModel()->data_container();
181 CookieTreeNode::DetailedInfo::DetailedInfo() : node_type(TYPE_NONE
) {}
183 CookieTreeNode::DetailedInfo::~DetailedInfo() {}
185 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::Init(
187 DCHECK_EQ(TYPE_NONE
, node_type
);
192 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitHost() {
197 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitCookie(
198 const net::CanonicalCookie
* cookie
) {
200 this->cookie
= cookie
;
204 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitDatabase(
205 const BrowsingDataDatabaseHelper::DatabaseInfo
* database_info
) {
207 this->database_info
= database_info
;
208 origin
= database_info
->identifier
.ToOrigin();
212 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitLocalStorage(
213 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
214 local_storage_info
) {
215 Init(TYPE_LOCAL_STORAGE
);
216 this->local_storage_info
= local_storage_info
;
217 origin
= local_storage_info
->origin_url
;
221 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitSessionStorage(
222 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
223 session_storage_info
) {
224 Init(TYPE_SESSION_STORAGE
);
225 this->session_storage_info
= session_storage_info
;
226 origin
= session_storage_info
->origin_url
;
230 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitAppCache(
232 const content::AppCacheInfo
* appcache_info
) {
234 this->appcache_info
= appcache_info
;
235 this->origin
= origin
;
239 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitIndexedDB(
240 const content::IndexedDBInfo
* indexed_db_info
) {
241 Init(TYPE_INDEXED_DB
);
242 this->indexed_db_info
= indexed_db_info
;
243 this->origin
= indexed_db_info
->origin
;
247 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFileSystem(
248 const BrowsingDataFileSystemHelper::FileSystemInfo
* file_system_info
) {
249 Init(TYPE_FILE_SYSTEM
);
250 this->file_system_info
= file_system_info
;
251 this->origin
= file_system_info
->origin
;
255 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitQuota(
256 const BrowsingDataQuotaHelper::QuotaInfo
* quota_info
) {
258 this->quota_info
= quota_info
;
262 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitChannelID(
263 const net::ChannelIDStore::ChannelID
* channel_id
) {
264 Init(TYPE_CHANNEL_ID
);
265 this->channel_id
= channel_id
;
269 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitServiceWorker(
270 const content::ServiceWorkerUsageInfo
* service_worker_info
) {
271 Init(TYPE_SERVICE_WORKER
);
272 this->service_worker_info
= service_worker_info
;
273 this->origin
= service_worker_info
->origin
;
277 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitCacheStorage(
278 const content::CacheStorageUsageInfo
* cache_storage_info
) {
279 Init(TYPE_CACHE_STORAGE
);
280 this->cache_storage_info
= cache_storage_info
;
281 this->origin
= cache_storage_info
->origin
;
285 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFlashLSO(
286 const std::string
& flash_lso_domain
) {
287 Init(TYPE_FLASH_LSO
);
288 this->flash_lso_domain
= flash_lso_domain
;
292 ///////////////////////////////////////////////////////////////////////////////
293 // CookieTreeNode, public:
295 void CookieTreeNode::DeleteStoredObjects() {
296 std::for_each(children().begin(),
298 std::mem_fun(&CookieTreeNode::DeleteStoredObjects
));
301 CookiesTreeModel
* CookieTreeNode::GetModel() const {
303 return parent()->GetModel();
308 ///////////////////////////////////////////////////////////////////////////////
309 // CookieTreeCookieNode, public:
311 CookieTreeCookieNode::CookieTreeCookieNode(
312 std::list
<net::CanonicalCookie
>::iterator cookie
)
313 : CookieTreeNode(base::UTF8ToUTF16(cookie
->Name())),
317 CookieTreeCookieNode::~CookieTreeCookieNode() {}
319 void CookieTreeCookieNode::DeleteStoredObjects() {
320 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
321 container
->cookie_helper_
->DeleteCookie(*cookie_
);
322 container
->cookie_list_
.erase(cookie_
);
325 CookieTreeNode::DetailedInfo
CookieTreeCookieNode::GetDetailedInfo() const {
326 return DetailedInfo().InitCookie(&*cookie_
);
329 ///////////////////////////////////////////////////////////////////////////////
330 // CookieTreeAppCacheNode, public:
332 CookieTreeAppCacheNode::CookieTreeAppCacheNode(
333 const GURL
& origin_url
,
334 std::list
<content::AppCacheInfo
>::iterator appcache_info
)
335 : CookieTreeNode(base::UTF8ToUTF16(appcache_info
->manifest_url
.spec())),
336 origin_url_(origin_url
),
337 appcache_info_(appcache_info
) {
340 CookieTreeAppCacheNode::~CookieTreeAppCacheNode() {
343 void CookieTreeAppCacheNode::DeleteStoredObjects() {
344 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
347 DCHECK(container
->appcache_helper_
.get());
348 container
->appcache_helper_
349 ->DeleteAppCacheGroup(appcache_info_
->manifest_url
);
350 container
->appcache_info_
[origin_url_
].erase(appcache_info_
);
354 CookieTreeNode::DetailedInfo
CookieTreeAppCacheNode::GetDetailedInfo() const {
355 return DetailedInfo().InitAppCache(origin_url_
, &*appcache_info_
);
358 ///////////////////////////////////////////////////////////////////////////////
359 // CookieTreeDatabaseNode, public:
361 CookieTreeDatabaseNode::CookieTreeDatabaseNode(
362 std::list
<BrowsingDataDatabaseHelper::DatabaseInfo
>::iterator database_info
)
363 : CookieTreeNode(database_info
->database_name
.empty() ?
364 l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME
) :
365 base::UTF8ToUTF16(database_info
->database_name
)),
366 database_info_(database_info
) {
369 CookieTreeDatabaseNode::~CookieTreeDatabaseNode() {}
371 void CookieTreeDatabaseNode::DeleteStoredObjects() {
372 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
375 container
->database_helper_
->DeleteDatabase(
376 database_info_
->identifier
.ToString(), database_info_
->database_name
);
377 container
->database_info_list_
.erase(database_info_
);
381 CookieTreeNode::DetailedInfo
CookieTreeDatabaseNode::GetDetailedInfo() const {
382 return DetailedInfo().InitDatabase(&*database_info_
);
385 ///////////////////////////////////////////////////////////////////////////////
386 // CookieTreeLocalStorageNode, public:
388 CookieTreeLocalStorageNode::CookieTreeLocalStorageNode(
389 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
391 : CookieTreeNode(base::UTF8ToUTF16(local_storage_info
->origin_url
.spec())),
392 local_storage_info_(local_storage_info
) {
395 CookieTreeLocalStorageNode::~CookieTreeLocalStorageNode() {}
397 void CookieTreeLocalStorageNode::DeleteStoredObjects() {
398 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
401 container
->local_storage_helper_
->DeleteOrigin(
402 local_storage_info_
->origin_url
);
403 container
->local_storage_info_list_
.erase(local_storage_info_
);
407 CookieTreeNode::DetailedInfo
408 CookieTreeLocalStorageNode::GetDetailedInfo() const {
409 return DetailedInfo().InitLocalStorage(
410 &*local_storage_info_
);
413 ///////////////////////////////////////////////////////////////////////////////
414 // CookieTreeSessionStorageNode, public:
416 CookieTreeSessionStorageNode::CookieTreeSessionStorageNode(
417 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
418 session_storage_info
)
420 base::UTF8ToUTF16(session_storage_info
->origin_url
.spec())),
421 session_storage_info_(session_storage_info
) {
424 CookieTreeSessionStorageNode::~CookieTreeSessionStorageNode() {}
426 void CookieTreeSessionStorageNode::DeleteStoredObjects() {
427 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
430 // TODO(rsesek): There's no easy way to get the namespace_id for a session
431 // storage, nor is there an easy way to clear session storage just by
432 // origin. This is probably okay since session storage is not persistent.
433 // http://crbug.com/168996
434 container
->session_storage_info_list_
.erase(session_storage_info_
);
438 CookieTreeNode::DetailedInfo
439 CookieTreeSessionStorageNode::GetDetailedInfo() const {
440 return DetailedInfo().InitSessionStorage(&*session_storage_info_
);
443 ///////////////////////////////////////////////////////////////////////////////
444 // CookieTreeIndexedDBNode, public:
446 CookieTreeIndexedDBNode::CookieTreeIndexedDBNode(
447 std::list
<content::IndexedDBInfo
>::iterator indexed_db_info
)
448 : CookieTreeNode(base::UTF8ToUTF16(indexed_db_info
->origin
.spec())),
449 indexed_db_info_(indexed_db_info
) {}
451 CookieTreeIndexedDBNode::~CookieTreeIndexedDBNode() {}
453 void CookieTreeIndexedDBNode::DeleteStoredObjects() {
454 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
457 container
->indexed_db_helper_
->DeleteIndexedDB(indexed_db_info_
->origin
);
458 container
->indexed_db_info_list_
.erase(indexed_db_info_
);
462 CookieTreeNode::DetailedInfo
CookieTreeIndexedDBNode::GetDetailedInfo() const {
463 return DetailedInfo().InitIndexedDB(&*indexed_db_info_
);
466 ///////////////////////////////////////////////////////////////////////////////
467 // CookieTreeFileSystemNode, public:
469 CookieTreeFileSystemNode::CookieTreeFileSystemNode(
470 std::list
<BrowsingDataFileSystemHelper::FileSystemInfo
>::iterator
472 : CookieTreeNode(base::UTF8ToUTF16(
473 file_system_info
->origin
.spec())),
474 file_system_info_(file_system_info
) {
477 CookieTreeFileSystemNode::~CookieTreeFileSystemNode() {}
479 void CookieTreeFileSystemNode::DeleteStoredObjects() {
480 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
483 container
->file_system_helper_
->DeleteFileSystemOrigin(
484 file_system_info_
->origin
);
485 container
->file_system_info_list_
.erase(file_system_info_
);
489 CookieTreeNode::DetailedInfo
CookieTreeFileSystemNode::GetDetailedInfo() const {
490 return DetailedInfo().InitFileSystem(&*file_system_info_
);
493 ///////////////////////////////////////////////////////////////////////////////
494 // CookieTreeQuotaNode, public:
496 CookieTreeQuotaNode::CookieTreeQuotaNode(
497 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
)
498 : CookieTreeNode(base::UTF8ToUTF16(quota_info
->host
)),
499 quota_info_(quota_info
) {
502 CookieTreeQuotaNode::~CookieTreeQuotaNode() {}
504 void CookieTreeQuotaNode::DeleteStoredObjects() {
505 // Calling this function may cause unexpected over-quota state of origin.
506 // However, it'll caused no problem, just prevent usage growth of the origin.
507 LocalDataContainer
* container
= GetModel()->data_container();
510 container
->quota_helper_
->RevokeHostQuota(quota_info_
->host
);
511 container
->quota_info_list_
.erase(quota_info_
);
515 CookieTreeNode::DetailedInfo
CookieTreeQuotaNode::GetDetailedInfo() const {
516 return DetailedInfo().InitQuota(&*quota_info_
);
519 ///////////////////////////////////////////////////////////////////////////////
520 // CookieTreeChannelIDNode, public:
522 CookieTreeChannelIDNode::CookieTreeChannelIDNode(
523 net::ChannelIDStore::ChannelIDList::iterator channel_id
)
524 : CookieTreeNode(base::ASCIIToUTF16(channel_id
->server_identifier())),
525 channel_id_(channel_id
) {
528 CookieTreeChannelIDNode::~CookieTreeChannelIDNode() {}
530 void CookieTreeChannelIDNode::DeleteStoredObjects() {
531 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
534 container
->channel_id_helper_
->DeleteChannelID(
535 channel_id_
->server_identifier());
536 container
->channel_id_list_
.erase(channel_id_
);
540 CookieTreeNode::DetailedInfo
541 CookieTreeChannelIDNode::GetDetailedInfo() const {
542 return DetailedInfo().InitChannelID(&*channel_id_
);
545 ///////////////////////////////////////////////////////////////////////////////
546 // CookieTreeServiceWorkerNode, public:
548 CookieTreeServiceWorkerNode::CookieTreeServiceWorkerNode(
549 std::list
<content::ServiceWorkerUsageInfo
>::iterator service_worker_info
)
550 : CookieTreeNode(base::UTF8ToUTF16(service_worker_info
->origin
.spec())),
551 service_worker_info_(service_worker_info
) {
554 CookieTreeServiceWorkerNode::~CookieTreeServiceWorkerNode() {
557 void CookieTreeServiceWorkerNode::DeleteStoredObjects() {
558 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
561 container
->service_worker_helper_
->DeleteServiceWorkers(
562 service_worker_info_
->origin
);
563 container
->service_worker_info_list_
.erase(service_worker_info_
);
567 CookieTreeNode::DetailedInfo
CookieTreeServiceWorkerNode::GetDetailedInfo()
569 return DetailedInfo().InitServiceWorker(&*service_worker_info_
);
572 ///////////////////////////////////////////////////////////////////////////////
573 // CookieTreeCacheStorageNode, public:
575 CookieTreeCacheStorageNode::CookieTreeCacheStorageNode(
576 std::list
<content::CacheStorageUsageInfo
>::iterator cache_storage_info
)
577 : CookieTreeNode(base::UTF8ToUTF16(cache_storage_info
->origin
.spec())),
578 cache_storage_info_(cache_storage_info
) {}
580 CookieTreeCacheStorageNode::~CookieTreeCacheStorageNode() {}
582 void CookieTreeCacheStorageNode::DeleteStoredObjects() {
583 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
586 container
->cache_storage_helper_
->DeleteCacheStorage(
587 cache_storage_info_
->origin
);
588 container
->cache_storage_info_list_
.erase(cache_storage_info_
);
592 CookieTreeNode::DetailedInfo
CookieTreeCacheStorageNode::GetDetailedInfo()
594 return DetailedInfo().InitCacheStorage(&*cache_storage_info_
);
597 ///////////////////////////////////////////////////////////////////////////////
598 // CookieTreeRootNode, public:
600 CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel
* model
)
604 CookieTreeRootNode::~CookieTreeRootNode() {}
606 CookieTreeHostNode
* CookieTreeRootNode::GetOrCreateHostNode(
608 scoped_ptr
<CookieTreeHostNode
> host_node(
609 new CookieTreeHostNode(url
));
611 // First see if there is an existing match.
612 std::vector
<CookieTreeNode
*>::iterator host_node_iterator
=
613 std::lower_bound(children().begin(), children().end(), host_node
.get(),
614 HostNodeComparator());
615 if (host_node_iterator
!= children().end() &&
616 CookieTreeHostNode::TitleForUrl(url
) ==
617 (*host_node_iterator
)->GetTitle())
618 return static_cast<CookieTreeHostNode
*>(*host_node_iterator
);
619 // Node doesn't exist, insert the new one into the (ordered) children.
621 model_
->Add(this, host_node
.get(),
622 (host_node_iterator
- children().begin()));
623 return host_node
.release();
626 CookiesTreeModel
* CookieTreeRootNode::GetModel() const {
630 CookieTreeNode::DetailedInfo
CookieTreeRootNode::GetDetailedInfo() const {
631 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT
);
634 ///////////////////////////////////////////////////////////////////////////////
635 // CookieTreeHostNode, public:
638 base::string16
CookieTreeHostNode::TitleForUrl(const GURL
& url
) {
639 const std::string
file_origin_node_name(
640 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
641 return base::UTF8ToUTF16(url
.SchemeIsFile() ? file_origin_node_name
645 CookieTreeHostNode::CookieTreeHostNode(const GURL
& url
)
646 : CookieTreeNode(TitleForUrl(url
)),
648 canonicalized_host_(CanonicalizeHost(url
)) {}
650 CookieTreeHostNode::~CookieTreeHostNode() {}
652 const std::string
CookieTreeHostNode::GetHost() const {
653 const std::string
file_origin_node_name(
654 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
655 return url_
.SchemeIsFile() ? file_origin_node_name
: url_
.host();
658 CookieTreeNode::DetailedInfo
CookieTreeHostNode::GetDetailedInfo() const {
659 return DetailedInfo().InitHost();
662 CookieTreeCookiesNode
* CookieTreeHostNode::GetOrCreateCookiesNode() {
664 return cookies_child_
;
665 cookies_child_
= new CookieTreeCookiesNode
;
666 AddChildSortedByTitle(cookies_child_
);
667 return cookies_child_
;
670 CookieTreeDatabasesNode
* CookieTreeHostNode::GetOrCreateDatabasesNode() {
671 if (databases_child_
)
672 return databases_child_
;
673 databases_child_
= new CookieTreeDatabasesNode
;
674 AddChildSortedByTitle(databases_child_
);
675 return databases_child_
;
678 CookieTreeLocalStoragesNode
*
679 CookieTreeHostNode::GetOrCreateLocalStoragesNode() {
680 if (local_storages_child_
)
681 return local_storages_child_
;
682 local_storages_child_
= new CookieTreeLocalStoragesNode
;
683 AddChildSortedByTitle(local_storages_child_
);
684 return local_storages_child_
;
687 CookieTreeSessionStoragesNode
*
688 CookieTreeHostNode::GetOrCreateSessionStoragesNode() {
689 if (session_storages_child_
)
690 return session_storages_child_
;
691 session_storages_child_
= new CookieTreeSessionStoragesNode
;
692 AddChildSortedByTitle(session_storages_child_
);
693 return session_storages_child_
;
696 CookieTreeAppCachesNode
* CookieTreeHostNode::GetOrCreateAppCachesNode() {
697 if (appcaches_child_
)
698 return appcaches_child_
;
699 appcaches_child_
= new CookieTreeAppCachesNode
;
700 AddChildSortedByTitle(appcaches_child_
);
701 return appcaches_child_
;
704 CookieTreeIndexedDBsNode
* CookieTreeHostNode::GetOrCreateIndexedDBsNode() {
705 if (indexed_dbs_child_
)
706 return indexed_dbs_child_
;
707 indexed_dbs_child_
= new CookieTreeIndexedDBsNode
;
708 AddChildSortedByTitle(indexed_dbs_child_
);
709 return indexed_dbs_child_
;
712 CookieTreeFileSystemsNode
* CookieTreeHostNode::GetOrCreateFileSystemsNode() {
713 if (file_systems_child_
)
714 return file_systems_child_
;
715 file_systems_child_
= new CookieTreeFileSystemsNode
;
716 AddChildSortedByTitle(file_systems_child_
);
717 return file_systems_child_
;
720 CookieTreeQuotaNode
* CookieTreeHostNode::UpdateOrCreateQuotaNode(
721 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
) {
724 quota_child_
= new CookieTreeQuotaNode(quota_info
);
725 AddChildSortedByTitle(quota_child_
);
729 CookieTreeChannelIDsNode
*
730 CookieTreeHostNode::GetOrCreateChannelIDsNode() {
731 if (channel_ids_child_
)
732 return channel_ids_child_
;
733 channel_ids_child_
= new CookieTreeChannelIDsNode
;
734 AddChildSortedByTitle(channel_ids_child_
);
735 return channel_ids_child_
;
738 CookieTreeServiceWorkersNode
*
739 CookieTreeHostNode::GetOrCreateServiceWorkersNode() {
740 if (service_workers_child_
)
741 return service_workers_child_
;
742 service_workers_child_
= new CookieTreeServiceWorkersNode
;
743 AddChildSortedByTitle(service_workers_child_
);
744 return service_workers_child_
;
747 CookieTreeCacheStoragesNode
*
748 CookieTreeHostNode::GetOrCreateCacheStoragesNode() {
749 if (cache_storages_child_
)
750 return cache_storages_child_
;
751 cache_storages_child_
= new CookieTreeCacheStoragesNode
;
752 AddChildSortedByTitle(cache_storages_child_
);
753 return cache_storages_child_
;
756 CookieTreeFlashLSONode
* CookieTreeHostNode::GetOrCreateFlashLSONode(
757 const std::string
& domain
) {
758 DCHECK_EQ(GetHost(), domain
);
759 if (flash_lso_child_
)
760 return flash_lso_child_
;
761 flash_lso_child_
= new CookieTreeFlashLSONode(domain
);
762 AddChildSortedByTitle(flash_lso_child_
);
763 return flash_lso_child_
;
766 void CookieTreeHostNode::CreateContentException(
767 content_settings::CookieSettings
* cookie_settings
,
768 ContentSetting setting
) const {
769 DCHECK(setting
== CONTENT_SETTING_ALLOW
||
770 setting
== CONTENT_SETTING_BLOCK
||
771 setting
== CONTENT_SETTING_SESSION_ONLY
);
772 if (CanCreateContentException()) {
773 cookie_settings
->ResetCookieSetting(
774 ContentSettingsPattern::FromURLNoWildcard(url_
),
775 ContentSettingsPattern::Wildcard());
776 cookie_settings
->SetCookieSetting(
777 ContentSettingsPattern::FromURL(url_
),
778 ContentSettingsPattern::Wildcard(), setting
);
782 bool CookieTreeHostNode::CanCreateContentException() const {
783 return !url_
.SchemeIsFile();
786 ///////////////////////////////////////////////////////////////////////////////
787 // CookieTreeCookiesNode, public:
789 CookieTreeCookiesNode::CookieTreeCookiesNode()
790 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES
)) {
793 CookieTreeCookiesNode::~CookieTreeCookiesNode() {
796 CookieTreeNode::DetailedInfo
CookieTreeCookiesNode::GetDetailedInfo() const {
797 return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES
);
800 ///////////////////////////////////////////////////////////////////////////////
801 // CookieTreeAppCachesNode, public:
803 CookieTreeAppCachesNode::CookieTreeAppCachesNode()
804 : CookieTreeNode(l10n_util::GetStringUTF16(
805 IDS_COOKIES_APPLICATION_CACHES
)) {
808 CookieTreeAppCachesNode::~CookieTreeAppCachesNode() {}
810 CookieTreeNode::DetailedInfo
CookieTreeAppCachesNode::GetDetailedInfo() const {
811 return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES
);
814 ///////////////////////////////////////////////////////////////////////////////
815 // CookieTreeDatabasesNode, public:
817 CookieTreeDatabasesNode::CookieTreeDatabasesNode()
818 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES
)) {
821 CookieTreeDatabasesNode::~CookieTreeDatabasesNode() {}
823 CookieTreeNode::DetailedInfo
CookieTreeDatabasesNode::GetDetailedInfo() const {
824 return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES
);
827 ///////////////////////////////////////////////////////////////////////////////
828 // CookieTreeLocalStoragesNode, public:
830 CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode()
831 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE
)) {
834 CookieTreeLocalStoragesNode::~CookieTreeLocalStoragesNode() {}
836 CookieTreeNode::DetailedInfo
837 CookieTreeLocalStoragesNode::GetDetailedInfo() const {
838 return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES
);
841 ///////////////////////////////////////////////////////////////////////////////
842 // CookieTreeSessionStoragesNode, public:
844 CookieTreeSessionStoragesNode::CookieTreeSessionStoragesNode()
845 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE
)) {
848 CookieTreeSessionStoragesNode::~CookieTreeSessionStoragesNode() {}
850 CookieTreeNode::DetailedInfo
851 CookieTreeSessionStoragesNode::GetDetailedInfo() const {
852 return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES
);
855 ///////////////////////////////////////////////////////////////////////////////
856 // CookieTreeIndexedDBsNode, public:
858 CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode()
859 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS
)) {
862 CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {}
864 CookieTreeNode::DetailedInfo
865 CookieTreeIndexedDBsNode::GetDetailedInfo() const {
866 return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS
);
869 ///////////////////////////////////////////////////////////////////////////////
870 // CookieTreeFileSystemsNode, public:
872 CookieTreeFileSystemsNode::CookieTreeFileSystemsNode()
873 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS
)) {
876 CookieTreeFileSystemsNode::~CookieTreeFileSystemsNode() {}
878 CookieTreeNode::DetailedInfo
879 CookieTreeFileSystemsNode::GetDetailedInfo() const {
880 return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS
);
883 ///////////////////////////////////////////////////////////////////////////////
884 // CookieTreeChannelIDsNode, public:
886 CookieTreeChannelIDsNode::CookieTreeChannelIDsNode()
888 l10n_util::GetStringUTF16(IDS_COOKIES_CHANNEL_IDS
)) {
891 CookieTreeChannelIDsNode::~CookieTreeChannelIDsNode() {}
893 CookieTreeNode::DetailedInfo
894 CookieTreeChannelIDsNode::GetDetailedInfo() const {
895 return DetailedInfo().Init(DetailedInfo::TYPE_CHANNEL_IDS
);
898 void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode
* new_child
) {
900 std::vector
<CookieTreeNode
*>::iterator iter
=
901 std::lower_bound(children().begin(), children().end(), new_child
,
902 NodeTitleComparator());
903 GetModel()->Add(this, new_child
, iter
- children().begin());
906 ///////////////////////////////////////////////////////////////////////////////
907 // CookieTreeServiceWorkersNode, public:
909 CookieTreeServiceWorkersNode::CookieTreeServiceWorkersNode()
910 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SERVICE_WORKERS
)) {
913 CookieTreeServiceWorkersNode::~CookieTreeServiceWorkersNode() {
916 CookieTreeNode::DetailedInfo
CookieTreeServiceWorkersNode::GetDetailedInfo()
918 return DetailedInfo().Init(DetailedInfo::TYPE_SERVICE_WORKERS
);
921 ///////////////////////////////////////////////////////////////////////////////
922 // CookieTreeCacheStoragesNode, public:
924 CookieTreeCacheStoragesNode::CookieTreeCacheStoragesNode()
925 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_CACHE_STORAGE
)) {}
927 CookieTreeCacheStoragesNode::~CookieTreeCacheStoragesNode() {}
929 CookieTreeNode::DetailedInfo
CookieTreeCacheStoragesNode::GetDetailedInfo()
931 return DetailedInfo().Init(DetailedInfo::TYPE_CACHE_STORAGES
);
934 ///////////////////////////////////////////////////////////////////////////////
935 // CookieTreeFlashLSONode
936 CookieTreeFlashLSONode::CookieTreeFlashLSONode(
937 const std::string
& domain
)
939 CookieTreeFlashLSONode::~CookieTreeFlashLSONode() {}
941 void CookieTreeFlashLSONode::DeleteStoredObjects() {
942 // We are one level below the host node.
943 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(parent());
944 CHECK_EQ(host
->GetDetailedInfo().node_type
,
945 CookieTreeNode::DetailedInfo::TYPE_HOST
);
946 LocalDataContainer
* container
= GetModel()->data_container();
947 container
->flash_lso_helper_
->DeleteFlashLSOsForSite(domain_
);
950 CookieTreeNode::DetailedInfo
CookieTreeFlashLSONode::GetDetailedInfo() const {
951 return DetailedInfo().InitFlashLSO(domain_
);
954 ///////////////////////////////////////////////////////////////////////////////
955 // ScopedBatchUpdateNotifier
956 CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier(
957 CookiesTreeModel
* model
,
958 CookieTreeNode
* node
)
959 : model_(model
), node_(node
) {
960 model_
->RecordBatchSeen();
963 CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() {
964 if (batch_in_progress_
) {
965 model_
->NotifyObserverTreeNodeChanged(node_
);
966 model_
->NotifyObserverEndBatch();
968 // If no batch started, and this is the last batch, give the model a chance
969 // to send out a final notification.
970 model_
->MaybeNotifyBatchesEnded();
974 void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() {
975 if (!batch_in_progress_
) {
976 model_
->NotifyObserverBeginBatch();
977 batch_in_progress_
= true;
981 ///////////////////////////////////////////////////////////////////////////////
982 // CookiesTreeModel, public:
983 CookiesTreeModel::CookiesTreeModel(
984 LocalDataContainer
* data_container
,
985 ExtensionSpecialStoragePolicy
* special_storage_policy
,
986 bool group_by_cookie_source
)
987 : ui::TreeNodeModel
<CookieTreeNode
>(new CookieTreeRootNode(this)),
988 data_container_(data_container
),
989 #if defined(ENABLE_EXTENSIONS)
990 special_storage_policy_(special_storage_policy
),
992 group_by_cookie_source_(group_by_cookie_source
) {
993 data_container_
->Init(this);
996 CookiesTreeModel::~CookiesTreeModel() {
1000 int CookiesTreeModel::GetSendForMessageID(const net::CanonicalCookie
& cookie
) {
1001 if (cookie
.IsSecure()) {
1002 if (cookie
.IsFirstPartyOnly())
1003 return IDS_COOKIES_COOKIE_SENDFOR_SECURE_FIRSTPARTY
;
1004 return IDS_COOKIES_COOKIE_SENDFOR_SECURE
;
1006 if (cookie
.IsFirstPartyOnly())
1007 return IDS_COOKIES_COOKIE_SENDFOR_FIRSTPARTY
;
1008 return IDS_COOKIES_COOKIE_SENDFOR_ANY
;
1011 ///////////////////////////////////////////////////////////////////////////////
1012 // CookiesTreeModel, TreeModel methods (public):
1014 // TreeModel methods:
1015 // Returns the set of icons for the nodes in the tree. You only need override
1016 // this if you don't want to use the default folder icons.
1017 void CookiesTreeModel::GetIcons(std::vector
<gfx::ImageSkia
>* icons
) {
1018 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
1019 IDR_DEFAULT_FAVICON
).ToImageSkia());
1020 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
1021 IDR_COOKIE_ICON
).ToImageSkia());
1022 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
1023 IDR_COOKIE_STORAGE_ICON
).ToImageSkia());
1026 // Returns the index of the icon to use for |node|. Return -1 to use the
1027 // default icon. The index is relative to the list of icons returned from
1029 int CookiesTreeModel::GetIconIndex(ui::TreeModelNode
* node
) {
1030 CookieTreeNode
* ct_node
= static_cast<CookieTreeNode
*>(node
);
1031 switch (ct_node
->GetDetailedInfo().node_type
) {
1032 case CookieTreeNode::DetailedInfo::TYPE_HOST
:
1034 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
1036 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
1038 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
1039 return DATABASE
; // close enough
1040 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
1041 return DATABASE
; // ditto
1042 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
1043 return DATABASE
; // ditto
1044 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
1045 return DATABASE
; // ditto
1046 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
1047 return DATABASE
; // ditto
1048 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
1050 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
1051 return COOKIE
; // It's kinda like a cookie?
1052 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER
:
1053 return DATABASE
; // Just like appcache
1054 case CookieTreeNode::DetailedInfo::TYPE_CACHE_STORAGE
:
1055 return DATABASE
; // ditto
1062 void CookiesTreeModel::DeleteAllStoredObjects() {
1063 NotifyObserverBeginBatch();
1064 CookieTreeNode
* root
= GetRoot();
1065 root
->DeleteStoredObjects();
1066 int num_children
= root
->child_count();
1067 for (int i
= num_children
- 1; i
>= 0; --i
)
1068 delete Remove(root
, root
->GetChild(i
));
1069 NotifyObserverTreeNodeChanged(root
);
1070 NotifyObserverEndBatch();
1073 void CookiesTreeModel::DeleteCookieNode(CookieTreeNode
* cookie_node
) {
1074 if (cookie_node
== GetRoot())
1076 cookie_node
->DeleteStoredObjects();
1077 CookieTreeNode
* parent_node
= cookie_node
->parent();
1078 delete Remove(parent_node
, cookie_node
);
1079 if (parent_node
->empty())
1080 DeleteCookieNode(parent_node
);
1083 void CookiesTreeModel::UpdateSearchResults(const base::string16
& filter
) {
1084 CookieTreeNode
* root
= GetRoot();
1085 SetBatchExpectation(1, true);
1086 ScopedBatchUpdateNotifier
notifier(this, root
);
1087 int num_children
= root
->child_count();
1088 notifier
.StartBatchUpdate();
1089 for (int i
= num_children
- 1; i
>= 0; --i
)
1090 delete Remove(root
, root
->GetChild(i
));
1092 PopulateCookieInfoWithFilter(data_container(), ¬ifier
, filter
);
1093 PopulateDatabaseInfoWithFilter(data_container(), ¬ifier
, filter
);
1094 PopulateLocalStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
1095 PopulateSessionStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
1096 PopulateAppCacheInfoWithFilter(data_container(), ¬ifier
, filter
);
1097 PopulateIndexedDBInfoWithFilter(data_container(), ¬ifier
, filter
);
1098 PopulateFileSystemInfoWithFilter(data_container(), ¬ifier
, filter
);
1099 PopulateQuotaInfoWithFilter(data_container(), ¬ifier
, filter
);
1100 PopulateChannelIDInfoWithFilter(data_container(), ¬ifier
, filter
);
1101 PopulateServiceWorkerUsageInfoWithFilter(data_container(), ¬ifier
, filter
);
1102 PopulateCacheStorageUsageInfoWithFilter(data_container(), ¬ifier
, filter
);
1105 #if defined(ENABLE_EXTENSIONS)
1106 const extensions::ExtensionSet
* CookiesTreeModel::ExtensionsProtectingNode(
1107 const CookieTreeNode
& cookie_node
) {
1108 if (!special_storage_policy_
.get())
1111 CookieTreeNode::DetailedInfo info
= cookie_node
.GetDetailedInfo();
1113 if (!TypeIsProtected(info
.node_type
))
1116 DCHECK(!info
.origin
.is_empty());
1117 return special_storage_policy_
->ExtensionsProtectingOrigin(info
.origin
);
1121 void CookiesTreeModel::AddCookiesTreeObserver(Observer
* observer
) {
1122 cookies_observer_list_
.AddObserver(observer
);
1123 // Call super so that TreeNodeModel can notify, too.
1124 ui::TreeNodeModel
<CookieTreeNode
>::AddObserver(observer
);
1127 void CookiesTreeModel::RemoveCookiesTreeObserver(Observer
* observer
) {
1128 cookies_observer_list_
.RemoveObserver(observer
);
1129 // Call super so that TreeNodeModel doesn't have dead pointers.
1130 ui::TreeNodeModel
<CookieTreeNode
>::RemoveObserver(observer
);
1133 void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer
* container
) {
1134 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1135 PopulateAppCacheInfoWithFilter(container
, ¬ifier
, base::string16());
1138 void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer
* container
) {
1139 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1140 PopulateCookieInfoWithFilter(container
, ¬ifier
, base::string16());
1143 void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer
* container
) {
1144 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1145 PopulateDatabaseInfoWithFilter(container
, ¬ifier
, base::string16());
1148 void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer
* container
) {
1149 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1150 PopulateLocalStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1153 void CookiesTreeModel::PopulateSessionStorageInfo(
1154 LocalDataContainer
* container
) {
1155 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1156 PopulateSessionStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1159 void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer
* container
) {
1160 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1161 PopulateIndexedDBInfoWithFilter(container
, ¬ifier
, base::string16());
1164 void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer
* container
) {
1165 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1166 PopulateFileSystemInfoWithFilter(container
, ¬ifier
, base::string16());
1169 void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer
* container
) {
1170 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1171 PopulateQuotaInfoWithFilter(container
, ¬ifier
, base::string16());
1174 void CookiesTreeModel::PopulateChannelIDInfo(
1175 LocalDataContainer
* container
) {
1176 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1177 PopulateChannelIDInfoWithFilter(container
, ¬ifier
, base::string16());
1180 void CookiesTreeModel::PopulateServiceWorkerUsageInfo(
1181 LocalDataContainer
* container
) {
1182 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1183 PopulateServiceWorkerUsageInfoWithFilter(
1184 container
, ¬ifier
, base::string16());
1187 void CookiesTreeModel::PopulateCacheStorageUsageInfo(
1188 LocalDataContainer
* container
) {
1189 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1190 PopulateCacheStorageUsageInfoWithFilter(container
, ¬ifier
,
1194 void CookiesTreeModel::PopulateFlashLSOInfo(
1195 LocalDataContainer
* container
) {
1196 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1197 PopulateFlashLSOInfoWithFilter(container
, ¬ifier
, base::string16());
1200 void CookiesTreeModel::PopulateAppCacheInfoWithFilter(
1201 LocalDataContainer
* container
,
1202 ScopedBatchUpdateNotifier
* notifier
,
1203 const base::string16
& filter
) {
1204 using content::AppCacheInfo
;
1205 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1207 if (container
->appcache_info_
.empty())
1210 notifier
->StartBatchUpdate();
1211 for (auto& origin
: container
->appcache_info_
) {
1212 base::string16 host_node_name
= base::UTF8ToUTF16(origin
.first
.host());
1213 if (filter
.empty() ||
1214 (host_node_name
.find(filter
) != base::string16::npos
)) {
1215 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
.first
);
1216 CookieTreeAppCachesNode
* appcaches_node
=
1217 host_node
->GetOrCreateAppCachesNode();
1219 for (std::list
<AppCacheInfo
>::iterator info
= origin
.second
.begin();
1220 info
!= origin
.second
.end(); ++info
) {
1221 appcaches_node
->AddAppCacheNode(
1222 new CookieTreeAppCacheNode(origin
.first
, info
));
1228 void CookiesTreeModel::PopulateCookieInfoWithFilter(
1229 LocalDataContainer
* container
,
1230 ScopedBatchUpdateNotifier
* notifier
,
1231 const base::string16
& filter
) {
1232 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1234 notifier
->StartBatchUpdate();
1235 for (CookieList::iterator it
= container
->cookie_list_
.begin();
1236 it
!= container
->cookie_list_
.end(); ++it
) {
1237 GURL source
= CanonicalizeCookieSource(*it
);
1238 if (source
.is_empty() || !group_by_cookie_source_
) {
1239 std::string domain
= it
->Domain();
1240 if (domain
.length() > 1 && domain
[0] == '.')
1241 domain
= domain
.substr(1);
1243 // We treat secure cookies just the same as normal ones.
1244 source
= GURL(std::string(url::kHttpScheme
) +
1245 url::kStandardSchemeSeparator
+ domain
+ "/");
1248 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(source
)
1249 .find(filter
) != base::string16::npos
)) {
1250 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(source
);
1251 CookieTreeCookiesNode
* cookies_node
=
1252 host_node
->GetOrCreateCookiesNode();
1253 CookieTreeCookieNode
* new_cookie
= new CookieTreeCookieNode(it
);
1254 cookies_node
->AddCookieNode(new_cookie
);
1259 void CookiesTreeModel::PopulateDatabaseInfoWithFilter(
1260 LocalDataContainer
* container
,
1261 ScopedBatchUpdateNotifier
* notifier
,
1262 const base::string16
& filter
) {
1263 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1265 if (container
->database_info_list_
.empty())
1268 notifier
->StartBatchUpdate();
1269 for (DatabaseInfoList::iterator database_info
=
1270 container
->database_info_list_
.begin();
1271 database_info
!= container
->database_info_list_
.end();
1273 GURL
origin(database_info
->identifier
.ToOrigin());
1275 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1276 .find(filter
) != base::string16::npos
)) {
1277 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1278 CookieTreeDatabasesNode
* databases_node
=
1279 host_node
->GetOrCreateDatabasesNode();
1280 databases_node
->AddDatabaseNode(
1281 new CookieTreeDatabaseNode(database_info
));
1286 void CookiesTreeModel::PopulateLocalStorageInfoWithFilter(
1287 LocalDataContainer
* container
,
1288 ScopedBatchUpdateNotifier
* notifier
,
1289 const base::string16
& filter
) {
1290 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1292 if (container
->local_storage_info_list_
.empty())
1295 notifier
->StartBatchUpdate();
1296 for (LocalStorageInfoList::iterator local_storage_info
=
1297 container
->local_storage_info_list_
.begin();
1298 local_storage_info
!= container
->local_storage_info_list_
.end();
1299 ++local_storage_info
) {
1300 const GURL
& origin(local_storage_info
->origin_url
);
1302 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1303 .find(filter
) != std::string::npos
)) {
1304 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1305 CookieTreeLocalStoragesNode
* local_storages_node
=
1306 host_node
->GetOrCreateLocalStoragesNode();
1307 local_storages_node
->AddLocalStorageNode(
1308 new CookieTreeLocalStorageNode(local_storage_info
));
1313 void CookiesTreeModel::PopulateSessionStorageInfoWithFilter(
1314 LocalDataContainer
* container
,
1315 ScopedBatchUpdateNotifier
* notifier
,
1316 const base::string16
& filter
) {
1317 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1319 if (container
->session_storage_info_list_
.empty())
1322 notifier
->StartBatchUpdate();
1323 for (LocalStorageInfoList::iterator session_storage_info
=
1324 container
->session_storage_info_list_
.begin();
1325 session_storage_info
!= container
->session_storage_info_list_
.end();
1326 ++session_storage_info
) {
1327 const GURL
& origin
= session_storage_info
->origin_url
;
1329 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1330 .find(filter
) != base::string16::npos
)) {
1331 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1332 CookieTreeSessionStoragesNode
* session_storages_node
=
1333 host_node
->GetOrCreateSessionStoragesNode();
1334 session_storages_node
->AddSessionStorageNode(
1335 new CookieTreeSessionStorageNode(session_storage_info
));
1340 void CookiesTreeModel::PopulateIndexedDBInfoWithFilter(
1341 LocalDataContainer
* container
,
1342 ScopedBatchUpdateNotifier
* notifier
,
1343 const base::string16
& filter
) {
1344 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1346 if (container
->indexed_db_info_list_
.empty())
1349 notifier
->StartBatchUpdate();
1350 for (IndexedDBInfoList::iterator indexed_db_info
=
1351 container
->indexed_db_info_list_
.begin();
1352 indexed_db_info
!= container
->indexed_db_info_list_
.end();
1353 ++indexed_db_info
) {
1354 const GURL
& origin
= indexed_db_info
->origin
;
1356 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1357 .find(filter
) != base::string16::npos
)) {
1358 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1359 CookieTreeIndexedDBsNode
* indexed_dbs_node
=
1360 host_node
->GetOrCreateIndexedDBsNode();
1361 indexed_dbs_node
->AddIndexedDBNode(
1362 new CookieTreeIndexedDBNode(indexed_db_info
));
1367 void CookiesTreeModel::PopulateChannelIDInfoWithFilter(
1368 LocalDataContainer
* container
,
1369 ScopedBatchUpdateNotifier
* notifier
,
1370 const base::string16
& filter
) {
1371 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1373 if (container
->channel_id_list_
.empty())
1376 notifier
->StartBatchUpdate();
1377 for (ChannelIDList::iterator channel_id_info
=
1378 container
->channel_id_list_
.begin();
1379 channel_id_info
!= container
->channel_id_list_
.end();
1380 ++channel_id_info
) {
1381 GURL
origin(channel_id_info
->server_identifier());
1382 if (!origin
.is_valid()) {
1383 // Channel ID. Make a valid URL to satisfy the
1384 // CookieTreeRootNode::GetOrCreateHostNode interface.
1385 origin
= GURL(std::string(url::kHttpsScheme
) +
1386 url::kStandardSchemeSeparator
+
1387 channel_id_info
->server_identifier() + "/");
1389 base::string16 title
= CookieTreeHostNode::TitleForUrl(origin
);
1390 if (filter
.empty() || title
.find(filter
) != base::string16::npos
) {
1391 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1392 CookieTreeChannelIDsNode
* channel_ids_node
=
1393 host_node
->GetOrCreateChannelIDsNode();
1394 channel_ids_node
->AddChannelIDNode(
1395 new CookieTreeChannelIDNode(channel_id_info
));
1400 void CookiesTreeModel::PopulateServiceWorkerUsageInfoWithFilter(
1401 LocalDataContainer
* container
,
1402 ScopedBatchUpdateNotifier
* notifier
,
1403 const base::string16
& filter
) {
1404 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1406 if (container
->service_worker_info_list_
.empty())
1409 notifier
->StartBatchUpdate();
1410 for (ServiceWorkerUsageInfoList::iterator service_worker_info
=
1411 container
->service_worker_info_list_
.begin();
1412 service_worker_info
!= container
->service_worker_info_list_
.end();
1413 ++service_worker_info
) {
1414 const GURL
& origin
= service_worker_info
->origin
;
1416 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1417 .find(filter
) != base::string16::npos
)) {
1418 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1419 CookieTreeServiceWorkersNode
* service_workers_node
=
1420 host_node
->GetOrCreateServiceWorkersNode();
1421 service_workers_node
->AddServiceWorkerNode(
1422 new CookieTreeServiceWorkerNode(service_worker_info
));
1427 void CookiesTreeModel::PopulateCacheStorageUsageInfoWithFilter(
1428 LocalDataContainer
* container
,
1429 ScopedBatchUpdateNotifier
* notifier
,
1430 const base::string16
& filter
) {
1431 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1433 if (container
->cache_storage_info_list_
.empty())
1436 notifier
->StartBatchUpdate();
1437 for (CacheStorageUsageInfoList::iterator cache_storage_info
=
1438 container
->cache_storage_info_list_
.begin();
1439 cache_storage_info
!= container
->cache_storage_info_list_
.end();
1440 ++cache_storage_info
) {
1441 const GURL
& origin
= cache_storage_info
->origin
;
1443 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1444 .find(filter
) != base::string16::npos
)) {
1445 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1446 CookieTreeCacheStoragesNode
* cache_storages_node
=
1447 host_node
->GetOrCreateCacheStoragesNode();
1448 cache_storages_node
->AddCacheStorageNode(
1449 new CookieTreeCacheStorageNode(cache_storage_info
));
1454 void CookiesTreeModel::PopulateFileSystemInfoWithFilter(
1455 LocalDataContainer
* container
,
1456 ScopedBatchUpdateNotifier
* notifier
,
1457 const base::string16
& filter
) {
1458 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1460 if (container
->file_system_info_list_
.empty())
1463 notifier
->StartBatchUpdate();
1464 for (FileSystemInfoList::iterator file_system_info
=
1465 container
->file_system_info_list_
.begin();
1466 file_system_info
!= container
->file_system_info_list_
.end();
1467 ++file_system_info
) {
1468 GURL
origin(file_system_info
->origin
);
1470 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1471 .find(filter
) != base::string16::npos
)) {
1472 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1473 CookieTreeFileSystemsNode
* file_systems_node
=
1474 host_node
->GetOrCreateFileSystemsNode();
1475 file_systems_node
->AddFileSystemNode(
1476 new CookieTreeFileSystemNode(file_system_info
));
1481 void CookiesTreeModel::PopulateQuotaInfoWithFilter(
1482 LocalDataContainer
* container
,
1483 ScopedBatchUpdateNotifier
* notifier
,
1484 const base::string16
& filter
) {
1485 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1487 if (container
->quota_info_list_
.empty())
1490 notifier
->StartBatchUpdate();
1491 for (QuotaInfoList::iterator quota_info
= container
->quota_info_list_
.begin();
1492 quota_info
!= container
->quota_info_list_
.end();
1494 if (filter
.empty() || (base::UTF8ToUTF16(quota_info
->host
).find(filter
) !=
1495 base::string16::npos
)) {
1496 CookieTreeHostNode
* host_node
=
1497 root
->GetOrCreateHostNode(GURL("http://" + quota_info
->host
));
1498 host_node
->UpdateOrCreateQuotaNode(quota_info
);
1503 void CookiesTreeModel::PopulateFlashLSOInfoWithFilter(
1504 LocalDataContainer
* container
,
1505 ScopedBatchUpdateNotifier
* notifier
,
1506 const base::string16
& filter
) {
1507 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1509 if (container
->flash_lso_domain_list_
.empty())
1512 std::string filter_utf8
= base::UTF16ToUTF8(filter
);
1513 notifier
->StartBatchUpdate();
1514 for (std::vector
<std::string
>::iterator it
=
1515 container
->flash_lso_domain_list_
.begin();
1516 it
!= container
->flash_lso_domain_list_
.end(); ++it
) {
1517 if (filter_utf8
.empty() || it
->find(filter_utf8
) != std::string::npos
) {
1518 // Create a fake origin for GetOrCreateHostNode().
1519 GURL
origin("http://" + *it
);
1520 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1521 host_node
->GetOrCreateFlashLSONode(*it
);
1526 void CookiesTreeModel::SetBatchExpectation(int batches_expected
, bool reset
) {
1527 batches_expected_
= batches_expected
;
1530 batches_started_
= 0;
1533 MaybeNotifyBatchesEnded();
1537 void CookiesTreeModel::RecordBatchSeen() {
1541 void CookiesTreeModel::NotifyObserverBeginBatch() {
1542 // Only notify the model once if we're batching in a nested manner.
1543 if (batches_started_
++ == 0) {
1544 FOR_EACH_OBSERVER(Observer
,
1545 cookies_observer_list_
,
1546 TreeModelBeginBatch(this));
1550 void CookiesTreeModel::NotifyObserverEndBatch() {
1552 MaybeNotifyBatchesEnded();
1555 void CookiesTreeModel::MaybeNotifyBatchesEnded() {
1556 // Only notify the observers if this is the outermost call to EndBatch() if
1557 // called in a nested manner.
1558 if (batches_ended_
== batches_started_
&&
1559 batches_seen_
== batches_expected_
) {
1560 FOR_EACH_OBSERVER(Observer
,
1561 cookies_observer_list_
,
1562 TreeModelEndBatch(this));