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 "webkit/fileapi/file_system_usage_tracker.h" |
| 6 |
| 7 #include <algorithm> |
| 8 |
| 9 #include "base/file_path.h" |
| 10 #include "base/file_util.h" |
| 11 #include "base/logging.h" |
| 12 #include "base/message_loop_proxy.h" |
| 13 #include "base/scoped_ptr.h" |
| 14 #include "base/task.h" |
| 15 #include "googleurl/src/gurl.h" |
| 16 #include "webkit/fileapi/file_system_path_manager.h" |
| 17 |
| 18 namespace fileapi { |
| 19 |
| 20 class FileSystemUsageTracker::GetUsageTask |
| 21 : public base::RefCountedThreadSafe<GetUsageTask> { |
| 22 public: |
| 23 GetUsageTask( |
| 24 FileSystemUsageTracker* tracker, |
| 25 scoped_refptr<base::MessageLoopProxy> file_message_loop, |
| 26 std::string fs_name, |
| 27 const FilePath& origin_base_path) |
| 28 : tracker_(tracker), |
| 29 file_message_loop_(file_message_loop), |
| 30 original_message_loop_( |
| 31 base::MessageLoopProxy::CreateForCurrentThread()), |
| 32 fs_name_(fs_name), |
| 33 fs_usage_(0), |
| 34 origin_base_path_(origin_base_path) { |
| 35 } |
| 36 |
| 37 virtual ~GetUsageTask() {} |
| 38 |
| 39 void Start() { |
| 40 DCHECK(tracker_); |
| 41 tracker_->RegisterUsageTask(this); |
| 42 file_message_loop_->PostTask( |
| 43 FROM_HERE, NewRunnableMethod(this, &GetUsageTask::RunOnFileThread)); |
| 44 } |
| 45 |
| 46 void Cancel() { |
| 47 DCHECK(original_message_loop_->BelongsToCurrentThread()); |
| 48 tracker_ = NULL; |
| 49 } |
| 50 |
| 51 private: |
| 52 void RunOnFileThread() { |
| 53 DCHECK(file_message_loop_->BelongsToCurrentThread()); |
| 54 |
| 55 // TODO(dmikurube): add the code that retrieves the origin usage here. |
| 56 |
| 57 original_message_loop_->PostTask( |
| 58 FROM_HERE, NewRunnableMethod(this, &GetUsageTask::Completed)); |
| 59 } |
| 60 |
| 61 void Completed() { |
| 62 DCHECK(original_message_loop_->BelongsToCurrentThread()); |
| 63 if (tracker_) { |
| 64 tracker_->UnregisterUsageTask(this); |
| 65 tracker_->DidGetOriginUsage(fs_name_, fs_usage_); |
| 66 } |
| 67 } |
| 68 |
| 69 FileSystemUsageTracker* tracker_; |
| 70 scoped_refptr<base::MessageLoopProxy> file_message_loop_; |
| 71 scoped_refptr<base::MessageLoopProxy> original_message_loop_; |
| 72 std::string fs_name_; |
| 73 int64 fs_usage_; |
| 74 FilePath origin_base_path_; |
| 75 }; |
| 76 |
| 77 FileSystemUsageTracker::FileSystemUsageTracker( |
| 78 scoped_refptr<base::MessageLoopProxy> file_message_loop, |
| 79 const FilePath& profile_path, |
| 80 bool is_incognito) |
| 81 : file_message_loop_(file_message_loop), |
| 82 base_path_(profile_path.Append( |
| 83 FileSystemPathManager::kFileSystemDirectory)), |
| 84 is_incognito_(is_incognito) { |
| 85 DCHECK(file_message_loop); |
| 86 } |
| 87 |
| 88 FileSystemUsageTracker::~FileSystemUsageTracker() { |
| 89 std::for_each(running_usage_tasks_.begin(), |
| 90 running_usage_tasks_.end(), |
| 91 std::mem_fun(&GetUsageTask::Cancel)); |
| 92 } |
| 93 |
| 94 void FileSystemUsageTracker::GetOriginUsage( |
| 95 const GURL& origin_url, |
| 96 fileapi::FileSystemType type, |
| 97 GetUsageCallback* callback_ptr) { |
| 98 DCHECK(callback_ptr); |
| 99 scoped_ptr<GetUsageCallback> callback(callback_ptr); |
| 100 |
| 101 if (is_incognito_) { |
| 102 // We don't support FileSystem in incognito mode yet. |
| 103 callback->Run(0); |
| 104 return; |
| 105 } |
| 106 |
| 107 std::string fs_name = FileSystemPathManager::GetFileSystemName( |
| 108 origin_url, type); |
| 109 if (pending_usage_callbacks_.find(fs_name) != |
| 110 pending_usage_callbacks_.end()) { |
| 111 // Another get usage task is running. Add the callback to |
| 112 // the pending queue and return. |
| 113 pending_usage_callbacks_[fs_name].push_back(callback.release()); |
| 114 return; |
| 115 } |
| 116 |
| 117 // Get the filesystem base path (i.e. "FileSystem/<origin>/<type>", |
| 118 // without unique part). |
| 119 FilePath origin_base_path = |
| 120 FileSystemPathManager::GetFileSystemBaseDirectoryForOriginAndType( |
| 121 base_path_, origin_url, type); |
| 122 if (origin_base_path.empty()) { |
| 123 // The directory does not exist. |
| 124 callback->Run(0); |
| 125 return; |
| 126 } |
| 127 |
| 128 pending_usage_callbacks_[fs_name].push_back(callback.release()); |
| 129 scoped_refptr<GetUsageTask> task( |
| 130 new GetUsageTask(this, file_message_loop_, fs_name, origin_base_path)); |
| 131 task->Start(); |
| 132 } |
| 133 |
| 134 void FileSystemUsageTracker::RegisterUsageTask(GetUsageTask* task) { |
| 135 running_usage_tasks_.push_back(task); |
| 136 } |
| 137 |
| 138 void FileSystemUsageTracker::UnregisterUsageTask(GetUsageTask* task) { |
| 139 DCHECK(running_usage_tasks_.front() == task); |
| 140 running_usage_tasks_.pop_front(); |
| 141 } |
| 142 |
| 143 void FileSystemUsageTracker::DidGetOriginUsage( |
| 144 const std::string& fs_name, int64 usage) { |
| 145 PendingUsageCallbackMap::iterator cb_list_iter = |
| 146 pending_usage_callbacks_.find(fs_name); |
| 147 DCHECK(cb_list_iter != pending_usage_callbacks_.end()); |
| 148 PendingCallbackList cb_list = cb_list_iter->second; |
| 149 for (PendingCallbackList::iterator cb_iter = cb_list.begin(); |
| 150 cb_iter != cb_list.end(); |
| 151 ++cb_iter) { |
| 152 scoped_ptr<GetUsageCallback> callback(*cb_iter); |
| 153 callback->Run(usage); |
| 154 } |
| 155 pending_usage_callbacks_.erase(cb_list_iter); |
| 156 } |
| 157 |
| 158 } // namespace fileapi |
OLD | NEW |