blob: 5245b71502534424594180d78251a98bfb23ee1c [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 "components/browsing_data/content/file_system_helper.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/sequenced_task_runner.h"
#include "components/browsing_data/content/browsing_data_helper.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/native_io_context.h"
#include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/file_system_quota_util.h"
#include "storage/common/file_system/file_system_types.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "url/origin.h"
using content::BrowserThread;
namespace storage {
class FileSystemContext;
} // namespace storage
namespace browsing_data {
FileSystemHelper::FileSystemHelper(
storage::FileSystemContext* filesystem_context,
const std::vector<storage::FileSystemType>& additional_types,
content::NativeIOContext* native_io_context)
: filesystem_context_(filesystem_context),
native_io_context_(native_io_context) {
for (storage::FileSystemType type : additional_types)
types_.push_back(type);
DCHECK(filesystem_context_.get());
}
FileSystemHelper::~FileSystemHelper() {}
base::SequencedTaskRunner* FileSystemHelper::file_task_runner() {
return filesystem_context_->default_file_task_runner();
}
void FileSystemHelper::StartFetching(FetchCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!callback.is_null());
file_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&FileSystemHelper::FetchFileSystemInfoInFileThread, this,
base::BindOnce(&FileSystemHelper::DidFetchFileSystemInfo,
this, std::move(callback))));
}
void FileSystemHelper::DeleteFileSystemOrigin(const url::Origin& origin) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
file_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&FileSystemHelper::DeleteFileSystemForStorageKeyInFileThread, this,
blink::StorageKey(origin)));
native_io_context_->DeleteStorageKeyData(blink::StorageKey(origin),
base::DoNothing());
}
void FileSystemHelper::FetchFileSystemInfoInFileThread(FetchCallback callback) {
DCHECK(file_task_runner()->RunsTasksInCurrentSequence());
DCHECK(!callback.is_null());
std::list<FileSystemInfo> result;
std::map<GURL, FileSystemInfo> file_system_info_map;
for (storage::FileSystemType type : types_) {
storage::FileSystemQuotaUtil* quota_util =
filesystem_context_->GetQuotaUtil(type);
DCHECK(quota_util);
std::vector<blink::StorageKey> storage_keys =
quota_util->GetStorageKeysForTypeOnFileTaskRunner(type);
for (const auto& current : storage_keys) {
if (!HasWebScheme(current.origin().GetURL()))
continue; // Non-websafe state is not considered browsing data.
int64_t usage = quota_util->GetStorageKeyUsageOnFileTaskRunner(
filesystem_context_.get(), current, type);
auto inserted =
file_system_info_map
.insert(std::make_pair(current.origin().GetURL(),
FileSystemInfo(current.origin())))
.first;
inserted->second.usage_map[type] = usage;
}
}
for (const auto& iter : file_system_info_map)
result.push_back(iter.second);
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), result));
}
void FileSystemHelper::DeleteFileSystemForStorageKeyInFileThread(
const blink::StorageKey& storage_key) {
DCHECK(file_task_runner()->RunsTasksInCurrentSequence());
filesystem_context_->DeleteDataForStorageKeyOnFileTaskRunner(storage_key);
}
void FileSystemHelper::DidFetchFileSystemInfo(
FetchCallback callback,
const std::list<FileSystemInfo>& file_system_info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
native_io_context_->GetStorageKeyUsageMap(
base::BindOnce(&FileSystemHelper::AppendNativeIOInfoToFileSystemInfo,
this, std::move(callback), std::move(file_system_info)));
}
void FileSystemHelper::AppendNativeIOInfoToFileSystemInfo(
FetchCallback callback,
const std::list<FileSystemInfo>& file_system_info_list,
const std::map<blink::StorageKey, int64_t>& native_io_usage_map) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::list<FileSystemInfo> result = file_system_info_list;
std::map<GURL, FileSystemInfo> file_system_info_map;
for (const auto& current : native_io_usage_map) {
url::Origin origin = current.first.origin();
if (!HasWebScheme(origin.GetURL()))
continue; // Non-websafe state is not considered browsing data.
int64_t usage = current.second;
auto inserted =
file_system_info_map
.insert(std::make_pair(origin.GetURL(), FileSystemInfo(origin)))
.first;
inserted->second
.usage_map[storage::FileSystemType::kFileSystemTypeTemporary] = usage;
}
for (const auto& iter : file_system_info_map)
result.push_back(iter.second);
std::move(callback).Run(result);
}
FileSystemHelper::FileSystemInfo::FileSystemInfo(const url::Origin& origin)
: origin(origin) {}
FileSystemHelper::FileSystemInfo::FileSystemInfo(const FileSystemInfo& other) =
default;
FileSystemHelper::FileSystemInfo::~FileSystemInfo() {}
CannedFileSystemHelper::CannedFileSystemHelper(
storage::FileSystemContext* filesystem_context,
const std::vector<storage::FileSystemType>& additional_types,
content::NativeIOContext* native_io_context)
: FileSystemHelper(filesystem_context,
additional_types,
native_io_context) {}
CannedFileSystemHelper::~CannedFileSystemHelper() {}
void CannedFileSystemHelper::Add(const url::Origin& origin) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!HasWebScheme(origin.GetURL()))
return; // Non-websafe state is not considered browsing data.
pending_origins_.insert(origin);
}
void CannedFileSystemHelper::Reset() {
pending_origins_.clear();
}
bool CannedFileSystemHelper::empty() const {
return pending_origins_.empty();
}
size_t CannedFileSystemHelper::GetCount() const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return pending_origins_.size();
}
void CannedFileSystemHelper::StartFetching(FetchCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!callback.is_null());
std::list<FileSystemInfo> result;
for (const auto& origin : pending_origins_)
result.emplace_back(origin);
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), result));
}
void CannedFileSystemHelper::DeleteFileSystemOrigin(const url::Origin& origin) {
pending_origins_.erase(origin);
FileSystemHelper::DeleteFileSystemOrigin(origin);
}
} // namespace browsing_data