summaryrefslogtreecommitdiffstats
path: root/webkit/fileapi
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-10 13:17:58 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-10 13:17:58 +0000
commit955dd7ebf6808dd93dd1aedc7390e7280e848f80 (patch)
tree6a9e559583084a956005c367249026647e3879bf /webkit/fileapi
parent0c5e07b0a63a5aea8ab0c2b50177b4c99e7c9538 (diff)
downloadchromium_src-955dd7ebf6808dd93dd1aedc7390e7280e848f80.zip
chromium_src-955dd7ebf6808dd93dd1aedc7390e7280e848f80.tar.gz
chromium_src-955dd7ebf6808dd93dd1aedc7390e7280e848f80.tar.bz2
Add 1st cut of FileSystemUsageTracker that tracks the usage changes in FileSystem API.
For now it has no meaningful implementation yet; mostly just for defining a few interfaces. BUG= TEST=FileSystemUsageTrackerTest.DummyTest Review URL: http://codereview.chromium.org/6426001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@74429 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/fileapi')
-rw-r--r--webkit/fileapi/file_system_path_manager.cc53
-rw-r--r--webkit/fileapi/file_system_path_manager.h24
-rw-r--r--webkit/fileapi/file_system_usage_tracker.cc158
-rw-r--r--webkit/fileapi/file_system_usage_tracker.h71
-rw-r--r--webkit/fileapi/file_system_usage_tracker_unittest.cc66
-rw-r--r--webkit/fileapi/sandboxed_file_system_context.cc11
-rw-r--r--webkit/fileapi/sandboxed_file_system_context.h6
-rw-r--r--webkit/fileapi/webkit_fileapi.gypi2
8 files changed, 362 insertions, 29 deletions
diff --git a/webkit/fileapi/file_system_path_manager.cc b/webkit/fileapi/file_system_path_manager.cc
index 72c5355..3e0cd5e 100644
--- a/webkit/fileapi/file_system_path_manager.cc
+++ b/webkit/fileapi/file_system_path_manager.cc
@@ -77,6 +77,14 @@ FilePath::StringType CreateUniqueDirectoryName(const GURL& origin_url) {
static const char kExtensionScheme[] = "chrome-extension";
+inline std::string GetFileSystemTypeString(fileapi::FileSystemType type) {
+ if (type == fileapi::kFileSystemTypeTemporary)
+ return fileapi::FileSystemPathManager::kTemporaryName;
+ else if (type == fileapi::kFileSystemTypePersistent)
+ return fileapi::FileSystemPathManager::kPersistentName;
+ return std::string();
+}
+
} // anonymous namespace
class FileSystemPathManager::GetFileSystemRootPathTask
@@ -198,29 +206,17 @@ void FileSystemPathManager::GetFileSystemRootPath(
return;
}
- if (type != fileapi::kFileSystemTypeTemporary &&
- type != fileapi::kFileSystemTypePersistent) {
- LOG(WARNING) << "Unknown filesystem type is requested:" << type;
+ FilePath origin_base_path = GetFileSystemBaseDirectoryForOriginAndType(
+ base_path(), origin_url, type);
+ if (origin_base_path.empty()) {
callback->Run(false, FilePath(), std::string());
return;
}
- std::string storage_identifier = GetStorageIdentifierFromURL(origin_url);
-
- std::string type_string;
- if (type == fileapi::kFileSystemTypeTemporary)
- type_string = kTemporaryName;
- else if (type == fileapi::kFileSystemTypePersistent)
- type_string = kPersistentName;
- DCHECK(!type_string.empty());
-
- FilePath origin_base_path = base_path_.AppendASCII(storage_identifier)
- .AppendASCII(type_string);
- std::string name = storage_identifier + ":" + type_string;
-
scoped_refptr<GetFileSystemRootPathTask> task(
new GetFileSystemRootPathTask(file_message_loop_,
- name, callback.release()));
+ GetFileSystemName(origin_url, type),
+ callback.release()));
task->Start(origin_url, origin_base_path, create);
}
@@ -326,6 +322,14 @@ bool FileSystemPathManager::IsAllowedScheme(const GURL& url) const {
(url.SchemeIsFile() && allow_file_access_from_files_);
}
+// static
+std::string FileSystemPathManager::GetFileSystemName(
+ const GURL& origin_url, fileapi::FileSystemType type) {
+ return GetStorageIdentifierFromURL(origin_url)
+ .append(":").append(GetFileSystemTypeString(type));
+}
+
+// static
std::string FileSystemPathManager::GetStorageIdentifierFromURL(
const GURL& url) {
WebKit::WebSecurityOrigin web_security_origin =
@@ -333,6 +337,21 @@ std::string FileSystemPathManager::GetStorageIdentifierFromURL(
return web_security_origin.databaseIdentifier().utf8();
}
+// static
+FilePath FileSystemPathManager::GetFileSystemBaseDirectoryForOriginAndType(
+ const FilePath& base_path, const GURL& origin_url,
+ fileapi::FileSystemType type) {
+ if (!origin_url.is_valid())
+ return FilePath();
+ std::string type_string = GetFileSystemTypeString(type);
+ if (type_string.empty()) {
+ LOG(WARNING) << "Unknown filesystem type is requested:" << type;
+ return FilePath();
+ }
+ return base_path.AppendASCII(GetStorageIdentifierFromURL(origin_url))
+ .AppendASCII(type_string);
+}
+
} // namespace fileapi
COMPILE_ASSERT(int(WebFileSystem::TypeTemporary) == \
diff --git a/webkit/fileapi/file_system_path_manager.h b/webkit/fileapi/file_system_path_manager.h
index 16c7182..f7a3803 100644
--- a/webkit/fileapi/file_system_path_manager.h
+++ b/webkit/fileapi/file_system_path_manager.h
@@ -5,8 +5,6 @@
#ifndef WEBKIT_FILEAPI_FILE_SYSTEM_PATH_MANAGER_H_
#define WEBKIT_FILEAPI_FILE_SYSTEM_PATH_MANAGER_H_
-#include <map>
-
#include "base/callback.h"
#include "base/file_path.h"
#include "base/scoped_ptr.h"
@@ -20,6 +18,12 @@ class MessageLoopProxy;
namespace fileapi {
+// An interface to construct or crack sandboxed filesystem paths.
+// Currently each sandboxed filesystem path looks like:
+//
+// <profile_dir>/FileSystem/<origin_identifier>/<type>/chrome-<unique>/...
+//
+// where <type> is either one of "Temporary" or "Persistent".
class FileSystemPathManager {
public:
FileSystemPathManager(scoped_refptr<base::MessageLoopProxy> file_message_loop,
@@ -74,9 +78,25 @@ class FileSystemPathManager {
return base_path_;
}
+ // Returns the filesystem name string for the given |origin_url| and |type|.
+ static std::string GetFileSystemName(const GURL& url,
+ fileapi::FileSystemType type);
+
// Returns the storage identifier string for the given |url|.
static std::string GetStorageIdentifierFromURL(const GURL& url);
+ // Gets a base directory path of the sandboxed filesystem that is
+ // specified by |origin_url| and |type|.
+ // |base_path| must be pointing the FileSystem's data directory
+ // under the profile directory, i.e. <profile_dir>/kFileSystemDirectory.
+ // Returns an empty path if any of the given parameters are invalid.
+ // Returned directory path does not contain 'unique' part, therefore
+ // it is not an actural root path for the filesystem.
+ static FilePath GetFileSystemBaseDirectoryForOriginAndType(
+ const FilePath& base_path,
+ const GURL& origin_url,
+ fileapi::FileSystemType type);
+
private:
class GetFileSystemRootPathTask;
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
diff --git a/webkit/fileapi/file_system_usage_tracker.h b/webkit/fileapi/file_system_usage_tracker.h
new file mode 100644
index 0000000..10a5177
--- /dev/null
+++ b/webkit/fileapi/file_system_usage_tracker.h
@@ -0,0 +1,71 @@
+// 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.
+
+#ifndef WEBKIT_FILEAPI_FILE_SYSTEM_USAGE_TRACKER_H_
+#define WEBKIT_FILEAPI_FILE_SYSTEM_USAGE_TRACKER_H_
+
+#include <deque>
+#include <list>
+#include <map>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/file_path.h"
+#include "base/ref_counted.h"
+#include "webkit/fileapi/file_system_types.h"
+
+class GURL;
+
+namespace base {
+class MessageLoopProxy;
+}
+
+namespace fileapi {
+
+// Owned by the SandboxedFileSystemContext, which is a per-profile
+// instance, and has the same lifetime as the SandboxedFileSystemContext.
+// It's going to be created and destroyed on the IO thread in chrome.
+// (The destruction on the same thread where it is created was guaranteed
+// by its owner, SandboxedFileSystemContext.)
+class FileSystemUsageTracker {
+ public:
+ FileSystemUsageTracker(
+ scoped_refptr<base::MessageLoopProxy> file_message_loop,
+ const FilePath& profile_path,
+ bool is_incognito);
+ ~FileSystemUsageTracker();
+
+ // Get the amount of data stored in the filesystem specified by
+ // |origin_url| and |type|.
+ typedef Callback1<int64 /* usage */>::Type GetUsageCallback;
+ void GetOriginUsage(const GURL& origin_url,
+ fileapi::FileSystemType type,
+ GetUsageCallback* callback);
+
+ private:
+ class GetUsageTask;
+
+ void RegisterUsageTask(GetUsageTask* task);
+ void UnregisterUsageTask(GetUsageTask* task);
+
+ void DidGetOriginUsage(const std::string& fs_name, int64 usage);
+
+ scoped_refptr<base::MessageLoopProxy> file_message_loop_;
+ FilePath base_path_;
+ bool is_incognito_;
+
+ typedef std::deque<GetUsageTask*> UsageTaskQueue;
+ UsageTaskQueue running_usage_tasks_;
+
+ typedef std::list<GetUsageCallback*> PendingCallbackList;
+ typedef std::map<std::string, PendingCallbackList> PendingUsageCallbackMap;
+ PendingUsageCallbackMap pending_usage_callbacks_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileSystemUsageTracker);
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_FILEAPI_FILE_SYSTEM_USAGE_TRACKER_H_
diff --git a/webkit/fileapi/file_system_usage_tracker_unittest.cc b/webkit/fileapi/file_system_usage_tracker_unittest.cc
new file mode 100644
index 0000000..0d8a33c
--- /dev/null
+++ b/webkit/fileapi/file_system_usage_tracker_unittest.cc
@@ -0,0 +1,66 @@
+// 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 "base/basictypes.h"
+#include "base/file_util.h"
+#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
+#include "base/scoped_callback_factory.h"
+#include "googleurl/src/gurl.h"
+#include "base/scoped_temp_dir.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/fileapi/file_system_path_manager.h"
+#include "webkit/fileapi/file_system_types.h"
+
+using namespace fileapi;
+
+class FileSystemUsageTrackerTest : public testing::Test {
+ public:
+ FileSystemUsageTrackerTest()
+ : callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ }
+
+ void SetUp() {
+ ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
+ }
+
+ protected:
+ FileSystemUsageTracker* NewUsageTracker(bool is_incognito) {
+ return new FileSystemUsageTracker(
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ data_dir_.path(), is_incognito);
+ }
+
+ int64 GetOriginUsage(FileSystemUsageTracker* tracker,
+ const GURL& origin_url,
+ fileapi::FileSystemType type) {
+ tracker->GetOriginUsage(origin_url, type,
+ callback_factory_.NewCallback(
+ &FileSystemUsageTrackerTest::OnGetUsage));
+ MessageLoop::current()->RunAllPending();
+ return usage_;
+ }
+
+ private:
+ void OnGetUsage(int64 usage) {
+ usage_ = usage;
+ }
+
+ ScopedTempDir data_dir_;
+ base::ScopedCallbackFactory<FileSystemUsageTrackerTest> callback_factory_;
+ int64 usage_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileSystemUsageTrackerTest);
+};
+
+// TODO(dmikurube): change this test to a meaningful one once we add
+// the real code in the FileSystemUsageTracker.
+TEST_F(FileSystemUsageTrackerTest, DummyTest) {
+ scoped_ptr<FileSystemUsageTracker> tracker(NewUsageTracker(false));
+ ASSERT_EQ(0, GetOriginUsage(tracker.get(),
+ GURL("http://www.dummy.org/"),
+ fileapi::kFileSystemTypeTemporary));
+}
diff --git a/webkit/fileapi/sandboxed_file_system_context.cc b/webkit/fileapi/sandboxed_file_system_context.cc
index 16232d5..1fd458d 100644
--- a/webkit/fileapi/sandboxed_file_system_context.cc
+++ b/webkit/fileapi/sandboxed_file_system_context.cc
@@ -8,6 +8,7 @@
#include "base/message_loop_proxy.h"
#include "webkit/fileapi/file_system_path_manager.h"
#include "webkit/fileapi/file_system_quota_manager.h"
+#include "webkit/fileapi/file_system_usage_tracker.h"
namespace fileapi {
@@ -23,18 +24,14 @@ SandboxedFileSystemContext::SandboxedFileSystemContext(
path_manager_(new FileSystemPathManager(
file_message_loop, profile_path, is_incognito, allow_file_access)),
quota_manager_(new FileSystemQuotaManager(
- allow_file_access, unlimited_quota)) {
+ allow_file_access, unlimited_quota)),
+ usage_tracker_(new FileSystemUsageTracker(
+ file_message_loop, profile_path, is_incognito)) {
}
SandboxedFileSystemContext::~SandboxedFileSystemContext() {
}
-void SandboxedFileSystemContext::Shutdown() {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- path_manager_.reset();
- quota_manager_.reset();
-}
-
void SandboxedFileSystemContext::DeleteDataForOriginOnFileThread(
const GURL& origin_url) {
DCHECK(path_manager_.get());
diff --git a/webkit/fileapi/sandboxed_file_system_context.h b/webkit/fileapi/sandboxed_file_system_context.h
index fcb90bb..e3b7a67 100644
--- a/webkit/fileapi/sandboxed_file_system_context.h
+++ b/webkit/fileapi/sandboxed_file_system_context.h
@@ -19,6 +19,7 @@ namespace fileapi {
class FileSystemPathManager;
class FileSystemQuotaManager;
+class FileSystemUsageTracker;
class SandboxedFileSystemContext;
struct DefaultContextDeleter;
@@ -37,8 +38,6 @@ class SandboxedFileSystemContext
bool unlimited_quota);
~SandboxedFileSystemContext();
- void Shutdown();
-
void DeleteDataForOriginOnFileThread(const GURL& origin_url);
// Quota related methods.
@@ -47,16 +46,17 @@ class SandboxedFileSystemContext
FileSystemPathManager* path_manager() { return path_manager_.get(); }
FileSystemQuotaManager* quota_manager() { return quota_manager_.get(); }
+ FileSystemUsageTracker* usage_tracker() { return usage_tracker_.get(); }
private:
friend struct DefaultContextDeleter;
void DeleteOnCorrectThread() const;
- bool allow_file_access_from_files_;
scoped_refptr<base::MessageLoopProxy> file_message_loop_;
scoped_refptr<base::MessageLoopProxy> io_message_loop_;
scoped_ptr<FileSystemPathManager> path_manager_;
scoped_ptr<FileSystemQuotaManager> quota_manager_;
+ scoped_ptr<FileSystemUsageTracker> usage_tracker_;
DISALLOW_IMPLICIT_CONSTRUCTORS(SandboxedFileSystemContext);
};
diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi
index f5f8675..c1beb11 100644
--- a/webkit/fileapi/webkit_fileapi.gypi
+++ b/webkit/fileapi/webkit_fileapi.gypi
@@ -26,6 +26,8 @@
'file_system_types.h',
'file_system_url_request_job.cc',
'file_system_url_request_job.h',
+ 'file_system_usage_tracker.cc',
+ 'file_system_usage_tracker.h',
'file_system_util.cc',
'file_system_util.h',
'file_writer_delegate.cc',