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.h"
20 #include "chrome/grit/generated_resources.h"
21 #include "content/public/common/url_constants.h"
22 #include "grit/theme_resources.h"
23 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
24 #include "net/cookies/canonical_cookie.h"
25 #include "net/url_request/url_request_context.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/image/image_skia.h"
29 #include "ui/resources/grit/ui_resources.h"
31 #if defined(ENABLE_EXTENSIONS)
32 #include "chrome/browser/extensions/extension_special_storage_policy.h"
33 #include "extensions/common/extension_set.h"
38 struct NodeTitleComparator
{
39 bool operator()(const CookieTreeNode
* lhs
, const CookieTreeNode
* rhs
) {
40 return lhs
->GetTitle() < rhs
->GetTitle();
44 // Comparison functor, for use in CookieTreeRootNode.
45 struct HostNodeComparator
{
46 bool operator()(const CookieTreeNode
* lhs
, const CookieTreeNode
* rhs
) {
47 // This comparator is only meant to compare CookieTreeHostNode types. Make
48 // sure we check this, as the static cast below is dangerous if we get the
50 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST
,
51 lhs
->GetDetailedInfo().node_type
);
52 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST
,
53 rhs
->GetDetailedInfo().node_type
);
55 const CookieTreeHostNode
* ltn
=
56 static_cast<const CookieTreeHostNode
*>(lhs
);
57 const CookieTreeHostNode
* rtn
=
58 static_cast<const CookieTreeHostNode
*>(rhs
);
60 // We want to order by registry controlled domain, so we would get
61 // google.com, ad.google.com, www.google.com,
62 // microsoft.com, ad.microsoft.com. CanonicalizeHost transforms the origins
63 // into a form like google.com.www so that string comparisons work.
64 return (ltn
->canonicalized_host() <
65 rtn
->canonicalized_host());
69 std::string
CanonicalizeHost(const GURL
& url
) {
70 // The canonicalized representation makes the registry controlled domain
71 // come first, and then adds subdomains in reverse order, e.g.
72 // 1.mail.google.com would become google.com.mail.1, and then a standard
73 // string comparison works to order hosts by registry controlled domain
74 // first. Leading dots are ignored, ".google.com" is the same as
77 if (url
.SchemeIsFile()) {
78 return std::string(url::kFileScheme
) +
79 url::kStandardSchemeSeparator
;
82 std::string host
= url
.host();
84 net::registry_controlled_domains::GetDomainAndRegistry(
86 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES
);
87 if (!retval
.length()) // Is an IP address or other special origin.
90 std::string::size_type position
= host
.rfind(retval
);
92 // The host may be the registry controlled domain, in which case fail fast.
93 if (position
== 0 || position
== std::string::npos
)
96 // If host is www.google.com, retval will contain google.com at this point.
97 // Start operating to the left of the registry controlled domain, e.g. in
98 // the www.google.com example, start at index 3.
101 // If position == 0, that means it's a dot; this will be ignored to treat
102 // ".google.com" the same as "google.com".
103 while (position
> 0) {
104 retval
+= std::string(".");
105 // Copy up to the next dot. host[position] is a dot so start after it.
106 std::string::size_type next_dot
= host
.rfind(".", position
- 1);
107 if (next_dot
== std::string::npos
) {
108 retval
+= host
.substr(0, position
);
111 retval
+= host
.substr(next_dot
+ 1, position
- (next_dot
+ 1));
117 #if defined(ENABLE_EXTENSIONS)
118 bool TypeIsProtected(CookieTreeNode::DetailedInfo::NodeType type
) {
120 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
122 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
124 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
126 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
128 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
130 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
132 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
134 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
136 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
138 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER
:
140 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO
:
149 // This function returns the local data container associated with a leaf tree
150 // node. The app node is assumed to be 3 levels above the leaf because of the
151 // following structure:
152 // root -> origin -> storage type -> leaf node
153 LocalDataContainer
* GetLocalDataContainerForNode(CookieTreeNode
* node
) {
154 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(
155 node
->parent()->parent());
156 CHECK_EQ(host
->GetDetailedInfo().node_type
,
157 CookieTreeNode::DetailedInfo::TYPE_HOST
);
158 return node
->GetModel()->data_container();
163 CookieTreeNode::DetailedInfo::DetailedInfo()
164 : node_type(TYPE_NONE
),
167 local_storage_info(NULL
),
168 session_storage_info(NULL
),
170 indexed_db_info(NULL
),
171 file_system_info(NULL
),
174 service_worker_info(NULL
) {
177 CookieTreeNode::DetailedInfo::~DetailedInfo() {}
179 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::Init(
181 DCHECK_EQ(TYPE_NONE
, node_type
);
186 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitHost() {
191 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitCookie(
192 const net::CanonicalCookie
* cookie
) {
194 this->cookie
= cookie
;
198 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitDatabase(
199 const BrowsingDataDatabaseHelper::DatabaseInfo
* database_info
) {
201 this->database_info
= database_info
;
202 origin
= database_info
->identifier
.ToOrigin();
206 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitLocalStorage(
207 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
208 local_storage_info
) {
209 Init(TYPE_LOCAL_STORAGE
);
210 this->local_storage_info
= local_storage_info
;
211 origin
= local_storage_info
->origin_url
;
215 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitSessionStorage(
216 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
217 session_storage_info
) {
218 Init(TYPE_SESSION_STORAGE
);
219 this->session_storage_info
= session_storage_info
;
220 origin
= session_storage_info
->origin_url
;
224 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitAppCache(
226 const content::AppCacheInfo
* appcache_info
) {
228 this->appcache_info
= appcache_info
;
229 this->origin
= origin
;
233 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitIndexedDB(
234 const content::IndexedDBInfo
* indexed_db_info
) {
235 Init(TYPE_INDEXED_DB
);
236 this->indexed_db_info
= indexed_db_info
;
237 this->origin
= indexed_db_info
->origin_
;
241 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFileSystem(
242 const BrowsingDataFileSystemHelper::FileSystemInfo
* file_system_info
) {
243 Init(TYPE_FILE_SYSTEM
);
244 this->file_system_info
= file_system_info
;
245 this->origin
= file_system_info
->origin
;
249 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitQuota(
250 const BrowsingDataQuotaHelper::QuotaInfo
* quota_info
) {
252 this->quota_info
= quota_info
;
256 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitChannelID(
257 const net::ChannelIDStore::ChannelID
* channel_id
) {
258 Init(TYPE_CHANNEL_ID
);
259 this->channel_id
= channel_id
;
263 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitServiceWorker(
264 const content::ServiceWorkerUsageInfo
* service_worker_info
) {
265 Init(TYPE_SERVICE_WORKER
);
266 this->service_worker_info
= service_worker_info
;
267 this->origin
= service_worker_info
->origin
;
271 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFlashLSO(
272 const std::string
& flash_lso_domain
) {
273 Init(TYPE_FLASH_LSO
);
274 this->flash_lso_domain
= flash_lso_domain
;
278 ///////////////////////////////////////////////////////////////////////////////
279 // CookieTreeNode, public:
281 void CookieTreeNode::DeleteStoredObjects() {
282 std::for_each(children().begin(),
284 std::mem_fun(&CookieTreeNode::DeleteStoredObjects
));
287 CookiesTreeModel
* CookieTreeNode::GetModel() const {
289 return parent()->GetModel();
294 ///////////////////////////////////////////////////////////////////////////////
295 // CookieTreeCookieNode, public:
297 CookieTreeCookieNode::CookieTreeCookieNode(
298 std::list
<net::CanonicalCookie
>::iterator cookie
)
299 : CookieTreeNode(base::UTF8ToUTF16(cookie
->Name())),
303 CookieTreeCookieNode::~CookieTreeCookieNode() {}
305 void CookieTreeCookieNode::DeleteStoredObjects() {
306 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
307 container
->cookie_helper_
->DeleteCookie(*cookie_
);
308 container
->cookie_list_
.erase(cookie_
);
311 CookieTreeNode::DetailedInfo
CookieTreeCookieNode::GetDetailedInfo() const {
312 return DetailedInfo().InitCookie(&*cookie_
);
315 ///////////////////////////////////////////////////////////////////////////////
316 // CookieTreeAppCacheNode, public:
318 CookieTreeAppCacheNode::CookieTreeAppCacheNode(
319 const GURL
& origin_url
,
320 std::list
<content::AppCacheInfo
>::iterator appcache_info
)
321 : CookieTreeNode(base::UTF8ToUTF16(appcache_info
->manifest_url
.spec())),
322 origin_url_(origin_url
),
323 appcache_info_(appcache_info
) {
326 CookieTreeAppCacheNode::~CookieTreeAppCacheNode() {
329 void CookieTreeAppCacheNode::DeleteStoredObjects() {
330 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
333 DCHECK(container
->appcache_helper_
.get());
334 container
->appcache_helper_
335 ->DeleteAppCacheGroup(appcache_info_
->manifest_url
);
336 container
->appcache_info_
[origin_url_
].erase(appcache_info_
);
340 CookieTreeNode::DetailedInfo
CookieTreeAppCacheNode::GetDetailedInfo() const {
341 return DetailedInfo().InitAppCache(origin_url_
, &*appcache_info_
);
344 ///////////////////////////////////////////////////////////////////////////////
345 // CookieTreeDatabaseNode, public:
347 CookieTreeDatabaseNode::CookieTreeDatabaseNode(
348 std::list
<BrowsingDataDatabaseHelper::DatabaseInfo
>::iterator database_info
)
349 : CookieTreeNode(database_info
->database_name
.empty() ?
350 l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME
) :
351 base::UTF8ToUTF16(database_info
->database_name
)),
352 database_info_(database_info
) {
355 CookieTreeDatabaseNode::~CookieTreeDatabaseNode() {}
357 void CookieTreeDatabaseNode::DeleteStoredObjects() {
358 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
361 container
->database_helper_
->DeleteDatabase(
362 database_info_
->identifier
.ToString(), database_info_
->database_name
);
363 container
->database_info_list_
.erase(database_info_
);
367 CookieTreeNode::DetailedInfo
CookieTreeDatabaseNode::GetDetailedInfo() const {
368 return DetailedInfo().InitDatabase(&*database_info_
);
371 ///////////////////////////////////////////////////////////////////////////////
372 // CookieTreeLocalStorageNode, public:
374 CookieTreeLocalStorageNode::CookieTreeLocalStorageNode(
375 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
377 : CookieTreeNode(base::UTF8ToUTF16(local_storage_info
->origin_url
.spec())),
378 local_storage_info_(local_storage_info
) {
381 CookieTreeLocalStorageNode::~CookieTreeLocalStorageNode() {}
383 void CookieTreeLocalStorageNode::DeleteStoredObjects() {
384 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
387 container
->local_storage_helper_
->DeleteOrigin(
388 local_storage_info_
->origin_url
);
389 container
->local_storage_info_list_
.erase(local_storage_info_
);
393 CookieTreeNode::DetailedInfo
394 CookieTreeLocalStorageNode::GetDetailedInfo() const {
395 return DetailedInfo().InitLocalStorage(
396 &*local_storage_info_
);
399 ///////////////////////////////////////////////////////////////////////////////
400 // CookieTreeSessionStorageNode, public:
402 CookieTreeSessionStorageNode::CookieTreeSessionStorageNode(
403 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
404 session_storage_info
)
406 base::UTF8ToUTF16(session_storage_info
->origin_url
.spec())),
407 session_storage_info_(session_storage_info
) {
410 CookieTreeSessionStorageNode::~CookieTreeSessionStorageNode() {}
412 void CookieTreeSessionStorageNode::DeleteStoredObjects() {
413 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
416 // TODO(rsesek): There's no easy way to get the namespace_id for a session
417 // storage, nor is there an easy way to clear session storage just by
418 // origin. This is probably okay since session storage is not persistent.
419 // http://crbug.com/168996
420 container
->session_storage_info_list_
.erase(session_storage_info_
);
424 CookieTreeNode::DetailedInfo
425 CookieTreeSessionStorageNode::GetDetailedInfo() const {
426 return DetailedInfo().InitSessionStorage(&*session_storage_info_
);
429 ///////////////////////////////////////////////////////////////////////////////
430 // CookieTreeIndexedDBNode, public:
432 CookieTreeIndexedDBNode::CookieTreeIndexedDBNode(
433 std::list
<content::IndexedDBInfo
>::iterator
435 : CookieTreeNode(base::UTF8ToUTF16(
436 indexed_db_info
->origin_
.spec())),
437 indexed_db_info_(indexed_db_info
) {
440 CookieTreeIndexedDBNode::~CookieTreeIndexedDBNode() {}
442 void CookieTreeIndexedDBNode::DeleteStoredObjects() {
443 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
446 container
->indexed_db_helper_
->DeleteIndexedDB(
447 indexed_db_info_
->origin_
);
448 container
->indexed_db_info_list_
.erase(indexed_db_info_
);
452 CookieTreeNode::DetailedInfo
CookieTreeIndexedDBNode::GetDetailedInfo() const {
453 return DetailedInfo().InitIndexedDB(&*indexed_db_info_
);
456 ///////////////////////////////////////////////////////////////////////////////
457 // CookieTreeFileSystemNode, public:
459 CookieTreeFileSystemNode::CookieTreeFileSystemNode(
460 std::list
<BrowsingDataFileSystemHelper::FileSystemInfo
>::iterator
462 : CookieTreeNode(base::UTF8ToUTF16(
463 file_system_info
->origin
.spec())),
464 file_system_info_(file_system_info
) {
467 CookieTreeFileSystemNode::~CookieTreeFileSystemNode() {}
469 void CookieTreeFileSystemNode::DeleteStoredObjects() {
470 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
473 container
->file_system_helper_
->DeleteFileSystemOrigin(
474 file_system_info_
->origin
);
475 container
->file_system_info_list_
.erase(file_system_info_
);
479 CookieTreeNode::DetailedInfo
CookieTreeFileSystemNode::GetDetailedInfo() const {
480 return DetailedInfo().InitFileSystem(&*file_system_info_
);
483 ///////////////////////////////////////////////////////////////////////////////
484 // CookieTreeQuotaNode, public:
486 CookieTreeQuotaNode::CookieTreeQuotaNode(
487 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
)
488 : CookieTreeNode(base::UTF8ToUTF16(quota_info
->host
)),
489 quota_info_(quota_info
) {
492 CookieTreeQuotaNode::~CookieTreeQuotaNode() {}
494 void CookieTreeQuotaNode::DeleteStoredObjects() {
495 // Calling this function may cause unexpected over-quota state of origin.
496 // However, it'll caused no problem, just prevent usage growth of the origin.
497 LocalDataContainer
* container
= GetModel()->data_container();
500 container
->quota_helper_
->RevokeHostQuota(quota_info_
->host
);
501 container
->quota_info_list_
.erase(quota_info_
);
505 CookieTreeNode::DetailedInfo
CookieTreeQuotaNode::GetDetailedInfo() const {
506 return DetailedInfo().InitQuota(&*quota_info_
);
509 ///////////////////////////////////////////////////////////////////////////////
510 // CookieTreeChannelIDNode, public:
512 CookieTreeChannelIDNode::CookieTreeChannelIDNode(
513 net::ChannelIDStore::ChannelIDList::iterator channel_id
)
514 : CookieTreeNode(base::ASCIIToUTF16(channel_id
->server_identifier())),
515 channel_id_(channel_id
) {
518 CookieTreeChannelIDNode::~CookieTreeChannelIDNode() {}
520 void CookieTreeChannelIDNode::DeleteStoredObjects() {
521 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
524 container
->channel_id_helper_
->DeleteChannelID(
525 channel_id_
->server_identifier());
526 container
->channel_id_list_
.erase(channel_id_
);
530 CookieTreeNode::DetailedInfo
531 CookieTreeChannelIDNode::GetDetailedInfo() const {
532 return DetailedInfo().InitChannelID(&*channel_id_
);
535 ///////////////////////////////////////////////////////////////////////////////
536 // CookieTreeServiceWorkerNode, public:
538 CookieTreeServiceWorkerNode::CookieTreeServiceWorkerNode(
539 std::list
<content::ServiceWorkerUsageInfo
>::iterator service_worker_info
)
540 : CookieTreeNode(base::UTF8ToUTF16(service_worker_info
->origin
.spec())),
541 service_worker_info_(service_worker_info
) {
544 CookieTreeServiceWorkerNode::~CookieTreeServiceWorkerNode() {
547 void CookieTreeServiceWorkerNode::DeleteStoredObjects() {
548 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
551 container
->service_worker_helper_
->DeleteServiceWorkers(
552 service_worker_info_
->origin
);
553 container
->service_worker_info_list_
.erase(service_worker_info_
);
557 CookieTreeNode::DetailedInfo
CookieTreeServiceWorkerNode::GetDetailedInfo()
559 return DetailedInfo().InitServiceWorker(&*service_worker_info_
);
562 ///////////////////////////////////////////////////////////////////////////////
563 // CookieTreeRootNode, public:
565 CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel
* model
)
569 CookieTreeRootNode::~CookieTreeRootNode() {}
571 CookieTreeHostNode
* CookieTreeRootNode::GetOrCreateHostNode(
573 scoped_ptr
<CookieTreeHostNode
> host_node(
574 new CookieTreeHostNode(url
));
576 // First see if there is an existing match.
577 std::vector
<CookieTreeNode
*>::iterator host_node_iterator
=
578 std::lower_bound(children().begin(), children().end(), host_node
.get(),
579 HostNodeComparator());
580 if (host_node_iterator
!= children().end() &&
581 CookieTreeHostNode::TitleForUrl(url
) ==
582 (*host_node_iterator
)->GetTitle())
583 return static_cast<CookieTreeHostNode
*>(*host_node_iterator
);
584 // Node doesn't exist, insert the new one into the (ordered) children.
586 model_
->Add(this, host_node
.get(),
587 (host_node_iterator
- children().begin()));
588 return host_node
.release();
591 CookiesTreeModel
* CookieTreeRootNode::GetModel() const {
595 CookieTreeNode::DetailedInfo
CookieTreeRootNode::GetDetailedInfo() const {
596 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT
);
599 ///////////////////////////////////////////////////////////////////////////////
600 // CookieTreeHostNode, public:
603 base::string16
CookieTreeHostNode::TitleForUrl(const GURL
& url
) {
604 const std::string
file_origin_node_name(
605 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
606 return base::UTF8ToUTF16(url
.SchemeIsFile() ? file_origin_node_name
610 CookieTreeHostNode::CookieTreeHostNode(const GURL
& url
)
611 : CookieTreeNode(TitleForUrl(url
)),
612 cookies_child_(NULL
),
613 databases_child_(NULL
),
614 local_storages_child_(NULL
),
615 session_storages_child_(NULL
),
616 appcaches_child_(NULL
),
617 indexed_dbs_child_(NULL
),
618 file_systems_child_(NULL
),
620 channel_ids_child_(NULL
),
621 service_workers_child_(NULL
),
622 flash_lso_child_(NULL
),
624 canonicalized_host_(CanonicalizeHost(url
)) {
627 CookieTreeHostNode::~CookieTreeHostNode() {}
629 const std::string
CookieTreeHostNode::GetHost() const {
630 const std::string
file_origin_node_name(
631 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
632 return url_
.SchemeIsFile() ? file_origin_node_name
: url_
.host();
635 CookieTreeNode::DetailedInfo
CookieTreeHostNode::GetDetailedInfo() const {
636 return DetailedInfo().InitHost();
639 CookieTreeCookiesNode
* CookieTreeHostNode::GetOrCreateCookiesNode() {
641 return cookies_child_
;
642 cookies_child_
= new CookieTreeCookiesNode
;
643 AddChildSortedByTitle(cookies_child_
);
644 return cookies_child_
;
647 CookieTreeDatabasesNode
* CookieTreeHostNode::GetOrCreateDatabasesNode() {
648 if (databases_child_
)
649 return databases_child_
;
650 databases_child_
= new CookieTreeDatabasesNode
;
651 AddChildSortedByTitle(databases_child_
);
652 return databases_child_
;
655 CookieTreeLocalStoragesNode
*
656 CookieTreeHostNode::GetOrCreateLocalStoragesNode() {
657 if (local_storages_child_
)
658 return local_storages_child_
;
659 local_storages_child_
= new CookieTreeLocalStoragesNode
;
660 AddChildSortedByTitle(local_storages_child_
);
661 return local_storages_child_
;
664 CookieTreeSessionStoragesNode
*
665 CookieTreeHostNode::GetOrCreateSessionStoragesNode() {
666 if (session_storages_child_
)
667 return session_storages_child_
;
668 session_storages_child_
= new CookieTreeSessionStoragesNode
;
669 AddChildSortedByTitle(session_storages_child_
);
670 return session_storages_child_
;
673 CookieTreeAppCachesNode
* CookieTreeHostNode::GetOrCreateAppCachesNode() {
674 if (appcaches_child_
)
675 return appcaches_child_
;
676 appcaches_child_
= new CookieTreeAppCachesNode
;
677 AddChildSortedByTitle(appcaches_child_
);
678 return appcaches_child_
;
681 CookieTreeIndexedDBsNode
* CookieTreeHostNode::GetOrCreateIndexedDBsNode() {
682 if (indexed_dbs_child_
)
683 return indexed_dbs_child_
;
684 indexed_dbs_child_
= new CookieTreeIndexedDBsNode
;
685 AddChildSortedByTitle(indexed_dbs_child_
);
686 return indexed_dbs_child_
;
689 CookieTreeFileSystemsNode
* CookieTreeHostNode::GetOrCreateFileSystemsNode() {
690 if (file_systems_child_
)
691 return file_systems_child_
;
692 file_systems_child_
= new CookieTreeFileSystemsNode
;
693 AddChildSortedByTitle(file_systems_child_
);
694 return file_systems_child_
;
697 CookieTreeQuotaNode
* CookieTreeHostNode::UpdateOrCreateQuotaNode(
698 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
) {
701 quota_child_
= new CookieTreeQuotaNode(quota_info
);
702 AddChildSortedByTitle(quota_child_
);
706 CookieTreeChannelIDsNode
*
707 CookieTreeHostNode::GetOrCreateChannelIDsNode() {
708 if (channel_ids_child_
)
709 return channel_ids_child_
;
710 channel_ids_child_
= new CookieTreeChannelIDsNode
;
711 AddChildSortedByTitle(channel_ids_child_
);
712 return channel_ids_child_
;
715 CookieTreeServiceWorkersNode
*
716 CookieTreeHostNode::GetOrCreateServiceWorkersNode() {
717 if (service_workers_child_
)
718 return service_workers_child_
;
719 service_workers_child_
= new CookieTreeServiceWorkersNode
;
720 AddChildSortedByTitle(service_workers_child_
);
721 return service_workers_child_
;
724 CookieTreeFlashLSONode
* CookieTreeHostNode::GetOrCreateFlashLSONode(
725 const std::string
& domain
) {
726 DCHECK_EQ(GetHost(), domain
);
727 if (flash_lso_child_
)
728 return flash_lso_child_
;
729 flash_lso_child_
= new CookieTreeFlashLSONode(domain
);
730 AddChildSortedByTitle(flash_lso_child_
);
731 return flash_lso_child_
;
734 void CookieTreeHostNode::CreateContentException(
735 CookieSettings
* cookie_settings
, ContentSetting setting
) const {
736 DCHECK(setting
== CONTENT_SETTING_ALLOW
||
737 setting
== CONTENT_SETTING_BLOCK
||
738 setting
== CONTENT_SETTING_SESSION_ONLY
);
739 if (CanCreateContentException()) {
740 cookie_settings
->ResetCookieSetting(
741 ContentSettingsPattern::FromURLNoWildcard(url_
),
742 ContentSettingsPattern::Wildcard());
743 cookie_settings
->SetCookieSetting(
744 ContentSettingsPattern::FromURL(url_
),
745 ContentSettingsPattern::Wildcard(), setting
);
749 bool CookieTreeHostNode::CanCreateContentException() const {
750 return !url_
.SchemeIsFile();
753 ///////////////////////////////////////////////////////////////////////////////
754 // CookieTreeCookiesNode, public:
756 CookieTreeCookiesNode::CookieTreeCookiesNode()
757 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES
)) {
760 CookieTreeCookiesNode::~CookieTreeCookiesNode() {
763 CookieTreeNode::DetailedInfo
CookieTreeCookiesNode::GetDetailedInfo() const {
764 return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES
);
767 ///////////////////////////////////////////////////////////////////////////////
768 // CookieTreeAppCachesNode, public:
770 CookieTreeAppCachesNode::CookieTreeAppCachesNode()
771 : CookieTreeNode(l10n_util::GetStringUTF16(
772 IDS_COOKIES_APPLICATION_CACHES
)) {
775 CookieTreeAppCachesNode::~CookieTreeAppCachesNode() {}
777 CookieTreeNode::DetailedInfo
CookieTreeAppCachesNode::GetDetailedInfo() const {
778 return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES
);
781 ///////////////////////////////////////////////////////////////////////////////
782 // CookieTreeDatabasesNode, public:
784 CookieTreeDatabasesNode::CookieTreeDatabasesNode()
785 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES
)) {
788 CookieTreeDatabasesNode::~CookieTreeDatabasesNode() {}
790 CookieTreeNode::DetailedInfo
CookieTreeDatabasesNode::GetDetailedInfo() const {
791 return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES
);
794 ///////////////////////////////////////////////////////////////////////////////
795 // CookieTreeLocalStoragesNode, public:
797 CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode()
798 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE
)) {
801 CookieTreeLocalStoragesNode::~CookieTreeLocalStoragesNode() {}
803 CookieTreeNode::DetailedInfo
804 CookieTreeLocalStoragesNode::GetDetailedInfo() const {
805 return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES
);
808 ///////////////////////////////////////////////////////////////////////////////
809 // CookieTreeSessionStoragesNode, public:
811 CookieTreeSessionStoragesNode::CookieTreeSessionStoragesNode()
812 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE
)) {
815 CookieTreeSessionStoragesNode::~CookieTreeSessionStoragesNode() {}
817 CookieTreeNode::DetailedInfo
818 CookieTreeSessionStoragesNode::GetDetailedInfo() const {
819 return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES
);
822 ///////////////////////////////////////////////////////////////////////////////
823 // CookieTreeIndexedDBsNode, public:
825 CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode()
826 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS
)) {
829 CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {}
831 CookieTreeNode::DetailedInfo
832 CookieTreeIndexedDBsNode::GetDetailedInfo() const {
833 return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS
);
836 ///////////////////////////////////////////////////////////////////////////////
837 // CookieTreeFileSystemsNode, public:
839 CookieTreeFileSystemsNode::CookieTreeFileSystemsNode()
840 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS
)) {
843 CookieTreeFileSystemsNode::~CookieTreeFileSystemsNode() {}
845 CookieTreeNode::DetailedInfo
846 CookieTreeFileSystemsNode::GetDetailedInfo() const {
847 return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS
);
850 ///////////////////////////////////////////////////////////////////////////////
851 // CookieTreeChannelIDsNode, public:
853 CookieTreeChannelIDsNode::CookieTreeChannelIDsNode()
855 l10n_util::GetStringUTF16(IDS_COOKIES_CHANNEL_IDS
)) {
858 CookieTreeChannelIDsNode::~CookieTreeChannelIDsNode() {}
860 CookieTreeNode::DetailedInfo
861 CookieTreeChannelIDsNode::GetDetailedInfo() const {
862 return DetailedInfo().Init(DetailedInfo::TYPE_CHANNEL_IDS
);
865 void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode
* new_child
) {
867 std::vector
<CookieTreeNode
*>::iterator iter
=
868 std::lower_bound(children().begin(), children().end(), new_child
,
869 NodeTitleComparator());
870 GetModel()->Add(this, new_child
, iter
- children().begin());
873 ///////////////////////////////////////////////////////////////////////////////
874 // CookieTreeServiceWorkersNode, public:
876 CookieTreeServiceWorkersNode::CookieTreeServiceWorkersNode()
877 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SERVICE_WORKERS
)) {
880 CookieTreeServiceWorkersNode::~CookieTreeServiceWorkersNode() {
883 CookieTreeNode::DetailedInfo
CookieTreeServiceWorkersNode::GetDetailedInfo()
885 return DetailedInfo().Init(DetailedInfo::TYPE_SERVICE_WORKERS
);
888 ///////////////////////////////////////////////////////////////////////////////
889 // CookieTreeFlashLSONode
890 CookieTreeFlashLSONode::CookieTreeFlashLSONode(
891 const std::string
& domain
)
893 CookieTreeFlashLSONode::~CookieTreeFlashLSONode() {}
895 void CookieTreeFlashLSONode::DeleteStoredObjects() {
896 // We are one level below the host node.
897 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(parent());
898 CHECK_EQ(host
->GetDetailedInfo().node_type
,
899 CookieTreeNode::DetailedInfo::TYPE_HOST
);
900 LocalDataContainer
* container
= GetModel()->data_container();
901 container
->flash_lso_helper_
->DeleteFlashLSOsForSite(domain_
);
904 CookieTreeNode::DetailedInfo
CookieTreeFlashLSONode::GetDetailedInfo() const {
905 return DetailedInfo().InitFlashLSO(domain_
);
908 ///////////////////////////////////////////////////////////////////////////////
909 // ScopedBatchUpdateNotifier
910 CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier(
911 CookiesTreeModel
* model
, CookieTreeNode
* node
)
912 : model_(model
), node_(node
), batch_in_progress_(false) {
913 model_
->RecordBatchSeen();
916 CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() {
917 if (batch_in_progress_
) {
918 model_
->NotifyObserverTreeNodeChanged(node_
);
919 model_
->NotifyObserverEndBatch();
921 // If no batch started, and this is the last batch, give the model a chance
922 // to send out a final notification.
923 model_
->MaybeNotifyBatchesEnded();
927 void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() {
928 if (!batch_in_progress_
) {
929 model_
->NotifyObserverBeginBatch();
930 batch_in_progress_
= true;
934 ///////////////////////////////////////////////////////////////////////////////
935 // CookiesTreeModel, public:
936 CookiesTreeModel::CookiesTreeModel(
937 LocalDataContainer
* data_container
,
938 ExtensionSpecialStoragePolicy
* special_storage_policy
,
939 bool group_by_cookie_source
)
940 : ui::TreeNodeModel
<CookieTreeNode
>(new CookieTreeRootNode(this)),
941 data_container_(data_container
),
942 #if defined(ENABLE_EXTENSIONS)
943 special_storage_policy_(special_storage_policy
),
945 group_by_cookie_source_(group_by_cookie_source
),
946 batches_expected_(0),
950 data_container_
->Init(this);
953 CookiesTreeModel::~CookiesTreeModel() {
957 int CookiesTreeModel::GetSendForMessageID(const net::CanonicalCookie
& cookie
) {
958 if (cookie
.IsSecure()) {
959 if (cookie
.IsFirstPartyOnly())
960 return IDS_COOKIES_COOKIE_SENDFOR_SECURE_FIRSTPARTY
;
961 return IDS_COOKIES_COOKIE_SENDFOR_SECURE
;
963 if (cookie
.IsFirstPartyOnly())
964 return IDS_COOKIES_COOKIE_SENDFOR_FIRSTPARTY
;
965 return IDS_COOKIES_COOKIE_SENDFOR_ANY
;
968 ///////////////////////////////////////////////////////////////////////////////
969 // CookiesTreeModel, TreeModel methods (public):
971 // TreeModel methods:
972 // Returns the set of icons for the nodes in the tree. You only need override
973 // this if you don't want to use the default folder icons.
974 void CookiesTreeModel::GetIcons(std::vector
<gfx::ImageSkia
>* icons
) {
975 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
976 IDR_DEFAULT_FAVICON
).ToImageSkia());
977 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
978 IDR_COOKIE_ICON
).ToImageSkia());
979 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
980 IDR_COOKIE_STORAGE_ICON
).ToImageSkia());
983 // Returns the index of the icon to use for |node|. Return -1 to use the
984 // default icon. The index is relative to the list of icons returned from
986 int CookiesTreeModel::GetIconIndex(ui::TreeModelNode
* node
) {
987 CookieTreeNode
* ct_node
= static_cast<CookieTreeNode
*>(node
);
988 switch (ct_node
->GetDetailedInfo().node_type
) {
989 case CookieTreeNode::DetailedInfo::TYPE_HOST
:
991 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
993 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
995 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
996 return DATABASE
; // close enough
997 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
998 return DATABASE
; // ditto
999 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
1000 return DATABASE
; // ditto
1001 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
1002 return DATABASE
; // ditto
1003 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
1004 return DATABASE
; // ditto
1005 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
1007 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
1008 return COOKIE
; // It's kinda like a cookie?
1009 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER
:
1010 return DATABASE
; // Just like appcache
1017 void CookiesTreeModel::DeleteAllStoredObjects() {
1018 NotifyObserverBeginBatch();
1019 CookieTreeNode
* root
= GetRoot();
1020 root
->DeleteStoredObjects();
1021 int num_children
= root
->child_count();
1022 for (int i
= num_children
- 1; i
>= 0; --i
)
1023 delete Remove(root
, root
->GetChild(i
));
1024 NotifyObserverTreeNodeChanged(root
);
1025 NotifyObserverEndBatch();
1028 void CookiesTreeModel::DeleteCookieNode(CookieTreeNode
* cookie_node
) {
1029 if (cookie_node
== GetRoot())
1031 cookie_node
->DeleteStoredObjects();
1032 CookieTreeNode
* parent_node
= cookie_node
->parent();
1033 delete Remove(parent_node
, cookie_node
);
1034 if (parent_node
->empty())
1035 DeleteCookieNode(parent_node
);
1038 void CookiesTreeModel::UpdateSearchResults(const base::string16
& filter
) {
1039 CookieTreeNode
* root
= GetRoot();
1040 SetBatchExpectation(1, true);
1041 ScopedBatchUpdateNotifier
notifier(this, root
);
1042 int num_children
= root
->child_count();
1043 notifier
.StartBatchUpdate();
1044 for (int i
= num_children
- 1; i
>= 0; --i
)
1045 delete Remove(root
, root
->GetChild(i
));
1047 PopulateCookieInfoWithFilter(data_container(), ¬ifier
, filter
);
1048 PopulateDatabaseInfoWithFilter(data_container(), ¬ifier
, filter
);
1049 PopulateLocalStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
1050 PopulateSessionStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
1051 PopulateAppCacheInfoWithFilter(data_container(), ¬ifier
, filter
);
1052 PopulateIndexedDBInfoWithFilter(data_container(), ¬ifier
, filter
);
1053 PopulateFileSystemInfoWithFilter(data_container(), ¬ifier
, filter
);
1054 PopulateQuotaInfoWithFilter(data_container(), ¬ifier
, filter
);
1055 PopulateChannelIDInfoWithFilter(data_container(), ¬ifier
, filter
);
1056 PopulateServiceWorkerUsageInfoWithFilter(data_container(), ¬ifier
, filter
);
1059 #if defined(ENABLE_EXTENSIONS)
1060 const extensions::ExtensionSet
* CookiesTreeModel::ExtensionsProtectingNode(
1061 const CookieTreeNode
& cookie_node
) {
1062 if (!special_storage_policy_
.get())
1065 CookieTreeNode::DetailedInfo info
= cookie_node
.GetDetailedInfo();
1067 if (!TypeIsProtected(info
.node_type
))
1070 DCHECK(!info
.origin
.is_empty());
1071 return special_storage_policy_
->ExtensionsProtectingOrigin(info
.origin
);
1075 void CookiesTreeModel::AddCookiesTreeObserver(Observer
* observer
) {
1076 cookies_observer_list_
.AddObserver(observer
);
1077 // Call super so that TreeNodeModel can notify, too.
1078 ui::TreeNodeModel
<CookieTreeNode
>::AddObserver(observer
);
1081 void CookiesTreeModel::RemoveCookiesTreeObserver(Observer
* observer
) {
1082 cookies_observer_list_
.RemoveObserver(observer
);
1083 // Call super so that TreeNodeModel doesn't have dead pointers.
1084 ui::TreeNodeModel
<CookieTreeNode
>::RemoveObserver(observer
);
1087 void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer
* container
) {
1088 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1089 PopulateAppCacheInfoWithFilter(container
, ¬ifier
, base::string16());
1092 void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer
* container
) {
1093 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1094 PopulateCookieInfoWithFilter(container
, ¬ifier
, base::string16());
1097 void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer
* container
) {
1098 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1099 PopulateDatabaseInfoWithFilter(container
, ¬ifier
, base::string16());
1102 void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer
* container
) {
1103 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1104 PopulateLocalStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1107 void CookiesTreeModel::PopulateSessionStorageInfo(
1108 LocalDataContainer
* container
) {
1109 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1110 PopulateSessionStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1113 void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer
* container
) {
1114 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1115 PopulateIndexedDBInfoWithFilter(container
, ¬ifier
, base::string16());
1118 void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer
* container
) {
1119 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1120 PopulateFileSystemInfoWithFilter(container
, ¬ifier
, base::string16());
1123 void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer
* container
) {
1124 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1125 PopulateQuotaInfoWithFilter(container
, ¬ifier
, base::string16());
1128 void CookiesTreeModel::PopulateChannelIDInfo(
1129 LocalDataContainer
* container
) {
1130 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1131 PopulateChannelIDInfoWithFilter(container
, ¬ifier
, base::string16());
1134 void CookiesTreeModel::PopulateServiceWorkerUsageInfo(
1135 LocalDataContainer
* container
) {
1136 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1137 PopulateServiceWorkerUsageInfoWithFilter(
1138 container
, ¬ifier
, base::string16());
1141 void CookiesTreeModel::PopulateFlashLSOInfo(
1142 LocalDataContainer
* container
) {
1143 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1144 PopulateFlashLSOInfoWithFilter(container
, ¬ifier
, base::string16());
1147 void CookiesTreeModel::PopulateAppCacheInfoWithFilter(
1148 LocalDataContainer
* container
,
1149 ScopedBatchUpdateNotifier
* notifier
,
1150 const base::string16
& filter
) {
1151 using content::AppCacheInfo
;
1152 typedef std::map
<GURL
, std::list
<AppCacheInfo
> > InfoByOrigin
;
1153 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1155 if (container
->appcache_info_
.empty())
1158 notifier
->StartBatchUpdate();
1159 for (InfoByOrigin::iterator origin
= container
->appcache_info_
.begin();
1160 origin
!= container
->appcache_info_
.end(); ++origin
) {
1161 base::string16 host_node_name
= base::UTF8ToUTF16(origin
->first
.host());
1162 if (filter
.empty() ||
1163 (host_node_name
.find(filter
) != base::string16::npos
)) {
1164 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
->first
);
1165 CookieTreeAppCachesNode
* appcaches_node
=
1166 host_node
->GetOrCreateAppCachesNode();
1168 for (std::list
<AppCacheInfo
>::iterator info
= origin
->second
.begin();
1169 info
!= origin
->second
.end(); ++info
) {
1170 appcaches_node
->AddAppCacheNode(
1171 new CookieTreeAppCacheNode(origin
->first
, info
));
1177 void CookiesTreeModel::PopulateCookieInfoWithFilter(
1178 LocalDataContainer
* container
,
1179 ScopedBatchUpdateNotifier
* notifier
,
1180 const base::string16
& filter
) {
1181 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1183 notifier
->StartBatchUpdate();
1184 for (CookieList::iterator it
= container
->cookie_list_
.begin();
1185 it
!= container
->cookie_list_
.end(); ++it
) {
1186 std::string source_string
= it
->Source();
1187 if (source_string
.empty() || !group_by_cookie_source_
) {
1188 std::string domain
= it
->Domain();
1189 if (domain
.length() > 1 && domain
[0] == '.')
1190 domain
= domain
.substr(1);
1192 // We treat secure cookies just the same as normal ones.
1193 source_string
= std::string(url::kHttpScheme
) +
1194 url::kStandardSchemeSeparator
+ domain
+ "/";
1197 GURL
source(source_string
);
1198 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(source
)
1199 .find(filter
) != base::string16::npos
)) {
1200 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(source
);
1201 CookieTreeCookiesNode
* cookies_node
=
1202 host_node
->GetOrCreateCookiesNode();
1203 CookieTreeCookieNode
* new_cookie
= new CookieTreeCookieNode(it
);
1204 cookies_node
->AddCookieNode(new_cookie
);
1209 void CookiesTreeModel::PopulateDatabaseInfoWithFilter(
1210 LocalDataContainer
* container
,
1211 ScopedBatchUpdateNotifier
* notifier
,
1212 const base::string16
& filter
) {
1213 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1215 if (container
->database_info_list_
.empty())
1218 notifier
->StartBatchUpdate();
1219 for (DatabaseInfoList::iterator database_info
=
1220 container
->database_info_list_
.begin();
1221 database_info
!= container
->database_info_list_
.end();
1223 GURL
origin(database_info
->identifier
.ToOrigin());
1225 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1226 .find(filter
) != base::string16::npos
)) {
1227 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1228 CookieTreeDatabasesNode
* databases_node
=
1229 host_node
->GetOrCreateDatabasesNode();
1230 databases_node
->AddDatabaseNode(
1231 new CookieTreeDatabaseNode(database_info
));
1236 void CookiesTreeModel::PopulateLocalStorageInfoWithFilter(
1237 LocalDataContainer
* container
,
1238 ScopedBatchUpdateNotifier
* notifier
,
1239 const base::string16
& filter
) {
1240 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1242 if (container
->local_storage_info_list_
.empty())
1245 notifier
->StartBatchUpdate();
1246 for (LocalStorageInfoList::iterator local_storage_info
=
1247 container
->local_storage_info_list_
.begin();
1248 local_storage_info
!= container
->local_storage_info_list_
.end();
1249 ++local_storage_info
) {
1250 const GURL
& origin(local_storage_info
->origin_url
);
1252 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1253 .find(filter
) != std::string::npos
)) {
1254 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1255 CookieTreeLocalStoragesNode
* local_storages_node
=
1256 host_node
->GetOrCreateLocalStoragesNode();
1257 local_storages_node
->AddLocalStorageNode(
1258 new CookieTreeLocalStorageNode(local_storage_info
));
1263 void CookiesTreeModel::PopulateSessionStorageInfoWithFilter(
1264 LocalDataContainer
* container
,
1265 ScopedBatchUpdateNotifier
* notifier
,
1266 const base::string16
& filter
) {
1267 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1269 if (container
->session_storage_info_list_
.empty())
1272 notifier
->StartBatchUpdate();
1273 for (LocalStorageInfoList::iterator session_storage_info
=
1274 container
->session_storage_info_list_
.begin();
1275 session_storage_info
!= container
->session_storage_info_list_
.end();
1276 ++session_storage_info
) {
1277 const GURL
& origin
= session_storage_info
->origin_url
;
1279 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1280 .find(filter
) != base::string16::npos
)) {
1281 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1282 CookieTreeSessionStoragesNode
* session_storages_node
=
1283 host_node
->GetOrCreateSessionStoragesNode();
1284 session_storages_node
->AddSessionStorageNode(
1285 new CookieTreeSessionStorageNode(session_storage_info
));
1290 void CookiesTreeModel::PopulateIndexedDBInfoWithFilter(
1291 LocalDataContainer
* container
,
1292 ScopedBatchUpdateNotifier
* notifier
,
1293 const base::string16
& filter
) {
1294 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1296 if (container
->indexed_db_info_list_
.empty())
1299 notifier
->StartBatchUpdate();
1300 for (IndexedDBInfoList::iterator indexed_db_info
=
1301 container
->indexed_db_info_list_
.begin();
1302 indexed_db_info
!= container
->indexed_db_info_list_
.end();
1303 ++indexed_db_info
) {
1304 const GURL
& origin
= indexed_db_info
->origin_
;
1306 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1307 .find(filter
) != base::string16::npos
)) {
1308 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1309 CookieTreeIndexedDBsNode
* indexed_dbs_node
=
1310 host_node
->GetOrCreateIndexedDBsNode();
1311 indexed_dbs_node
->AddIndexedDBNode(
1312 new CookieTreeIndexedDBNode(indexed_db_info
));
1317 void CookiesTreeModel::PopulateChannelIDInfoWithFilter(
1318 LocalDataContainer
* container
,
1319 ScopedBatchUpdateNotifier
* notifier
,
1320 const base::string16
& filter
) {
1321 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1323 if (container
->channel_id_list_
.empty())
1326 notifier
->StartBatchUpdate();
1327 for (ChannelIDList::iterator channel_id_info
=
1328 container
->channel_id_list_
.begin();
1329 channel_id_info
!= container
->channel_id_list_
.end();
1330 ++channel_id_info
) {
1331 GURL
origin(channel_id_info
->server_identifier());
1332 if (!origin
.is_valid()) {
1333 // Channel ID. Make a valid URL to satisfy the
1334 // CookieTreeRootNode::GetOrCreateHostNode interface.
1335 origin
= GURL(std::string(url::kHttpsScheme
) +
1336 url::kStandardSchemeSeparator
+
1337 channel_id_info
->server_identifier() + "/");
1339 base::string16 title
= CookieTreeHostNode::TitleForUrl(origin
);
1340 if (filter
.empty() || title
.find(filter
) != base::string16::npos
) {
1341 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1342 CookieTreeChannelIDsNode
* channel_ids_node
=
1343 host_node
->GetOrCreateChannelIDsNode();
1344 channel_ids_node
->AddChannelIDNode(
1345 new CookieTreeChannelIDNode(channel_id_info
));
1350 void CookiesTreeModel::PopulateServiceWorkerUsageInfoWithFilter(
1351 LocalDataContainer
* container
,
1352 ScopedBatchUpdateNotifier
* notifier
,
1353 const base::string16
& filter
) {
1354 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1356 if (container
->service_worker_info_list_
.empty())
1359 notifier
->StartBatchUpdate();
1360 for (ServiceWorkerUsageInfoList::iterator service_worker_info
=
1361 container
->service_worker_info_list_
.begin();
1362 service_worker_info
!= container
->service_worker_info_list_
.end();
1363 ++service_worker_info
) {
1364 const GURL
& origin
= service_worker_info
->origin
;
1366 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1367 .find(filter
) != base::string16::npos
)) {
1368 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1369 CookieTreeServiceWorkersNode
* service_workers_node
=
1370 host_node
->GetOrCreateServiceWorkersNode();
1371 service_workers_node
->AddServiceWorkerNode(
1372 new CookieTreeServiceWorkerNode(service_worker_info
));
1377 void CookiesTreeModel::PopulateFileSystemInfoWithFilter(
1378 LocalDataContainer
* container
,
1379 ScopedBatchUpdateNotifier
* notifier
,
1380 const base::string16
& filter
) {
1381 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1383 if (container
->file_system_info_list_
.empty())
1386 notifier
->StartBatchUpdate();
1387 for (FileSystemInfoList::iterator file_system_info
=
1388 container
->file_system_info_list_
.begin();
1389 file_system_info
!= container
->file_system_info_list_
.end();
1390 ++file_system_info
) {
1391 GURL
origin(file_system_info
->origin
);
1393 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1394 .find(filter
) != base::string16::npos
)) {
1395 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1396 CookieTreeFileSystemsNode
* file_systems_node
=
1397 host_node
->GetOrCreateFileSystemsNode();
1398 file_systems_node
->AddFileSystemNode(
1399 new CookieTreeFileSystemNode(file_system_info
));
1404 void CookiesTreeModel::PopulateQuotaInfoWithFilter(
1405 LocalDataContainer
* container
,
1406 ScopedBatchUpdateNotifier
* notifier
,
1407 const base::string16
& filter
) {
1408 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1410 if (container
->quota_info_list_
.empty())
1413 notifier
->StartBatchUpdate();
1414 for (QuotaInfoList::iterator quota_info
= container
->quota_info_list_
.begin();
1415 quota_info
!= container
->quota_info_list_
.end();
1417 if (filter
.empty() || (base::UTF8ToUTF16(quota_info
->host
).find(filter
) !=
1418 base::string16::npos
)) {
1419 CookieTreeHostNode
* host_node
=
1420 root
->GetOrCreateHostNode(GURL("http://" + quota_info
->host
));
1421 host_node
->UpdateOrCreateQuotaNode(quota_info
);
1426 void CookiesTreeModel::PopulateFlashLSOInfoWithFilter(
1427 LocalDataContainer
* container
,
1428 ScopedBatchUpdateNotifier
* notifier
,
1429 const base::string16
& filter
) {
1430 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1432 if (container
->flash_lso_domain_list_
.empty())
1435 std::string filter_utf8
= base::UTF16ToUTF8(filter
);
1436 notifier
->StartBatchUpdate();
1437 for (std::vector
<std::string
>::iterator it
=
1438 container
->flash_lso_domain_list_
.begin();
1439 it
!= container
->flash_lso_domain_list_
.end(); ++it
) {
1440 if (filter_utf8
.empty() || it
->find(filter_utf8
) != std::string::npos
) {
1441 // Create a fake origin for GetOrCreateHostNode().
1442 GURL
origin("http://" + *it
);
1443 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1444 host_node
->GetOrCreateFlashLSONode(*it
);
1449 void CookiesTreeModel::SetBatchExpectation(int batches_expected
, bool reset
) {
1450 batches_expected_
= batches_expected
;
1453 batches_started_
= 0;
1456 MaybeNotifyBatchesEnded();
1460 void CookiesTreeModel::RecordBatchSeen() {
1464 void CookiesTreeModel::NotifyObserverBeginBatch() {
1465 // Only notify the model once if we're batching in a nested manner.
1466 if (batches_started_
++ == 0) {
1467 FOR_EACH_OBSERVER(Observer
,
1468 cookies_observer_list_
,
1469 TreeModelBeginBatch(this));
1473 void CookiesTreeModel::NotifyObserverEndBatch() {
1475 MaybeNotifyBatchesEnded();
1478 void CookiesTreeModel::MaybeNotifyBatchesEnded() {
1479 // Only notify the observers if this is the outermost call to EndBatch() if
1480 // called in a nested manner.
1481 if (batches_ended_
== batches_started_
&&
1482 batches_seen_
== batches_expected_
) {
1483 FOR_EACH_OBSERVER(Observer
,
1484 cookies_observer_list_
,
1485 TreeModelEndBatch(this));