OLD | NEW |
| (Empty) |
1 // Copyright 2013 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/browser/fileapi/plugin_private_file_system_backend.h" | |
6 | |
7 #include <map> | |
8 | |
9 #include "base/stl_util.h" | |
10 #include "base/synchronization/lock.h" | |
11 #include "base/task_runner_util.h" | |
12 #include "net/base/net_util.h" | |
13 #include "webkit/browser/blob/file_stream_reader.h" | |
14 #include "webkit/browser/fileapi/async_file_util_adapter.h" | |
15 #include "webkit/browser/fileapi/file_stream_writer.h" | |
16 #include "webkit/browser/fileapi/file_system_context.h" | |
17 #include "webkit/browser/fileapi/file_system_operation.h" | |
18 #include "webkit/browser/fileapi/file_system_operation_context.h" | |
19 #include "webkit/browser/fileapi/file_system_options.h" | |
20 #include "webkit/browser/fileapi/isolated_context.h" | |
21 #include "webkit/browser/fileapi/obfuscated_file_util.h" | |
22 #include "webkit/browser/fileapi/quota/quota_reservation.h" | |
23 #include "webkit/common/fileapi/file_system_util.h" | |
24 | |
25 namespace storage { | |
26 | |
27 class PluginPrivateFileSystemBackend::FileSystemIDToPluginMap { | |
28 public: | |
29 explicit FileSystemIDToPluginMap(base::SequencedTaskRunner* task_runner) | |
30 : task_runner_(task_runner) {} | |
31 ~FileSystemIDToPluginMap() {} | |
32 | |
33 std::string GetPluginIDForURL(const FileSystemURL& url) { | |
34 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
35 Map::iterator found = map_.find(url.filesystem_id()); | |
36 if (url.type() != kFileSystemTypePluginPrivate || found == map_.end()) { | |
37 NOTREACHED() << "Unsupported url is given: " << url.DebugString(); | |
38 return std::string(); | |
39 } | |
40 return found->second; | |
41 } | |
42 | |
43 void RegisterFileSystem(const std::string& filesystem_id, | |
44 const std::string& plugin_id) { | |
45 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
46 DCHECK(!filesystem_id.empty()); | |
47 DCHECK(!ContainsKey(map_, filesystem_id)) << filesystem_id; | |
48 map_[filesystem_id] = plugin_id; | |
49 } | |
50 | |
51 void RemoveFileSystem(const std::string& filesystem_id) { | |
52 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
53 map_.erase(filesystem_id); | |
54 } | |
55 | |
56 private: | |
57 typedef std::map<std::string, std::string> Map; | |
58 scoped_refptr<base::SequencedTaskRunner> task_runner_; | |
59 Map map_; | |
60 }; | |
61 | |
62 namespace { | |
63 | |
64 const base::FilePath::CharType* kFileSystemDirectory = | |
65 SandboxFileSystemBackendDelegate::kFileSystemDirectory; | |
66 const base::FilePath::CharType* kPluginPrivateDirectory = | |
67 FILE_PATH_LITERAL("Plugins"); | |
68 | |
69 base::File::Error OpenFileSystemOnFileTaskRunner( | |
70 ObfuscatedFileUtil* file_util, | |
71 PluginPrivateFileSystemBackend::FileSystemIDToPluginMap* plugin_map, | |
72 const GURL& origin_url, | |
73 const std::string& filesystem_id, | |
74 const std::string& plugin_id, | |
75 OpenFileSystemMode mode) { | |
76 base::File::Error error = base::File::FILE_ERROR_FAILED; | |
77 const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT); | |
78 file_util->GetDirectoryForOriginAndType( | |
79 origin_url, plugin_id, create, &error); | |
80 if (error == base::File::FILE_OK) | |
81 plugin_map->RegisterFileSystem(filesystem_id, plugin_id); | |
82 return error; | |
83 } | |
84 | |
85 } // namespace | |
86 | |
87 PluginPrivateFileSystemBackend::PluginPrivateFileSystemBackend( | |
88 base::SequencedTaskRunner* file_task_runner, | |
89 const base::FilePath& profile_path, | |
90 storage::SpecialStoragePolicy* special_storage_policy, | |
91 const FileSystemOptions& file_system_options) | |
92 : file_task_runner_(file_task_runner), | |
93 file_system_options_(file_system_options), | |
94 base_path_(profile_path.Append(kFileSystemDirectory) | |
95 .Append(kPluginPrivateDirectory)), | |
96 plugin_map_(new FileSystemIDToPluginMap(file_task_runner)), | |
97 weak_factory_(this) { | |
98 file_util_.reset( | |
99 new AsyncFileUtilAdapter(new ObfuscatedFileUtil( | |
100 special_storage_policy, | |
101 base_path_, file_system_options.env_override(), | |
102 file_task_runner, | |
103 base::Bind(&FileSystemIDToPluginMap::GetPluginIDForURL, | |
104 base::Owned(plugin_map_)), | |
105 std::set<std::string>(), | |
106 NULL))); | |
107 } | |
108 | |
109 PluginPrivateFileSystemBackend::~PluginPrivateFileSystemBackend() { | |
110 if (!file_task_runner_->RunsTasksOnCurrentThread()) { | |
111 AsyncFileUtil* file_util = file_util_.release(); | |
112 if (!file_task_runner_->DeleteSoon(FROM_HERE, file_util)) | |
113 delete file_util; | |
114 } | |
115 } | |
116 | |
117 void PluginPrivateFileSystemBackend::OpenPrivateFileSystem( | |
118 const GURL& origin_url, | |
119 FileSystemType type, | |
120 const std::string& filesystem_id, | |
121 const std::string& plugin_id, | |
122 OpenFileSystemMode mode, | |
123 const StatusCallback& callback) { | |
124 if (!CanHandleType(type) || file_system_options_.is_incognito()) { | |
125 base::MessageLoopProxy::current()->PostTask( | |
126 FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_SECURITY)); | |
127 return; | |
128 } | |
129 | |
130 PostTaskAndReplyWithResult( | |
131 file_task_runner_.get(), | |
132 FROM_HERE, | |
133 base::Bind(&OpenFileSystemOnFileTaskRunner, | |
134 obfuscated_file_util(), plugin_map_, | |
135 origin_url, filesystem_id, plugin_id, mode), | |
136 callback); | |
137 } | |
138 | |
139 bool PluginPrivateFileSystemBackend::CanHandleType(FileSystemType type) const { | |
140 return type == kFileSystemTypePluginPrivate; | |
141 } | |
142 | |
143 void PluginPrivateFileSystemBackend::Initialize(FileSystemContext* context) { | |
144 } | |
145 | |
146 void PluginPrivateFileSystemBackend::ResolveURL( | |
147 const FileSystemURL& url, | |
148 OpenFileSystemMode mode, | |
149 const OpenFileSystemCallback& callback) { | |
150 // We never allow opening a new plugin-private filesystem via usual | |
151 // ResolveURL. | |
152 base::MessageLoopProxy::current()->PostTask( | |
153 FROM_HERE, | |
154 base::Bind(callback, GURL(), std::string(), | |
155 base::File::FILE_ERROR_SECURITY)); | |
156 } | |
157 | |
158 AsyncFileUtil* | |
159 PluginPrivateFileSystemBackend::GetAsyncFileUtil(FileSystemType type) { | |
160 return file_util_.get(); | |
161 } | |
162 | |
163 WatcherManager* PluginPrivateFileSystemBackend::GetWatcherManager( | |
164 FileSystemType type) { | |
165 return NULL; | |
166 } | |
167 | |
168 CopyOrMoveFileValidatorFactory* | |
169 PluginPrivateFileSystemBackend::GetCopyOrMoveFileValidatorFactory( | |
170 FileSystemType type, | |
171 base::File::Error* error_code) { | |
172 DCHECK(error_code); | |
173 *error_code = base::File::FILE_OK; | |
174 return NULL; | |
175 } | |
176 | |
177 FileSystemOperation* PluginPrivateFileSystemBackend::CreateFileSystemOperation( | |
178 const FileSystemURL& url, | |
179 FileSystemContext* context, | |
180 base::File::Error* error_code) const { | |
181 scoped_ptr<FileSystemOperationContext> operation_context( | |
182 new FileSystemOperationContext(context)); | |
183 return FileSystemOperation::Create(url, context, operation_context.Pass()); | |
184 } | |
185 | |
186 bool PluginPrivateFileSystemBackend::SupportsStreaming( | |
187 const storage::FileSystemURL& url) const { | |
188 return false; | |
189 } | |
190 | |
191 bool PluginPrivateFileSystemBackend::HasInplaceCopyImplementation( | |
192 storage::FileSystemType type) const { | |
193 return false; | |
194 } | |
195 | |
196 scoped_ptr<storage::FileStreamReader> | |
197 PluginPrivateFileSystemBackend::CreateFileStreamReader( | |
198 const FileSystemURL& url, | |
199 int64 offset, | |
200 const base::Time& expected_modification_time, | |
201 FileSystemContext* context) const { | |
202 return scoped_ptr<storage::FileStreamReader>(); | |
203 } | |
204 | |
205 scoped_ptr<FileStreamWriter> | |
206 PluginPrivateFileSystemBackend::CreateFileStreamWriter( | |
207 const FileSystemURL& url, | |
208 int64 offset, | |
209 FileSystemContext* context) const { | |
210 return scoped_ptr<FileStreamWriter>(); | |
211 } | |
212 | |
213 FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() { | |
214 return this; | |
215 } | |
216 | |
217 base::File::Error | |
218 PluginPrivateFileSystemBackend::DeleteOriginDataOnFileTaskRunner( | |
219 FileSystemContext* context, | |
220 storage::QuotaManagerProxy* proxy, | |
221 const GURL& origin_url, | |
222 FileSystemType type) { | |
223 if (!CanHandleType(type)) | |
224 return base::File::FILE_ERROR_SECURITY; | |
225 bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType( | |
226 origin_url, std::string()); | |
227 if (result) | |
228 return base::File::FILE_OK; | |
229 return base::File::FILE_ERROR_FAILED; | |
230 } | |
231 | |
232 void PluginPrivateFileSystemBackend::GetOriginsForTypeOnFileTaskRunner( | |
233 FileSystemType type, | |
234 std::set<GURL>* origins) { | |
235 if (!CanHandleType(type)) | |
236 return; | |
237 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( | |
238 obfuscated_file_util()->CreateOriginEnumerator()); | |
239 GURL origin; | |
240 while (!(origin = enumerator->Next()).is_empty()) | |
241 origins->insert(origin); | |
242 } | |
243 | |
244 void PluginPrivateFileSystemBackend::GetOriginsForHostOnFileTaskRunner( | |
245 FileSystemType type, | |
246 const std::string& host, | |
247 std::set<GURL>* origins) { | |
248 if (!CanHandleType(type)) | |
249 return; | |
250 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( | |
251 obfuscated_file_util()->CreateOriginEnumerator()); | |
252 GURL origin; | |
253 while (!(origin = enumerator->Next()).is_empty()) { | |
254 if (host == net::GetHostOrSpecFromURL(origin)) | |
255 origins->insert(origin); | |
256 } | |
257 } | |
258 | |
259 int64 PluginPrivateFileSystemBackend::GetOriginUsageOnFileTaskRunner( | |
260 FileSystemContext* context, | |
261 const GURL& origin_url, | |
262 FileSystemType type) { | |
263 // We don't track usage on this filesystem. | |
264 return 0; | |
265 } | |
266 | |
267 scoped_refptr<QuotaReservation> | |
268 PluginPrivateFileSystemBackend::CreateQuotaReservationOnFileTaskRunner( | |
269 const GURL& origin_url, | |
270 FileSystemType type) { | |
271 // We don't track usage on this filesystem. | |
272 NOTREACHED(); | |
273 return scoped_refptr<QuotaReservation>(); | |
274 } | |
275 | |
276 void PluginPrivateFileSystemBackend::AddFileUpdateObserver( | |
277 FileSystemType type, | |
278 FileUpdateObserver* observer, | |
279 base::SequencedTaskRunner* task_runner) {} | |
280 | |
281 void PluginPrivateFileSystemBackend::AddFileChangeObserver( | |
282 FileSystemType type, | |
283 FileChangeObserver* observer, | |
284 base::SequencedTaskRunner* task_runner) {} | |
285 | |
286 void PluginPrivateFileSystemBackend::AddFileAccessObserver( | |
287 FileSystemType type, | |
288 FileAccessObserver* observer, | |
289 base::SequencedTaskRunner* task_runner) {} | |
290 | |
291 const UpdateObserverList* PluginPrivateFileSystemBackend::GetUpdateObservers( | |
292 FileSystemType type) const { | |
293 return NULL; | |
294 } | |
295 | |
296 const ChangeObserverList* PluginPrivateFileSystemBackend::GetChangeObservers( | |
297 FileSystemType type) const { | |
298 return NULL; | |
299 } | |
300 | |
301 const AccessObserverList* PluginPrivateFileSystemBackend::GetAccessObservers( | |
302 FileSystemType type) const { | |
303 return NULL; | |
304 } | |
305 | |
306 ObfuscatedFileUtil* PluginPrivateFileSystemBackend::obfuscated_file_util() { | |
307 return static_cast<ObfuscatedFileUtil*>( | |
308 static_cast<AsyncFileUtilAdapter*>(file_util_.get())->sync_file_util()); | |
309 } | |
310 | |
311 } // namespace storage | |
OLD | NEW |