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_local_storage_helper.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/message_loop.h"
      9 #include "base/string_util.h"
     10 #include "base/utf_string_conversions.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "content/browser/browser_thread.h"
     13 #include "content/browser/in_process_webkit/webkit_context.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 #include "webkit/glue/webkit_glue.h"
     18 
     19 using WebKit::WebSecurityOrigin;
     20 
     21 BrowsingDataLocalStorageHelper::LocalStorageInfo::LocalStorageInfo()
     22     : port(0),
     23       size(0) {
     24 }
     25 
     26 BrowsingDataLocalStorageHelper::LocalStorageInfo::LocalStorageInfo(
     27     const std::string& protocol,
     28     const std::string& host,
     29     unsigned short port,
     30     const std::string& database_identifier,
     31     const std::string& origin,
     32     const FilePath& file_path,
     33     int64 size,
     34     base::Time last_modified)
     35     : protocol(protocol),
     36       host(host),
     37       port(port),
     38       database_identifier(database_identifier),
     39       origin(origin),
     40       file_path(file_path),
     41       size(size),
     42       last_modified(last_modified) {
     43       }
     44 
     45 BrowsingDataLocalStorageHelper::LocalStorageInfo::~LocalStorageInfo() {}
     46 
     47 BrowsingDataLocalStorageHelper::BrowsingDataLocalStorageHelper(
     48     Profile* profile)
     49     : profile_(profile),
     50       completion_callback_(NULL),
     51       is_fetching_(false) {
     52   DCHECK(profile_);
     53 }
     54 
     55 BrowsingDataLocalStorageHelper::~BrowsingDataLocalStorageHelper() {
     56 }
     57 
     58 void BrowsingDataLocalStorageHelper::StartFetching(
     59     Callback1<const std::vector<LocalStorageInfo>& >::Type* callback) {
     60   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     61   DCHECK(!is_fetching_);
     62   DCHECK(callback);
     63   is_fetching_ = true;
     64   completion_callback_.reset(callback);
     65   BrowserThread::PostTask(
     66       BrowserThread::WEBKIT, FROM_HERE,
     67       NewRunnableMethod(
     68           this,
     69           &BrowsingDataLocalStorageHelper::
     70               FetchLocalStorageInfoInWebKitThread));
     71 }
     72 
     73 void BrowsingDataLocalStorageHelper::CancelNotification() {
     74   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     75   completion_callback_.reset(NULL);
     76 }
     77 
     78 void BrowsingDataLocalStorageHelper::DeleteLocalStorageFile(
     79     const FilePath& file_path) {
     80   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     81   BrowserThread::PostTask(
     82       BrowserThread::WEBKIT, FROM_HERE,
     83        NewRunnableMethod(
     84            this,
     85            &BrowsingDataLocalStorageHelper::
     86               DeleteLocalStorageFileInWebKitThread,
     87            file_path));
     88 }
     89 
     90 void BrowsingDataLocalStorageHelper::FetchLocalStorageInfoInWebKitThread() {
     91   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
     92   file_util::FileEnumerator file_enumerator(
     93       profile_->GetWebKitContext()->data_path().Append(
     94           DOMStorageContext::kLocalStorageDirectory),
     95       false, file_util::FileEnumerator::FILES);
     96   for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
     97        file_path = file_enumerator.Next()) {
     98     if (file_path.Extension() == DOMStorageContext::kLocalStorageExtension) {
     99       WebSecurityOrigin web_security_origin =
    100           WebSecurityOrigin::createFromDatabaseIdentifier(
    101               webkit_glue::FilePathToWebString(file_path.BaseName()));
    102       if (EqualsASCII(web_security_origin.protocol(),
    103                       chrome::kExtensionScheme)) {
    104         // Extension state is not considered browsing data.
    105         continue;
    106       }
    107       base::PlatformFileInfo file_info;
    108       bool ret = file_util::GetFileInfo(file_path, &file_info);
    109       if (ret) {
    110         local_storage_info_.push_back(LocalStorageInfo(
    111             web_security_origin.protocol().utf8(),
    112             web_security_origin.host().utf8(),
    113             web_security_origin.port(),
    114             web_security_origin.databaseIdentifier().utf8(),
    115             web_security_origin.toString().utf8(),
    116             file_path,
    117             file_info.size,
    118             file_info.last_modified));
    119       }
    120     }
    121   }
    122 
    123   BrowserThread::PostTask(
    124       BrowserThread::UI, FROM_HERE,
    125       NewRunnableMethod(
    126           this, &BrowsingDataLocalStorageHelper::NotifyInUIThread));
    127 }
    128 
    129 void BrowsingDataLocalStorageHelper::NotifyInUIThread() {
    130   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    131   DCHECK(is_fetching_);
    132   // Note: completion_callback_ mutates only in the UI thread, so it's safe to
    133   // test it here.
    134   if (completion_callback_ != NULL) {
    135     completion_callback_->Run(local_storage_info_);
    136     completion_callback_.reset();
    137   }
    138   is_fetching_ = false;
    139 }
    140 
    141 void BrowsingDataLocalStorageHelper::DeleteLocalStorageFileInWebKitThread(
    142     const FilePath& file_path) {
    143   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
    144   profile_->GetWebKitContext()->dom_storage_context()->DeleteLocalStorageFile(
    145       file_path);
    146 }
    147 
    148 CannedBrowsingDataLocalStorageHelper::CannedBrowsingDataLocalStorageHelper(
    149     Profile* profile)
    150     : BrowsingDataLocalStorageHelper(profile),
    151       profile_(profile) {
    152 }
    153 
    154 CannedBrowsingDataLocalStorageHelper*
    155 CannedBrowsingDataLocalStorageHelper::Clone() {
    156   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    157   CannedBrowsingDataLocalStorageHelper* clone =
    158       new CannedBrowsingDataLocalStorageHelper(profile_);
    159 
    160   base::AutoLock auto_lock(lock_);
    161   clone->pending_local_storage_info_ = pending_local_storage_info_;
    162   clone->local_storage_info_ = local_storage_info_;
    163   return clone;
    164 }
    165 
    166 void CannedBrowsingDataLocalStorageHelper::AddLocalStorage(
    167     const GURL& origin) {
    168   base::AutoLock auto_lock(lock_);
    169   pending_local_storage_info_.push_back(origin);
    170 }
    171 
    172 void CannedBrowsingDataLocalStorageHelper::Reset() {
    173   base::AutoLock auto_lock(lock_);
    174   local_storage_info_.clear();
    175   pending_local_storage_info_.clear();
    176 }
    177 
    178 bool CannedBrowsingDataLocalStorageHelper::empty() const {
    179   base::AutoLock auto_lock(lock_);
    180   return local_storage_info_.empty() && pending_local_storage_info_.empty();
    181 }
    182 
    183 void CannedBrowsingDataLocalStorageHelper::StartFetching(
    184     Callback1<const std::vector<LocalStorageInfo>& >::Type* callback) {
    185   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    186   DCHECK(!is_fetching_);
    187   DCHECK(callback);
    188   is_fetching_ = true;
    189   completion_callback_.reset(callback);
    190   BrowserThread::PostTask(
    191       BrowserThread::WEBKIT, FROM_HERE,
    192       NewRunnableMethod(
    193           this,
    194           &CannedBrowsingDataLocalStorageHelper::
    195               ConvertPendingInfoInWebKitThread));
    196 }
    197 
    198 CannedBrowsingDataLocalStorageHelper::~CannedBrowsingDataLocalStorageHelper() {}
    199 
    200 void CannedBrowsingDataLocalStorageHelper::ConvertPendingInfoInWebKitThread() {
    201   base::AutoLock auto_lock(lock_);
    202   for (std::vector<GURL>::iterator info = pending_local_storage_info_.begin();
    203        info != pending_local_storage_info_.end(); ++info) {
    204     WebSecurityOrigin web_security_origin =
    205         WebSecurityOrigin::createFromString(
    206             UTF8ToUTF16(info->spec()));
    207     std::string security_origin(web_security_origin.toString().utf8());
    208 
    209     bool duplicate = false;
    210     for (std::vector<LocalStorageInfo>::iterator
    211          local_storage = local_storage_info_.begin();
    212          local_storage != local_storage_info_.end(); ++local_storage) {
    213       if (local_storage->origin == security_origin) {
    214         duplicate = true;
    215         break;
    216       }
    217     }
    218     if (duplicate)
    219       continue;
    220 
    221     local_storage_info_.push_back(LocalStorageInfo(
    222         web_security_origin.protocol().utf8(),
    223         web_security_origin.host().utf8(),
    224         web_security_origin.port(),
    225         web_security_origin.databaseIdentifier().utf8(),
    226         security_origin,
    227         profile_->GetWebKitContext()->dom_storage_context()->
    228             GetLocalStorageFilePath(web_security_origin.databaseIdentifier()),
    229         0,
    230         base::Time()));
    231   }
    232   pending_local_storage_info_.clear();
    233 
    234   BrowserThread::PostTask(
    235       BrowserThread::UI, FROM_HERE,
    236       NewRunnableMethod(
    237           this, &CannedBrowsingDataLocalStorageHelper::NotifyInUIThread));
    238 }
    239