// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" #include #include "base/bind.h" #include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/browsing_data/browsing_data_helper.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/indexed_db_context.h" using content::BrowserThread; using content::IndexedDBContext; using content::IndexedDBInfo; BrowsingDataIndexedDBHelper::BrowsingDataIndexedDBHelper( IndexedDBContext* indexed_db_context) : indexed_db_context_(indexed_db_context), is_fetching_(false) { DCHECK(indexed_db_context_.get()); } BrowsingDataIndexedDBHelper::~BrowsingDataIndexedDBHelper() { } void BrowsingDataIndexedDBHelper::StartFetching( const base::Callback&)>& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(!is_fetching_); DCHECK(!callback.is_null()); is_fetching_ = true; completion_callback_ = callback; indexed_db_context_->TaskRunner()->PostTask( FROM_HERE, base::Bind( &BrowsingDataIndexedDBHelper::FetchIndexedDBInfoInIndexedDBThread, this)); } void BrowsingDataIndexedDBHelper::DeleteIndexedDB( const GURL& origin) { DCHECK_CURRENTLY_ON(BrowserThread::UI); indexed_db_context_->TaskRunner()->PostTask( FROM_HERE, base::Bind( &BrowsingDataIndexedDBHelper::DeleteIndexedDBInIndexedDBThread, this, origin)); } void BrowsingDataIndexedDBHelper::FetchIndexedDBInfoInIndexedDBThread() { DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); std::vector origins = indexed_db_context_->GetAllOriginsInfo(); for (std::vector::const_iterator iter = origins.begin(); iter != origins.end(); ++iter) { const IndexedDBInfo& origin = *iter; if (!BrowsingDataHelper::HasWebScheme(origin.origin_)) continue; // Non-websafe state is not considered browsing data. indexed_db_info_.push_back(origin); } BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&BrowsingDataIndexedDBHelper::NotifyInUIThread, this)); } void BrowsingDataIndexedDBHelper::NotifyInUIThread() { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(is_fetching_); completion_callback_.Run(indexed_db_info_); completion_callback_.Reset(); is_fetching_ = false; } void BrowsingDataIndexedDBHelper::DeleteIndexedDBInIndexedDBThread( const GURL& origin) { DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); indexed_db_context_->DeleteForOrigin(origin); } CannedBrowsingDataIndexedDBHelper:: PendingIndexedDBInfo::PendingIndexedDBInfo(const GURL& origin, const base::string16& name) : origin(origin), name(name) { } CannedBrowsingDataIndexedDBHelper:: PendingIndexedDBInfo::~PendingIndexedDBInfo() { } bool CannedBrowsingDataIndexedDBHelper::PendingIndexedDBInfo::operator<( const PendingIndexedDBInfo& other) const { if (origin == other.origin) return name < other.name; return origin < other.origin; } CannedBrowsingDataIndexedDBHelper::CannedBrowsingDataIndexedDBHelper( content::IndexedDBContext* context) : BrowsingDataIndexedDBHelper(context) { } CannedBrowsingDataIndexedDBHelper::~CannedBrowsingDataIndexedDBHelper() {} void CannedBrowsingDataIndexedDBHelper::AddIndexedDB( const GURL& origin, const base::string16& name) { if (!BrowsingDataHelper::HasWebScheme(origin)) return; // Non-websafe state is not considered browsing data. pending_indexed_db_info_.insert(PendingIndexedDBInfo(origin, name)); } void CannedBrowsingDataIndexedDBHelper::Reset() { indexed_db_info_.clear(); pending_indexed_db_info_.clear(); } bool CannedBrowsingDataIndexedDBHelper::empty() const { return indexed_db_info_.empty() && pending_indexed_db_info_.empty(); } size_t CannedBrowsingDataIndexedDBHelper::GetIndexedDBCount() const { return pending_indexed_db_info_.size(); } const std::set& CannedBrowsingDataIndexedDBHelper::GetIndexedDBInfo() const { return pending_indexed_db_info_; } void CannedBrowsingDataIndexedDBHelper::StartFetching( const base::Callback&)>& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(!callback.is_null()); std::list result; for (std::set::const_iterator pending_info = pending_indexed_db_info_.begin(); pending_info != pending_indexed_db_info_.end(); ++pending_info) { IndexedDBInfo info(pending_info->origin, 0, base::Time(), 0); result.push_back(info); } BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); } void CannedBrowsingDataIndexedDBHelper::DeleteIndexedDB( const GURL& origin) { for (std::set::iterator it = pending_indexed_db_info_.begin(); it != pending_indexed_db_info_.end(); ) { if (it->origin == origin) pending_indexed_db_info_.erase(it++); else ++it; } BrowsingDataIndexedDBHelper::DeleteIndexedDB(origin); }