Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / child / quota_dispatcher.cc
blobfa766dba12768662171606dde3d76374f8133b5d
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.
5 #include "content/child/quota_dispatcher.h"
7 #include "base/basictypes.h"
8 #include "base/lazy_instance.h"
9 #include "base/threading/thread_local.h"
10 #include "content/child/quota_message_filter.h"
11 #include "content/child/thread_safe_sender.h"
12 #include "content/common/quota_messages.h"
13 #include "third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h"
14 #include "third_party/WebKit/public/platform/WebStorageQuotaType.h"
15 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
16 #include "url/gurl.h"
18 using blink::WebStorageQuotaCallbacks;
19 using blink::WebStorageQuotaError;
20 using blink::WebStorageQuotaType;
21 using storage::QuotaStatusCode;
22 using storage::StorageType;
24 namespace content {
26 static base::LazyInstance<base::ThreadLocalPointer<QuotaDispatcher> >::Leaky
27 g_quota_dispatcher_tls = LAZY_INSTANCE_INITIALIZER;
29 namespace {
31 // QuotaDispatcher::Callback implementation for WebStorageQuotaCallbacks.
32 class WebStorageQuotaDispatcherCallback : public QuotaDispatcher::Callback {
33 public:
34 explicit WebStorageQuotaDispatcherCallback(
35 blink::WebStorageQuotaCallbacks callback)
36 : callbacks_(callback) {}
37 ~WebStorageQuotaDispatcherCallback() override {}
39 void DidQueryStorageUsageAndQuota(int64 usage, int64 quota) override {
40 callbacks_.didQueryStorageUsageAndQuota(usage, quota);
42 void DidGrantStorageQuota(int64 usage, int64 granted_quota) override {
43 callbacks_.didGrantStorageQuota(usage, granted_quota);
45 void DidFail(storage::QuotaStatusCode error) override {
46 callbacks_.didFail(static_cast<WebStorageQuotaError>(error));
49 private:
50 blink::WebStorageQuotaCallbacks callbacks_;
52 DISALLOW_COPY_AND_ASSIGN(WebStorageQuotaDispatcherCallback);
55 int CurrentWorkerId() {
56 return WorkerTaskRunner::Instance()->CurrentWorkerId();
59 } // namespace
61 QuotaDispatcher::QuotaDispatcher(ThreadSafeSender* thread_safe_sender,
62 QuotaMessageFilter* quota_message_filter)
63 : thread_safe_sender_(thread_safe_sender),
64 quota_message_filter_(quota_message_filter) {
65 g_quota_dispatcher_tls.Pointer()->Set(this);
68 QuotaDispatcher::~QuotaDispatcher() {
69 IDMap<Callback, IDMapOwnPointer>::iterator iter(&pending_quota_callbacks_);
70 while (!iter.IsAtEnd()) {
71 iter.GetCurrentValue()->DidFail(storage::kQuotaErrorAbort);
72 iter.Advance();
75 g_quota_dispatcher_tls.Pointer()->Set(NULL);
78 QuotaDispatcher* QuotaDispatcher::ThreadSpecificInstance(
79 ThreadSafeSender* thread_safe_sender,
80 QuotaMessageFilter* quota_message_filter) {
81 if (g_quota_dispatcher_tls.Pointer()->Get())
82 return g_quota_dispatcher_tls.Pointer()->Get();
84 QuotaDispatcher* dispatcher = new QuotaDispatcher(
85 thread_safe_sender, quota_message_filter);
86 if (WorkerTaskRunner::Instance()->CurrentWorkerId())
87 WorkerTaskRunner::Instance()->AddStopObserver(dispatcher);
88 return dispatcher;
91 void QuotaDispatcher::OnWorkerRunLoopStopped() {
92 delete this;
95 void QuotaDispatcher::OnMessageReceived(const IPC::Message& msg) {
96 bool handled = true;
97 IPC_BEGIN_MESSAGE_MAP(QuotaDispatcher, msg)
98 IPC_MESSAGE_HANDLER(QuotaMsg_DidGrantStorageQuota,
99 DidGrantStorageQuota)
100 IPC_MESSAGE_HANDLER(QuotaMsg_DidQueryStorageUsageAndQuota,
101 DidQueryStorageUsageAndQuota);
102 IPC_MESSAGE_HANDLER(QuotaMsg_DidFail, DidFail);
103 IPC_MESSAGE_UNHANDLED(handled = false)
104 IPC_END_MESSAGE_MAP()
105 DCHECK(handled) << "Unhandled message:" << msg.type();
108 void QuotaDispatcher::QueryStorageUsageAndQuota(
109 const GURL& origin_url,
110 StorageType type,
111 Callback* callback) {
112 DCHECK(callback);
113 int request_id = quota_message_filter_->GenerateRequestID(CurrentWorkerId());
114 pending_quota_callbacks_.AddWithID(callback, request_id);
115 thread_safe_sender_->Send(new QuotaHostMsg_QueryStorageUsageAndQuota(
116 request_id, origin_url, type));
119 void QuotaDispatcher::RequestStorageQuota(
120 int render_view_id,
121 const GURL& origin_url,
122 StorageType type,
123 uint64 requested_size,
124 Callback* callback) {
125 DCHECK(callback);
126 DCHECK(CurrentWorkerId() == 0);
127 int request_id = quota_message_filter_->GenerateRequestID(CurrentWorkerId());
128 pending_quota_callbacks_.AddWithID(callback, request_id);
130 StorageQuotaParams params;
131 params.render_view_id = render_view_id;
132 params.request_id = request_id;
133 params.origin_url = origin_url;
134 params.storage_type = type;
135 params.requested_size = requested_size;
136 params.user_gesture =
137 blink::WebUserGestureIndicator::isProcessingUserGesture();
138 thread_safe_sender_->Send(new QuotaHostMsg_RequestStorageQuota(params));
141 // static
142 QuotaDispatcher::Callback*
143 QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(
144 blink::WebStorageQuotaCallbacks callbacks) {
145 return new WebStorageQuotaDispatcherCallback(callbacks);
148 void QuotaDispatcher::DidGrantStorageQuota(
149 int request_id,
150 int64 current_usage,
151 int64 granted_quota) {
152 Callback* callback = pending_quota_callbacks_.Lookup(request_id);
153 DCHECK(callback);
154 callback->DidGrantStorageQuota(current_usage, granted_quota);
155 pending_quota_callbacks_.Remove(request_id);
158 void QuotaDispatcher::DidQueryStorageUsageAndQuota(
159 int request_id,
160 int64 current_usage,
161 int64 current_quota) {
162 Callback* callback = pending_quota_callbacks_.Lookup(request_id);
163 DCHECK(callback);
164 callback->DidQueryStorageUsageAndQuota(current_usage, current_quota);
165 pending_quota_callbacks_.Remove(request_id);
168 void QuotaDispatcher::DidFail(
169 int request_id,
170 QuotaStatusCode error) {
171 Callback* callback = pending_quota_callbacks_.Lookup(request_id);
172 DCHECK(callback);
173 callback->DidFail(error);
174 pending_quota_callbacks_.Remove(request_id);
177 static_assert(int(blink::WebStorageQuotaTypeTemporary) ==
178 int(storage::kStorageTypeTemporary),
179 "mismatching enums: kStorageTypeTemporary");
180 static_assert(int(blink::WebStorageQuotaTypePersistent) ==
181 int(storage::kStorageTypePersistent),
182 "mismatching enums: kStorageTypePersistent");
184 static_assert(int(blink::WebStorageQuotaErrorNotSupported) ==
185 int(storage::kQuotaErrorNotSupported),
186 "mismatching enums: kQuotaErrorNotSupported");
187 static_assert(int(blink::WebStorageQuotaErrorAbort) ==
188 int(storage::kQuotaErrorAbort),
189 "mismatching enums: kQuotaErrorAbort");
191 } // namespace content