| Index: chrome/browser/browsing_data_filesystem_helper.cc
|
| diff --git a/chrome/browser/browsing_data_filesystem_helper.cc b/chrome/browser/browsing_data_filesystem_helper.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..619147aa13ee3409cb3b14bd2e8d53f2b286f2d2
|
| --- /dev/null
|
| +++ b/chrome/browser/browsing_data_filesystem_helper.cc
|
| @@ -0,0 +1,297 @@
|
| +// 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_filesystem_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 "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 "content/browser/browser_thread.h"
|
| +#include "content/browser/in_process_webkit/webkit_context.h"
|
| +#include "webkit/glue/webkit_glue.h"
|
| +
|
| +#include "webkit/fileapi/file_system_context.h"
|
| +#include "webkit/fileapi/file_system_types.h"
|
| +#include "webkit/fileapi/sandbox_mount_point_provider.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> filesystem_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),
|
| + 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));
|
| + fileapi::SandboxMountPointProvider::OriginEnumerator* origin_enumerator =
|
| + profile_->GetFileSystemContext()->path_manager()->sandbox_provider()->
|
| + CreateOriginEnumerator();
|
| +
|
| + GURL current;
|
| + while (!(current = origin_enumerator->Next()).is_empty()) {
|
| + if (current.SchemeIs(chrome::kExtensionScheme)) {
|
| + // Extension state is not considered browsing data.
|
| + continue;
|
| + }
|
| + filesystem_info_.push_back(
|
| + FilesystemInfo(
|
| + current.scheme(),
|
| + current.host(),
|
| + current.port(),
|
| + 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(filesystem_info_);
|
| + completion_callback_.reset();
|
| + }
|
| + is_fetching_ = false;
|
| +}
|
| +
|
| +void BrowsingDataFilesystemHelperImpl::DeleteFilesystemOriginInFileThread(
|
| + const GURL& origin) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| + fileapi::FileSystemContext* context = profile_->GetFileSystemContext();
|
| + context->DeleteDataForOriginOnFileThread(origin);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +BrowsingDataFilesystemHelper::FilesystemInfo::FilesystemInfo(
|
| + const std::string& protocol,
|
| + const std::string& host,
|
| + const std::string& port,
|
| + const GURL& origin,
|
| + bool has_persistent,
|
| + bool has_temporary)
|
| + : protocol(protocol),
|
| + host(host),
|
| + port(port),
|
| + 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),
|
| + completion_callback_(NULL),
|
| + is_fetching_(false) {
|
| + DCHECK(profile);
|
| +}
|
| +
|
| +CannedBrowsingDataFilesystemHelper*
|
| + CannedBrowsingDataFilesystemHelper::Clone() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + CannedBrowsingDataFilesystemHelper* clone =
|
| + new CannedBrowsingDataFilesystemHelper(profile_);
|
| +
|
| + base::AutoLock auto_lock(lock_);
|
| + clone->pending_filesystem_info_ = pending_filesystem_info_;
|
| + clone->filesystem_info_ = filesystem_info_;
|
| + return clone;
|
| +}
|
| +
|
| +void CannedBrowsingDataFilesystemHelper::AddFilesystem(
|
| + const GURL& origin, const fileapi::FileSystemType type) {
|
| + base::AutoLock auto_lock(lock_);
|
| + pending_filesystem_info_.push_back(PendingFilesystemInfo(origin, type));
|
| +}
|
| +
|
| +void CannedBrowsingDataFilesystemHelper::Reset() {
|
| + base::AutoLock auto_lock(lock_);
|
| + filesystem_info_.clear();
|
| + pending_filesystem_info_.clear();
|
| +}
|
| +
|
| +bool CannedBrowsingDataFilesystemHelper::empty() const {
|
| + base::AutoLock auto_lock(lock_);
|
| + return filesystem_info_.empty() && pending_filesystem_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::WEBKIT, FROM_HERE, NewRunnableMethod(
|
| + this,
|
| + &CannedBrowsingDataFilesystemHelper::ConvertPendingInfoInWebKitThread));
|
| +}
|
| +
|
| +CannedBrowsingDataFilesystemHelper::~CannedBrowsingDataFilesystemHelper() {}
|
| +
|
| +void CannedBrowsingDataFilesystemHelper::ConvertPendingInfoInWebKitThread() {
|
| + base::AutoLock auto_lock(lock_);
|
| + for (std::vector<PendingFilesystemInfo>::const_iterator
|
| + info = pending_filesystem_info_.begin();
|
| + info != pending_filesystem_info_.end(); ++info) {
|
| + bool duplicate = false;
|
| + for (std::vector<FilesystemInfo>::iterator
|
| + filesystem = filesystem_info_.begin();
|
| + filesystem != filesystem_info_.end();
|
| + ++filesystem) {
|
| + if (filesystem->origin == info->origin) {
|
| + if (info->type == fileapi::kFileSystemTypePersistent) {
|
| + filesystem->has_persistent = true;
|
| + } else {
|
| + filesystem->has_temporary = true;
|
| + }
|
| + duplicate = true;
|
| + break;
|
| + }
|
| + }
|
| + if (duplicate)
|
| + continue;
|
| +
|
| + filesystem_info_.push_back(FilesystemInfo(
|
| + info->origin.scheme(),
|
| + info->origin.host(),
|
| + info->origin.port(),
|
| + info->origin,
|
| + (info->type == fileapi::kFileSystemTypePersistent),
|
| + (info->type == fileapi::kFileSystemTypeTemporary)));
|
| + }
|
| + pending_filesystem_info_.clear();
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + NewRunnableMethod(
|
| + this, &CannedBrowsingDataFilesystemHelper::NotifyInUIThread));
|
| +}
|
| +
|
| +void CannedBrowsingDataFilesystemHelper::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(filesystem_info_);
|
| + completion_callback_.reset();
|
| + }
|
| + is_fetching_ = false;
|
| +}
|
|
|