ifdef remaining extensions code in chrome/browser/browsing_data.
[chromium-blink-merge.git] / chrome / browser / browsing_data / cookies_tree_model.cc
blobfbeb58d96f88cc41550291fc4b46cc1457313e12
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 <vector>
11 #include "base/bind.h"
12 #include "base/memory/linked_ptr.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h"
16 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
18 #include "chrome/browser/content_settings/cookie_settings.h"
19 #include "content/public/common/url_constants.h"
20 #include "grit/generated_resources.h"
21 #include "grit/theme_resources.h"
22 #include "grit/ui_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"
30 #if defined(ENABLE_EXTENSIONS)
31 #include "chrome/browser/extensions/extension_special_storage_policy.h"
32 #include "extensions/common/extension_set.h"
33 #endif
35 namespace {
37 struct NodeTitleComparator {
38 bool operator()(const CookieTreeNode* lhs, const CookieTreeNode* rhs) {
39 return lhs->GetTitle() < rhs->GetTitle();
43 // Comparison functor, for use in CookieTreeRootNode.
44 struct HostNodeComparator {
45 bool operator()(const CookieTreeNode* lhs, const CookieTreeNode* rhs) {
46 // This comparator is only meant to compare CookieTreeHostNode types. Make
47 // sure we check this, as the static cast below is dangerous if we get the
48 // wrong object type.
49 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST,
50 lhs->GetDetailedInfo().node_type);
51 CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST,
52 rhs->GetDetailedInfo().node_type);
54 const CookieTreeHostNode* ltn =
55 static_cast<const CookieTreeHostNode*>(lhs);
56 const CookieTreeHostNode* rtn =
57 static_cast<const CookieTreeHostNode*>(rhs);
59 // We want to order by registry controlled domain, so we would get
60 // google.com, ad.google.com, www.google.com,
61 // microsoft.com, ad.microsoft.com. CanonicalizeHost transforms the origins
62 // into a form like google.com.www so that string comparisons work.
63 return (ltn->canonicalized_host() <
64 rtn->canonicalized_host());
68 std::string CanonicalizeHost(const GURL& url) {
69 // The canonicalized representation makes the registry controlled domain
70 // come first, and then adds subdomains in reverse order, e.g.
71 // 1.mail.google.com would become google.com.mail.1, and then a standard
72 // string comparison works to order hosts by registry controlled domain
73 // first. Leading dots are ignored, ".google.com" is the same as
74 // "google.com".
76 if (url.SchemeIsFile()) {
77 return std::string(url::kFileScheme) +
78 url::kStandardSchemeSeparator;
81 std::string host = url.host();
82 std::string retval =
83 net::registry_controlled_domains::GetDomainAndRegistry(
84 host,
85 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
86 if (!retval.length()) // Is an IP address or other special origin.
87 return host;
89 std::string::size_type position = host.rfind(retval);
91 // The host may be the registry controlled domain, in which case fail fast.
92 if (position == 0 || position == std::string::npos)
93 return host;
95 // If host is www.google.com, retval will contain google.com at this point.
96 // Start operating to the left of the registry controlled domain, e.g. in
97 // the www.google.com example, start at index 3.
98 --position;
100 // If position == 0, that means it's a dot; this will be ignored to treat
101 // ".google.com" the same as "google.com".
102 while (position > 0) {
103 retval += std::string(".");
104 // Copy up to the next dot. host[position] is a dot so start after it.
105 std::string::size_type next_dot = host.rfind(".", position - 1);
106 if (next_dot == std::string::npos) {
107 retval += host.substr(0, position);
108 break;
110 retval += host.substr(next_dot + 1, position - (next_dot + 1));
111 position = next_dot;
113 return retval;
116 #if defined(ENABLE_EXTENSIONS)
117 bool TypeIsProtected(CookieTreeNode::DetailedInfo::NodeType type) {
118 switch (type) {
119 case CookieTreeNode::DetailedInfo::TYPE_COOKIE:
120 return false;
121 case CookieTreeNode::DetailedInfo::TYPE_DATABASE:
122 return true;
123 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE:
124 return true;
125 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE:
126 return true;
127 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE:
128 return true;
129 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB:
130 return true;
131 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM:
132 return true;
133 case CookieTreeNode::DetailedInfo::TYPE_QUOTA:
134 return false;
135 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID:
136 return false;
137 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO:
138 return false;
139 default:
140 break;
142 return false;
144 #endif
146 // This function returns the local data container associated with a leaf tree
147 // node. The app node is assumed to be 3 levels above the leaf because of the
148 // following structure:
149 // root -> origin -> storage type -> leaf node
150 LocalDataContainer* GetLocalDataContainerForNode(CookieTreeNode* node) {
151 CookieTreeHostNode* host = static_cast<CookieTreeHostNode*>(
152 node->parent()->parent());
153 CHECK_EQ(host->GetDetailedInfo().node_type,
154 CookieTreeNode::DetailedInfo::TYPE_HOST);
155 return node->GetModel()->data_container();
158 } // namespace
160 CookieTreeNode::DetailedInfo::DetailedInfo()
161 : node_type(TYPE_NONE),
162 cookie(NULL),
163 database_info(NULL),
164 local_storage_info(NULL),
165 session_storage_info(NULL),
166 appcache_info(NULL),
167 indexed_db_info(NULL),
168 file_system_info(NULL),
169 quota_info(NULL),
170 channel_id(NULL) {}
172 CookieTreeNode::DetailedInfo::~DetailedInfo() {}
174 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::Init(
175 NodeType type) {
176 DCHECK_EQ(TYPE_NONE, node_type);
177 node_type = type;
178 return *this;
181 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitHost() {
182 Init(TYPE_HOST);
183 return *this;
186 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitCookie(
187 const net::CanonicalCookie* cookie) {
188 Init(TYPE_COOKIE);
189 this->cookie = cookie;
190 return *this;
193 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitDatabase(
194 const BrowsingDataDatabaseHelper::DatabaseInfo* database_info) {
195 Init(TYPE_DATABASE);
196 this->database_info = database_info;
197 origin = database_info->identifier.ToOrigin();
198 return *this;
201 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitLocalStorage(
202 const BrowsingDataLocalStorageHelper::LocalStorageInfo*
203 local_storage_info) {
204 Init(TYPE_LOCAL_STORAGE);
205 this->local_storage_info = local_storage_info;
206 origin = local_storage_info->origin_url;
207 return *this;
210 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitSessionStorage(
211 const BrowsingDataLocalStorageHelper::LocalStorageInfo*
212 session_storage_info) {
213 Init(TYPE_SESSION_STORAGE);
214 this->session_storage_info = session_storage_info;
215 origin = session_storage_info->origin_url;
216 return *this;
219 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitAppCache(
220 const GURL& origin,
221 const content::AppCacheInfo* appcache_info) {
222 Init(TYPE_APPCACHE);
223 this->appcache_info = appcache_info;
224 this->origin = origin;
225 return *this;
228 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitIndexedDB(
229 const content::IndexedDBInfo* indexed_db_info) {
230 Init(TYPE_INDEXED_DB);
231 this->indexed_db_info = indexed_db_info;
232 this->origin = indexed_db_info->origin_;
233 return *this;
236 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitFileSystem(
237 const BrowsingDataFileSystemHelper::FileSystemInfo* file_system_info) {
238 Init(TYPE_FILE_SYSTEM);
239 this->file_system_info = file_system_info;
240 this->origin = file_system_info->origin;
241 return *this;
244 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitQuota(
245 const BrowsingDataQuotaHelper::QuotaInfo* quota_info) {
246 Init(TYPE_QUOTA);
247 this->quota_info = quota_info;
248 return *this;
251 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitChannelID(
252 const net::ChannelIDStore::ChannelID* channel_id) {
253 Init(TYPE_CHANNEL_ID);
254 this->channel_id = channel_id;
255 return *this;
258 CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitFlashLSO(
259 const std::string& flash_lso_domain) {
260 Init(TYPE_FLASH_LSO);
261 this->flash_lso_domain = flash_lso_domain;
262 return *this;
265 ///////////////////////////////////////////////////////////////////////////////
266 // CookieTreeNode, public:
268 void CookieTreeNode::DeleteStoredObjects() {
269 std::for_each(children().begin(),
270 children().end(),
271 std::mem_fun(&CookieTreeNode::DeleteStoredObjects));
274 CookiesTreeModel* CookieTreeNode::GetModel() const {
275 if (parent())
276 return parent()->GetModel();
277 else
278 return NULL;
281 ///////////////////////////////////////////////////////////////////////////////
282 // CookieTreeCookieNode, public:
284 CookieTreeCookieNode::CookieTreeCookieNode(
285 std::list<net::CanonicalCookie>::iterator cookie)
286 : CookieTreeNode(base::UTF8ToUTF16(cookie->Name())),
287 cookie_(cookie) {
290 CookieTreeCookieNode::~CookieTreeCookieNode() {}
292 void CookieTreeCookieNode::DeleteStoredObjects() {
293 LocalDataContainer* container = GetLocalDataContainerForNode(this);
294 CHECK(container);
295 container->cookie_helper_->DeleteCookie(*cookie_);
296 container->cookie_list_.erase(cookie_);
299 CookieTreeNode::DetailedInfo CookieTreeCookieNode::GetDetailedInfo() const {
300 return DetailedInfo().InitCookie(&*cookie_);
303 ///////////////////////////////////////////////////////////////////////////////
304 // CookieTreeAppCacheNode, public:
306 CookieTreeAppCacheNode::CookieTreeAppCacheNode(
307 const GURL& origin_url,
308 std::list<content::AppCacheInfo>::iterator appcache_info)
309 : CookieTreeNode(base::UTF8ToUTF16(appcache_info->manifest_url.spec())),
310 origin_url_(origin_url),
311 appcache_info_(appcache_info) {
314 CookieTreeAppCacheNode::~CookieTreeAppCacheNode() {
317 void CookieTreeAppCacheNode::DeleteStoredObjects() {
318 LocalDataContainer* container = GetLocalDataContainerForNode(this);
320 if (container) {
321 DCHECK(container->appcache_helper_.get());
322 container->appcache_helper_
323 ->DeleteAppCacheGroup(appcache_info_->manifest_url);
324 container->appcache_info_[origin_url_].erase(appcache_info_);
328 CookieTreeNode::DetailedInfo CookieTreeAppCacheNode::GetDetailedInfo() const {
329 return DetailedInfo().InitAppCache(origin_url_, &*appcache_info_);
332 ///////////////////////////////////////////////////////////////////////////////
333 // CookieTreeDatabaseNode, public:
335 CookieTreeDatabaseNode::CookieTreeDatabaseNode(
336 std::list<BrowsingDataDatabaseHelper::DatabaseInfo>::iterator database_info)
337 : CookieTreeNode(database_info->database_name.empty() ?
338 l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME) :
339 base::UTF8ToUTF16(database_info->database_name)),
340 database_info_(database_info) {
343 CookieTreeDatabaseNode::~CookieTreeDatabaseNode() {}
345 void CookieTreeDatabaseNode::DeleteStoredObjects() {
346 LocalDataContainer* container = GetLocalDataContainerForNode(this);
348 if (container) {
349 container->database_helper_->DeleteDatabase(
350 database_info_->identifier.ToString(), database_info_->database_name);
351 container->database_info_list_.erase(database_info_);
355 CookieTreeNode::DetailedInfo CookieTreeDatabaseNode::GetDetailedInfo() const {
356 return DetailedInfo().InitDatabase(&*database_info_);
359 ///////////////////////////////////////////////////////////////////////////////
360 // CookieTreeLocalStorageNode, public:
362 CookieTreeLocalStorageNode::CookieTreeLocalStorageNode(
363 std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::iterator
364 local_storage_info)
365 : CookieTreeNode(base::UTF8ToUTF16(local_storage_info->origin_url.spec())),
366 local_storage_info_(local_storage_info) {
369 CookieTreeLocalStorageNode::~CookieTreeLocalStorageNode() {}
371 void CookieTreeLocalStorageNode::DeleteStoredObjects() {
372 LocalDataContainer* container = GetLocalDataContainerForNode(this);
374 if (container) {
375 container->local_storage_helper_->DeleteOrigin(
376 local_storage_info_->origin_url);
377 container->local_storage_info_list_.erase(local_storage_info_);
381 CookieTreeNode::DetailedInfo
382 CookieTreeLocalStorageNode::GetDetailedInfo() const {
383 return DetailedInfo().InitLocalStorage(
384 &*local_storage_info_);
387 ///////////////////////////////////////////////////////////////////////////////
388 // CookieTreeSessionStorageNode, public:
390 CookieTreeSessionStorageNode::CookieTreeSessionStorageNode(
391 std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::iterator
392 session_storage_info)
393 : CookieTreeNode(
394 base::UTF8ToUTF16(session_storage_info->origin_url.spec())),
395 session_storage_info_(session_storage_info) {
398 CookieTreeSessionStorageNode::~CookieTreeSessionStorageNode() {}
400 void CookieTreeSessionStorageNode::DeleteStoredObjects() {
401 LocalDataContainer* container = GetLocalDataContainerForNode(this);
403 if (container) {
404 // TODO(rsesek): There's no easy way to get the namespace_id for a session
405 // storage, nor is there an easy way to clear session storage just by
406 // origin. This is probably okay since session storage is not persistent.
407 // http://crbug.com/168996
408 container->session_storage_info_list_.erase(session_storage_info_);
412 CookieTreeNode::DetailedInfo
413 CookieTreeSessionStorageNode::GetDetailedInfo() const {
414 return DetailedInfo().InitSessionStorage(&*session_storage_info_);
417 ///////////////////////////////////////////////////////////////////////////////
418 // CookieTreeIndexedDBNode, public:
420 CookieTreeIndexedDBNode::CookieTreeIndexedDBNode(
421 std::list<content::IndexedDBInfo>::iterator
422 indexed_db_info)
423 : CookieTreeNode(base::UTF8ToUTF16(
424 indexed_db_info->origin_.spec())),
425 indexed_db_info_(indexed_db_info) {
428 CookieTreeIndexedDBNode::~CookieTreeIndexedDBNode() {}
430 void CookieTreeIndexedDBNode::DeleteStoredObjects() {
431 LocalDataContainer* container = GetLocalDataContainerForNode(this);
433 if (container) {
434 container->indexed_db_helper_->DeleteIndexedDB(
435 indexed_db_info_->origin_);
436 container->indexed_db_info_list_.erase(indexed_db_info_);
440 CookieTreeNode::DetailedInfo CookieTreeIndexedDBNode::GetDetailedInfo() const {
441 return DetailedInfo().InitIndexedDB(&*indexed_db_info_);
444 ///////////////////////////////////////////////////////////////////////////////
445 // CookieTreeFileSystemNode, public:
447 CookieTreeFileSystemNode::CookieTreeFileSystemNode(
448 std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator
449 file_system_info)
450 : CookieTreeNode(base::UTF8ToUTF16(
451 file_system_info->origin.spec())),
452 file_system_info_(file_system_info) {
455 CookieTreeFileSystemNode::~CookieTreeFileSystemNode() {}
457 void CookieTreeFileSystemNode::DeleteStoredObjects() {
458 LocalDataContainer* container = GetLocalDataContainerForNode(this);
460 if (container) {
461 container->file_system_helper_->DeleteFileSystemOrigin(
462 file_system_info_->origin);
463 container->file_system_info_list_.erase(file_system_info_);
467 CookieTreeNode::DetailedInfo CookieTreeFileSystemNode::GetDetailedInfo() const {
468 return DetailedInfo().InitFileSystem(&*file_system_info_);
471 ///////////////////////////////////////////////////////////////////////////////
472 // CookieTreeQuotaNode, public:
474 CookieTreeQuotaNode::CookieTreeQuotaNode(
475 std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info)
476 : CookieTreeNode(base::UTF8ToUTF16(quota_info->host)),
477 quota_info_(quota_info) {
480 CookieTreeQuotaNode::~CookieTreeQuotaNode() {}
482 void CookieTreeQuotaNode::DeleteStoredObjects() {
483 // Calling this function may cause unexpected over-quota state of origin.
484 // However, it'll caused no problem, just prevent usage growth of the origin.
485 LocalDataContainer* container = GetModel()->data_container();
487 if (container) {
488 container->quota_helper_->RevokeHostQuota(quota_info_->host);
489 container->quota_info_list_.erase(quota_info_);
493 CookieTreeNode::DetailedInfo CookieTreeQuotaNode::GetDetailedInfo() const {
494 return DetailedInfo().InitQuota(&*quota_info_);
497 ///////////////////////////////////////////////////////////////////////////////
498 // CookieTreeChannelIDNode, public:
500 CookieTreeChannelIDNode::CookieTreeChannelIDNode(
501 net::ChannelIDStore::ChannelIDList::iterator channel_id)
502 : CookieTreeNode(base::ASCIIToUTF16(channel_id->server_identifier())),
503 channel_id_(channel_id) {
506 CookieTreeChannelIDNode::~CookieTreeChannelIDNode() {}
508 void CookieTreeChannelIDNode::DeleteStoredObjects() {
509 LocalDataContainer* container = GetLocalDataContainerForNode(this);
511 if (container) {
512 container->channel_id_helper_->DeleteChannelID(
513 channel_id_->server_identifier());
514 container->channel_id_list_.erase(channel_id_);
518 CookieTreeNode::DetailedInfo
519 CookieTreeChannelIDNode::GetDetailedInfo() const {
520 return DetailedInfo().InitChannelID(&*channel_id_);
523 ///////////////////////////////////////////////////////////////////////////////
524 // CookieTreeRootNode, public:
526 CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel* model)
527 : model_(model) {
530 CookieTreeRootNode::~CookieTreeRootNode() {}
532 CookieTreeHostNode* CookieTreeRootNode::GetOrCreateHostNode(
533 const GURL& url) {
534 scoped_ptr<CookieTreeHostNode> host_node(
535 new CookieTreeHostNode(url));
537 // First see if there is an existing match.
538 std::vector<CookieTreeNode*>::iterator host_node_iterator =
539 std::lower_bound(children().begin(), children().end(), host_node.get(),
540 HostNodeComparator());
541 if (host_node_iterator != children().end() &&
542 CookieTreeHostNode::TitleForUrl(url) ==
543 (*host_node_iterator)->GetTitle())
544 return static_cast<CookieTreeHostNode*>(*host_node_iterator);
545 // Node doesn't exist, insert the new one into the (ordered) children.
546 DCHECK(model_);
547 model_->Add(this, host_node.get(),
548 (host_node_iterator - children().begin()));
549 return host_node.release();
552 CookiesTreeModel* CookieTreeRootNode::GetModel() const {
553 return model_;
556 CookieTreeNode::DetailedInfo CookieTreeRootNode::GetDetailedInfo() const {
557 return DetailedInfo().Init(DetailedInfo::TYPE_ROOT);
560 ///////////////////////////////////////////////////////////////////////////////
561 // CookieTreeHostNode, public:
563 // static
564 base::string16 CookieTreeHostNode::TitleForUrl(const GURL& url) {
565 const std::string file_origin_node_name(
566 std::string(url::kFileScheme) + url::kStandardSchemeSeparator);
567 return base::UTF8ToUTF16(url.SchemeIsFile() ? file_origin_node_name
568 : url.host());
571 CookieTreeHostNode::CookieTreeHostNode(const GURL& url)
572 : CookieTreeNode(TitleForUrl(url)),
573 cookies_child_(NULL),
574 databases_child_(NULL),
575 local_storages_child_(NULL),
576 session_storages_child_(NULL),
577 appcaches_child_(NULL),
578 indexed_dbs_child_(NULL),
579 file_systems_child_(NULL),
580 quota_child_(NULL),
581 channel_ids_child_(NULL),
582 flash_lso_child_(NULL),
583 url_(url),
584 canonicalized_host_(CanonicalizeHost(url)) {}
586 CookieTreeHostNode::~CookieTreeHostNode() {}
588 const std::string CookieTreeHostNode::GetHost() const {
589 const std::string file_origin_node_name(
590 std::string(url::kFileScheme) + url::kStandardSchemeSeparator);
591 return url_.SchemeIsFile() ? file_origin_node_name : url_.host();
594 CookieTreeNode::DetailedInfo CookieTreeHostNode::GetDetailedInfo() const {
595 return DetailedInfo().InitHost();
598 CookieTreeCookiesNode* CookieTreeHostNode::GetOrCreateCookiesNode() {
599 if (cookies_child_)
600 return cookies_child_;
601 cookies_child_ = new CookieTreeCookiesNode;
602 AddChildSortedByTitle(cookies_child_);
603 return cookies_child_;
606 CookieTreeDatabasesNode* CookieTreeHostNode::GetOrCreateDatabasesNode() {
607 if (databases_child_)
608 return databases_child_;
609 databases_child_ = new CookieTreeDatabasesNode;
610 AddChildSortedByTitle(databases_child_);
611 return databases_child_;
614 CookieTreeLocalStoragesNode*
615 CookieTreeHostNode::GetOrCreateLocalStoragesNode() {
616 if (local_storages_child_)
617 return local_storages_child_;
618 local_storages_child_ = new CookieTreeLocalStoragesNode;
619 AddChildSortedByTitle(local_storages_child_);
620 return local_storages_child_;
623 CookieTreeSessionStoragesNode*
624 CookieTreeHostNode::GetOrCreateSessionStoragesNode() {
625 if (session_storages_child_)
626 return session_storages_child_;
627 session_storages_child_ = new CookieTreeSessionStoragesNode;
628 AddChildSortedByTitle(session_storages_child_);
629 return session_storages_child_;
632 CookieTreeAppCachesNode* CookieTreeHostNode::GetOrCreateAppCachesNode() {
633 if (appcaches_child_)
634 return appcaches_child_;
635 appcaches_child_ = new CookieTreeAppCachesNode;
636 AddChildSortedByTitle(appcaches_child_);
637 return appcaches_child_;
640 CookieTreeIndexedDBsNode* CookieTreeHostNode::GetOrCreateIndexedDBsNode() {
641 if (indexed_dbs_child_)
642 return indexed_dbs_child_;
643 indexed_dbs_child_ = new CookieTreeIndexedDBsNode;
644 AddChildSortedByTitle(indexed_dbs_child_);
645 return indexed_dbs_child_;
648 CookieTreeFileSystemsNode* CookieTreeHostNode::GetOrCreateFileSystemsNode() {
649 if (file_systems_child_)
650 return file_systems_child_;
651 file_systems_child_ = new CookieTreeFileSystemsNode;
652 AddChildSortedByTitle(file_systems_child_);
653 return file_systems_child_;
656 CookieTreeQuotaNode* CookieTreeHostNode::UpdateOrCreateQuotaNode(
657 std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info) {
658 if (quota_child_)
659 return quota_child_;
660 quota_child_ = new CookieTreeQuotaNode(quota_info);
661 AddChildSortedByTitle(quota_child_);
662 return quota_child_;
665 CookieTreeChannelIDsNode*
666 CookieTreeHostNode::GetOrCreateChannelIDsNode() {
667 if (channel_ids_child_)
668 return channel_ids_child_;
669 channel_ids_child_ = new CookieTreeChannelIDsNode;
670 AddChildSortedByTitle(channel_ids_child_);
671 return channel_ids_child_;
674 CookieTreeFlashLSONode* CookieTreeHostNode::GetOrCreateFlashLSONode(
675 const std::string& domain) {
676 DCHECK_EQ(GetHost(), domain);
677 if (flash_lso_child_)
678 return flash_lso_child_;
679 flash_lso_child_ = new CookieTreeFlashLSONode(domain);
680 AddChildSortedByTitle(flash_lso_child_);
681 return flash_lso_child_;
684 void CookieTreeHostNode::CreateContentException(
685 CookieSettings* cookie_settings, ContentSetting setting) const {
686 DCHECK(setting == CONTENT_SETTING_ALLOW ||
687 setting == CONTENT_SETTING_BLOCK ||
688 setting == CONTENT_SETTING_SESSION_ONLY);
689 if (CanCreateContentException()) {
690 cookie_settings->ResetCookieSetting(
691 ContentSettingsPattern::FromURLNoWildcard(url_),
692 ContentSettingsPattern::Wildcard());
693 cookie_settings->SetCookieSetting(
694 ContentSettingsPattern::FromURL(url_),
695 ContentSettingsPattern::Wildcard(), setting);
699 bool CookieTreeHostNode::CanCreateContentException() const {
700 return !url_.SchemeIsFile();
703 ///////////////////////////////////////////////////////////////////////////////
704 // CookieTreeCookiesNode, public:
706 CookieTreeCookiesNode::CookieTreeCookiesNode()
707 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES)) {
710 CookieTreeCookiesNode::~CookieTreeCookiesNode() {
713 CookieTreeNode::DetailedInfo CookieTreeCookiesNode::GetDetailedInfo() const {
714 return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES);
717 ///////////////////////////////////////////////////////////////////////////////
718 // CookieTreeAppCachesNode, public:
720 CookieTreeAppCachesNode::CookieTreeAppCachesNode()
721 : CookieTreeNode(l10n_util::GetStringUTF16(
722 IDS_COOKIES_APPLICATION_CACHES)) {
725 CookieTreeAppCachesNode::~CookieTreeAppCachesNode() {}
727 CookieTreeNode::DetailedInfo CookieTreeAppCachesNode::GetDetailedInfo() const {
728 return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES);
731 ///////////////////////////////////////////////////////////////////////////////
732 // CookieTreeDatabasesNode, public:
734 CookieTreeDatabasesNode::CookieTreeDatabasesNode()
735 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES)) {
738 CookieTreeDatabasesNode::~CookieTreeDatabasesNode() {}
740 CookieTreeNode::DetailedInfo CookieTreeDatabasesNode::GetDetailedInfo() const {
741 return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES);
744 ///////////////////////////////////////////////////////////////////////////////
745 // CookieTreeLocalStoragesNode, public:
747 CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode()
748 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE)) {
751 CookieTreeLocalStoragesNode::~CookieTreeLocalStoragesNode() {}
753 CookieTreeNode::DetailedInfo
754 CookieTreeLocalStoragesNode::GetDetailedInfo() const {
755 return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES);
758 ///////////////////////////////////////////////////////////////////////////////
759 // CookieTreeSessionStoragesNode, public:
761 CookieTreeSessionStoragesNode::CookieTreeSessionStoragesNode()
762 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE)) {
765 CookieTreeSessionStoragesNode::~CookieTreeSessionStoragesNode() {}
767 CookieTreeNode::DetailedInfo
768 CookieTreeSessionStoragesNode::GetDetailedInfo() const {
769 return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES);
772 ///////////////////////////////////////////////////////////////////////////////
773 // CookieTreeIndexedDBsNode, public:
775 CookieTreeIndexedDBsNode::CookieTreeIndexedDBsNode()
776 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS)) {
779 CookieTreeIndexedDBsNode::~CookieTreeIndexedDBsNode() {}
781 CookieTreeNode::DetailedInfo
782 CookieTreeIndexedDBsNode::GetDetailedInfo() const {
783 return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS);
786 ///////////////////////////////////////////////////////////////////////////////
787 // CookieTreeFileSystemsNode, public:
789 CookieTreeFileSystemsNode::CookieTreeFileSystemsNode()
790 : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS)) {
793 CookieTreeFileSystemsNode::~CookieTreeFileSystemsNode() {}
795 CookieTreeNode::DetailedInfo
796 CookieTreeFileSystemsNode::GetDetailedInfo() const {
797 return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS);
800 ///////////////////////////////////////////////////////////////////////////////
801 // CookieTreeChannelIDsNode, public:
803 CookieTreeChannelIDsNode::CookieTreeChannelIDsNode()
804 : CookieTreeNode(
805 l10n_util::GetStringUTF16(IDS_COOKIES_CHANNEL_IDS)) {
808 CookieTreeChannelIDsNode::~CookieTreeChannelIDsNode() {}
810 CookieTreeNode::DetailedInfo
811 CookieTreeChannelIDsNode::GetDetailedInfo() const {
812 return DetailedInfo().Init(DetailedInfo::TYPE_CHANNEL_IDS);
815 void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode* new_child) {
816 DCHECK(new_child);
817 std::vector<CookieTreeNode*>::iterator iter =
818 std::lower_bound(children().begin(), children().end(), new_child,
819 NodeTitleComparator());
820 GetModel()->Add(this, new_child, iter - children().begin());
823 ///////////////////////////////////////////////////////////////////////////////
824 // CookieTreeFlashLSONode
825 CookieTreeFlashLSONode::CookieTreeFlashLSONode(
826 const std::string& domain)
827 : domain_(domain) {}
828 CookieTreeFlashLSONode::~CookieTreeFlashLSONode() {}
830 void CookieTreeFlashLSONode::DeleteStoredObjects() {
831 // We are one level below the host node.
832 CookieTreeHostNode* host = static_cast<CookieTreeHostNode*>(parent());
833 CHECK_EQ(host->GetDetailedInfo().node_type,
834 CookieTreeNode::DetailedInfo::TYPE_HOST);
835 LocalDataContainer* container = GetModel()->data_container();
836 CHECK(container);
838 container->flash_lso_helper_->DeleteFlashLSOsForSite(domain_);
841 CookieTreeNode::DetailedInfo CookieTreeFlashLSONode::GetDetailedInfo() const {
842 return DetailedInfo().InitFlashLSO(domain_);
845 ///////////////////////////////////////////////////////////////////////////////
846 // ScopedBatchUpdateNotifier
847 CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier(
848 CookiesTreeModel* model, CookieTreeNode* node)
849 : model_(model), node_(node), batch_in_progress_(false) {
852 CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() {
853 if (batch_in_progress_) {
854 model_->NotifyObserverTreeNodeChanged(node_);
855 model_->NotifyObserverEndBatch();
859 void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() {
860 if (!batch_in_progress_) {
861 model_->NotifyObserverBeginBatch();
862 batch_in_progress_ = true;
866 ///////////////////////////////////////////////////////////////////////////////
867 // CookiesTreeModel, public:
868 CookiesTreeModel::CookiesTreeModel(
869 LocalDataContainer* data_container,
870 ExtensionSpecialStoragePolicy* special_storage_policy,
871 bool group_by_cookie_source)
872 : ui::TreeNodeModel<CookieTreeNode>(new CookieTreeRootNode(this)),
873 data_container_(data_container),
874 #if defined(ENABLE_EXTENSIONS)
875 special_storage_policy_(special_storage_policy),
876 #endif
877 group_by_cookie_source_(group_by_cookie_source),
878 batch_update_(0) {
879 data_container_->Init(this);
882 CookiesTreeModel::~CookiesTreeModel() {
885 ///////////////////////////////////////////////////////////////////////////////
886 // CookiesTreeModel, TreeModel methods (public):
888 // TreeModel methods:
889 // Returns the set of icons for the nodes in the tree. You only need override
890 // this if you don't want to use the default folder icons.
891 void CookiesTreeModel::GetIcons(std::vector<gfx::ImageSkia>* icons) {
892 icons->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
893 IDR_DEFAULT_FAVICON).ToImageSkia());
894 icons->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
895 IDR_COOKIE_ICON).ToImageSkia());
896 icons->push_back(*ResourceBundle::GetSharedInstance().GetNativeImageNamed(
897 IDR_COOKIE_STORAGE_ICON).ToImageSkia());
900 // Returns the index of the icon to use for |node|. Return -1 to use the
901 // default icon. The index is relative to the list of icons returned from
902 // GetIcons.
903 int CookiesTreeModel::GetIconIndex(ui::TreeModelNode* node) {
904 CookieTreeNode* ct_node = static_cast<CookieTreeNode*>(node);
905 switch (ct_node->GetDetailedInfo().node_type) {
906 case CookieTreeNode::DetailedInfo::TYPE_HOST:
907 return ORIGIN;
908 case CookieTreeNode::DetailedInfo::TYPE_COOKIE:
909 return COOKIE;
910 case CookieTreeNode::DetailedInfo::TYPE_DATABASE:
911 return DATABASE;
912 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE:
913 return DATABASE; // close enough
914 case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE:
915 return DATABASE; // ditto
916 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE:
917 return DATABASE; // ditto
918 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB:
919 return DATABASE; // ditto
920 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM:
921 return DATABASE; // ditto
922 case CookieTreeNode::DetailedInfo::TYPE_QUOTA:
923 return -1;
924 case CookieTreeNode::DetailedInfo::TYPE_CHANNEL_ID:
925 return COOKIE; // It's kinda like a cookie?
926 default:
927 break;
929 return -1;
932 void CookiesTreeModel::DeleteAllStoredObjects() {
933 NotifyObserverBeginBatch();
934 CookieTreeNode* root = GetRoot();
935 root->DeleteStoredObjects();
936 int num_children = root->child_count();
937 for (int i = num_children - 1; i >= 0; --i)
938 delete Remove(root, root->GetChild(i));
939 NotifyObserverTreeNodeChanged(root);
940 NotifyObserverEndBatch();
943 void CookiesTreeModel::DeleteCookieNode(CookieTreeNode* cookie_node) {
944 if (cookie_node == GetRoot())
945 return;
946 cookie_node->DeleteStoredObjects();
947 CookieTreeNode* parent_node = cookie_node->parent();
948 delete Remove(parent_node, cookie_node);
949 if (parent_node->empty())
950 DeleteCookieNode(parent_node);
953 void CookiesTreeModel::UpdateSearchResults(const base::string16& filter) {
954 CookieTreeNode* root = GetRoot();
955 ScopedBatchUpdateNotifier notifier(this, root);
956 int num_children = root->child_count();
957 notifier.StartBatchUpdate();
958 for (int i = num_children - 1; i >= 0; --i)
959 delete Remove(root, root->GetChild(i));
961 PopulateCookieInfoWithFilter(data_container(), &notifier, filter);
962 PopulateDatabaseInfoWithFilter(data_container(), &notifier, filter);
963 PopulateLocalStorageInfoWithFilter(data_container(), &notifier, filter);
964 PopulateSessionStorageInfoWithFilter(data_container(), &notifier, filter);
965 PopulateAppCacheInfoWithFilter(data_container(), &notifier, filter);
966 PopulateIndexedDBInfoWithFilter(data_container(), &notifier, filter);
967 PopulateFileSystemInfoWithFilter(data_container(), &notifier, filter);
968 PopulateQuotaInfoWithFilter(data_container(), &notifier, filter);
969 PopulateChannelIDInfoWithFilter(data_container(), &notifier, filter);
972 #if defined(ENABLE_EXTENSIONS)
973 const extensions::ExtensionSet* CookiesTreeModel::ExtensionsProtectingNode(
974 const CookieTreeNode& cookie_node) {
975 if (!special_storage_policy_)
976 return NULL;
978 CookieTreeNode::DetailedInfo info = cookie_node.GetDetailedInfo();
980 if (!TypeIsProtected(info.node_type))
981 return NULL;
983 DCHECK(!info.origin.is_empty());
984 return special_storage_policy_->ExtensionsProtectingOrigin(info.origin);
986 #endif
988 void CookiesTreeModel::AddCookiesTreeObserver(Observer* observer) {
989 cookies_observer_list_.AddObserver(observer);
990 // Call super so that TreeNodeModel can notify, too.
991 ui::TreeNodeModel<CookieTreeNode>::AddObserver(observer);
994 void CookiesTreeModel::RemoveCookiesTreeObserver(Observer* observer) {
995 cookies_observer_list_.RemoveObserver(observer);
996 // Call super so that TreeNodeModel doesn't have dead pointers.
997 ui::TreeNodeModel<CookieTreeNode>::RemoveObserver(observer);
1000 void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer* container) {
1001 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1002 PopulateAppCacheInfoWithFilter(container, &notifier, base::string16());
1005 void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer* container) {
1006 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1007 PopulateCookieInfoWithFilter(container, &notifier, base::string16());
1010 void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer* container) {
1011 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1012 PopulateDatabaseInfoWithFilter(container, &notifier, base::string16());
1015 void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer* container) {
1016 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1017 PopulateLocalStorageInfoWithFilter(container, &notifier, base::string16());
1020 void CookiesTreeModel::PopulateSessionStorageInfo(
1021 LocalDataContainer* container) {
1022 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1023 PopulateSessionStorageInfoWithFilter(container, &notifier, base::string16());
1026 void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer* container) {
1027 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1028 PopulateIndexedDBInfoWithFilter(container, &notifier, base::string16());
1031 void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer* container) {
1032 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1033 PopulateFileSystemInfoWithFilter(container, &notifier, base::string16());
1036 void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer* container) {
1037 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1038 PopulateQuotaInfoWithFilter(container, &notifier, base::string16());
1041 void CookiesTreeModel::PopulateChannelIDInfo(
1042 LocalDataContainer* container) {
1043 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1044 PopulateChannelIDInfoWithFilter(container, &notifier, base::string16());
1047 void CookiesTreeModel::PopulateFlashLSOInfo(
1048 LocalDataContainer* container) {
1049 ScopedBatchUpdateNotifier notifier(this, GetRoot());
1050 PopulateFlashLSOInfoWithFilter(container, &notifier, base::string16());
1053 void CookiesTreeModel::PopulateAppCacheInfoWithFilter(
1054 LocalDataContainer* container,
1055 ScopedBatchUpdateNotifier* notifier,
1056 const base::string16& filter) {
1057 using content::AppCacheInfo;
1058 typedef std::map<GURL, std::list<AppCacheInfo> > InfoByOrigin;
1059 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1061 if (container->appcache_info_.empty())
1062 return;
1064 notifier->StartBatchUpdate();
1065 for (InfoByOrigin::iterator origin = container->appcache_info_.begin();
1066 origin != container->appcache_info_.end(); ++origin) {
1067 base::string16 host_node_name = base::UTF8ToUTF16(origin->first.host());
1068 if (filter.empty() ||
1069 (host_node_name.find(filter) != base::string16::npos)) {
1070 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin->first);
1071 CookieTreeAppCachesNode* appcaches_node =
1072 host_node->GetOrCreateAppCachesNode();
1074 for (std::list<AppCacheInfo>::iterator info = origin->second.begin();
1075 info != origin->second.end(); ++info) {
1076 appcaches_node->AddAppCacheNode(
1077 new CookieTreeAppCacheNode(origin->first, info));
1083 void CookiesTreeModel::PopulateCookieInfoWithFilter(
1084 LocalDataContainer* container,
1085 ScopedBatchUpdateNotifier* notifier,
1086 const base::string16& filter) {
1087 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1089 notifier->StartBatchUpdate();
1090 for (CookieList::iterator it = container->cookie_list_.begin();
1091 it != container->cookie_list_.end(); ++it) {
1092 std::string source_string = it->Source();
1093 if (source_string.empty() || !group_by_cookie_source_) {
1094 std::string domain = it->Domain();
1095 if (domain.length() > 1 && domain[0] == '.')
1096 domain = domain.substr(1);
1098 // We treat secure cookies just the same as normal ones.
1099 source_string = std::string(url::kHttpScheme) +
1100 url::kStandardSchemeSeparator + domain + "/";
1103 GURL source(source_string);
1104 if (!filter.size() ||
1105 (CookieTreeHostNode::TitleForUrl(source).find(filter) !=
1106 base::string16::npos)) {
1107 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(source);
1108 CookieTreeCookiesNode* cookies_node =
1109 host_node->GetOrCreateCookiesNode();
1110 CookieTreeCookieNode* new_cookie = new CookieTreeCookieNode(it);
1111 cookies_node->AddCookieNode(new_cookie);
1116 void CookiesTreeModel::PopulateDatabaseInfoWithFilter(
1117 LocalDataContainer* container,
1118 ScopedBatchUpdateNotifier* notifier,
1119 const base::string16& filter) {
1120 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1122 if (container->database_info_list_.empty())
1123 return;
1125 notifier->StartBatchUpdate();
1126 for (DatabaseInfoList::iterator database_info =
1127 container->database_info_list_.begin();
1128 database_info != container->database_info_list_.end();
1129 ++database_info) {
1130 GURL origin(database_info->identifier.ToOrigin());
1132 if (!filter.size() ||
1133 (CookieTreeHostNode::TitleForUrl(origin).find(filter) !=
1134 base::string16::npos)) {
1135 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1136 CookieTreeDatabasesNode* databases_node =
1137 host_node->GetOrCreateDatabasesNode();
1138 databases_node->AddDatabaseNode(
1139 new CookieTreeDatabaseNode(database_info));
1144 void CookiesTreeModel::PopulateLocalStorageInfoWithFilter(
1145 LocalDataContainer* container,
1146 ScopedBatchUpdateNotifier* notifier,
1147 const base::string16& filter) {
1148 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1150 if (container->local_storage_info_list_.empty())
1151 return;
1153 notifier->StartBatchUpdate();
1154 for (LocalStorageInfoList::iterator local_storage_info =
1155 container->local_storage_info_list_.begin();
1156 local_storage_info != container->local_storage_info_list_.end();
1157 ++local_storage_info) {
1158 const GURL& origin(local_storage_info->origin_url);
1160 if (!filter.size() ||
1161 (CookieTreeHostNode::TitleForUrl(origin).find(filter) !=
1162 std::string::npos)) {
1163 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1164 CookieTreeLocalStoragesNode* local_storages_node =
1165 host_node->GetOrCreateLocalStoragesNode();
1166 local_storages_node->AddLocalStorageNode(
1167 new CookieTreeLocalStorageNode(local_storage_info));
1172 void CookiesTreeModel::PopulateSessionStorageInfoWithFilter(
1173 LocalDataContainer* container,
1174 ScopedBatchUpdateNotifier* notifier,
1175 const base::string16& filter) {
1176 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1178 if (container->session_storage_info_list_.empty())
1179 return;
1181 notifier->StartBatchUpdate();
1182 for (LocalStorageInfoList::iterator session_storage_info =
1183 container->session_storage_info_list_.begin();
1184 session_storage_info != container->session_storage_info_list_.end();
1185 ++session_storage_info) {
1186 const GURL& origin = session_storage_info->origin_url;
1188 if (!filter.size() ||
1189 (CookieTreeHostNode::TitleForUrl(origin).find(filter) !=
1190 base::string16::npos)) {
1191 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1192 CookieTreeSessionStoragesNode* session_storages_node =
1193 host_node->GetOrCreateSessionStoragesNode();
1194 session_storages_node->AddSessionStorageNode(
1195 new CookieTreeSessionStorageNode(session_storage_info));
1200 void CookiesTreeModel::PopulateIndexedDBInfoWithFilter(
1201 LocalDataContainer* container,
1202 ScopedBatchUpdateNotifier* notifier,
1203 const base::string16& filter) {
1204 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1206 if (container->indexed_db_info_list_.empty())
1207 return;
1209 notifier->StartBatchUpdate();
1210 for (IndexedDBInfoList::iterator indexed_db_info =
1211 container->indexed_db_info_list_.begin();
1212 indexed_db_info != container->indexed_db_info_list_.end();
1213 ++indexed_db_info) {
1214 const GURL& origin = indexed_db_info->origin_;
1216 if (!filter.size() ||
1217 (CookieTreeHostNode::TitleForUrl(origin).find(filter) !=
1218 base::string16::npos)) {
1219 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1220 CookieTreeIndexedDBsNode* indexed_dbs_node =
1221 host_node->GetOrCreateIndexedDBsNode();
1222 indexed_dbs_node->AddIndexedDBNode(
1223 new CookieTreeIndexedDBNode(indexed_db_info));
1228 void CookiesTreeModel::PopulateChannelIDInfoWithFilter(
1229 LocalDataContainer* container,
1230 ScopedBatchUpdateNotifier* notifier,
1231 const base::string16& filter) {
1232 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1234 if (container->channel_id_list_.empty())
1235 return;
1237 notifier->StartBatchUpdate();
1238 for (ChannelIDList::iterator channel_id_info =
1239 container->channel_id_list_.begin();
1240 channel_id_info != container->channel_id_list_.end();
1241 ++channel_id_info) {
1242 GURL origin(channel_id_info->server_identifier());
1243 if (!origin.is_valid()) {
1244 // Channel ID. Make a valid URL to satisfy the
1245 // CookieTreeRootNode::GetOrCreateHostNode interface.
1246 origin = GURL(std::string(url::kHttpsScheme) +
1247 url::kStandardSchemeSeparator +
1248 channel_id_info->server_identifier() + "/");
1250 base::string16 title = CookieTreeHostNode::TitleForUrl(origin);
1251 if (!filter.size() || title.find(filter) != base::string16::npos) {
1252 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1253 CookieTreeChannelIDsNode* channel_ids_node =
1254 host_node->GetOrCreateChannelIDsNode();
1255 channel_ids_node->AddChannelIDNode(
1256 new CookieTreeChannelIDNode(channel_id_info));
1261 void CookiesTreeModel::PopulateFileSystemInfoWithFilter(
1262 LocalDataContainer* container,
1263 ScopedBatchUpdateNotifier* notifier,
1264 const base::string16& filter) {
1265 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1267 if (container->file_system_info_list_.empty())
1268 return;
1270 notifier->StartBatchUpdate();
1271 for (FileSystemInfoList::iterator file_system_info =
1272 container->file_system_info_list_.begin();
1273 file_system_info != container->file_system_info_list_.end();
1274 ++file_system_info) {
1275 GURL origin(file_system_info->origin);
1277 if (!filter.size() ||
1278 (CookieTreeHostNode::TitleForUrl(origin).find(filter) !=
1279 base::string16::npos)) {
1280 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1281 CookieTreeFileSystemsNode* file_systems_node =
1282 host_node->GetOrCreateFileSystemsNode();
1283 file_systems_node->AddFileSystemNode(
1284 new CookieTreeFileSystemNode(file_system_info));
1289 void CookiesTreeModel::PopulateQuotaInfoWithFilter(
1290 LocalDataContainer* container,
1291 ScopedBatchUpdateNotifier* notifier,
1292 const base::string16& filter) {
1293 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1295 if (container->quota_info_list_.empty())
1296 return;
1298 notifier->StartBatchUpdate();
1299 for (QuotaInfoList::iterator quota_info = container->quota_info_list_.begin();
1300 quota_info != container->quota_info_list_.end();
1301 ++quota_info) {
1302 if (!filter.size() ||
1303 (base::UTF8ToUTF16(quota_info->host).find(filter) !=
1304 base::string16::npos)) {
1305 CookieTreeHostNode* host_node =
1306 root->GetOrCreateHostNode(GURL("http://" + quota_info->host));
1307 host_node->UpdateOrCreateQuotaNode(quota_info);
1312 void CookiesTreeModel::PopulateFlashLSOInfoWithFilter(
1313 LocalDataContainer* container,
1314 ScopedBatchUpdateNotifier* notifier,
1315 const base::string16& filter) {
1316 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
1318 if (container->flash_lso_domain_list_.empty())
1319 return;
1321 std::string filter_utf8 = base::UTF16ToUTF8(filter);
1322 notifier->StartBatchUpdate();
1323 for (std::vector<std::string>::iterator it =
1324 container->flash_lso_domain_list_.begin();
1325 it != container->flash_lso_domain_list_.end(); ++it) {
1326 if (!filter_utf8.size() || it->find(filter_utf8) != std::string::npos) {
1327 // Create a fake origin for GetOrCreateHostNode().
1328 GURL origin("http://" + *it);
1329 CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin);
1330 host_node->GetOrCreateFlashLSONode(*it);
1335 void CookiesTreeModel::NotifyObserverBeginBatch() {
1336 // Only notify the model once if we're batching in a nested manner.
1337 if (batch_update_++ == 0) {
1338 FOR_EACH_OBSERVER(Observer,
1339 cookies_observer_list_,
1340 TreeModelBeginBatch(this));
1344 void CookiesTreeModel::NotifyObserverEndBatch() {
1345 // Only notify the observers if this is the outermost call to EndBatch() if
1346 // called in a nested manner.
1347 if (--batch_update_ == 0) {
1348 FOR_EACH_OBSERVER(Observer,
1349 cookies_observer_list_,
1350 TreeModelEndBatch(this));