diff options
Diffstat (limited to 'webkit/fileapi/file_system_usage_tracker.cc')
-rw-r--r-- | webkit/fileapi/file_system_usage_tracker.cc | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/webkit/fileapi/file_system_usage_tracker.cc b/webkit/fileapi/file_system_usage_tracker.cc new file mode 100644 index 0000000..2b16a1f --- /dev/null +++ b/webkit/fileapi/file_system_usage_tracker.cc @@ -0,0 +1,158 @@ +// 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 "webkit/fileapi/file_system_usage_tracker.h" + +#include <algorithm> + +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/logging.h" +#include "base/message_loop_proxy.h" +#include "base/scoped_ptr.h" +#include "base/task.h" +#include "googleurl/src/gurl.h" +#include "webkit/fileapi/file_system_path_manager.h" + +namespace fileapi { + +class FileSystemUsageTracker::GetUsageTask + : public base::RefCountedThreadSafe<GetUsageTask> { + public: + GetUsageTask( + FileSystemUsageTracker* tracker, + scoped_refptr<base::MessageLoopProxy> file_message_loop, + std::string fs_name, + const FilePath& origin_base_path) + : tracker_(tracker), + file_message_loop_(file_message_loop), + original_message_loop_( + base::MessageLoopProxy::CreateForCurrentThread()), + fs_name_(fs_name), + fs_usage_(0), + origin_base_path_(origin_base_path) { + } + + virtual ~GetUsageTask() {} + + void Start() { + DCHECK(tracker_); + tracker_->RegisterUsageTask(this); + file_message_loop_->PostTask( + FROM_HERE, NewRunnableMethod(this, &GetUsageTask::RunOnFileThread)); + } + + void Cancel() { + DCHECK(original_message_loop_->BelongsToCurrentThread()); + tracker_ = NULL; + } + + private: + void RunOnFileThread() { + DCHECK(file_message_loop_->BelongsToCurrentThread()); + + // TODO(dmikurube): add the code that retrieves the origin usage here. + + original_message_loop_->PostTask( + FROM_HERE, NewRunnableMethod(this, &GetUsageTask::Completed)); + } + + void Completed() { + DCHECK(original_message_loop_->BelongsToCurrentThread()); + if (tracker_) { + tracker_->UnregisterUsageTask(this); + tracker_->DidGetOriginUsage(fs_name_, fs_usage_); + } + } + + FileSystemUsageTracker* tracker_; + scoped_refptr<base::MessageLoopProxy> file_message_loop_; + scoped_refptr<base::MessageLoopProxy> original_message_loop_; + std::string fs_name_; + int64 fs_usage_; + FilePath origin_base_path_; +}; + +FileSystemUsageTracker::FileSystemUsageTracker( + scoped_refptr<base::MessageLoopProxy> file_message_loop, + const FilePath& profile_path, + bool is_incognito) + : file_message_loop_(file_message_loop), + base_path_(profile_path.Append( + FileSystemPathManager::kFileSystemDirectory)), + is_incognito_(is_incognito) { + DCHECK(file_message_loop); +} + +FileSystemUsageTracker::~FileSystemUsageTracker() { + std::for_each(running_usage_tasks_.begin(), + running_usage_tasks_.end(), + std::mem_fun(&GetUsageTask::Cancel)); +} + +void FileSystemUsageTracker::GetOriginUsage( + const GURL& origin_url, + fileapi::FileSystemType type, + GetUsageCallback* callback_ptr) { + DCHECK(callback_ptr); + scoped_ptr<GetUsageCallback> callback(callback_ptr); + + if (is_incognito_) { + // We don't support FileSystem in incognito mode yet. + callback->Run(0); + return; + } + + std::string fs_name = FileSystemPathManager::GetFileSystemName( + origin_url, type); + if (pending_usage_callbacks_.find(fs_name) != + pending_usage_callbacks_.end()) { + // Another get usage task is running. Add the callback to + // the pending queue and return. + pending_usage_callbacks_[fs_name].push_back(callback.release()); + return; + } + + // Get the filesystem base path (i.e. "FileSystem/<origin>/<type>", + // without unique part). + FilePath origin_base_path = + FileSystemPathManager::GetFileSystemBaseDirectoryForOriginAndType( + base_path_, origin_url, type); + if (origin_base_path.empty()) { + // The directory does not exist. + callback->Run(0); + return; + } + + pending_usage_callbacks_[fs_name].push_back(callback.release()); + scoped_refptr<GetUsageTask> task( + new GetUsageTask(this, file_message_loop_, fs_name, origin_base_path)); + task->Start(); +} + +void FileSystemUsageTracker::RegisterUsageTask(GetUsageTask* task) { + running_usage_tasks_.push_back(task); +} + +void FileSystemUsageTracker::UnregisterUsageTask(GetUsageTask* task) { + DCHECK(running_usage_tasks_.front() == task); + running_usage_tasks_.pop_front(); +} + +void FileSystemUsageTracker::DidGetOriginUsage( + const std::string& fs_name, int64 usage) { + PendingUsageCallbackMap::iterator cb_list_iter = + pending_usage_callbacks_.find(fs_name); + DCHECK(cb_list_iter != pending_usage_callbacks_.end()); + PendingCallbackList cb_list = cb_list_iter->second; + for (PendingCallbackList::iterator cb_iter = cb_list.begin(); + cb_iter != cb_list.end(); + ++cb_iter) { + scoped_ptr<GetUsageCallback> callback(*cb_iter); + callback->Run(usage); + } + pending_usage_callbacks_.erase(cb_list_iter); +} + +} // namespace fileapi |