Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2011 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_database_helper.h"
      6 
      7 #include "base/callback.h"
      8 #include "base/file_util.h"
      9 #include "base/message_loop.h"
     10 #include "base/utf_string_conversions.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "content/browser/browser_thread.h"
     13 #include "net/base/net_errors.h"
     14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h"
     15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
     16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
     17 
     18 using WebKit::WebSecurityOrigin;
     19 
     20 BrowsingDataDatabaseHelper::DatabaseInfo::DatabaseInfo()
     21     : size(0) {
     22 }
     23 
     24 BrowsingDataDatabaseHelper::DatabaseInfo::DatabaseInfo(
     25     const std::string& host,
     26     const std::string& database_name,
     27     const std::string& origin_identifier,
     28     const std::string& description,
     29     const std::string& origin,
     30     int64 size,
     31     base::Time last_modified)
     32     : host(host),
     33       database_name(database_name),
     34       origin_identifier(origin_identifier),
     35       description(description),
     36       origin(origin),
     37       size(size),
     38       last_modified(last_modified) {
     39 }
     40 
     41 BrowsingDataDatabaseHelper::DatabaseInfo::~DatabaseInfo() {}
     42 
     43 bool BrowsingDataDatabaseHelper::DatabaseInfo::IsFileSchemeData() {
     44   return StartsWithASCII(origin_identifier,
     45                          std::string(chrome::kFileScheme),
     46                          true);
     47 }
     48 
     49 BrowsingDataDatabaseHelper::BrowsingDataDatabaseHelper(Profile* profile)
     50     : completion_callback_(NULL),
     51       is_fetching_(false),
     52       tracker_(profile->GetDatabaseTracker()) {
     53 }
     54 
     55 BrowsingDataDatabaseHelper::~BrowsingDataDatabaseHelper() {
     56 }
     57 
     58 void BrowsingDataDatabaseHelper::StartFetching(
     59     Callback1<const std::vector<DatabaseInfo>& >::Type* callback) {
     60   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     61   DCHECK(!is_fetching_);
     62   DCHECK(callback);
     63   is_fetching_ = true;
     64   database_info_.clear();
     65   completion_callback_.reset(callback);
     66   BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod(
     67       this, &BrowsingDataDatabaseHelper::FetchDatabaseInfoInWebKitThread));
     68 }
     69 
     70 void BrowsingDataDatabaseHelper::CancelNotification() {
     71   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     72   completion_callback_.reset(NULL);
     73 }
     74 
     75 void BrowsingDataDatabaseHelper::DeleteDatabase(const std::string& origin,
     76                                                 const std::string& name) {
     77   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     78   BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod(
     79       this, &BrowsingDataDatabaseHelper::DeleteDatabaseInWebKitThread, origin,
     80       name));
     81 }
     82 
     83 void BrowsingDataDatabaseHelper::FetchDatabaseInfoInWebKitThread() {
     84   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
     85   std::vector<webkit_database::OriginInfo> origins_info;
     86   if (tracker_.get() && tracker_->GetAllOriginsInfo(&origins_info)) {
     87     for (std::vector<webkit_database::OriginInfo>::const_iterator ori =
     88          origins_info.begin(); ori != origins_info.end(); ++ori) {
     89       const std::string origin_identifier(UTF16ToUTF8(ori->GetOrigin()));
     90       if (StartsWithASCII(origin_identifier,
     91                           std::string(chrome::kExtensionScheme),
     92                           true)) {
     93         // Extension state is not considered browsing data.
     94         continue;
     95       }
     96       WebSecurityOrigin web_security_origin =
     97           WebSecurityOrigin::createFromDatabaseIdentifier(
     98               ori->GetOrigin());
     99       std::vector<string16> databases;
    100       ori->GetAllDatabaseNames(&databases);
    101       for (std::vector<string16>::const_iterator db = databases.begin();
    102            db != databases.end(); ++db) {
    103         FilePath file_path = tracker_->GetFullDBFilePath(ori->GetOrigin(), *db);
    104         base::PlatformFileInfo file_info;
    105         if (file_util::GetFileInfo(file_path, &file_info)) {
    106           database_info_.push_back(DatabaseInfo(
    107                 web_security_origin.host().utf8(),
    108                 UTF16ToUTF8(*db),
    109                 origin_identifier,
    110                 UTF16ToUTF8(ori->GetDatabaseDescription(*db)),
    111                 web_security_origin.toString().utf8(),
    112                 file_info.size,
    113                 file_info.last_modified));
    114         }
    115       }
    116     }
    117   }
    118 
    119   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
    120       this, &BrowsingDataDatabaseHelper::NotifyInUIThread));
    121 }
    122 
    123 void BrowsingDataDatabaseHelper::NotifyInUIThread() {
    124   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    125   DCHECK(is_fetching_);
    126   // Note: completion_callback_ mutates only in the UI thread, so it's safe to
    127   // test it here.
    128   if (completion_callback_ != NULL) {
    129     completion_callback_->Run(database_info_);
    130     completion_callback_.reset();
    131   }
    132   is_fetching_ = false;
    133   database_info_.clear();
    134 }
    135 
    136 void BrowsingDataDatabaseHelper::DeleteDatabaseInWebKitThread(
    137     const std::string& origin,
    138     const std::string& name) {
    139   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
    140   if (!tracker_.get())
    141     return;
    142   tracker_->DeleteDatabase(UTF8ToUTF16(origin), UTF8ToUTF16(name), NULL);
    143 }
    144 
    145 CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::PendingDatabaseInfo() {}
    146 
    147 CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::PendingDatabaseInfo(
    148     const GURL& origin,
    149     const std::string& name,
    150     const std::string& description)
    151     : origin(origin),
    152       name(name),
    153       description(description) {
    154 }
    155 
    156 CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::~PendingDatabaseInfo() {}
    157 
    158 CannedBrowsingDataDatabaseHelper::CannedBrowsingDataDatabaseHelper(
    159     Profile* profile)
    160     : BrowsingDataDatabaseHelper(profile),
    161       profile_(profile) {
    162 }
    163 
    164 CannedBrowsingDataDatabaseHelper* CannedBrowsingDataDatabaseHelper::Clone() {
    165   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    166   CannedBrowsingDataDatabaseHelper* clone =
    167       new CannedBrowsingDataDatabaseHelper(profile_);
    168 
    169   base::AutoLock auto_lock(lock_);
    170   clone->pending_database_info_ = pending_database_info_;
    171   clone->database_info_ = database_info_;
    172   return clone;
    173 }
    174 
    175 void CannedBrowsingDataDatabaseHelper::AddDatabase(
    176     const GURL& origin,
    177     const std::string& name,
    178     const std::string& description) {
    179   base::AutoLock auto_lock(lock_);
    180   pending_database_info_.push_back(PendingDatabaseInfo(
    181         origin, name, description));
    182 }
    183 
    184 void CannedBrowsingDataDatabaseHelper::Reset() {
    185   base::AutoLock auto_lock(lock_);
    186   database_info_.clear();
    187   pending_database_info_.clear();
    188 }
    189 
    190 bool CannedBrowsingDataDatabaseHelper::empty() const {
    191   base::AutoLock auto_lock(lock_);
    192   return database_info_.empty() && pending_database_info_.empty();
    193 }
    194 
    195 void CannedBrowsingDataDatabaseHelper::StartFetching(
    196     Callback1<const std::vector<DatabaseInfo>& >::Type* callback) {
    197   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    198   DCHECK(!is_fetching_);
    199   DCHECK(callback);
    200   is_fetching_ = true;
    201   completion_callback_.reset(callback);
    202   BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod(
    203       this, &CannedBrowsingDataDatabaseHelper::ConvertInfoInWebKitThread));
    204 }
    205 
    206 CannedBrowsingDataDatabaseHelper::~CannedBrowsingDataDatabaseHelper() {}
    207 
    208 void CannedBrowsingDataDatabaseHelper::ConvertInfoInWebKitThread() {
    209   base::AutoLock auto_lock(lock_);
    210   for (std::vector<PendingDatabaseInfo>::const_iterator
    211        info = pending_database_info_.begin();
    212        info != pending_database_info_.end(); ++info) {
    213     WebSecurityOrigin web_security_origin =
    214         WebSecurityOrigin::createFromString(
    215             UTF8ToUTF16(info->origin.spec()));
    216     std::string origin_identifier =
    217         web_security_origin.databaseIdentifier().utf8();
    218 
    219     bool duplicate = false;
    220     for (std::vector<DatabaseInfo>::iterator database = database_info_.begin();
    221          database != database_info_.end(); ++database) {
    222       if (database->origin_identifier == origin_identifier &&
    223           database->database_name == info->name) {
    224         duplicate = true;
    225         break;
    226       }
    227     }
    228     if (duplicate)
    229       continue;
    230 
    231     database_info_.push_back(DatabaseInfo(
    232         web_security_origin.host().utf8(),
    233         info->name,
    234         origin_identifier,
    235         info->description,
    236         web_security_origin.toString().utf8(),
    237         0,
    238         base::Time()));
    239   }
    240   pending_database_info_.clear();
    241 
    242   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
    243       this, &CannedBrowsingDataDatabaseHelper::NotifyInUIThread));
    244 }
    245