1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/browsing_data/cookies_tree_model.h"
12 #include "base/bind.h"
13 #include "base/memory/linked_ptr.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
18 #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
19 #include "chrome/browser/content_settings/cookie_settings_factory.h"
20 #include "chrome/grit/generated_resources.h"
21 #include "components/content_settings/core/browser/cookie_settings.h"
22 #include "content/public/common/url_constants.h"
23 #include "grit/theme_resources.h"
24 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
25 #include "net/cookies/canonical_cookie.h"
26 #include "net/url_request/url_request_context.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/base/resource/resource_bundle.h"
29 #include "ui/gfx/image/image_skia.h"
30 #include "ui/resources/grit/ui_resources.h"
32 #if defined(ENABLE_EXTENSIONS)
33 #include "chrome/browser/extensions/extension_special_storage_policy.h"
34 #include "extensions/common/extension_set.h"
39 struct NodeTitleComparator
{
40 bool operator()(const CookieTreeNode
* lhs
, const CookieTreeNode
* rhs
) {
41 return lhs
->GetTitle() < rhs
->GetTitle();
45 // Comparison functor, for use in CookieTreeRootNode.
46 struct HostNodeComparator
{
47 bool operator()(const CookieTreeNode
* lhs
, const CookieTreeNode
* rhs
) {
48 // This comparator is only meant to compare CookieTreeHostNode types. Make
49 // sure we check this, as the static cast below is dangerous if we get the
51 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST
,
52 lhs
->GetDetailedInfo().node_type
);
53 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST
,
54 rhs
->GetDetailedInfo().node_type
);
56 const CookieTreeHostNode
* ltn
=
57 static_cast<const CookieTreeHostNode
*>(lhs
);
58 const CookieTreeHostNode
* rtn
=
59 static_cast<const CookieTreeHostNode
*>(rhs
);
61 // We want to order by registry controlled domain, so we would get
62 // google.com, ad.google.com, www.google.com,
63 // microsoft.com, ad.microsoft.com. CanonicalizeHost transforms the origins
64 // into a form like google.com.www so that string comparisons work.
65 return (ltn
->canonicalized_host() <
66 rtn
->canonicalized_host());
70 std::string
CanonicalizeHost(const GURL
& url
) {
71 // The canonicalized representation makes the registry controlled domain
72 // come first, and then adds subdomains in reverse order, e.g.
73 // 1.mail.google.com would become google.com.mail.1, and then a standard
74 // string comparison works to order hosts by registry controlled domain
75 // first. Leading dots are ignored, ".google.com" is the same as
78 if (url
.SchemeIsFile()) {
79 return std::string(url::kFileScheme
) +
80 url::kStandardSchemeSeparator
;
83 std::string host
= url
.host();
85 net::registry_controlled_domains::GetDomainAndRegistry(
87 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES
);
88 if (!retval
.length()) // Is an IP address or other special origin.
91 std::string::size_type position
= host
.rfind(retval
);
93 // The host may be the registry controlled domain, in which case fail fast.
94 if (position
== 0 || position
== std::string::npos
)
97 // If host is www.google.com, retval will contain google.com at this point.
98 // Start operating to the left of the registry controlled domain, e.g. in
99 // the www.google.com example, start at index 3.
102 // If position == 0, that means it's a dot; this will be ignored to treat
103 // ".google.com" the same as "google.com".
104 while (position
> 0) {
105 retval
+= std::string(".");
106 // Copy up to the next dot. host[position] is a dot so start after it.
107 std::string::size_type next_dot
= host
.rfind(".", position
- 1);
108 if (next_dot
== std::string::npos
) {
109 retval
+= host
.substr(0, position
);
112 retval
+= host
.substr(next_dot
+ 1, position
- (next_dot
+ 1));
118 #if defined(ENABLE_EXTENSIONS)
119 bool TypeIsProtected(CookieTreeNode::DetailedInfo::NodeType type
) {
121 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
123 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
125 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
127 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
129 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
131 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
133 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
135 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
137 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
139 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER
:
141 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO
:
150 // This function returns the local data container associated with a leaf tree
151 // node. The app node is assumed to be 3 levels above the leaf because of the
152 // following structure:
153 // root -> origin -> storage type -> leaf node
154 LocalDataContainer
* GetLocalDataContainerForNode(CookieTreeNode
* node
) {
155 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(
156 node
->parent()->parent());
157 CHECK_EQ(host
->GetDetailedInfo().node_type
,
158 CookieTreeNode::DetailedInfo::TYPE_HOST
);
159 return node
->GetModel()->data_container();
164 CookieTreeNode::DetailedInfo::DetailedInfo() : node_type(TYPE_NONE
) {}
166 CookieTreeNode::DetailedInfo::~DetailedInfo() {}
168 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::Init(
170 DCHECK_EQ(TYPE_NONE
, node_type
);
175 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitHost() {
180 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitCookie(
181 const net::CanonicalCookie
* cookie
) {
183 this->cookie
= cookie
;
187 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitDatabase(
188 const BrowsingDataDatabaseHelper::DatabaseInfo
* database_info
) {
190 this->database_info
= database_info
;
191 origin
= database_info
->identifier
.ToOrigin();
195 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitLocalStorage(
196 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
197 local_storage_info
) {
198 Init(TYPE_LOCAL_STORAGE
);
199 this->local_storage_info
= local_storage_info
;
200 origin
= local_storage_info
->origin_url
;
204 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitSessionStorage(
205 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
206 session_storage_info
) {
207 Init(TYPE_SESSION_STORAGE
);
208 this->session_storage_info
= session_storage_info
;
209 origin
= session_storage_info
->origin_url
;
213 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitAppCache(
215 const content::AppCacheInfo
* appcache_info
) {
217 this->appcache_info
= appcache_info
;
218 this->origin
= origin
;
222 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitIndexedDB(
223 const content::IndexedDBInfo
* indexed_db_info
) {
224 Init(TYPE_INDEXED_DB
);
225 this->indexed_db_info
= indexed_db_info
;
226 this->origin
= indexed_db_info
->origin_
;
230 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFileSystem(
231 const BrowsingDataFileSystemHelper::FileSystemInfo
* file_system_info
) {
232 Init(TYPE_FILE_SYSTEM
);
233 this->file_system_info
= file_system_info
;
234 this->origin
= file_system_info
->origin
;
238 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitQuota(
239 const BrowsingDataQuotaHelper::QuotaInfo
* quota_info
) {
241 this->quota_info
= quota_info
;
245 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitChannelID(
246 const net::ChannelIDStore::ChannelID
* channel_id
) {
247 Init(TYPE_CHANNEL_ID
);
248 this->channel_id
= channel_id
;
252 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitServiceWorker(
253 const content::ServiceWorkerUsageInfo
* service_worker_info
) {
254 Init(TYPE_SERVICE_WORKER
);
255 this->service_worker_info
= service_worker_info
;
256 this->origin
= service_worker_info
->origin
;
260 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFlashLSO(
261 const std::string
& flash_lso_domain
) {
262 Init(TYPE_FLASH_LSO
);
263 this->flash_lso_domain
= flash_lso_domain
;
267 ///////////////////////////////////////////////////////////////////////////////
268 // CookieTreeNode, public:
270 void CookieTreeNode::DeleteStoredObjects() {
271 std::for_each(children().begin(),
273 std::mem_fun(&CookieTreeNode::DeleteStoredObjects
));
276 CookiesTreeModel
* CookieTreeNode::GetModel() const {
278 return parent()->GetModel();
283 ///////////////////////////////////////////////////////////////////////////////
284 // CookieTreeCookieNode, public:
286 CookieTreeCookieNode::CookieTreeCookieNode(
287 std::list
<net::CanonicalCookie
>::iterator cookie
)
288 : CookieTreeNode(base::UTF8ToUTF16(cookie
->Name())),
292 CookieTreeCookieNode::~CookieTreeCookieNode() {}
294 void CookieTreeCookieNode::DeleteStoredObjects() {
295 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
296 container
->cookie_helper_
->DeleteCookie(*cookie_
);
297 container
->cookie_list_
.erase(cookie_
);
300 CookieTreeNode::DetailedInfo
CookieTreeCookieNode::GetDetailedInfo() const {
301 return DetailedInfo().InitCookie(&*cookie_
);
304 ///////////////////////////////////////////////////////////////////////////////
305 // CookieTreeAppCacheNode, public:
307 CookieTreeAppCacheNode::CookieTreeAppCacheNode(
308 const GURL
& origin_url
,
309 std::list
<content::AppCacheInfo
>::iterator appcache_info
)
310 : CookieTreeNode(base::UTF8ToUTF16(appcache_info
->manifest_url
.spec())),
311 origin_url_(origin_url
),
312 appcache_info_(appcache_info
) {
315 CookieTreeAppCacheNode::~CookieTreeAppCacheNode() {
318 void CookieTreeAppCacheNode::DeleteStoredObjects() {
319 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
322 DCHECK(container
->appcache_helper_
.get());
323 container
->appcache_helper_
324 ->DeleteAppCacheGroup(appcache_info_
->manifest_url
);
325 container
->appcache_info_
[origin_url_
].erase(appcache_info_
);
329 CookieTreeNode::DetailedInfo
CookieTreeAppCacheNode::GetDetailedInfo() const {
330 return DetailedInfo().InitAppCache(origin_url_
, &*appcache_info_
);
333 ///////////////////////////////////////////////////////////////////////////////
334 // CookieTreeDatabaseNode, public:
336 CookieTreeDatabaseNode::CookieTreeDatabaseNode(
337 std::list
<BrowsingDataDatabaseHelper::DatabaseInfo
>::iterator database_info
)
338 : CookieTreeNode(database_info
->database_name
.empty() ?
339 l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME
) :
340 base::UTF8ToUTF16(database_info
->database_name
)),
341 database_info_(database_info
) {
344 CookieTreeDatabaseNode::~CookieTreeDatabaseNode() {}
346 void CookieTreeDatabaseNode::DeleteStoredObjects() {
347 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
350 container
->database_helper_
->DeleteDatabase(
351 database_info_
->identifier
.ToString(), database_info_
->database_name
);
352 container
->database_info_list_
.erase(database_info_
);
356 CookieTreeNode::DetailedInfo
CookieTreeDatabaseNode::GetDetailedInfo() const {
357 return DetailedInfo().InitDatabase(&*database_info_
);
360 ///////////////////////////////////////////////////////////////////////////////
361 // CookieTreeLocalStorageNode, public:
363 CookieTreeLocalStorageNode::CookieTreeLocalStorageNode(
364 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
366 : CookieTreeNode(base::UTF8ToUTF16(local_storage_info
->origin_url
.spec())),
367 local_storage_info_(local_storage_info
) {
370 CookieTreeLocalStorageNode::~CookieTreeLocalStorageNode() {}
372 void CookieTreeLocalStorageNode::DeleteStoredObjects() {
373 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
376 container
->local_storage_helper_
->DeleteOrigin(
377 local_storage_info_
->origin_url
);
378 container
->local_storage_info_list_
.erase(local_storage_info_
);
382 CookieTreeNode::DetailedInfo
383 CookieTreeLocalStorageNode::GetDetailedInfo() const {
384 return DetailedInfo().InitLocalStorage(
385 &*local_storage_info_
);
388 ///////////////////////////////////////////////////////////////////////////////
389 // CookieTreeSessionStorageNode, public:
391 CookieTreeSessionStorageNode::CookieTreeSessionStorageNode(
392 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
393 session_storage_info
)
395 base::UTF8ToUTF16(session_storage_info
->origin_url
.spec())),
396 session_storage_info_(session_storage_info
) {
399 CookieTreeSessionStorageNode::~CookieTreeSessionStorageNode() {}
401 void CookieTreeSessionStorageNode::DeleteStoredObjects() {
402 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
405 // TODO(rsesek): There's no easy way to get the namespace_id for a session
406 // storage, nor is there an easy way to clear session storage just by
407 // origin. This is probably okay since session storage is not persistent.
408 // http://crbug.com/168996
409 container
->session_storage_info_list_
.erase(session_storage_info_
);
413 CookieTreeNode::DetailedInfo
414 CookieTreeSessionStorageNode::GetDetailedInfo() const {
415 return DetailedInfo().InitSessionStorage(&*session_storage_info_
);
418 ///////////////////////////////////////////////////////////////////////////////
419 // CookieTreeIndexedDBNode, public:
421 CookieTreeIndexedDBNode::CookieTreeIndexedDBNode(
422 std::list
<content::IndexedDBInfo
>::iterator
424 : CookieTreeNode(base::UTF8ToUTF16(
425 indexed_db_info
->origin_
.spec())),
426 indexed_db_info_(indexed_db_info
) {
429 CookieTreeIndexedDBNode::~CookieTreeIndexedDBNode() {}
431 void CookieTreeIndexedDBNode::DeleteStoredObjects() {
432 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
435 container
->indexed_db_helper_
->DeleteIndexedDB(
436 indexed_db_info_
->origin_
);
437 container
->indexed_db_info_list_
.erase(indexed_db_info_
);
441 CookieTreeNode::DetailedInfo
CookieTreeIndexedDBNode::GetDetailedInfo() const {
442 return DetailedInfo().InitIndexedDB(&*indexed_db_info_
);
445 ///////////////////////////////////////////////////////////////////////////////
446 // CookieTreeFileSystemNode, public:
448 CookieTreeFileSystemNode::CookieTreeFileSystemNode(
449 std::list
<BrowsingDataFileSystemHelper::FileSystemInfo
>::iterator
451 : CookieTreeNode(base::UTF8ToUTF16(
452 file_system_info
->origin
.spec())),
453 file_system_info_(file_system_info
) {
456 CookieTreeFileSystemNode::~CookieTreeFileSystemNode() {}
458 void CookieTreeFileSystemNode::DeleteStoredObjects() {
459 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
462 container
->file_system_helper_
->DeleteFileSystemOrigin(
463 file_system_info_
->origin
);
464 container
->file_system_info_list_
.erase(file_system_info_
);
468 CookieTreeNode::DetailedInfo
CookieTreeFileSystemNode::GetDetailedInfo() const {
469 return DetailedInfo().InitFileSystem(&*file_system_info_
);
472 ///////////////////////////////////////////////////////////////////////////////
473 // CookieTreeQuotaNode, public:
475 CookieTreeQuotaNode::CookieTreeQuotaNode(
476 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
)
477 : CookieTreeNode(base::UTF8ToUTF16(quota_info
->host
)),
478 quota_info_(quota_info
) {
481 CookieTreeQuotaNode::~CookieTreeQuotaNode() {}
483 void CookieTreeQuotaNode::DeleteStoredObjects() {
484 // Calling this function may cause unexpected over-quota state of origin.
485 // However, it'll caused no problem, just prevent usage growth of the origin.
486 LocalDataContainer
* container
= GetModel()->data_container();
489 container
->quota_helper_
->RevokeHostQuota(quota_info_
->host
);
490 container
->quota_info_list_
.erase(quota_info_
);
494 CookieTreeNode::DetailedInfo
CookieTreeQuotaNode::GetDetailedInfo() const {
495 return DetailedInfo().InitQuota(&*quota_info_
);
498 ///////////////////////////////////////////////////////////////////////////////
499 // CookieTreeChannelIDNode, public:
501 CookieTreeChannelIDNode::CookieTreeChannelIDNode(
502 net::ChannelIDStore::ChannelIDList::iterator channel_id
)
503 : CookieTreeNode(base::ASCIIToUTF16(channel_id
->server_identifier())),
504 channel_id_(channel_id
) {
507 CookieTreeChannelIDNode::~CookieTreeChannelIDNode() {}
509 void CookieTreeChannelIDNode::DeleteStoredObjects() {
510 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
513 container
->channel_id_helper_
->DeleteChannelID(
514 channel_id_
->server_identifier());
515 container
->channel_id_list_
.erase(channel_id_
);
519 CookieTreeNode::DetailedInfo
520 CookieTreeChannelIDNode::GetDetailedInfo() const {
521 return DetailedInfo().InitChannelID(&*channel_id_
);
524 ///////////////////////////////////////////////////////////////////////////////
525 // CookieTreeServiceWorkerNode, public:
527 CookieTreeServiceWorkerNode::CookieTreeServiceWorkerNode(
528 std::list
<content::ServiceWorkerUsageInfo
>::iterator service_worker_info
)
529 : CookieTreeNode(base::UTF8ToUTF16(service_worker_info
->origin
.spec())),
530 service_worker_info_(service_worker_info
) {
533 CookieTreeServiceWorkerNode::~CookieTreeServiceWorkerNode() {
536 void CookieTreeServiceWorkerNode::DeleteStoredObjects() {
537 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
540 container
->service_worker_helper_
->DeleteServiceWorkers(
541 service_worker_info_
->origin
);
542 container
->service_worker_info_list_
.erase(service_worker_info_
);
546 CookieTreeNode::DetailedInfo
CookieTreeServiceWorkerNode::GetDetailedInfo()
548 return DetailedInfo().InitServiceWorker(&*service_worker_info_
);
551 ///////////////////////////////////////////////////////////////////////////////
552 // CookieTreeRootNode, public:
554 CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel
* model
)
558 CookieTreeRootNode::~CookieTreeRootNode() {}
560 CookieTreeHostNode
* CookieTreeRootNode::GetOrCreateHostNode(
562 scoped_ptr
<CookieTreeHostNode
> host_node(
563 new CookieTreeHostNode(url
));
565 // First see if there is an existing match.
566 std::vector
<CookieTreeNode
*>::iterator host_node_iterator
=
567 std::lower_bound(children().begin(), children().end(), host_node
.get(),
568 HostNodeComparator());
569 if (host_node_iterator
!= children().end() &&
570 CookieTreeHostNode::TitleForUrl(url
) ==
571 (*host_node_iterator
)->GetTitle())
572 return static_cast<CookieTreeHostNode
*>(*host_node_iterator
);
573 // Node doesn't exist, insert the new one into the (ordered) children.
575 model_
->Add(this, host_node
.get(),
576 (host_node_iterator
- children().begin()));
577 return host_node
.release();
580 CookiesTreeModel
* CookieTreeRootNode::GetModel() const {
584 CookieTreeNode::DetailedInfo
CookieTreeRootNode::GetDetailedInfo() const {
585 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT
);
588 ///////////////////////////////////////////////////////////////////////////////
589 // CookieTreeHostNode, public:
592 base::string16
CookieTreeHostNode::TitleForUrl(const GURL
& url
) {
593 const std::string
file_origin_node_name(
594 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
595 return base::UTF8ToUTF16(url
.SchemeIsFile() ? file_origin_node_name
599 CookieTreeHostNode::CookieTreeHostNode(const GURL
& url
)
600 : CookieTreeNode(TitleForUrl(url
)),
602 canonicalized_host_(CanonicalizeHost(url
)) {}
604 CookieTreeHostNode::~CookieTreeHostNode() {}
606 const std::string
CookieTreeHostNode::GetHost() const {
607 const std::string
file_origin_node_name(
608 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
609 return url_
.SchemeIsFile() ? file_origin_node_name
: url_
.host();
612 CookieTreeNode::DetailedInfo
CookieTreeHostNode::GetDetailedInfo() const {
613 return DetailedInfo().InitHost();
616 CookieTreeCookiesNode
* CookieTreeHostNode::GetOrCreateCookiesNode() {
618 return cookies_child_
;
619 cookies_child_
= new CookieTreeCookiesNode
;
620 AddChildSortedByTitle(cookies_child_
);
621 return cookies_child_
;
624 CookieTreeDatabasesNode
* CookieTreeHostNode::GetOrCreateDatabasesNode() {
625 if (databases_child_
)
626 return databases_child_
;
627 databases_child_
= new CookieTreeDatabasesNode
;
628 AddChildSortedByTitle(databases_child_
);
629 return databases_child_
;
632 CookieTreeLocalStoragesNode
*
633 CookieTreeHostNode::GetOrCreateLocalStoragesNode() {
634 if (local_storages_child_
)
635 return local_storages_child_
;
636 local_storages_child_
= new CookieTreeLocalStoragesNode
;
637 AddChildSortedByTitle(local_storages_child_
);
638 return local_storages_child_
;
641 CookieTreeSessionStoragesNode
*
642 CookieTreeHostNode::GetOrCreateSessionStoragesNode() {
643 if (session_storages_child_
)
644 return session_storages_child_
;
645 session_storages_child_
= new CookieTreeSessionStoragesNode
;
646 AddChildSortedByTitle(session_storages_child_
);
647 return session_storages_child_
;
650 CookieTreeAppCachesNode
* CookieTreeHostNode::GetOrCreateAppCachesNode() {
651 if (appcaches_child_
)
652 return appcaches_child_
;
653 appcaches_child_
= new CookieTreeAppCachesNode
;
654 AddChildSortedByTitle(appcaches_child_
);
655 return appcaches_child_
;
658 CookieTreeIndexedDBsNode
* CookieTreeHostNode::GetOrCreateIndexedDBsNode() {
659 if (indexed_dbs_child_
)
660 return indexed_dbs_child_
;
661 indexed_dbs_child_
= new CookieTreeIndexedDBsNode
;
662 AddChildSortedByTitle(indexed_dbs_child_
);
663 return indexed_dbs_child_
;
666 CookieTreeFileSystemsNode
* CookieTreeHostNode::GetOrCreateFileSystemsNode() {
667 if (file_systems_child_
)
668 return file_systems_child_
;
669 file_systems_child_
= new CookieTreeFileSystemsNode
;
670 AddChildSortedByTitle(file_systems_child_
);
671 return file_systems_child_
;
674 CookieTreeQuotaNode
* CookieTreeHostNode::UpdateOrCreateQuotaNode(
675 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
) {
678 quota_child_
= new CookieTreeQuotaNode(quota_info
);
679 AddChildSortedByTitle(quota_child_
);
683 CookieTreeChannelIDsNode
*
684 CookieTreeHostNode::GetOrCreateChannelIDsNode() {
685 if (channel_ids_child_
)
686 return channel_ids_child_
;
687 channel_ids_child_
= new CookieTreeChannelIDsNode
;
688 AddChildSortedByTitle(channel_ids_child_
);
689 return channel_ids_child_
;
692 CookieTreeServiceWorkersNode
*
693 CookieTreeHostNode::GetOrCreateServiceWorkersNode() {
694 if (service_workers_child_
)
695 return service_workers_child_
;
696 service_workers_child_
= new CookieTreeServiceWorkersNode
;
697 AddChildSortedByTitle(service_workers_child_
);
698 return service_workers_child_
;
701 CookieTreeFlashLSONode
* CookieTreeHostNode::GetOrCreateFlashLSONode(
702 const std::string
& domain
) {
703 DCHECK_EQ(GetHost(), domain
);
704 if (flash_lso_child_
)
705 return flash_lso_child_
;
706 flash_lso_child_
= new CookieTreeFlashLSONode(domain
);
707 AddChildSortedByTitle(flash_lso_child_
);
708 return flash_lso_child_
;
711 void CookieTreeHostNode::CreateContentException(
712 content_settings::CookieSettings
* cookie_settings
,
713 ContentSetting setting
) const {
714 DCHECK(setting
== CONTENT_SETTING_ALLOW
||
715 setting
== CONTENT_SETTING_BLOCK
||
716 setting
== CONTENT_SETTING_SESSION_ONLY
);
717 if (CanCreateContentException()) {
718 cookie_settings
->ResetCookieSetting(
719 ContentSettingsPattern::FromURLNoWildcard(url_
),
720 ContentSettingsPattern::Wildcard());
721 cookie_settings
->SetCookieSetting(
722 ContentSettingsPattern::FromURL(url_
),
723 ContentSettingsPattern::Wildcard(), setting
);
727 bool CookieTreeHostNode::CanCreateContentException() const {
728 return !url_
.SchemeIsFile();
731 ///////////////////////////////////////////////////////////////////////////////
732 // CookieTreeCookiesNode, public:
734 CookieTreeCookiesNode::CookieTreeCookiesNode()
735 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES
)) {
738 CookieTreeCookiesNode::~CookieTreeCookiesNode() {
741 CookieTreeNode::DetailedInfo
CookieTreeCookiesNode::GetDetailedInfo() const {
742 return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES
);
745 ///////////////////////////////////////////////////////////////////////////////
746 // CookieTreeAppCachesNode, public:
748 CookieTreeAppCachesNode::CookieTreeAppCachesNode()
749 : CookieTreeNode(l10n_util::GetStringUTF16(
750 IDS_COOKIES_APPLICATION_CACHES
)) {
753 CookieTreeAppCachesNode::~CookieTreeAppCachesNode() {}
755 CookieTreeNode::DetailedInfo
CookieTreeAppCachesNode::GetDetailedInfo() const {
756 return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES
);
759 ///////////////////////////////////////////////////////////////////////////////
760 // CookieTreeDatabasesNode, public:
762 CookieTreeDatabasesNode::CookieTreeDatabasesNode()
763 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES
)) {
766 CookieTreeDatabasesNode::~CookieTreeDatabasesNode() {}
768 CookieTreeNode::DetailedInfo
CookieTreeDatabasesNode::GetDetailedInfo() const {
769 return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES
);
772 ///////////////////////////////////////////////////////////////////////////////
773 // CookieTreeLocalStoragesNode, public:
775 CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode()
776 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE
)) {
779 CookieTreeLocalStoragesNode::~CookieTreeLocalStoragesNode() {}
781 CookieTreeNode::DetailedInfo
782 CookieTreeLocalStoragesNode::GetDetailedInfo() const {
783 return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES
);
786 ///////////////////////////////////////////////////////////////////////////////
787 // CookieTreeSessionStoragesNode, public:
789 CookieTreeSessionStoragesNode::CookieTreeSessionStoragesNode()
790 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE
)) {
793 CookieTreeSessionStoragesNode::~CookieTreeSessionStoragesNode() {}
795 CookieTreeNode::DetailedInfo
796 CookieTreeSessionStoragesNode::GetDetailedInfo() const {
797 return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES
);
800 ///////////////////////////////////////////////////////////////////////////////
801 // CookieTreeIndexedDBsNode, public:
803 CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode()
804 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS
)) {
807 CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {}
809 CookieTreeNode::DetailedInfo
810 CookieTreeIndexedDBsNode::GetDetailedInfo() const {
811 return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS
);
814 ///////////////////////////////////////////////////////////////////////////////
815 // CookieTreeFileSystemsNode, public:
817 CookieTreeFileSystemsNode::CookieTreeFileSystemsNode()
818 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS
)) {
821 CookieTreeFileSystemsNode::~CookieTreeFileSystemsNode() {}
823 CookieTreeNode::DetailedInfo
824 CookieTreeFileSystemsNode::GetDetailedInfo() const {
825 return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS
);
828 ///////////////////////////////////////////////////////////////////////////////
829 // CookieTreeChannelIDsNode, public:
831 CookieTreeChannelIDsNode::CookieTreeChannelIDsNode()
833 l10n_util::GetStringUTF16(IDS_COOKIES_CHANNEL_IDS
)) {
836 CookieTreeChannelIDsNode::~CookieTreeChannelIDsNode() {}
838 CookieTreeNode::DetailedInfo
839 CookieTreeChannelIDsNode::GetDetailedInfo() const {
840 return DetailedInfo().Init(DetailedInfo::TYPE_CHANNEL_IDS
);
843 void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode
* new_child
) {
845 std::vector
<CookieTreeNode
*>::iterator iter
=
846 std::lower_bound(children().begin(), children().end(), new_child
,
847 NodeTitleComparator());
848 GetModel()->Add(this, new_child
, iter
- children().begin());
851 ///////////////////////////////////////////////////////////////////////////////
852 // CookieTreeServiceWorkersNode, public:
854 CookieTreeServiceWorkersNode::CookieTreeServiceWorkersNode()
855 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SERVICE_WORKERS
)) {
858 CookieTreeServiceWorkersNode::~CookieTreeServiceWorkersNode() {
861 CookieTreeNode::DetailedInfo
CookieTreeServiceWorkersNode::GetDetailedInfo()
863 return DetailedInfo().Init(DetailedInfo::TYPE_SERVICE_WORKERS
);
866 ///////////////////////////////////////////////////////////////////////////////
867 // CookieTreeFlashLSONode
868 CookieTreeFlashLSONode::CookieTreeFlashLSONode(
869 const std::string
& domain
)
871 CookieTreeFlashLSONode::~CookieTreeFlashLSONode() {}
873 void CookieTreeFlashLSONode::DeleteStoredObjects() {
874 // We are one level below the host node.
875 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(parent());
876 CHECK_EQ(host
->GetDetailedInfo().node_type
,
877 CookieTreeNode::DetailedInfo::TYPE_HOST
);
878 LocalDataContainer
* container
= GetModel()->data_container();
879 container
->flash_lso_helper_
->DeleteFlashLSOsForSite(domain_
);
882 CookieTreeNode::DetailedInfo
CookieTreeFlashLSONode::GetDetailedInfo() const {
883 return DetailedInfo().InitFlashLSO(domain_
);
886 ///////////////////////////////////////////////////////////////////////////////
887 // ScopedBatchUpdateNotifier
888 CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier(
889 CookiesTreeModel
* model
,
890 CookieTreeNode
* node
)
891 : model_(model
), node_(node
) {
892 model_
->RecordBatchSeen();
895 CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() {
896 if (batch_in_progress_
) {
897 model_
->NotifyObserverTreeNodeChanged(node_
);
898 model_
->NotifyObserverEndBatch();
900 // If no batch started, and this is the last batch, give the model a chance
901 // to send out a final notification.
902 model_
->MaybeNotifyBatchesEnded();
906 void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() {
907 if (!batch_in_progress_
) {
908 model_
->NotifyObserverBeginBatch();
909 batch_in_progress_
= true;
913 ///////////////////////////////////////////////////////////////////////////////
914 // CookiesTreeModel, public:
915 CookiesTreeModel::CookiesTreeModel(
916 LocalDataContainer
* data_container
,
917 ExtensionSpecialStoragePolicy
* special_storage_policy
,
918 bool group_by_cookie_source
)
919 : ui::TreeNodeModel
<CookieTreeNode
>(new CookieTreeRootNode(this)),
920 data_container_(data_container
),
921 #if defined(ENABLE_EXTENSIONS)
922 special_storage_policy_(special_storage_policy
),
924 group_by_cookie_source_(group_by_cookie_source
) {
925 data_container_
->Init(this);
928 CookiesTreeModel::~CookiesTreeModel() {
932 int CookiesTreeModel::GetSendForMessageID(const net::CanonicalCookie
& cookie
) {
933 if (cookie
.IsSecure()) {
934 if (cookie
.IsFirstPartyOnly())
935 return IDS_COOKIES_COOKIE_SENDFOR_SECURE_FIRSTPARTY
;
936 return IDS_COOKIES_COOKIE_SENDFOR_SECURE
;
938 if (cookie
.IsFirstPartyOnly())
939 return IDS_COOKIES_COOKIE_SENDFOR_FIRSTPARTY
;
940 return IDS_COOKIES_COOKIE_SENDFOR_ANY
;
943 ///////////////////////////////////////////////////////////////////////////////
944 // CookiesTreeModel, TreeModel methods (public):
946 // TreeModel methods:
947 // Returns the set of icons for the nodes in the tree. You only need override
948 // this if you don't want to use the default folder icons.
949 void CookiesTreeModel::GetIcons(std::vector
<gfx::ImageSkia
>* icons
) {
950 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
951 IDR_DEFAULT_FAVICON
).ToImageSkia());
952 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
953 IDR_COOKIE_ICON
).ToImageSkia());
954 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
955 IDR_COOKIE_STORAGE_ICON
).ToImageSkia());
958 // Returns the index of the icon to use for |node|. Return -1 to use the
959 // default icon. The index is relative to the list of icons returned from
961 int CookiesTreeModel::GetIconIndex(ui::TreeModelNode
* node
) {
962 CookieTreeNode
* ct_node
= static_cast<CookieTreeNode
*>(node
);
963 switch (ct_node
->GetDetailedInfo().node_type
) {
964 case CookieTreeNode::DetailedInfo::TYPE_HOST
:
966 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
968 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
970 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
971 return DATABASE
; // close enough
972 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
973 return DATABASE
; // ditto
974 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
975 return DATABASE
; // ditto
976 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
977 return DATABASE
; // ditto
978 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
979 return DATABASE
; // ditto
980 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
982 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
983 return COOKIE
; // It's kinda like a cookie?
984 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER
:
985 return DATABASE
; // Just like appcache
992 void CookiesTreeModel::DeleteAllStoredObjects() {
993 NotifyObserverBeginBatch();
994 CookieTreeNode
* root
= GetRoot();
995 root
->DeleteStoredObjects();
996 int num_children
= root
->child_count();
997 for (int i
= num_children
- 1; i
>= 0; --i
)
998 delete Remove(root
, root
->GetChild(i
));
999 NotifyObserverTreeNodeChanged(root
);
1000 NotifyObserverEndBatch();
1003 void CookiesTreeModel::DeleteCookieNode(CookieTreeNode
* cookie_node
) {
1004 if (cookie_node
== GetRoot())
1006 cookie_node
->DeleteStoredObjects();
1007 CookieTreeNode
* parent_node
= cookie_node
->parent();
1008 delete Remove(parent_node
, cookie_node
);
1009 if (parent_node
->empty())
1010 DeleteCookieNode(parent_node
);
1013 void CookiesTreeModel::UpdateSearchResults(const base::string16
& filter
) {
1014 CookieTreeNode
* root
= GetRoot();
1015 SetBatchExpectation(1, true);
1016 ScopedBatchUpdateNotifier
notifier(this, root
);
1017 int num_children
= root
->child_count();
1018 notifier
.StartBatchUpdate();
1019 for (int i
= num_children
- 1; i
>= 0; --i
)
1020 delete Remove(root
, root
->GetChild(i
));
1022 PopulateCookieInfoWithFilter(data_container(), ¬ifier
, filter
);
1023 PopulateDatabaseInfoWithFilter(data_container(), ¬ifier
, filter
);
1024 PopulateLocalStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
1025 PopulateSessionStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
1026 PopulateAppCacheInfoWithFilter(data_container(), ¬ifier
, filter
);
1027 PopulateIndexedDBInfoWithFilter(data_container(), ¬ifier
, filter
);
1028 PopulateFileSystemInfoWithFilter(data_container(), ¬ifier
, filter
);
1029 PopulateQuotaInfoWithFilter(data_container(), ¬ifier
, filter
);
1030 PopulateChannelIDInfoWithFilter(data_container(), ¬ifier
, filter
);
1031 PopulateServiceWorkerUsageInfoWithFilter(data_container(), ¬ifier
, filter
);
1034 #if defined(ENABLE_EXTENSIONS)
1035 const extensions::ExtensionSet
* CookiesTreeModel::ExtensionsProtectingNode(
1036 const CookieTreeNode
& cookie_node
) {
1037 if (!special_storage_policy_
.get())
1040 CookieTreeNode::DetailedInfo info
= cookie_node
.GetDetailedInfo();
1042 if (!TypeIsProtected(info
.node_type
))
1045 DCHECK(!info
.origin
.is_empty());
1046 return special_storage_policy_
->ExtensionsProtectingOrigin(info
.origin
);
1050 void CookiesTreeModel::AddCookiesTreeObserver(Observer
* observer
) {
1051 cookies_observer_list_
.AddObserver(observer
);
1052 // Call super so that TreeNodeModel can notify, too.
1053 ui::TreeNodeModel
<CookieTreeNode
>::AddObserver(observer
);
1056 void CookiesTreeModel::RemoveCookiesTreeObserver(Observer
* observer
) {
1057 cookies_observer_list_
.RemoveObserver(observer
);
1058 // Call super so that TreeNodeModel doesn't have dead pointers.
1059 ui::TreeNodeModel
<CookieTreeNode
>::RemoveObserver(observer
);
1062 void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer
* container
) {
1063 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1064 PopulateAppCacheInfoWithFilter(container
, ¬ifier
, base::string16());
1067 void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer
* container
) {
1068 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1069 PopulateCookieInfoWithFilter(container
, ¬ifier
, base::string16());
1072 void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer
* container
) {
1073 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1074 PopulateDatabaseInfoWithFilter(container
, ¬ifier
, base::string16());
1077 void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer
* container
) {
1078 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1079 PopulateLocalStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1082 void CookiesTreeModel::PopulateSessionStorageInfo(
1083 LocalDataContainer
* container
) {
1084 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1085 PopulateSessionStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1088 void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer
* container
) {
1089 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1090 PopulateIndexedDBInfoWithFilter(container
, ¬ifier
, base::string16());
1093 void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer
* container
) {
1094 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1095 PopulateFileSystemInfoWithFilter(container
, ¬ifier
, base::string16());
1098 void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer
* container
) {
1099 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1100 PopulateQuotaInfoWithFilter(container
, ¬ifier
, base::string16());
1103 void CookiesTreeModel::PopulateChannelIDInfo(
1104 LocalDataContainer
* container
) {
1105 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1106 PopulateChannelIDInfoWithFilter(container
, ¬ifier
, base::string16());
1109 void CookiesTreeModel::PopulateServiceWorkerUsageInfo(
1110 LocalDataContainer
* container
) {
1111 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1112 PopulateServiceWorkerUsageInfoWithFilter(
1113 container
, ¬ifier
, base::string16());
1116 void CookiesTreeModel::PopulateFlashLSOInfo(
1117 LocalDataContainer
* container
) {
1118 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1119 PopulateFlashLSOInfoWithFilter(container
, ¬ifier
, base::string16());
1122 void CookiesTreeModel::PopulateAppCacheInfoWithFilter(
1123 LocalDataContainer
* container
,
1124 ScopedBatchUpdateNotifier
* notifier
,
1125 const base::string16
& filter
) {
1126 using content::AppCacheInfo
;
1127 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1129 if (container
->appcache_info_
.empty())
1132 notifier
->StartBatchUpdate();
1133 for (auto& origin
: container
->appcache_info_
) {
1134 base::string16 host_node_name
= base::UTF8ToUTF16(origin
.first
.host());
1135 if (filter
.empty() ||
1136 (host_node_name
.find(filter
) != base::string16::npos
)) {
1137 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
.first
);
1138 CookieTreeAppCachesNode
* appcaches_node
=
1139 host_node
->GetOrCreateAppCachesNode();
1141 for (std::list
<AppCacheInfo
>::iterator info
= origin
.second
.begin();
1142 info
!= origin
.second
.end(); ++info
) {
1143 appcaches_node
->AddAppCacheNode(
1144 new CookieTreeAppCacheNode(origin
.first
, info
));
1150 void CookiesTreeModel::PopulateCookieInfoWithFilter(
1151 LocalDataContainer
* container
,
1152 ScopedBatchUpdateNotifier
* notifier
,
1153 const base::string16
& filter
) {
1154 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1156 notifier
->StartBatchUpdate();
1157 for (CookieList::iterator it
= container
->cookie_list_
.begin();
1158 it
!= container
->cookie_list_
.end(); ++it
) {
1159 std::string source_string
= it
->Source();
1160 if (source_string
.empty() || !group_by_cookie_source_
) {
1161 std::string domain
= it
->Domain();
1162 if (domain
.length() > 1 && domain
[0] == '.')
1163 domain
= domain
.substr(1);
1165 // We treat secure cookies just the same as normal ones.
1166 source_string
= std::string(url::kHttpScheme
) +
1167 url::kStandardSchemeSeparator
+ domain
+ "/";
1170 GURL
source(source_string
);
1171 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(source
)
1172 .find(filter
) != base::string16::npos
)) {
1173 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(source
);
1174 CookieTreeCookiesNode
* cookies_node
=
1175 host_node
->GetOrCreateCookiesNode();
1176 CookieTreeCookieNode
* new_cookie
= new CookieTreeCookieNode(it
);
1177 cookies_node
->AddCookieNode(new_cookie
);
1182 void CookiesTreeModel::PopulateDatabaseInfoWithFilter(
1183 LocalDataContainer
* container
,
1184 ScopedBatchUpdateNotifier
* notifier
,
1185 const base::string16
& filter
) {
1186 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1188 if (container
->database_info_list_
.empty())
1191 notifier
->StartBatchUpdate();
1192 for (DatabaseInfoList::iterator database_info
=
1193 container
->database_info_list_
.begin();
1194 database_info
!= container
->database_info_list_
.end();
1196 GURL
origin(database_info
->identifier
.ToOrigin());
1198 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1199 .find(filter
) != base::string16::npos
)) {
1200 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1201 CookieTreeDatabasesNode
* databases_node
=
1202 host_node
->GetOrCreateDatabasesNode();
1203 databases_node
->AddDatabaseNode(
1204 new CookieTreeDatabaseNode(database_info
));
1209 void CookiesTreeModel::PopulateLocalStorageInfoWithFilter(
1210 LocalDataContainer
* container
,
1211 ScopedBatchUpdateNotifier
* notifier
,
1212 const base::string16
& filter
) {
1213 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1215 if (container
->local_storage_info_list_
.empty())
1218 notifier
->StartBatchUpdate();
1219 for (LocalStorageInfoList::iterator local_storage_info
=
1220 container
->local_storage_info_list_
.begin();
1221 local_storage_info
!= container
->local_storage_info_list_
.end();
1222 ++local_storage_info
) {
1223 const GURL
& origin(local_storage_info
->origin_url
);
1225 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1226 .find(filter
) != std::string::npos
)) {
1227 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1228 CookieTreeLocalStoragesNode
* local_storages_node
=
1229 host_node
->GetOrCreateLocalStoragesNode();
1230 local_storages_node
->AddLocalStorageNode(
1231 new CookieTreeLocalStorageNode(local_storage_info
));
1236 void CookiesTreeModel::PopulateSessionStorageInfoWithFilter(
1237 LocalDataContainer
* container
,
1238 ScopedBatchUpdateNotifier
* notifier
,
1239 const base::string16
& filter
) {
1240 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1242 if (container
->session_storage_info_list_
.empty())
1245 notifier
->StartBatchUpdate();
1246 for (LocalStorageInfoList::iterator session_storage_info
=
1247 container
->session_storage_info_list_
.begin();
1248 session_storage_info
!= container
->session_storage_info_list_
.end();
1249 ++session_storage_info
) {
1250 const GURL
& origin
= session_storage_info
->origin_url
;
1252 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1253 .find(filter
) != base::string16::npos
)) {
1254 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1255 CookieTreeSessionStoragesNode
* session_storages_node
=
1256 host_node
->GetOrCreateSessionStoragesNode();
1257 session_storages_node
->AddSessionStorageNode(
1258 new CookieTreeSessionStorageNode(session_storage_info
));
1263 void CookiesTreeModel::PopulateIndexedDBInfoWithFilter(
1264 LocalDataContainer
* container
,
1265 ScopedBatchUpdateNotifier
* notifier
,
1266 const base::string16
& filter
) {
1267 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1269 if (container
->indexed_db_info_list_
.empty())
1272 notifier
->StartBatchUpdate();
1273 for (IndexedDBInfoList::iterator indexed_db_info
=
1274 container
->indexed_db_info_list_
.begin();
1275 indexed_db_info
!= container
->indexed_db_info_list_
.end();
1276 ++indexed_db_info
) {
1277 const GURL
& origin
= indexed_db_info
->origin_
;
1279 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1280 .find(filter
) != base::string16::npos
)) {
1281 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1282 CookieTreeIndexedDBsNode
* indexed_dbs_node
=
1283 host_node
->GetOrCreateIndexedDBsNode();
1284 indexed_dbs_node
->AddIndexedDBNode(
1285 new CookieTreeIndexedDBNode(indexed_db_info
));
1290 void CookiesTreeModel::PopulateChannelIDInfoWithFilter(
1291 LocalDataContainer
* container
,
1292 ScopedBatchUpdateNotifier
* notifier
,
1293 const base::string16
& filter
) {
1294 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1296 if (container
->channel_id_list_
.empty())
1299 notifier
->StartBatchUpdate();
1300 for (ChannelIDList::iterator channel_id_info
=
1301 container
->channel_id_list_
.begin();
1302 channel_id_info
!= container
->channel_id_list_
.end();
1303 ++channel_id_info
) {
1304 GURL
origin(channel_id_info
->server_identifier());
1305 if (!origin
.is_valid()) {
1306 // Channel ID. Make a valid URL to satisfy the
1307 // CookieTreeRootNode::GetOrCreateHostNode interface.
1308 origin
= GURL(std::string(url::kHttpsScheme
) +
1309 url::kStandardSchemeSeparator
+
1310 channel_id_info
->server_identifier() + "/");
1312 base::string16 title
= CookieTreeHostNode::TitleForUrl(origin
);
1313 if (filter
.empty() || title
.find(filter
) != base::string16::npos
) {
1314 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1315 CookieTreeChannelIDsNode
* channel_ids_node
=
1316 host_node
->GetOrCreateChannelIDsNode();
1317 channel_ids_node
->AddChannelIDNode(
1318 new CookieTreeChannelIDNode(channel_id_info
));
1323 void CookiesTreeModel::PopulateServiceWorkerUsageInfoWithFilter(
1324 LocalDataContainer
* container
,
1325 ScopedBatchUpdateNotifier
* notifier
,
1326 const base::string16
& filter
) {
1327 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1329 if (container
->service_worker_info_list_
.empty())
1332 notifier
->StartBatchUpdate();
1333 for (ServiceWorkerUsageInfoList::iterator service_worker_info
=
1334 container
->service_worker_info_list_
.begin();
1335 service_worker_info
!= container
->service_worker_info_list_
.end();
1336 ++service_worker_info
) {
1337 const GURL
& origin
= service_worker_info
->origin
;
1339 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1340 .find(filter
) != base::string16::npos
)) {
1341 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1342 CookieTreeServiceWorkersNode
* service_workers_node
=
1343 host_node
->GetOrCreateServiceWorkersNode();
1344 service_workers_node
->AddServiceWorkerNode(
1345 new CookieTreeServiceWorkerNode(service_worker_info
));
1350 void CookiesTreeModel::PopulateFileSystemInfoWithFilter(
1351 LocalDataContainer
* container
,
1352 ScopedBatchUpdateNotifier
* notifier
,
1353 const base::string16
& filter
) {
1354 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1356 if (container
->file_system_info_list_
.empty())
1359 notifier
->StartBatchUpdate();
1360 for (FileSystemInfoList::iterator file_system_info
=
1361 container
->file_system_info_list_
.begin();
1362 file_system_info
!= container
->file_system_info_list_
.end();
1363 ++file_system_info
) {
1364 GURL
origin(file_system_info
->origin
);
1366 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1367 .find(filter
) != base::string16::npos
)) {
1368 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1369 CookieTreeFileSystemsNode
* file_systems_node
=
1370 host_node
->GetOrCreateFileSystemsNode();
1371 file_systems_node
->AddFileSystemNode(
1372 new CookieTreeFileSystemNode(file_system_info
));
1377 void CookiesTreeModel::PopulateQuotaInfoWithFilter(
1378 LocalDataContainer
* container
,
1379 ScopedBatchUpdateNotifier
* notifier
,
1380 const base::string16
& filter
) {
1381 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1383 if (container
->quota_info_list_
.empty())
1386 notifier
->StartBatchUpdate();
1387 for (QuotaInfoList::iterator quota_info
= container
->quota_info_list_
.begin();
1388 quota_info
!= container
->quota_info_list_
.end();
1390 if (filter
.empty() || (base::UTF8ToUTF16(quota_info
->host
).find(filter
) !=
1391 base::string16::npos
)) {
1392 CookieTreeHostNode
* host_node
=
1393 root
->GetOrCreateHostNode(GURL("http://" + quota_info
->host
));
1394 host_node
->UpdateOrCreateQuotaNode(quota_info
);
1399 void CookiesTreeModel::PopulateFlashLSOInfoWithFilter(
1400 LocalDataContainer
* container
,
1401 ScopedBatchUpdateNotifier
* notifier
,
1402 const base::string16
& filter
) {
1403 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1405 if (container
->flash_lso_domain_list_
.empty())
1408 std::string filter_utf8
= base::UTF16ToUTF8(filter
);
1409 notifier
->StartBatchUpdate();
1410 for (std::vector
<std::string
>::iterator it
=
1411 container
->flash_lso_domain_list_
.begin();
1412 it
!= container
->flash_lso_domain_list_
.end(); ++it
) {
1413 if (filter_utf8
.empty() || it
->find(filter_utf8
) != std::string::npos
) {
1414 // Create a fake origin for GetOrCreateHostNode().
1415 GURL
origin("http://" + *it
);
1416 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1417 host_node
->GetOrCreateFlashLSONode(*it
);
1422 void CookiesTreeModel::SetBatchExpectation(int batches_expected
, bool reset
) {
1423 batches_expected_
= batches_expected
;
1426 batches_started_
= 0;
1429 MaybeNotifyBatchesEnded();
1433 void CookiesTreeModel::RecordBatchSeen() {
1437 void CookiesTreeModel::NotifyObserverBeginBatch() {
1438 // Only notify the model once if we're batching in a nested manner.
1439 if (batches_started_
++ == 0) {
1440 FOR_EACH_OBSERVER(Observer
,
1441 cookies_observer_list_
,
1442 TreeModelBeginBatch(this));
1446 void CookiesTreeModel::NotifyObserverEndBatch() {
1448 MaybeNotifyBatchesEnded();
1451 void CookiesTreeModel::MaybeNotifyBatchesEnded() {
1452 // Only notify the observers if this is the outermost call to EndBatch() if
1453 // called in a nested manner.
1454 if (batches_ended_
== batches_started_
&&
1455 batches_seen_
== batches_expected_
) {
1456 FOR_EACH_OBSERVER(Observer
,
1457 cookies_observer_list_
,
1458 TreeModelEndBatch(this));