|
OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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 "webkit/appcache/appcache_quota_client.h" | |
6 | |
7 #include <algorithm> | |
8 #include <map> | |
9 | |
10 #include "webkit/appcache/appcache_service.h" | |
11 | |
12 using quota::QuotaClient; | |
13 | |
14 namespace { | |
15 | |
16 quota::QuotaStatusCode NetErrorCodeToQuotaStatus(int code) { | |
17 if (code == net::OK) | |
18 return quota::kQuotaStatusOk; | |
19 else if (code == net::ERR_ABORTED) | |
20 return quota::kQuotaErrorAbort; | |
21 else | |
22 return quota::kQuotaStatusUnknown; | |
23 } | |
24 | |
25 template <class RequestType> | |
26 void DeleteCallbackHelper(const RequestType& request) { | |
27 delete request.callback; | |
28 } | |
29 | |
30 } | |
31 | |
32 namespace appcache { | |
33 | |
34 AppCacheQuotaClient::AppCacheQuotaClient(AppCacheService* service) | |
35 : ALLOW_THIS_IN_INITIALIZER_LIST(service_delete_callback_( | |
36 this, &AppCacheQuotaClient::DidDeleteAppCachesForOrigin)), | |
37 service_(service), appcache_is_ready_(false), | |
38 quota_manager_is_destroyed_(false) { | |
39 } | |
40 | |
41 AppCacheQuotaClient::~AppCacheQuotaClient() { | |
42 DeletePendingRequests(); | |
kinuko
2011/06/02 08:38:06
do we need this? we seem to be deleting callbacks
michaeln
2011/06/02 22:46:55
I don't think we do... thnx.
| |
43 } | |
44 | |
45 QuotaClient::ID AppCacheQuotaClient::id() const { | |
46 return kAppcache; | |
47 } | |
48 | |
49 void AppCacheQuotaClient::OnQuotaManagerDestroyed() { | |
50 DeletePendingRequests(); | |
51 quota_manager_is_destroyed_ = true; | |
52 if (!service_) | |
53 delete this; | |
54 } | |
55 | |
56 void AppCacheQuotaClient::GetOriginUsage( | |
57 const GURL& origin, | |
58 quota::StorageType type, | |
59 GetUsageCallback* callback_ptr) { | |
60 DCHECK(callback_ptr); | |
61 DCHECK(!quota_manager_is_destroyed_); | |
62 // Note: Requests may not be processed in order. | |
kinuko
2011/06/02 08:38:06
Does the QM's usage tracker need to be able to han
michaeln
2011/06/02 22:46:55
I'll rearrange things here to respond in order ins
| |
63 | |
64 scoped_ptr<GetUsageCallback> callback(callback_ptr); | |
65 if (!service_ || type != quota::kStorageTypeTemporary) { | |
66 callback->Run(0); | |
67 return; | |
68 } | |
69 | |
70 if (!appcache_is_ready_) { | |
71 pending_usage_requests_.push_back(UsageRequest()); | |
72 pending_usage_requests_.back().origin = origin; | |
73 pending_usage_requests_.back().callback = callback.release(); | |
74 return; | |
75 } | |
76 | |
77 const AppCacheStorage::UsageMap* map = GetUsageMap(); | |
78 AppCacheStorage::UsageMap::const_iterator found = map->find(origin); | |
79 if (found == map->end()) { | |
80 callback->Run(0); | |
81 return; | |
82 } | |
83 callback->Run(found->second); | |
84 } | |
85 | |
86 void AppCacheQuotaClient::GetOriginsForType( | |
87 quota::StorageType type, | |
88 GetOriginsCallback* callback_ptr) { | |
89 GetOriginsHelper(type, std::string(), callback_ptr); | |
90 } | |
91 | |
92 void AppCacheQuotaClient::GetOriginsForHost( | |
93 quota::StorageType type, | |
94 const std::string& host, | |
95 GetOriginsCallback* callback_ptr) { | |
96 DCHECK(!host.empty()); | |
97 GetOriginsHelper(type, host, callback_ptr); | |
98 } | |
99 | |
100 void AppCacheQuotaClient::DeleteOriginData(const GURL& origin, | |
101 quota::StorageType type, | |
102 DeletionCallback* callback_ptr) { | |
103 DCHECK(callback_ptr); | |
104 DCHECK(!quota_manager_is_destroyed_); | |
105 // Note: Requests may not be processed in order. | |
106 | |
107 scoped_ptr<DeletionCallback> callback(callback_ptr); | |
108 if (!service_ || type != quota::kStorageTypeTemporary) { | |
109 callback->Run(quota::kQuotaStatusOk); | |
110 return; | |
111 } | |
112 | |
113 if (!appcache_is_ready_ || current_delete_request_callback_.get()) { | |
114 pending_delete_requests_.push_back(DeleteRequest()); | |
115 pending_delete_requests_.back().origin = origin; | |
116 pending_delete_requests_.back().callback = callback.release(); | |
117 return; | |
118 } | |
119 | |
120 current_delete_request_callback_.swap(callback); | |
121 service_->DeleteAppCachesForOrigin(origin, &service_delete_callback_); | |
122 } | |
123 | |
124 void AppCacheQuotaClient::DidDeleteAppCachesForOrigin(int rv) { | |
125 if (quota_manager_is_destroyed_) | |
126 return; | |
127 | |
128 // Finish the request by calling our callers callback. | |
129 current_delete_request_callback_->Run(NetErrorCodeToQuotaStatus(rv)); | |
130 current_delete_request_callback_.reset(); | |
131 if (pending_delete_requests_.empty()) | |
132 return; | |
133 | |
134 // Start the next in the queue. | |
135 DeleteRequest& next_request = pending_delete_requests_.front(); | |
136 current_delete_request_callback_.reset(next_request.callback); | |
137 service_->DeleteAppCachesForOrigin(next_request.origin, | |
138 &service_delete_callback_); | |
139 pending_delete_requests_.pop_front(); | |
140 } | |
141 | |
142 void AppCacheQuotaClient::GetOriginsHelper( | |
143 quota::StorageType type, | |
144 const std::string& opt_host, | |
145 GetOriginsCallback* callback_ptr) { | |
146 DCHECK(callback_ptr); | |
147 DCHECK(!quota_manager_is_destroyed_); | |
148 // Note: Requests may not be processed in order. | |
149 | |
150 scoped_ptr<GetOriginsCallback> callback(callback_ptr); | |
151 if (!service_ || type != quota::kStorageTypeTemporary) { | |
152 callback->Run(std::set<GURL>()); | |
153 return; | |
154 } | |
155 | |
156 if (!appcache_is_ready_) { | |
157 pending_origins_requests_.push_back(OriginsRequest()); | |
158 pending_origins_requests_.back().callback = callback.release(); | |
159 pending_origins_requests_.back().opt_host = opt_host; | |
160 return; | |
161 } | |
162 | |
163 const AppCacheStorage::UsageMap* map = GetUsageMap(); | |
164 std::set<GURL> origins; | |
165 for (AppCacheStorage::UsageMap::const_iterator iter = map->begin(); | |
166 iter != map->end(); ++iter) { | |
167 if (!opt_host.empty() || iter->first.host() == opt_host) | |
168 origins.insert(iter->first); | |
169 } | |
170 callback->Run(origins); | |
171 } | |
172 | |
173 void AppCacheQuotaClient::ProcessPendingRequests() { | |
174 DCHECK(appcache_is_ready_); | |
175 while (!pending_usage_requests_.empty()) { | |
176 UsageRequest& request = pending_usage_requests_.front(); | |
177 GetOriginUsage(request.origin, quota::kStorageTypeTemporary, | |
178 request.callback); | |
179 pending_usage_requests_.pop_front(); | |
180 } | |
181 | |
182 while (!pending_origins_requests_.empty()) { | |
183 OriginsRequest& request = pending_origins_requests_.front(); | |
184 GetOriginsHelper(quota::kStorageTypeTemporary, request.opt_host, | |
185 request.callback); | |
186 pending_origins_requests_.pop_front(); | |
187 } | |
188 | |
189 if (!pending_delete_requests_.empty()) { | |
190 // Just start the first delete, others will follow upon completion. | |
191 DeleteRequest& request = pending_delete_requests_.front(); | |
192 DeleteOriginData(request.origin, quota::kStorageTypeTemporary, | |
193 request.callback); | |
194 pending_delete_requests_.pop_front(); | |
195 } | |
196 } | |
197 | |
198 void AppCacheQuotaClient::AbortPendingRequests() { | |
199 std::for_each(pending_usage_requests_.begin(), | |
200 pending_usage_requests_.end(), | |
201 AbortUsageRequest); | |
202 std::for_each(pending_origins_requests_.begin(), | |
203 pending_origins_requests_.end(), | |
204 AbortOriginsRequest); | |
205 std::for_each(pending_delete_requests_.begin(), | |
206 pending_delete_requests_.end(), | |
207 AbortDeleteRequest); | |
208 } | |
209 | |
210 void AppCacheQuotaClient::DeletePendingRequests() { | |
211 std::for_each(pending_usage_requests_.begin(), | |
212 pending_usage_requests_.end(), | |
213 DeleteCallbackHelper<UsageRequest>); | |
214 std::for_each(pending_origins_requests_.begin(), | |
215 pending_origins_requests_.end(), | |
216 DeleteCallbackHelper<OriginsRequest>); | |
217 std::for_each(pending_delete_requests_.begin(), | |
218 pending_delete_requests_.end(), | |
219 DeleteCallbackHelper<DeleteRequest>); | |
220 } | |
221 | |
222 const AppCacheStorage::UsageMap* AppCacheQuotaClient::GetUsageMap() { | |
223 DCHECK(service_); | |
224 return service_->storage()->usage_map(); | |
225 } | |
226 | |
227 void AppCacheQuotaClient::NotifyAppCacheReady() { | |
228 appcache_is_ready_ = true; | |
229 ProcessPendingRequests(); | |
230 } | |
231 | |
232 void AppCacheQuotaClient::NotifyAppCacheDestroyed() { | |
233 service_ = NULL; | |
234 AbortPendingRequests(); | |
235 if (quota_manager_is_destroyed_) | |
236 delete this; | |
237 } | |
238 | |
239 // static | |
240 void AppCacheQuotaClient::AbortUsageRequest(const UsageRequest& request) { | |
241 request.callback->Run(0); | |
242 delete request.callback; | |
243 } | |
244 | |
245 // static | |
246 void AppCacheQuotaClient::AbortOriginsRequest(const OriginsRequest& request) { | |
247 request.callback->Run(std::set<GURL>()); | |
248 delete request.callback; | |
249 } | |
250 | |
251 // static | |
252 void AppCacheQuotaClient::AbortDeleteRequest(const DeleteRequest& request) { | |
253 request.callback->Run(quota::kQuotaErrorAbort); | |
254 delete request.callback; | |
255 } | |
256 | |
257 } // namespace appcache | |
OLD | NEW |