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