| Index: ios/chrome/browser/browsing_data/cache_counter.cc
|
| diff --git a/ios/chrome/browser/browsing_data/cache_counter.cc b/ios/chrome/browser/browsing_data/cache_counter.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ada6b75652ba5cf7592a3c2a0e40662b938d3e17
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/browsing_data/cache_counter.cc
|
| @@ -0,0 +1,144 @@
|
| +// 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/bind.h"
|
| +#include "components/browsing_data/core/pref_names.h"
|
| +#include "ios/chrome/browser/browsing_data/cache_counter.h"
|
| +#include "ios/web/public/browser_state.h"
|
| +#include "ios/web/public/web_thread.h"
|
| +#include "net/base/completion_callback.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "net/disk_cache/disk_cache.h"
|
| +#include "net/http/http_cache.h"
|
| +#include "net/http/http_transaction_factory.h"
|
| +#include "net/url_request/url_request_context.h"
|
| +#include "net/url_request/url_request_context_getter.h"
|
| +
|
| +namespace {
|
| +
|
| +class IOThreadCacheCounter {
|
| + public:
|
| + IOThreadCacheCounter(
|
| + const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
| + const net::CompletionCallback& result_callback)
|
| + : next_step_(STEP_GET_BACKEND),
|
| + context_getter_(context_getter),
|
| + result_callback_(result_callback),
|
| + result_(0),
|
| + backend_(nullptr) {}
|
| +
|
| + void Count() {
|
| + web::WebThread::PostTask(web::WebThread::IO, FROM_HERE,
|
| + base::Bind(&IOThreadCacheCounter::CountInternal,
|
| + base::Unretained(this), net::OK));
|
| + }
|
| +
|
| + private:
|
| + enum Step {
|
| + STEP_GET_BACKEND, // Get the disk_cache::Backend instance.
|
| + STEP_COUNT, // Run CalculateSizeOfAllEntries() on it.
|
| + STEP_CALLBACK, // Respond on the UI thread.
|
| + STEP_DONE // Calculation completed.
|
| + };
|
| +
|
| + void CountInternal(int rv) {
|
| + DCHECK_CURRENTLY_ON(web::WebThread::IO);
|
| +
|
| + while (rv != net::ERR_IO_PENDING && next_step_ != STEP_DONE) {
|
| + // In case of an error, skip to the last step.
|
| + if (rv < 0)
|
| + next_step_ = STEP_CALLBACK;
|
| +
|
| + // Process the counting in three steps: STEP_GET_BACKEND -> STEP_COUNT ->
|
| + // -> STEP_CALLBACK.
|
| + switch (next_step_) {
|
| + case STEP_GET_BACKEND: {
|
| + next_step_ = STEP_COUNT;
|
| +
|
| + net::HttpCache* http_cache = context_getter_->GetURLRequestContext()
|
| + ->http_transaction_factory()
|
| + ->GetCache();
|
| +
|
| + rv = http_cache->GetBackend(
|
| + &backend_, base::Bind(&IOThreadCacheCounter::CountInternal,
|
| + base::Unretained(this)));
|
| + break;
|
| + }
|
| +
|
| + case STEP_COUNT: {
|
| + next_step_ = STEP_CALLBACK;
|
| +
|
| + DCHECK(backend_);
|
| + rv = backend_->CalculateSizeOfAllEntries(base::Bind(
|
| + &IOThreadCacheCounter::CountInternal, base::Unretained(this)));
|
| + break;
|
| + }
|
| +
|
| + case STEP_CALLBACK: {
|
| + next_step_ = STEP_DONE;
|
| + result_ = rv;
|
| +
|
| + web::WebThread::PostTask(
|
| + web::WebThread::UI, FROM_HERE,
|
| + base::Bind(&IOThreadCacheCounter::OnCountingFinished,
|
| + base::Unretained(this)));
|
| +
|
| + break;
|
| + }
|
| +
|
| + case STEP_DONE: {
|
| + NOTREACHED();
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + void OnCountingFinished() {
|
| + DCHECK_CURRENTLY_ON(web::WebThread::UI);
|
| + result_callback_.Run(result_);
|
| + delete this;
|
| + }
|
| +
|
| + Step next_step_;
|
| + scoped_refptr<net::URLRequestContextGetter> context_getter_;
|
| + net::CompletionCallback result_callback_;
|
| + int result_;
|
| + disk_cache::Backend* backend_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +CacheCounter::CacheCounter(web::BrowserState* browser_state)
|
| + : pending_(false), browser_state_(browser_state), weak_ptr_factory_(this) {}
|
| +
|
| +CacheCounter::~CacheCounter() {}
|
| +
|
| +const char* CacheCounter::GetPrefName() const {
|
| + return browsing_data::prefs::kDeleteCache;
|
| +}
|
| +
|
| +void CacheCounter::Count() {
|
| + // TODO(msramek): disk_cache::Backend 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.
|
| + pending_ = true;
|
| +
|
| + // IOThreadCacheCounter deletes itself when done.
|
| + (new IOThreadCacheCounter(browser_state_->GetRequestContext(),
|
| + base::Bind(&CacheCounter::OnCacheSizeCalculated,
|
| + weak_ptr_factory_.GetWeakPtr())))
|
| + ->Count();
|
| +}
|
| +
|
| +void CacheCounter::OnCacheSizeCalculated(int result_bytes) {
|
| + pending_ = false;
|
| +
|
| + // A value less than 0 means a net error code.
|
| + if (result_bytes < 0)
|
| + return;
|
| +
|
| + ReportResult(result_bytes);
|
| +}
|
|
|