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 |