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