blob: c36a096f8307846af01949946ab6682a6b4aaa61 [file] [log] [blame]
// 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/browsing_data_appcache_helper.h"
#include <algorithm>
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/task/post_task.h"
#include "base/time/time.h"
#include "chrome/browser/browsing_data/browsing_data_helper.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/storage_usage_info.h"
#include "content/public/common/content_features.h"
#include "net/base/completion_once_callback.h"
#include "third_party/blink/public/mojom/appcache/appcache_info.mojom.h"
using content::AppCacheService;
using content::BrowserThread;
namespace {
void OnAppCacheInfoFetchComplete(
BrowsingDataAppCacheHelper::FetchCallback callback,
scoped_refptr<content::AppCacheInfoCollection> info_collection,
int /*rv*/) {
DCHECK(!callback.is_null());
std::list<content::StorageUsageInfo> result;
for (const auto& origin_info : info_collection->infos_by_origin) {
const url::Origin& origin = origin_info.first;
// Filter out appcache info entries for non-websafe schemes. Extension state
// and DevTools, for example, are not considered browsing data.
if (!BrowsingDataHelper::IsWebScheme(origin.scheme()))
continue;
DCHECK(!origin_info.second.empty());
base::Time last_modified;
int64_t total_size = 0;
for (const auto& info : origin_info.second) {
last_modified = std::max(last_modified, info.last_update_time);
// The sizes only cover the on-disk response sizes. They do not include
// the padding sizes added by the Quota system to cross-origin resources.
//
// We count the actual disk usage because this number is only reported in
// UI (not in any API accessible to the site). This decision may need to
// be revisited if users are confused by the Quota system's decisions.
total_size += info.response_sizes;
}
result.emplace_back(origin, total_size, last_modified);
}
if (base::FeatureList::IsEnabled(features::kNavigationLoaderOnUI)) {
std::move(callback).Run(std::move(result));
} else {
base::PostTask(FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback), std::move(result)));
}
}
} // namespace
BrowsingDataAppCacheHelper::BrowsingDataAppCacheHelper(
AppCacheService* appcache_service)
: appcache_service_(appcache_service) {}
void BrowsingDataAppCacheHelper::StartFetching(FetchCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!callback.is_null());
if (base::FeatureList::IsEnabled(features::kNavigationLoaderOnUI)) {
StartFetchingOnLoaderThread(std::move(callback));
} else {
base::PostTask(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BrowsingDataAppCacheHelper::StartFetchingOnLoaderThread,
this, std::move(callback)));
}
}
void BrowsingDataAppCacheHelper::DeleteAppCaches(const url::Origin& origin) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (base::FeatureList::IsEnabled(features::kNavigationLoaderOnUI)) {
DeleteAppCachesOnLoaderThread(origin);
} else {
base::PostTask(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&BrowsingDataAppCacheHelper::DeleteAppCachesOnLoaderThread, this,
origin));
}
}
BrowsingDataAppCacheHelper::~BrowsingDataAppCacheHelper() {}
void BrowsingDataAppCacheHelper::StartFetchingOnLoaderThread(
FetchCallback callback) {
DCHECK(!callback.is_null());
scoped_refptr<content::AppCacheInfoCollection> info_collection =
new content::AppCacheInfoCollection();
appcache_service_->GetAllAppCacheInfo(
info_collection.get(),
base::BindOnce(&OnAppCacheInfoFetchComplete, std::move(callback),
info_collection));
}
void BrowsingDataAppCacheHelper::DeleteAppCachesOnLoaderThread(
const url::Origin& origin) {
appcache_service_->DeleteAppCachesForOrigin(origin,
net::CompletionOnceCallback());
}
CannedBrowsingDataAppCacheHelper::CannedBrowsingDataAppCacheHelper(
AppCacheService* appcache_service)
: BrowsingDataAppCacheHelper(appcache_service) {}
void CannedBrowsingDataAppCacheHelper::Add(const url::Origin& origin) {
if (!BrowsingDataHelper::HasWebScheme(origin.GetURL()))
return; // Ignore non-websafe schemes.
pending_origins_.insert(origin);
}
void CannedBrowsingDataAppCacheHelper::Reset() {
pending_origins_.clear();
}
bool CannedBrowsingDataAppCacheHelper::empty() const {
return pending_origins_.empty();
}
size_t CannedBrowsingDataAppCacheHelper::GetCount() const {
return pending_origins_.size();
}
const std::set<url::Origin>& CannedBrowsingDataAppCacheHelper::GetOrigins()
const {
return pending_origins_;
}
void CannedBrowsingDataAppCacheHelper::StartFetching(FetchCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!callback.is_null());
std::list<content::StorageUsageInfo> result;
for (const auto& origin : pending_origins_)
result.emplace_back(origin, 0, base::Time());
base::PostTask(FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback), result));
}
void CannedBrowsingDataAppCacheHelper::DeleteAppCaches(
const url::Origin& origin) {
pending_origins_.erase(origin);
BrowsingDataAppCacheHelper::DeleteAppCaches(origin);
}
CannedBrowsingDataAppCacheHelper::~CannedBrowsingDataAppCacheHelper() {}