Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / chrome / browser / browsing_data / cookies_tree_model.cc
blob40f2a28fd52f21b96ba504b902bbc5f2e6914b6e
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_FLASH_LSO:
157 return false;
158 default:
159 break;
161 return false;
163 #endif
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();
177 } // namespace
179 CookieTreeNode::DetailedInfo::DetailedInfo() : node_type(TYPE_NONE) {}
181 CookieTreeNode::DetailedInfo::~DetailedInfo() {}
183 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::Init(
184 NodeType type) {
185 DCHECK_EQ(TYPE_NONE, node_type);
186 node_type = type;
187 return *this;
190 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitHost() {
191 Init(TYPE_HOST);
192 return *this;
195 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitCookie(
196 const net::CanonicalCookie* cookie) {
197 Init(TYPE_COOKIE);
198 this->cookie = cookie;
199 return *this;
202 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitDatabase(
203 const BrowsingDataDatabaseHelper::DatabaseInfo* database_info) {
204 Init(TYPE_DATABASE);
205 this->database_info = database_info;
206 origin = database_info->identifier.ToOrigin();
207 return *this;
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;
216 return *this;
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;
225 return *this;
228 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitAppCache(
229 const GURL& origin,
230 const content::AppCacheInfo* appcache_info) {
231 Init(TYPE_APPCACHE);
232 this->appcache_info = appcache_info;
233 this->origin = origin;
234 return *this;
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_;
242 return *this;
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;
250 return *this;
253 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitQuota(
254 const BrowsingDataQuotaHelper::QuotaInfo* quota_info) {
255 Init(TYPE_QUOTA);
256 this->quota_info = quota_info;
257 return *this;
260 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitChannelID(
261 const net::ChannelIDStore::ChannelID* channel_id) {
262 Init(TYPE_CHANNEL_ID);
263 this->channel_id = channel_id;
264 return *this;
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;
272 return *this;
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;
279 return *this;
282 ///////////////////////////////////////////////////////////////////////////////
283 // CookieTreeNode, public:
285 void CookieTreeNode::DeleteStoredObjects() {
286 std::for_each(children().begin(),
287 children().end(),
288 std::mem_fun(&CookieTreeNode::DeleteStoredObjects));
291 CookiesTreeModel* CookieTreeNode::GetModel() const {
292 if (parent())
293 return parent()->GetModel();
294 else
295 return nullptr;
298 ///////////////////////////////////////////////////////////////////////////////
299 // CookieTreeCookieNode, public:
301 CookieTreeCookieNode::CookieTreeCookieNode(
302 std::list<net::CanonicalCookie>::iterator cookie)
303 : CookieTreeNode(base::UTF8ToUTF16(cookie->Name())),
304 cookie_(cookie) {
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);
336 if (container) {
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);
364 if (container) {
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
380 local_storage_info)
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);
390 if (container) {
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)
409 : CookieTreeNode(
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);
419 if (container) {
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
438 indexed_db_info)
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);
449 if (container) {
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
465 file_system_info)
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);
476 if (container) {
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();
503 if (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);
527 if (container) {
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);
554 if (container) {
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()
562 const {
563 return DetailedInfo().InitServiceWorker(&*service_worker_info_);
566 ///////////////////////////////////////////////////////////////////////////////
567 // CookieTreeRootNode, public:
569 CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel* model)
570 : model_(model) {
573 CookieTreeRootNode::~CookieTreeRootNode() {}
575 CookieTreeHostNode* CookieTreeRootNode::GetOrCreateHostNode(
576 const GURL& url) {
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.
589 DCHECK(model_);
590 model_->Add(this, host_node.get(),
591 (host_node_iterator - children().begin()));
592 return host_node.release();
595 CookiesTreeModel* CookieTreeRootNode::GetModel() const {
596 return model_;
599 CookieTreeNode::DetailedInfo CookieTreeRootNode::GetDetailedInfo() const {
600 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT);
603 ///////////////////////////////////////////////////////////////////////////////
604 // CookieTreeHostNode, public:
606 // static
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
611 : url.host());
614 CookieTreeHostNode::CookieTreeHostNode(const GURL& url)
615 : CookieTreeNode(TitleForUrl(url)),
616 url_(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() {
632 if (cookies_child_)
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) {
691 if (quota_child_)
692 return quota_child_;
693 quota_child_ = new CookieTreeQuotaNode(quota_info);
694 AddChildSortedByTitle(quota_child_);
695 return 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()
847 : CookieTreeNode(
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) {
859 DCHECK(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()
877 const {
878 return DetailedInfo().Init(DetailedInfo::TYPE_SERVICE_WORKERS);
881 ///////////////////////////////////////////////////////////////////////////////
882 // CookieTreeFlashLSONode
883 CookieTreeFlashLSONode::CookieTreeFlashLSONode(
884 const std::string& domain)
885 : domain_(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();
914 } else {
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),
938 #endif
939 group_by_cookie_source_(group_by_cookie_source) {
940 data_container_->Init(this);
943 CookiesTreeModel::~CookiesTreeModel() {
946 // static
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
975 // GetIcons.
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:
980 return ORIGIN;
981 case CookieTreeNode::DetailedInfo::TYPE_COOKIE:
982 return COOKIE;
983 case CookieTreeNode::DetailedInfo::TYPE_DATABASE:
984 return 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:
996 return -1;
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
1001 default:
1002 break;
1004 return -1;
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())
1020 return;
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(), &notifier, filter);
1038 PopulateDatabaseInfoWithFilter(data_container(), &notifier, filter);
1039 PopulateLocalStorageInfoWithFilter(data_container(), &notifier, filter);
1040 PopulateSessionStorageInfoWithFilter(data_container(), &notifier, filter);
1041 PopulateAppCacheInfoWithFilter(data_container(), &notifier, filter);
1042 PopulateIndexedDBInfoWithFilter(data_container(), &notifier, filter);
1043 PopulateFileSystemInfoWithFilter(data_container(), &notifier, filter);
1044 PopulateQuotaInfoWithFilter(data_container(), &notifier, filter);
1045 PopulateChannelIDInfoWithFilter(data_container(), &notifier, filter);
1046 PopulateServiceWorkerUsageInfoWithFilter(data_container(), &notifier, filter);
1049 #if defined(ENABLE_EXTENSIONS)
1050 const extensions::ExtensionSet* CookiesTreeModel::ExtensionsProtectingNode(
1051 const CookieTreeNode& cookie_node) {
1052 if (!special_storage_policy_.get())
1053 return nullptr;
1055 CookieTreeNode::DetailedInfo info = cookie_node.GetDetailedInfo();
1057 if (!TypeIsProtected(info.node_type))
1058 return nullptr;
1060 DCHECK(!info.origin.is_empty());
1061 return special_storage_policy_->ExtensionsProtectingOrigin(info.origin);
1063 #endif
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, &notifier, base::string16());
1082 void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer* container) {
1083 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1084 PopulateCookieInfoWithFilter(container, &notifier, base::string16());
1087 void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer* container) {
1088 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1089 PopulateDatabaseInfoWithFilter(container, &notifier, base::string16());
1092 void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer* container) {
1093 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1094 PopulateLocalStorageInfoWithFilter(container, &notifier, base::string16());
1097 void CookiesTreeModel::PopulateSessionStorageInfo(
1098 LocalDataContainer* container) {
1099 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1100 PopulateSessionStorageInfoWithFilter(container, &notifier, base::string16());
1103 void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer* container) {
1104 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1105 PopulateIndexedDBInfoWithFilter(container, &notifier, base::string16());
1108 void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer* container) {
1109 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1110 PopulateFileSystemInfoWithFilter(container, &notifier, base::string16());
1113 void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer* container) {
1114 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1115 PopulateQuotaInfoWithFilter(container, &notifier, base::string16());
1118 void CookiesTreeModel::PopulateChannelIDInfo(
1119 LocalDataContainer* container) {
1120 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1121 PopulateChannelIDInfoWithFilter(container, &notifier, base::string16());
1124 void CookiesTreeModel::PopulateServiceWorkerUsageInfo(
1125 LocalDataContainer* container) {
1126 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1127 PopulateServiceWorkerUsageInfoWithFilter(
1128 container, &notifier, base::string16());
1131 void CookiesTreeModel::PopulateFlashLSOInfo(
1132 LocalDataContainer* container) {
1133 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1134 PopulateFlashLSOInfoWithFilter(container, &notifier, 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())
1145 return;
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())
1203 return;
1205 notifier->StartBatchUpdate();
1206 for (DatabaseInfoList::iterator database_info =
1207 container->database_info_list_.begin();
1208 database_info != container->database_info_list_.end();
1209 ++database_info) {
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())
1230 return;
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())
1257 return;
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())
1284 return;
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())
1311 return;
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())
1344 return;
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())
1371 return;
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())
1398 return;
1400 notifier->StartBatchUpdate();
1401 for (QuotaInfoList::iterator quota_info = container->quota_info_list_.begin();
1402 quota_info != container->quota_info_list_.end();
1403 ++quota_info) {
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())
1420 return;
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;
1438 if (reset) {
1439 batches_seen_ = 0;
1440 batches_started_ = 0;
1441 batches_ended_ = 0;
1442 } else {
1443 MaybeNotifyBatchesEnded();
1447 void CookiesTreeModel::RecordBatchSeen() {
1448 batches_seen_++;
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() {
1461 batches_ended_++;
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));