| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/browsing_data/cookies_tree_model.h" |
| |
| #include <stddef.h> |
| |
| #include <algorithm> |
| #include <functional> |
| #include <map> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "build/build_config.h" |
| #include "chrome/app/vector_icons/vector_icons.h" |
| #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h" |
| #include "chrome/browser/browsing_data/browsing_data_cache_storage_helper.h" |
| #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h" |
| #include "chrome/browser/browsing_data/browsing_data_database_helper.h" |
| #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" |
| #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" |
| #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" |
| #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" |
| #include "chrome/browser/browsing_data/browsing_data_quota_helper.h" |
| #include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h" |
| #include "chrome/browser/browsing_data/browsing_data_shared_worker_helper.h" |
| #include "chrome/browser/content_settings/cookie_settings_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "chrome/grit/theme_resources.h" |
| #include "components/content_settings/core/browser/cookie_settings.h" |
| #include "content/public/browser/storage_partition.h" |
| #include "content/public/browser/storage_usage_info.h" |
| #include "content/public/common/url_constants.h" |
| #include "extensions/buildflags/buildflags.h" |
| #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| #include "net/cookies/canonical_cookie.h" |
| #include "net/url_request/url_request_context.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/gfx/color_palette.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/gfx/paint_vector_icon.h" |
| #include "ui/resources/grit/ui_resources.h" |
| #include "url/gurl.h" |
| #include "url/origin.h" |
| |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| #include "chrome/browser/extensions/extension_special_storage_policy.h" |
| #include "extensions/common/extension_set.h" |
| #endif |
| |
| namespace { |
| |
| struct NodeTitleComparator { |
| bool operator()(const std::unique_ptr<CookieTreeNode>& lhs, |
| const std::unique_ptr<CookieTreeNode>& rhs) { |
| return lhs->GetTitle() < rhs->GetTitle(); |
| } |
| }; |
| |
| // Comparison functor, for use in CookieTreeRootNode. |
| struct HostNodeComparator { |
| bool operator()(const std::unique_ptr<CookieTreeNode>& lhs, |
| const std::unique_ptr<CookieTreeHostNode>& rhs) { |
| // This comparator is only meant to compare CookieTreeHostNode types. Make |
| // sure we check this, as the static cast below is dangerous if we get the |
| // wrong object type. |
| CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST, |
| lhs->GetDetailedInfo().node_type); |
| CHECK_EQ(CookieTreeNode::DetailedInfo::TYPE_HOST, |
| rhs->GetDetailedInfo().node_type); |
| |
| const CookieTreeHostNode* ltn = |
| static_cast<const CookieTreeHostNode*>(lhs.get()); |
| const CookieTreeHostNode* rtn = rhs.get(); |
| |
| // We want to order by registry controlled domain, so we would get |
| // google.com, ad.google.com, www.google.com, |
| // microsoft.com, ad.microsoft.com. CanonicalizeHost transforms the origins |
| // into a form like google.com.www so that string comparisons work. |
| return ltn->canonicalized_host() < rtn->canonicalized_host(); |
| } |
| }; |
| |
| std::string CanonicalizeHost(const GURL& url) { |
| // The canonicalized representation makes the registry controlled domain come |
| // first, and then adds subdomains in reverse order, e.g. 1.mail.google.com |
| // would become google.com.mail.1, and then a standard string comparison works |
| // to order hosts by registry controlled domain first. Leading dots are |
| // ignored, ".google.com" is the same as "google.com". |
| if (url.SchemeIsFile()) { |
| return std::string(url::kFileScheme) + url::kStandardSchemeSeparator; |
| } |
| |
| std::string host = url.host(); |
| std::string retval = |
| net::registry_controlled_domains::GetDomainAndRegistry( |
| host, |
| net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); |
| if (!retval.length()) // Is an IP address or other special origin. |
| return host; |
| |
| std::string::size_type position = host.rfind(retval); |
| |
| // The host may be the registry controlled domain, in which case fail fast. |
| if (position == 0 || position == std::string::npos) |
| return host; |
| |
| // If host is www.google.com, retval will contain google.com at this point. |
| // Start operating to the left of the registry controlled domain, e.g. in |
| // the www.google.com example, start at index 3. |
| --position; |
| |
| // If position == 0, that means it's a dot; this will be ignored to treat |
| // ".google.com" the same as "google.com". |
| while (position > 0) { |
| retval += std::string("."); |
| // Copy up to the next dot. host[position] is a dot so start after it. |
| std::string::size_type next_dot = host.rfind(".", position - 1); |
| if (next_dot == std::string::npos) { |
| retval += host.substr(0, position); |
| break; |
| } |
| retval += host.substr(next_dot + 1, position - (next_dot + 1)); |
| position = next_dot; |
| } |
| return retval; |
| } |
| |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| bool TypeIsProtected(CookieTreeNode::DetailedInfo::NodeType type) { |
| switch (type) { |
| // Fall through each below cases to return true. |
| case CookieTreeNode::DetailedInfo::TYPE_DATABASE: |
| case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: |
| case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE: |
| case CookieTreeNode::DetailedInfo::TYPE_APPCACHE: |
| case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB: |
| case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM: |
| case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER: |
| case CookieTreeNode::DetailedInfo::TYPE_SHARED_WORKER: |
| case CookieTreeNode::DetailedInfo::TYPE_CACHE_STORAGE: |
| return true; |
| |
| // Fall through each below cases to return false. |
| case CookieTreeNode::DetailedInfo::TYPE_COOKIE: |
| case CookieTreeNode::DetailedInfo::TYPE_QUOTA: |
| case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO: |
| case CookieTreeNode::DetailedInfo::TYPE_MEDIA_LICENSE: |
| return false; |
| default: |
| break; |
| } |
| return false; |
| } |
| #endif |
| |
| // This function returns the local data container associated with a leaf tree |
| // node. The app node is assumed to be 3 levels above the leaf because of the |
| // following structure: |
| // root -> origin -> storage type -> leaf node |
| LocalDataContainer* GetLocalDataContainerForNode(CookieTreeNode* node) { |
| CookieTreeHostNode* host = static_cast<CookieTreeHostNode*>( |
| node->parent()->parent()); |
| CHECK_EQ(host->GetDetailedInfo().node_type, |
| CookieTreeNode::DetailedInfo::TYPE_HOST); |
| return node->GetModel()->data_container(); |
| } |
| |
| } // namespace |
| |
| CookieTreeNode::DetailedInfo::DetailedInfo() : node_type(TYPE_NONE) {} |
| |
| CookieTreeNode::DetailedInfo::DetailedInfo(const DetailedInfo& other) = default; |
| |
| CookieTreeNode::DetailedInfo::~DetailedInfo() {} |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::Init( |
| NodeType type) { |
| DCHECK_EQ(TYPE_NONE, node_type); |
| node_type = type; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitHost( |
| const GURL& origin) { |
| Init(TYPE_HOST); |
| this->origin = url::Origin::Create(origin); |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitCookie( |
| const net::CanonicalCookie* cookie) { |
| Init(TYPE_COOKIE); |
| this->cookie = cookie; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitDatabase( |
| const content::StorageUsageInfo* usage_info) { |
| Init(TYPE_DATABASE); |
| this->usage_info = usage_info; |
| origin = usage_info->origin; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitLocalStorage( |
| const content::StorageUsageInfo* usage_info) { |
| Init(TYPE_LOCAL_STORAGE); |
| this->usage_info = usage_info; |
| origin = usage_info->origin; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitSessionStorage( |
| const content::StorageUsageInfo* usage_info) { |
| Init(TYPE_SESSION_STORAGE); |
| this->usage_info = usage_info; |
| origin = usage_info->origin; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitAppCache( |
| const GURL& origin, |
| const blink::mojom::AppCacheInfo* appcache_info) { |
| Init(TYPE_APPCACHE); |
| this->appcache_info = appcache_info; |
| this->origin = url::Origin::Create(origin); |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitIndexedDB( |
| const content::StorageUsageInfo* usage_info) { |
| Init(TYPE_INDEXED_DB); |
| this->usage_info = usage_info; |
| this->origin = usage_info->origin; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitFileSystem( |
| const BrowsingDataFileSystemHelper::FileSystemInfo* file_system_info) { |
| Init(TYPE_FILE_SYSTEM); |
| this->file_system_info = file_system_info; |
| this->origin = file_system_info->origin; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitQuota( |
| const BrowsingDataQuotaHelper::QuotaInfo* quota_info) { |
| Init(TYPE_QUOTA); |
| this->quota_info = quota_info; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitServiceWorker( |
| const content::StorageUsageInfo* usage_info) { |
| Init(TYPE_SERVICE_WORKER); |
| this->usage_info = usage_info; |
| this->origin = usage_info->origin; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitSharedWorker( |
| const BrowsingDataSharedWorkerHelper::SharedWorkerInfo* |
| shared_worker_info) { |
| Init(TYPE_SHARED_WORKER); |
| this->shared_worker_info = shared_worker_info; |
| this->origin = url::Origin::Create(shared_worker_info->worker.GetOrigin()); |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitCacheStorage( |
| const content::StorageUsageInfo* usage_info) { |
| Init(TYPE_CACHE_STORAGE); |
| this->usage_info = usage_info; |
| this->origin = usage_info->origin; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitFlashLSO( |
| const std::string& flash_lso_domain) { |
| Init(TYPE_FLASH_LSO); |
| this->flash_lso_domain = flash_lso_domain; |
| return *this; |
| } |
| |
| CookieTreeNode::DetailedInfo& CookieTreeNode::DetailedInfo::InitMediaLicense( |
| const BrowsingDataMediaLicenseHelper::MediaLicenseInfo* |
| media_license_info) { |
| Init(TYPE_MEDIA_LICENSE); |
| this->media_license_info = media_license_info; |
| this->origin = url::Origin::Create(media_license_info->origin); |
| return *this; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeNode, public: |
| |
| void CookieTreeNode::DeleteStoredObjects() { |
| for (const auto& child : children()) |
| child->DeleteStoredObjects(); |
| } |
| |
| CookiesTreeModel* CookieTreeNode::GetModel() const { |
| if (parent()) |
| return parent()->GetModel(); |
| return nullptr; |
| } |
| |
| int64_t CookieTreeNode::InclusiveSize() const { |
| return 0; |
| } |
| |
| int CookieTreeNode::NumberOfCookies() const { |
| int number_of_cookies = 0; |
| for (int i = 0; i < this->child_count(); ++i) { |
| number_of_cookies += this->GetChild(i)->NumberOfCookies(); |
| } |
| return number_of_cookies; |
| } |
| |
| void CookieTreeNode::AddChildSortedByTitle( |
| std::unique_ptr<CookieTreeNode> new_child) { |
| DCHECK(new_child); |
| auto iter = std::lower_bound(children().begin(), children().end(), new_child, |
| NodeTitleComparator()); |
| GetModel()->Add(this, std::move(new_child), iter - children().begin()); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeCookieNode |
| |
| class CookieTreeCookieNode : public CookieTreeNode { |
| public: |
| friend class CookieTreeCookiesNode; |
| |
| // The cookie should remain valid at least as long as the |
| // CookieTreeCookieNode is valid. |
| explicit CookieTreeCookieNode( |
| std::list<net::CanonicalCookie>::iterator cookie) |
| : CookieTreeNode(base::UTF8ToUTF16(cookie->Name())), cookie_(cookie) {} |
| |
| ~CookieTreeCookieNode() override {} |
| |
| // CookieTreeNode methods: |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| container->cookie_helper_->DeleteCookie(*cookie_); |
| container->cookie_list_.erase(cookie_); |
| } |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitCookie(&*cookie_); |
| } |
| |
| int NumberOfCookies() const override { return 1; } |
| |
| private: |
| // |cookie_| is expected to remain valid as long as the CookieTreeCookieNode |
| // is valid. |
| std::list<net::CanonicalCookie>::iterator cookie_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeCookieNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeAppCacheNode |
| |
| class CookieTreeAppCacheNode : public CookieTreeNode { |
| public: |
| friend class CookieTreeAppCachesNode; |
| |
| // |appcache_info| should remain valid at least as long as the |
| // CookieTreeAppCacheNode is valid. |
| explicit CookieTreeAppCacheNode( |
| const url::Origin& origin, |
| std::list<blink::mojom::AppCacheInfo>::iterator appcache_info) |
| : CookieTreeNode(base::UTF8ToUTF16(appcache_info->manifest_url.spec())), |
| origin_(origin), |
| appcache_info_(appcache_info) {} |
| ~CookieTreeAppCacheNode() override {} |
| |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| |
| if (container) { |
| DCHECK(container->appcache_helper_.get()); |
| container->appcache_helper_->DeleteAppCacheGroup( |
| appcache_info_->manifest_url); |
| container->appcache_info_[origin_].erase(appcache_info_); |
| } |
| } |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitAppCache(origin_.GetURL(), &*appcache_info_); |
| } |
| |
| int64_t InclusiveSize() const override { return appcache_info_->size; } |
| |
| private: |
| url::Origin origin_; |
| std::list<blink::mojom::AppCacheInfo>::iterator appcache_info_; |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeAppCacheNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeDatabaseNode |
| |
| class CookieTreeDatabaseNode : public CookieTreeNode { |
| public: |
| friend class CookieTreeDatabasesNode; |
| |
| // |usage_info| should remain valid at least as long as the |
| // CookieTreeDatabaseNode is valid. |
| explicit CookieTreeDatabaseNode( |
| std::list<content::StorageUsageInfo>::iterator usage_info) |
| : CookieTreeNode(base::UTF8ToUTF16(usage_info->origin.Serialize())), |
| usage_info_(usage_info) {} |
| |
| ~CookieTreeDatabaseNode() override {} |
| |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| |
| if (container) { |
| container->database_helper_->DeleteDatabase(usage_info_->origin); |
| container->database_info_list_.erase(usage_info_); |
| } |
| } |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitDatabase(&*usage_info_); |
| } |
| |
| int64_t InclusiveSize() const override { |
| return usage_info_->total_size_bytes; |
| } |
| |
| private: |
| // |database_info_| is expected to remain valid as long as the |
| // CookieTreeDatabaseNode is valid. |
| std::list<content::StorageUsageInfo>::iterator usage_info_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeDatabaseNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeLocalStorageNode |
| |
| class CookieTreeLocalStorageNode : public CookieTreeNode { |
| public: |
| // |usage_info| should remain valid at least as long as the |
| // CookieTreeLocalStorageNode is valid. |
| explicit CookieTreeLocalStorageNode( |
| std::list<content::StorageUsageInfo>::iterator local_storage_info) |
| : CookieTreeNode( |
| base::UTF8ToUTF16(local_storage_info->origin.Serialize())), |
| local_storage_info_(local_storage_info) {} |
| |
| ~CookieTreeLocalStorageNode() override {} |
| |
| // CookieTreeNode methods: |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| |
| if (container) { |
| container->local_storage_helper_->DeleteOrigin( |
| local_storage_info_->origin, base::DoNothing()); |
| container->local_storage_info_list_.erase(local_storage_info_); |
| } |
| } |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitLocalStorage(&*local_storage_info_); |
| } |
| |
| int64_t InclusiveSize() const override { |
| return local_storage_info_->total_size_bytes; |
| } |
| |
| private: |
| // |local_storage_info_| is expected to remain valid as long as the |
| // CookieTreeLocalStorageNode is valid. |
| std::list<content::StorageUsageInfo>::iterator local_storage_info_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeLocalStorageNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeSessionStorageNode |
| |
| class CookieTreeSessionStorageNode : public CookieTreeNode { |
| public: |
| // |session_storage_info| should remain valid at least as long as the |
| // CookieTreeSessionStorageNode is valid. |
| explicit CookieTreeSessionStorageNode( |
| std::list<content::StorageUsageInfo>::iterator session_storage_info) |
| : CookieTreeNode( |
| base::UTF8ToUTF16(session_storage_info->origin.Serialize())), |
| session_storage_info_(session_storage_info) {} |
| |
| ~CookieTreeSessionStorageNode() override {} |
| |
| // CookieTreeNode methods: |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| |
| if (container) { |
| // TODO(rsesek): There's no easy way to get the namespace_id for a session |
| // storage, nor is there an easy way to clear session storage just by |
| // origin. This is probably okay since session storage is not persistent. |
| // http://crbug.com/168996 |
| container->session_storage_info_list_.erase(session_storage_info_); |
| } |
| } |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitSessionStorage(&*session_storage_info_); |
| } |
| |
| private: |
| // |session_storage_info_| is expected to remain valid as long as the |
| // CookieTreeSessionStorageNode is valid. |
| std::list<content::StorageUsageInfo>::iterator session_storage_info_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeSessionStorageNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeIndexedDBNode |
| |
| class CookieTreeIndexedDBNode : public CookieTreeNode { |
| public: |
| // |usage_info| should remain valid at least as long as the |
| // CookieTreeIndexedDBNode is valid. |
| explicit CookieTreeIndexedDBNode( |
| std::list<content::StorageUsageInfo>::iterator usage_info) |
| : CookieTreeNode(base::UTF8ToUTF16(usage_info->origin.Serialize())), |
| usage_info_(usage_info) {} |
| |
| ~CookieTreeIndexedDBNode() override {} |
| |
| // CookieTreeNode methods: |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| |
| if (container) { |
| container->indexed_db_helper_->DeleteIndexedDB( |
| usage_info_->origin.GetURL()); |
| container->indexed_db_info_list_.erase(usage_info_); |
| } |
| } |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitIndexedDB(&*usage_info_); |
| } |
| |
| int64_t InclusiveSize() const override { |
| return usage_info_->total_size_bytes; |
| } |
| |
| private: |
| // |usage_info_| is expected to remain valid as long as the |
| // CookieTreeIndexedDBNode is valid. |
| std::list<content::StorageUsageInfo>::iterator usage_info_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeIndexedDBNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeFileSystemNode |
| |
| class CookieTreeFileSystemNode : public CookieTreeNode { |
| public: |
| friend class CookieTreeFileSystemsNode; |
| |
| // |file_system_info| should remain valid at least as long as the |
| // CookieTreeFileSystemNode is valid. |
| explicit CookieTreeFileSystemNode( |
| std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator |
| file_system_info) |
| : CookieTreeNode(base::UTF8ToUTF16(file_system_info->origin.Serialize())), |
| file_system_info_(file_system_info) {} |
| ~CookieTreeFileSystemNode() override {} |
| |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| |
| if (container) { |
| container->file_system_helper_->DeleteFileSystemOrigin( |
| file_system_info_->origin); |
| container->file_system_info_list_.erase(file_system_info_); |
| } |
| } |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitFileSystem(&*file_system_info_); |
| } |
| |
| int64_t InclusiveSize() const override { |
| int64_t size = 0; |
| for (auto const& usage : file_system_info_->usage_map) { |
| size += usage.second; |
| } |
| return size; |
| } |
| |
| private: |
| // file_system_info_ expected to remain valid as long as the |
| // CookieTreeFileSystemNode is valid. |
| std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator |
| file_system_info_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeFileSystemNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeQuotaNode |
| |
| class CookieTreeQuotaNode : public CookieTreeNode { |
| public: |
| // |quota_info| should remain valid at least as long as the |
| // CookieTreeQuotaNode is valid. |
| explicit CookieTreeQuotaNode( |
| std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info) |
| : CookieTreeNode(base::UTF8ToUTF16(quota_info->host)), |
| quota_info_(quota_info) {} |
| |
| ~CookieTreeQuotaNode() override {} |
| |
| void DeleteStoredObjects() override { |
| // Calling this function may cause unexpected over-quota state of origin. |
| // However, it'll caused no problem, just prevent usage growth of the |
| // origin. |
| LocalDataContainer* container = GetModel()->data_container(); |
| |
| if (container) { |
| container->quota_helper_->RevokeHostQuota(quota_info_->host); |
| container->quota_info_list_.erase(quota_info_); |
| } |
| } |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitQuota(&*quota_info_); |
| } |
| |
| private: |
| // |quota_info_| is expected to remain valid as long as the |
| // CookieTreeQuotaNode is valid. |
| std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeQuotaNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeServiceWorkerNode |
| |
| class CookieTreeServiceWorkerNode : public CookieTreeNode { |
| public: |
| // |usage_info| should remain valid at least as long as the |
| // CookieTreeServiceWorkerNode is valid. |
| explicit CookieTreeServiceWorkerNode( |
| std::list<content::StorageUsageInfo>::iterator usage_info) |
| : CookieTreeNode(base::UTF8ToUTF16(usage_info->origin.Serialize())), |
| usage_info_(usage_info) {} |
| |
| ~CookieTreeServiceWorkerNode() override {} |
| |
| // CookieTreeNode methods: |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| |
| if (container) { |
| container->service_worker_helper_->DeleteServiceWorkers( |
| usage_info_->origin.GetURL()); |
| container->service_worker_info_list_.erase(usage_info_); |
| } |
| } |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitServiceWorker(&*usage_info_); |
| } |
| |
| int64_t InclusiveSize() const override { |
| return usage_info_->total_size_bytes; |
| } |
| |
| private: |
| // |usage_info_| is expected to remain valid as long as the |
| // CookieTreeServiceWorkerNode is valid. |
| std::list<content::StorageUsageInfo>::iterator usage_info_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeServiceWorkerNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeSharedWorkerNode |
| |
| class CookieTreeSharedWorkerNode : public CookieTreeNode { |
| public: |
| // |shared_worker_info| should remain valid at least as long as the |
| // CookieTreeSharedWorkerNode is valid. |
| explicit CookieTreeSharedWorkerNode( |
| std::list<BrowsingDataSharedWorkerHelper::SharedWorkerInfo>::iterator |
| shared_worker_info) |
| : CookieTreeNode(base::UTF8ToUTF16(shared_worker_info->worker.spec())), |
| shared_worker_info_(shared_worker_info) {} |
| |
| ~CookieTreeSharedWorkerNode() override {} |
| |
| // CookieTreeNode methods: |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| |
| if (container) { |
| container->shared_worker_helper_->DeleteSharedWorker( |
| shared_worker_info_->worker, shared_worker_info_->name, |
| shared_worker_info_->constructor_origin); |
| container->shared_worker_info_list_.erase(shared_worker_info_); |
| } |
| } |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitSharedWorker(&*shared_worker_info_); |
| } |
| |
| private: |
| // |shared_worker_info_| is expected to remain valid as long as the |
| // CookieTreeSharedWorkerNode is valid. |
| std::list<BrowsingDataSharedWorkerHelper::SharedWorkerInfo>::iterator |
| shared_worker_info_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeSharedWorkerNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeCacheStorageNode |
| |
| class CookieTreeCacheStorageNode : public CookieTreeNode { |
| public: |
| // |usage_info| should remain valid at least as long as the |
| // CookieTreeCacheStorageNode is valid. |
| explicit CookieTreeCacheStorageNode( |
| std::list<content::StorageUsageInfo>::iterator usage_info) |
| : CookieTreeNode(base::UTF8ToUTF16(usage_info->origin.Serialize())), |
| usage_info_(usage_info) {} |
| |
| ~CookieTreeCacheStorageNode() override {} |
| |
| // CookieTreeNode methods: |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| |
| if (container) { |
| container->cache_storage_helper_->DeleteCacheStorage( |
| usage_info_->origin.GetURL()); |
| container->cache_storage_info_list_.erase(usage_info_); |
| } |
| } |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitCacheStorage(&*usage_info_); |
| } |
| |
| int64_t InclusiveSize() const override { |
| return usage_info_->total_size_bytes; |
| } |
| |
| private: |
| // |usage_info_| is expected to remain valid as long as the |
| // CookieTreeCacheStorageNode is valid. |
| std::list<content::StorageUsageInfo>::iterator usage_info_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeCacheStorageNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeMediaLicenseNode |
| |
| class CookieTreeMediaLicenseNode : public CookieTreeNode { |
| public: |
| friend class CookieTreeMediaLicensesNode; |
| |
| // |media_license_info| is expected to remain valid as long as the |
| // CookieTreeMediaLicenseNode is valid. |
| explicit CookieTreeMediaLicenseNode( |
| const std::list<BrowsingDataMediaLicenseHelper::MediaLicenseInfo>:: |
| iterator media_license_info) |
| : CookieTreeNode(base::UTF8ToUTF16(media_license_info->origin.spec())), |
| media_license_info_(media_license_info) {} |
| |
| ~CookieTreeMediaLicenseNode() override {} |
| |
| void DeleteStoredObjects() override { |
| LocalDataContainer* container = GetLocalDataContainerForNode(this); |
| |
| if (container) { |
| container->media_license_helper_->DeleteMediaLicenseOrigin( |
| media_license_info_->origin); |
| container->media_license_info_list_.erase(media_license_info_); |
| } |
| } |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitMediaLicense(&*media_license_info_); |
| } |
| |
| int64_t InclusiveSize() const override { return media_license_info_->size; } |
| |
| private: |
| // |media_license_info_| is expected to remain valid as long as the |
| // CookieTreeMediaLicenseNode is valid. |
| std::list<BrowsingDataMediaLicenseHelper::MediaLicenseInfo>::iterator |
| media_license_info_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeMediaLicenseNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeRootNode, public: |
| |
| CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel* model) |
| : model_(model) { |
| } |
| |
| CookieTreeRootNode::~CookieTreeRootNode() {} |
| |
| CookieTreeHostNode* CookieTreeRootNode::GetOrCreateHostNode(const GURL& url) { |
| std::unique_ptr<CookieTreeHostNode> host_node = |
| std::make_unique<CookieTreeHostNode>(url); |
| |
| // First see if there is an existing match. |
| auto host_node_iterator = std::lower_bound( |
| children().begin(), children().end(), host_node, HostNodeComparator()); |
| if (host_node_iterator != children().end() && |
| CookieTreeHostNode::TitleForUrl(url) == |
| (*host_node_iterator)->GetTitle()) { |
| CookieTreeHostNode* found_node = |
| static_cast<CookieTreeHostNode*>(host_node_iterator->get()); |
| // Cookies node will create fake url with http scheme, so update the url if |
| // there is a more valid url. |
| if (found_node->GetDetailedInfo().origin.GetURL().SchemeIs( |
| url::kHttpScheme) && |
| url.SchemeIs(url::kHttpsScheme)) |
| found_node->UpdateHostUrl(url); |
| return found_node; |
| } |
| // Node doesn't exist, insert the new one into the (ordered) children. |
| DCHECK(model_); |
| return static_cast<CookieTreeHostNode*>(model_->Add( |
| this, std::move(host_node), (host_node_iterator - children().begin()))); |
| } |
| |
| CookiesTreeModel* CookieTreeRootNode::GetModel() const { |
| return model_; |
| } |
| |
| CookieTreeNode::DetailedInfo CookieTreeRootNode::GetDetailedInfo() const { |
| return DetailedInfo().Init(DetailedInfo::TYPE_ROOT); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeCookiesNode |
| |
| class CookieTreeCookiesNode : public CookieTreeNode { |
| public: |
| CookieTreeCookiesNode() |
| : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_COOKIES)) {} |
| |
| ~CookieTreeCookiesNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_COOKIES); |
| } |
| |
| void AddCookieNode(std::unique_ptr<CookieTreeCookieNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeCookiesNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeCollectionNode |
| |
| class CookieTreeCollectionNode : public CookieTreeNode { |
| public: |
| explicit CookieTreeCollectionNode(const base::string16& title) |
| : CookieTreeNode(title) {} |
| |
| ~CookieTreeCollectionNode() override {} |
| |
| int64_t InclusiveSize() const final { |
| int64_t total_size = 0; |
| for (int i = 0; i < this->child_count(); ++i) { |
| total_size += this->GetChild(i)->InclusiveSize(); |
| } |
| return total_size; |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeCollectionNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeAppCachesNode |
| |
| class CookieTreeAppCachesNode : public CookieTreeCollectionNode { |
| public: |
| CookieTreeAppCachesNode() |
| : CookieTreeCollectionNode( |
| l10n_util::GetStringUTF16(IDS_COOKIES_APPLICATION_CACHES)) {} |
| |
| ~CookieTreeAppCachesNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_APPCACHES); |
| } |
| |
| void AddAppCacheNode(std::unique_ptr<CookieTreeAppCacheNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeAppCachesNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeDatabasesNode |
| |
| class CookieTreeDatabasesNode : public CookieTreeCollectionNode { |
| public: |
| CookieTreeDatabasesNode() |
| : CookieTreeCollectionNode( |
| l10n_util::GetStringUTF16(IDS_COOKIES_WEB_DATABASES)) {} |
| |
| ~CookieTreeDatabasesNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_DATABASES); |
| } |
| |
| void AddDatabaseNode(std::unique_ptr<CookieTreeDatabaseNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeDatabasesNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeLocalStoragesNode |
| |
| class CookieTreeLocalStoragesNode : public CookieTreeCollectionNode { |
| public: |
| CookieTreeLocalStoragesNode() |
| : CookieTreeCollectionNode( |
| l10n_util::GetStringUTF16(IDS_COOKIES_LOCAL_STORAGE)) {} |
| |
| ~CookieTreeLocalStoragesNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_LOCAL_STORAGES); |
| } |
| |
| void AddLocalStorageNode(std::unique_ptr<CookieTreeLocalStorageNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeLocalStoragesNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeSessionStoragesNode |
| |
| class CookieTreeSessionStoragesNode : public CookieTreeNode { |
| public: |
| CookieTreeSessionStoragesNode() |
| : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SESSION_STORAGE)) { |
| } |
| |
| ~CookieTreeSessionStoragesNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_SESSION_STORAGES); |
| } |
| |
| void AddSessionStorageNode( |
| std::unique_ptr<CookieTreeSessionStorageNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeSessionStoragesNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeIndexedDBsNode |
| |
| class CookieTreeIndexedDBsNode : public CookieTreeCollectionNode { |
| public: |
| CookieTreeIndexedDBsNode() |
| : CookieTreeCollectionNode( |
| l10n_util::GetStringUTF16(IDS_COOKIES_INDEXED_DBS)) {} |
| |
| ~CookieTreeIndexedDBsNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_INDEXED_DBS); |
| } |
| |
| void AddIndexedDBNode(std::unique_ptr<CookieTreeIndexedDBNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeIndexedDBsNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeFileSystemsNode |
| |
| class CookieTreeFileSystemsNode : public CookieTreeCollectionNode { |
| public: |
| CookieTreeFileSystemsNode() |
| : CookieTreeCollectionNode( |
| l10n_util::GetStringUTF16(IDS_COOKIES_FILE_SYSTEMS)) {} |
| |
| ~CookieTreeFileSystemsNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_FILE_SYSTEMS); |
| } |
| |
| void AddFileSystemNode(std::unique_ptr<CookieTreeFileSystemNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeFileSystemsNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeServiceWorkersNode |
| |
| class CookieTreeServiceWorkersNode : public CookieTreeCollectionNode { |
| public: |
| CookieTreeServiceWorkersNode() |
| : CookieTreeCollectionNode( |
| l10n_util::GetStringUTF16(IDS_COOKIES_SERVICE_WORKERS)) {} |
| |
| ~CookieTreeServiceWorkersNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_SERVICE_WORKERS); |
| } |
| |
| void AddServiceWorkerNode( |
| std::unique_ptr<CookieTreeServiceWorkerNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeServiceWorkersNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeSharedWorkersNode |
| |
| class CookieTreeSharedWorkersNode : public CookieTreeNode { |
| public: |
| CookieTreeSharedWorkersNode() |
| : CookieTreeNode(l10n_util::GetStringUTF16(IDS_COOKIES_SHARED_WORKERS)) {} |
| |
| ~CookieTreeSharedWorkersNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_SHARED_WORKERS); |
| } |
| |
| void AddSharedWorkerNode(std::unique_ptr<CookieTreeSharedWorkerNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeSharedWorkersNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeCacheStoragesNode |
| |
| class CookieTreeCacheStoragesNode : public CookieTreeCollectionNode { |
| public: |
| CookieTreeCacheStoragesNode() |
| : CookieTreeCollectionNode( |
| l10n_util::GetStringUTF16(IDS_COOKIES_CACHE_STORAGE)) {} |
| |
| ~CookieTreeCacheStoragesNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_CACHE_STORAGES); |
| } |
| |
| void AddCacheStorageNode(std::unique_ptr<CookieTreeCacheStorageNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeCacheStoragesNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeFlashLSONode |
| |
| class CookieTreeFlashLSONode : public CookieTreeNode { |
| public: |
| explicit CookieTreeFlashLSONode(const std::string& domain) |
| : domain_(domain) {} |
| ~CookieTreeFlashLSONode() override {} |
| |
| // CookieTreeNode methods: |
| void DeleteStoredObjects() override { |
| // We are one level below the host node. |
| CookieTreeHostNode* host = static_cast<CookieTreeHostNode*>(parent()); |
| CHECK_EQ(host->GetDetailedInfo().node_type, |
| CookieTreeNode::DetailedInfo::TYPE_HOST); |
| LocalDataContainer* container = GetModel()->data_container(); |
| container->flash_lso_helper_->DeleteFlashLSOsForSite(domain_, |
| base::OnceClosure()); |
| auto entry = std::find(container->flash_lso_domain_list_.begin(), |
| container->flash_lso_domain_list_.end(), domain_); |
| container->flash_lso_domain_list_.erase(entry); |
| } |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().InitFlashLSO(domain_); |
| } |
| |
| private: |
| std::string domain_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeFlashLSONode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeMediaLicensesNode |
| |
| class CookieTreeMediaLicensesNode : public CookieTreeCollectionNode { |
| public: |
| CookieTreeMediaLicensesNode() |
| : CookieTreeCollectionNode( |
| l10n_util::GetStringUTF16(IDS_COOKIES_MEDIA_LICENSES)) {} |
| |
| ~CookieTreeMediaLicensesNode() override {} |
| |
| DetailedInfo GetDetailedInfo() const override { |
| return DetailedInfo().Init(DetailedInfo::TYPE_MEDIA_LICENSES); |
| } |
| |
| void AddMediaLicenseNode(std::unique_ptr<CookieTreeMediaLicenseNode> child) { |
| AddChildSortedByTitle(std::move(child)); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(CookieTreeMediaLicensesNode); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookieTreeHostNode, public: |
| |
| // static |
| base::string16 CookieTreeHostNode::TitleForUrl(const GURL& url) { |
| const std::string file_origin_node_name( |
| std::string(url::kFileScheme) + url::kStandardSchemeSeparator); |
| return base::UTF8ToUTF16(url.SchemeIsFile() |
| ? file_origin_node_name |
| : url::Origin::Create(url).host()); |
| } |
| |
| CookieTreeHostNode::CookieTreeHostNode(const GURL& url) |
| : CookieTreeNode(TitleForUrl(url)), |
| url_(url), |
| canonicalized_host_(CanonicalizeHost(url)) {} |
| |
| CookieTreeHostNode::~CookieTreeHostNode() {} |
| |
| std::string CookieTreeHostNode::GetHost() const { |
| const std::string file_origin_node_name( |
| std::string(url::kFileScheme) + url::kStandardSchemeSeparator); |
| return url_.SchemeIsFile() ? file_origin_node_name : url_.host(); |
| } |
| |
| void CookieTreeHostNode::UpdateHostUrl(const GURL& url) { |
| this->url_ = url; |
| } |
| |
| CookieTreeNode::DetailedInfo CookieTreeHostNode::GetDetailedInfo() const { |
| return DetailedInfo().InitHost(url_); |
| } |
| |
| CookieTreeCookiesNode* CookieTreeHostNode::GetOrCreateCookiesNode() { |
| if (cookies_child_) |
| return cookies_child_; |
| cookies_child_ = new CookieTreeCookiesNode; |
| AddChildSortedByTitle(base::WrapUnique(cookies_child_)); |
| return cookies_child_; |
| } |
| |
| CookieTreeDatabasesNode* CookieTreeHostNode::GetOrCreateDatabasesNode() { |
| if (databases_child_) |
| return databases_child_; |
| databases_child_ = new CookieTreeDatabasesNode; |
| AddChildSortedByTitle(base::WrapUnique(databases_child_)); |
| return databases_child_; |
| } |
| |
| CookieTreeLocalStoragesNode* |
| CookieTreeHostNode::GetOrCreateLocalStoragesNode() { |
| if (local_storages_child_) |
| return local_storages_child_; |
| local_storages_child_ = new CookieTreeLocalStoragesNode; |
| AddChildSortedByTitle(base::WrapUnique(local_storages_child_)); |
| return local_storages_child_; |
| } |
| |
| CookieTreeSessionStoragesNode* |
| CookieTreeHostNode::GetOrCreateSessionStoragesNode() { |
| if (session_storages_child_) |
| return session_storages_child_; |
| session_storages_child_ = new CookieTreeSessionStoragesNode; |
| AddChildSortedByTitle(base::WrapUnique(session_storages_child_)); |
| return session_storages_child_; |
| } |
| |
| CookieTreeAppCachesNode* CookieTreeHostNode::GetOrCreateAppCachesNode() { |
| if (appcaches_child_) |
| return appcaches_child_; |
| appcaches_child_ = new CookieTreeAppCachesNode; |
| AddChildSortedByTitle(base::WrapUnique(appcaches_child_)); |
| return appcaches_child_; |
| } |
| |
| CookieTreeIndexedDBsNode* CookieTreeHostNode::GetOrCreateIndexedDBsNode() { |
| if (indexed_dbs_child_) |
| return indexed_dbs_child_; |
| indexed_dbs_child_ = new CookieTreeIndexedDBsNode; |
| AddChildSortedByTitle(base::WrapUnique(indexed_dbs_child_)); |
| return indexed_dbs_child_; |
| } |
| |
| CookieTreeFileSystemsNode* CookieTreeHostNode::GetOrCreateFileSystemsNode() { |
| if (file_systems_child_) |
| return file_systems_child_; |
| file_systems_child_ = new CookieTreeFileSystemsNode; |
| AddChildSortedByTitle(base::WrapUnique(file_systems_child_)); |
| return file_systems_child_; |
| } |
| |
| CookieTreeQuotaNode* CookieTreeHostNode::UpdateOrCreateQuotaNode( |
| std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info) { |
| if (quota_child_) |
| return quota_child_; |
| quota_child_ = new CookieTreeQuotaNode(quota_info); |
| AddChildSortedByTitle(base::WrapUnique(quota_child_)); |
| return quota_child_; |
| } |
| |
| CookieTreeServiceWorkersNode* |
| CookieTreeHostNode::GetOrCreateServiceWorkersNode() { |
| if (service_workers_child_) |
| return service_workers_child_; |
| service_workers_child_ = new CookieTreeServiceWorkersNode; |
| AddChildSortedByTitle(base::WrapUnique(service_workers_child_)); |
| return service_workers_child_; |
| } |
| |
| CookieTreeSharedWorkersNode* |
| CookieTreeHostNode::GetOrCreateSharedWorkersNode() { |
| if (shared_workers_child_) |
| return shared_workers_child_; |
| shared_workers_child_ = new CookieTreeSharedWorkersNode; |
| AddChildSortedByTitle(base::WrapUnique(shared_workers_child_)); |
| return shared_workers_child_; |
| } |
| |
| CookieTreeCacheStoragesNode* |
| CookieTreeHostNode::GetOrCreateCacheStoragesNode() { |
| if (cache_storages_child_) |
| return cache_storages_child_; |
| cache_storages_child_ = new CookieTreeCacheStoragesNode; |
| AddChildSortedByTitle(base::WrapUnique(cache_storages_child_)); |
| return cache_storages_child_; |
| } |
| |
| CookieTreeFlashLSONode* CookieTreeHostNode::GetOrCreateFlashLSONode( |
| const std::string& domain) { |
| DCHECK_EQ(GetHost(), domain); |
| if (flash_lso_child_) |
| return flash_lso_child_; |
| flash_lso_child_ = new CookieTreeFlashLSONode(domain); |
| AddChildSortedByTitle(base::WrapUnique(flash_lso_child_)); |
| return flash_lso_child_; |
| } |
| |
| CookieTreeMediaLicensesNode* |
| CookieTreeHostNode::GetOrCreateMediaLicensesNode() { |
| if (media_licenses_child_) |
| return media_licenses_child_; |
| media_licenses_child_ = new CookieTreeMediaLicensesNode(); |
| AddChildSortedByTitle(base::WrapUnique(media_licenses_child_)); |
| return media_licenses_child_; |
| } |
| |
| void CookieTreeHostNode::CreateContentException( |
| content_settings::CookieSettings* cookie_settings, |
| ContentSetting setting) const { |
| DCHECK(setting == CONTENT_SETTING_ALLOW || |
| setting == CONTENT_SETTING_BLOCK || |
| setting == CONTENT_SETTING_SESSION_ONLY); |
| if (CanCreateContentException()) { |
| cookie_settings->ResetCookieSetting(url_); |
| cookie_settings->SetCookieSetting(url_, setting); |
| } |
| } |
| |
| bool CookieTreeHostNode::CanCreateContentException() const { |
| return !url_.SchemeIsFile(); |
| } |
| |
| int64_t CookieTreeHostNode::InclusiveSize() const { |
| int64_t total_size = 0; |
| for (int i = 0; i < this->child_count(); ++i) { |
| total_size += this->GetChild(i)->InclusiveSize(); |
| } |
| return total_size; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // ScopedBatchUpdateNotifier |
| CookiesTreeModel::ScopedBatchUpdateNotifier::ScopedBatchUpdateNotifier( |
| CookiesTreeModel* model, |
| CookieTreeNode* node) |
| : model_(model), node_(node) { |
| model_->RecordBatchSeen(); |
| } |
| |
| CookiesTreeModel::ScopedBatchUpdateNotifier::~ScopedBatchUpdateNotifier() { |
| if (batch_in_progress_) { |
| model_->NotifyObserverTreeNodeChanged(node_); |
| model_->NotifyObserverEndBatch(); |
| } else { |
| // If no batch started, and this is the last batch, give the model a chance |
| // to send out a final notification. |
| model_->MaybeNotifyBatchesEnded(); |
| } |
| } |
| |
| void CookiesTreeModel::ScopedBatchUpdateNotifier::StartBatchUpdate() { |
| if (!batch_in_progress_) { |
| model_->NotifyObserverBeginBatch(); |
| batch_in_progress_ = true; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookiesTreeModel, public: |
| CookiesTreeModel::CookiesTreeModel( |
| std::unique_ptr<LocalDataContainer> data_container, |
| ExtensionSpecialStoragePolicy* special_storage_policy) |
| : ui::TreeNodeModel<CookieTreeNode>( |
| std::make_unique<CookieTreeRootNode>(this)), |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| special_storage_policy_(special_storage_policy), |
| #endif |
| data_container_(std::move(data_container)) { |
| data_container_->Init(this); |
| } |
| |
| CookiesTreeModel::~CookiesTreeModel() { |
| } |
| |
| // static |
| int CookiesTreeModel::GetSendForMessageID(const net::CanonicalCookie& cookie) { |
| if (cookie.IsSecure()) { |
| if (cookie.SameSite() != net::CookieSameSite::NO_RESTRICTION) |
| return IDS_COOKIES_COOKIE_SENDFOR_SECURE_SAME_SITE; |
| return IDS_COOKIES_COOKIE_SENDFOR_SECURE; |
| } |
| if (cookie.SameSite() != net::CookieSameSite::NO_RESTRICTION) |
| return IDS_COOKIES_COOKIE_SENDFOR_SAME_SITE; |
| return IDS_COOKIES_COOKIE_SENDFOR_ANY; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // CookiesTreeModel, TreeModel methods (public): |
| |
| // TreeModel methods: |
| // Returns the set of icons for the nodes in the tree. You only need override |
| // this if you don't want to use the default folder icons. |
| void CookiesTreeModel::GetIcons(std::vector<gfx::ImageSkia>* icons) { |
| icons->push_back( |
| gfx::CreateVectorIcon(kCookieIcon, 18, gfx::kChromeIconGrey)); |
| icons->push_back(*ui::ResourceBundle::GetSharedInstance() |
| .GetNativeImageNamed(IDR_COOKIE_STORAGE_ICON) |
| .ToImageSkia()); |
| } |
| |
| // Returns the index of the icon to use for |node|. Return -1 to use the |
| // default icon. The index is relative to the list of icons returned from |
| // GetIcons. |
| int CookiesTreeModel::GetIconIndex(ui::TreeModelNode* node) { |
| CookieTreeNode* ct_node = static_cast<CookieTreeNode*>(node); |
| switch (ct_node->GetDetailedInfo().node_type) { |
| case CookieTreeNode::DetailedInfo::TYPE_COOKIE: |
| return COOKIE; |
| |
| // Fall through each below cases to return DATABASE. |
| case CookieTreeNode::DetailedInfo::TYPE_DATABASE: |
| case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: |
| case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE: |
| case CookieTreeNode::DetailedInfo::TYPE_APPCACHE: |
| case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB: |
| case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM: |
| case CookieTreeNode::DetailedInfo::TYPE_SERVICE_WORKER: |
| case CookieTreeNode::DetailedInfo::TYPE_SHARED_WORKER: |
| case CookieTreeNode::DetailedInfo::TYPE_CACHE_STORAGE: |
| case CookieTreeNode::DetailedInfo::TYPE_MEDIA_LICENSE: |
| return DATABASE; |
| case CookieTreeNode::DetailedInfo::TYPE_HOST: |
| case CookieTreeNode::DetailedInfo::TYPE_QUOTA: |
| return -1; |
| default: |
| break; |
| } |
| return -1; |
| } |
| |
| void CookiesTreeModel::DeleteAllStoredObjects() { |
| NotifyObserverBeginBatch(); |
| CookieTreeNode* root = GetRoot(); |
| root->DeleteStoredObjects(); |
| root->DeleteAll(); |
| NotifyObserverTreeNodeChanged(root); |
| NotifyObserverEndBatch(); |
| } |
| |
| void CookiesTreeModel::DeleteCookieNode(CookieTreeNode* cookie_node) { |
| if (cookie_node == GetRoot()) |
| return; |
| cookie_node->DeleteStoredObjects(); |
| CookieTreeNode* parent_node = cookie_node->parent(); |
| Remove(parent_node, cookie_node); |
| if (parent_node->empty()) |
| DeleteCookieNode(parent_node); |
| } |
| |
| void CookiesTreeModel::UpdateSearchResults(const base::string16& filter) { |
| CookieTreeNode* root = GetRoot(); |
| SetBatchExpectation(1, true); |
| ScopedBatchUpdateNotifier notifier(this, root); |
| notifier.StartBatchUpdate(); |
| root->DeleteAll(); |
| |
| PopulateCookieInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateDatabaseInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateLocalStorageInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateSessionStorageInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateAppCacheInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateIndexedDBInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateFileSystemInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateQuotaInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateServiceWorkerUsageInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateSharedWorkerInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateCacheStorageUsageInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateFlashLSOInfoWithFilter(data_container(), ¬ifier, filter); |
| PopulateMediaLicenseInfoWithFilter(data_container(), ¬ifier, filter); |
| } |
| |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| const extensions::ExtensionSet* CookiesTreeModel::ExtensionsProtectingNode( |
| const CookieTreeNode& cookie_node) { |
| if (!special_storage_policy_.get()) |
| return nullptr; |
| |
| CookieTreeNode::DetailedInfo info = cookie_node.GetDetailedInfo(); |
| |
| if (!TypeIsProtected(info.node_type)) |
| return nullptr; |
| |
| DCHECK(!info.origin.opaque()); |
| return special_storage_policy_->ExtensionsProtectingOrigin( |
| info.origin.GetURL()); |
| } |
| #endif |
| |
| void CookiesTreeModel::AddCookiesTreeObserver(Observer* observer) { |
| cookies_observer_list_.AddObserver(observer); |
| // Call super so that TreeNodeModel can notify, too. |
| ui::TreeNodeModel<CookieTreeNode>::AddObserver(observer); |
| } |
| |
| void CookiesTreeModel::RemoveCookiesTreeObserver(Observer* observer) { |
| cookies_observer_list_.RemoveObserver(observer); |
| // Call super so that TreeNodeModel doesn't have dead pointers. |
| ui::TreeNodeModel<CookieTreeNode>::RemoveObserver(observer); |
| } |
| |
| void CookiesTreeModel::PopulateAppCacheInfo(LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateAppCacheInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateCookieInfo(LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateCookieInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateDatabaseInfo(LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateDatabaseInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateLocalStorageInfo(LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateLocalStorageInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateSessionStorageInfo( |
| LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateSessionStorageInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateIndexedDBInfo(LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateIndexedDBInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateFileSystemInfo(LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateFileSystemInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateQuotaInfo(LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateQuotaInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateServiceWorkerUsageInfo( |
| LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateServiceWorkerUsageInfoWithFilter( |
| container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateSharedWorkerInfo(LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateSharedWorkerInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateCacheStorageUsageInfo( |
| LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateCacheStorageUsageInfoWithFilter(container, ¬ifier, |
| base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateFlashLSOInfo( |
| LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateFlashLSOInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateMediaLicenseInfo(LocalDataContainer* container) { |
| ScopedBatchUpdateNotifier notifier(this, GetRoot()); |
| PopulateMediaLicenseInfoWithFilter(container, ¬ifier, base::string16()); |
| } |
| |
| void CookiesTreeModel::PopulateAppCacheInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->appcache_info_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto& origin : container->appcache_info_) { |
| base::string16 host_node_name = base::UTF8ToUTF16(origin.first.host()); |
| if (filter.empty() || |
| (host_node_name.find(filter) != base::string16::npos)) { |
| CookieTreeHostNode* host_node = |
| root->GetOrCreateHostNode(origin.first.GetURL()); |
| CookieTreeAppCachesNode* appcaches_node = |
| host_node->GetOrCreateAppCachesNode(); |
| |
| for (auto info = origin.second.begin(); info != origin.second.end(); |
| ++info) { |
| appcaches_node->AddAppCacheNode( |
| std::make_unique<CookieTreeAppCacheNode>(origin.first, info)); |
| } |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateCookieInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| notifier->StartBatchUpdate(); |
| for (auto it = container->cookie_list_.begin(); |
| it != container->cookie_list_.end(); ++it) { |
| std::string domain = it->Domain(); |
| if (domain.length() > 1 && domain[0] == '.') |
| domain = domain.substr(1); |
| |
| // Cookies ignore schemes, so group all HTTP and HTTPS cookies together. |
| GURL source(std::string(url::kHttpScheme) + url::kStandardSchemeSeparator + |
| domain + "/"); |
| |
| if (filter.empty() || (CookieTreeHostNode::TitleForUrl(source) |
| .find(filter) != base::string16::npos)) { |
| CookieTreeHostNode* host_node = root->GetOrCreateHostNode(source); |
| CookieTreeCookiesNode* cookies_node = |
| host_node->GetOrCreateCookiesNode(); |
| cookies_node->AddCookieNode(std::make_unique<CookieTreeCookieNode>(it)); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateDatabaseInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->database_info_list_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto database_info = container->database_info_list_.begin(); |
| database_info != container->database_info_list_.end(); ++database_info) { |
| if (filter.empty() || |
| (CookieTreeHostNode::TitleForUrl(database_info->origin.GetURL()) |
| .find(filter) != base::string16::npos)) { |
| CookieTreeHostNode* host_node = |
| root->GetOrCreateHostNode(database_info->origin.GetURL()); |
| CookieTreeDatabasesNode* databases_node = |
| host_node->GetOrCreateDatabasesNode(); |
| databases_node->AddDatabaseNode( |
| std::make_unique<CookieTreeDatabaseNode>(database_info)); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateLocalStorageInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->local_storage_info_list_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto local_storage_info = container->local_storage_info_list_.begin(); |
| local_storage_info != container->local_storage_info_list_.end(); |
| ++local_storage_info) { |
| const GURL& origin(local_storage_info->origin.GetURL()); |
| |
| if (filter.empty() || (CookieTreeHostNode::TitleForUrl(origin) |
| .find(filter) != std::string::npos)) { |
| CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); |
| CookieTreeLocalStoragesNode* local_storages_node = |
| host_node->GetOrCreateLocalStoragesNode(); |
| local_storages_node->AddLocalStorageNode( |
| std::make_unique<CookieTreeLocalStorageNode>(local_storage_info)); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateSessionStorageInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->session_storage_info_list_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto session_storage_info = |
| container->session_storage_info_list_.begin(); |
| session_storage_info != container->session_storage_info_list_.end(); |
| ++session_storage_info) { |
| const GURL& origin = session_storage_info->origin.GetURL(); |
| |
| if (filter.empty() || (CookieTreeHostNode::TitleForUrl(origin) |
| .find(filter) != base::string16::npos)) { |
| CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); |
| CookieTreeSessionStoragesNode* session_storages_node = |
| host_node->GetOrCreateSessionStoragesNode(); |
| session_storages_node->AddSessionStorageNode( |
| std::make_unique<CookieTreeSessionStorageNode>(session_storage_info)); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateIndexedDBInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->indexed_db_info_list_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto indexed_db_info = container->indexed_db_info_list_.begin(); |
| indexed_db_info != container->indexed_db_info_list_.end(); |
| ++indexed_db_info) { |
| const url::Origin& origin = indexed_db_info->origin; |
| |
| if (filter.empty() || |
| (CookieTreeHostNode::TitleForUrl(origin.GetURL()).find(filter) != |
| base::string16::npos)) { |
| CookieTreeHostNode* host_node = |
| root->GetOrCreateHostNode(origin.GetURL()); |
| CookieTreeIndexedDBsNode* indexed_dbs_node = |
| host_node->GetOrCreateIndexedDBsNode(); |
| indexed_dbs_node->AddIndexedDBNode( |
| std::make_unique<CookieTreeIndexedDBNode>(indexed_db_info)); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateServiceWorkerUsageInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->service_worker_info_list_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto service_worker_info = container->service_worker_info_list_.begin(); |
| service_worker_info != container->service_worker_info_list_.end(); |
| ++service_worker_info) { |
| const url::Origin& origin = service_worker_info->origin; |
| |
| if (filter.empty() || |
| (CookieTreeHostNode::TitleForUrl(origin.GetURL()).find(filter) != |
| base::string16::npos)) { |
| CookieTreeHostNode* host_node = |
| root->GetOrCreateHostNode(origin.GetURL()); |
| CookieTreeServiceWorkersNode* service_workers_node = |
| host_node->GetOrCreateServiceWorkersNode(); |
| service_workers_node->AddServiceWorkerNode( |
| std::make_unique<CookieTreeServiceWorkerNode>(service_worker_info)); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateSharedWorkerInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->shared_worker_info_list_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto shared_worker_info = container->shared_worker_info_list_.begin(); |
| shared_worker_info != container->shared_worker_info_list_.end(); |
| ++shared_worker_info) { |
| const GURL& worker = shared_worker_info->worker; |
| |
| if (filter.empty() || (CookieTreeHostNode::TitleForUrl(worker).find( |
| filter) != base::string16::npos)) { |
| CookieTreeHostNode* host_node = root->GetOrCreateHostNode(worker); |
| CookieTreeSharedWorkersNode* shared_workers_node = |
| host_node->GetOrCreateSharedWorkersNode(); |
| shared_workers_node->AddSharedWorkerNode( |
| std::make_unique<CookieTreeSharedWorkerNode>(shared_worker_info)); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateCacheStorageUsageInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->cache_storage_info_list_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto cache_storage_info = container->cache_storage_info_list_.begin(); |
| cache_storage_info != container->cache_storage_info_list_.end(); |
| ++cache_storage_info) { |
| const url::Origin& origin = cache_storage_info->origin; |
| |
| if (filter.empty() || |
| (CookieTreeHostNode::TitleForUrl(origin.GetURL()).find(filter) != |
| base::string16::npos)) { |
| CookieTreeHostNode* host_node = |
| root->GetOrCreateHostNode(origin.GetURL()); |
| CookieTreeCacheStoragesNode* cache_storages_node = |
| host_node->GetOrCreateCacheStoragesNode(); |
| cache_storages_node->AddCacheStorageNode( |
| std::make_unique<CookieTreeCacheStorageNode>(cache_storage_info)); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateFileSystemInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->file_system_info_list_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto file_system_info = container->file_system_info_list_.begin(); |
| file_system_info != container->file_system_info_list_.end(); |
| ++file_system_info) { |
| GURL origin = file_system_info->origin.GetURL(); |
| |
| if (filter.empty() || (CookieTreeHostNode::TitleForUrl(origin) |
| .find(filter) != base::string16::npos)) { |
| CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); |
| CookieTreeFileSystemsNode* file_systems_node = |
| host_node->GetOrCreateFileSystemsNode(); |
| file_systems_node->AddFileSystemNode( |
| std::make_unique<CookieTreeFileSystemNode>(file_system_info)); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateQuotaInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->quota_info_list_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto quota_info = container->quota_info_list_.begin(); |
| quota_info != container->quota_info_list_.end(); ++quota_info) { |
| if (filter.empty() || (base::UTF8ToUTF16(quota_info->host).find(filter) != |
| base::string16::npos)) { |
| CookieTreeHostNode* host_node = |
| root->GetOrCreateHostNode(GURL("http://" + quota_info->host)); |
| host_node->UpdateOrCreateQuotaNode(quota_info); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateFlashLSOInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->flash_lso_domain_list_.empty()) |
| return; |
| |
| std::string filter_utf8 = base::UTF16ToUTF8(filter); |
| notifier->StartBatchUpdate(); |
| for (auto it = container->flash_lso_domain_list_.begin(); |
| it != container->flash_lso_domain_list_.end(); ++it) { |
| if (filter_utf8.empty() || it->find(filter_utf8) != std::string::npos) { |
| // Create a fake origin for GetOrCreateHostNode(). |
| GURL origin("http://" + *it); |
| CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); |
| host_node->GetOrCreateFlashLSONode(*it); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::PopulateMediaLicenseInfoWithFilter( |
| LocalDataContainer* container, |
| ScopedBatchUpdateNotifier* notifier, |
| const base::string16& filter) { |
| CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| |
| if (container->media_license_info_list_.empty()) |
| return; |
| |
| notifier->StartBatchUpdate(); |
| for (auto media_license_info = container->media_license_info_list_.begin(); |
| media_license_info != container->media_license_info_list_.end(); |
| ++media_license_info) { |
| GURL origin(media_license_info->origin); |
| |
| if (filter.empty() || (CookieTreeHostNode::TitleForUrl(origin).find( |
| filter) != base::string16::npos)) { |
| CookieTreeHostNode* host_node = root->GetOrCreateHostNode(origin); |
| CookieTreeMediaLicensesNode* media_licenses_node = |
| host_node->GetOrCreateMediaLicensesNode(); |
| media_licenses_node->AddMediaLicenseNode( |
| std::make_unique<CookieTreeMediaLicenseNode>(media_license_info)); |
| } |
| } |
| } |
| |
| void CookiesTreeModel::SetBatchExpectation(int batches_expected, bool reset) { |
| batches_expected_ = batches_expected; |
| if (reset) { |
| batches_seen_ = 0; |
| batches_started_ = 0; |
| batches_ended_ = 0; |
| } else { |
| MaybeNotifyBatchesEnded(); |
| } |
| } |
| |
| void CookiesTreeModel::RecordBatchSeen() { |
| batches_seen_++; |
| } |
| |
| void CookiesTreeModel::NotifyObserverBeginBatch() { |
| // Only notify the model once if we're batching in a nested manner. |
| if (batches_started_++ == 0) { |
| for (Observer& observer : cookies_observer_list_) |
| observer.TreeModelBeginBatch(this); |
| } |
| } |
| |
| void CookiesTreeModel::NotifyObserverEndBatch() { |
| batches_ended_++; |
| MaybeNotifyBatchesEnded(); |
| } |
| |
| void CookiesTreeModel::MaybeNotifyBatchesEnded() { |
| // Only notify the observers if this is the outermost call to EndBatch() if |
| // called in a nested manner. |
| if (batches_ended_ == batches_started_ && |
| batches_seen_ == batches_expected_) { |
| for (Observer& observer : cookies_observer_list_) |
| observer.TreeModelEndBatch(this); |
| SetBatchExpectation(0, true); |
| } |
| } |
| // static |
| std::unique_ptr<CookiesTreeModel> CookiesTreeModel::CreateForProfile( |
| Profile* profile, |
| bool omit_cookies) { |
| auto* storage_partition = |
| content::BrowserContext::GetDefaultStoragePartition(profile); |
| auto* file_system_context = storage_partition->GetFileSystemContext(); |
| auto* cookie_helper = |
| omit_cookies ? nullptr : new BrowsingDataCookieHelper(storage_partition); |
| |
| auto container = std::make_unique<LocalDataContainer>( |
| cookie_helper, new BrowsingDataDatabaseHelper(profile), |
| new BrowsingDataLocalStorageHelper(profile), |
| /*session_storage_helper=*/nullptr, |
| new BrowsingDataAppCacheHelper(profile), |
| new BrowsingDataIndexedDBHelper(storage_partition->GetIndexedDBContext()), |
| BrowsingDataFileSystemHelper::Create(file_system_context), |
| BrowsingDataQuotaHelper::Create(profile), |
| new BrowsingDataServiceWorkerHelper( |
| storage_partition->GetServiceWorkerContext()), |
| new BrowsingDataSharedWorkerHelper(storage_partition, |
| profile->GetResourceContext()), |
| new BrowsingDataCacheStorageHelper( |
| storage_partition->GetCacheStorageContext()), |
| #if defined(OS_ANDROID) |
| // Android doesn't have flash LSO hence it cannot be created for |
| // android build. |
| nullptr, |
| #else |
| BrowsingDataFlashLSOHelper::Create(profile), |
| #endif |
| BrowsingDataMediaLicenseHelper::Create(file_system_context)); |
| return std::make_unique<CookiesTreeModel>( |
| std::move(container), profile->GetExtensionSpecialStoragePolicy()); |
| } |