• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DatabaseInfo()20 BrowsingDataDatabaseHelper::DatabaseInfo::DatabaseInfo()
21     : size(0) {
22 }
23 
DatabaseInfo(const std::string & host,const std::string & database_name,const std::string & origin_identifier,const std::string & description,const std::string & origin,int64 size,base::Time last_modified)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 
~DatabaseInfo()41 BrowsingDataDatabaseHelper::DatabaseInfo::~DatabaseInfo() {}
42 
IsFileSchemeData()43 bool BrowsingDataDatabaseHelper::DatabaseInfo::IsFileSchemeData() {
44   return StartsWithASCII(origin_identifier,
45                          std::string(chrome::kFileScheme),
46                          true);
47 }
48 
BrowsingDataDatabaseHelper(Profile * profile)49 BrowsingDataDatabaseHelper::BrowsingDataDatabaseHelper(Profile* profile)
50     : completion_callback_(NULL),
51       is_fetching_(false),
52       tracker_(profile->GetDatabaseTracker()) {
53 }
54 
~BrowsingDataDatabaseHelper()55 BrowsingDataDatabaseHelper::~BrowsingDataDatabaseHelper() {
56 }
57 
StartFetching(Callback1<const std::vector<DatabaseInfo> &>::Type * callback)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 
CancelNotification()70 void BrowsingDataDatabaseHelper::CancelNotification() {
71   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
72   completion_callback_.reset(NULL);
73 }
74 
DeleteDatabase(const std::string & origin,const std::string & name)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 
FetchDatabaseInfoInWebKitThread()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 
NotifyInUIThread()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 
DeleteDatabaseInWebKitThread(const std::string & origin,const std::string & name)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 
PendingDatabaseInfo()145 CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::PendingDatabaseInfo() {}
146 
PendingDatabaseInfo(const GURL & origin,const std::string & name,const std::string & description)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 
~PendingDatabaseInfo()156 CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::~PendingDatabaseInfo() {}
157 
CannedBrowsingDataDatabaseHelper(Profile * profile)158 CannedBrowsingDataDatabaseHelper::CannedBrowsingDataDatabaseHelper(
159     Profile* profile)
160     : BrowsingDataDatabaseHelper(profile),
161       profile_(profile) {
162 }
163 
Clone()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 
AddDatabase(const GURL & origin,const std::string & name,const std::string & description)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 
Reset()184 void CannedBrowsingDataDatabaseHelper::Reset() {
185   base::AutoLock auto_lock(lock_);
186   database_info_.clear();
187   pending_database_info_.clear();
188 }
189 
empty() const190 bool CannedBrowsingDataDatabaseHelper::empty() const {
191   base::AutoLock auto_lock(lock_);
192   return database_info_.empty() && pending_database_info_.empty();
193 }
194 
StartFetching(Callback1<const std::vector<DatabaseInfo> &>::Type * callback)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 
~CannedBrowsingDataDatabaseHelper()206 CannedBrowsingDataDatabaseHelper::~CannedBrowsingDataDatabaseHelper() {}
207 
ConvertInfoInWebKitThread()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