Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / browsing_data / browsing_data_file_system_helper.cc
1 // Copyright (c) 2012 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 "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
6
7 #include <set>
8
9 #include "base/bind.h"
10 #include "base/compiler_specific.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/browsing_data/browsing_data_helper.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "storage/browser/fileapi/file_system_context.h"
18 #include "storage/browser/fileapi/file_system_quota_util.h"
19 #include "storage/common/fileapi/file_system_types.h"
20
21 using content::BrowserThread;
22
23 namespace storage {
24 class FileSystemContext;
25 }
26
27 namespace {
28
29 // An implementation of the BrowsingDataFileSystemHelper interface that pulls
30 // data from a given |filesystem_context| and returns a list of FileSystemInfo
31 // items to a client.
32 class BrowsingDataFileSystemHelperImpl : public BrowsingDataFileSystemHelper {
33  public:
34   // BrowsingDataFileSystemHelper implementation
35   explicit BrowsingDataFileSystemHelperImpl(
36       storage::FileSystemContext* filesystem_context);
37   virtual void StartFetching(const base::Callback<
38       void(const std::list<FileSystemInfo>&)>& callback) OVERRIDE;
39   virtual void DeleteFileSystemOrigin(const GURL& origin) OVERRIDE;
40
41  private:
42   virtual ~BrowsingDataFileSystemHelperImpl();
43
44   // Enumerates all filesystem files, storing the resulting list into
45   // file_system_file_ for later use. This must be called on the file
46   // task runner.
47   void FetchFileSystemInfoInFileThread();
48
49   // Triggers the success callback as the end of a StartFetching workflow. This
50   // must be called on the UI thread.
51   void NotifyOnUIThread();
52
53   // Deletes all file systems associated with |origin|. This must be called on
54   // the file task runner.
55   void DeleteFileSystemOriginInFileThread(const GURL& origin);
56
57   // Returns the file task runner for the |filesystem_context_|.
58   base::SequencedTaskRunner* file_task_runner() {
59     return filesystem_context_->default_file_task_runner();
60   }
61
62   // Keep a reference to the FileSystemContext object for the current profile
63   // for use on the file task runner.
64   scoped_refptr<storage::FileSystemContext> filesystem_context_;
65
66   // Holds the current list of file systems returned to the client after
67   // StartFetching is called. Access to |file_system_info_| is triggered
68   // indirectly via the UI thread and guarded by |is_fetching_|. This means
69   // |file_system_info_| is only accessed while |is_fetching_| is true. The
70   // flag |is_fetching_| is only accessed on the UI thread. In the context of
71   // this class |file_system_info_| only mutates on the file task runner.
72   std::list<FileSystemInfo> file_system_info_;
73
74   // Holds the callback passed in at the beginning of the StartFetching workflow
75   // so that it can be triggered via NotifyOnUIThread. This only mutates on the
76   // UI thread.
77   base::Callback<void(const std::list<FileSystemInfo>&)> completion_callback_;
78
79   // Indicates whether or not we're currently fetching information: set to true
80   // when StartFetching is called on the UI thread, and reset to false when
81   // NotifyOnUIThread triggers the success callback.
82   // This property only mutates on the UI thread.
83   bool is_fetching_;
84
85   DISALLOW_COPY_AND_ASSIGN(BrowsingDataFileSystemHelperImpl);
86 };
87
88 BrowsingDataFileSystemHelperImpl::BrowsingDataFileSystemHelperImpl(
89     storage::FileSystemContext* filesystem_context)
90     : filesystem_context_(filesystem_context), is_fetching_(false) {
91   DCHECK(filesystem_context_.get());
92 }
93
94 BrowsingDataFileSystemHelperImpl::~BrowsingDataFileSystemHelperImpl() {
95 }
96
97 void BrowsingDataFileSystemHelperImpl::StartFetching(
98     const base::Callback<void(const std::list<FileSystemInfo>&)>& callback) {
99   DCHECK_CURRENTLY_ON(BrowserThread::UI);
100   DCHECK(!is_fetching_);
101   DCHECK(!callback.is_null());
102   is_fetching_ = true;
103   completion_callback_ = callback;
104   file_task_runner()->PostTask(
105       FROM_HERE,
106       base::Bind(
107           &BrowsingDataFileSystemHelperImpl::FetchFileSystemInfoInFileThread,
108           this));
109 }
110
111 void BrowsingDataFileSystemHelperImpl::DeleteFileSystemOrigin(
112     const GURL& origin) {
113   DCHECK_CURRENTLY_ON(BrowserThread::UI);
114   file_task_runner()->PostTask(
115       FROM_HERE,
116       base::Bind(
117           &BrowsingDataFileSystemHelperImpl::DeleteFileSystemOriginInFileThread,
118           this, origin));
119 }
120
121 void BrowsingDataFileSystemHelperImpl::FetchFileSystemInfoInFileThread() {
122   DCHECK(file_task_runner()->RunsTasksOnCurrentThread());
123
124   // We check usage for these filesystem types.
125   const storage::FileSystemType types[] = {
126     storage::kFileSystemTypeTemporary,
127     storage::kFileSystemTypePersistent,
128 #if defined(ENABLE_EXTENSIONS)
129     storage::kFileSystemTypeSyncable,
130 #endif
131   };
132
133   typedef std::map<GURL, FileSystemInfo> OriginInfoMap;
134   OriginInfoMap file_system_info_map;
135   for (size_t i = 0; i < arraysize(types); ++i) {
136     storage::FileSystemType type = types[i];
137     storage::FileSystemQuotaUtil* quota_util =
138         filesystem_context_->GetQuotaUtil(type);
139     DCHECK(quota_util);
140     std::set<GURL> origins;
141     quota_util->GetOriginsForTypeOnFileTaskRunner(type, &origins);
142     for (std::set<GURL>::iterator iter = origins.begin();
143         iter != origins.end(); ++iter) {
144       const GURL& current = *iter;
145       if (!BrowsingDataHelper::HasWebScheme(current))
146         continue;  // Non-websafe state is not considered browsing data.
147       int64 usage = quota_util->GetOriginUsageOnFileTaskRunner(
148           filesystem_context_.get(), current, type);
149       OriginInfoMap::iterator inserted =
150           file_system_info_map.insert(
151               std::make_pair(current, FileSystemInfo(current))).first;
152       inserted->second.usage_map[type] = usage;
153     }
154   }
155
156   for (OriginInfoMap::iterator iter = file_system_info_map.begin();
157        iter != file_system_info_map.end(); ++iter) {
158     file_system_info_.push_back(iter->second);
159   }
160
161   BrowserThread::PostTask(
162       BrowserThread::UI, FROM_HERE,
163       base::Bind(&BrowsingDataFileSystemHelperImpl::NotifyOnUIThread, this));
164 }
165
166 void BrowsingDataFileSystemHelperImpl::NotifyOnUIThread() {
167   DCHECK_CURRENTLY_ON(BrowserThread::UI);
168   DCHECK(is_fetching_);
169   completion_callback_.Run(file_system_info_);
170   completion_callback_.Reset();
171   is_fetching_ = false;
172 }
173
174 void BrowsingDataFileSystemHelperImpl::DeleteFileSystemOriginInFileThread(
175     const GURL& origin) {
176   DCHECK(file_task_runner()->RunsTasksOnCurrentThread());
177   filesystem_context_->DeleteDataForOriginOnFileTaskRunner(origin);
178 }
179
180 }  // namespace
181
182 BrowsingDataFileSystemHelper::FileSystemInfo::FileSystemInfo(
183     const GURL& origin) : origin(origin) {}
184
185 BrowsingDataFileSystemHelper::FileSystemInfo::~FileSystemInfo() {}
186
187 // static
188 BrowsingDataFileSystemHelper* BrowsingDataFileSystemHelper::Create(
189     storage::FileSystemContext* filesystem_context) {
190   return new BrowsingDataFileSystemHelperImpl(filesystem_context);
191 }
192
193 CannedBrowsingDataFileSystemHelper::CannedBrowsingDataFileSystemHelper(
194     Profile* profile) {
195 }
196
197 CannedBrowsingDataFileSystemHelper::~CannedBrowsingDataFileSystemHelper() {}
198
199 void CannedBrowsingDataFileSystemHelper::AddFileSystem(
200     const GURL& origin,
201     const storage::FileSystemType type,
202     const int64 size) {
203   DCHECK_CURRENTLY_ON(BrowserThread::UI);
204   // This canned implementation of AddFileSystem uses an O(n^2) algorithm; which
205   // is fine, as it isn't meant for use in a high-volume context. If it turns
206   // out that we want to start using this in a context with many, many origins,
207   // we should think about reworking the implementation.
208   bool duplicate_origin = false;
209   for (std::list<FileSystemInfo>::iterator
210            file_system = file_system_info_.begin();
211        file_system != file_system_info_.end();
212        ++file_system) {
213     if (file_system->origin == origin) {
214       file_system->usage_map[type] = size;
215       duplicate_origin = true;
216       break;
217     }
218   }
219   if (duplicate_origin)
220     return;
221
222   if (!BrowsingDataHelper::HasWebScheme(origin))
223     return;  // Non-websafe state is not considered browsing data.
224
225   FileSystemInfo info(origin);
226   info.usage_map[type] = size;
227   file_system_info_.push_back(info);
228 }
229
230 void CannedBrowsingDataFileSystemHelper::Reset() {
231   file_system_info_.clear();
232 }
233
234 bool CannedBrowsingDataFileSystemHelper::empty() const {
235   return file_system_info_.empty();
236 }
237
238 size_t CannedBrowsingDataFileSystemHelper::GetFileSystemCount() const {
239   DCHECK_CURRENTLY_ON(BrowserThread::UI);
240   return file_system_info_.size();
241 }
242
243 void CannedBrowsingDataFileSystemHelper::StartFetching(
244     const base::Callback<void(const std::list<FileSystemInfo>&)>& callback) {
245   DCHECK_CURRENTLY_ON(BrowserThread::UI);
246   DCHECK(!callback.is_null());
247
248   BrowserThread::PostTask(
249       BrowserThread::UI, FROM_HERE, base::Bind(callback, file_system_info_));
250 }