• Home
  • History
  • Annotate
  • 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 "storage/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 "storage/browser/database/database_tracker.h"
18 #include "storage/browser/database/database_util.h"
19 #include "storage/common/database/database_identifier.h"
20 
21 using storage::QuotaClient;
22 
23 namespace storage {
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(storage::GetIdentifierFromOrigin(origin_url),
32                                 &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 = storage::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 = storage::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   storage::QuotaStatusCode status;
84   if (result == net::OK)
85     status = storage::kQuotaStatusOk;
86   else
87     status = storage::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,storage::StorageType type,const GetUsageCallback & callback)122 void DatabaseQuotaClient::GetOriginUsage(const GURL& origin_url,
123                                          storage::StorageType type,
124                                          const GetUsageCallback& callback) {
125   DCHECK(!callback.is_null());
126   DCHECK(db_tracker_.get());
127 
128   // All databases are in the temp namespace for now.
129   if (type != storage::kStorageTypeTemporary) {
130     callback.Run(0);
131     return;
132   }
133 
134   base::PostTaskAndReplyWithResult(
135       db_tracker_thread_.get(),
136       FROM_HERE,
137       base::Bind(&GetOriginUsageOnDBThread, db_tracker_, origin_url),
138       callback);
139 }
140 
GetOriginsForType(storage::StorageType type,const GetOriginsCallback & callback)141 void DatabaseQuotaClient::GetOriginsForType(
142     storage::StorageType type,
143     const GetOriginsCallback& callback) {
144   DCHECK(!callback.is_null());
145   DCHECK(db_tracker_.get());
146 
147   // All databases are in the temp namespace for now.
148   if (type != storage::kStorageTypeTemporary) {
149     callback.Run(std::set<GURL>());
150     return;
151   }
152 
153   std::set<GURL>* origins_ptr = new std::set<GURL>();
154   db_tracker_thread_->PostTaskAndReply(
155       FROM_HERE,
156       base::Bind(&GetOriginsOnDBThread,
157                  db_tracker_,
158                  base::Unretained(origins_ptr)),
159       base::Bind(&DidGetOrigins,
160                  callback,
161                  base::Owned(origins_ptr)));
162 }
163 
GetOriginsForHost(storage::StorageType type,const std::string & host,const GetOriginsCallback & callback)164 void DatabaseQuotaClient::GetOriginsForHost(
165     storage::StorageType type,
166     const std::string& host,
167     const GetOriginsCallback& callback) {
168   DCHECK(!callback.is_null());
169   DCHECK(db_tracker_.get());
170 
171   // All databases are in the temp namespace for now.
172   if (type != storage::kStorageTypeTemporary) {
173     callback.Run(std::set<GURL>());
174     return;
175   }
176 
177   std::set<GURL>* origins_ptr = new std::set<GURL>();
178   db_tracker_thread_->PostTaskAndReply(
179       FROM_HERE,
180       base::Bind(&GetOriginsForHostOnDBThread,
181                  db_tracker_,
182                  base::Unretained(origins_ptr),
183                  host),
184       base::Bind(&DidGetOrigins,
185                  callback,
186                  base::Owned(origins_ptr)));
187 }
188 
DeleteOriginData(const GURL & origin,storage::StorageType type,const DeletionCallback & callback)189 void DatabaseQuotaClient::DeleteOriginData(const GURL& origin,
190                                            storage::StorageType type,
191                                            const DeletionCallback& callback) {
192   DCHECK(!callback.is_null());
193   DCHECK(db_tracker_.get());
194 
195   // All databases are in the temp namespace for now, so nothing to delete.
196   if (type != storage::kStorageTypeTemporary) {
197     callback.Run(storage::kQuotaStatusOk);
198     return;
199   }
200 
201   base::Callback<void(int)> delete_callback =
202       base::Bind(&DidDeleteOriginData,
203                  base::MessageLoopProxy::current(),
204                  callback);
205 
206   PostTaskAndReplyWithResult(
207       db_tracker_thread_.get(),
208       FROM_HERE,
209       base::Bind(&DatabaseTracker::DeleteDataForOrigin,
210                  db_tracker_,
211                  storage::GetIdentifierFromOrigin(origin),
212                  delete_callback),
213       delete_callback);
214 }
215 
DoesSupport(storage::StorageType type) const216 bool DatabaseQuotaClient::DoesSupport(storage::StorageType type) const {
217   return type == storage::kStorageTypeTemporary;
218 }
219 
220 }  // namespace storage
221