| 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 |