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 "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 
     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 
     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 
     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 
     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   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 
     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(
    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 
    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 
    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 
    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 
    218 }  // namespace webkit_database
    219