OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/bind.h" |
| 6 #include "components/browsing_data/core/pref_names.h" |
| 7 #include "ios/chrome/browser/browsing_data/cache_counter.h" |
| 8 #include "ios/web/public/browser_state.h" |
| 9 #include "ios/web/public/web_thread.h" |
| 10 #include "net/base/completion_callback.h" |
| 11 #include "net/base/net_errors.h" |
| 12 #include "net/disk_cache/disk_cache.h" |
| 13 #include "net/http/http_cache.h" |
| 14 #include "net/http/http_transaction_factory.h" |
| 15 #include "net/url_request/url_request_context.h" |
| 16 #include "net/url_request/url_request_context_getter.h" |
| 17 |
| 18 namespace { |
| 19 |
| 20 class IOThreadCacheCounter { |
| 21 public: |
| 22 IOThreadCacheCounter( |
| 23 const scoped_refptr<net::URLRequestContextGetter>& context_getter, |
| 24 const net::CompletionCallback& result_callback) |
| 25 : next_step_(STEP_GET_BACKEND), |
| 26 context_getter_(context_getter), |
| 27 result_callback_(result_callback), |
| 28 result_(0), |
| 29 backend_(nullptr) {} |
| 30 |
| 31 void Count() { |
| 32 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, |
| 33 base::Bind(&IOThreadCacheCounter::CountInternal, |
| 34 base::Unretained(this), net::OK)); |
| 35 } |
| 36 |
| 37 private: |
| 38 enum Step { |
| 39 STEP_GET_BACKEND, // Get the disk_cache::Backend instance. |
| 40 STEP_COUNT, // Run CalculateSizeOfAllEntries() on it. |
| 41 STEP_CALLBACK, // Respond on the UI thread. |
| 42 STEP_DONE // Calculation completed. |
| 43 }; |
| 44 |
| 45 void CountInternal(int rv) { |
| 46 DCHECK_CURRENTLY_ON(web::WebThread::IO); |
| 47 |
| 48 while (rv != net::ERR_IO_PENDING && next_step_ != STEP_DONE) { |
| 49 // In case of an error, skip to the last step. |
| 50 if (rv < 0) |
| 51 next_step_ = STEP_CALLBACK; |
| 52 |
| 53 // Process the counting in three steps: STEP_GET_BACKEND -> STEP_COUNT -> |
| 54 // -> STEP_CALLBACK. |
| 55 switch (next_step_) { |
| 56 case STEP_GET_BACKEND: { |
| 57 next_step_ = STEP_COUNT; |
| 58 |
| 59 net::HttpCache* http_cache = context_getter_->GetURLRequestContext() |
| 60 ->http_transaction_factory() |
| 61 ->GetCache(); |
| 62 |
| 63 rv = http_cache->GetBackend( |
| 64 &backend_, base::Bind(&IOThreadCacheCounter::CountInternal, |
| 65 base::Unretained(this))); |
| 66 break; |
| 67 } |
| 68 |
| 69 case STEP_COUNT: { |
| 70 next_step_ = STEP_CALLBACK; |
| 71 |
| 72 DCHECK(backend_); |
| 73 rv = backend_->CalculateSizeOfAllEntries(base::Bind( |
| 74 &IOThreadCacheCounter::CountInternal, base::Unretained(this))); |
| 75 break; |
| 76 } |
| 77 |
| 78 case STEP_CALLBACK: { |
| 79 next_step_ = STEP_DONE; |
| 80 result_ = rv; |
| 81 |
| 82 web::WebThread::PostTask( |
| 83 web::WebThread::UI, FROM_HERE, |
| 84 base::Bind(&IOThreadCacheCounter::OnCountingFinished, |
| 85 base::Unretained(this))); |
| 86 |
| 87 break; |
| 88 } |
| 89 |
| 90 case STEP_DONE: { |
| 91 NOTREACHED(); |
| 92 } |
| 93 } |
| 94 } |
| 95 } |
| 96 |
| 97 void OnCountingFinished() { |
| 98 DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| 99 result_callback_.Run(result_); |
| 100 delete this; |
| 101 } |
| 102 |
| 103 Step next_step_; |
| 104 scoped_refptr<net::URLRequestContextGetter> context_getter_; |
| 105 net::CompletionCallback result_callback_; |
| 106 int result_; |
| 107 disk_cache::Backend* backend_; |
| 108 }; |
| 109 |
| 110 } // namespace |
| 111 |
| 112 CacheCounter::CacheCounter(web::BrowserState* browser_state) |
| 113 : pending_(false), browser_state_(browser_state), weak_ptr_factory_(this) {} |
| 114 |
| 115 CacheCounter::~CacheCounter() {} |
| 116 |
| 117 const char* CacheCounter::GetPrefName() const { |
| 118 return browsing_data::prefs::kDeleteCache; |
| 119 } |
| 120 |
| 121 void CacheCounter::Count() { |
| 122 // TODO(msramek): disk_cache::Backend currently does not implement counting |
| 123 // for subsets of cache, only for the entire cache. Thus, we ignore the time |
| 124 // period setting and always request counting for the unbounded time interval. |
| 125 // It is up to the UI to interpret the results for finite time intervals as |
| 126 // upper estimates. |
| 127 pending_ = true; |
| 128 |
| 129 // IOThreadCacheCounter deletes itself when done. |
| 130 (new IOThreadCacheCounter(browser_state_->GetRequestContext(), |
| 131 base::Bind(&CacheCounter::OnCacheSizeCalculated, |
| 132 weak_ptr_factory_.GetWeakPtr()))) |
| 133 ->Count(); |
| 134 } |
| 135 |
| 136 void CacheCounter::OnCacheSizeCalculated(int result_bytes) { |
| 137 pending_ = false; |
| 138 |
| 139 // A value less than 0 means a net error code. |
| 140 if (result_bytes < 0) |
| 141 return; |
| 142 |
| 143 ReportResult(result_bytes); |
| 144 } |
OLD | NEW |