| OLD | NEW |
| (Empty) | |
| 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_filesystem_helper.h" |
| 6 |
| 7 #include "base/file_util.h" |
| 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/message_loop.h" |
| 10 #include "base/string_util.h" |
| 11 #include "base/utf_string_conversions.h" |
| 12 #include "chrome/browser/profiles/profile.h" |
| 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h" |
| 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
| 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" |
| 16 #include "content/browser/browser_thread.h" |
| 17 #include "content/browser/in_process_webkit/webkit_context.h" |
| 18 #include "webkit/glue/webkit_glue.h" |
| 19 |
| 20 #include "webkit/fileapi/file_system_context.h" |
| 21 #include "webkit/fileapi/file_system_types.h" |
| 22 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
| 23 |
| 24 using WebKit::WebSecurityOrigin; |
| 25 |
| 26 namespace { |
| 27 |
| 28 class BrowsingDataFilesystemHelperImpl : public BrowsingDataFilesystemHelper { |
| 29 public: |
| 30 explicit BrowsingDataFilesystemHelperImpl(Profile* profile); |
| 31 |
| 32 virtual void StartFetching( |
| 33 Callback1<const std::vector<FilesystemInfo>& >::Type* callback); |
| 34 virtual void CancelNotification(); |
| 35 virtual void DeleteFilesystemOrigin(const GURL& origin); |
| 36 |
| 37 private: |
| 38 virtual ~BrowsingDataFilesystemHelperImpl(); |
| 39 |
| 40 // Enumerates all filesystem files in the FILE thread. |
| 41 void FetchFilesystemInfoInFileThread(); |
| 42 // Notifies the completion callback in the UI thread. |
| 43 void NotifyInUIThread(); |
| 44 // Delete data for an origin on the FILE thread. |
| 45 void DeleteFilesystemOriginInFileThread(const GURL& origin); |
| 46 |
| 47 Profile* profile_; |
| 48 |
| 49 // This only mutates in the FILE thread. |
| 50 std::vector<FilesystemInfo> filesystem_info_; |
| 51 |
| 52 // This only mutates on the UI thread. |
| 53 scoped_ptr<Callback1<const std::vector<FilesystemInfo>& >::Type > |
| 54 completion_callback_; |
| 55 |
| 56 // Indicates whether or not we're currently fetching information: |
| 57 // it's true when StartFetching() is called in the UI thread, and it's reset |
| 58 // after we notified the callback in the UI thread. |
| 59 // This only mutates on the UI thread. |
| 60 bool is_fetching_; |
| 61 |
| 62 DISALLOW_COPY_AND_ASSIGN(BrowsingDataFilesystemHelperImpl); |
| 63 }; |
| 64 |
| 65 BrowsingDataFilesystemHelperImpl::BrowsingDataFilesystemHelperImpl( |
| 66 Profile* profile) |
| 67 : profile_(profile), |
| 68 completion_callback_(NULL), |
| 69 is_fetching_(false) { |
| 70 DCHECK(profile_); |
| 71 } |
| 72 |
| 73 BrowsingDataFilesystemHelperImpl::~BrowsingDataFilesystemHelperImpl() { |
| 74 } |
| 75 |
| 76 void BrowsingDataFilesystemHelperImpl::StartFetching( |
| 77 Callback1<const std::vector<FilesystemInfo>& >::Type* callback) { |
| 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 79 DCHECK(!is_fetching_); |
| 80 DCHECK(callback); |
| 81 is_fetching_ = true; |
| 82 completion_callback_.reset(callback); |
| 83 BrowserThread::PostTask( |
| 84 BrowserThread::FILE, FROM_HERE, |
| 85 NewRunnableMethod( |
| 86 this, |
| 87 &BrowsingDataFilesystemHelperImpl:: |
| 88 FetchFilesystemInfoInFileThread)); |
| 89 } |
| 90 |
| 91 void BrowsingDataFilesystemHelperImpl::CancelNotification() { |
| 92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 93 completion_callback_.reset(NULL); |
| 94 } |
| 95 |
| 96 void BrowsingDataFilesystemHelperImpl::DeleteFilesystemOrigin( |
| 97 const GURL& origin) { |
| 98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 99 BrowserThread::PostTask( |
| 100 BrowserThread::FILE, FROM_HERE, |
| 101 NewRunnableMethod( |
| 102 this, |
| 103 &BrowsingDataFilesystemHelperImpl:: |
| 104 DeleteFilesystemOriginInFileThread, |
| 105 origin)); |
| 106 } |
| 107 |
| 108 void BrowsingDataFilesystemHelperImpl::FetchFilesystemInfoInFileThread() { |
| 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 110 fileapi::SandboxMountPointProvider::OriginEnumerator* origin_enumerator = |
| 111 profile_->GetFileSystemContext()->path_manager()->sandbox_provider()-> |
| 112 CreateOriginEnumerator(); |
| 113 |
| 114 GURL current; |
| 115 while (!(current = origin_enumerator->Next()).is_empty()) { |
| 116 if (current.SchemeIs(chrome::kExtensionScheme)) { |
| 117 // Extension state is not considered browsing data. |
| 118 continue; |
| 119 } |
| 120 filesystem_info_.push_back( |
| 121 FilesystemInfo( |
| 122 current.scheme(), |
| 123 current.host(), |
| 124 current.port(), |
| 125 current, |
| 126 origin_enumerator->HasFileSystemType( |
| 127 fileapi::kFileSystemTypePersistent), |
| 128 origin_enumerator->HasFileSystemType( |
| 129 fileapi::kFileSystemTypeTemporary))); |
| 130 } |
| 131 |
| 132 BrowserThread::PostTask( |
| 133 BrowserThread::UI, FROM_HERE, |
| 134 NewRunnableMethod( |
| 135 this, &BrowsingDataFilesystemHelperImpl::NotifyInUIThread)); |
| 136 } |
| 137 |
| 138 void BrowsingDataFilesystemHelperImpl::NotifyInUIThread() { |
| 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 140 DCHECK(is_fetching_); |
| 141 // Note: completion_callback_ mutates only in the UI thread, so it's safe to |
| 142 // test it here. |
| 143 if (completion_callback_ != NULL) { |
| 144 completion_callback_->Run(filesystem_info_); |
| 145 completion_callback_.reset(); |
| 146 } |
| 147 is_fetching_ = false; |
| 148 } |
| 149 |
| 150 void BrowsingDataFilesystemHelperImpl::DeleteFilesystemOriginInFileThread( |
| 151 const GURL& origin) { |
| 152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 153 fileapi::FileSystemContext* context = profile_->GetFileSystemContext(); |
| 154 context->DeleteDataForOriginOnFileThread(origin); |
| 155 } |
| 156 |
| 157 } // namespace |
| 158 |
| 159 BrowsingDataFilesystemHelper::FilesystemInfo::FilesystemInfo( |
| 160 const std::string& protocol, |
| 161 const std::string& host, |
| 162 const std::string& port, |
| 163 const GURL& origin, |
| 164 bool has_persistent, |
| 165 bool has_temporary) |
| 166 : protocol(protocol), |
| 167 host(host), |
| 168 port(port), |
| 169 origin(origin), |
| 170 has_persistent(has_persistent), |
| 171 has_temporary(has_temporary) { |
| 172 } |
| 173 |
| 174 BrowsingDataFilesystemHelper::FilesystemInfo::~FilesystemInfo() {} |
| 175 |
| 176 // static |
| 177 BrowsingDataFilesystemHelper* BrowsingDataFilesystemHelper::Create( |
| 178 Profile* profile) { |
| 179 return new BrowsingDataFilesystemHelperImpl(profile); |
| 180 } |
| 181 |
| 182 CannedBrowsingDataFilesystemHelper:: |
| 183 PendingFilesystemInfo::PendingFilesystemInfo() { |
| 184 } |
| 185 |
| 186 CannedBrowsingDataFilesystemHelper:: |
| 187 PendingFilesystemInfo::PendingFilesystemInfo(const GURL& origin, |
| 188 const fileapi::FileSystemType type) |
| 189 : origin(origin), |
| 190 type(type) { |
| 191 } |
| 192 |
| 193 CannedBrowsingDataFilesystemHelper:: |
| 194 PendingFilesystemInfo::~PendingFilesystemInfo() { |
| 195 } |
| 196 |
| 197 CannedBrowsingDataFilesystemHelper::CannedBrowsingDataFilesystemHelper( |
| 198 Profile* profile) |
| 199 : profile_(profile), |
| 200 completion_callback_(NULL), |
| 201 is_fetching_(false) { |
| 202 DCHECK(profile); |
| 203 } |
| 204 |
| 205 CannedBrowsingDataFilesystemHelper* |
| 206 CannedBrowsingDataFilesystemHelper::Clone() { |
| 207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 208 CannedBrowsingDataFilesystemHelper* clone = |
| 209 new CannedBrowsingDataFilesystemHelper(profile_); |
| 210 |
| 211 base::AutoLock auto_lock(lock_); |
| 212 clone->pending_filesystem_info_ = pending_filesystem_info_; |
| 213 clone->filesystem_info_ = filesystem_info_; |
| 214 return clone; |
| 215 } |
| 216 |
| 217 void CannedBrowsingDataFilesystemHelper::AddFilesystem( |
| 218 const GURL& origin, const fileapi::FileSystemType type) { |
| 219 base::AutoLock auto_lock(lock_); |
| 220 pending_filesystem_info_.push_back(PendingFilesystemInfo(origin, type)); |
| 221 } |
| 222 |
| 223 void CannedBrowsingDataFilesystemHelper::Reset() { |
| 224 base::AutoLock auto_lock(lock_); |
| 225 filesystem_info_.clear(); |
| 226 pending_filesystem_info_.clear(); |
| 227 } |
| 228 |
| 229 bool CannedBrowsingDataFilesystemHelper::empty() const { |
| 230 base::AutoLock auto_lock(lock_); |
| 231 return filesystem_info_.empty() && pending_filesystem_info_.empty(); |
| 232 } |
| 233 |
| 234 void CannedBrowsingDataFilesystemHelper::StartFetching( |
| 235 Callback1<const std::vector<FilesystemInfo>& >::Type* callback) { |
| 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 237 DCHECK(!is_fetching_); |
| 238 DCHECK(callback); |
| 239 is_fetching_ = true; |
| 240 completion_callback_.reset(callback); |
| 241 BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod( |
| 242 this, |
| 243 &CannedBrowsingDataFilesystemHelper::ConvertPendingInfoInWebKitThread)); |
| 244 } |
| 245 |
| 246 CannedBrowsingDataFilesystemHelper::~CannedBrowsingDataFilesystemHelper() {} |
| 247 |
| 248 void CannedBrowsingDataFilesystemHelper::ConvertPendingInfoInWebKitThread() { |
| 249 base::AutoLock auto_lock(lock_); |
| 250 for (std::vector<PendingFilesystemInfo>::const_iterator |
| 251 info = pending_filesystem_info_.begin(); |
| 252 info != pending_filesystem_info_.end(); ++info) { |
| 253 bool duplicate = false; |
| 254 for (std::vector<FilesystemInfo>::iterator |
| 255 filesystem = filesystem_info_.begin(); |
| 256 filesystem != filesystem_info_.end(); |
| 257 ++filesystem) { |
| 258 if (filesystem->origin == info->origin) { |
| 259 if (info->type == fileapi::kFileSystemTypePersistent) { |
| 260 filesystem->has_persistent = true; |
| 261 } else { |
| 262 filesystem->has_temporary = true; |
| 263 } |
| 264 duplicate = true; |
| 265 break; |
| 266 } |
| 267 } |
| 268 if (duplicate) |
| 269 continue; |
| 270 |
| 271 filesystem_info_.push_back(FilesystemInfo( |
| 272 info->origin.scheme(), |
| 273 info->origin.host(), |
| 274 info->origin.port(), |
| 275 info->origin, |
| 276 (info->type == fileapi::kFileSystemTypePersistent), |
| 277 (info->type == fileapi::kFileSystemTypeTemporary))); |
| 278 } |
| 279 pending_filesystem_info_.clear(); |
| 280 |
| 281 BrowserThread::PostTask( |
| 282 BrowserThread::UI, FROM_HERE, |
| 283 NewRunnableMethod( |
| 284 this, &CannedBrowsingDataFilesystemHelper::NotifyInUIThread)); |
| 285 } |
| 286 |
| 287 void CannedBrowsingDataFilesystemHelper::NotifyInUIThread() { |
| 288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 289 DCHECK(is_fetching_); |
| 290 // Note: completion_callback_ mutates only in the UI thread, so it's safe to |
| 291 // test it here. |
| 292 if (completion_callback_ != NULL) { |
| 293 completion_callback_->Run(filesystem_info_); |
| 294 completion_callback_.reset(); |
| 295 } |
| 296 is_fetching_ = false; |
| 297 } |
| OLD | NEW |