Elim cr-checkbox
[chromium-blink-merge.git] / chrome / browser / chromeos / file_system_provider / fake_provided_file_system.cc
blob90e3667e605b3e547f21129565bc6ec2544fda00
1 // Copyright 2014 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/chromeos/file_system_provider/fake_provided_file_system.h"
7 #include "base/thread_task_runner_handle.h"
8 #include "net/base/io_buffer.h"
10 namespace chromeos {
11 namespace file_system_provider {
12 namespace {
14 const char kFakeFileName[] = "hello.txt";
15 const char kFakeFileText[] =
16 "This is a testing file. Lorem ipsum dolor sit amet est.";
17 const size_t kFakeFileSize = sizeof(kFakeFileText) - 1u;
18 const char kFakeFileModificationTime[] = "Fri Apr 25 01:47:53 UTC 2014";
19 const char kFakeFileMimeType[] = "text/plain";
21 } // namespace
23 const base::FilePath::CharType kFakeFilePath[] =
24 FILE_PATH_LITERAL("/hello.txt");
26 FakeEntry::FakeEntry() {
29 FakeEntry::FakeEntry(scoped_ptr<EntryMetadata> metadata,
30 const std::string& contents)
31 : metadata(metadata.Pass()), contents(contents) {
34 FakeEntry::~FakeEntry() {
37 FakeProvidedFileSystem::FakeProvidedFileSystem(
38 const ProvidedFileSystemInfo& file_system_info)
39 : file_system_info_(file_system_info),
40 last_file_handle_(0),
41 weak_ptr_factory_(this) {
42 AddEntry(base::FilePath(FILE_PATH_LITERAL("/")), true, "", 0, base::Time(),
43 "", "");
45 base::Time modification_time;
46 DCHECK(base::Time::FromString(kFakeFileModificationTime, &modification_time));
47 AddEntry(base::FilePath(kFakeFilePath), false, kFakeFileName, kFakeFileSize,
48 modification_time, kFakeFileMimeType, kFakeFileText);
51 FakeProvidedFileSystem::~FakeProvidedFileSystem() {}
53 void FakeProvidedFileSystem::AddEntry(const base::FilePath& entry_path,
54 bool is_directory,
55 const std::string& name,
56 int64 size,
57 base::Time modification_time,
58 std::string mime_type,
59 std::string contents) {
60 DCHECK(entries_.find(entry_path) == entries_.end());
61 scoped_ptr<EntryMetadata> metadata(new EntryMetadata);
63 metadata->is_directory = is_directory;
64 metadata->name = name;
65 metadata->size = size;
66 metadata->modification_time = modification_time;
67 metadata->mime_type = mime_type;
69 entries_[entry_path] =
70 make_linked_ptr(new FakeEntry(metadata.Pass(), contents));
73 const FakeEntry* FakeProvidedFileSystem::GetEntry(
74 const base::FilePath& entry_path) const {
75 const Entries::const_iterator entry_it = entries_.find(entry_path);
76 if (entry_it == entries_.end())
77 return NULL;
79 return entry_it->second.get();
82 AbortCallback FakeProvidedFileSystem::RequestUnmount(
83 const storage::AsyncFileUtil::StatusCallback& callback) {
84 return PostAbortableTask(base::Bind(callback, base::File::FILE_OK));
87 AbortCallback FakeProvidedFileSystem::GetMetadata(
88 const base::FilePath& entry_path,
89 ProvidedFileSystemInterface::MetadataFieldMask fields,
90 const ProvidedFileSystemInterface::GetMetadataCallback& callback) {
91 const Entries::const_iterator entry_it = entries_.find(entry_path);
93 if (entry_it == entries_.end()) {
94 return PostAbortableTask(
95 base::Bind(callback,
96 base::Passed(make_scoped_ptr<EntryMetadata>(NULL)),
97 base::File::FILE_ERROR_NOT_FOUND));
100 scoped_ptr<EntryMetadata> metadata(new EntryMetadata);
101 metadata->is_directory = entry_it->second->metadata->is_directory;
102 metadata->name = entry_it->second->metadata->name;
103 metadata->size = entry_it->second->metadata->size;
104 metadata->modification_time = entry_it->second->metadata->modification_time;
105 metadata->mime_type = entry_it->second->metadata->mime_type;
106 metadata->thumbnail = entry_it->second->metadata->thumbnail;
108 return PostAbortableTask(
109 base::Bind(callback, base::Passed(&metadata), base::File::FILE_OK));
112 AbortCallback FakeProvidedFileSystem::GetActions(
113 const base::FilePath& entry_path,
114 const ProvidedFileSystemInterface::GetActionsCallback& callback) {
115 // TODO(mtomasz): Implement it once needed.
116 const std::vector<Action> actions;
117 return PostAbortableTask(base::Bind(callback, actions, base::File::FILE_OK));
120 AbortCallback FakeProvidedFileSystem::ExecuteAction(
121 const base::FilePath& entry_path,
122 const std::string& action_id,
123 const storage::AsyncFileUtil::StatusCallback& callback) {
124 // TODO(mtomasz): Implement it once needed.
125 return PostAbortableTask(base::Bind(callback, base::File::FILE_OK));
128 AbortCallback FakeProvidedFileSystem::ReadDirectory(
129 const base::FilePath& directory_path,
130 const storage::AsyncFileUtil::ReadDirectoryCallback& callback) {
131 storage::AsyncFileUtil::EntryList entry_list;
133 for (Entries::const_iterator it = entries_.begin(); it != entries_.end();
134 ++it) {
135 const base::FilePath file_path = it->first;
136 if (file_path == directory_path || directory_path.IsParent(file_path)) {
137 const EntryMetadata* const metadata = it->second->metadata.get();
138 entry_list.push_back(storage::DirectoryEntry(
139 metadata->name,
140 metadata->is_directory ? storage::DirectoryEntry::DIRECTORY
141 : storage::DirectoryEntry::FILE,
142 metadata->size,
143 metadata->modification_time));
147 return PostAbortableTask(base::Bind(
148 callback, base::File::FILE_OK, entry_list, false /* has_more */));
151 AbortCallback FakeProvidedFileSystem::OpenFile(
152 const base::FilePath& entry_path,
153 OpenFileMode mode,
154 const OpenFileCallback& callback) {
155 const Entries::const_iterator entry_it = entries_.find(entry_path);
157 if (entry_it == entries_.end()) {
158 return PostAbortableTask(base::Bind(
159 callback, 0 /* file_handle */, base::File::FILE_ERROR_NOT_FOUND));
162 const int file_handle = ++last_file_handle_;
163 opened_files_[file_handle] = OpenedFile(entry_path, mode);
164 return PostAbortableTask(
165 base::Bind(callback, file_handle, base::File::FILE_OK));
168 AbortCallback FakeProvidedFileSystem::CloseFile(
169 int file_handle,
170 const storage::AsyncFileUtil::StatusCallback& callback) {
171 const auto opened_file_it = opened_files_.find(file_handle);
173 if (opened_file_it == opened_files_.end()) {
174 return PostAbortableTask(
175 base::Bind(callback, base::File::FILE_ERROR_NOT_FOUND));
178 opened_files_.erase(opened_file_it);
179 return PostAbortableTask(base::Bind(callback, base::File::FILE_OK));
182 AbortCallback FakeProvidedFileSystem::ReadFile(
183 int file_handle,
184 net::IOBuffer* buffer,
185 int64 offset,
186 int length,
187 const ProvidedFileSystemInterface::ReadChunkReceivedCallback& callback) {
188 const auto opened_file_it = opened_files_.find(file_handle);
190 if (opened_file_it == opened_files_.end() ||
191 opened_file_it->second.file_path.AsUTF8Unsafe() != kFakeFilePath) {
192 return PostAbortableTask(
193 base::Bind(callback,
194 0 /* chunk_length */,
195 false /* has_more */,
196 base::File::FILE_ERROR_INVALID_OPERATION));
199 const Entries::const_iterator entry_it =
200 entries_.find(opened_file_it->second.file_path);
201 if (entry_it == entries_.end()) {
202 return PostAbortableTask(
203 base::Bind(callback,
204 0 /* chunk_length */,
205 false /* has_more */,
206 base::File::FILE_ERROR_INVALID_OPERATION));
209 // Send the response byte by byte.
210 int64 current_offset = offset;
211 int current_length = length;
213 // Reading behind EOF is fine, it will just return 0 bytes.
214 if (current_offset >= entry_it->second->metadata->size || !current_length) {
215 return PostAbortableTask(base::Bind(callback,
216 0 /* chunk_length */,
217 false /* has_more */,
218 base::File::FILE_OK));
221 const FakeEntry* const entry = entry_it->second.get();
222 std::vector<int> task_ids;
223 while (current_offset < entry->metadata->size && current_length) {
224 buffer->data()[current_offset - offset] = entry->contents[current_offset];
225 const bool has_more =
226 (current_offset + 1 < entry->metadata->size) && (current_length - 1);
227 const int task_id =
228 tracker_.PostTask(base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
229 base::Bind(callback, 1 /* chunk_length */, has_more,
230 base::File::FILE_OK));
231 task_ids.push_back(task_id);
232 current_offset++;
233 current_length--;
236 return base::Bind(&FakeProvidedFileSystem::AbortMany,
237 weak_ptr_factory_.GetWeakPtr(),
238 task_ids);
241 AbortCallback FakeProvidedFileSystem::CreateDirectory(
242 const base::FilePath& directory_path,
243 bool recursive,
244 const storage::AsyncFileUtil::StatusCallback& callback) {
245 // TODO(mtomasz): Implement it once needed.
246 return PostAbortableTask(base::Bind(callback, base::File::FILE_OK));
249 AbortCallback FakeProvidedFileSystem::DeleteEntry(
250 const base::FilePath& entry_path,
251 bool recursive,
252 const storage::AsyncFileUtil::StatusCallback& callback) {
253 // TODO(mtomasz): Implement it once needed.
254 return PostAbortableTask(base::Bind(callback, base::File::FILE_OK));
257 AbortCallback FakeProvidedFileSystem::CreateFile(
258 const base::FilePath& file_path,
259 const storage::AsyncFileUtil::StatusCallback& callback) {
260 const base::File::Error result = file_path.AsUTF8Unsafe() != kFakeFilePath
261 ? base::File::FILE_ERROR_EXISTS
262 : base::File::FILE_OK;
264 return PostAbortableTask(base::Bind(callback, result));
267 AbortCallback FakeProvidedFileSystem::CopyEntry(
268 const base::FilePath& source_path,
269 const base::FilePath& target_path,
270 const storage::AsyncFileUtil::StatusCallback& callback) {
271 // TODO(mtomasz): Implement it once needed.
272 return PostAbortableTask(base::Bind(callback, base::File::FILE_OK));
275 AbortCallback FakeProvidedFileSystem::MoveEntry(
276 const base::FilePath& source_path,
277 const base::FilePath& target_path,
278 const storage::AsyncFileUtil::StatusCallback& callback) {
279 // TODO(mtomasz): Implement it once needed.
280 return PostAbortableTask(base::Bind(callback, base::File::FILE_OK));
283 AbortCallback FakeProvidedFileSystem::Truncate(
284 const base::FilePath& file_path,
285 int64 length,
286 const storage::AsyncFileUtil::StatusCallback& callback) {
287 // TODO(mtomasz): Implement it once needed.
288 return PostAbortableTask(base::Bind(callback, base::File::FILE_OK));
291 AbortCallback FakeProvidedFileSystem::WriteFile(
292 int file_handle,
293 net::IOBuffer* buffer,
294 int64 offset,
295 int length,
296 const storage::AsyncFileUtil::StatusCallback& callback) {
297 const auto opened_file_it = opened_files_.find(file_handle);
299 if (opened_file_it == opened_files_.end() ||
300 opened_file_it->second.file_path.AsUTF8Unsafe() != kFakeFilePath) {
301 return PostAbortableTask(
302 base::Bind(callback, base::File::FILE_ERROR_INVALID_OPERATION));
305 const Entries::iterator entry_it =
306 entries_.find(opened_file_it->second.file_path);
307 if (entry_it == entries_.end()) {
308 return PostAbortableTask(
309 base::Bind(callback, base::File::FILE_ERROR_INVALID_OPERATION));
312 FakeEntry* const entry = entry_it->second.get();
313 if (offset > entry->metadata->size) {
314 return PostAbortableTask(
315 base::Bind(callback, base::File::FILE_ERROR_INVALID_OPERATION));
318 // Allocate the string size in advance.
319 if (offset + length > entry->metadata->size) {
320 entry->metadata->size = offset + length;
321 entry->contents.resize(entry->metadata->size);
324 entry->contents.replace(offset, length, buffer->data(), length);
326 return PostAbortableTask(base::Bind(callback, base::File::FILE_OK));
329 AbortCallback FakeProvidedFileSystem::AddWatcher(
330 const GURL& origin,
331 const base::FilePath& entry_watcher,
332 bool recursive,
333 bool persistent,
334 const storage::AsyncFileUtil::StatusCallback& callback,
335 const storage::WatcherManager::NotificationCallback&
336 notification_callback) {
337 // TODO(mtomasz): Implement it once needed.
338 return PostAbortableTask(base::Bind(callback, base::File::FILE_OK));
341 void FakeProvidedFileSystem::RemoveWatcher(
342 const GURL& origin,
343 const base::FilePath& entry_path,
344 bool recursive,
345 const storage::AsyncFileUtil::StatusCallback& callback) {
346 // TODO(mtomasz): Implement it once needed.
347 callback.Run(base::File::FILE_OK);
350 const ProvidedFileSystemInfo& FakeProvidedFileSystem::GetFileSystemInfo()
351 const {
352 return file_system_info_;
355 RequestManager* FakeProvidedFileSystem::GetRequestManager() {
356 NOTREACHED();
357 return NULL;
360 Watchers* FakeProvidedFileSystem::GetWatchers() {
361 return &watchers_;
364 const OpenedFiles& FakeProvidedFileSystem::GetOpenedFiles() const {
365 return opened_files_;
368 void FakeProvidedFileSystem::AddObserver(ProvidedFileSystemObserver* observer) {
369 DCHECK(observer);
370 observers_.AddObserver(observer);
373 void FakeProvidedFileSystem::RemoveObserver(
374 ProvidedFileSystemObserver* observer) {
375 DCHECK(observer);
376 observers_.RemoveObserver(observer);
379 void FakeProvidedFileSystem::Notify(
380 const base::FilePath& entry_path,
381 bool recursive,
382 storage::WatcherManager::ChangeType change_type,
383 scoped_ptr<ProvidedFileSystemObserver::Changes> changes,
384 const std::string& tag,
385 const storage::AsyncFileUtil::StatusCallback& callback) {
386 NOTREACHED();
387 callback.Run(base::File::FILE_ERROR_SECURITY);
390 void FakeProvidedFileSystem::Configure(
391 const storage::AsyncFileUtil::StatusCallback& callback) {
392 NOTREACHED();
393 callback.Run(base::File::FILE_ERROR_SECURITY);
396 ProvidedFileSystemInterface* FakeProvidedFileSystem::Create(
397 Profile* profile,
398 const ProvidedFileSystemInfo& file_system_info) {
399 return new FakeProvidedFileSystem(file_system_info);
402 base::WeakPtr<ProvidedFileSystemInterface>
403 FakeProvidedFileSystem::GetWeakPtr() {
404 return weak_ptr_factory_.GetWeakPtr();
407 AbortCallback FakeProvidedFileSystem::PostAbortableTask(
408 const base::Closure& callback) {
409 const int task_id = tracker_.PostTask(
410 base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE, callback);
411 return base::Bind(
412 &FakeProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), task_id);
415 void FakeProvidedFileSystem::Abort(int task_id) {
416 tracker_.TryCancel(task_id);
419 void FakeProvidedFileSystem::AbortMany(const std::vector<int>& task_ids) {
420 for (size_t i = 0; i < task_ids.size(); ++i) {
421 tracker_.TryCancel(task_ids[i]);
425 } // namespace file_system_provider
426 } // namespace chromeos