• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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/browser/database/database_quota_client.h"
6 
7 #include <vector>
8 
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/location.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/task_runner_util.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/net_util.h"
17 #include "webkit/browser/database/database_tracker.h"
18 #include "webkit/browser/database/database_util.h"
19 #include "webkit/common/database/database_identifier.h"
20 
21 using quota::QuotaClient;
22 
23 namespace webkit_database {
24 
25 namespace {
26 
GetOriginUsageOnDBThread(DatabaseTracker * db_tracker,const GURL & origin_url)27 int64 GetOriginUsageOnDBThread(
28     DatabaseTracker* db_tracker,
29     const GURL& origin_url) {
30   OriginInfo info;
31   if (db_tracker->GetOriginInfo(
32           webkit_database::GetIdentifierFromOrigin(origin_url), &info))
33     return info.TotalSize();
34   return 0;
35 }
36 
GetOriginsOnDBThread(DatabaseTracker * db_tracker,std::set<GURL> * origins_ptr)37 void GetOriginsOnDBThread(
38     DatabaseTracker* db_tracker,
39     std::set<GURL>* origins_ptr) {
40   std::vector<std::string> origin_identifiers;
41   if (db_tracker->GetAllOriginIdentifiers(&origin_identifiers)) {
42     for (std::vector<std::string>::const_iterator iter =
43          origin_identifiers.begin();
44          iter != origin_identifiers.end(); ++iter) {
45       GURL origin = webkit_database::GetOriginFromIdentifier(*iter);
46       origins_ptr->insert(origin);
47     }
48   }
49 }
50 
GetOriginsForHostOnDBThread(DatabaseTracker * db_tracker,std::set<GURL> * origins_ptr,const std::string & host)51 void GetOriginsForHostOnDBThread(
52     DatabaseTracker* db_tracker,
53     std::set<GURL>* origins_ptr,
54     const std::string& host) {
55   std::vector<std::string> origin_identifiers;
56   if (db_tracker->GetAllOriginIdentifiers(&origin_identifiers)) {
57     for (std::vector<std::string>::const_iterator iter =
58          origin_identifiers.begin();
59          iter != origin_identifiers.end(); ++iter) {
60       GURL origin = webkit_database::GetOriginFromIdentifier(*iter);
61       if (host == net::GetHostOrSpecFromURL(origin))
62         origins_ptr->insert(origin);
63     }
64   }
65 }
66 
DidGetOrigins(const QuotaClient::GetOriginsCallback & callback,std::set<GURL> * origins_ptr)67 void DidGetOrigins(
68     const QuotaClient::GetOriginsCallback& callback,
69     std::set<GURL>* origins_ptr) {
70   callback.Run(*origins_ptr);
71 }
72 
DidDeleteOriginData(base::SingleThreadTaskRunner * original_task_runner,const QuotaClient::DeletionCallback & callback,int result)73 void DidDeleteOriginData(
74     base::SingleThreadTaskRunner* original_task_runner,
75     const QuotaClient::DeletionCallback& callback,
76     int result) {
77   if (result == net::ERR_IO_PENDING) {
78     // The callback will be invoked via
79     // DatabaseTracker::ScheduleDatabasesForDeletion.
80     return;
81   }
82 
83   quota::QuotaStatusCode status;
84   if (result == net::OK)
85     status = quota::kQuotaStatusOk;
86   else
87     status = quota::kQuotaStatusUnknown;
88 
89   if (original_task_runner->BelongsToCurrentThread())
90     callback.Run(status);
91   else
92     original_task_runner->PostTask(FROM_HERE, base::Bind(callback, status));
93 }
94 
95 }  // namespace
96 
DatabaseQuotaClient(base::MessageLoopProxy * db_tracker_thread,DatabaseTracker * db_tracker)97 DatabaseQuotaClient::DatabaseQuotaClient(
98     base::MessageLoopProxy* db_tracker_thread,
99     DatabaseTracker* db_tracker)
100     : db_tracker_thread_(db_tracker_thread), db_tracker_(db_tracker) {
101 }
102 
~DatabaseQuotaClient()103 DatabaseQuotaClient::~DatabaseQuotaClient() {
104   if (db_tracker_thread_.get() &&
105       !db_tracker_thread_->RunsTasksOnCurrentThread() && db_tracker_.get()) {
106     DatabaseTracker* tracker = db_tracker_.get();
107     tracker->AddRef();
108     db_tracker_ = NULL;
109     if (!db_tracker_thread_->ReleaseSoon(FROM_HERE, tracker))
110       tracker->Release();
111   }
112 }
113 
id() const114 QuotaClient::ID DatabaseQuotaClient::id() const {
115   return kDatabase;
116 }
117 
OnQuotaManagerDestroyed()118 void DatabaseQuotaClient::OnQuotaManagerDestroyed() {
119   delete this;
120 }
121 
GetOriginUsage(const GURL & origin_url,quota::StorageType type,const GetUsageCallback & callback)122 void DatabaseQuotaClient::GetOriginUsage(
123     const GURL& origin_url,
124     quota::StorageType type,
125     const GetUsageCallback& callback) {
126   DCHECK(!callback.is_null());
127   DCHECK(db_tracker_.get());
128 
129   // All databases are in the temp namespace for now.
130   if (type != quota::kStorageTypeTemporary) {
131     callback.Run(0);
132     return;
133   }
134 
135   base::PostTaskAndReplyWithResult(
136       db_tracker_thread_.get(),
137       FROM_HERE,
138       base::Bind(&GetOriginUsageOnDBThread, db_tracker_, origin_url),
139       callback);
140 }
141 
GetOriginsForType(quota::StorageType type,const GetOriginsCallback & callback)142 void DatabaseQuotaClient::GetOriginsForType(
143     quota::StorageType type,
144     const GetOriginsCallback& callback) {
145   DCHECK(!callback.is_null());
146   DCHECK(db_tracker_.get());
147 
148   // All databases are in the temp namespace for now.
149   if (type != quota::kStorageTypeTemporary) {
150     callback.Run(std::set<GURL>());
151     return;
152   }
153 
154   std::set<GURL>* origins_ptr = new std::set<GURL>();
155   db_tracker_thread_->PostTaskAndReply(
156       FROM_HERE,
157       base::Bind(&GetOriginsOnDBThread,
158                  db_tracker_,
159                  base::Unretained(origins_ptr)),
160       base::Bind(&DidGetOrigins,
161                  callback,
162                  base::Owned(origins_ptr)));
163 }
164 
GetOriginsForHost(quota::StorageType type,const std::string & host,const GetOriginsCallback & callback)165 void DatabaseQuotaClient::GetOriginsForHost(
166     quota::StorageType type,
167     const std::string& host,
168     const GetOriginsCallback& callback) {
169   DCHECK(!callback.is_null());
170   DCHECK(db_tracker_.get());
171 
172   // All databases are in the temp namespace for now.
173   if (type != quota::kStorageTypeTemporary) {
174     callback.Run(std::set<GURL>());
175     return;
176   }
177 
178   std::set<GURL>* origins_ptr = new std::set<GURL>();
179   db_tracker_thread_->PostTaskAndReply(
180       FROM_HERE,
181       base::Bind(&GetOriginsForHostOnDBThread,
182                  db_tracker_,
183                  base::Unretained(origins_ptr),
184                  host),
185       base::Bind(&DidGetOrigins,
186                  callback,
187                  base::Owned(origins_ptr)));
188 }
189 
DeleteOriginData(const GURL & origin,quota::StorageType type,const DeletionCallback & callback)190 void DatabaseQuotaClient::DeleteOriginData(
191     const GURL& origin,
192     quota::StorageType type,
193     const DeletionCallback& callback) {
194   DCHECK(!callback.is_null());
195   DCHECK(db_tracker_.get());
196 
197   // All databases are in the temp namespace for now, so nothing to delete.
198   if (type != quota::kStorageTypeTemporary) {
199     callback.Run(quota::kQuotaStatusOk);
200     return;
201   }
202 
203   base::Callback<void(int)> delete_callback =
204       base::Bind(&DidDeleteOriginData,
205                  base::MessageLoopProxy::current(),
206                  callback);
207 
208   PostTaskAndReplyWithResult(
209       db_tracker_thread_.get(),
210       FROM_HERE,
211       base::Bind(&DatabaseTracker::DeleteDataForOrigin,
212                  db_tracker_,
213                  webkit_database::GetIdentifierFromOrigin(origin),
214                  delete_callback),
215       delete_callback);
216 }
217 
DoesSupport(quota::StorageType type) const218 bool DatabaseQuotaClient::DoesSupport(quota::StorageType type) const {
219   return type == quota::kStorageTypeTemporary;
220 }
221 
222 }  // namespace webkit_database
223