Home | History | Annotate | Download | only in database
      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 
     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 
     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 
     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 
     67 void DidGetOrigins(
     68     const QuotaClient::GetOriginsCallback& callback,
     69     std::set<GURL>* origins_ptr) {
     70   callback.Run(*origins_ptr);
     71 }
     72 
     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 
     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 
    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 
    114 QuotaClient::ID DatabaseQuotaClient::id() const {
    115   return kDatabase;
    116 }
    117 
    118 void DatabaseQuotaClient::OnQuotaManagerDestroyed() {
    119   delete this;
    120 }
    121 
    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 
    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 
    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 
    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 
    216 bool DatabaseQuotaClient::DoesSupport(storage::StorageType type) const {
    217   return type == storage::kStorageTypeTemporary;
    218 }
    219 
    220 }  // namespace storage
    221