| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system
.h" | 5 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system
.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/files/file.h" | 9 #include "base/files/file.h" |
| 10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
| 11 #include "net/base/io_buffer.h" | 11 #include "net/base/io_buffer.h" |
| 12 | 12 |
| 13 namespace chromeos { | 13 namespace chromeos { |
| 14 namespace file_system_provider { | 14 namespace file_system_provider { |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 // Adds a fake entry to the entry list. | |
| 18 void AddDirectoryEntry(fileapi::AsyncFileUtil::EntryList* entry_list, | |
| 19 const std::string& name, | |
| 20 fileapi::DirectoryEntry::DirectoryEntryType type, | |
| 21 int64 size, | |
| 22 std::string last_modified_time_string) { | |
| 23 base::Time last_modified_time; | |
| 24 const bool result = base::Time::FromString(last_modified_time_string.c_str(), | |
| 25 &last_modified_time); | |
| 26 DCHECK(result); | |
| 27 entry_list->push_back( | |
| 28 fileapi::DirectoryEntry(name, type, size, last_modified_time)); | |
| 29 } | |
| 30 | |
| 31 } // namespace | |
| 32 | |
| 33 const char kFakeFileName[] = "hello.txt"; | 17 const char kFakeFileName[] = "hello.txt"; |
| 34 const char kFakeFilePath[] = "/hello.txt"; | |
| 35 const char kFakeFileText[] = | 18 const char kFakeFileText[] = |
| 36 "This is a testing file. Lorem ipsum dolor sit amet est."; | 19 "This is a testing file. Lorem ipsum dolor sit amet est."; |
| 37 const size_t kFakeFileSize = sizeof(kFakeFileText) - 1u; | 20 const size_t kFakeFileSize = sizeof(kFakeFileText) - 1u; |
| 38 const char kFakeFileModificationTime[] = "Fri Apr 25 01:47:53 UTC 2014"; | 21 const char kFakeFileModificationTime[] = "Fri Apr 25 01:47:53 UTC 2014"; |
| 22 const char kFakeFileMimeType[] = "text/plain"; |
| 23 |
| 24 } // namespace |
| 25 |
| 26 const char kFakeFilePath[] = "/hello.txt"; |
| 39 | 27 |
| 40 FakeProvidedFileSystem::FakeProvidedFileSystem( | 28 FakeProvidedFileSystem::FakeProvidedFileSystem( |
| 41 const ProvidedFileSystemInfo& file_system_info) | 29 const ProvidedFileSystemInfo& file_system_info) |
| 42 : file_system_info_(file_system_info), | 30 : file_system_info_(file_system_info), |
| 43 last_file_handle_(0), | 31 last_file_handle_(0), |
| 44 weak_ptr_factory_(this) { | 32 weak_ptr_factory_(this) { |
| 33 AddEntry( |
| 34 base::FilePath::FromUTF8Unsafe("/"), true, "", 0, base::Time(), "", ""); |
| 35 |
| 36 base::Time modification_time; |
| 37 DCHECK(base::Time::FromString(kFakeFileModificationTime, &modification_time)); |
| 38 AddEntry(base::FilePath::FromUTF8Unsafe(kFakeFilePath), |
| 39 false, |
| 40 kFakeFileName, |
| 41 kFakeFileSize, |
| 42 modification_time, |
| 43 kFakeFileMimeType, |
| 44 kFakeFileText); |
| 45 } | 45 } |
| 46 | 46 |
| 47 FakeProvidedFileSystem::~FakeProvidedFileSystem() {} | 47 FakeProvidedFileSystem::~FakeProvidedFileSystem() {} |
| 48 | 48 |
| 49 void FakeProvidedFileSystem::AddEntry(const base::FilePath& entry_path, |
| 50 bool is_directory, |
| 51 const std::string& name, |
| 52 int64 size, |
| 53 base::Time modification_time, |
| 54 std::string mime_type, |
| 55 std::string contents) { |
| 56 DCHECK(entries_.find(entry_path) == entries_.end()); |
| 57 EntryMetadata metadata; |
| 58 |
| 59 metadata.is_directory = is_directory; |
| 60 metadata.name = name; |
| 61 metadata.size = size; |
| 62 metadata.modification_time = modification_time; |
| 63 metadata.mime_type = mime_type; |
| 64 |
| 65 entries_[entry_path] = FakeEntry(metadata, contents); |
| 66 } |
| 67 |
| 68 bool FakeProvidedFileSystem::GetEntry(const base::FilePath& entry_path, |
| 69 FakeEntry* fake_entry) const { |
| 70 const Entries::const_iterator entry_it = entries_.find(entry_path); |
| 71 if (entry_it == entries_.end()) |
| 72 return false; |
| 73 |
| 74 *fake_entry = entry_it->second; |
| 75 return true; |
| 76 } |
| 77 |
| 49 void FakeProvidedFileSystem::RequestUnmount( | 78 void FakeProvidedFileSystem::RequestUnmount( |
| 50 const fileapi::AsyncFileUtil::StatusCallback& callback) { | 79 const fileapi::AsyncFileUtil::StatusCallback& callback) { |
| 51 base::MessageLoopProxy::current()->PostTask( | 80 base::MessageLoopProxy::current()->PostTask( |
| 52 FROM_HERE, base::Bind(callback, base::File::FILE_OK)); | 81 FROM_HERE, base::Bind(callback, base::File::FILE_OK)); |
| 53 } | 82 } |
| 54 | 83 |
| 55 void FakeProvidedFileSystem::GetMetadata( | 84 void FakeProvidedFileSystem::GetMetadata( |
| 56 const base::FilePath& entry_path, | 85 const base::FilePath& entry_path, |
| 57 const ProvidedFileSystemInterface::GetMetadataCallback& callback) { | 86 const ProvidedFileSystemInterface::GetMetadataCallback& callback) { |
| 58 if (entry_path.AsUTF8Unsafe() == "/") { | 87 const Entries::const_iterator entry_it = entries_.find(entry_path); |
| 59 EntryMetadata metadata; | |
| 60 metadata.size = 0; | |
| 61 metadata.is_directory = true; | |
| 62 base::Time modification_time; | |
| 63 const bool result = base::Time::FromString("Thu Apr 24 00:46:52 UTC 2014", | |
| 64 &modification_time); | |
| 65 DCHECK(result); | |
| 66 metadata.modification_time = modification_time; | |
| 67 | 88 |
| 89 if (entry_it == entries_.end()) { |
| 68 base::MessageLoopProxy::current()->PostTask( | 90 base::MessageLoopProxy::current()->PostTask( |
| 69 FROM_HERE, base::Bind(callback, metadata, base::File::FILE_OK)); | 91 FROM_HERE, |
| 70 return; | 92 base::Bind( |
| 71 } | 93 callback, EntryMetadata(), base::File::FILE_ERROR_NOT_FOUND)); |
| 72 | |
| 73 if (entry_path.AsUTF8Unsafe() == kFakeFilePath) { | |
| 74 EntryMetadata metadata; | |
| 75 metadata.size = kFakeFileSize; | |
| 76 metadata.is_directory = false; | |
| 77 base::Time modification_time; | |
| 78 const bool result = | |
| 79 base::Time::FromString(kFakeFileModificationTime, &modification_time); | |
| 80 DCHECK(result); | |
| 81 metadata.modification_time = modification_time; | |
| 82 metadata.mime_type = "text/plain"; | |
| 83 | |
| 84 base::MessageLoopProxy::current()->PostTask( | |
| 85 FROM_HERE, base::Bind(callback, metadata, base::File::FILE_OK)); | |
| 86 return; | 94 return; |
| 87 } | 95 } |
| 88 | 96 |
| 89 base::MessageLoopProxy::current()->PostTask( | 97 base::MessageLoopProxy::current()->PostTask( |
| 90 FROM_HERE, | 98 FROM_HERE, |
| 91 base::Bind(callback, EntryMetadata(), base::File::FILE_ERROR_NOT_FOUND)); | 99 base::Bind(callback, entry_it->second.metadata, base::File::FILE_OK)); |
| 92 } | 100 } |
| 93 | 101 |
| 94 void FakeProvidedFileSystem::ReadDirectory( | 102 void FakeProvidedFileSystem::ReadDirectory( |
| 95 const base::FilePath& directory_path, | 103 const base::FilePath& directory_path, |
| 96 const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) { | 104 const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) { |
| 97 // Return fake contents for the root directory only. | 105 fileapi::AsyncFileUtil::EntryList entry_list; |
| 98 if (directory_path.AsUTF8Unsafe() != "/") { | 106 |
| 99 base::MessageLoopProxy::current()->PostTask( | 107 for (Entries::const_iterator it = entries_.begin(); it != entries_.end(); |
| 100 FROM_HERE, | 108 ++it) { |
| 101 base::Bind(callback, | 109 const base::FilePath file_path = it->first; |
| 102 base::File::FILE_ERROR_NOT_FOUND, | 110 if (file_path == directory_path || directory_path.IsParent(file_path)) { |
| 103 fileapi::AsyncFileUtil::EntryList(), | 111 const EntryMetadata& metadata = it->second.metadata; |
| 104 false /* has_more */)); | 112 entry_list.push_back(fileapi::DirectoryEntry( |
| 105 return; | 113 metadata.name, |
| 114 metadata.is_directory ? fileapi::DirectoryEntry::DIRECTORY |
| 115 : fileapi::DirectoryEntry::FILE, |
| 116 metadata.size, |
| 117 metadata.modification_time)); |
| 118 } |
| 106 } | 119 } |
| 107 | 120 |
| 108 { | 121 base::MessageLoopProxy::current()->PostTask( |
| 109 fileapi::AsyncFileUtil::EntryList entry_list; | 122 FROM_HERE, |
| 110 AddDirectoryEntry(&entry_list, | 123 base::Bind( |
| 111 kFakeFileName, | 124 callback, base::File::FILE_OK, entry_list, false /* has_more */)); |
| 112 fileapi::DirectoryEntry::FILE, | 125 } |
| 113 kFakeFileSize, | |
| 114 "Thu Apr 24 00:46:52 UTC 2014"); | |
| 115 | 126 |
| 116 AddDirectoryEntry(&entry_list, | 127 void FakeProvidedFileSystem::OpenFile(const base::FilePath& entry_path, |
| 117 "world.txt", | 128 OpenFileMode mode, |
| 118 fileapi::DirectoryEntry::FILE, | 129 const OpenFileCallback& callback) { |
| 119 1024 /* size */, | 130 const Entries::const_iterator entry_it = entries_.find(entry_path); |
| 120 "Wed Apr 23 00:20:30 UTC 2014"); | |
| 121 | 131 |
| 132 if (entry_it == entries_.end()) { |
| 122 base::MessageLoopProxy::current()->PostTask( | 133 base::MessageLoopProxy::current()->PostTask( |
| 123 FROM_HERE, | 134 FROM_HERE, |
| 124 base::Bind( | 135 base::Bind( |
| 125 callback, base::File::FILE_OK, entry_list, true /* has_more */)); | |
| 126 } | |
| 127 | |
| 128 { | |
| 129 fileapi::AsyncFileUtil::EntryList entry_list; | |
| 130 AddDirectoryEntry(&entry_list, | |
| 131 "pictures", | |
| 132 fileapi::DirectoryEntry::DIRECTORY, | |
| 133 0 /* size */, | |
| 134 "Tue May 22 00:40:50 UTC 2014"); | |
| 135 | |
| 136 base::MessageLoopProxy::current()->PostTask( | |
| 137 FROM_HERE, | |
| 138 base::Bind( | |
| 139 callback, base::File::FILE_OK, entry_list, false /* has_more */)); | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 void FakeProvidedFileSystem::OpenFile(const base::FilePath& file_path, | |
| 144 OpenFileMode mode, | |
| 145 const OpenFileCallback& callback) { | |
| 146 if (mode == OPEN_FILE_MODE_WRITE) { | |
| 147 base::MessageLoopProxy::current()->PostTask( | |
| 148 FROM_HERE, | |
| 149 base::Bind(callback, | |
| 150 0 /* file_handle */, | |
| 151 base::File::FILE_ERROR_ACCESS_DENIED)); | |
| 152 } | |
| 153 | |
| 154 if (file_path.AsUTF8Unsafe() != "/hello.txt") { | |
| 155 base::MessageLoopProxy::current()->PostTask( | |
| 156 FROM_HERE, | |
| 157 base::Bind( | |
| 158 callback, 0 /* file_handle */, base::File::FILE_ERROR_NOT_FOUND)); | 136 callback, 0 /* file_handle */, base::File::FILE_ERROR_NOT_FOUND)); |
| 159 return; | 137 return; |
| 160 } | 138 } |
| 161 | 139 |
| 162 const int file_handle = ++last_file_handle_; | 140 const int file_handle = ++last_file_handle_; |
| 163 opened_files_[file_handle] = file_path; | 141 opened_files_[file_handle] = entry_path; |
| 164 base::MessageLoopProxy::current()->PostTask( | 142 base::MessageLoopProxy::current()->PostTask( |
| 165 FROM_HERE, base::Bind(callback, file_handle, base::File::FILE_OK)); | 143 FROM_HERE, base::Bind(callback, file_handle, base::File::FILE_OK)); |
| 166 } | 144 } |
| 167 | 145 |
| 168 void FakeProvidedFileSystem::CloseFile( | 146 void FakeProvidedFileSystem::CloseFile( |
| 169 int file_handle, | 147 int file_handle, |
| 170 const fileapi::AsyncFileUtil::StatusCallback& callback) { | 148 const fileapi::AsyncFileUtil::StatusCallback& callback) { |
| 171 const OpenedFilesMap::iterator opened_file_it = | 149 const OpenedFilesMap::iterator opened_file_it = |
| 172 opened_files_.find(file_handle); | 150 opened_files_.find(file_handle); |
| 151 |
| 173 if (opened_file_it == opened_files_.end()) { | 152 if (opened_file_it == opened_files_.end()) { |
| 174 base::MessageLoopProxy::current()->PostTask( | 153 base::MessageLoopProxy::current()->PostTask( |
| 175 FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_NOT_FOUND)); | 154 FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_NOT_FOUND)); |
| 176 return; | 155 return; |
| 177 } | 156 } |
| 178 | 157 |
| 179 opened_files_.erase(opened_file_it); | 158 opened_files_.erase(opened_file_it); |
| 180 base::MessageLoopProxy::current()->PostTask( | 159 base::MessageLoopProxy::current()->PostTask( |
| 181 FROM_HERE, base::Bind(callback, base::File::FILE_OK)); | 160 FROM_HERE, base::Bind(callback, base::File::FILE_OK)); |
| 182 } | 161 } |
| 183 | 162 |
| 184 void FakeProvidedFileSystem::ReadFile( | 163 void FakeProvidedFileSystem::ReadFile( |
| 185 int file_handle, | 164 int file_handle, |
| 186 net::IOBuffer* buffer, | 165 net::IOBuffer* buffer, |
| 187 int64 offset, | 166 int64 offset, |
| 188 int length, | 167 int length, |
| 189 const ProvidedFileSystemInterface::ReadChunkReceivedCallback& callback) { | 168 const ProvidedFileSystemInterface::ReadChunkReceivedCallback& callback) { |
| 190 const OpenedFilesMap::iterator opened_file_it = | 169 const OpenedFilesMap::iterator opened_file_it = |
| 191 opened_files_.find(file_handle); | 170 opened_files_.find(file_handle); |
| 171 |
| 192 if (opened_file_it == opened_files_.end() || | 172 if (opened_file_it == opened_files_.end() || |
| 193 opened_file_it->second.AsUTF8Unsafe() != kFakeFilePath) { | 173 opened_file_it->second.AsUTF8Unsafe() != kFakeFilePath) { |
| 194 base::MessageLoopProxy::current()->PostTask( | 174 base::MessageLoopProxy::current()->PostTask( |
| 195 FROM_HERE, | 175 FROM_HERE, |
| 196 base::Bind(callback, | 176 base::Bind(callback, |
| 197 0 /* chunk_length */, | 177 0 /* chunk_length */, |
| 198 false /* has_more */, | 178 false /* has_more */, |
| 199 base::File::FILE_ERROR_INVALID_OPERATION)); | 179 base::File::FILE_ERROR_INVALID_OPERATION)); |
| 200 return; | 180 return; |
| 201 } | 181 } |
| 202 | 182 |
| 183 const Entries::const_iterator entry_it = |
| 184 entries_.find(opened_file_it->second); |
| 185 if (entry_it == entries_.end()) { |
| 186 base::MessageLoopProxy::current()->PostTask( |
| 187 FROM_HERE, |
| 188 base::Bind(callback, |
| 189 0 /* chunk_length */, |
| 190 false /* has_more */, |
| 191 base::File::FILE_ERROR_INVALID_OPERATION)); |
| 192 return; |
| 193 } |
| 194 |
| 203 // Send the response byte by byte. | 195 // Send the response byte by byte. |
| 204 size_t current_offset = static_cast<size_t>(offset); | 196 int64 current_offset = offset; |
| 205 size_t current_length = static_cast<size_t>(length); | 197 int current_length = length; |
| 206 | 198 |
| 207 // Reading behind EOF is fine, it will just return 0 bytes. | 199 // Reading behind EOF is fine, it will just return 0 bytes. |
| 208 if (current_offset >= kFakeFileSize || !current_length) { | 200 if (current_offset >= entry_it->second.metadata.size || !current_length) { |
| 209 base::MessageLoopProxy::current()->PostTask( | 201 base::MessageLoopProxy::current()->PostTask( |
| 210 FROM_HERE, | 202 FROM_HERE, |
| 211 base::Bind(callback, | 203 base::Bind(callback, |
| 212 0 /* chunk_length */, | 204 0 /* chunk_length */, |
| 213 false /* has_more */, | 205 false /* has_more */, |
| 214 base::File::FILE_OK)); | 206 base::File::FILE_OK)); |
| 215 } | 207 } |
| 216 | 208 |
| 217 while (current_offset < kFakeFileSize && current_length) { | 209 const FakeEntry& entry = entry_it->second; |
| 218 buffer->data()[current_offset - offset] = kFakeFileText[current_offset]; | 210 while (current_offset < entry.metadata.size && current_length) { |
| 211 buffer->data()[current_offset - offset] = entry.contents[current_offset]; |
| 219 const bool has_more = | 212 const bool has_more = |
| 220 (current_offset + 1 < kFakeFileSize) && (current_length - 1); | 213 (current_offset + 1 < entry.metadata.size) && (current_length - 1); |
| 221 base::MessageLoopProxy::current()->PostTask( | 214 base::MessageLoopProxy::current()->PostTask( |
| 222 FROM_HERE, | 215 FROM_HERE, |
| 223 base::Bind( | 216 base::Bind( |
| 224 callback, 1 /* chunk_length */, has_more, base::File::FILE_OK)); | 217 callback, 1 /* chunk_length */, has_more, base::File::FILE_OK)); |
| 225 current_offset++; | 218 current_offset++; |
| 226 current_length--; | 219 current_length--; |
| 227 } | 220 } |
| 228 } | 221 } |
| 229 | 222 |
| 230 void FakeProvidedFileSystem::CreateDirectory( | 223 void FakeProvidedFileSystem::CreateDirectory( |
| 231 const base::FilePath& directory_path, | 224 const base::FilePath& directory_path, |
| 232 bool exclusive, | 225 bool exclusive, |
| 233 bool recursive, | 226 bool recursive, |
| 234 const fileapi::AsyncFileUtil::StatusCallback& callback) { | 227 const fileapi::AsyncFileUtil::StatusCallback& callback) { |
| 228 // TODO(mtomasz): Implement it once needed. |
| 235 base::MessageLoopProxy::current()->PostTask( | 229 base::MessageLoopProxy::current()->PostTask( |
| 236 FROM_HERE, base::Bind(callback, base::File::FILE_OK)); | 230 FROM_HERE, base::Bind(callback, base::File::FILE_OK)); |
| 237 } | 231 } |
| 238 | 232 |
| 239 void FakeProvidedFileSystem::DeleteEntry( | 233 void FakeProvidedFileSystem::DeleteEntry( |
| 240 const base::FilePath& entry_path, | 234 const base::FilePath& entry_path, |
| 241 bool recursive, | 235 bool recursive, |
| 242 const fileapi::AsyncFileUtil::StatusCallback& callback) { | 236 const fileapi::AsyncFileUtil::StatusCallback& callback) { |
| 237 // TODO(mtomasz): Implement it once needed. |
| 243 base::MessageLoopProxy::current()->PostTask( | 238 base::MessageLoopProxy::current()->PostTask( |
| 244 FROM_HERE, base::Bind(callback, base::File::FILE_OK)); | 239 FROM_HERE, base::Bind(callback, base::File::FILE_OK)); |
| 245 } | 240 } |
| 246 | 241 |
| 247 const ProvidedFileSystemInfo& FakeProvidedFileSystem::GetFileSystemInfo() | 242 const ProvidedFileSystemInfo& FakeProvidedFileSystem::GetFileSystemInfo() |
| 248 const { | 243 const { |
| 249 return file_system_info_; | 244 return file_system_info_; |
| 250 } | 245 } |
| 251 | 246 |
| 252 RequestManager* FakeProvidedFileSystem::GetRequestManager() { | 247 RequestManager* FakeProvidedFileSystem::GetRequestManager() { |
| 253 NOTREACHED(); | 248 NOTREACHED(); |
| 254 return NULL; | 249 return NULL; |
| 255 } | 250 } |
| 256 | 251 |
| 257 ProvidedFileSystemInterface* FakeProvidedFileSystem::Create( | 252 ProvidedFileSystemInterface* FakeProvidedFileSystem::Create( |
| 258 Profile* profile, | 253 Profile* profile, |
| 259 const ProvidedFileSystemInfo& file_system_info) { | 254 const ProvidedFileSystemInfo& file_system_info) { |
| 260 return new FakeProvidedFileSystem(file_system_info); | 255 return new FakeProvidedFileSystem(file_system_info); |
| 261 } | 256 } |
| 262 | 257 |
| 263 base::WeakPtr<ProvidedFileSystemInterface> | 258 base::WeakPtr<ProvidedFileSystemInterface> |
| 264 FakeProvidedFileSystem::GetWeakPtr() { | 259 FakeProvidedFileSystem::GetWeakPtr() { |
| 265 return weak_ptr_factory_.GetWeakPtr(); | 260 return weak_ptr_factory_.GetWeakPtr(); |
| 266 } | 261 } |
| 267 | 262 |
| 268 } // namespace file_system_provider | 263 } // namespace file_system_provider |
| 269 } // namespace chromeos | 264 } // namespace chromeos |
| OLD | NEW |