• 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_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 
LocalStorageInfo()21 BrowsingDataLocalStorageHelper::LocalStorageInfo::LocalStorageInfo()
22     : port(0),
23       size(0) {
24 }
25 
LocalStorageInfo(const std::string & protocol,const std::string & host,unsigned short port,const std::string & database_identifier,const std::string & origin,const FilePath & file_path,int64 size,base::Time last_modified)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 
~LocalStorageInfo()45 BrowsingDataLocalStorageHelper::LocalStorageInfo::~LocalStorageInfo() {}
46 
BrowsingDataLocalStorageHelper(Profile * profile)47 BrowsingDataLocalStorageHelper::BrowsingDataLocalStorageHelper(
48     Profile* profile)
49     : profile_(profile),
50       completion_callback_(NULL),
51       is_fetching_(false) {
52   DCHECK(profile_);
53 }
54 
~BrowsingDataLocalStorageHelper()55 BrowsingDataLocalStorageHelper::~BrowsingDataLocalStorageHelper() {
56 }
57 
StartFetching(Callback1<const std::vector<LocalStorageInfo> &>::Type * callback)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 
CancelNotification()73 void BrowsingDataLocalStorageHelper::CancelNotification() {
74   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
75   completion_callback_.reset(NULL);
76 }
77 
DeleteLocalStorageFile(const FilePath & file_path)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 
FetchLocalStorageInfoInWebKitThread()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 
NotifyInUIThread()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 
DeleteLocalStorageFileInWebKitThread(const FilePath & file_path)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 
CannedBrowsingDataLocalStorageHelper(Profile * profile)148 CannedBrowsingDataLocalStorageHelper::CannedBrowsingDataLocalStorageHelper(
149     Profile* profile)
150     : BrowsingDataLocalStorageHelper(profile),
151       profile_(profile) {
152 }
153 
154 CannedBrowsingDataLocalStorageHelper*
Clone()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 
AddLocalStorage(const GURL & origin)166 void CannedBrowsingDataLocalStorageHelper::AddLocalStorage(
167     const GURL& origin) {
168   base::AutoLock auto_lock(lock_);
169   pending_local_storage_info_.push_back(origin);
170 }
171 
Reset()172 void CannedBrowsingDataLocalStorageHelper::Reset() {
173   base::AutoLock auto_lock(lock_);
174   local_storage_info_.clear();
175   pending_local_storage_info_.clear();
176 }
177 
empty() const178 bool CannedBrowsingDataLocalStorageHelper::empty() const {
179   base::AutoLock auto_lock(lock_);
180   return local_storage_info_.empty() && pending_local_storage_info_.empty();
181 }
182 
StartFetching(Callback1<const std::vector<LocalStorageInfo> &>::Type * callback)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 
~CannedBrowsingDataLocalStorageHelper()198 CannedBrowsingDataLocalStorageHelper::~CannedBrowsingDataLocalStorageHelper() {}
199 
ConvertPendingInfoInWebKitThread()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