Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / child / quota_dispatcher.cc
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 "content/child/quota_dispatcher.h"
6
7 #include "base/basictypes.h"
8 #include "base/lazy_instance.h"
9 #include "base/threading/thread_local.h"
10 #include "content/child/child_thread.h"
11 #include "content/child/quota_message_filter.h"
12 #include "content/child/thread_safe_sender.h"
13 #include "content/common/quota_messages.h"
14 #include "third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h"
15 #include "third_party/WebKit/public/platform/WebStorageQuotaType.h"
16 #include "url/gurl.h"
17
18 using quota::QuotaStatusCode;
19 using quota::StorageType;
20
21 using blink::WebStorageQuotaCallbacks;
22 using blink::WebStorageQuotaError;
23 using blink::WebStorageQuotaType;
24
25 using webkit_glue::WorkerTaskRunner;
26
27 namespace content {
28
29 static base::LazyInstance<base::ThreadLocalPointer<QuotaDispatcher> >::Leaky
30     g_quota_dispatcher_tls = LAZY_INSTANCE_INITIALIZER;
31
32 namespace {
33
34 // QuotaDispatcher::Callback implementation for WebStorageQuotaCallbacks.
35 class WebStorageQuotaDispatcherCallback : public QuotaDispatcher::Callback {
36  public:
37   explicit WebStorageQuotaDispatcherCallback(
38       blink::WebStorageQuotaCallbacks callback)
39       : callbacks_(callback) {}
40   virtual ~WebStorageQuotaDispatcherCallback() {}
41
42   virtual void DidQueryStorageUsageAndQuota(int64 usage, int64 quota) OVERRIDE {
43     callbacks_.didQueryStorageUsageAndQuota(usage, quota);
44   }
45   virtual void DidGrantStorageQuota(int64 usage, int64 granted_quota) OVERRIDE {
46     callbacks_.didGrantStorageQuota(usage, granted_quota);
47   }
48   virtual void DidFail(quota::QuotaStatusCode error) OVERRIDE {
49     callbacks_.didFail(static_cast<WebStorageQuotaError>(error));
50   }
51
52  private:
53   blink::WebStorageQuotaCallbacks callbacks_;
54
55   DISALLOW_COPY_AND_ASSIGN(WebStorageQuotaDispatcherCallback);
56 };
57
58 int CurrentWorkerId() {
59   return WorkerTaskRunner::Instance()->CurrentWorkerId();
60 }
61
62 }  // namespace
63
64 QuotaDispatcher::QuotaDispatcher(ThreadSafeSender* thread_safe_sender,
65                                  QuotaMessageFilter* quota_message_filter)
66     : thread_safe_sender_(thread_safe_sender),
67       quota_message_filter_(quota_message_filter) {
68   g_quota_dispatcher_tls.Pointer()->Set(this);
69 }
70
71 QuotaDispatcher::~QuotaDispatcher() {
72   IDMap<Callback, IDMapOwnPointer>::iterator iter(&pending_quota_callbacks_);
73   while (!iter.IsAtEnd()) {
74     iter.GetCurrentValue()->DidFail(quota::kQuotaErrorAbort);
75     iter.Advance();
76   }
77
78   g_quota_dispatcher_tls.Pointer()->Set(NULL);
79 }
80
81 QuotaDispatcher* QuotaDispatcher::ThreadSpecificInstance(
82     ThreadSafeSender* thread_safe_sender,
83     QuotaMessageFilter* quota_message_filter) {
84   if (g_quota_dispatcher_tls.Pointer()->Get())
85     return g_quota_dispatcher_tls.Pointer()->Get();
86
87   QuotaDispatcher* dispatcher = new QuotaDispatcher(
88       thread_safe_sender, quota_message_filter);
89   if (WorkerTaskRunner::Instance()->CurrentWorkerId())
90     WorkerTaskRunner::Instance()->AddStopObserver(dispatcher);
91   return dispatcher;
92 }
93
94 void QuotaDispatcher::OnWorkerRunLoopStopped() {
95   delete this;
96 }
97
98 void QuotaDispatcher::OnMessageReceived(const IPC::Message& msg) {
99   bool handled = true;
100   IPC_BEGIN_MESSAGE_MAP(QuotaDispatcher, msg)
101     IPC_MESSAGE_HANDLER(QuotaMsg_DidGrantStorageQuota,
102                         DidGrantStorageQuota)
103     IPC_MESSAGE_HANDLER(QuotaMsg_DidQueryStorageUsageAndQuota,
104                         DidQueryStorageUsageAndQuota);
105     IPC_MESSAGE_HANDLER(QuotaMsg_DidFail, DidFail);
106     IPC_MESSAGE_UNHANDLED(handled = false)
107   IPC_END_MESSAGE_MAP()
108   DCHECK(handled) << "Unhandled message:" << msg.type();
109 }
110
111 void QuotaDispatcher::QueryStorageUsageAndQuota(
112     const GURL& origin_url,
113     StorageType type,
114     Callback* callback) {
115   DCHECK(callback);
116   int request_id = quota_message_filter_->GenerateRequestID(CurrentWorkerId());
117   pending_quota_callbacks_.AddWithID(callback, request_id);
118   thread_safe_sender_->Send(new QuotaHostMsg_QueryStorageUsageAndQuota(
119       request_id, origin_url, type));
120 }
121
122 void QuotaDispatcher::RequestStorageQuota(
123     int render_view_id,
124     const GURL& origin_url,
125     StorageType type,
126     uint64 requested_size,
127     Callback* callback) {
128   DCHECK(callback);
129   DCHECK(CurrentWorkerId() == 0);
130   int request_id = quota_message_filter_->GenerateRequestID(CurrentWorkerId());
131   pending_quota_callbacks_.AddWithID(callback, request_id);
132   thread_safe_sender_->Send(new QuotaHostMsg_RequestStorageQuota(
133       render_view_id, request_id, origin_url, type, requested_size));
134 }
135
136 // static
137 QuotaDispatcher::Callback*
138 QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(
139     blink::WebStorageQuotaCallbacks callbacks) {
140   return new WebStorageQuotaDispatcherCallback(callbacks);
141 }
142
143 void QuotaDispatcher::DidGrantStorageQuota(
144     int request_id,
145     int64 current_usage,
146     int64 granted_quota) {
147   Callback* callback = pending_quota_callbacks_.Lookup(request_id);
148   DCHECK(callback);
149   callback->DidGrantStorageQuota(current_usage, granted_quota);
150   pending_quota_callbacks_.Remove(request_id);
151 }
152
153 void QuotaDispatcher::DidQueryStorageUsageAndQuota(
154     int request_id,
155     int64 current_usage,
156     int64 current_quota) {
157   Callback* callback = pending_quota_callbacks_.Lookup(request_id);
158   DCHECK(callback);
159   callback->DidQueryStorageUsageAndQuota(current_usage, current_quota);
160   pending_quota_callbacks_.Remove(request_id);
161 }
162
163 void QuotaDispatcher::DidFail(
164     int request_id,
165     QuotaStatusCode error) {
166   Callback* callback = pending_quota_callbacks_.Lookup(request_id);
167   DCHECK(callback);
168   callback->DidFail(error);
169   pending_quota_callbacks_.Remove(request_id);
170 }
171
172 COMPILE_ASSERT(int(blink::WebStorageQuotaTypeTemporary) == \
173                int(quota::kStorageTypeTemporary), mismatching_enums);
174 COMPILE_ASSERT(int(blink::WebStorageQuotaTypePersistent) == \
175                int(quota::kStorageTypePersistent), mismatching_enums);
176
177 COMPILE_ASSERT(int(blink::WebStorageQuotaErrorNotSupported) == \
178                int(quota::kQuotaErrorNotSupported), mismatching_enums);
179 COMPILE_ASSERT(int(blink::WebStorageQuotaErrorAbort) == \
180                int(quota::kQuotaErrorAbort), mismatching_enums);
181
182 }  // namespace content