Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / browsing_data / cookies_tree_model.cc
blob2b4bcbedf881e4d9acd9d4fd3bee11fb393e105b
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.h"
20 #include "chrome/grit/generated_resources.h"
21 #include "content/public/common/url_constants.h"
22 #include "grit/theme_resources.h"
23 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
24 #include "net/cookies/canonical_cookie.h"
25 #include "net/url_request/url_request_context.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/image/image_skia.h"
29 #include "ui/resources/grit/ui_resources.h"
31 #if defined(ENABLE_EXTENSIONS)
32 #include "chrome/browser/extensions/extension_special_storage_policy.h"
33 #include "extensions/common/extension_set.h"
34 #endif
36 namespace {
38 struct NodeTitleComparator {
39 bool operator()(const CookieTreeNode* lhs, const CookieTreeNode* rhs) {
40 return lhs->GetTitle() < rhs->GetTitle();
44 // Comparison functor, for use in CookieTreeRootNode.
45 struct HostNodeComparator {
46 bool operator()(const CookieTreeNode* lhs, const CookieTreeNode* rhs) {
47 // This comparator is only meant to compare CookieTreeHostNode types. Make
48 // sure we check this, as the static cast below is dangerous if we get the
49 // wrong object type.
50 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST,
51 lhs->GetDetailedInfo().node_type);
52 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST,
53 rhs->GetDetailedInfo().node_type);
55 const CookieTreeHostNode* ltn =
56 static_cast<const CookieTreeHostNode*>(lhs);
57 const CookieTreeHostNode* rtn =
58 static_cast<const CookieTreeHostNode*>(rhs);
60 // We want to order by registry controlled domain, so we would get
61 // google.com, ad.google.com, www.google.com,
62 // microsoft.com, ad.microsoft.com. CanonicalizeHost transforms the origins
63 // into a form like google.com.www so that string comparisons work.
64 return (ltn->canonicalized_host() <
65 rtn->canonicalized_host());
69 std::string CanonicalizeHost(const GURL& url) {
70 // The canonicalized representation makes the registry controlled domain
71 // come first, and then adds subdomains in reverse order, e.g.
72 // 1.mail.google.com would become google.com.mail.1, and then a standard
73 // string comparison works to order hosts by registry controlled domain
74 // first. Leading dots are ignored, ".google.com" is the same as
75 // "google.com".
77 if (url.SchemeIsFile()) {
78 return std::string(url::kFileScheme) +
79 url::kStandardSchemeSeparator;
82 std::string host = url.host();
83 std::string retval =
84 net::registry_controlled_domains::GetDomainAndRegistry(
85 host,
86 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
87 if (!retval.length()) // Is an IP address or other special origin.
88 return host;
90 std::string::size_type position = host.rfind(retval);
92 // The host may be the registry controlled domain, in which case fail fast.
93 if (position == 0 || position == std::string::npos)
94 return host;
96 // If host is www.google.com, retval will contain google.com at this point.
97 // Start operating to the left of the registry controlled domain, e.g. in
98 // the www.google.com example, start at index 3.
99 --position;
101 // If position == 0, that means it's a dot; this will be ignored to treat
102 // ".google.com" the same as "google.com".
103 while (position > 0) {
104 retval += std::string(".");
105 // Copy up to the next dot. host[position] is a dot so start after it.
106 std::string::size_type next_dot = host.rfind(".", position - 1);
107 if (next_dot == std::string::npos) {
108 retval += host.substr(0, position);
109 break;
111 retval += host.substr(next_dot + 1, position - (next_dot + 1));
112 position = next_dot;
114 return retval;
117 #if defined(ENABLE_EXTENSIONS)
118 bool TypeIsProtected(CookieTreeNode::DetailedInfo::NodeType type) {
119 switch (type) {
120 case CookieTreeNode::DetailedInfo::TYPE_COOKIE:
121 return false;
122 case CookieTreeNode::DetailedInfo::TYPE_DATABASE:
123 return true;
124 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE:
125 return true;
126 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE:
127 return true;
128 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE:
129 return true;
130 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB:
131 return true;
132 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM:
133 return true;
134 case CookieTreeNode::DetailedInfo::TYPE_QUOTA:
135 return false;
136 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID:
137 return false;
138 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER:
139 return true;
140 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO:
141 return false;
142 default:
143 break;
145 return false;
147 #endif
149 // This function returns the local data container associated with a leaf tree
150 // node. The app node is assumed to be 3 levels above the leaf because of the
151 // following structure:
152 // root -> origin -> storage type -> leaf node
153 LocalDataContainer* GetLocalDataContainerForNode(CookieTreeNode* node) {
154 CookieTreeHostNode* host = static_cast<CookieTreeHostNode*>(
155 node->parent()->parent());
156 CHECK_EQ(host->GetDetailedInfo().node_type,
157 CookieTreeNode::DetailedInfo::TYPE_HOST);
158 return node->GetModel()->data_container();
161 } // namespace
163 CookieTreeNode::DetailedInfo::DetailedInfo()
164 : node_type(TYPE_NONE),
165 cookie(NULL),
166 database_info(NULL),
167 local_storage_info(NULL),
168 session_storage_info(NULL),
169 appcache_info(NULL),
170 indexed_db_info(NULL),
171 file_system_info(NULL),
172 quota_info(NULL),
173 channel_id(NULL),
174 service_worker_info(NULL) {
177 CookieTreeNode::DetailedInfo::~DetailedInfo() {}
179 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::Init(
180 NodeType type) {
181 DCHECK_EQ(TYPE_NONE, node_type);
182 node_type = type;
183 return *this;
186 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitHost() {
187 Init(TYPE_HOST);
188 return *this;
191 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitCookie(
192 const net::CanonicalCookie* cookie) {
193 Init(TYPE_COOKIE);
194 this->cookie = cookie;
195 return *this;
198 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitDatabase(
199 const BrowsingDataDatabaseHelper::DatabaseInfo* database_info) {
200 Init(TYPE_DATABASE);
201 this->database_info = database_info;
202 origin = database_info->identifier.ToOrigin();
203 return *this;
206 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitLocalStorage(
207 const BrowsingDataLocalStorageHelper::LocalStorageInfo*
208 local_storage_info) {
209 Init(TYPE_LOCAL_STORAGE);
210 this->local_storage_info = local_storage_info;
211 origin = local_storage_info->origin_url;
212 return *this;
215 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitSessionStorage(
216 const BrowsingDataLocalStorageHelper::LocalStorageInfo*
217 session_storage_info) {
218 Init(TYPE_SESSION_STORAGE);
219 this->session_storage_info = session_storage_info;
220 origin = session_storage_info->origin_url;
221 return *this;
224 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitAppCache(
225 const GURL& origin,
226 const content::AppCacheInfo* appcache_info) {
227 Init(TYPE_APPCACHE);
228 this->appcache_info = appcache_info;
229 this->origin = origin;
230 return *this;
233 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitIndexedDB(
234 const content::IndexedDBInfo* indexed_db_info) {
235 Init(TYPE_INDEXED_DB);
236 this->indexed_db_info = indexed_db_info;
237 this->origin = indexed_db_info->origin_;
238 return *this;
241 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitFileSystem(
242 const BrowsingDataFileSystemHelper::FileSystemInfo* file_system_info) {
243 Init(TYPE_FILE_SYSTEM);
244 this->file_system_info = file_system_info;
245 this->origin = file_system_info->origin;
246 return *this;
249 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitQuota(
250 const BrowsingDataQuotaHelper::QuotaInfo* quota_info) {
251 Init(TYPE_QUOTA);
252 this->quota_info = quota_info;
253 return *this;
256 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitChannelID(
257 const net::ChannelIDStore::ChannelID* channel_id) {
258 Init(TYPE_CHANNEL_ID);
259 this->channel_id = channel_id;
260 return *this;
263 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitServiceWorker(
264 const content::ServiceWorkerUsageInfo* service_worker_info) {
265 Init(TYPE_SERVICE_WORKER);
266 this->service_worker_info = service_worker_info;
267 this->origin = service_worker_info->origin;
268 return *this;
271 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitFlashLSO(
272 const std::string& flash_lso_domain) {
273 Init(TYPE_FLASH_LSO);
274 this->flash_lso_domain = flash_lso_domain;
275 return *this;
278 ///////////////////////////////////////////////////////////////////////////////
279 // CookieTreeNode, public:
281 void CookieTreeNode::DeleteStoredObjects() {
282 std::for_each(children().begin(),
283 children().end(),
284 std::mem_fun(&CookieTreeNode::DeleteStoredObjects));
287 CookiesTreeModel* CookieTreeNode::GetModel() const {
288 if (parent())
289 return parent()->GetModel();
290 else
291 return NULL;
294 ///////////////////////////////////////////////////////////////////////////////
295 // CookieTreeCookieNode, public:
297 CookieTreeCookieNode::CookieTreeCookieNode(
298 std::list<net::CanonicalCookie>::iterator cookie)
299 : CookieTreeNode(base::UTF8ToUTF16(cookie->Name())),
300 cookie_(cookie) {
303 CookieTreeCookieNode::~CookieTreeCookieNode() {}
305 void CookieTreeCookieNode::DeleteStoredObjects() {
306 LocalDataContainer* container = GetLocalDataContainerForNode(this);
307 container->cookie_helper_->DeleteCookie(*cookie_);
308 container->cookie_list_.erase(cookie_);
311 CookieTreeNode::DetailedInfo CookieTreeCookieNode::GetDetailedInfo() const {
312 return DetailedInfo().InitCookie(&*cookie_);
315 ///////////////////////////////////////////////////////////////////////////////
316 // CookieTreeAppCacheNode, public:
318 CookieTreeAppCacheNode::CookieTreeAppCacheNode(
319 const GURL& origin_url,
320 std::list<content::AppCacheInfo>::iterator appcache_info)
321 : CookieTreeNode(base::UTF8ToUTF16(appcache_info->manifest_url.spec())),
322 origin_url_(origin_url),
323 appcache_info_(appcache_info) {
326 CookieTreeAppCacheNode::~CookieTreeAppCacheNode() {
329 void CookieTreeAppCacheNode::DeleteStoredObjects() {
330 LocalDataContainer* container = GetLocalDataContainerForNode(this);
332 if (container) {
333 DCHECK(container->appcache_helper_.get());
334 container->appcache_helper_
335 ->DeleteAppCacheGroup(appcache_info_->manifest_url);
336 container->appcache_info_[origin_url_].erase(appcache_info_);
340 CookieTreeNode::DetailedInfo CookieTreeAppCacheNode::GetDetailedInfo() const {
341 return DetailedInfo().InitAppCache(origin_url_, &*appcache_info_);
344 ///////////////////////////////////////////////////////////////////////////////
345 // CookieTreeDatabaseNode, public:
347 CookieTreeDatabaseNode::CookieTreeDatabaseNode(
348 std::list<BrowsingDataDatabaseHelper::DatabaseInfo>::iterator database_info)
349 : CookieTreeNode(database_info->database_name.empty() ?
350 l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME) :
351 base::UTF8ToUTF16(database_info->database_name)),
352 database_info_(database_info) {
355 CookieTreeDatabaseNode::~CookieTreeDatabaseNode() {}
357 void CookieTreeDatabaseNode::DeleteStoredObjects() {
358 LocalDataContainer* container = GetLocalDataContainerForNode(this);
360 if (container) {
361 container->database_helper_->DeleteDatabase(
362 database_info_->identifier.ToString(), database_info_->database_name);
363 container->database_info_list_.erase(database_info_);
367 CookieTreeNode::DetailedInfo CookieTreeDatabaseNode::GetDetailedInfo() const {
368 return DetailedInfo().InitDatabase(&*database_info_);
371 ///////////////////////////////////////////////////////////////////////////////
372 // CookieTreeLocalStorageNode, public:
374 CookieTreeLocalStorageNode::CookieTreeLocalStorageNode(
375 std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::iterator
376 local_storage_info)
377 : CookieTreeNode(base::UTF8ToUTF16(local_storage_info->origin_url.spec())),
378 local_storage_info_(local_storage_info) {
381 CookieTreeLocalStorageNode::~CookieTreeLocalStorageNode() {}
383 void CookieTreeLocalStorageNode::DeleteStoredObjects() {
384 LocalDataContainer* container = GetLocalDataContainerForNode(this);
386 if (container) {
387 container->local_storage_helper_->DeleteOrigin(
388 local_storage_info_->origin_url);
389 container->local_storage_info_list_.erase(local_storage_info_);
393 CookieTreeNode::DetailedInfo
394 CookieTreeLocalStorageNode::GetDetailedInfo() const {
395 return DetailedInfo().InitLocalStorage(
396 &*local_storage_info_);
399 ///////////////////////////////////////////////////////////////////////////////
400 // CookieTreeSessionStorageNode, public:
402 CookieTreeSessionStorageNode::CookieTreeSessionStorageNode(
403 std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::iterator
404 session_storage_info)
405 : CookieTreeNode(
406 base::UTF8ToUTF16(session_storage_info->origin_url.spec())),
407 session_storage_info_(session_storage_info) {
410 CookieTreeSessionStorageNode::~CookieTreeSessionStorageNode() {}
412 void CookieTreeSessionStorageNode::DeleteStoredObjects() {
413 LocalDataContainer* container = GetLocalDataContainerForNode(this);
415 if (container) {
416 // TODO(rsesek): There's no easy way to get the namespace_id for a session
417 // storage, nor is there an easy way to clear session storage just by
418 // origin. This is probably okay since session storage is not persistent.
419 // http://crbug.com/168996
420 container->session_storage_info_list_.erase(session_storage_info_);
424 CookieTreeNode::DetailedInfo
425 CookieTreeSessionStorageNode::GetDetailedInfo() const {
426 return DetailedInfo().InitSessionStorage(&*session_storage_info_);
429 ///////////////////////////////////////////////////////////////////////////////
430 // CookieTreeIndexedDBNode, public:
432 CookieTreeIndexedDBNode::CookieTreeIndexedDBNode(
433 std::list<content::IndexedDBInfo>::iterator
434 indexed_db_info)
435 : CookieTreeNode(base::UTF8ToUTF16(
436 indexed_db_info->origin_.spec())),
437 indexed_db_info_(indexed_db_info) {
440 CookieTreeIndexedDBNode::~CookieTreeIndexedDBNode() {}
442 void CookieTreeIndexedDBNode::DeleteStoredObjects() {
443 LocalDataContainer* container = GetLocalDataContainerForNode(this);
445 if (container) {
446 container->indexed_db_helper_->DeleteIndexedDB(
447 indexed_db_info_->origin_);
448 container->indexed_db_info_list_.erase(indexed_db_info_);
452 CookieTreeNode::DetailedInfo CookieTreeIndexedDBNode::GetDetailedInfo() const {
453 return DetailedInfo().InitIndexedDB(&*indexed_db_info_);
456 ///////////////////////////////////////////////////////////////////////////////
457 // CookieTreeFileSystemNode, public:
459 CookieTreeFileSystemNode::CookieTreeFileSystemNode(
460 std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator
461 file_system_info)
462 : CookieTreeNode(base::UTF8ToUTF16(
463 file_system_info->origin.spec())),
464 file_system_info_(file_system_info) {
467 CookieTreeFileSystemNode::~CookieTreeFileSystemNode() {}
469 void CookieTreeFileSystemNode::DeleteStoredObjects() {
470 LocalDataContainer* container = GetLocalDataContainerForNode(this);
472 if (container) {
473 container->file_system_helper_->DeleteFileSystemOrigin(
474 file_system_info_->origin);
475 container->file_system_info_list_.erase(file_system_info_);
479 CookieTreeNode::DetailedInfo CookieTreeFileSystemNode::GetDetailedInfo() const {
480 return DetailedInfo().InitFileSystem(&*file_system_info_);
483 ///////////////////////////////////////////////////////////////////////////////
484 // CookieTreeQuotaNode, public:
486 CookieTreeQuotaNode::CookieTreeQuotaNode(
487 std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info)
488 : CookieTreeNode(base::UTF8ToUTF16(quota_info->host)),
489 quota_info_(quota_info) {
492 CookieTreeQuotaNode::~CookieTreeQuotaNode() {}
494 void CookieTreeQuotaNode::DeleteStoredObjects() {
495 // Calling this function may cause unexpected over-quota state of origin.
496 // However, it'll caused no problem, just prevent usage growth of the origin.
497 LocalDataContainer* container = GetModel()->data_container();
499 if (container) {
500 container->quota_helper_->RevokeHostQuota(quota_info_->host);
501 container->quota_info_list_.erase(quota_info_);
505 CookieTreeNode::DetailedInfo CookieTreeQuotaNode::GetDetailedInfo() const {
506 return DetailedInfo().InitQuota(&*quota_info_);
509 ///////////////////////////////////////////////////////////////////////////////
510 // CookieTreeChannelIDNode, public:
512 CookieTreeChannelIDNode::CookieTreeChannelIDNode(
513 net::ChannelIDStore::ChannelIDList::iterator channel_id)
514 : CookieTreeNode(base::ASCIIToUTF16(channel_id->server_identifier())),
515 channel_id_(channel_id) {
518 CookieTreeChannelIDNode::~CookieTreeChannelIDNode() {}
520 void CookieTreeChannelIDNode::DeleteStoredObjects() {
521 LocalDataContainer* container = GetLocalDataContainerForNode(this);
523 if (container) {
524 container->channel_id_helper_->DeleteChannelID(
525 channel_id_->server_identifier());
526 container->channel_id_list_.erase(channel_id_);
530 CookieTreeNode::DetailedInfo
531 CookieTreeChannelIDNode::GetDetailedInfo() const {
532 return DetailedInfo().InitChannelID(&*channel_id_);
535 ///////////////////////////////////////////////////////////////////////////////
536 // CookieTreeServiceWorkerNode, public:
538 CookieTreeServiceWorkerNode::CookieTreeServiceWorkerNode(
539 std::list<content::ServiceWorkerUsageInfo>::iterator service_worker_info)
540 : CookieTreeNode(base::UTF8ToUTF16(service_worker_info->origin.spec())),
541 service_worker_info_(service_worker_info) {
544 CookieTreeServiceWorkerNode::~CookieTreeServiceWorkerNode() {
547 void CookieTreeServiceWorkerNode::DeleteStoredObjects() {
548 LocalDataContainer* container = GetLocalDataContainerForNode(this);
550 if (container) {
551 container->service_worker_helper_->DeleteServiceWorkers(
552 service_worker_info_->origin);
553 container->service_worker_info_list_.erase(service_worker_info_);
557 CookieTreeNode::DetailedInfo CookieTreeServiceWorkerNode::GetDetailedInfo()
558 const {
559 return DetailedInfo().InitServiceWorker(&*service_worker_info_);
562 ///////////////////////////////////////////////////////////////////////////////
563 // CookieTreeRootNode, public:
565 CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel* model)
566 : model_(model) {
569 CookieTreeRootNode::~CookieTreeRootNode() {}
571 CookieTreeHostNode* CookieTreeRootNode::GetOrCreateHostNode(
572 const GURL& url) {
573 scoped_ptr<CookieTreeHostNode> host_node(
574 new CookieTreeHostNode(url));
576 // First see if there is an existing match.
577 std::vector<CookieTreeNode*>::iterator host_node_iterator =
578 std::lower_bound(children().begin(), children().end(), host_node.get(),
579 HostNodeComparator());
580 if (host_node_iterator != children().end() &&
581 CookieTreeHostNode::TitleForUrl(url) ==
582 (*host_node_iterator)->GetTitle())
583 return static_cast<CookieTreeHostNode*>(*host_node_iterator);
584 // Node doesn't exist, insert the new one into the (ordered) children.
585 DCHECK(model_);
586 model_->Add(this, host_node.get(),
587 (host_node_iterator - children().begin()));
588 return host_node.release();
591 CookiesTreeModel* CookieTreeRootNode::GetModel() const {
592 return model_;
595 CookieTreeNode::DetailedInfo CookieTreeRootNode::GetDetailedInfo() const {
596 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT);
599 ///////////////////////////////////////////////////////////////////////////////
600 // CookieTreeHostNode, public:
602 // static
603 base::string16 CookieTreeHostNode::TitleForUrl(const GURL& url) {
604 const std::string file_origin_node_name(
605 std::string(url::kFileScheme) + url::kStandardSchemeSeparator);
606 return base::UTF8ToUTF16(url.SchemeIsFile() ? file_origin_node_name
607 : url.host());
610 CookieTreeHostNode::CookieTreeHostNode(const GURL& url)
611 : CookieTreeNode(TitleForUrl(url)),
612 cookies_child_(NULL),
613 databases_child_(NULL),
614 local_storages_child_(NULL),
615 session_storages_child_(NULL),
616 appcaches_child_(NULL),
617 indexed_dbs_child_(NULL),
618 file_systems_child_(NULL),
619 quota_child_(NULL),
620 channel_ids_child_(NULL),
621 service_workers_child_(NULL),
622 flash_lso_child_(NULL),
623 url_(url),
624 canonicalized_host_(CanonicalizeHost(url)) {
627 CookieTreeHostNode::~CookieTreeHostNode() {}
629 const std::string CookieTreeHostNode::GetHost() const {
630 const std::string file_origin_node_name(
631 std::string(url::kFileScheme) + url::kStandardSchemeSeparator);
632 return url_.SchemeIsFile() ? file_origin_node_name : url_.host();
635 CookieTreeNode::DetailedInfo CookieTreeHostNode::GetDetailedInfo() const {
636 return DetailedInfo().InitHost();
639 CookieTreeCookiesNode* CookieTreeHostNode::GetOrCreateCookiesNode() {
640 if (cookies_child_)
641 return cookies_child_;
642 cookies_child_ = new CookieTreeCookiesNode;
643 AddChildSortedByTitle(cookies_child_);
644 return cookies_child_;
647 CookieTreeDatabasesNode* CookieTreeHostNode::GetOrCreateDatabasesNode() {
648 if (databases_child_)
649 return databases_child_;
650 databases_child_ = new CookieTreeDatabasesNode;
651 AddChildSortedByTitle(databases_child_);
652 return databases_child_;
655 CookieTreeLocalStoragesNode*
656 CookieTreeHostNode::GetOrCreateLocalStoragesNode() {
657 if (local_storages_child_)
658 return local_storages_child_;
659 local_storages_child_ = new CookieTreeLocalStoragesNode;
660 AddChildSortedByTitle(local_storages_child_);
661 return local_storages_child_;
664 CookieTreeSessionStoragesNode*
665 CookieTreeHostNode::GetOrCreateSessionStoragesNode() {
666 if (session_storages_child_)
667 return session_storages_child_;
668 session_storages_child_ = new CookieTreeSessionStoragesNode;
669 AddChildSortedByTitle(session_storages_child_);
670 return session_storages_child_;
673 CookieTreeAppCachesNode* CookieTreeHostNode::GetOrCreateAppCachesNode() {
674 if (appcaches_child_)
675 return appcaches_child_;
676 appcaches_child_ = new CookieTreeAppCachesNode;
677 AddChildSortedByTitle(appcaches_child_);
678 return appcaches_child_;
681 CookieTreeIndexedDBsNode* CookieTreeHostNode::GetOrCreateIndexedDBsNode() {
682 if (indexed_dbs_child_)
683 return indexed_dbs_child_;
684 indexed_dbs_child_ = new CookieTreeIndexedDBsNode;
685 AddChildSortedByTitle(indexed_dbs_child_);
686 return indexed_dbs_child_;
689 CookieTreeFileSystemsNode* CookieTreeHostNode::GetOrCreateFileSystemsNode() {
690 if (file_systems_child_)
691 return file_systems_child_;
692 file_systems_child_ = new CookieTreeFileSystemsNode;
693 AddChildSortedByTitle(file_systems_child_);
694 return file_systems_child_;
697 CookieTreeQuotaNode* CookieTreeHostNode::UpdateOrCreateQuotaNode(
698 std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info) {
699 if (quota_child_)
700 return quota_child_;
701 quota_child_ = new CookieTreeQuotaNode(quota_info);
702 AddChildSortedByTitle(quota_child_);
703 return quota_child_;
706 CookieTreeChannelIDsNode*
707 CookieTreeHostNode::GetOrCreateChannelIDsNode() {
708 if (channel_ids_child_)
709 return channel_ids_child_;
710 channel_ids_child_ = new CookieTreeChannelIDsNode;
711 AddChildSortedByTitle(channel_ids_child_);
712 return channel_ids_child_;
715 CookieTreeServiceWorkersNode*
716 CookieTreeHostNode::GetOrCreateServiceWorkersNode() {
717 if (service_workers_child_)
718 return service_workers_child_;
719 service_workers_child_ = new CookieTreeServiceWorkersNode;
720 AddChildSortedByTitle(service_workers_child_);
721 return service_workers_child_;
724 CookieTreeFlashLSONode* CookieTreeHostNode::GetOrCreateFlashLSONode(
725 const std::string& domain) {
726 DCHECK_EQ(GetHost(), domain);
727 if (flash_lso_child_)
728 return flash_lso_child_;
729 flash_lso_child_ = new CookieTreeFlashLSONode(domain);
730 AddChildSortedByTitle(flash_lso_child_);
731 return flash_lso_child_;
734 void CookieTreeHostNode::CreateContentException(
735 CookieSettings* cookie_settings, ContentSetting setting) const {
736 DCHECK(setting == CONTENT_SETTING_ALLOW ||
737 setting == CONTENT_SETTING_BLOCK ||
738 setting == CONTENT_SETTING_SESSION_ONLY);
739 if (CanCreateContentException()) {
740 cookie_settings->ResetCookieSetting(
741 ContentSettingsPattern::FromURLNoWildcard(url_),
742 ContentSettingsPattern::Wildcard());
743 cookie_settings->SetCookieSetting(
744 ContentSettingsPattern::FromURL(url_),
745 ContentSettingsPattern::Wildcard(), setting);
749 bool CookieTreeHostNode::CanCreateContentException() const {
750 return !url_.SchemeIsFile();
753 ///////////////////////////////////////////////////////////////////////////////
754 // CookieTreeCookiesNode, public:
756 CookieTreeCookiesNode::CookieTreeCookiesNode()
757 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES)) {
760 CookieTreeCookiesNode::~CookieTreeCookiesNode() {
763 CookieTreeNode::DetailedInfo CookieTreeCookiesNode::GetDetailedInfo() const {
764 return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES);
767 ///////////////////////////////////////////////////////////////////////////////
768 // CookieTreeAppCachesNode, public:
770 CookieTreeAppCachesNode::CookieTreeAppCachesNode()
771 : CookieTreeNode(l10n_util::GetStringUTF16(
772 IDS_COOKIES_APPLICATION_CACHES)) {
775 CookieTreeAppCachesNode::~CookieTreeAppCachesNode() {}
777 CookieTreeNode::DetailedInfo CookieTreeAppCachesNode::GetDetailedInfo() const {
778 return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES);
781 ///////////////////////////////////////////////////////////////////////////////
782 // CookieTreeDatabasesNode, public:
784 CookieTreeDatabasesNode::CookieTreeDatabasesNode()
785 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES)) {
788 CookieTreeDatabasesNode::~CookieTreeDatabasesNode() {}
790 CookieTreeNode::DetailedInfo CookieTreeDatabasesNode::GetDetailedInfo() const {
791 return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES);
794 ///////////////////////////////////////////////////////////////////////////////
795 // CookieTreeLocalStoragesNode, public:
797 CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode()
798 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE)) {
801 CookieTreeLocalStoragesNode::~CookieTreeLocalStoragesNode() {}
803 CookieTreeNode::DetailedInfo
804 CookieTreeLocalStoragesNode::GetDetailedInfo() const {
805 return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES);
808 ///////////////////////////////////////////////////////////////////////////////
809 // CookieTreeSessionStoragesNode, public:
811 CookieTreeSessionStoragesNode::CookieTreeSessionStoragesNode()
812 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE)) {
815 CookieTreeSessionStoragesNode::~CookieTreeSessionStoragesNode() {}
817 CookieTreeNode::DetailedInfo
818 CookieTreeSessionStoragesNode::GetDetailedInfo() const {
819 return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES);
822 ///////////////////////////////////////////////////////////////////////////////
823 // CookieTreeIndexedDBsNode, public:
825 CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode()
826 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS)) {
829 CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {}
831 CookieTreeNode::DetailedInfo
832 CookieTreeIndexedDBsNode::GetDetailedInfo() const {
833 return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS);
836 ///////////////////////////////////////////////////////////////////////////////
837 // CookieTreeFileSystemsNode, public:
839 CookieTreeFileSystemsNode::CookieTreeFileSystemsNode()
840 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS)) {
843 CookieTreeFileSystemsNode::~CookieTreeFileSystemsNode() {}
845 CookieTreeNode::DetailedInfo
846 CookieTreeFileSystemsNode::GetDetailedInfo() const {
847 return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS);
850 ///////////////////////////////////////////////////////////////////////////////
851 // CookieTreeChannelIDsNode, public:
853 CookieTreeChannelIDsNode::CookieTreeChannelIDsNode()
854 : CookieTreeNode(
855 l10n_util::GetStringUTF16(IDS_COOKIES_CHANNEL_IDS)) {
858 CookieTreeChannelIDsNode::~CookieTreeChannelIDsNode() {}
860 CookieTreeNode::DetailedInfo
861 CookieTreeChannelIDsNode::GetDetailedInfo() const {
862 return DetailedInfo().Init(DetailedInfo::TYPE_CHANNEL_IDS);
865 void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode* new_child) {
866 DCHECK(new_child);
867 std::vector<CookieTreeNode*>::iterator iter =
868 std::lower_bound(children().begin(), children().end(), new_child,
869 NodeTitleComparator());
870 GetModel()->Add(this, new_child, iter - children().begin());
873 ///////////////////////////////////////////////////////////////////////////////
874 // CookieTreeServiceWorkersNode, public:
876 CookieTreeServiceWorkersNode::CookieTreeServiceWorkersNode()
877 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SERVICE_WORKERS)) {
880 CookieTreeServiceWorkersNode::~CookieTreeServiceWorkersNode() {
883 CookieTreeNode::DetailedInfo CookieTreeServiceWorkersNode::GetDetailedInfo()
884 const {
885 return DetailedInfo().Init(DetailedInfo::TYPE_SERVICE_WORKERS);
888 ///////////////////////////////////////////////////////////////////////////////
889 // CookieTreeFlashLSONode
890 CookieTreeFlashLSONode::CookieTreeFlashLSONode(
891 const std::string& domain)
892 : domain_(domain) {}
893 CookieTreeFlashLSONode::~CookieTreeFlashLSONode() {}
895 void CookieTreeFlashLSONode::DeleteStoredObjects() {
896 // We are one level below the host node.
897 CookieTreeHostNode* host = static_cast<CookieTreeHostNode*>(parent());
898 CHECK_EQ(host->GetDetailedInfo().node_type,
899 CookieTreeNode::DetailedInfo::TYPE_HOST);
900 LocalDataContainer* container = GetModel()->data_container();
901 container->flash_lso_helper_->DeleteFlashLSOsForSite(domain_);
904 CookieTreeNode::DetailedInfo CookieTreeFlashLSONode::GetDetailedInfo() const {
905 return DetailedInfo().InitFlashLSO(domain_);
908 ///////////////////////////////////////////////////////////////////////////////
909 // ScopedBatchUpdateNotifier
910 CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier(
911 CookiesTreeModel* model, CookieTreeNode* node)
912 : model_(model), node_(node), batch_in_progress_(false) {
913 model_->RecordBatchSeen();
916 CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() {
917 if (batch_in_progress_) {
918 model_->NotifyObserverTreeNodeChanged(node_);
919 model_->NotifyObserverEndBatch();
920 } else {
921 // If no batch started, and this is the last batch, give the model a chance
922 // to send out a final notification.
923 model_->MaybeNotifyBatchesEnded();
927 void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() {
928 if (!batch_in_progress_) {
929 model_->NotifyObserverBeginBatch();
930 batch_in_progress_ = true;
934 ///////////////////////////////////////////////////////////////////////////////
935 // CookiesTreeModel, public:
936 CookiesTreeModel::CookiesTreeModel(
937 LocalDataContainer* data_container,
938 ExtensionSpecialStoragePolicy* special_storage_policy,
939 bool group_by_cookie_source)
940 : ui::TreeNodeModel<CookieTreeNode>(new CookieTreeRootNode(this)),
941 data_container_(data_container),
942 #if defined(ENABLE_EXTENSIONS)
943 special_storage_policy_(special_storage_policy),
944 #endif
945 group_by_cookie_source_(group_by_cookie_source),
946 batches_expected_(0),
947 batches_seen_(0),
948 batches_started_(0),
949 batches_ended_(0) {
950 data_container_->Init(this);
953 CookiesTreeModel::~CookiesTreeModel() {
956 // static
957 int CookiesTreeModel::GetSendForMessageID(const net::CanonicalCookie& cookie) {
958 if (cookie.IsSecure()) {
959 if (cookie.IsFirstPartyOnly())
960 return IDS_COOKIES_COOKIE_SENDFOR_SECURE_FIRSTPARTY;
961 return IDS_COOKIES_COOKIE_SENDFOR_SECURE;
963 if (cookie.IsFirstPartyOnly())
964 return IDS_COOKIES_COOKIE_SENDFOR_FIRSTPARTY;
965 return IDS_COOKIES_COOKIE_SENDFOR_ANY;
968 ///////////////////////////////////////////////////////////////////////////////
969 // CookiesTreeModel, TreeModel methods (public):
971 // TreeModel methods:
972 // Returns the set of icons for the nodes in the tree. You only need override
973 // this if you don't want to use the default folder icons.
974 void CookiesTreeModel::GetIcons(std::vector<gfx::ImageSkia>* icons) {
975 icons->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
976 IDR_DEFAULT_FAVICON).ToImageSkia());
977 icons->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
978 IDR_COOKIE_ICON).ToImageSkia());
979 icons->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
980 IDR_COOKIE_STORAGE_ICON).ToImageSkia());
983 // Returns the index of the icon to use for |node|. Return -1 to use the
984 // default icon. The index is relative to the list of icons returned from
985 // GetIcons.
986 int CookiesTreeModel::GetIconIndex(ui::TreeModelNode* node) {
987 CookieTreeNode* ct_node = static_cast<CookieTreeNode*>(node);
988 switch (ct_node->GetDetailedInfo().node_type) {
989 case CookieTreeNode::DetailedInfo::TYPE_HOST:
990 return ORIGIN;
991 case CookieTreeNode::DetailedInfo::TYPE_COOKIE:
992 return COOKIE;
993 case CookieTreeNode::DetailedInfo::TYPE_DATABASE:
994 return DATABASE;
995 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE:
996 return DATABASE; // close enough
997 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE:
998 return DATABASE; // ditto
999 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE:
1000 return DATABASE; // ditto
1001 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB:
1002 return DATABASE; // ditto
1003 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM:
1004 return DATABASE; // ditto
1005 case CookieTreeNode::DetailedInfo::TYPE_QUOTA:
1006 return -1;
1007 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID:
1008 return COOKIE; // It's kinda like a cookie?
1009 case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER:
1010 return DATABASE; // Just like appcache
1011 default:
1012 break;
1014 return -1;
1017 void CookiesTreeModel::DeleteAllStoredObjects() {
1018 NotifyObserverBeginBatch();
1019 CookieTreeNode* root = GetRoot();
1020 root->DeleteStoredObjects();
1021 int num_children = root->child_count();
1022 for (int i = num_children - 1; i >= 0; --i)
1023 delete Remove(root, root->GetChild(i));
1024 NotifyObserverTreeNodeChanged(root);
1025 NotifyObserverEndBatch();
1028 void CookiesTreeModel::DeleteCookieNode(CookieTreeNode* cookie_node) {
1029 if (cookie_node == GetRoot())
1030 return;
1031 cookie_node->DeleteStoredObjects();
1032 CookieTreeNode* parent_node = cookie_node->parent();
1033 delete Remove(parent_node, cookie_node);
1034 if (parent_node->empty())
1035 DeleteCookieNode(parent_node);
1038 void CookiesTreeModel::UpdateSearchResults(const base::string16& filter) {
1039 CookieTreeNode* root = GetRoot();
1040 SetBatchExpectation(1, true);
1041 ScopedBatchUpdateNotifier notifier(this, root);
1042 int num_children = root->child_count();
1043 notifier.StartBatchUpdate();
1044 for (int i = num_children - 1; i >= 0; --i)
1045 delete Remove(root, root->GetChild(i));
1047 PopulateCookieInfoWithFilter(data_container(), &notifier, filter);
1048 PopulateDatabaseInfoWithFilter(data_container(), &notifier, filter);
1049 PopulateLocalStorageInfoWithFilter(data_container(), &notifier, filter);
1050 PopulateSessionStorageInfoWithFilter(data_container(), &notifier, filter);
1051 PopulateAppCacheInfoWithFilter(data_container(), &notifier, filter);
1052 PopulateIndexedDBInfoWithFilter(data_container(), &notifier, filter);
1053 PopulateFileSystemInfoWithFilter(data_container(), &notifier, filter);
1054 PopulateQuotaInfoWithFilter(data_container(), &notifier, filter);
1055 PopulateChannelIDInfoWithFilter(data_container(), &notifier, filter);
1056 PopulateServiceWorkerUsageInfoWithFilter(data_container(), &notifier, filter);
1059 #if defined(ENABLE_EXTENSIONS)
1060 const extensions::ExtensionSet* CookiesTreeModel::ExtensionsProtectingNode(
1061 const CookieTreeNode& cookie_node) {
1062 if (!special_storage_policy_.get())
1063 return NULL;
1065 CookieTreeNode::DetailedInfo info = cookie_node.GetDetailedInfo();
1067 if (!TypeIsProtected(info.node_type))
1068 return NULL;
1070 DCHECK(!info.origin.is_empty());
1071 return special_storage_policy_->ExtensionsProtectingOrigin(info.origin);
1073 #endif
1075 void CookiesTreeModel::AddCookiesTreeObserver(Observer* observer) {
1076 cookies_observer_list_.AddObserver(observer);
1077 // Call super so that TreeNodeModel can notify, too.
1078 ui::TreeNodeModel<CookieTreeNode>::AddObserver(observer);
1081 void CookiesTreeModel::RemoveCookiesTreeObserver(Observer* observer) {
1082 cookies_observer_list_.RemoveObserver(observer);
1083 // Call super so that TreeNodeModel doesn't have dead pointers.
1084 ui::TreeNodeModel<CookieTreeNode>::RemoveObserver(observer);
1087 void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer* container) {
1088 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1089 PopulateAppCacheInfoWithFilter(container, &notifier, base::string16());
1092 void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer* container) {
1093 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1094 PopulateCookieInfoWithFilter(container, &notifier, base::string16());
1097 void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer* container) {
1098 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1099 PopulateDatabaseInfoWithFilter(container, &notifier, base::string16());
1102 void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer* container) {
1103 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1104 PopulateLocalStorageInfoWithFilter(container, &notifier, base::string16());
1107 void CookiesTreeModel::PopulateSessionStorageInfo(
1108 LocalDataContainer* container) {
1109 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1110 PopulateSessionStorageInfoWithFilter(container, &notifier, base::string16());
1113 void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer* container) {
1114 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1115 PopulateIndexedDBInfoWithFilter(container, &notifier, base::string16());
1118 void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer* container) {
1119 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1120 PopulateFileSystemInfoWithFilter(container, &notifier, base::string16());
1123 void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer* container) {
1124 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1125 PopulateQuotaInfoWithFilter(container, &notifier, base::string16());
1128 void CookiesTreeModel::PopulateChannelIDInfo(
1129 LocalDataContainer* container) {
1130 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1131 PopulateChannelIDInfoWithFilter(container, &notifier, base::string16());
1134 void CookiesTreeModel::PopulateServiceWorkerUsageInfo(
1135 LocalDataContainer* container) {
1136 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1137 PopulateServiceWorkerUsageInfoWithFilter(
1138 container, &notifier, base::string16());
1141 void CookiesTreeModel::PopulateFlashLSOInfo(
1142 LocalDataContainer* container) {
1143 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1144 PopulateFlashLSOInfoWithFilter(container, &notifier, base::string16());
1147 void CookiesTreeModel::PopulateAppCacheInfoWithFilter(
1148 LocalDataContainer* container,
1149 ScopedBatchUpdateNotifier* notifier,
1150 const base::string16& filter) {
1151 using content::AppCacheInfo;
1152 typedef std::map<GURL, std::list<AppCacheInfo> > InfoByOrigin;
1153 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1155 if (container->appcache_info_.empty())
1156 return;
1158 notifier->StartBatchUpdate();
1159 for (InfoByOrigin::iterator origin = container->appcache_info_.begin();
1160 origin != container->appcache_info_.end(); ++origin) {
1161 base::string16 host_node_name = base::UTF8ToUTF16(origin->first.host());
1162 if (filter.empty() ||
1163 (host_node_name.find(filter) != base::string16::npos)) {
1164 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin->first);
1165 CookieTreeAppCachesNode* appcaches_node =
1166 host_node->GetOrCreateAppCachesNode();
1168 for (std::list<AppCacheInfo>::iterator info = origin->second.begin();
1169 info != origin->second.end(); ++info) {
1170 appcaches_node->AddAppCacheNode(
1171 new CookieTreeAppCacheNode(origin->first, info));
1177 void CookiesTreeModel::PopulateCookieInfoWithFilter(
1178 LocalDataContainer* container,
1179 ScopedBatchUpdateNotifier* notifier,
1180 const base::string16& filter) {
1181 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1183 notifier->StartBatchUpdate();
1184 for (CookieList::iterator it = container->cookie_list_.begin();
1185 it != container->cookie_list_.end(); ++it) {
1186 std::string source_string = it->Source();
1187 if (source_string.empty() || !group_by_cookie_source_) {
1188 std::string domain = it->Domain();
1189 if (domain.length() > 1 && domain[0] == '.')
1190 domain = domain.substr(1);
1192 // We treat secure cookies just the same as normal ones.
1193 source_string = std::string(url::kHttpScheme) +
1194 url::kStandardSchemeSeparator + domain + "/";
1197 GURL source(source_string);
1198 if (filter.empty() || (CookieTreeHostNode::TitleForUrl(source)
1199 .find(filter) != base::string16::npos)) {
1200 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(source);
1201 CookieTreeCookiesNode* cookies_node =
1202 host_node->GetOrCreateCookiesNode();
1203 CookieTreeCookieNode* new_cookie = new CookieTreeCookieNode(it);
1204 cookies_node->AddCookieNode(new_cookie);
1209 void CookiesTreeModel::PopulateDatabaseInfoWithFilter(
1210 LocalDataContainer* container,
1211 ScopedBatchUpdateNotifier* notifier,
1212 const base::string16& filter) {
1213 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1215 if (container->database_info_list_.empty())
1216 return;
1218 notifier->StartBatchUpdate();
1219 for (DatabaseInfoList::iterator database_info =
1220 container->database_info_list_.begin();
1221 database_info != container->database_info_list_.end();
1222 ++database_info) {
1223 GURL origin(database_info->identifier.ToOrigin());
1225 if (filter.empty() || (CookieTreeHostNode::TitleForUrl(origin)
1226 .find(filter) != base::string16::npos)) {
1227 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1228 CookieTreeDatabasesNode* databases_node =
1229 host_node->GetOrCreateDatabasesNode();
1230 databases_node->AddDatabaseNode(
1231 new CookieTreeDatabaseNode(database_info));
1236 void CookiesTreeModel::PopulateLocalStorageInfoWithFilter(
1237 LocalDataContainer* container,
1238 ScopedBatchUpdateNotifier* notifier,
1239 const base::string16& filter) {
1240 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1242 if (container->local_storage_info_list_.empty())
1243 return;
1245 notifier->StartBatchUpdate();
1246 for (LocalStorageInfoList::iterator local_storage_info =
1247 container->local_storage_info_list_.begin();
1248 local_storage_info != container->local_storage_info_list_.end();
1249 ++local_storage_info) {
1250 const GURL& origin(local_storage_info->origin_url);
1252 if (filter.empty() || (CookieTreeHostNode::TitleForUrl(origin)
1253 .find(filter) != std::string::npos)) {
1254 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1255 CookieTreeLocalStoragesNode* local_storages_node =
1256 host_node->GetOrCreateLocalStoragesNode();
1257 local_storages_node->AddLocalStorageNode(
1258 new CookieTreeLocalStorageNode(local_storage_info));
1263 void CookiesTreeModel::PopulateSessionStorageInfoWithFilter(
1264 LocalDataContainer* container,
1265 ScopedBatchUpdateNotifier* notifier,
1266 const base::string16& filter) {
1267 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1269 if (container->session_storage_info_list_.empty())
1270 return;
1272 notifier->StartBatchUpdate();
1273 for (LocalStorageInfoList::iterator session_storage_info =
1274 container->session_storage_info_list_.begin();
1275 session_storage_info != container->session_storage_info_list_.end();
1276 ++session_storage_info) {
1277 const GURL& origin = session_storage_info->origin_url;
1279 if (filter.empty() || (CookieTreeHostNode::TitleForUrl(origin)
1280 .find(filter) != base::string16::npos)) {
1281 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1282 CookieTreeSessionStoragesNode* session_storages_node =
1283 host_node->GetOrCreateSessionStoragesNode();
1284 session_storages_node->AddSessionStorageNode(
1285 new CookieTreeSessionStorageNode(session_storage_info));
1290 void CookiesTreeModel::PopulateIndexedDBInfoWithFilter(
1291 LocalDataContainer* container,
1292 ScopedBatchUpdateNotifier* notifier,
1293 const base::string16& filter) {
1294 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1296 if (container->indexed_db_info_list_.empty())
1297 return;
1299 notifier->StartBatchUpdate();
1300 for (IndexedDBInfoList::iterator indexed_db_info =
1301 container->indexed_db_info_list_.begin();
1302 indexed_db_info != container->indexed_db_info_list_.end();
1303 ++indexed_db_info) {
1304 const GURL& origin = indexed_db_info->origin_;
1306 if (filter.empty() || (CookieTreeHostNode::TitleForUrl(origin)
1307 .find(filter) != base::string16::npos)) {
1308 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1309 CookieTreeIndexedDBsNode* indexed_dbs_node =
1310 host_node->GetOrCreateIndexedDBsNode();
1311 indexed_dbs_node->AddIndexedDBNode(
1312 new CookieTreeIndexedDBNode(indexed_db_info));
1317 void CookiesTreeModel::PopulateChannelIDInfoWithFilter(
1318 LocalDataContainer* container,
1319 ScopedBatchUpdateNotifier* notifier,
1320 const base::string16& filter) {
1321 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1323 if (container->channel_id_list_.empty())
1324 return;
1326 notifier->StartBatchUpdate();
1327 for (ChannelIDList::iterator channel_id_info =
1328 container->channel_id_list_.begin();
1329 channel_id_info != container->channel_id_list_.end();
1330 ++channel_id_info) {
1331 GURL origin(channel_id_info->server_identifier());
1332 if (!origin.is_valid()) {
1333 // Channel ID. Make a valid URL to satisfy the
1334 // CookieTreeRootNode::GetOrCreateHostNode interface.
1335 origin = GURL(std::string(url::kHttpsScheme) +
1336 url::kStandardSchemeSeparator +
1337 channel_id_info->server_identifier() + "/");
1339 base::string16 title = CookieTreeHostNode::TitleForUrl(origin);
1340 if (filter.empty() || title.find(filter) != base::string16::npos) {
1341 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1342 CookieTreeChannelIDsNode* channel_ids_node =
1343 host_node->GetOrCreateChannelIDsNode();
1344 channel_ids_node->AddChannelIDNode(
1345 new CookieTreeChannelIDNode(channel_id_info));
1350 void CookiesTreeModel::PopulateServiceWorkerUsageInfoWithFilter(
1351 LocalDataContainer* container,
1352 ScopedBatchUpdateNotifier* notifier,
1353 const base::string16& filter) {
1354 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1356 if (container->service_worker_info_list_.empty())
1357 return;
1359 notifier->StartBatchUpdate();
1360 for (ServiceWorkerUsageInfoList::iterator service_worker_info =
1361 container->service_worker_info_list_.begin();
1362 service_worker_info != container->service_worker_info_list_.end();
1363 ++service_worker_info) {
1364 const GURL& origin = service_worker_info->origin;
1366 if (filter.empty() || (CookieTreeHostNode::TitleForUrl(origin)
1367 .find(filter) != base::string16::npos)) {
1368 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1369 CookieTreeServiceWorkersNode* service_workers_node =
1370 host_node->GetOrCreateServiceWorkersNode();
1371 service_workers_node->AddServiceWorkerNode(
1372 new CookieTreeServiceWorkerNode(service_worker_info));
1377 void CookiesTreeModel::PopulateFileSystemInfoWithFilter(
1378 LocalDataContainer* container,
1379 ScopedBatchUpdateNotifier* notifier,
1380 const base::string16& filter) {
1381 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1383 if (container->file_system_info_list_.empty())
1384 return;
1386 notifier->StartBatchUpdate();
1387 for (FileSystemInfoList::iterator file_system_info =
1388 container->file_system_info_list_.begin();
1389 file_system_info != container->file_system_info_list_.end();
1390 ++file_system_info) {
1391 GURL origin(file_system_info->origin);
1393 if (filter.empty() || (CookieTreeHostNode::TitleForUrl(origin)
1394 .find(filter) != base::string16::npos)) {
1395 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1396 CookieTreeFileSystemsNode* file_systems_node =
1397 host_node->GetOrCreateFileSystemsNode();
1398 file_systems_node->AddFileSystemNode(
1399 new CookieTreeFileSystemNode(file_system_info));
1404 void CookiesTreeModel::PopulateQuotaInfoWithFilter(
1405 LocalDataContainer* container,
1406 ScopedBatchUpdateNotifier* notifier,
1407 const base::string16& filter) {
1408 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1410 if (container->quota_info_list_.empty())
1411 return;
1413 notifier->StartBatchUpdate();
1414 for (QuotaInfoList::iterator quota_info = container->quota_info_list_.begin();
1415 quota_info != container->quota_info_list_.end();
1416 ++quota_info) {
1417 if (filter.empty() || (base::UTF8ToUTF16(quota_info->host).find(filter) !=
1418 base::string16::npos)) {
1419 CookieTreeHostNode* host_node =
1420 root->GetOrCreateHostNode(GURL("http://" + quota_info->host));
1421 host_node->UpdateOrCreateQuotaNode(quota_info);
1426 void CookiesTreeModel::PopulateFlashLSOInfoWithFilter(
1427 LocalDataContainer* container,
1428 ScopedBatchUpdateNotifier* notifier,
1429 const base::string16& filter) {
1430 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1432 if (container->flash_lso_domain_list_.empty())
1433 return;
1435 std::string filter_utf8 = base::UTF16ToUTF8(filter);
1436 notifier->StartBatchUpdate();
1437 for (std::vector<std::string>::iterator it =
1438 container->flash_lso_domain_list_.begin();
1439 it != container->flash_lso_domain_list_.end(); ++it) {
1440 if (filter_utf8.empty() || it->find(filter_utf8) != std::string::npos) {
1441 // Create a fake origin for GetOrCreateHostNode().
1442 GURL origin("http://" + *it);
1443 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1444 host_node->GetOrCreateFlashLSONode(*it);
1449 void CookiesTreeModel::SetBatchExpectation(int batches_expected, bool reset) {
1450 batches_expected_ = batches_expected;
1451 if (reset) {
1452 batches_seen_ = 0;
1453 batches_started_ = 0;
1454 batches_ended_ = 0;
1455 } else {
1456 MaybeNotifyBatchesEnded();
1460 void CookiesTreeModel::RecordBatchSeen() {
1461 batches_seen_++;
1464 void CookiesTreeModel::NotifyObserverBeginBatch() {
1465 // Only notify the model once if we're batching in a nested manner.
1466 if (batches_started_++ == 0) {
1467 FOR_EACH_OBSERVER(Observer,
1468 cookies_observer_list_,
1469 TreeModelBeginBatch(this));
1473 void CookiesTreeModel::NotifyObserverEndBatch() {
1474 batches_ended_++;
1475 MaybeNotifyBatchesEnded();
1478 void CookiesTreeModel::MaybeNotifyBatchesEnded() {
1479 // Only notify the observers if this is the outermost call to EndBatch() if
1480 // called in a nested manner.
1481 if (batches_ended_ == batches_started_ &&
1482 batches_seen_ == batches_expected_) {
1483 FOR_EACH_OBSERVER(Observer,
1484 cookies_observer_list_,
1485 TreeModelEndBatch(this));