Home | History | Annotate | Download | only in browsing_data
      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 "chrome/browser/browsing_data/browsing_data_database_helper.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/bind.h"
     10 #include "base/callback.h"
     11 #include "base/files/file_util.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "chrome/browser/browsing_data/browsing_data_helper.h"
     14 #include "chrome/browser/profiles/profile.h"
     15 #include "content/public/browser/browser_thread.h"
     16 #include "content/public/browser/storage_partition.h"
     17 #include "net/base/completion_callback.h"
     18 #include "net/base/net_errors.h"
     19 #include "storage/common/database/database_identifier.h"
     20 
     21 using content::BrowserContext;
     22 using content::BrowserThread;
     23 using storage::DatabaseIdentifier;
     24 
     25 BrowsingDataDatabaseHelper::DatabaseInfo::DatabaseInfo(
     26     const DatabaseIdentifier& identifier,
     27     const std::string& database_name,
     28     const std::string& description,
     29     int64 size,
     30     base::Time last_modified)
     31     : identifier(identifier),
     32       database_name(database_name),
     33       description(description),
     34       size(size),
     35       last_modified(last_modified) {
     36 }
     37 
     38 BrowsingDataDatabaseHelper::DatabaseInfo::~DatabaseInfo() {}
     39 
     40 BrowsingDataDatabaseHelper::BrowsingDataDatabaseHelper(Profile* profile)
     41     : is_fetching_(false),
     42       tracker_(BrowserContext::
     43                   GetDefaultStoragePartition(profile)->GetDatabaseTracker()) {
     44 }
     45 
     46 BrowsingDataDatabaseHelper::~BrowsingDataDatabaseHelper() {
     47 }
     48 
     49 void BrowsingDataDatabaseHelper::StartFetching(
     50     const base::Callback<void(const std::list<DatabaseInfo>&)>& callback) {
     51   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     52   DCHECK(!is_fetching_);
     53   DCHECK(!callback.is_null());
     54 
     55   is_fetching_ = true;
     56   database_info_.clear();
     57   completion_callback_ = callback;
     58   BrowserThread::PostTask(
     59       BrowserThread::FILE, FROM_HERE,
     60       base::Bind(&BrowsingDataDatabaseHelper::FetchDatabaseInfoOnFileThread,
     61                  this));
     62 }
     63 
     64 void BrowsingDataDatabaseHelper::DeleteDatabase(const std::string& origin,
     65                                                 const std::string& name) {
     66   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     67   BrowserThread::PostTask(
     68       BrowserThread::FILE, FROM_HERE,
     69       base::Bind(&BrowsingDataDatabaseHelper::DeleteDatabaseOnFileThread, this,
     70                  origin, name));
     71 }
     72 
     73 void BrowsingDataDatabaseHelper::FetchDatabaseInfoOnFileThread() {
     74   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
     75   std::vector<storage::OriginInfo> origins_info;
     76   if (tracker_.get() && tracker_->GetAllOriginsInfo(&origins_info)) {
     77     for (std::vector<storage::OriginInfo>::const_iterator ori =
     78              origins_info.begin();
     79          ori != origins_info.end();
     80          ++ori) {
     81       DatabaseIdentifier identifier =
     82           DatabaseIdentifier::Parse(ori->GetOriginIdentifier());
     83       if (!BrowsingDataHelper::HasWebScheme(identifier.ToOrigin())) {
     84         // Non-websafe state is not considered browsing data.
     85         continue;
     86       }
     87       std::vector<base::string16> databases;
     88       ori->GetAllDatabaseNames(&databases);
     89       for (std::vector<base::string16>::const_iterator db = databases.begin();
     90            db != databases.end(); ++db) {
     91         base::FilePath file_path =
     92             tracker_->GetFullDBFilePath(ori->GetOriginIdentifier(), *db);
     93         base::File::Info file_info;
     94         if (base::GetFileInfo(file_path, &file_info)) {
     95           database_info_.push_back(DatabaseInfo(
     96                 identifier,
     97                 base::UTF16ToUTF8(*db),
     98                 base::UTF16ToUTF8(ori->GetDatabaseDescription(*db)),
     99                 file_info.size,
    100                 file_info.last_modified));
    101         }
    102       }
    103     }
    104   }
    105 
    106   BrowserThread::PostTask(
    107       BrowserThread::UI, FROM_HERE,
    108       base::Bind(&BrowsingDataDatabaseHelper::NotifyInUIThread, this));
    109 }
    110 
    111 void BrowsingDataDatabaseHelper::NotifyInUIThread() {
    112   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    113   DCHECK(is_fetching_);
    114   completion_callback_.Run(database_info_);
    115   completion_callback_.Reset();
    116   is_fetching_ = false;
    117   database_info_.clear();
    118 }
    119 
    120 void BrowsingDataDatabaseHelper::DeleteDatabaseOnFileThread(
    121     const std::string& origin,
    122     const std::string& name) {
    123   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
    124   if (!tracker_.get())
    125     return;
    126   tracker_->DeleteDatabase(origin, base::UTF8ToUTF16(name),
    127                            net::CompletionCallback());
    128 }
    129 
    130 CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::PendingDatabaseInfo(
    131     const GURL& origin,
    132     const std::string& name,
    133     const std::string& description)
    134     : origin(origin),
    135       name(name),
    136       description(description) {
    137 }
    138 
    139 CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::~PendingDatabaseInfo() {}
    140 
    141 bool CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::operator<(
    142     const PendingDatabaseInfo& other) const {
    143   if (origin == other.origin)
    144     return name < other.name;
    145   return origin < other.origin;
    146 }
    147 
    148 CannedBrowsingDataDatabaseHelper::CannedBrowsingDataDatabaseHelper(
    149     Profile* profile)
    150     : BrowsingDataDatabaseHelper(profile) {
    151 }
    152 
    153 void CannedBrowsingDataDatabaseHelper::AddDatabase(
    154     const GURL& origin,
    155     const std::string& name,
    156     const std::string& description) {
    157   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    158   if (BrowsingDataHelper::HasWebScheme(origin)) {
    159     pending_database_info_.insert(PendingDatabaseInfo(
    160           origin, name, description));
    161   }
    162 }
    163 
    164 void CannedBrowsingDataDatabaseHelper::Reset() {
    165   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    166   pending_database_info_.clear();
    167 }
    168 
    169 bool CannedBrowsingDataDatabaseHelper::empty() const {
    170   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    171   return pending_database_info_.empty();
    172 }
    173 
    174 size_t CannedBrowsingDataDatabaseHelper::GetDatabaseCount() const {
    175   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    176   return pending_database_info_.size();
    177 }
    178 
    179 const std::set<CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo>&
    180 CannedBrowsingDataDatabaseHelper::GetPendingDatabaseInfo() {
    181   return pending_database_info_;
    182 }
    183 
    184 void CannedBrowsingDataDatabaseHelper::StartFetching(
    185     const base::Callback<void(const std::list<DatabaseInfo>&)>& callback) {
    186   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    187   DCHECK(!callback.is_null());
    188 
    189   std::list<DatabaseInfo> result;
    190   for (std::set<PendingDatabaseInfo>::const_iterator
    191        info = pending_database_info_.begin();
    192        info != pending_database_info_.end(); ++info) {
    193     DatabaseIdentifier identifier =
    194         DatabaseIdentifier::CreateFromOrigin(info->origin);
    195 
    196     result.push_back(DatabaseInfo(
    197         identifier,
    198         info->name,
    199         info->description,
    200         0,
    201         base::Time()));
    202   }
    203 
    204   BrowserThread::PostTask(
    205       BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
    206 }
    207 
    208 void CannedBrowsingDataDatabaseHelper::DeleteDatabase(
    209     const std::string& origin_identifier,
    210     const std::string& name) {
    211   GURL origin =
    212       storage::DatabaseIdentifier::Parse(origin_identifier).ToOrigin();
    213   for (std::set<PendingDatabaseInfo>::iterator it =
    214            pending_database_info_.begin();
    215        it != pending_database_info_.end();
    216        ++it) {
    217     if (it->origin == origin && it->name == name) {
    218       pending_database_info_.erase(it);
    219       break;
    220     }
    221   }
    222   BrowsingDataDatabaseHelper::DeleteDatabase(origin_identifier, name);
    223 }
    224 
    225 CannedBrowsingDataDatabaseHelper::~CannedBrowsingDataDatabaseHelper() {}
    226