1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/browsing_data/cookies_tree_model.h"
12 #include "base/bind.h"
13 #include "base/memory/linked_ptr.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
18 #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
19 #include "chrome/browser/content_settings/cookie_settings_factory.h"
20 #include "chrome/grit/generated_resources.h"
21 #include "components/content_settings/core/browser/cookie_settings.h"
22 #include "content/public/common/url_constants.h"
23 #include "grit/theme_resources.h"
24 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
25 #include "net/cookies/canonical_cookie.h"
26 #include "net/url_request/url_request_context.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/base/resource/resource_bundle.h"
29 #include "ui/gfx/image/image_skia.h"
30 #include "ui/resources/grit/ui_resources.h"
32 #if defined(ENABLE_EXTENSIONS)
33 #include "chrome/browser/extensions/extension_special_storage_policy.h"
34 #include "extensions/common/extension_set.h"
39 struct NodeTitleComparator
{
40 bool operator()(const CookieTreeNode
* lhs
, const CookieTreeNode
* rhs
) {
41 return lhs
->GetTitle() < rhs
->GetTitle();
45 // Comparison functor, for use in CookieTreeRootNode.
46 struct HostNodeComparator
{
47 bool operator()(const CookieTreeNode
* lhs
, const CookieTreeNode
* rhs
) {
48 // This comparator is only meant to compare CookieTreeHostNode types. Make
49 // sure we check this, as the static cast below is dangerous if we get the
51 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST
,
52 lhs
->GetDetailedInfo().node_type
);
53 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST
,
54 rhs
->GetDetailedInfo().node_type
);
56 const CookieTreeHostNode
* ltn
=
57 static_cast<const CookieTreeHostNode
*>(lhs
);
58 const CookieTreeHostNode
* rtn
=
59 static_cast<const CookieTreeHostNode
*>(rhs
);
61 // We want to order by registry controlled domain, so we would get
62 // google.com, ad.google.com, www.google.com,
63 // microsoft.com, ad.microsoft.com. CanonicalizeHost transforms the origins
64 // into a form like google.com.www so that string comparisons work.
65 return (ltn
->canonicalized_host() <
66 rtn
->canonicalized_host());
70 std::string
CanonicalizeHost(const GURL
& url
) {
71 // The canonicalized representation makes the registry controlled domain
72 // come first, and then adds subdomains in reverse order, e.g.
73 // 1.mail.google.com would become google.com.mail.1, and then a standard
74 // string comparison works to order hosts by registry controlled domain
75 // first. Leading dots are ignored, ".google.com" is the same as
78 if (url
.SchemeIsFile()) {
79 return std::string(url::kFileScheme
) +
80 url::kStandardSchemeSeparator
;
83 std::string host
= url
.host();
85 net::registry_controlled_domains::GetDomainAndRegistry(
87 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES
);
88 if (!retval
.length()) // Is an IP address or other special origin.
91 std::string::size_type position
= host
.rfind(retval
);
93 // The host may be the registry controlled domain, in which case fail fast.
94 if (position
== 0 || position
== std::string::npos
)
97 // If host is www.google.com, retval will contain google.com at this point.
98 // Start operating to the left of the registry controlled domain, e.g. in
99 // the www.google.com example, start at index 3.
102 // If position == 0, that means it's a dot; this will be ignored to treat
103 // ".google.com" the same as "google.com".
104 while (position
> 0) {
105 retval
+= std::string(".");
106 // Copy up to the next dot. host[position] is a dot so start after it.
107 std::string::size_type next_dot
= host
.rfind(".", position
- 1);
108 if (next_dot
== std::string::npos
) {
109 retval
+= host
.substr(0, position
);
112 retval
+= host
.substr(next_dot
+ 1, position
- (next_dot
+ 1));
118 // When creating a cookie tree node from a cookie, strip the port of the
119 // cookie source and treat all non-file:// URLs as http://.
120 GURL
CanonicalizeCookieSource(const net::CanonicalCookie
& cookie
) {
121 GURL url
= cookie
.Source();
122 if (url
.SchemeIsFile())
125 url::Replacements
<char> replacements
;
126 replacements
.ClearPort();
127 if (url
.SchemeIsCryptographic())
128 replacements
.SetScheme("http", url::Component(0, 4));
130 return url
.GetOrigin().ReplaceComponents(replacements
);
133 #if defined(ENABLE_EXTENSIONS)
134 bool TypeIsProtected(CookieTreeNode::DetailedInfo::NodeType type
) {
136 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
138 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
140 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
142 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
144 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
146 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
148 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
150 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
152 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
154 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER
:
156 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO
:
165 // This function returns the local data container associated with a leaf tree
166 // node. The app node is assumed to be 3 levels above the leaf because of the
167 // following structure:
168 // root -> origin -> storage type -> leaf node
169 LocalDataContainer
* GetLocalDataContainerForNode(CookieTreeNode
* node
) {
170 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(
171 node
->parent()->parent());
172 CHECK_EQ(host
->GetDetailedInfo().node_type
,
173 CookieTreeNode::DetailedInfo::TYPE_HOST
);
174 return node
->GetModel()->data_container();
179 CookieTreeNode::DetailedInfo::DetailedInfo() : node_type(TYPE_NONE
) {}
181 CookieTreeNode::DetailedInfo::~DetailedInfo() {}
183 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::Init(
185 DCHECK_EQ(TYPE_NONE
, node_type
);
190 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitHost() {
195 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitCookie(
196 const net::CanonicalCookie
* cookie
) {
198 this->cookie
= cookie
;
202 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitDatabase(
203 const BrowsingDataDatabaseHelper::DatabaseInfo
* database_info
) {
205 this->database_info
= database_info
;
206 origin
= database_info
->identifier
.ToOrigin();
210 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitLocalStorage(
211 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
212 local_storage_info
) {
213 Init(TYPE_LOCAL_STORAGE
);
214 this->local_storage_info
= local_storage_info
;
215 origin
= local_storage_info
->origin_url
;
219 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitSessionStorage(
220 const BrowsingDataLocalStorageHelper::LocalStorageInfo
*
221 session_storage_info
) {
222 Init(TYPE_SESSION_STORAGE
);
223 this->session_storage_info
= session_storage_info
;
224 origin
= session_storage_info
->origin_url
;
228 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitAppCache(
230 const content::AppCacheInfo
* appcache_info
) {
232 this->appcache_info
= appcache_info
;
233 this->origin
= origin
;
237 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitIndexedDB(
238 const content::IndexedDBInfo
* indexed_db_info
) {
239 Init(TYPE_INDEXED_DB
);
240 this->indexed_db_info
= indexed_db_info
;
241 this->origin
= indexed_db_info
->origin_
;
245 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFileSystem(
246 const BrowsingDataFileSystemHelper::FileSystemInfo
* file_system_info
) {
247 Init(TYPE_FILE_SYSTEM
);
248 this->file_system_info
= file_system_info
;
249 this->origin
= file_system_info
->origin
;
253 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitQuota(
254 const BrowsingDataQuotaHelper::QuotaInfo
* quota_info
) {
256 this->quota_info
= quota_info
;
260 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitChannelID(
261 const net::ChannelIDStore::ChannelID
* channel_id
) {
262 Init(TYPE_CHANNEL_ID
);
263 this->channel_id
= channel_id
;
267 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitServiceWorker(
268 const content::ServiceWorkerUsageInfo
* service_worker_info
) {
269 Init(TYPE_SERVICE_WORKER
);
270 this->service_worker_info
= service_worker_info
;
271 this->origin
= service_worker_info
->origin
;
275 CookieTreeNode::DetailedInfo
& CookieTreeNode::DetailedInfo::InitFlashLSO(
276 const std::string
& flash_lso_domain
) {
277 Init(TYPE_FLASH_LSO
);
278 this->flash_lso_domain
= flash_lso_domain
;
282 ///////////////////////////////////////////////////////////////////////////////
283 // CookieTreeNode, public:
285 void CookieTreeNode::DeleteStoredObjects() {
286 std::for_each(children().begin(),
288 std::mem_fun(&CookieTreeNode::DeleteStoredObjects
));
291 CookiesTreeModel
* CookieTreeNode::GetModel() const {
293 return parent()->GetModel();
298 ///////////////////////////////////////////////////////////////////////////////
299 // CookieTreeCookieNode, public:
301 CookieTreeCookieNode::CookieTreeCookieNode(
302 std::list
<net::CanonicalCookie
>::iterator cookie
)
303 : CookieTreeNode(base::UTF8ToUTF16(cookie
->Name())),
307 CookieTreeCookieNode::~CookieTreeCookieNode() {}
309 void CookieTreeCookieNode::DeleteStoredObjects() {
310 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
311 container
->cookie_helper_
->DeleteCookie(*cookie_
);
312 container
->cookie_list_
.erase(cookie_
);
315 CookieTreeNode::DetailedInfo
CookieTreeCookieNode::GetDetailedInfo() const {
316 return DetailedInfo().InitCookie(&*cookie_
);
319 ///////////////////////////////////////////////////////////////////////////////
320 // CookieTreeAppCacheNode, public:
322 CookieTreeAppCacheNode::CookieTreeAppCacheNode(
323 const GURL
& origin_url
,
324 std::list
<content::AppCacheInfo
>::iterator appcache_info
)
325 : CookieTreeNode(base::UTF8ToUTF16(appcache_info
->manifest_url
.spec())),
326 origin_url_(origin_url
),
327 appcache_info_(appcache_info
) {
330 CookieTreeAppCacheNode::~CookieTreeAppCacheNode() {
333 void CookieTreeAppCacheNode::DeleteStoredObjects() {
334 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
337 DCHECK(container
->appcache_helper_
.get());
338 container
->appcache_helper_
339 ->DeleteAppCacheGroup(appcache_info_
->manifest_url
);
340 container
->appcache_info_
[origin_url_
].erase(appcache_info_
);
344 CookieTreeNode::DetailedInfo
CookieTreeAppCacheNode::GetDetailedInfo() const {
345 return DetailedInfo().InitAppCache(origin_url_
, &*appcache_info_
);
348 ///////////////////////////////////////////////////////////////////////////////
349 // CookieTreeDatabaseNode, public:
351 CookieTreeDatabaseNode::CookieTreeDatabaseNode(
352 std::list
<BrowsingDataDatabaseHelper::DatabaseInfo
>::iterator database_info
)
353 : CookieTreeNode(database_info
->database_name
.empty() ?
354 l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME
) :
355 base::UTF8ToUTF16(database_info
->database_name
)),
356 database_info_(database_info
) {
359 CookieTreeDatabaseNode::~CookieTreeDatabaseNode() {}
361 void CookieTreeDatabaseNode::DeleteStoredObjects() {
362 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
365 container
->database_helper_
->DeleteDatabase(
366 database_info_
->identifier
.ToString(), database_info_
->database_name
);
367 container
->database_info_list_
.erase(database_info_
);
371 CookieTreeNode::DetailedInfo
CookieTreeDatabaseNode::GetDetailedInfo() const {
372 return DetailedInfo().InitDatabase(&*database_info_
);
375 ///////////////////////////////////////////////////////////////////////////////
376 // CookieTreeLocalStorageNode, public:
378 CookieTreeLocalStorageNode::CookieTreeLocalStorageNode(
379 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
381 : CookieTreeNode(base::UTF8ToUTF16(local_storage_info
->origin_url
.spec())),
382 local_storage_info_(local_storage_info
) {
385 CookieTreeLocalStorageNode::~CookieTreeLocalStorageNode() {}
387 void CookieTreeLocalStorageNode::DeleteStoredObjects() {
388 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
391 container
->local_storage_helper_
->DeleteOrigin(
392 local_storage_info_
->origin_url
);
393 container
->local_storage_info_list_
.erase(local_storage_info_
);
397 CookieTreeNode::DetailedInfo
398 CookieTreeLocalStorageNode::GetDetailedInfo() const {
399 return DetailedInfo().InitLocalStorage(
400 &*local_storage_info_
);
403 ///////////////////////////////////////////////////////////////////////////////
404 // CookieTreeSessionStorageNode, public:
406 CookieTreeSessionStorageNode::CookieTreeSessionStorageNode(
407 std::list
<BrowsingDataLocalStorageHelper::LocalStorageInfo
>::iterator
408 session_storage_info
)
410 base::UTF8ToUTF16(session_storage_info
->origin_url
.spec())),
411 session_storage_info_(session_storage_info
) {
414 CookieTreeSessionStorageNode::~CookieTreeSessionStorageNode() {}
416 void CookieTreeSessionStorageNode::DeleteStoredObjects() {
417 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
420 // TODO(rsesek): There's no easy way to get the namespace_id for a session
421 // storage, nor is there an easy way to clear session storage just by
422 // origin. This is probably okay since session storage is not persistent.
423 // http://crbug.com/168996
424 container
->session_storage_info_list_
.erase(session_storage_info_
);
428 CookieTreeNode::DetailedInfo
429 CookieTreeSessionStorageNode::GetDetailedInfo() const {
430 return DetailedInfo().InitSessionStorage(&*session_storage_info_
);
433 ///////////////////////////////////////////////////////////////////////////////
434 // CookieTreeIndexedDBNode, public:
436 CookieTreeIndexedDBNode::CookieTreeIndexedDBNode(
437 std::list
<content::IndexedDBInfo
>::iterator
439 : CookieTreeNode(base::UTF8ToUTF16(
440 indexed_db_info
->origin_
.spec())),
441 indexed_db_info_(indexed_db_info
) {
444 CookieTreeIndexedDBNode::~CookieTreeIndexedDBNode() {}
446 void CookieTreeIndexedDBNode::DeleteStoredObjects() {
447 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
450 container
->indexed_db_helper_
->DeleteIndexedDB(
451 indexed_db_info_
->origin_
);
452 container
->indexed_db_info_list_
.erase(indexed_db_info_
);
456 CookieTreeNode::DetailedInfo
CookieTreeIndexedDBNode::GetDetailedInfo() const {
457 return DetailedInfo().InitIndexedDB(&*indexed_db_info_
);
460 ///////////////////////////////////////////////////////////////////////////////
461 // CookieTreeFileSystemNode, public:
463 CookieTreeFileSystemNode::CookieTreeFileSystemNode(
464 std::list
<BrowsingDataFileSystemHelper::FileSystemInfo
>::iterator
466 : CookieTreeNode(base::UTF8ToUTF16(
467 file_system_info
->origin
.spec())),
468 file_system_info_(file_system_info
) {
471 CookieTreeFileSystemNode::~CookieTreeFileSystemNode() {}
473 void CookieTreeFileSystemNode::DeleteStoredObjects() {
474 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
477 container
->file_system_helper_
->DeleteFileSystemOrigin(
478 file_system_info_
->origin
);
479 container
->file_system_info_list_
.erase(file_system_info_
);
483 CookieTreeNode::DetailedInfo
CookieTreeFileSystemNode::GetDetailedInfo() const {
484 return DetailedInfo().InitFileSystem(&*file_system_info_
);
487 ///////////////////////////////////////////////////////////////////////////////
488 // CookieTreeQuotaNode, public:
490 CookieTreeQuotaNode::CookieTreeQuotaNode(
491 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
)
492 : CookieTreeNode(base::UTF8ToUTF16(quota_info
->host
)),
493 quota_info_(quota_info
) {
496 CookieTreeQuotaNode::~CookieTreeQuotaNode() {}
498 void CookieTreeQuotaNode::DeleteStoredObjects() {
499 // Calling this function may cause unexpected over-quota state of origin.
500 // However, it'll caused no problem, just prevent usage growth of the origin.
501 LocalDataContainer
* container
= GetModel()->data_container();
504 container
->quota_helper_
->RevokeHostQuota(quota_info_
->host
);
505 container
->quota_info_list_
.erase(quota_info_
);
509 CookieTreeNode::DetailedInfo
CookieTreeQuotaNode::GetDetailedInfo() const {
510 return DetailedInfo().InitQuota(&*quota_info_
);
513 ///////////////////////////////////////////////////////////////////////////////
514 // CookieTreeChannelIDNode, public:
516 CookieTreeChannelIDNode::CookieTreeChannelIDNode(
517 net::ChannelIDStore::ChannelIDList::iterator channel_id
)
518 : CookieTreeNode(base::ASCIIToUTF16(channel_id
->server_identifier())),
519 channel_id_(channel_id
) {
522 CookieTreeChannelIDNode::~CookieTreeChannelIDNode() {}
524 void CookieTreeChannelIDNode::DeleteStoredObjects() {
525 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
528 container
->channel_id_helper_
->DeleteChannelID(
529 channel_id_
->server_identifier());
530 container
->channel_id_list_
.erase(channel_id_
);
534 CookieTreeNode::DetailedInfo
535 CookieTreeChannelIDNode::GetDetailedInfo() const {
536 return DetailedInfo().InitChannelID(&*channel_id_
);
539 ///////////////////////////////////////////////////////////////////////////////
540 // CookieTreeServiceWorkerNode, public:
542 CookieTreeServiceWorkerNode::CookieTreeServiceWorkerNode(
543 std::list
<content::ServiceWorkerUsageInfo
>::iterator service_worker_info
)
544 : CookieTreeNode(base::UTF8ToUTF16(service_worker_info
->origin
.spec())),
545 service_worker_info_(service_worker_info
) {
548 CookieTreeServiceWorkerNode::~CookieTreeServiceWorkerNode() {
551 void CookieTreeServiceWorkerNode::DeleteStoredObjects() {
552 LocalDataContainer
* container
= GetLocalDataContainerForNode(this);
555 container
->service_worker_helper_
->DeleteServiceWorkers(
556 service_worker_info_
->origin
);
557 container
->service_worker_info_list_
.erase(service_worker_info_
);
561 CookieTreeNode::DetailedInfo
CookieTreeServiceWorkerNode::GetDetailedInfo()
563 return DetailedInfo().InitServiceWorker(&*service_worker_info_
);
566 ///////////////////////////////////////////////////////////////////////////////
567 // CookieTreeRootNode, public:
569 CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel
* model
)
573 CookieTreeRootNode::~CookieTreeRootNode() {}
575 CookieTreeHostNode
* CookieTreeRootNode::GetOrCreateHostNode(
577 scoped_ptr
<CookieTreeHostNode
> host_node(
578 new CookieTreeHostNode(url
));
580 // First see if there is an existing match.
581 std::vector
<CookieTreeNode
*>::iterator host_node_iterator
=
582 std::lower_bound(children().begin(), children().end(), host_node
.get(),
583 HostNodeComparator());
584 if (host_node_iterator
!= children().end() &&
585 CookieTreeHostNode::TitleForUrl(url
) ==
586 (*host_node_iterator
)->GetTitle())
587 return static_cast<CookieTreeHostNode
*>(*host_node_iterator
);
588 // Node doesn't exist, insert the new one into the (ordered) children.
590 model_
->Add(this, host_node
.get(),
591 (host_node_iterator
- children().begin()));
592 return host_node
.release();
595 CookiesTreeModel
* CookieTreeRootNode::GetModel() const {
599 CookieTreeNode::DetailedInfo
CookieTreeRootNode::GetDetailedInfo() const {
600 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT
);
603 ///////////////////////////////////////////////////////////////////////////////
604 // CookieTreeHostNode, public:
607 base::string16
CookieTreeHostNode::TitleForUrl(const GURL
& url
) {
608 const std::string
file_origin_node_name(
609 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
610 return base::UTF8ToUTF16(url
.SchemeIsFile() ? file_origin_node_name
614 CookieTreeHostNode::CookieTreeHostNode(const GURL
& url
)
615 : CookieTreeNode(TitleForUrl(url
)),
617 canonicalized_host_(CanonicalizeHost(url
)) {}
619 CookieTreeHostNode::~CookieTreeHostNode() {}
621 const std::string
CookieTreeHostNode::GetHost() const {
622 const std::string
file_origin_node_name(
623 std::string(url::kFileScheme
) + url::kStandardSchemeSeparator
);
624 return url_
.SchemeIsFile() ? file_origin_node_name
: url_
.host();
627 CookieTreeNode::DetailedInfo
CookieTreeHostNode::GetDetailedInfo() const {
628 return DetailedInfo().InitHost();
631 CookieTreeCookiesNode
* CookieTreeHostNode::GetOrCreateCookiesNode() {
633 return cookies_child_
;
634 cookies_child_
= new CookieTreeCookiesNode
;
635 AddChildSortedByTitle(cookies_child_
);
636 return cookies_child_
;
639 CookieTreeDatabasesNode
* CookieTreeHostNode::GetOrCreateDatabasesNode() {
640 if (databases_child_
)
641 return databases_child_
;
642 databases_child_
= new CookieTreeDatabasesNode
;
643 AddChildSortedByTitle(databases_child_
);
644 return databases_child_
;
647 CookieTreeLocalStoragesNode
*
648 CookieTreeHostNode::GetOrCreateLocalStoragesNode() {
649 if (local_storages_child_
)
650 return local_storages_child_
;
651 local_storages_child_
= new CookieTreeLocalStoragesNode
;
652 AddChildSortedByTitle(local_storages_child_
);
653 return local_storages_child_
;
656 CookieTreeSessionStoragesNode
*
657 CookieTreeHostNode::GetOrCreateSessionStoragesNode() {
658 if (session_storages_child_
)
659 return session_storages_child_
;
660 session_storages_child_
= new CookieTreeSessionStoragesNode
;
661 AddChildSortedByTitle(session_storages_child_
);
662 return session_storages_child_
;
665 CookieTreeAppCachesNode
* CookieTreeHostNode::GetOrCreateAppCachesNode() {
666 if (appcaches_child_
)
667 return appcaches_child_
;
668 appcaches_child_
= new CookieTreeAppCachesNode
;
669 AddChildSortedByTitle(appcaches_child_
);
670 return appcaches_child_
;
673 CookieTreeIndexedDBsNode
* CookieTreeHostNode::GetOrCreateIndexedDBsNode() {
674 if (indexed_dbs_child_
)
675 return indexed_dbs_child_
;
676 indexed_dbs_child_
= new CookieTreeIndexedDBsNode
;
677 AddChildSortedByTitle(indexed_dbs_child_
);
678 return indexed_dbs_child_
;
681 CookieTreeFileSystemsNode
* CookieTreeHostNode::GetOrCreateFileSystemsNode() {
682 if (file_systems_child_
)
683 return file_systems_child_
;
684 file_systems_child_
= new CookieTreeFileSystemsNode
;
685 AddChildSortedByTitle(file_systems_child_
);
686 return file_systems_child_
;
689 CookieTreeQuotaNode
* CookieTreeHostNode::UpdateOrCreateQuotaNode(
690 std::list
<BrowsingDataQuotaHelper::QuotaInfo
>::iterator quota_info
) {
693 quota_child_
= new CookieTreeQuotaNode(quota_info
);
694 AddChildSortedByTitle(quota_child_
);
698 CookieTreeChannelIDsNode
*
699 CookieTreeHostNode::GetOrCreateChannelIDsNode() {
700 if (channel_ids_child_
)
701 return channel_ids_child_
;
702 channel_ids_child_
= new CookieTreeChannelIDsNode
;
703 AddChildSortedByTitle(channel_ids_child_
);
704 return channel_ids_child_
;
707 CookieTreeServiceWorkersNode
*
708 CookieTreeHostNode::GetOrCreateServiceWorkersNode() {
709 if (service_workers_child_
)
710 return service_workers_child_
;
711 service_workers_child_
= new CookieTreeServiceWorkersNode
;
712 AddChildSortedByTitle(service_workers_child_
);
713 return service_workers_child_
;
716 CookieTreeFlashLSONode
* CookieTreeHostNode::GetOrCreateFlashLSONode(
717 const std::string
& domain
) {
718 DCHECK_EQ(GetHost(), domain
);
719 if (flash_lso_child_
)
720 return flash_lso_child_
;
721 flash_lso_child_
= new CookieTreeFlashLSONode(domain
);
722 AddChildSortedByTitle(flash_lso_child_
);
723 return flash_lso_child_
;
726 void CookieTreeHostNode::CreateContentException(
727 content_settings::CookieSettings
* cookie_settings
,
728 ContentSetting setting
) const {
729 DCHECK(setting
== CONTENT_SETTING_ALLOW
||
730 setting
== CONTENT_SETTING_BLOCK
||
731 setting
== CONTENT_SETTING_SESSION_ONLY
);
732 if (CanCreateContentException()) {
733 cookie_settings
->ResetCookieSetting(
734 ContentSettingsPattern::FromURLNoWildcard(url_
),
735 ContentSettingsPattern::Wildcard());
736 cookie_settings
->SetCookieSetting(
737 ContentSettingsPattern::FromURL(url_
),
738 ContentSettingsPattern::Wildcard(), setting
);
742 bool CookieTreeHostNode::CanCreateContentException() const {
743 return !url_
.SchemeIsFile();
746 ///////////////////////////////////////////////////////////////////////////////
747 // CookieTreeCookiesNode, public:
749 CookieTreeCookiesNode::CookieTreeCookiesNode()
750 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES
)) {
753 CookieTreeCookiesNode::~CookieTreeCookiesNode() {
756 CookieTreeNode::DetailedInfo
CookieTreeCookiesNode::GetDetailedInfo() const {
757 return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES
);
760 ///////////////////////////////////////////////////////////////////////////////
761 // CookieTreeAppCachesNode, public:
763 CookieTreeAppCachesNode::CookieTreeAppCachesNode()
764 : CookieTreeNode(l10n_util::GetStringUTF16(
765 IDS_COOKIES_APPLICATION_CACHES
)) {
768 CookieTreeAppCachesNode::~CookieTreeAppCachesNode() {}
770 CookieTreeNode::DetailedInfo
CookieTreeAppCachesNode::GetDetailedInfo() const {
771 return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES
);
774 ///////////////////////////////////////////////////////////////////////////////
775 // CookieTreeDatabasesNode, public:
777 CookieTreeDatabasesNode::CookieTreeDatabasesNode()
778 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES
)) {
781 CookieTreeDatabasesNode::~CookieTreeDatabasesNode() {}
783 CookieTreeNode::DetailedInfo
CookieTreeDatabasesNode::GetDetailedInfo() const {
784 return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES
);
787 ///////////////////////////////////////////////////////////////////////////////
788 // CookieTreeLocalStoragesNode, public:
790 CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode()
791 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE
)) {
794 CookieTreeLocalStoragesNode::~CookieTreeLocalStoragesNode() {}
796 CookieTreeNode::DetailedInfo
797 CookieTreeLocalStoragesNode::GetDetailedInfo() const {
798 return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES
);
801 ///////////////////////////////////////////////////////////////////////////////
802 // CookieTreeSessionStoragesNode, public:
804 CookieTreeSessionStoragesNode::CookieTreeSessionStoragesNode()
805 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE
)) {
808 CookieTreeSessionStoragesNode::~CookieTreeSessionStoragesNode() {}
810 CookieTreeNode::DetailedInfo
811 CookieTreeSessionStoragesNode::GetDetailedInfo() const {
812 return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES
);
815 ///////////////////////////////////////////////////////////////////////////////
816 // CookieTreeIndexedDBsNode, public:
818 CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode()
819 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS
)) {
822 CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {}
824 CookieTreeNode::DetailedInfo
825 CookieTreeIndexedDBsNode::GetDetailedInfo() const {
826 return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS
);
829 ///////////////////////////////////////////////////////////////////////////////
830 // CookieTreeFileSystemsNode, public:
832 CookieTreeFileSystemsNode::CookieTreeFileSystemsNode()
833 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS
)) {
836 CookieTreeFileSystemsNode::~CookieTreeFileSystemsNode() {}
838 CookieTreeNode::DetailedInfo
839 CookieTreeFileSystemsNode::GetDetailedInfo() const {
840 return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS
);
843 ///////////////////////////////////////////////////////////////////////////////
844 // CookieTreeChannelIDsNode, public:
846 CookieTreeChannelIDsNode::CookieTreeChannelIDsNode()
848 l10n_util::GetStringUTF16(IDS_COOKIES_CHANNEL_IDS
)) {
851 CookieTreeChannelIDsNode::~CookieTreeChannelIDsNode() {}
853 CookieTreeNode::DetailedInfo
854 CookieTreeChannelIDsNode::GetDetailedInfo() const {
855 return DetailedInfo().Init(DetailedInfo::TYPE_CHANNEL_IDS
);
858 void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode
* new_child
) {
860 std::vector
<CookieTreeNode
*>::iterator iter
=
861 std::lower_bound(children().begin(), children().end(), new_child
,
862 NodeTitleComparator());
863 GetModel()->Add(this, new_child
, iter
- children().begin());
866 ///////////////////////////////////////////////////////////////////////////////
867 // CookieTreeServiceWorkersNode, public:
869 CookieTreeServiceWorkersNode::CookieTreeServiceWorkersNode()
870 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SERVICE_WORKERS
)) {
873 CookieTreeServiceWorkersNode::~CookieTreeServiceWorkersNode() {
876 CookieTreeNode::DetailedInfo
CookieTreeServiceWorkersNode::GetDetailedInfo()
878 return DetailedInfo().Init(DetailedInfo::TYPE_SERVICE_WORKERS
);
881 ///////////////////////////////////////////////////////////////////////////////
882 // CookieTreeFlashLSONode
883 CookieTreeFlashLSONode::CookieTreeFlashLSONode(
884 const std::string
& domain
)
886 CookieTreeFlashLSONode::~CookieTreeFlashLSONode() {}
888 void CookieTreeFlashLSONode::DeleteStoredObjects() {
889 // We are one level below the host node.
890 CookieTreeHostNode
* host
= static_cast<CookieTreeHostNode
*>(parent());
891 CHECK_EQ(host
->GetDetailedInfo().node_type
,
892 CookieTreeNode::DetailedInfo::TYPE_HOST
);
893 LocalDataContainer
* container
= GetModel()->data_container();
894 container
->flash_lso_helper_
->DeleteFlashLSOsForSite(domain_
);
897 CookieTreeNode::DetailedInfo
CookieTreeFlashLSONode::GetDetailedInfo() const {
898 return DetailedInfo().InitFlashLSO(domain_
);
901 ///////////////////////////////////////////////////////////////////////////////
902 // ScopedBatchUpdateNotifier
903 CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier(
904 CookiesTreeModel
* model
,
905 CookieTreeNode
* node
)
906 : model_(model
), node_(node
) {
907 model_
->RecordBatchSeen();
910 CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() {
911 if (batch_in_progress_
) {
912 model_
->NotifyObserverTreeNodeChanged(node_
);
913 model_
->NotifyObserverEndBatch();
915 // If no batch started, and this is the last batch, give the model a chance
916 // to send out a final notification.
917 model_
->MaybeNotifyBatchesEnded();
921 void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() {
922 if (!batch_in_progress_
) {
923 model_
->NotifyObserverBeginBatch();
924 batch_in_progress_
= true;
928 ///////////////////////////////////////////////////////////////////////////////
929 // CookiesTreeModel, public:
930 CookiesTreeModel::CookiesTreeModel(
931 LocalDataContainer
* data_container
,
932 ExtensionSpecialStoragePolicy
* special_storage_policy
,
933 bool group_by_cookie_source
)
934 : ui::TreeNodeModel
<CookieTreeNode
>(new CookieTreeRootNode(this)),
935 data_container_(data_container
),
936 #if defined(ENABLE_EXTENSIONS)
937 special_storage_policy_(special_storage_policy
),
939 group_by_cookie_source_(group_by_cookie_source
) {
940 data_container_
->Init(this);
943 CookiesTreeModel::~CookiesTreeModel() {
947 int CookiesTreeModel::GetSendForMessageID(const net::CanonicalCookie
& cookie
) {
948 if (cookie
.IsSecure()) {
949 if (cookie
.IsFirstPartyOnly())
950 return IDS_COOKIES_COOKIE_SENDFOR_SECURE_FIRSTPARTY
;
951 return IDS_COOKIES_COOKIE_SENDFOR_SECURE
;
953 if (cookie
.IsFirstPartyOnly())
954 return IDS_COOKIES_COOKIE_SENDFOR_FIRSTPARTY
;
955 return IDS_COOKIES_COOKIE_SENDFOR_ANY
;
958 ///////////////////////////////////////////////////////////////////////////////
959 // CookiesTreeModel, TreeModel methods (public):
961 // TreeModel methods:
962 // Returns the set of icons for the nodes in the tree. You only need override
963 // this if you don't want to use the default folder icons.
964 void CookiesTreeModel::GetIcons(std::vector
<gfx::ImageSkia
>* icons
) {
965 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
966 IDR_DEFAULT_FAVICON
).ToImageSkia());
967 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
968 IDR_COOKIE_ICON
).ToImageSkia());
969 icons
->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
970 IDR_COOKIE_STORAGE_ICON
).ToImageSkia());
973 // Returns the index of the icon to use for |node|. Return -1 to use the
974 // default icon. The index is relative to the list of icons returned from
976 int CookiesTreeModel::GetIconIndex(ui::TreeModelNode
* node
) {
977 CookieTreeNode
* ct_node
= static_cast<CookieTreeNode
*>(node
);
978 switch (ct_node
->GetDetailedInfo().node_type
) {
979 case CookieTreeNode::DetailedInfo::TYPE_HOST
:
981 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
:
983 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
:
985 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
:
986 return DATABASE
; // close enough
987 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE
:
988 return DATABASE
; // ditto
989 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
:
990 return DATABASE
; // ditto
991 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
:
992 return DATABASE
; // ditto
993 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
:
994 return DATABASE
; // ditto
995 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
:
997 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID
:
998 return COOKIE
; // It's kinda like a cookie?
999 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER
:
1000 return DATABASE
; // Just like appcache
1007 void CookiesTreeModel::DeleteAllStoredObjects() {
1008 NotifyObserverBeginBatch();
1009 CookieTreeNode
* root
= GetRoot();
1010 root
->DeleteStoredObjects();
1011 int num_children
= root
->child_count();
1012 for (int i
= num_children
- 1; i
>= 0; --i
)
1013 delete Remove(root
, root
->GetChild(i
));
1014 NotifyObserverTreeNodeChanged(root
);
1015 NotifyObserverEndBatch();
1018 void CookiesTreeModel::DeleteCookieNode(CookieTreeNode
* cookie_node
) {
1019 if (cookie_node
== GetRoot())
1021 cookie_node
->DeleteStoredObjects();
1022 CookieTreeNode
* parent_node
= cookie_node
->parent();
1023 delete Remove(parent_node
, cookie_node
);
1024 if (parent_node
->empty())
1025 DeleteCookieNode(parent_node
);
1028 void CookiesTreeModel::UpdateSearchResults(const base::string16
& filter
) {
1029 CookieTreeNode
* root
= GetRoot();
1030 SetBatchExpectation(1, true);
1031 ScopedBatchUpdateNotifier
notifier(this, root
);
1032 int num_children
= root
->child_count();
1033 notifier
.StartBatchUpdate();
1034 for (int i
= num_children
- 1; i
>= 0; --i
)
1035 delete Remove(root
, root
->GetChild(i
));
1037 PopulateCookieInfoWithFilter(data_container(), ¬ifier
, filter
);
1038 PopulateDatabaseInfoWithFilter(data_container(), ¬ifier
, filter
);
1039 PopulateLocalStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
1040 PopulateSessionStorageInfoWithFilter(data_container(), ¬ifier
, filter
);
1041 PopulateAppCacheInfoWithFilter(data_container(), ¬ifier
, filter
);
1042 PopulateIndexedDBInfoWithFilter(data_container(), ¬ifier
, filter
);
1043 PopulateFileSystemInfoWithFilter(data_container(), ¬ifier
, filter
);
1044 PopulateQuotaInfoWithFilter(data_container(), ¬ifier
, filter
);
1045 PopulateChannelIDInfoWithFilter(data_container(), ¬ifier
, filter
);
1046 PopulateServiceWorkerUsageInfoWithFilter(data_container(), ¬ifier
, filter
);
1049 #if defined(ENABLE_EXTENSIONS)
1050 const extensions::ExtensionSet
* CookiesTreeModel::ExtensionsProtectingNode(
1051 const CookieTreeNode
& cookie_node
) {
1052 if (!special_storage_policy_
.get())
1055 CookieTreeNode::DetailedInfo info
= cookie_node
.GetDetailedInfo();
1057 if (!TypeIsProtected(info
.node_type
))
1060 DCHECK(!info
.origin
.is_empty());
1061 return special_storage_policy_
->ExtensionsProtectingOrigin(info
.origin
);
1065 void CookiesTreeModel::AddCookiesTreeObserver(Observer
* observer
) {
1066 cookies_observer_list_
.AddObserver(observer
);
1067 // Call super so that TreeNodeModel can notify, too.
1068 ui::TreeNodeModel
<CookieTreeNode
>::AddObserver(observer
);
1071 void CookiesTreeModel::RemoveCookiesTreeObserver(Observer
* observer
) {
1072 cookies_observer_list_
.RemoveObserver(observer
);
1073 // Call super so that TreeNodeModel doesn't have dead pointers.
1074 ui::TreeNodeModel
<CookieTreeNode
>::RemoveObserver(observer
);
1077 void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer
* container
) {
1078 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1079 PopulateAppCacheInfoWithFilter(container
, ¬ifier
, base::string16());
1082 void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer
* container
) {
1083 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1084 PopulateCookieInfoWithFilter(container
, ¬ifier
, base::string16());
1087 void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer
* container
) {
1088 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1089 PopulateDatabaseInfoWithFilter(container
, ¬ifier
, base::string16());
1092 void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer
* container
) {
1093 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1094 PopulateLocalStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1097 void CookiesTreeModel::PopulateSessionStorageInfo(
1098 LocalDataContainer
* container
) {
1099 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1100 PopulateSessionStorageInfoWithFilter(container
, ¬ifier
, base::string16());
1103 void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer
* container
) {
1104 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1105 PopulateIndexedDBInfoWithFilter(container
, ¬ifier
, base::string16());
1108 void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer
* container
) {
1109 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1110 PopulateFileSystemInfoWithFilter(container
, ¬ifier
, base::string16());
1113 void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer
* container
) {
1114 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1115 PopulateQuotaInfoWithFilter(container
, ¬ifier
, base::string16());
1118 void CookiesTreeModel::PopulateChannelIDInfo(
1119 LocalDataContainer
* container
) {
1120 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1121 PopulateChannelIDInfoWithFilter(container
, ¬ifier
, base::string16());
1124 void CookiesTreeModel::PopulateServiceWorkerUsageInfo(
1125 LocalDataContainer
* container
) {
1126 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1127 PopulateServiceWorkerUsageInfoWithFilter(
1128 container
, ¬ifier
, base::string16());
1131 void CookiesTreeModel::PopulateFlashLSOInfo(
1132 LocalDataContainer
* container
) {
1133 ScopedBatchUpdateNotifier
notifier(this, GetRoot());
1134 PopulateFlashLSOInfoWithFilter(container
, ¬ifier
, base::string16());
1137 void CookiesTreeModel::PopulateAppCacheInfoWithFilter(
1138 LocalDataContainer
* container
,
1139 ScopedBatchUpdateNotifier
* notifier
,
1140 const base::string16
& filter
) {
1141 using content::AppCacheInfo
;
1142 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1144 if (container
->appcache_info_
.empty())
1147 notifier
->StartBatchUpdate();
1148 for (auto& origin
: container
->appcache_info_
) {
1149 base::string16 host_node_name
= base::UTF8ToUTF16(origin
.first
.host());
1150 if (filter
.empty() ||
1151 (host_node_name
.find(filter
) != base::string16::npos
)) {
1152 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
.first
);
1153 CookieTreeAppCachesNode
* appcaches_node
=
1154 host_node
->GetOrCreateAppCachesNode();
1156 for (std::list
<AppCacheInfo
>::iterator info
= origin
.second
.begin();
1157 info
!= origin
.second
.end(); ++info
) {
1158 appcaches_node
->AddAppCacheNode(
1159 new CookieTreeAppCacheNode(origin
.first
, info
));
1165 void CookiesTreeModel::PopulateCookieInfoWithFilter(
1166 LocalDataContainer
* container
,
1167 ScopedBatchUpdateNotifier
* notifier
,
1168 const base::string16
& filter
) {
1169 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1171 notifier
->StartBatchUpdate();
1172 for (CookieList::iterator it
= container
->cookie_list_
.begin();
1173 it
!= container
->cookie_list_
.end(); ++it
) {
1174 GURL source
= CanonicalizeCookieSource(*it
);
1175 if (source
.is_empty() || !group_by_cookie_source_
) {
1176 std::string domain
= it
->Domain();
1177 if (domain
.length() > 1 && domain
[0] == '.')
1178 domain
= domain
.substr(1);
1180 // We treat secure cookies just the same as normal ones.
1181 source
= GURL(std::string(url::kHttpScheme
) +
1182 url::kStandardSchemeSeparator
+ domain
+ "/");
1185 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(source
)
1186 .find(filter
) != base::string16::npos
)) {
1187 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(source
);
1188 CookieTreeCookiesNode
* cookies_node
=
1189 host_node
->GetOrCreateCookiesNode();
1190 CookieTreeCookieNode
* new_cookie
= new CookieTreeCookieNode(it
);
1191 cookies_node
->AddCookieNode(new_cookie
);
1196 void CookiesTreeModel::PopulateDatabaseInfoWithFilter(
1197 LocalDataContainer
* container
,
1198 ScopedBatchUpdateNotifier
* notifier
,
1199 const base::string16
& filter
) {
1200 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1202 if (container
->database_info_list_
.empty())
1205 notifier
->StartBatchUpdate();
1206 for (DatabaseInfoList::iterator database_info
=
1207 container
->database_info_list_
.begin();
1208 database_info
!= container
->database_info_list_
.end();
1210 GURL
origin(database_info
->identifier
.ToOrigin());
1212 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1213 .find(filter
) != base::string16::npos
)) {
1214 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1215 CookieTreeDatabasesNode
* databases_node
=
1216 host_node
->GetOrCreateDatabasesNode();
1217 databases_node
->AddDatabaseNode(
1218 new CookieTreeDatabaseNode(database_info
));
1223 void CookiesTreeModel::PopulateLocalStorageInfoWithFilter(
1224 LocalDataContainer
* container
,
1225 ScopedBatchUpdateNotifier
* notifier
,
1226 const base::string16
& filter
) {
1227 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1229 if (container
->local_storage_info_list_
.empty())
1232 notifier
->StartBatchUpdate();
1233 for (LocalStorageInfoList::iterator local_storage_info
=
1234 container
->local_storage_info_list_
.begin();
1235 local_storage_info
!= container
->local_storage_info_list_
.end();
1236 ++local_storage_info
) {
1237 const GURL
& origin(local_storage_info
->origin_url
);
1239 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1240 .find(filter
) != std::string::npos
)) {
1241 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1242 CookieTreeLocalStoragesNode
* local_storages_node
=
1243 host_node
->GetOrCreateLocalStoragesNode();
1244 local_storages_node
->AddLocalStorageNode(
1245 new CookieTreeLocalStorageNode(local_storage_info
));
1250 void CookiesTreeModel::PopulateSessionStorageInfoWithFilter(
1251 LocalDataContainer
* container
,
1252 ScopedBatchUpdateNotifier
* notifier
,
1253 const base::string16
& filter
) {
1254 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1256 if (container
->session_storage_info_list_
.empty())
1259 notifier
->StartBatchUpdate();
1260 for (LocalStorageInfoList::iterator session_storage_info
=
1261 container
->session_storage_info_list_
.begin();
1262 session_storage_info
!= container
->session_storage_info_list_
.end();
1263 ++session_storage_info
) {
1264 const GURL
& origin
= session_storage_info
->origin_url
;
1266 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1267 .find(filter
) != base::string16::npos
)) {
1268 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1269 CookieTreeSessionStoragesNode
* session_storages_node
=
1270 host_node
->GetOrCreateSessionStoragesNode();
1271 session_storages_node
->AddSessionStorageNode(
1272 new CookieTreeSessionStorageNode(session_storage_info
));
1277 void CookiesTreeModel::PopulateIndexedDBInfoWithFilter(
1278 LocalDataContainer
* container
,
1279 ScopedBatchUpdateNotifier
* notifier
,
1280 const base::string16
& filter
) {
1281 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1283 if (container
->indexed_db_info_list_
.empty())
1286 notifier
->StartBatchUpdate();
1287 for (IndexedDBInfoList::iterator indexed_db_info
=
1288 container
->indexed_db_info_list_
.begin();
1289 indexed_db_info
!= container
->indexed_db_info_list_
.end();
1290 ++indexed_db_info
) {
1291 const GURL
& origin
= indexed_db_info
->origin_
;
1293 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1294 .find(filter
) != base::string16::npos
)) {
1295 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1296 CookieTreeIndexedDBsNode
* indexed_dbs_node
=
1297 host_node
->GetOrCreateIndexedDBsNode();
1298 indexed_dbs_node
->AddIndexedDBNode(
1299 new CookieTreeIndexedDBNode(indexed_db_info
));
1304 void CookiesTreeModel::PopulateChannelIDInfoWithFilter(
1305 LocalDataContainer
* container
,
1306 ScopedBatchUpdateNotifier
* notifier
,
1307 const base::string16
& filter
) {
1308 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1310 if (container
->channel_id_list_
.empty())
1313 notifier
->StartBatchUpdate();
1314 for (ChannelIDList::iterator channel_id_info
=
1315 container
->channel_id_list_
.begin();
1316 channel_id_info
!= container
->channel_id_list_
.end();
1317 ++channel_id_info
) {
1318 GURL
origin(channel_id_info
->server_identifier());
1319 if (!origin
.is_valid()) {
1320 // Channel ID. Make a valid URL to satisfy the
1321 // CookieTreeRootNode::GetOrCreateHostNode interface.
1322 origin
= GURL(std::string(url::kHttpsScheme
) +
1323 url::kStandardSchemeSeparator
+
1324 channel_id_info
->server_identifier() + "/");
1326 base::string16 title
= CookieTreeHostNode::TitleForUrl(origin
);
1327 if (filter
.empty() || title
.find(filter
) != base::string16::npos
) {
1328 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1329 CookieTreeChannelIDsNode
* channel_ids_node
=
1330 host_node
->GetOrCreateChannelIDsNode();
1331 channel_ids_node
->AddChannelIDNode(
1332 new CookieTreeChannelIDNode(channel_id_info
));
1337 void CookiesTreeModel::PopulateServiceWorkerUsageInfoWithFilter(
1338 LocalDataContainer
* container
,
1339 ScopedBatchUpdateNotifier
* notifier
,
1340 const base::string16
& filter
) {
1341 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1343 if (container
->service_worker_info_list_
.empty())
1346 notifier
->StartBatchUpdate();
1347 for (ServiceWorkerUsageInfoList::iterator service_worker_info
=
1348 container
->service_worker_info_list_
.begin();
1349 service_worker_info
!= container
->service_worker_info_list_
.end();
1350 ++service_worker_info
) {
1351 const GURL
& origin
= service_worker_info
->origin
;
1353 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1354 .find(filter
) != base::string16::npos
)) {
1355 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1356 CookieTreeServiceWorkersNode
* service_workers_node
=
1357 host_node
->GetOrCreateServiceWorkersNode();
1358 service_workers_node
->AddServiceWorkerNode(
1359 new CookieTreeServiceWorkerNode(service_worker_info
));
1364 void CookiesTreeModel::PopulateFileSystemInfoWithFilter(
1365 LocalDataContainer
* container
,
1366 ScopedBatchUpdateNotifier
* notifier
,
1367 const base::string16
& filter
) {
1368 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1370 if (container
->file_system_info_list_
.empty())
1373 notifier
->StartBatchUpdate();
1374 for (FileSystemInfoList::iterator file_system_info
=
1375 container
->file_system_info_list_
.begin();
1376 file_system_info
!= container
->file_system_info_list_
.end();
1377 ++file_system_info
) {
1378 GURL
origin(file_system_info
->origin
);
1380 if (filter
.empty() || (CookieTreeHostNode::TitleForUrl(origin
)
1381 .find(filter
) != base::string16::npos
)) {
1382 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1383 CookieTreeFileSystemsNode
* file_systems_node
=
1384 host_node
->GetOrCreateFileSystemsNode();
1385 file_systems_node
->AddFileSystemNode(
1386 new CookieTreeFileSystemNode(file_system_info
));
1391 void CookiesTreeModel::PopulateQuotaInfoWithFilter(
1392 LocalDataContainer
* container
,
1393 ScopedBatchUpdateNotifier
* notifier
,
1394 const base::string16
& filter
) {
1395 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1397 if (container
->quota_info_list_
.empty())
1400 notifier
->StartBatchUpdate();
1401 for (QuotaInfoList::iterator quota_info
= container
->quota_info_list_
.begin();
1402 quota_info
!= container
->quota_info_list_
.end();
1404 if (filter
.empty() || (base::UTF8ToUTF16(quota_info
->host
).find(filter
) !=
1405 base::string16::npos
)) {
1406 CookieTreeHostNode
* host_node
=
1407 root
->GetOrCreateHostNode(GURL("http://" + quota_info
->host
));
1408 host_node
->UpdateOrCreateQuotaNode(quota_info
);
1413 void CookiesTreeModel::PopulateFlashLSOInfoWithFilter(
1414 LocalDataContainer
* container
,
1415 ScopedBatchUpdateNotifier
* notifier
,
1416 const base::string16
& filter
) {
1417 CookieTreeRootNode
* root
= static_cast<CookieTreeRootNode
*>(GetRoot());
1419 if (container
->flash_lso_domain_list_
.empty())
1422 std::string filter_utf8
= base::UTF16ToUTF8(filter
);
1423 notifier
->StartBatchUpdate();
1424 for (std::vector
<std::string
>::iterator it
=
1425 container
->flash_lso_domain_list_
.begin();
1426 it
!= container
->flash_lso_domain_list_
.end(); ++it
) {
1427 if (filter_utf8
.empty() || it
->find(filter_utf8
) != std::string::npos
) {
1428 // Create a fake origin for GetOrCreateHostNode().
1429 GURL
origin("http://" + *it
);
1430 CookieTreeHostNode
* host_node
= root
->GetOrCreateHostNode(origin
);
1431 host_node
->GetOrCreateFlashLSONode(*it
);
1436 void CookiesTreeModel::SetBatchExpectation(int batches_expected
, bool reset
) {
1437 batches_expected_
= batches_expected
;
1440 batches_started_
= 0;
1443 MaybeNotifyBatchesEnded();
1447 void CookiesTreeModel::RecordBatchSeen() {
1451 void CookiesTreeModel::NotifyObserverBeginBatch() {
1452 // Only notify the model once if we're batching in a nested manner.
1453 if (batches_started_
++ == 0) {
1454 FOR_EACH_OBSERVER(Observer
,
1455 cookies_observer_list_
,
1456 TreeModelBeginBatch(this));
1460 void CookiesTreeModel::NotifyObserverEndBatch() {
1462 MaybeNotifyBatchesEnded();
1465 void CookiesTreeModel::MaybeNotifyBatchesEnded() {
1466 // Only notify the observers if this is the outermost call to EndBatch() if
1467 // called in a nested manner.
1468 if (batches_ended_
== batches_started_
&&
1469 batches_seen_
== batches_expected_
) {
1470 FOR_EACH_OBSERVER(Observer
,
1471 cookies_observer_list_
,
1472 TreeModelEndBatch(this));