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