Extract code handling PrinterProviderAPI from PrintPreviewHandler
[chromium-blink-merge.git] / chrome / browser / browsing_data / browsing_data_file_system_helper.cc
blobee896474343ec0cb86c15a6da30a23c8d4b9b2f0
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.
5 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
7 #include <set>
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"
21 using content::BrowserThread;
23 namespace storage {
24 class FileSystemContext;
27 namespace {
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 void StartFetching(
38 const base::Callback<void(const std::list<FileSystemInfo>&)>& callback)
39 override;
40 void DeleteFileSystemOrigin(const GURL& origin) override;
42 private:
43 ~BrowsingDataFileSystemHelperImpl() override;
45 // Enumerates all filesystem files, storing the resulting list into
46 // file_system_file_ for later use. This must be called on the file
47 // task runner.
48 void FetchFileSystemInfoInFileThread();
50 // Triggers the success callback as the end of a StartFetching workflow. This
51 // must be called on the UI thread.
52 void NotifyOnUIThread();
54 // Deletes all file systems associated with |origin|. This must be called on
55 // the file task runner.
56 void DeleteFileSystemOriginInFileThread(const GURL& origin);
58 // Returns the file task runner for the |filesystem_context_|.
59 base::SequencedTaskRunner* file_task_runner() {
60 return filesystem_context_->default_file_task_runner();
63 // Keep a reference to the FileSystemContext object for the current profile
64 // for use on the file task runner.
65 scoped_refptr<storage::FileSystemContext> filesystem_context_;
67 // Holds the current list of file systems returned to the client after
68 // StartFetching is called. Access to |file_system_info_| is triggered
69 // indirectly via the UI thread and guarded by |is_fetching_|. This means
70 // |file_system_info_| is only accessed while |is_fetching_| is true. The
71 // flag |is_fetching_| is only accessed on the UI thread. In the context of
72 // this class |file_system_info_| only mutates on the file task runner.
73 std::list<FileSystemInfo> file_system_info_;
75 // Holds the callback passed in at the beginning of the StartFetching workflow
76 // so that it can be triggered via NotifyOnUIThread. This only mutates on the
77 // UI thread.
78 base::Callback<void(const std::list<FileSystemInfo>&)> completion_callback_;
80 // Indicates whether or not we're currently fetching information: set to true
81 // when StartFetching is called on the UI thread, and reset to false when
82 // NotifyOnUIThread triggers the success callback.
83 // This property only mutates on the UI thread.
84 bool is_fetching_;
86 DISALLOW_COPY_AND_ASSIGN(BrowsingDataFileSystemHelperImpl);
89 BrowsingDataFileSystemHelperImpl::BrowsingDataFileSystemHelperImpl(
90 storage::FileSystemContext* filesystem_context)
91 : filesystem_context_(filesystem_context), is_fetching_(false) {
92 DCHECK(filesystem_context_.get());
95 BrowsingDataFileSystemHelperImpl::~BrowsingDataFileSystemHelperImpl() {
98 void BrowsingDataFileSystemHelperImpl::StartFetching(
99 const base::Callback<void(const std::list<FileSystemInfo>&)>& callback) {
100 DCHECK_CURRENTLY_ON(BrowserThread::UI);
101 DCHECK(!is_fetching_);
102 DCHECK(!callback.is_null());
103 is_fetching_ = true;
104 completion_callback_ = callback;
105 file_task_runner()->PostTask(
106 FROM_HERE,
107 base::Bind(
108 &BrowsingDataFileSystemHelperImpl::FetchFileSystemInfoInFileThread,
109 this));
112 void BrowsingDataFileSystemHelperImpl::DeleteFileSystemOrigin(
113 const GURL& origin) {
114 DCHECK_CURRENTLY_ON(BrowserThread::UI);
115 file_task_runner()->PostTask(
116 FROM_HERE,
117 base::Bind(
118 &BrowsingDataFileSystemHelperImpl::DeleteFileSystemOriginInFileThread,
119 this, origin));
122 void BrowsingDataFileSystemHelperImpl::FetchFileSystemInfoInFileThread() {
123 DCHECK(file_task_runner()->RunsTasksOnCurrentThread());
125 // We check usage for these filesystem types.
126 const storage::FileSystemType types[] = {
127 storage::kFileSystemTypeTemporary,
128 storage::kFileSystemTypePersistent,
129 #if defined(ENABLE_EXTENSIONS)
130 storage::kFileSystemTypeSyncable,
131 #endif
134 typedef std::map<GURL, FileSystemInfo> OriginInfoMap;
135 OriginInfoMap file_system_info_map;
136 for (size_t i = 0; i < arraysize(types); ++i) {
137 storage::FileSystemType type = types[i];
138 storage::FileSystemQuotaUtil* quota_util =
139 filesystem_context_->GetQuotaUtil(type);
140 DCHECK(quota_util);
141 std::set<GURL> origins;
142 quota_util->GetOriginsForTypeOnFileTaskRunner(type, &origins);
143 for (std::set<GURL>::iterator iter = origins.begin();
144 iter != origins.end(); ++iter) {
145 const GURL& current = *iter;
146 if (!BrowsingDataHelper::HasWebScheme(current))
147 continue; // Non-websafe state is not considered browsing data.
148 int64 usage = quota_util->GetOriginUsageOnFileTaskRunner(
149 filesystem_context_.get(), current, type);
150 OriginInfoMap::iterator inserted =
151 file_system_info_map.insert(
152 std::make_pair(current, FileSystemInfo(current))).first;
153 inserted->second.usage_map[type] = usage;
157 for (OriginInfoMap::iterator iter = file_system_info_map.begin();
158 iter != file_system_info_map.end(); ++iter) {
159 file_system_info_.push_back(iter->second);
162 BrowserThread::PostTask(
163 BrowserThread::UI, FROM_HERE,
164 base::Bind(&BrowsingDataFileSystemHelperImpl::NotifyOnUIThread, this));
167 void BrowsingDataFileSystemHelperImpl::NotifyOnUIThread() {
168 DCHECK_CURRENTLY_ON(BrowserThread::UI);
169 DCHECK(is_fetching_);
170 completion_callback_.Run(file_system_info_);
171 completion_callback_.Reset();
172 is_fetching_ = false;
175 void BrowsingDataFileSystemHelperImpl::DeleteFileSystemOriginInFileThread(
176 const GURL& origin) {
177 DCHECK(file_task_runner()->RunsTasksOnCurrentThread());
178 filesystem_context_->DeleteDataForOriginOnFileTaskRunner(origin);
181 } // namespace
183 BrowsingDataFileSystemHelper::FileSystemInfo::FileSystemInfo(
184 const GURL& origin) : origin(origin) {}
186 BrowsingDataFileSystemHelper::FileSystemInfo::~FileSystemInfo() {}
188 // static
189 BrowsingDataFileSystemHelper* BrowsingDataFileSystemHelper::Create(
190 storage::FileSystemContext* filesystem_context) {
191 return new BrowsingDataFileSystemHelperImpl(filesystem_context);
194 CannedBrowsingDataFileSystemHelper::CannedBrowsingDataFileSystemHelper(
195 Profile* profile) {
198 CannedBrowsingDataFileSystemHelper::~CannedBrowsingDataFileSystemHelper() {}
200 void CannedBrowsingDataFileSystemHelper::AddFileSystem(
201 const GURL& origin,
202 const storage::FileSystemType type,
203 const int64 size) {
204 DCHECK_CURRENTLY_ON(BrowserThread::UI);
205 // This canned implementation of AddFileSystem uses an O(n^2) algorithm; which
206 // is fine, as it isn't meant for use in a high-volume context. If it turns
207 // out that we want to start using this in a context with many, many origins,
208 // we should think about reworking the implementation.
209 bool duplicate_origin = false;
210 for (std::list<FileSystemInfo>::iterator
211 file_system = file_system_info_.begin();
212 file_system != file_system_info_.end();
213 ++file_system) {
214 if (file_system->origin == origin) {
215 file_system->usage_map[type] = size;
216 duplicate_origin = true;
217 break;
220 if (duplicate_origin)
221 return;
223 if (!BrowsingDataHelper::HasWebScheme(origin))
224 return; // Non-websafe state is not considered browsing data.
226 FileSystemInfo info(origin);
227 info.usage_map[type] = size;
228 file_system_info_.push_back(info);
231 void CannedBrowsingDataFileSystemHelper::Reset() {
232 file_system_info_.clear();
235 bool CannedBrowsingDataFileSystemHelper::empty() const {
236 return file_system_info_.empty();
239 size_t CannedBrowsingDataFileSystemHelper::GetFileSystemCount() const {
240 DCHECK_CURRENTLY_ON(BrowserThread::UI);
241 return file_system_info_.size();
244 void CannedBrowsingDataFileSystemHelper::StartFetching(
245 const base::Callback<void(const std::list<FileSystemInfo>&)>& callback) {
246 DCHECK_CURRENTLY_ON(BrowserThread::UI);
247 DCHECK(!callback.is_null());
249 BrowserThread::PostTask(
250 BrowserThread::UI, FROM_HERE, base::Bind(callback, file_system_info_));