Chromium Code Reviews| Index: chrome/browser/browsing_data_file_system_helper.cc |
| diff --git a/chrome/browser/browsing_data_file_system_helper.cc b/chrome/browser/browsing_data_file_system_helper.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..227973c39b45b7fc463e5f2a446a1c4c23cd3355 |
| --- /dev/null |
| +++ b/chrome/browser/browsing_data_file_system_helper.cc |
| @@ -0,0 +1,286 @@ |
| +// Copyright (c) 2011 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_file_system_helper.h" |
| + |
| +#include "base/file_util.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/message_loop.h" |
| +#include "base/string_util.h" |
| +#include "base/utf_string_conversions.h" |
| +#include "chrome/browser/profiles/profile.h" |
| +#include "content/browser/browser_thread.h" |
| +#include "content/browser/in_process_webkit/webkit_context.h" |
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h" |
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" |
| +#include "webkit/fileapi/file_system_context.h" |
| +#include "webkit/fileapi/file_system_types.h" |
| +#include "webkit/fileapi/sandbox_mount_point_provider.h" |
| +#include "webkit/glue/webkit_glue.h" |
| + |
| +using WebKit::WebSecurityOrigin; |
| + |
| +namespace { |
| + |
| +class BrowsingDataFileSystemHelperImpl : public BrowsingDataFileSystemHelper { |
| + public: |
| + explicit BrowsingDataFileSystemHelperImpl(Profile* profile); |
| + |
| + virtual void StartFetching( |
| + Callback1<const std::vector<FileSystemInfo>& >::Type* callback); |
| + virtual void CancelNotification(); |
| + virtual void DeleteFileSystemOrigin(const GURL& origin); |
| + |
| + private: |
| + virtual ~BrowsingDataFileSystemHelperImpl(); |
| + |
| + // Enumerates all filesystem files in the FILE thread. |
| + void FetchFileSystemInfoInFileThread(); |
| + // Notifies the completion callback in the UI thread. |
| + void NotifyInUIThread(); |
| + // Delete data for an origin on the FILE thread. |
| + void DeleteFileSystemOriginInFileThread(const GURL& origin); |
| + |
| + Profile* profile_; |
| + |
| + // This only mutates in the FILE thread. |
| + std::vector<FileSystemInfo> file_system_info_; |
| + |
| + // This only mutates on the UI thread. |
| + scoped_ptr<Callback1<const std::vector<FileSystemInfo>& >::Type > |
| + completion_callback_; |
| + |
| + // Indicates whether or not we're currently fetching information: |
| + // it's true when StartFetching() is called in the UI thread, and it's reset |
| + // after we notified the callback in the UI thread. |
| + // This only mutates on the UI thread. |
| + bool is_fetching_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(BrowsingDataFileSystemHelperImpl); |
| +}; |
| + |
| +BrowsingDataFileSystemHelperImpl::BrowsingDataFileSystemHelperImpl( |
| + Profile* profile) |
| + : profile_(profile), |
| + completion_callback_(NULL), |
|
kinuko
2011/05/25 10:24:41
nit: no need to explicitly initialize it to NULL
Mike West
2011/05/25 12:00:01
Done.
|
| + is_fetching_(false) { |
| + DCHECK(profile_); |
| +} |
| + |
| +BrowsingDataFileSystemHelperImpl::~BrowsingDataFileSystemHelperImpl() { |
| +} |
| + |
| +void BrowsingDataFileSystemHelperImpl::StartFetching( |
| + Callback1<const std::vector<FileSystemInfo>& >::Type* callback) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(!is_fetching_); |
| + DCHECK(callback); |
| + is_fetching_ = true; |
| + completion_callback_.reset(callback); |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + NewRunnableMethod( |
| + this, |
| + &BrowsingDataFileSystemHelperImpl:: |
| + FetchFileSystemInfoInFileThread)); |
| +} |
| + |
| +void BrowsingDataFileSystemHelperImpl::CancelNotification() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + completion_callback_.reset(NULL); |
| +} |
| + |
| +void BrowsingDataFileSystemHelperImpl::DeleteFileSystemOrigin( |
| + const GURL& origin) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + NewRunnableMethod( |
| + this, |
| + &BrowsingDataFileSystemHelperImpl:: |
| + DeleteFileSystemOriginInFileThread, |
| + origin)); |
| +} |
| + |
| +void BrowsingDataFileSystemHelperImpl::FetchFileSystemInfoInFileThread() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + scoped_ptr<fileapi::SandboxMountPointProvider::OriginEnumerator> |
| + origin_enumerator; |
| + |
| + origin_enumerator.reset(profile_->GetFileSystemContext()->path_manager()-> |
| + sandbox_provider()->CreateOriginEnumerator()); |
|
kinuko
2011/05/25 10:24:41
nit: probably this can be done when you initialize
Mike West
2011/05/25 12:00:01
Done.
|
| + |
| + GURL current; |
| + while (!(current = origin_enumerator->Next()).is_empty()) { |
| + if (current.SchemeIs(chrome::kExtensionScheme)) { |
| + // Extension state is not considered browsing data. |
| + continue; |
| + } |
| + file_system_info_.push_back( |
| + FileSystemInfo( |
| + current, |
| + origin_enumerator->HasFileSystemType( |
| + fileapi::kFileSystemTypePersistent), |
| + origin_enumerator->HasFileSystemType( |
| + fileapi::kFileSystemTypeTemporary))); |
| + } |
| + |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + NewRunnableMethod( |
| + this, &BrowsingDataFileSystemHelperImpl::NotifyInUIThread)); |
| +} |
| + |
| +void BrowsingDataFileSystemHelperImpl::NotifyInUIThread() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(is_fetching_); |
| + // Note: completion_callback_ mutates only in the UI thread, so it's safe to |
| + // test it here. |
| + if (completion_callback_ != NULL) { |
| + completion_callback_->Run(file_system_info_); |
| + completion_callback_.reset(); |
| + } |
| + is_fetching_ = false; |
| +} |
| + |
| +void BrowsingDataFileSystemHelperImpl::DeleteFileSystemOriginInFileThread( |
| + const GURL& origin) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + fileapi::FileSystemContext* context = profile_->GetFileSystemContext(); |
|
kinuko
2011/05/25 10:24:41
scoped_refptr<FileSystemContext> ? (Looks like it
Mike West
2011/05/25 12:00:01
Done.
|
| + context->DeleteDataForOriginOnFileThread(origin); |
| +} |
| + |
| +} // namespace |
| + |
| +BrowsingDataFileSystemHelper::FileSystemInfo::FileSystemInfo( |
| + const GURL& origin, |
| + bool has_persistent, |
| + bool has_temporary) |
| + : origin(origin), |
| + has_persistent(has_persistent), |
| + has_temporary(has_temporary) { |
| +} |
| + |
| +BrowsingDataFileSystemHelper::FileSystemInfo::~FileSystemInfo() {} |
| + |
| +// static |
| +BrowsingDataFileSystemHelper* BrowsingDataFileSystemHelper::Create( |
| + Profile* profile) { |
| + return new BrowsingDataFileSystemHelperImpl(profile); |
| +} |
| + |
| +CannedBrowsingDataFileSystemHelper:: |
| +PendingFileSystemInfo::PendingFileSystemInfo() { |
| +} |
| + |
| +CannedBrowsingDataFileSystemHelper:: |
| +PendingFileSystemInfo::PendingFileSystemInfo(const GURL& origin, |
| + const fileapi::FileSystemType type) |
| + : origin(origin), |
| + type(type) { |
| +} |
| + |
| +CannedBrowsingDataFileSystemHelper:: |
| +PendingFileSystemInfo::~PendingFileSystemInfo() { |
| +} |
| + |
| +CannedBrowsingDataFileSystemHelper::CannedBrowsingDataFileSystemHelper( |
| + Profile* profile) |
| + : profile_(profile), |
| + is_fetching_(false) { |
| + DCHECK(profile); |
| +} |
| + |
| +CannedBrowsingDataFileSystemHelper::~CannedBrowsingDataFileSystemHelper() {} |
| + |
| +CannedBrowsingDataFileSystemHelper* |
| + CannedBrowsingDataFileSystemHelper::Clone() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + CannedBrowsingDataFileSystemHelper* clone = |
| + new CannedBrowsingDataFileSystemHelper(profile_); |
| + |
| + base::AutoLock auto_lock(lock_); |
| + clone->pending_file_system_info_ = pending_file_system_info_; |
| + clone->file_system_info_ = file_system_info_; |
| + return clone; |
| +} |
| + |
| +void CannedBrowsingDataFileSystemHelper::AddFileSystem( |
| + const GURL& origin, const fileapi::FileSystemType type) { |
| + base::AutoLock auto_lock(lock_); |
| + pending_file_system_info_.push_back(PendingFileSystemInfo(origin, type)); |
| +} |
| + |
| +void CannedBrowsingDataFileSystemHelper::Reset() { |
| + base::AutoLock auto_lock(lock_); |
| + file_system_info_.clear(); |
| + pending_file_system_info_.clear(); |
| +} |
| + |
| +bool CannedBrowsingDataFileSystemHelper::empty() const { |
| + base::AutoLock auto_lock(lock_); |
| + return file_system_info_.empty() && pending_file_system_info_.empty(); |
| +} |
| + |
| +void CannedBrowsingDataFileSystemHelper::StartFetching( |
| + Callback1<const std::vector<FileSystemInfo>& >::Type* callback) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(!is_fetching_); |
| + DCHECK(callback); |
| + is_fetching_ = true; |
| + completion_callback_.reset(callback); |
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( |
| + this, |
| + &CannedBrowsingDataFileSystemHelper::ConvertPendingInfo)); |
| +} |
| + |
| +void CannedBrowsingDataFileSystemHelper::ConvertPendingInfo() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + base::AutoLock auto_lock(lock_); |
| + for (std::vector<PendingFileSystemInfo>::const_iterator |
| + info = pending_file_system_info_.begin(); |
| + info != pending_file_system_info_.end(); ++info) { |
| + bool duplicate = false; |
| + for (std::vector<FileSystemInfo>::iterator |
| + file_system = file_system_info_.begin(); |
| + file_system != file_system_info_.end(); |
| + ++file_system) { |
| + if (file_system->origin == info->origin) { |
| + if (info->type == fileapi::kFileSystemTypePersistent) { |
| + file_system->has_persistent = true; |
| + } else { |
| + file_system->has_temporary = true; |
| + } |
| + duplicate = true; |
| + break; |
| + } |
| + } |
| + if (duplicate) |
| + continue; |
| + |
| + file_system_info_.push_back(FileSystemInfo( |
| + info->origin, |
| + (info->type == fileapi::kFileSystemTypePersistent), |
| + (info->type == fileapi::kFileSystemTypeTemporary))); |
| + } |
| + pending_file_system_info_.clear(); |
| + |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + NewRunnableMethod( |
| + this, &CannedBrowsingDataFileSystemHelper::Notify)); |
| +} |
| + |
| +void CannedBrowsingDataFileSystemHelper::Notify() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(is_fetching_); |
| + // Note: completion_callback_ mutates only in the UI thread, so it's safe to |
| + // test it here. |
| + if (completion_callback_ != NULL) { |
| + completion_callback_->Run(file_system_info_); |
| + completion_callback_.reset(); |
| + } |
| + is_fetching_ = false; |
| +} |