Commit 75321ac0 authored by dullweber's avatar dullweber Committed by Commit bot

Refactor cache counting code as a preparation for a more exact implementation.

Move code from StoragePartitionHttpCacheRemover to CacheCountingHelper. Improve tests by adding a CacheTestUtil class for common functionality of cache counting and cache deletion tests.

BUG=671196
TBR=achuith@chromium.org

Review-Url: https://codereview.chromium.org/2556363003
Cr-Commit-Position: refs/heads/master@{#441399}
parent c540247a
......@@ -63,22 +63,17 @@ base::string16 GetChromeCounterTextFromResult(
if (pref_name == browsing_data::prefs::kDeleteCache) {
// Cache counter.
browsing_data::BrowsingDataCounter::ResultInt cache_size_bytes =
static_cast<const browsing_data::BrowsingDataCounter::FinishedResult*>(
result)
->Value();
PrefService* prefs = result->source()->GetPrefs();
browsing_data::TimePeriod time_period =
static_cast<browsing_data::TimePeriod>(
prefs->GetInteger(browsing_data::prefs::kDeleteTimePeriod));
const auto* cache_result =
static_cast<const CacheCounter::CacheResult*>(result);
int64_t cache_size_bytes = cache_result->cache_size();
bool is_upper_limit = cache_result->is_upper_limit();
// Three cases: Nonzero result for the entire cache, nonzero result for
// a subset of cache (i.e. a finite time interval), and almost zero (< 1MB).
static const int kBytesInAMegabyte = 1024 * 1024;
if (cache_size_bytes >= kBytesInAMegabyte) {
base::string16 formatted_size = FormatBytesMBOrHigher(cache_size_bytes);
return time_period == browsing_data::ALL_TIME
return !is_upper_limit
? formatted_size
: l10n_util::GetStringFUTF16(
IDS_DEL_CACHE_COUNTER_UPPER_ESTIMATE, formatted_size);
......
......@@ -4,10 +4,20 @@
#include "chrome/browser/browsing_data/cache_counter.h"
#include "chrome/browser/profiles/profile.h"
#include "components/browsing_data/content/storage_partition_http_cache_data_remover.h"
#include "components/browsing_data/content/conditional_cache_counting_helper.h"
#include "components/browsing_data/core/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
CacheCounter::CacheResult::CacheResult(const CacheCounter* source,
int64_t cache_size,
bool is_upper_limit)
: FinishedResult(source, cache_size),
cache_size_(cache_size),
is_upper_limit_(is_upper_limit) {}
CacheCounter::CacheResult::~CacheResult() {}
CacheCounter::CacheCounter(Profile* profile)
: profile_(profile),
pending_(false),
......@@ -21,27 +31,27 @@ const char* CacheCounter::GetPrefName() const {
}
void CacheCounter::Count() {
// TODO(msramek): StoragePartitionHttpCacheDataRemover currently does not
// implement counting for subsets of cache, only for the entire cache. Thus,
// we ignore the time period setting and always request counting for
// the unbounded time interval. It is up to the UI to interpret the results
// for finite time intervals as upper estimates.
browsing_data::StoragePartitionHttpCacheDataRemover::CreateForRange(
content::BrowserContext::GetDefaultStoragePartition(profile_),
base::Time(), base::Time::Max())
->Count(base::Bind(&CacheCounter::OnCacheSizeCalculated,
weak_ptr_factory_.GetWeakPtr()));
bool is_upper_limit = !GetPeriodStart().is_null();
base::WeakPtr<browsing_data::ConditionalCacheCountingHelper> counter =
browsing_data::ConditionalCacheCountingHelper::CreateForRange(
content::BrowserContext::GetDefaultStoragePartition(profile_),
base::Time(), base::Time::Max())
->CountAndDestroySelfWhenFinished(
base::Bind(&CacheCounter::OnCacheSizeCalculated,
weak_ptr_factory_.GetWeakPtr(), is_upper_limit));
pending_ = true;
}
void CacheCounter::OnCacheSizeCalculated(int64_t result_bytes) {
void CacheCounter::OnCacheSizeCalculated(bool is_upper_limit,
int64_t result_bytes) {
pending_ = false;
// A value less than 0 means a net error code.
if (result_bytes < 0)
return;
ReportResult(result_bytes);
auto result =
base::MakeUnique<CacheResult>(this, result_bytes, is_upper_limit);
ReportResult(std::move(result));
}
bool CacheCounter::Pending() {
......
......@@ -12,25 +12,49 @@
class Profile;
namespace browsing_data {
class ConditionalCacheCountingHelper;
}
class CacheCounter : public browsing_data::BrowsingDataCounter {
public:
class CacheResult : public FinishedResult {
public:
CacheResult(const CacheCounter* source,
int64_t cache_size,
bool is_upper_limit);
~CacheResult() override;
int64_t cache_size() const { return cache_size_; }
bool is_upper_limit() const { return is_upper_limit_; }
private:
int64_t cache_size_;
bool is_upper_limit_;
DISALLOW_COPY_AND_ASSIGN(CacheResult);
};
explicit CacheCounter(Profile* profile);
~CacheCounter() override;
const char* GetPrefName() const override;
// Whether this counter awaits the calculation result callback.
// Used only for testing.
bool Pending();
const char* GetPrefName() const override;
private:
void Count() override;
void OnCacheSizeCalculated(bool is_upper_limit, int64_t bytes);
void FetchEstimate(
base::WeakPtr<browsing_data::ConditionalCacheCountingHelper>);
Profile* profile_;
bool pending_;
base::WeakPtrFactory<CacheCounter> weak_ptr_factory_;
void Count() override;
void OnCacheSizeCalculated(int64_t bytes);
};
#endif // CHROME_BROWSER_BROWSING_DATA_CACHE_COUNTER_H_
......@@ -138,10 +138,9 @@ class CacheCounterTest : public InProcessBrowserTest {
finished_ = result->Finished();
if (finished_) {
result_ =
static_cast<browsing_data::BrowsingDataCounter::FinishedResult*>(
result.get())
->Value();
auto cache_result = static_cast<CacheCounter::CacheResult*>(result.get());
result_ = cache_result->cache_size();
is_upper_limit_ = cache_result->is_upper_limit();
}
if (run_loop_ && finished_)
......@@ -153,6 +152,11 @@ class CacheCounterTest : public InProcessBrowserTest {
return result_;
}
bool IsUpperLimit() {
DCHECK(finished_);
return is_upper_limit_;
}
private:
enum CacheEntryCreationStep {
GET_CACHE,
......@@ -169,6 +173,7 @@ class CacheCounterTest : public InProcessBrowserTest {
bool finished_;
browsing_data::BrowsingDataCounter::ResultInt result_;
bool is_upper_limit_;
};
// Tests that for the empty cache, the result is zero.
......@@ -268,22 +273,27 @@ IN_PROC_BROWSER_TEST_F(CacheCounterTest, PeriodChanged) {
SetDeletionPeriodPref(browsing_data::LAST_HOUR);
WaitForIOThread();
browsing_data::BrowsingDataCounter::ResultInt result = GetResult();
EXPECT_TRUE(IsUpperLimit());
SetDeletionPeriodPref(browsing_data::LAST_DAY);
WaitForIOThread();
EXPECT_EQ(result, GetResult());
EXPECT_TRUE(IsUpperLimit());
SetDeletionPeriodPref(browsing_data::LAST_WEEK);
WaitForIOThread();
EXPECT_EQ(result, GetResult());
EXPECT_TRUE(IsUpperLimit());
SetDeletionPeriodPref(browsing_data::FOUR_WEEKS);
WaitForIOThread();
EXPECT_EQ(result, GetResult());
EXPECT_TRUE(IsUpperLimit());
SetDeletionPeriodPref(browsing_data::ALL_TIME);
WaitForIOThread();
EXPECT_EQ(result, GetResult());
EXPECT_FALSE(IsUpperLimit());
}
} // namespace
// Copyright 2016 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 "base/synchronization/waitable_event.h"
#include "chrome/browser/browsing_data/cache_test_util.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
using content::BrowserThread;
CacheTestUtil::CacheTestUtil(content::StoragePartition* partition)
: partition_(partition), remaining_tasks_(0) {
done_callback_ =
base::Bind(&CacheTestUtil::DoneCallback, base::Unretained(this));
// UI and IO thread synchronization.
waitable_event_ = base::MakeUnique<base::WaitableEvent>(
base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&CacheTestUtil::SetUpOnIOThread, base::Unretained(this)));
WaitForTasksOnIOThread();
}
CacheTestUtil::~CacheTestUtil() {
// The cache iterator must be deleted on the thread where it was created,
// which is the IO thread.
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&CacheTestUtil::TearDownOnIOThread, base::Unretained(this)));
WaitForTasksOnIOThread();
}
void CacheTestUtil::CreateCacheEntries(const std::set<std::string>& keys) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&CacheTestUtil::CreateCacheEntriesOnIOThread,
base::Unretained(this), base::ConstRef(keys)));
WaitForTasksOnIOThread();
}
void CacheTestUtil::SetUpOnIOThread() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
net::URLRequestContextGetter* context = partition_->GetURLRequestContext();
net::HttpCache* cache =
context->GetURLRequestContext()->http_transaction_factory()->GetCache();
SetNumberOfWaitedTasks(1);
WaitForCompletion(cache->GetBackend(&backend_, done_callback_));
}
void CacheTestUtil::TearDownOnIOThread() {
iterator_.reset();
for (disk_cache::Entry* entry : entries_) {
entry->Close();
}
entries_.clear();
DoneCallback(net::OK);
}
void CacheTestUtil::CreateCacheEntriesOnIOThread(
const std::set<std::string>& keys) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
int pos = entries_.size();
entries_.resize(entries_.size() + keys.size());
SetNumberOfWaitedTasks(keys.size());
for (const std::string& key : keys) {
WaitForCompletion(
backend_->CreateEntry(key, &entries_[pos++], done_callback_));
}
}
// Waiting for tasks to be done on IO thread. --------------------------------
void CacheTestUtil::WaitForTasksOnIOThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
waitable_event_->Wait();
}
void CacheTestUtil::SetNumberOfWaitedTasks(int count) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
remaining_tasks_ = count;
}
void CacheTestUtil::WaitForCompletion(int value) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (value >= 0) {
// We got the result immediately.
DoneCallback(value);
} else if (value == net::ERR_IO_PENDING) {
// We need to wait for the callback.
} else {
// An error has occurred.
NOTREACHED();
}
}
void CacheTestUtil::DoneCallback(int value) {
DCHECK_GE(value, 0); // Negative values represent an error.
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (--remaining_tasks_ > 0)
return;
waitable_event_->Signal();
}
// Check cache content.
std::vector<std::string> CacheTestUtil::GetEntryKeys() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&CacheTestUtil::GetEntryKeysOnIOThread,
base::Unretained(this)));
WaitForTasksOnIOThread();
return keys_;
}
void CacheTestUtil::GetEntryKeysOnIOThread() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
keys_.clear();
current_entry_ = nullptr;
iterator_ = backend_->CreateIterator();
GetNextKey(net::OK);
}
void CacheTestUtil::GetNextKey(int error) {
while (error != net::ERR_IO_PENDING) {
if (error == net::ERR_FAILED) {
DoneCallback(net::OK);
return;
}
if (current_entry_) {
keys_.push_back(current_entry_->GetKey());
}
error = iterator_->OpenNextEntry(
&current_entry_,
base::Bind(&CacheTestUtil::GetNextKey, base::Unretained(this)));
}
}
// Copyright 2016 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.
#ifndef CHROME_BROWSER_BROWSING_DATA_CACHE_TEST_UTIL_H_
#define CHROME_BROWSER_BROWSING_DATA_CACHE_TEST_UTIL_H_
#include <set>
#include <vector>
#include "base/run_loop.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "net/disk_cache/disk_cache.h"
using content::BrowserThread;
// A util class that can be used to create and retreive cache entries.
class CacheTestUtil {
public:
explicit CacheTestUtil(content::StoragePartition* partition_);
~CacheTestUtil();
void CreateCacheEntries(const std::set<std::string>& keys);
std::vector<std::string> GetEntryKeys();
content::StoragePartition* partition() { return partition_; }
disk_cache::Backend* backend() { return backend_; }
private:
void SetUpOnIOThread();
void TearDownOnIOThread();
void CreateCacheEntriesOnIOThread(const std::set<std::string>& keys);
void GetEntryKeysOnIOThread();
void GetNextKey(int error);
void WaitForTasksOnIOThread();
void WaitForCompletion(int value);
void SetNumberOfWaitedTasks(int count);
void DoneCallback(int value);
base::Callback<void(int)> done_callback_;
content::StoragePartition* partition_;
disk_cache::Backend* backend_ = nullptr;
std::vector<disk_cache::Entry*> entries_;
std::unique_ptr<disk_cache::Backend::Iterator> iterator_;
disk_cache::Entry* current_entry_;
std::vector<std::string> keys_;
std::unique_ptr<base::WaitableEvent> waitable_event_;
int remaining_tasks_;
};
#endif // CHROME_BROWSER_BROWSING_DATA_CACHE_TEST_UTIL_H_
// Copyright (c) 2016 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 <algorithm>
#include <memory>
#include <set>
#include <string>
#include "base/run_loop.h"
#include "chrome/browser/browsing_data/cache_test_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/browsing_data/content/conditional_cache_counting_helper.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
using browsing_data::ConditionalCacheCountingHelper;
using content::BrowserThread;
class ConditionalCacheCountingHelperBrowserTest : public InProcessBrowserTest {
public:
const int64_t kTimeoutMs = 10;
void SetUpOnMainThread() override {
count_callback_ =
base::Bind(&ConditionalCacheCountingHelperBrowserTest::CountCallback,
base::Unretained(this));
cache_util_ = base::MakeUnique<CacheTestUtil>(
content::BrowserContext::GetDefaultStoragePartition(
browser()->profile()));
}
void TearDownOnMainThread() override { cache_util_.reset(); }
void CountCallback(int64_t size) {
// Negative values represent an unexpected error.
DCHECK(size >= 0 || size == net::ERR_ABORTED);
DCHECK_CURRENTLY_ON(BrowserThread::UI);
last_size_ = size;
if (run_loop_)
run_loop_->Quit();
}
void WaitForTasksOnIOThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
run_loop_.reset(new base::RunLoop());
run_loop_->Run();
}
void CountEntries(base::Time begin_time, base::Time end_time) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
last_size_ = -1;
auto helper = ConditionalCacheCountingHelper::CreateForRange(
cache_util_->partition(), begin_time, end_time);
helper->CountAndDestroySelfWhenFinished(count_callback_);
}
int64_t GetResult() {
DCHECK_GT(last_size_, 0);
return last_size_;
}
int64_t GetResultOrError() { return last_size_; }
CacheTestUtil* GetCacheTestUtil() { return cache_util_.get(); }
private:
ConditionalCacheCountingHelper::CacheCountCallback count_callback_;
std::unique_ptr<base::RunLoop> run_loop_;
std::unique_ptr<CacheTestUtil> cache_util_;
int64_t last_size_;
};
// Tests that ConditionalCacheCountingHelper only counts those cache entries
// that match the condition.
IN_PROC_BROWSER_TEST_F(ConditionalCacheCountingHelperBrowserTest, Count) {
// Create 5 entries.
std::set<std::string> keys1 = {"1", "2", "3", "4", "5"};
base::Time t1 = base::Time::Now();
GetCacheTestUtil()->CreateCacheEntries(keys1);
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(kTimeoutMs));
// base::Time t2 = base::Time::Now();
std::set<std::string> keys2 = {"6", "7"};
GetCacheTestUtil()->CreateCacheEntries(keys2);
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(kTimeoutMs));
base::Time t3 = base::Time::Now();
// TODO(dullweber): Add test for time ranges when GetEntrySize() is done.
// Count all entries.
CountEntries(t1, t3);
WaitForTasksOnIOThread();
int64_t size_1_3 = GetResult();
// Count everything
CountEntries(base::Time(), base::Time::Max());
WaitForTasksOnIOThread();
EXPECT_EQ(size_1_3, GetResult());
}
......@@ -12,6 +12,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "chrome/browser/browsing_data/cache_test_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
......@@ -43,182 +44,64 @@ bool HasHttpsExampleOrigin(const GURL& url) {
class ConditionalCacheDeletionHelperBrowserTest : public InProcessBrowserTest {
public:
// Initialization ------------------------------------------------------------
void SetUpOnMainThread() override {
// Prepare the commonly used callbacks.
done_callback_ = base::Bind(
&ConditionalCacheDeletionHelperBrowserTest::DoneCallback,
base::Unretained(this));
cache_util_ = base::MakeUnique<CacheTestUtil>(
content::BrowserContext::GetDefaultStoragePartition(
browser()->profile()));
done_callback_ =
base::Bind(&ConditionalCacheDeletionHelperBrowserTest::DoneCallback,
base::Unretained(this));
// UI and IO thread synchronization.
waitable_event_ = base::MakeUnique<base::WaitableEvent>(
base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
// Get the storage partition.
partition_ = content::BrowserContext::GetDefaultStoragePartition(
browser()->profile());
// Get the cache backends.
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ConditionalCacheDeletionHelperBrowserTest::SetUpOnIOThread,
base::Unretained(this)));
WaitForTasksOnIOThread();
}
void SetUpOnIOThread() {
net::URLRequestContextGetter* context = partition_->GetURLRequestContext();
net::HttpCache* cache = context->GetURLRequestContext()->
http_transaction_factory()->GetCache();
SetNumberOfWaitedTasks(1);
WaitForCompletion(cache->GetBackend(&backend_, done_callback_));
}
void TearDownOnMainThread() override {
// The cache iterator must be deleted on the thread where it was created,
// which is the IO thread.
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(
&ConditionalCacheDeletionHelperBrowserTest::TearDownOnIOThread,
base::Unretained(this)));
WaitForTasksOnIOThread();
}
void TearDownOnMainThread() override { cache_util_.reset(); }
void TearDownOnIOThread() {
iterator_.reset();
DoneCallback(net::OK);
}
// Waiting for tasks to be done on IO thread. --------------------------------
void WaitForTasksOnIOThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
waitable_event_->Wait();
}
void SetNumberOfWaitedTasks(int count) {
void DeleteEntries(
const base::Callback<bool(const disk_cache::Entry*)>& condition) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
remaining_tasks_ = count;
auto* helper =
new ConditionalCacheDeletionHelper(cache_util_->backend(), condition);
helper->DeleteAndDestroySelfWhenFinished(done_callback_);
}
void WaitForCompletion(int value) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (value >= 0) {
// We got the result immediately.
DoneCallback(value);
} else if (value == net::ERR_IO_PENDING) {
// We need to wait for the callback.
} else {
// An error has occurred.
NOTREACHED();
}
void CompareRemainingKeys(std::set<std::string> expected_set) {
std::vector<std::string> remaining_keys = cache_util_->GetEntryKeys();
std::sort(remaining_keys.begin(), remaining_keys.end());
std::vector<std::string> expected;
expected.assign(expected_set.begin(), expected_set.end());
EXPECT_EQ(expected, remaining_keys);
}
void DoneCallback(int value) {
DCHECK_GE(value, 0); // Negative values represent an error.
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (--remaining_tasks_ > 0)
return;
waitable_event_->Signal();
}
// Cache operation shorthands. -----------------------------------------------
void CreateCacheEntries(const std::set<std::string>& keys) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
entries_.resize(keys.size());
SetNumberOfWaitedTasks(keys.size());
int pos = 0;
for (const std::string& key : keys) {
WaitForCompletion(backend_->CreateEntry(
key, &entries_[pos++], done_callback_));
}
}
void DeleteEntries(
const base::Callback<bool(const disk_cache::Entry*)>& condition) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
ConditionalCacheDeletionHelper* helper = new ConditionalCacheDeletionHelper(
backend_,
condition);
WaitForCompletion(helper->DeleteAndDestroySelfWhenFinished(done_callback_));
}
void GetRemainingKeys() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
current_entry_ = nullptr;
iterator_ = backend_->CreateIterator();
GetNextKey(net::OK);
}
void GetNextKey(int error) {
while (error != net::ERR_IO_PENDING) {
if (error == net::ERR_FAILED) {
DoneCallback(net::OK);
return;
}
if (current_entry_) {
remaining_keys_.push_back(current_entry_->GetKey());
}
error = iterator_->OpenNextEntry(
&current_entry_,
base::Bind(&ConditionalCacheDeletionHelperBrowserTest::GetNextKey,
base::Unretained(this)));
}
}
void CompareRemainingKeys(std::set<std::string> expected_set) {
std::vector<std::string> expected;
expected.assign(expected_set.begin(), expected_set.end());
std::sort(remaining_keys_.begin(), remaining_keys_.end());
EXPECT_EQ(expected, remaining_keys_);
void WaitForTasksOnIOThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
waitable_event_->Wait();
}
// Miscellaneous. ------------------------------------------------------------
CacheTestUtil* GetCacheTestUtil() { return cache_util_.get(); }
private:
content::StoragePartition* partition_;
disk_cache::Backend* backend_ = nullptr;
std::unique_ptr<disk_cache::Backend::Iterator> iterator_;
disk_cache::Entry* current_entry_;
std::vector<disk_cache::Entry*> entries_;
base::Callback<void(int)> done_callback_;
std::unique_ptr<CacheTestUtil> cache_util_;
std::unique_ptr<base::WaitableEvent> waitable_event_;
int remaining_tasks_;
std::vector<std::string> remaining_keys_;
};
// Tests that ConditionalCacheDeletionHelper only deletes those cache entries
// that match the condition.
IN_PROC_BROWSER_TEST_F(ConditionalCacheDeletionHelperBrowserTest, Condition) {
// Create 5 entries.
std::set<std::string> keys;
keys.insert("123");
keys.insert("47");
keys.insert("56");
keys.insert("81");
keys.insert("42");
std::set<std::string> keys = {"123", "47", "56", "81", "42"};
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ConditionalCacheDeletionHelperBrowserTest::CreateCacheEntries,
base::Unretained(this),
base::ConstRef(keys)));
WaitForTasksOnIOThread();
GetCacheTestUtil()->CreateCacheEntries(keys);
// Delete the entries whose keys are even numbers.
BrowserThread::PostTask(
......@@ -229,12 +112,6 @@ IN_PROC_BROWSER_TEST_F(ConditionalCacheDeletionHelperBrowserTest, Condition) {
WaitForTasksOnIOThread();
// Expect that the keys with values 56 and 42 were deleted.
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ConditionalCacheDeletionHelperBrowserTest::GetRemainingKeys,
base::Unretained(this)));
WaitForTasksOnIOThread();
keys.erase("56");
keys.erase("42");
CompareRemainingKeys(keys);
......@@ -264,12 +141,7 @@ IN_PROC_BROWSER_TEST_F(ConditionalCacheDeletionHelperBrowserTest,
keys.insert("https://example.com/foo/bar/icon.png");
keys.insert("http://chrome.com");
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ConditionalCacheDeletionHelperBrowserTest::CreateCacheEntries,
base::Unretained(this),
base::ConstRef(keys)));
WaitForTasksOnIOThread();
GetCacheTestUtil()->CreateCacheEntries(keys);
// Wait |timeout_ms| milliseconds for the cache to write the entries.
// This assures that future entries will have timestamps strictly greater than
......@@ -284,12 +156,7 @@ IN_PROC_BROWSER_TEST_F(ConditionalCacheDeletionHelperBrowserTest,
newer_keys.insert("https://example.com/foo/bar/icon3.png");
newer_keys.insert("http://example.com/foo/bar/icon4.png");
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ConditionalCacheDeletionHelperBrowserTest::CreateCacheEntries,
base::Unretained(this),
base::ConstRef(newer_keys)));
WaitForTasksOnIOThread();
GetCacheTestUtil()->CreateCacheEntries(newer_keys);
// Create a condition for entries with the "https://example.com" origin
// created after waiting.
......@@ -306,12 +173,6 @@ IN_PROC_BROWSER_TEST_F(ConditionalCacheDeletionHelperBrowserTest,
WaitForTasksOnIOThread();
// Expect that only "icon2.png" and "icon3.png" were deleted.
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ConditionalCacheDeletionHelperBrowserTest::GetRemainingKeys,
base::Unretained(this)));
WaitForTasksOnIOThread();
keys.insert(newer_keys.begin(), newer_keys.end());
keys.erase("https://example.com/foo/bar/icon2.png");
keys.erase("https://example.com/foo/bar/icon3.png");
......
......@@ -28,7 +28,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/cryptohome/homedir_methods.h"
#include "components/browsing_data/content/storage_partition_http_cache_data_remover.h"
#include "components/browsing_data/content/conditional_cache_counting_helper.h"
#include "components/drive/chromeos/file_system_interface.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_context.h"
......@@ -300,11 +300,11 @@ void StorageManagerHandler::UpdateBrowsingDataSize() {
has_browser_site_data_size_ = false;
Profile* const profile = Profile::FromWebUI(web_ui());
// Fetch the size of http cache in browsing data.
// StoragePartitionHttpCacheDataRemover deletes itself when it is done.
browsing_data::StoragePartitionHttpCacheDataRemover::CreateForRange(
// ConditionalCacheCountingHelper deletes itself when it is done.
browsing_data::ConditionalCacheCountingHelper::CreateForRange(
content::BrowserContext::GetDefaultStoragePartition(profile),
base::Time(),
base::Time::Max())->Count(
base::Time(), base::Time::Max())
->CountAndDestroySelfWhenFinished(
base::Bind(&StorageManagerHandler::OnGetBrowsingDataSize,
weak_ptr_factory_.GetWeakPtr(), false));
......
......@@ -28,7 +28,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/cryptohome/homedir_methods.h"
#include "components/browsing_data/content/storage_partition_http_cache_data_remover.h"
#include "components/browsing_data/content/conditional_cache_counting_helper.h"
#include "components/drive/chromeos/file_system_interface.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_context.h"
......@@ -232,11 +232,11 @@ void StorageHandler::UpdateBrowsingDataSize() {
has_browser_site_data_size_ = false;
Profile* const profile = Profile::FromWebUI(web_ui());
// Fetch the size of http cache in browsing data.
// StoragePartitionHttpCacheDataRemover deletes itself when it is done.
browsing_data::StoragePartitionHttpCacheDataRemover::CreateForRange(
// ConditionalCacheCountingHelper deletes itself when it is done.
browsing_data::ConditionalCacheCountingHelper::CreateForRange(
content::BrowserContext::GetDefaultStoragePartition(profile),
base::Time(),
base::Time::Max())->Count(
base::Time(), base::Time::Max())
->CountAndDestroySelfWhenFinished(
base::Bind(&StorageHandler::OnGetBrowsingDataSize,
base::Unretained(this), false));
......
......@@ -1326,6 +1326,9 @@ test("browser_tests") {
"../browser/browsing_data/browsing_data_remover_test_util.cc",
"../browser/browsing_data/browsing_data_remover_test_util.h",
"../browser/browsing_data/cache_counter_browsertest.cc",
"../browser/browsing_data/cache_test_util.cc",
"../browser/browsing_data/cache_test_util.h",
"../browser/browsing_data/conditional_cache_counting_helper_browsertest.cc",
"../browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc",
"../browser/browsing_data/downloads_counter_browsertest.cc",
"../browser/browsing_data/history_counter_browsertest.cc",
......
......@@ -4,6 +4,8 @@
static_library("content") {
sources = [
"conditional_cache_counting_helper.cc",
"conditional_cache_counting_helper.h",
"conditional_cache_deletion_helper.cc",
"conditional_cache_deletion_helper.h",
"storage_partition_http_cache_data_remover.cc",
......
// Copyright 2016 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/conditional_cache_counting_helper.h"
#include "base/callback.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
using content::BrowserThread;
namespace browsing_data {
// static.
ConditionalCacheCountingHelper* ConditionalCacheCountingHelper::CreateForRange(
content::StoragePartition* storage_partition,
base::Time begin_time,
base::Time end_time) {
return new ConditionalCacheCountingHelper(
begin_time, end_time, storage_partition->GetURLRequestContext(),
storage_partition->GetMediaURLRequestContext());
}
ConditionalCacheCountingHelper::ConditionalCacheCountingHelper(
base::Time begin_time,
base::Time end_time,
net::URLRequestContextGetter* main_context_getter,
net::URLRequestContextGetter* media_context_getter)
: calculation_result_(0),
begin_time_(begin_time),
end_time_(end_time),
is_finished_(false),
main_context_getter_(main_context_getter),
media_context_getter_(media_context_getter),
next_cache_state_(CacheState::NONE),
cache_(nullptr),
iterator_(nullptr),
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
ConditionalCacheCountingHelper::~ConditionalCacheCountingHelper() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
base::WeakPtr<ConditionalCacheCountingHelper>
ConditionalCacheCountingHelper::CountAndDestroySelfWhenFinished(
const CacheCountCallback& result_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!result_callback.is_null());
result_callback_ = result_callback;
calculation_result_ = 0;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ConditionalCacheCountingHelper::CountHttpCacheOnIOThread,
base::Unretained(this)));
return weak_ptr_factory_.GetWeakPtr();
}
bool ConditionalCacheCountingHelper::IsFinished() {
return is_finished_;
}
void ConditionalCacheCountingHelper::Finished() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!is_finished_);
is_finished_ = true;
result_callback_.Run(calculation_result_);
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
void ConditionalCacheCountingHelper::CountHttpCacheOnIOThread() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
next_cache_state_ = CacheState::NONE;
DCHECK_EQ(CacheState::NONE, next_cache_state_);
DCHECK(main_context_getter_.get());
DCHECK(media_context_getter_.get());
next_cache_state_ = CacheState::CREATE_MAIN;
DoCountCache(net::OK);
}
// The expected state sequence is CacheState::NONE --> CacheState::CREATE_MAIN
// --> CacheState::PROCESS_MAIN --> CacheState::CREATE_MEDIA -->
// CacheState::PROCESS_MEDIA --> CacheState::DONE.
// On error, we jump directly to CacheState::DONE.
void ConditionalCacheCountingHelper::DoCountCache(int rv) {
DCHECK_NE(CacheState::NONE, next_cache_state_);
while (rv != net::ERR_IO_PENDING && next_cache_state_ != CacheState::NONE) {
// On error, finish and return the error code. A valid result value might
// be of two types - either net::OK from the CREATE states, or the result
// of calculation from the PROCESS states. Since net::OK == 0, it is valid
// to simply add the value to the final calculation result.
if (rv < 0) {
calculation_result_ = rv;
next_cache_state_ = CacheState::DONE;
} else {
DCHECK_EQ(0, net::OK);
calculation_result_ += rv;
}
switch (next_cache_state_) {
case CacheState::CREATE_MAIN:
case CacheState::CREATE_MEDIA: {
// Get a pointer to the cache.
net::URLRequestContextGetter* getter =
(next_cache_state_ == CacheState::CREATE_MAIN)
? main_context_getter_.get()
: media_context_getter_.get();
net::HttpCache* http_cache = getter->GetURLRequestContext()
->http_transaction_factory()
->GetCache();
next_cache_state_ = (next_cache_state_ == CacheState::CREATE_MAIN)
? CacheState::COUNT_MAIN
: CacheState::COUNT_MEDIA;
rv = http_cache->GetBackend(
&cache_, base::Bind(&ConditionalCacheCountingHelper::DoCountCache,
base::Unretained(this)));
break;
}
case CacheState::COUNT_MAIN:
case CacheState::COUNT_MEDIA: {
next_cache_state_ = (next_cache_state_ == CacheState::COUNT_MAIN)
? CacheState::CREATE_MEDIA
: CacheState::DONE;
// |cache_| can be null if it cannot be initialized.
if (cache_) {
if (begin_time_.is_null() && end_time_.is_max()) {
rv = cache_->CalculateSizeOfAllEntries(
base::Bind(&ConditionalCacheCountingHelper::DoCountCache,
base::Unretained(this)));
} else {
// TODO(dullweber): Readd code for counting with timeout.
// TODO(dullweber): Implement faster counting for SimpleBackendImpl.
rv = cache_->CalculateSizeOfAllEntries(
base::Bind(&ConditionalCacheCountingHelper::DoCountCache,
base::Unretained(this)));
}
cache_ = NULL;
}
break;
}
case CacheState::DONE: {
cache_ = NULL;
next_cache_state_ = CacheState::NONE;
// Notify the UI thread that we are done.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&ConditionalCacheCountingHelper::Finished,
base::Unretained(this)));
return;
}
case CacheState::NONE: {
NOTREACHED() << "bad state";
return;
}
}
}
}
} // namespace browsing_data
// Copyright 2016 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.
#ifndef COMPONENTS_BROWSING_DATA_CONTENT_CONDITIONAL_CACHE_COUNTING_HELPER_H_
#define COMPONENTS_BROWSING_DATA_CONTENT_CONDITIONAL_CACHE_COUNTING_HELPER_H_
#include <memory>
#include "base/callback_forward.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/disk_cache.h"
namespace content {
class StoragePartition;
}
namespace net {
class URLRequestContextGetter;
}
namespace browsing_data {
// Helper to count the size of the http cache data from a StoragePartition.
class ConditionalCacheCountingHelper {
public:
// Returns the number bytes in the selected range.
typedef base::Callback<void(int64_t)> CacheCountCallback;
static ConditionalCacheCountingHelper* CreateForRange(
content::StoragePartition* storage_partition,
base::Time begin_time,
base::Time end_time);
// Count the cache entries according to the specified time range. Destroys
// this instance of ConditionalCacheCountingHelper when finished.
// Must be called on the UI thread!
//
// The |completion_callback| will be invoked when the operation completes.
base::WeakPtr<ConditionalCacheCountingHelper> CountAndDestroySelfWhenFinished(
const CacheCountCallback& result_callback);
bool IsFinished();
private:
enum class CacheState {
NONE,
CREATE_MAIN,
CREATE_MEDIA,
COUNT_MAIN,
COUNT_MEDIA,
DONE
};
friend class base::DeleteHelper<ConditionalCacheCountingHelper>;
ConditionalCacheCountingHelper(
base::Time begin_time,
base::Time end_time,
net::URLRequestContextGetter* main_context_getter,
net::URLRequestContextGetter* media_context_getter);
~ConditionalCacheCountingHelper();
void Finished();
void CountHttpCacheOnIOThread();
void DoCountCache(int rv);
// Stores the cache size computation result before it can be returned
// via a callback. This is either the sum of size of the the two cache
// backends, or an error code if the calculation failed.
int64_t calculation_result_;
CacheCountCallback result_callback_;
const base::Time begin_time_;
const base::Time end_time_;
bool is_finished_;
const scoped_refptr<net::URLRequestContextGetter> main_context_getter_;
const scoped_refptr<net::URLRequestContextGetter> media_context_getter_;
CacheState next_cache_state_;
disk_cache::Backend* cache_;
std::unique_ptr<disk_cache::Backend::Iterator> iterator_;
base::WeakPtrFactory<ConditionalCacheCountingHelper> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ConditionalCacheCountingHelper);
};
} // namespace browsing_data
#endif // COMPONENTS_BROWSING_DATA_CONTENT_CONDITIONAL_CACHE_COUNTING_HELPER_H_
......@@ -17,8 +17,8 @@ bool EntryPredicateFromURLsAndTime(
const base::Time& begin_time,
const base::Time& end_time,
const disk_cache::Entry* entry) {
return (entry->GetLastModified() >= begin_time &&
entry->GetLastModified() < end_time &&
return (entry->GetLastUsed() >= begin_time &&
entry->GetLastUsed() < end_time &&
url_predicate.Run(GURL(entry->GetKey())));
}
......@@ -76,7 +76,7 @@ void ConditionalCacheDeletionHelper::IterateOverEntries(int error) {
}
if (error == net::ERR_FAILED) {
// The iteration finished successfuly or we can no longer iterate
// The iteration finished successfully or we can no longer iterate
// (e.g. the cache was destroyed). We cannot distinguish between the two,
// but we know that there is nothing more that we can do, so we return OK.
base::ThreadTaskRunnerHandle::Get()->PostTask(
......
......@@ -34,10 +34,8 @@ StoragePartitionHttpCacheDataRemover::StoragePartitionHttpCacheDataRemover(
delete_end_(delete_end),
main_context_getter_(main_context_getter),
media_context_getter_(media_context_getter),
next_cache_state_(STATE_NONE),
cache_(nullptr),
calculation_result_(0) {
}
next_cache_state_(CacheState::NONE),
cache_(nullptr) {}
StoragePartitionHttpCacheDataRemover::~StoragePartitionHttpCacheDataRemover() {
}
......@@ -81,76 +79,45 @@ void StoragePartitionHttpCacheDataRemover::Remove(
base::Unretained(this)));
}
void StoragePartitionHttpCacheDataRemover::Count(
const net::Int64CompletionCallback& result_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!result_callback.is_null());
result_callback_ = result_callback;
calculation_result_ = 0;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(
&StoragePartitionHttpCacheDataRemover::CountHttpCacheOnIOThread,
base::Unretained(this)));
}
void StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
next_cache_state_ = STATE_NONE;
DCHECK_EQ(STATE_NONE, next_cache_state_);
next_cache_state_ = CacheState::NONE;
DCHECK_EQ(CacheState::NONE, next_cache_state_);
DCHECK(main_context_getter_.get());
DCHECK(media_context_getter_.get());
next_cache_state_ = STATE_CREATE_MAIN;
next_cache_state_ = CacheState::CREATE_MAIN;
DoClearCache(net::OK);
}
void StoragePartitionHttpCacheDataRemover::CountHttpCacheOnIOThread() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
next_cache_state_ = STATE_NONE;
DCHECK_EQ(STATE_NONE, next_cache_state_);
DCHECK(main_context_getter_.get());
DCHECK(media_context_getter_.get());
next_cache_state_ = STATE_CREATE_MAIN;
DoCountCache(net::OK);
}
void StoragePartitionHttpCacheDataRemover::ClearedHttpCache() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
done_callback_.Run();
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
void StoragePartitionHttpCacheDataRemover::CountedHttpCache() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
result_callback_.Run(calculation_result_);
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
// The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN -->
// STATE_PROCESS_MAIN --> STATE_CREATE_MEDIA --> STATE_PROCESS_MEDIA -->
// STATE_DONE, and any errors are ignored.
// The expected state sequence is CacheState::NONE --> CacheState::CREATE_MAIN
// --> CacheState::PROCESS_MAIN --> CacheState::CREATE_MEDIA -->
// CacheState::PROCESS_MEDIA --> CacheState::DONE, and any errors are ignored.
void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
DCHECK_NE(STATE_NONE, next_cache_state_);
DCHECK_NE(CacheState::NONE, next_cache_state_);
while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) {
while (rv != net::ERR_IO_PENDING && next_cache_state_ != CacheState::NONE) {
switch (next_cache_state_) {
case STATE_CREATE_MAIN:
case STATE_CREATE_MEDIA: {
case CacheState::CREATE_MAIN:
case CacheState::CREATE_MEDIA: {
// Get a pointer to the cache.
net::URLRequestContextGetter* getter =
(next_cache_state_ == STATE_CREATE_MAIN)
(next_cache_state_ == CacheState::CREATE_MAIN)
? main_context_getter_.get()
: media_context_getter_.get();
net::HttpCache* http_cache = getter->GetURLRequestContext()
->http_transaction_factory()
->GetCache();
next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN)
? STATE_PROCESS_MAIN
: STATE_PROCESS_MEDIA;
next_cache_state_ = (next_cache_state_ == CacheState::CREATE_MAIN)
? CacheState::DELETE_MAIN
: CacheState::DELETE_MEDIA;
// Clear QUIC server information from memory and the disk cache.
http_cache->GetSession()
......@@ -172,11 +139,11 @@ void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
base::Unretained(this)));
break;
}
case STATE_PROCESS_MAIN:
case STATE_PROCESS_MEDIA: {
next_cache_state_ = (next_cache_state_ == STATE_PROCESS_MAIN)
? STATE_CREATE_MEDIA
: STATE_DONE;
case CacheState::DELETE_MAIN:
case CacheState::DELETE_MEDIA: {
next_cache_state_ = (next_cache_state_ == CacheState::DELETE_MAIN)
? CacheState::CREATE_MEDIA
: CacheState::DONE;
// |cache_| can be null if it cannot be initialized.
if (cache_) {
......@@ -205,9 +172,9 @@ void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
}
break;
}
case STATE_DONE: {
case CacheState::DONE: {
cache_ = NULL;
next_cache_state_ = STATE_NONE;
next_cache_state_ = CacheState::NONE;
// Notify the UI thread that we are done.
BrowserThread::PostTask(
......@@ -216,91 +183,8 @@ void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
base::Unretained(this)));
return;
}
default: {
NOTREACHED() << "bad state";
next_cache_state_ = STATE_NONE; // Stop looping.
return;
}
}
}
}
// The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN -->
// STATE_PROCESS_MAIN --> STATE_CREATE_MEDIA --> STATE_PROCESS_MEDIA -->
// STATE_DONE. On error, we jump directly to STATE_DONE.
void StoragePartitionHttpCacheDataRemover::DoCountCache(int rv) {
DCHECK_NE(STATE_NONE, next_cache_state_);
while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) {
// On error, finish and return the error code. A valid result value might
// be of two types - either net::OK from the CREATE states, or the result
// of calculation from the PROCESS states. Since net::OK == 0, it is valid
// to simply add the value to the final calculation result.
if (rv < 0) {
calculation_result_ = rv;
next_cache_state_ = STATE_DONE;
} else {
DCHECK_EQ(0, net::OK);
calculation_result_ += rv;
}
switch (next_cache_state_) {
case STATE_CREATE_MAIN:
case STATE_CREATE_MEDIA: {
// Get a pointer to the cache.
net::URLRequestContextGetter* getter =
(next_cache_state_ == STATE_CREATE_MAIN)
? main_context_getter_.get()
: media_context_getter_.get();
net::HttpCache* http_cache = getter->GetURLRequestContext()
->http_transaction_factory()
->GetCache();
next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN)
? STATE_PROCESS_MAIN
: STATE_PROCESS_MEDIA;
rv = http_cache->GetBackend(
&cache_,
base::Bind(&StoragePartitionHttpCacheDataRemover::DoCountCache,
base::Unretained(this)));
break;
}
case STATE_PROCESS_MAIN:
case STATE_PROCESS_MEDIA: {
next_cache_state_ = (next_cache_state_ == STATE_PROCESS_MAIN)
? STATE_CREATE_MEDIA
: STATE_DONE;
// |cache_| can be null if it cannot be initialized.
if (cache_) {
if (delete_begin_.is_null() && delete_end_.is_max()) {
rv = cache_->CalculateSizeOfAllEntries(
base::Bind(
&StoragePartitionHttpCacheDataRemover::DoCountCache,
base::Unretained(this)));
} else {
// TODO(msramek): Implement this when we need it.
DoCountCache(net::ERR_NOT_IMPLEMENTED);
}
cache_ = NULL;
}
break;
}
case STATE_DONE: {
cache_ = NULL;
next_cache_state_ = STATE_NONE;
// Notify the UI thread that we are done.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&StoragePartitionHttpCacheDataRemover::CountedHttpCache,
base::Unretained(this)));
return;
}
default: {
case CacheState::NONE: {
NOTREACHED() << "bad state";
next_cache_state_ = STATE_NONE; // Stop looping.
return;
}
}
......
......@@ -51,18 +51,14 @@ class StoragePartitionHttpCacheDataRemover {
// Calls |done_callback| upon completion and also destroys itself.
void Remove(const base::Closure& done_callback);
// Counts the total size of entries that would be removed by calling |Remove|.
// Reports it via |result_callback| and then destroys itself.
void Count(const net::Int64CompletionCallback& result_callback);
private:
enum CacheState {
STATE_NONE,
STATE_CREATE_MAIN,
STATE_CREATE_MEDIA,
STATE_PROCESS_MAIN,
STATE_PROCESS_MEDIA,
STATE_DONE
NONE,
CREATE_MAIN,
CREATE_MEDIA,
DELETE_MAIN,
DELETE_MEDIA,
DONE
};
StoragePartitionHttpCacheDataRemover(
......@@ -80,14 +76,9 @@ class StoragePartitionHttpCacheDataRemover {
~StoragePartitionHttpCacheDataRemover();
void ClearHttpCacheOnIOThread();
void CountHttpCacheOnIOThread();
void ClearedHttpCache();
void CountedHttpCache();
// Performs the actual work to delete or count the cache.
void DoClearCache(int rv);
void DoCountCache(int rv);
base::Callback<bool(const GURL&)> url_predicate_;
const base::Time delete_begin_;
......@@ -97,17 +88,11 @@ class StoragePartitionHttpCacheDataRemover {
const scoped_refptr<net::URLRequestContextGetter> media_context_getter_;
base::Closure done_callback_;
net::Int64CompletionCallback result_callback_;
// IO.
int next_cache_state_;
disk_cache::Backend* cache_;
// Stores the cache size computation result before it can be returned
// via a callback. This is either the sum of size of the the two cache
// backends, or an error code if the calculation failed.
int64_t calculation_result_;
DISALLOW_COPY_AND_ASSIGN(StoragePartitionHttpCacheDataRemover);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment