OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/browsing_data/storage_partition_http_cache_data_remover.h" | 5 #include "components/browsing_data/storage_partition_http_cache_data_remover.h" |
6 | 6 |
7 #include "content/public/browser/browser_thread.h" | 7 #include "content/public/browser/browser_thread.h" |
8 #include "content/public/browser/storage_partition.h" | 8 #include "content/public/browser/storage_partition.h" |
9 #include "net/base/sdch_manager.h" | 9 #include "net/base/sdch_manager.h" |
| 10 #include "net/disk_cache/blockfile/backend_impl.h" |
10 #include "net/disk_cache/disk_cache.h" | 11 #include "net/disk_cache/disk_cache.h" |
| 12 #include "net/disk_cache/memory/mem_backend_impl.h" |
| 13 #include "net/disk_cache/simple/simple_backend_impl.h" |
11 #include "net/http/http_cache.h" | 14 #include "net/http/http_cache.h" |
12 #include "net/url_request/url_request_context.h" | 15 #include "net/url_request/url_request_context.h" |
13 #include "net/url_request/url_request_context_getter.h" | 16 #include "net/url_request/url_request_context_getter.h" |
14 | 17 |
15 using content::BrowserThread; | 18 using content::BrowserThread; |
16 | 19 |
17 namespace browsing_data { | 20 namespace browsing_data { |
18 | 21 |
19 StoragePartitionHttpCacheDataRemover::StoragePartitionHttpCacheDataRemover( | 22 StoragePartitionHttpCacheDataRemover::StoragePartitionHttpCacheDataRemover( |
20 base::Time delete_begin, | 23 base::Time delete_begin, |
21 base::Time delete_end, | 24 base::Time delete_end, |
22 net::URLRequestContextGetter* main_context_getter, | 25 net::URLRequestContextGetter* main_context_getter, |
23 net::URLRequestContextGetter* media_context_getter) | 26 net::URLRequestContextGetter* media_context_getter) |
24 : delete_begin_(delete_begin), | 27 : delete_begin_(delete_begin), |
25 delete_end_(delete_end), | 28 delete_end_(delete_end), |
26 main_context_getter_(main_context_getter), | 29 main_context_getter_(main_context_getter), |
27 media_context_getter_(media_context_getter), | 30 media_context_getter_(media_context_getter), |
28 next_cache_state_(STATE_NONE), | 31 next_cache_state_(STATE_NONE), |
29 cache_(nullptr) { | 32 cache_(nullptr), |
| 33 calculation_result_(0) { |
30 } | 34 } |
31 | 35 |
32 StoragePartitionHttpCacheDataRemover::~StoragePartitionHttpCacheDataRemover() { | 36 StoragePartitionHttpCacheDataRemover::~StoragePartitionHttpCacheDataRemover() { |
33 } | 37 } |
34 | 38 |
35 // static. | 39 // static. |
36 StoragePartitionHttpCacheDataRemover* | 40 StoragePartitionHttpCacheDataRemover* |
37 StoragePartitionHttpCacheDataRemover::CreateForRange( | 41 StoragePartitionHttpCacheDataRemover::CreateForRange( |
38 content::StoragePartition* storage_partition, | 42 content::StoragePartition* storage_partition, |
39 base::Time delete_begin, | 43 base::Time delete_begin, |
40 base::Time delete_end) { | 44 base::Time delete_end) { |
41 return new StoragePartitionHttpCacheDataRemover( | 45 return new StoragePartitionHttpCacheDataRemover( |
42 delete_begin, delete_end, storage_partition->GetURLRequestContext(), | 46 delete_begin, delete_end, storage_partition->GetURLRequestContext(), |
43 storage_partition->GetMediaURLRequestContext()); | 47 storage_partition->GetMediaURLRequestContext()); |
44 } | 48 } |
45 | 49 |
46 void StoragePartitionHttpCacheDataRemover::Remove( | 50 void StoragePartitionHttpCacheDataRemover::Remove( |
47 const base::Closure& done_callback) { | 51 const base::Closure& done_callback) { |
48 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 52 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
49 DCHECK(!done_callback.is_null()); | 53 DCHECK(!done_callback.is_null()); |
50 done_callback_ = done_callback; | 54 done_callback_ = done_callback; |
51 | 55 |
52 BrowserThread::PostTask( | 56 BrowserThread::PostTask( |
53 BrowserThread::IO, FROM_HERE, | 57 BrowserThread::IO, FROM_HERE, |
54 base::Bind( | 58 base::Bind( |
55 &StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread, | 59 &StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread, |
56 base::Unretained(this))); | 60 base::Unretained(this))); |
57 } | 61 } |
58 | 62 |
| 63 void StoragePartitionHttpCacheDataRemover::Count( |
| 64 const net::Int64CompletionCallback& result_callback) { |
| 65 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 66 DCHECK(!result_callback.is_null()); |
| 67 result_callback_ = result_callback; |
| 68 calculation_result_ = 0; |
| 69 |
| 70 BrowserThread::PostTask( |
| 71 BrowserThread::IO, FROM_HERE, |
| 72 base::Bind( |
| 73 &StoragePartitionHttpCacheDataRemover::CountHttpCacheOnIOThread, |
| 74 base::Unretained(this))); |
| 75 } |
| 76 |
59 void StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread() { | 77 void StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread() { |
60 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 78 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
61 next_cache_state_ = STATE_NONE; | 79 next_cache_state_ = STATE_NONE; |
62 DCHECK_EQ(STATE_NONE, next_cache_state_); | 80 DCHECK_EQ(STATE_NONE, next_cache_state_); |
63 DCHECK(main_context_getter_.get()); | 81 DCHECK(main_context_getter_.get()); |
64 DCHECK(media_context_getter_.get()); | 82 DCHECK(media_context_getter_.get()); |
65 | 83 |
66 next_cache_state_ = STATE_CREATE_MAIN; | 84 next_cache_state_ = STATE_CREATE_MAIN; |
67 DoClearCache(net::OK); | 85 DoClearCache(net::OK); |
68 } | 86 } |
69 | 87 |
| 88 void StoragePartitionHttpCacheDataRemover::CountHttpCacheOnIOThread() { |
| 89 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 90 next_cache_state_ = STATE_NONE; |
| 91 DCHECK_EQ(STATE_NONE, next_cache_state_); |
| 92 DCHECK(main_context_getter_.get()); |
| 93 DCHECK(media_context_getter_.get()); |
| 94 |
| 95 next_cache_state_ = STATE_CREATE_MAIN; |
| 96 DoCountCache(net::OK); |
| 97 } |
| 98 |
70 void StoragePartitionHttpCacheDataRemover::ClearedHttpCache() { | 99 void StoragePartitionHttpCacheDataRemover::ClearedHttpCache() { |
71 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 100 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
72 done_callback_.Run(); | 101 done_callback_.Run(); |
73 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 102 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
74 } | 103 } |
75 | 104 |
| 105 void StoragePartitionHttpCacheDataRemover::CountedHttpCache() { |
| 106 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 107 result_callback_.Run(calculation_result_); |
| 108 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 109 } |
| 110 |
76 // The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN --> | 111 // The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN --> |
77 // STATE_DELETE_MAIN --> STATE_CREATE_MEDIA --> STATE_DELETE_MEDIA --> | 112 // STATE_PROCESS_MAIN --> STATE_CREATE_MEDIA --> STATE_PROCESS_MEDIA --> |
78 // STATE_DONE, and any errors are ignored. | 113 // STATE_DONE, and any errors are ignored. |
79 void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) { | 114 void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) { |
80 DCHECK_NE(STATE_NONE, next_cache_state_); | 115 DCHECK_NE(STATE_NONE, next_cache_state_); |
81 | 116 |
82 while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) { | 117 while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) { |
83 switch (next_cache_state_) { | 118 switch (next_cache_state_) { |
84 case STATE_CREATE_MAIN: | 119 case STATE_CREATE_MAIN: |
85 case STATE_CREATE_MEDIA: { | 120 case STATE_CREATE_MEDIA: { |
86 // Get a pointer to the cache. | 121 // Get a pointer to the cache. |
87 net::URLRequestContextGetter* getter = | 122 net::URLRequestContextGetter* getter = |
88 (next_cache_state_ == STATE_CREATE_MAIN) | 123 (next_cache_state_ == STATE_CREATE_MAIN) |
89 ? main_context_getter_.get() | 124 ? main_context_getter_.get() |
90 : media_context_getter_.get(); | 125 : media_context_getter_.get(); |
91 net::HttpCache* http_cache = getter->GetURLRequestContext() | 126 net::HttpCache* http_cache = getter->GetURLRequestContext() |
92 ->http_transaction_factory() | 127 ->http_transaction_factory() |
93 ->GetCache(); | 128 ->GetCache(); |
94 | 129 |
95 next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN) | 130 next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN) |
96 ? STATE_DELETE_MAIN | 131 ? STATE_PROCESS_MAIN |
97 : STATE_DELETE_MEDIA; | 132 : STATE_PROCESS_MEDIA; |
98 | 133 |
99 // Clear QUIC server information from memory and the disk cache. | 134 // Clear QUIC server information from memory and the disk cache. |
100 http_cache->GetSession() | 135 http_cache->GetSession() |
101 ->quic_stream_factory() | 136 ->quic_stream_factory() |
102 ->ClearCachedStatesInCryptoConfig(); | 137 ->ClearCachedStatesInCryptoConfig(); |
103 | 138 |
104 // Clear SDCH dictionary state. | 139 // Clear SDCH dictionary state. |
105 net::SdchManager* sdch_manager = | 140 net::SdchManager* sdch_manager = |
106 getter->GetURLRequestContext()->sdch_manager(); | 141 getter->GetURLRequestContext()->sdch_manager(); |
107 // The test is probably overkill, since chrome should always have an | 142 // The test is probably overkill, since chrome should always have an |
108 // SdchManager. But in general the URLRequestContext is *not* | 143 // SdchManager. But in general the URLRequestContext is *not* |
109 // guaranteed to have an SdchManager, so checking is wise. | 144 // guaranteed to have an SdchManager, so checking is wise. |
110 if (sdch_manager) | 145 if (sdch_manager) |
111 sdch_manager->ClearData(); | 146 sdch_manager->ClearData(); |
112 | 147 |
113 rv = http_cache->GetBackend( | 148 rv = http_cache->GetBackend( |
114 &cache_, | 149 &cache_, |
115 base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache, | 150 base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache, |
116 base::Unretained(this))); | 151 base::Unretained(this))); |
117 break; | 152 break; |
118 } | 153 } |
119 case STATE_DELETE_MAIN: | 154 case STATE_PROCESS_MAIN: |
120 case STATE_DELETE_MEDIA: { | 155 case STATE_PROCESS_MEDIA: { |
121 next_cache_state_ = (next_cache_state_ == STATE_DELETE_MAIN) | 156 next_cache_state_ = (next_cache_state_ == STATE_PROCESS_MAIN) |
122 ? STATE_CREATE_MEDIA | 157 ? STATE_CREATE_MEDIA |
123 : STATE_DONE; | 158 : STATE_DONE; |
124 | 159 |
125 // |cache_| can be null if it cannot be initialized. | 160 // |cache_| can be null if it cannot be initialized. |
126 if (cache_) { | 161 if (cache_) { |
127 if (delete_begin_.is_null()) { | 162 if (delete_begin_.is_null() && delete_end_.is_max()) { |
128 rv = cache_->DoomAllEntries( | 163 rv = cache_->DoomAllEntries(base::Bind( |
129 base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache, | 164 &StoragePartitionHttpCacheDataRemover::DoClearCache, |
130 base::Unretained(this))); | 165 base::Unretained(this))); |
131 } else { | 166 } else { |
132 rv = cache_->DoomEntriesBetween( | 167 rv = cache_->DoomEntriesBetween( |
133 delete_begin_, delete_end_, | 168 delete_begin_, delete_end_, |
134 base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache, | 169 base::Bind( |
135 base::Unretained(this))); | 170 &StoragePartitionHttpCacheDataRemover::DoClearCache, |
| 171 base::Unretained(this))); |
136 } | 172 } |
137 cache_ = NULL; | 173 cache_ = NULL; |
138 } | 174 } |
139 break; | 175 break; |
140 } | 176 } |
141 case STATE_DONE: { | 177 case STATE_DONE: { |
142 cache_ = NULL; | 178 cache_ = NULL; |
143 next_cache_state_ = STATE_NONE; | 179 next_cache_state_ = STATE_NONE; |
144 | 180 |
145 // Notify the UI thread that we are done. | 181 // Notify the UI thread that we are done. |
146 BrowserThread::PostTask( | 182 BrowserThread::PostTask( |
147 BrowserThread::UI, FROM_HERE, | 183 BrowserThread::UI, FROM_HERE, |
148 base::Bind(&StoragePartitionHttpCacheDataRemover::ClearedHttpCache, | 184 base::Bind(&StoragePartitionHttpCacheDataRemover::ClearedHttpCache, |
149 base::Unretained(this))); | 185 base::Unretained(this))); |
150 return; | 186 return; |
151 } | 187 } |
152 default: { | 188 default: { |
153 NOTREACHED() << "bad state"; | 189 NOTREACHED() << "bad state"; |
154 next_cache_state_ = STATE_NONE; // Stop looping. | 190 next_cache_state_ = STATE_NONE; // Stop looping. |
155 return; | 191 return; |
156 } | 192 } |
157 } | 193 } |
158 } | 194 } |
159 } | 195 } |
160 | 196 |
| 197 // The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN --> |
| 198 // STATE_PROCESS_MAIN --> STATE_CREATE_MEDIA --> STATE_PROCESS_MEDIA --> |
| 199 // STATE_DONE. On error, we jump directly to STATE_DONE. |
| 200 void StoragePartitionHttpCacheDataRemover::DoCountCache(int rv) { |
| 201 DCHECK_NE(STATE_NONE, next_cache_state_); |
| 202 |
| 203 while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) { |
| 204 // On error, finish and return the error code. A valid result value might |
| 205 // be of two types - either net::OK from the CREATE states, or the result |
| 206 // of calculation from the PROCESS states. Since net::OK == 0, it is valid |
| 207 // to simply add the value to the final calculation result. |
| 208 if (rv < 0) { |
| 209 calculation_result_ = rv; |
| 210 next_cache_state_ = STATE_DONE; |
| 211 } else { |
| 212 DCHECK_EQ(0, net::OK); |
| 213 calculation_result_ += rv; |
| 214 } |
| 215 |
| 216 switch (next_cache_state_) { |
| 217 case STATE_CREATE_MAIN: |
| 218 case STATE_CREATE_MEDIA: { |
| 219 // Get a pointer to the cache. |
| 220 net::URLRequestContextGetter* getter = |
| 221 (next_cache_state_ == STATE_CREATE_MAIN) |
| 222 ? main_context_getter_.get() |
| 223 : media_context_getter_.get(); |
| 224 net::HttpCache* http_cache = getter->GetURLRequestContext() |
| 225 ->http_transaction_factory() |
| 226 ->GetCache(); |
| 227 |
| 228 next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN) |
| 229 ? STATE_PROCESS_MAIN |
| 230 : STATE_PROCESS_MEDIA; |
| 231 |
| 232 rv = http_cache->GetBackend( |
| 233 &cache_, |
| 234 base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache, |
| 235 base::Unretained(this))); |
| 236 break; |
| 237 } |
| 238 case STATE_PROCESS_MAIN: |
| 239 case STATE_PROCESS_MEDIA: { |
| 240 next_cache_state_ = (next_cache_state_ == STATE_PROCESS_MAIN) |
| 241 ? STATE_CREATE_MEDIA |
| 242 : STATE_DONE; |
| 243 |
| 244 // |cache_| can be null if it cannot be initialized. |
| 245 if (cache_) { |
| 246 if (delete_begin_.is_null() && delete_end_.is_max()) { |
| 247 rv = cache_->CalculateSizeOfAllEntries( |
| 248 base::Bind( |
| 249 &StoragePartitionHttpCacheDataRemover::DoCountCache, |
| 250 base::Unretained(this))); |
| 251 } else { |
| 252 // TODO(msramek): Implement this when we need it. |
| 253 DoCountCache(net::ERR_NOT_IMPLEMENTED); |
| 254 } |
| 255 cache_ = NULL; |
| 256 } |
| 257 break; |
| 258 } |
| 259 case STATE_DONE: { |
| 260 cache_ = NULL; |
| 261 next_cache_state_ = STATE_NONE; |
| 262 |
| 263 // Notify the UI thread that we are done. |
| 264 BrowserThread::PostTask( |
| 265 BrowserThread::UI, FROM_HERE, |
| 266 base::Bind(&StoragePartitionHttpCacheDataRemover::CountedHttpCache, |
| 267 base::Unretained(this))); |
| 268 return; |
| 269 } |
| 270 default: { |
| 271 NOTREACHED() << "bad state"; |
| 272 next_cache_state_ = STATE_NONE; // Stop looping. |
| 273 return; |
| 274 } |
| 275 } |
| 276 } |
| 277 } |
| 278 |
161 } // namespace browsing_data | 279 } // namespace browsing_data |
OLD | NEW |