OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/quota_dispatcher_host.h" | 5 #include "content/browser/quota_dispatcher_host.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/weak_ptr.h" | 8 #include "base/memory/weak_ptr.h" |
9 #include "content/common/quota_messages.h" | 9 #include "content/common/quota_messages.h" |
10 #include "content/public/browser/quota_permission_context.h" | 10 #include "content/public/browser/quota_permission_context.h" |
11 #include "net/base/net_util.h" | 11 #include "net/base/net_util.h" |
12 #include "url/gurl.h" | 12 #include "url/gurl.h" |
13 #include "webkit/browser/quota/quota_manager.h" | 13 #include "webkit/browser/quota/quota_manager.h" |
14 | 14 |
15 using quota::QuotaClient; | 15 using quota::QuotaClient; |
16 using quota::QuotaManager; | 16 using quota::QuotaManager; |
17 using quota::QuotaStatusCode; | 17 using quota::QuotaStatusCode; |
18 using quota::StorageType; | 18 using quota::StorageType; |
19 | 19 |
20 namespace content { | 20 namespace content { |
21 | 21 |
22 // Created one per request to carry the request's request_id around. | 22 // Created one per request to carry the request's request_id around. |
23 // Dispatches requests from renderer/worker to the QuotaManager and | 23 // Dispatches requests from renderer/worker to the QuotaManager and |
24 // sends back the response to the renderer/worker. | 24 // sends back the response to the renderer/worker. |
25 class QuotaDispatcherHost::RequestDispatcher { | 25 class QuotaDispatcherHost::RequestDispatcher { |
26 public: | 26 public: |
27 RequestDispatcher(QuotaDispatcherHost* dispatcher_host, | 27 RequestDispatcher(base::WeakPtr<QuotaDispatcherHost> dispatcher_host, |
28 int request_id) | 28 int request_id) |
29 : dispatcher_host_(dispatcher_host), | 29 : dispatcher_host_(dispatcher_host), |
| 30 render_process_id_(dispatcher_host->process_id_), |
30 request_id_(request_id) { | 31 request_id_(request_id) { |
31 dispatcher_host_->outstanding_requests_.AddWithID(this, request_id_); | 32 dispatcher_host_->outstanding_requests_.AddWithID(this, request_id_); |
32 } | 33 } |
33 virtual ~RequestDispatcher() {} | 34 virtual ~RequestDispatcher() {} |
34 | 35 |
35 protected: | 36 protected: |
36 // Subclass must call this when it's done with the request. | 37 // Subclass must call this when it's done with the request. |
37 void Completed() { | 38 void Completed() { |
38 dispatcher_host_->outstanding_requests_.Remove(request_id_); | 39 if (dispatcher_host_) |
| 40 dispatcher_host_->outstanding_requests_.Remove(request_id_); |
39 } | 41 } |
40 | 42 |
41 QuotaDispatcherHost* dispatcher_host() const { return dispatcher_host_; } | 43 QuotaDispatcherHost* dispatcher_host() const { |
| 44 return dispatcher_host_.get(); |
| 45 } |
42 quota::QuotaManager* quota_manager() const { | 46 quota::QuotaManager* quota_manager() const { |
43 return dispatcher_host_->quota_manager_; | 47 return dispatcher_host_ ? dispatcher_host_->quota_manager_ : NULL; |
44 } | 48 } |
45 QuotaPermissionContext* permission_context() const { | 49 QuotaPermissionContext* permission_context() const { |
46 return dispatcher_host_->permission_context_.get(); | 50 return dispatcher_host_ ? |
| 51 dispatcher_host_->permission_context_.get() : NULL; |
47 } | 52 } |
48 int render_process_id() const { return dispatcher_host_->process_id_; } | 53 int render_process_id() const { return render_process_id_; } |
49 int request_id() const { return request_id_; } | 54 int request_id() const { return request_id_; } |
50 | 55 |
51 private: | 56 private: |
52 QuotaDispatcherHost* dispatcher_host_; | 57 base::WeakPtr<QuotaDispatcherHost> dispatcher_host_; |
| 58 int render_process_id_; |
53 int request_id_; | 59 int request_id_; |
54 }; | 60 }; |
55 | 61 |
56 class QuotaDispatcherHost::QueryUsageAndQuotaDispatcher | 62 class QuotaDispatcherHost::QueryUsageAndQuotaDispatcher |
57 : public RequestDispatcher { | 63 : public RequestDispatcher { |
58 public: | 64 public: |
59 QueryUsageAndQuotaDispatcher( | 65 QueryUsageAndQuotaDispatcher( |
60 QuotaDispatcherHost* dispatcher_host, | 66 base::WeakPtr<QuotaDispatcherHost> dispatcher_host, |
61 int request_id) | 67 int request_id) |
62 : RequestDispatcher(dispatcher_host, request_id), | 68 : RequestDispatcher(dispatcher_host, request_id), |
63 weak_factory_(this) {} | 69 weak_factory_(this) {} |
64 virtual ~QueryUsageAndQuotaDispatcher() {} | 70 virtual ~QueryUsageAndQuotaDispatcher() {} |
65 | 71 |
66 void QueryStorageUsageAndQuota(const GURL& origin, StorageType type) { | 72 void QueryStorageUsageAndQuota(const GURL& origin, StorageType type) { |
67 quota_manager()->GetUsageAndQuotaForWebApps( | 73 quota_manager()->GetUsageAndQuotaForWebApps( |
68 origin, type, | 74 origin, type, |
69 base::Bind(&QueryUsageAndQuotaDispatcher::DidQueryStorageUsageAndQuota, | 75 base::Bind(&QueryUsageAndQuotaDispatcher::DidQueryStorageUsageAndQuota, |
70 weak_factory_.GetWeakPtr())); | 76 weak_factory_.GetWeakPtr())); |
71 } | 77 } |
72 | 78 |
73 private: | 79 private: |
74 void DidQueryStorageUsageAndQuota( | 80 void DidQueryStorageUsageAndQuota( |
75 QuotaStatusCode status, int64 usage, int64 quota) { | 81 QuotaStatusCode status, int64 usage, int64 quota) { |
76 DCHECK(dispatcher_host()); | 82 if (!dispatcher_host()) |
| 83 return; |
77 if (status != quota::kQuotaStatusOk) { | 84 if (status != quota::kQuotaStatusOk) { |
78 dispatcher_host()->Send(new QuotaMsg_DidFail(request_id(), status)); | 85 dispatcher_host()->Send(new QuotaMsg_DidFail(request_id(), status)); |
79 } else { | 86 } else { |
80 dispatcher_host()->Send(new QuotaMsg_DidQueryStorageUsageAndQuota( | 87 dispatcher_host()->Send(new QuotaMsg_DidQueryStorageUsageAndQuota( |
81 request_id(), usage, quota)); | 88 request_id(), usage, quota)); |
82 } | 89 } |
83 Completed(); | 90 Completed(); |
84 } | 91 } |
85 | 92 |
86 base::WeakPtrFactory<QueryUsageAndQuotaDispatcher> weak_factory_; | 93 base::WeakPtrFactory<QueryUsageAndQuotaDispatcher> weak_factory_; |
87 }; | 94 }; |
88 | 95 |
89 class QuotaDispatcherHost::RequestQuotaDispatcher | 96 class QuotaDispatcherHost::RequestQuotaDispatcher |
90 : public RequestDispatcher { | 97 : public RequestDispatcher { |
91 public: | 98 public: |
92 typedef RequestQuotaDispatcher self_type; | 99 typedef RequestQuotaDispatcher self_type; |
93 | 100 |
94 RequestQuotaDispatcher(QuotaDispatcherHost* dispatcher_host, | 101 RequestQuotaDispatcher(base::WeakPtr<QuotaDispatcherHost> dispatcher_host, |
95 int request_id, | 102 int request_id, |
96 const GURL& origin, | 103 const GURL& origin, |
97 StorageType type, | 104 StorageType type, |
98 int64 requested_quota, | 105 int64 requested_quota, |
99 int render_view_id) | 106 int render_view_id) |
100 : RequestDispatcher(dispatcher_host, request_id), | 107 : RequestDispatcher(dispatcher_host, request_id), |
101 origin_(origin), | 108 origin_(origin), |
102 host_(net::GetHostOrSpecFromURL(origin)), | 109 host_(net::GetHostOrSpecFromURL(origin)), |
103 type_(type), | 110 type_(type), |
104 current_quota_(0), | 111 current_quota_(0), |
105 requested_quota_(requested_quota), | 112 requested_quota_(requested_quota), |
106 render_view_id_(render_view_id), | 113 render_view_id_(render_view_id), |
107 weak_factory_(this) {} | 114 weak_factory_(this) {} |
108 virtual ~RequestQuotaDispatcher() {} | 115 virtual ~RequestQuotaDispatcher() {} |
109 | 116 |
110 void Start() { | 117 void Start() { |
| 118 DCHECK(dispatcher_host()); |
111 DCHECK(type_ == quota::kStorageTypeTemporary || | 119 DCHECK(type_ == quota::kStorageTypeTemporary || |
112 type_ == quota::kStorageTypePersistent || | 120 type_ == quota::kStorageTypePersistent || |
113 type_ == quota::kStorageTypeSyncable); | 121 type_ == quota::kStorageTypeSyncable); |
114 if (type_ == quota::kStorageTypePersistent) { | 122 if (type_ == quota::kStorageTypePersistent) { |
115 quota_manager()->GetPersistentHostQuota( | 123 quota_manager()->GetPersistentHostQuota( |
116 host_, | 124 host_, |
117 base::Bind(&self_type::DidGetHostQuota, | 125 base::Bind(&self_type::DidGetHostQuota, |
118 weak_factory_.GetWeakPtr(), host_, type_)); | 126 weak_factory_.GetWeakPtr(), host_, type_)); |
119 } else { | 127 } else { |
120 quota_manager()->GetUsageAndQuotaForWebApps( | 128 quota_manager()->GetUsageAndQuotaForWebApps( |
121 origin_, type_, | 129 origin_, type_, |
122 base::Bind(&self_type::DidGetTemporaryUsageAndQuota, | 130 base::Bind(&self_type::DidGetTemporaryUsageAndQuota, |
123 weak_factory_.GetWeakPtr())); | 131 weak_factory_.GetWeakPtr())); |
124 } | 132 } |
125 } | 133 } |
126 | 134 |
127 private: | 135 private: |
128 void DidGetHostQuota(const std::string& host, | 136 void DidGetHostQuota(const std::string& host, |
129 StorageType type, | 137 StorageType type, |
130 QuotaStatusCode status, | 138 QuotaStatusCode status, |
131 int64 quota) { | 139 int64 quota) { |
| 140 if (!dispatcher_host()) |
| 141 return; |
132 DCHECK_EQ(type_, type); | 142 DCHECK_EQ(type_, type); |
133 DCHECK_EQ(host_, host); | 143 DCHECK_EQ(host_, host); |
134 if (status != quota::kQuotaStatusOk) { | 144 if (status != quota::kQuotaStatusOk) { |
135 DidFinish(status, 0); | 145 DidFinish(status, 0); |
136 return; | 146 return; |
137 } | 147 } |
138 if (requested_quota_ < 0) { | 148 if (requested_quota_ < 0) { |
139 DidFinish(quota::kQuotaErrorInvalidModification, 0); | 149 DidFinish(quota::kQuotaErrorInvalidModification, 0); |
140 return; | 150 return; |
141 } | 151 } |
(...skipping 13 matching lines...) Expand all Loading... |
155 } | 165 } |
156 | 166 |
157 void DidGetTemporaryUsageAndQuota(QuotaStatusCode status, | 167 void DidGetTemporaryUsageAndQuota(QuotaStatusCode status, |
158 int64 usage_unused, | 168 int64 usage_unused, |
159 int64 quota) { | 169 int64 quota) { |
160 DidFinish(status, std::min(requested_quota_, quota)); | 170 DidFinish(status, std::min(requested_quota_, quota)); |
161 } | 171 } |
162 | 172 |
163 void DidGetPermissionResponse( | 173 void DidGetPermissionResponse( |
164 QuotaPermissionContext::QuotaPermissionResponse response) { | 174 QuotaPermissionContext::QuotaPermissionResponse response) { |
| 175 if (!dispatcher_host()) |
| 176 return; |
165 if (response != QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW) { | 177 if (response != QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW) { |
166 // User didn't allow the new quota. Just returning the current quota. | 178 // User didn't allow the new quota. Just returning the current quota. |
167 DidFinish(quota::kQuotaStatusOk, current_quota_); | 179 DidFinish(quota::kQuotaStatusOk, current_quota_); |
168 return; | 180 return; |
169 } | 181 } |
170 // Now we're allowed to set the new quota. | 182 // Now we're allowed to set the new quota. |
171 quota_manager()->SetPersistentHostQuota( | 183 quota_manager()->SetPersistentHostQuota( |
172 host_, requested_quota_, | 184 host_, requested_quota_, |
173 base::Bind(&self_type::DidSetHostQuota, weak_factory_.GetWeakPtr())); | 185 base::Bind(&self_type::DidSetHostQuota, weak_factory_.GetWeakPtr())); |
174 } | 186 } |
175 | 187 |
176 void DidSetHostQuota(QuotaStatusCode status, int64 new_quota) { | 188 void DidSetHostQuota(QuotaStatusCode status, int64 new_quota) { |
177 DidFinish(status, new_quota); | 189 DidFinish(status, new_quota); |
178 } | 190 } |
179 | 191 |
180 void DidFinish(QuotaStatusCode status, int64 granted_quota) { | 192 void DidFinish(QuotaStatusCode status, int64 granted_quota) { |
| 193 if (!dispatcher_host()) |
| 194 return; |
181 DCHECK(dispatcher_host()); | 195 DCHECK(dispatcher_host()); |
182 if (status != quota::kQuotaStatusOk) { | 196 if (status != quota::kQuotaStatusOk) { |
183 dispatcher_host()->Send(new QuotaMsg_DidFail(request_id(), status)); | 197 dispatcher_host()->Send(new QuotaMsg_DidFail(request_id(), status)); |
184 } else { | 198 } else { |
185 dispatcher_host()->Send(new QuotaMsg_DidGrantStorageQuota( | 199 dispatcher_host()->Send(new QuotaMsg_DidGrantStorageQuota( |
186 request_id(), granted_quota)); | 200 request_id(), granted_quota)); |
187 } | 201 } |
188 Completed(); | 202 Completed(); |
189 } | 203 } |
190 | 204 |
191 const GURL origin_; | 205 const GURL origin_; |
192 const std::string host_; | 206 const std::string host_; |
193 const StorageType type_; | 207 const StorageType type_; |
194 int64 current_quota_; | 208 int64 current_quota_; |
195 const int64 requested_quota_; | 209 const int64 requested_quota_; |
196 const int render_view_id_; | 210 const int render_view_id_; |
197 base::WeakPtrFactory<self_type> weak_factory_; | 211 base::WeakPtrFactory<self_type> weak_factory_; |
198 }; | 212 }; |
199 | 213 |
200 QuotaDispatcherHost::QuotaDispatcherHost( | 214 QuotaDispatcherHost::QuotaDispatcherHost( |
201 int process_id, | 215 int process_id, |
202 QuotaManager* quota_manager, | 216 QuotaManager* quota_manager, |
203 QuotaPermissionContext* permission_context) | 217 QuotaPermissionContext* permission_context) |
204 : process_id_(process_id), | 218 : process_id_(process_id), |
205 quota_manager_(quota_manager), | 219 quota_manager_(quota_manager), |
206 permission_context_(permission_context) { | 220 permission_context_(permission_context), |
| 221 weak_factory_(this) { |
207 } | 222 } |
208 | 223 |
209 bool QuotaDispatcherHost::OnMessageReceived( | 224 bool QuotaDispatcherHost::OnMessageReceived( |
210 const IPC::Message& message, bool* message_was_ok) { | 225 const IPC::Message& message, bool* message_was_ok) { |
211 *message_was_ok = true; | 226 *message_was_ok = true; |
212 bool handled = true; | 227 bool handled = true; |
213 IPC_BEGIN_MESSAGE_MAP_EX(QuotaDispatcherHost, message, *message_was_ok) | 228 IPC_BEGIN_MESSAGE_MAP_EX(QuotaDispatcherHost, message, *message_was_ok) |
214 IPC_MESSAGE_HANDLER(QuotaHostMsg_QueryStorageUsageAndQuota, | 229 IPC_MESSAGE_HANDLER(QuotaHostMsg_QueryStorageUsageAndQuota, |
215 OnQueryStorageUsageAndQuota) | 230 OnQueryStorageUsageAndQuota) |
216 IPC_MESSAGE_HANDLER(QuotaHostMsg_RequestStorageQuota, | 231 IPC_MESSAGE_HANDLER(QuotaHostMsg_RequestStorageQuota, |
217 OnRequestStorageQuota) | 232 OnRequestStorageQuota) |
218 IPC_MESSAGE_UNHANDLED(handled = false) | 233 IPC_MESSAGE_UNHANDLED(handled = false) |
219 IPC_END_MESSAGE_MAP_EX() | 234 IPC_END_MESSAGE_MAP_EX() |
220 return handled; | 235 return handled; |
221 } | 236 } |
222 | 237 |
223 QuotaDispatcherHost::~QuotaDispatcherHost() {} | 238 QuotaDispatcherHost::~QuotaDispatcherHost() {} |
224 | 239 |
225 void QuotaDispatcherHost::OnQueryStorageUsageAndQuota( | 240 void QuotaDispatcherHost::OnQueryStorageUsageAndQuota( |
226 int request_id, | 241 int request_id, |
227 const GURL& origin, | 242 const GURL& origin, |
228 StorageType type) { | 243 StorageType type) { |
229 QueryUsageAndQuotaDispatcher* dispatcher = new QueryUsageAndQuotaDispatcher( | 244 QueryUsageAndQuotaDispatcher* dispatcher = new QueryUsageAndQuotaDispatcher( |
230 this, request_id); | 245 weak_factory_.GetWeakPtr(), request_id); |
231 dispatcher->QueryStorageUsageAndQuota(origin, type); | 246 dispatcher->QueryStorageUsageAndQuota(origin, type); |
232 } | 247 } |
233 | 248 |
234 void QuotaDispatcherHost::OnRequestStorageQuota( | 249 void QuotaDispatcherHost::OnRequestStorageQuota( |
235 int render_view_id, | 250 int render_view_id, |
236 int request_id, | 251 int request_id, |
237 const GURL& origin, | 252 const GURL& origin, |
238 StorageType type, | 253 StorageType type, |
239 int64 requested_size) { | 254 int64 requested_size) { |
240 if (quota_manager_->IsStorageUnlimited(origin, type)) { | 255 if (quota_manager_->IsStorageUnlimited(origin, type)) { |
241 // If the origin is marked 'unlimited' we always just return ok. | 256 // If the origin is marked 'unlimited' we always just return ok. |
242 Send(new QuotaMsg_DidGrantStorageQuota(request_id, requested_size)); | 257 Send(new QuotaMsg_DidGrantStorageQuota(request_id, requested_size)); |
243 return; | 258 return; |
244 } | 259 } |
245 | 260 |
246 if (type != quota::kStorageTypeTemporary && | 261 if (type != quota::kStorageTypeTemporary && |
247 type != quota::kStorageTypePersistent) { | 262 type != quota::kStorageTypePersistent) { |
248 // Unsupported storage types. | 263 // Unsupported storage types. |
249 Send(new QuotaMsg_DidFail(request_id, quota::kQuotaErrorNotSupported)); | 264 Send(new QuotaMsg_DidFail(request_id, quota::kQuotaErrorNotSupported)); |
250 return; | 265 return; |
251 } | 266 } |
252 | 267 |
253 RequestQuotaDispatcher* dispatcher = new RequestQuotaDispatcher( | 268 RequestQuotaDispatcher* dispatcher = new RequestQuotaDispatcher( |
254 this, request_id, origin, type, requested_size, render_view_id); | 269 weak_factory_.GetWeakPtr(), request_id, origin, type, |
| 270 requested_size, render_view_id); |
255 dispatcher->Start(); | 271 dispatcher->Start(); |
256 } | 272 } |
257 | 273 |
258 } // namespace content | 274 } // namespace content |
OLD | NEW |