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_indexed_db_helper.h" 6 7 #include <vector> 8 9 #include "base/bind.h" 10 #include "base/callback.h" 11 #include "base/compiler_specific.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/strings/string_util.h" 14 #include "base/strings/utf_string_conversions.h" 15 #include "chrome/browser/browsing_data/browsing_data_helper.h" 16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/indexed_db_context.h" 18 19 using content::BrowserThread; 20 using content::IndexedDBContext; 21 using content::IndexedDBInfo; 22 23 BrowsingDataIndexedDBHelper::BrowsingDataIndexedDBHelper( 24 IndexedDBContext* indexed_db_context) 25 : indexed_db_context_(indexed_db_context), 26 is_fetching_(false) { 27 DCHECK(indexed_db_context_.get()); 28 } 29 30 BrowsingDataIndexedDBHelper::~BrowsingDataIndexedDBHelper() { 31 } 32 33 void BrowsingDataIndexedDBHelper::StartFetching( 34 const base::Callback<void(const std::list<IndexedDBInfo>&)>& callback) { 35 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 36 DCHECK(!is_fetching_); 37 DCHECK_EQ(false, callback.is_null()); 38 39 is_fetching_ = true; 40 completion_callback_ = callback; 41 indexed_db_context_->TaskRunner()->PostTask( 42 FROM_HERE, 43 base::Bind( 44 &BrowsingDataIndexedDBHelper::FetchIndexedDBInfoInIndexedDBThread, 45 this)); 46 } 47 48 void BrowsingDataIndexedDBHelper::DeleteIndexedDB( 49 const GURL& origin) { 50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 51 indexed_db_context_->TaskRunner()->PostTask( 52 FROM_HERE, 53 base::Bind( 54 &BrowsingDataIndexedDBHelper::DeleteIndexedDBInIndexedDBThread, 55 this, 56 origin)); 57 } 58 59 void BrowsingDataIndexedDBHelper::FetchIndexedDBInfoInIndexedDBThread() { 60 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); 61 std::vector<IndexedDBInfo> origins = indexed_db_context_->GetAllOriginsInfo(); 62 for (std::vector<IndexedDBInfo>::const_iterator iter = origins.begin(); 63 iter != origins.end(); ++iter) { 64 const IndexedDBInfo& origin = *iter; 65 if (!BrowsingDataHelper::HasWebScheme(origin.origin_)) 66 continue; // Non-websafe state is not considered browsing data. 67 68 indexed_db_info_.push_back(origin); 69 } 70 71 BrowserThread::PostTask( 72 BrowserThread::UI, FROM_HERE, 73 base::Bind(&BrowsingDataIndexedDBHelper::NotifyInUIThread, this)); 74 } 75 76 void BrowsingDataIndexedDBHelper::NotifyInUIThread() { 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 78 DCHECK(is_fetching_); 79 completion_callback_.Run(indexed_db_info_); 80 completion_callback_.Reset(); 81 is_fetching_ = false; 82 } 83 84 void BrowsingDataIndexedDBHelper::DeleteIndexedDBInIndexedDBThread( 85 const GURL& origin) { 86 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); 87 indexed_db_context_->DeleteForOrigin(origin); 88 } 89 90 CannedBrowsingDataIndexedDBHelper:: 91 PendingIndexedDBInfo::PendingIndexedDBInfo(const GURL& origin, 92 const base::string16& name) 93 : origin(origin), 94 name(name) { 95 } 96 97 CannedBrowsingDataIndexedDBHelper:: 98 PendingIndexedDBInfo::~PendingIndexedDBInfo() { 99 } 100 101 bool CannedBrowsingDataIndexedDBHelper::PendingIndexedDBInfo::operator<( 102 const PendingIndexedDBInfo& other) const { 103 if (origin == other.origin) 104 return name < other.name; 105 return origin < other.origin; 106 } 107 108 CannedBrowsingDataIndexedDBHelper::CannedBrowsingDataIndexedDBHelper( 109 content::IndexedDBContext* context) 110 : BrowsingDataIndexedDBHelper(context) { 111 } 112 113 CannedBrowsingDataIndexedDBHelper::~CannedBrowsingDataIndexedDBHelper() {} 114 115 CannedBrowsingDataIndexedDBHelper* CannedBrowsingDataIndexedDBHelper::Clone() { 116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 117 CannedBrowsingDataIndexedDBHelper* clone = 118 new CannedBrowsingDataIndexedDBHelper(indexed_db_context_); 119 120 clone->pending_indexed_db_info_ = pending_indexed_db_info_; 121 clone->indexed_db_info_ = indexed_db_info_; 122 return clone; 123 } 124 125 void CannedBrowsingDataIndexedDBHelper::AddIndexedDB( 126 const GURL& origin, const base::string16& name) { 127 if (!BrowsingDataHelper::HasWebScheme(origin)) 128 return; // Non-websafe state is not considered browsing data. 129 130 pending_indexed_db_info_.insert(PendingIndexedDBInfo(origin, name)); 131 } 132 133 void CannedBrowsingDataIndexedDBHelper::Reset() { 134 indexed_db_info_.clear(); 135 pending_indexed_db_info_.clear(); 136 } 137 138 bool CannedBrowsingDataIndexedDBHelper::empty() const { 139 return indexed_db_info_.empty() && pending_indexed_db_info_.empty(); 140 } 141 142 size_t CannedBrowsingDataIndexedDBHelper::GetIndexedDBCount() const { 143 return pending_indexed_db_info_.size(); 144 } 145 146 const std::set<CannedBrowsingDataIndexedDBHelper::PendingIndexedDBInfo>& 147 CannedBrowsingDataIndexedDBHelper::GetIndexedDBInfo() const { 148 return pending_indexed_db_info_; 149 } 150 151 void CannedBrowsingDataIndexedDBHelper::StartFetching( 152 const base::Callback<void(const std::list<IndexedDBInfo>&)>& callback) { 153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 154 DCHECK(!callback.is_null()); 155 156 std::list<IndexedDBInfo> result; 157 for (std::set<PendingIndexedDBInfo>::const_iterator 158 pending_info = pending_indexed_db_info_.begin(); 159 pending_info != pending_indexed_db_info_.end(); ++pending_info) { 160 IndexedDBInfo info( 161 pending_info->origin, 0, base::Time(), base::FilePath(), 0); 162 result.push_back(info); 163 } 164 165 BrowserThread::PostTask( 166 BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); 167 } 168 169 void CannedBrowsingDataIndexedDBHelper::DeleteIndexedDB( 170 const GURL& origin) { 171 for (std::set<PendingIndexedDBInfo>::iterator it = 172 pending_indexed_db_info_.begin(); 173 it != pending_indexed_db_info_.end(); ) { 174 if (it->origin == origin) 175 pending_indexed_db_info_.erase(it++); 176 else 177 ++it; 178 } 179 BrowsingDataIndexedDBHelper::DeleteIndexedDB(origin); 180 } 181