Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(344)

Side by Side Diff: webkit/fileapi/obfuscated_file_util.cc

Issue 7470037: [Refactor] to rename and re-layer the file_util stack layers. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Rebased on the svn tree. Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/fileapi/obfuscated_file_util.h ('k') | webkit/fileapi/obfuscated_file_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "webkit/fileapi/obfuscated_file_system_file_util.h" 5 #include "webkit/fileapi/obfuscated_file_util.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/file_util.h" 11 #include "base/file_util.h"
12 #include "base/format_macros.h" 12 #include "base/format_macros.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 const FilePath::CharType kTemporaryDirectoryName[] = FILE_PATH_LITERAL("t"); 97 const FilePath::CharType kTemporaryDirectoryName[] = FILE_PATH_LITERAL("t");
98 const FilePath::CharType kPersistentDirectoryName[] = FILE_PATH_LITERAL("p"); 98 const FilePath::CharType kPersistentDirectoryName[] = FILE_PATH_LITERAL("p");
99 99
100 } // namespace 100 } // namespace
101 101
102 namespace fileapi { 102 namespace fileapi {
103 103
104 using base::PlatformFile; 104 using base::PlatformFile;
105 using base::PlatformFileError; 105 using base::PlatformFileError;
106 106
107 ObfuscatedFileSystemFileUtil::ObfuscatedFileSystemFileUtil( 107 class ObfuscatedFileEnumerator
108 : public FileSystemFileUtil::AbstractFileEnumerator {
109 public:
110 ObfuscatedFileEnumerator(
111 const FilePath& base_path,
112 FileSystemDirectoryDatabase* db,
113 FileSystemOperationContext* context,
114 FileSystemFileUtil* underlying_file_util,
115 const FilePath& virtual_root_path)
116 : base_path_(base_path),
117 db_(db),
118 context_(context),
119 underlying_file_util_(underlying_file_util) {
120 DCHECK(db_);
121 DCHECK(context_);
122 DCHECK(underlying_file_util_);
123
124 FileId file_id;
125 FileInfo file_info;
126 if (!db_->GetFileWithPath(virtual_root_path, &file_id))
127 return;
128 if (!db_->GetFileInfo(file_id, &file_info))
129 return;
130 if (!file_info.is_directory())
131 return;
132 FileRecord record = { file_id, file_info, virtual_root_path };
133 display_queue_.push(record);
134 Next(); // Enumerators don't include the directory itself.
135 }
136
137 ~ObfuscatedFileEnumerator() {}
138
139 virtual FilePath Next() OVERRIDE {
140 ProcessRecurseQueue();
141 if (display_queue_.empty())
142 return FilePath();
143 current_ = display_queue_.front();
144 display_queue_.pop();
145 if (current_.file_info.is_directory())
146 recurse_queue_.push(current_);
147 return current_.file_path;
148 }
149
150 virtual int64 Size() OVERRIDE {
151 if (IsDirectory())
152 return 0;
153
154 base::PlatformFileInfo file_info;
155 FilePath platform_file_path;
156
157 FilePath local_path = base_path_.Append(current_.file_info.data_path);
158 base::PlatformFileError error = underlying_file_util_->GetFileInfo(
159 context_, local_path, &file_info, &platform_file_path);
160 if (error != base::PLATFORM_FILE_OK) {
161 LOG(WARNING) << "Lost a backing file.";
162 return 0;
163 }
164 return file_info.size;
165 }
166
167 virtual bool IsDirectory() OVERRIDE {
168 return current_.file_info.is_directory();
169 }
170
171 private:
172 typedef FileSystemDirectoryDatabase::FileId FileId;
173 typedef FileSystemDirectoryDatabase::FileInfo FileInfo;
174
175 struct FileRecord {
176 FileId file_id;
177 FileInfo file_info;
178 FilePath file_path;
179 };
180
181 void ProcessRecurseQueue() {
182 while (display_queue_.empty() && !recurse_queue_.empty()) {
183 FileRecord directory = recurse_queue_.front();
184 std::vector<FileId> children;
185 recurse_queue_.pop();
186 if (!db_->ListChildren(directory.file_id, &children))
187 return;
188 std::vector<FileId>::iterator iter;
189 for (iter = children.begin(); iter != children.end(); ++iter) {
190 FileRecord child;
191 child.file_id = *iter;
192 if (!db_->GetFileInfo(child.file_id, &child.file_info))
193 return;
194 child.file_path = directory.file_path.Append(child.file_info.name);
195 display_queue_.push(child);
196 }
197 }
198 }
199
200 std::queue<FileRecord> display_queue_;
201 std::queue<FileRecord> recurse_queue_;
202 FileRecord current_;
203 FilePath base_path_;
204 FileSystemDirectoryDatabase* db_;
205 FileSystemOperationContext* context_;
206 FileSystemFileUtil* underlying_file_util_;
207 };
208
209 class ObfuscatedOriginEnumerator
210 : public ObfuscatedFileUtil::AbstractOriginEnumerator {
211 public:
212 typedef FileSystemOriginDatabase::OriginRecord OriginRecord;
213 ObfuscatedOriginEnumerator(
214 FileSystemOriginDatabase* origin_database,
215 const FilePath& base_path)
216 : base_path_(base_path) {
217 if (origin_database)
218 origin_database->ListAllOrigins(&origins_);
219 }
220
221 ~ObfuscatedOriginEnumerator() {}
222
223 // Returns the next origin. Returns empty if there are no more origins.
224 virtual GURL Next() OVERRIDE {
225 OriginRecord record;
226 if (!origins_.empty()) {
227 record = origins_.back();
228 origins_.pop_back();
229 }
230 current_ = record;
231 return GetOriginURLFromIdentifier(record.origin);
232 }
233
234 // Returns the current origin's information.
235 virtual bool HasFileSystemType(FileSystemType type) const OVERRIDE {
236 if (current_.path.empty())
237 return false;
238 FilePath::StringType type_string =
239 ObfuscatedFileUtil::GetDirectoryNameForType(type);
240 if (type_string.empty()) {
241 NOTREACHED();
242 return false;
243 }
244 FilePath path = base_path_.Append(current_.path).Append(type_string);
245 return file_util::DirectoryExists(path);
246 }
247
248 private:
249 std::vector<OriginRecord> origins_;
250 OriginRecord current_;
251 FilePath base_path_;
252 };
253
254 ObfuscatedFileUtil::ObfuscatedFileUtil(
108 const FilePath& file_system_directory, 255 const FilePath& file_system_directory,
109 FileSystemFileUtil* underlying_file_util) 256 FileSystemFileUtil* underlying_file_util)
110 : file_system_directory_(file_system_directory), 257 : FileSystemFileUtil(underlying_file_util),
111 underlying_file_util_(underlying_file_util) { 258 file_system_directory_(file_system_directory) {
112 } 259 }
113 260
114 ObfuscatedFileSystemFileUtil::~ObfuscatedFileSystemFileUtil() { 261 ObfuscatedFileUtil::~ObfuscatedFileUtil() {
115 DropDatabases(); 262 DropDatabases();
116 } 263 }
117 264
118 PlatformFileError ObfuscatedFileSystemFileUtil::CreateOrOpen( 265 PlatformFileError ObfuscatedFileUtil::CreateOrOpen(
119 FileSystemOperationContext* context, 266 FileSystemOperationContext* context,
120 const FilePath& virtual_path, int file_flags, 267 const FilePath& virtual_path, int file_flags,
121 PlatformFile* file_handle, bool* created) { 268 PlatformFile* file_handle, bool* created) {
122 DCHECK(!(file_flags & (base::PLATFORM_FILE_DELETE_ON_CLOSE | 269 DCHECK(!(file_flags & (base::PLATFORM_FILE_DELETE_ON_CLOSE |
123 base::PLATFORM_FILE_HIDDEN | base::PLATFORM_FILE_EXCLUSIVE_READ | 270 base::PLATFORM_FILE_HIDDEN | base::PLATFORM_FILE_EXCLUSIVE_READ |
124 base::PLATFORM_FILE_EXCLUSIVE_WRITE))); 271 base::PLATFORM_FILE_EXCLUSIVE_WRITE)));
125 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 272 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
126 context->src_origin_url(), context->src_type(), true); 273 context->src_origin_url(), context->src_type(), true);
127 if (!db) 274 if (!db)
128 return base::PLATFORM_FILE_ERROR_FAILED; 275 return base::PLATFORM_FILE_ERROR_FAILED;
(...skipping 22 matching lines...) Expand all
151 298
152 FileInfo file_info; 299 FileInfo file_info;
153 if (!db->GetFileInfo(file_id, &file_info)) { 300 if (!db->GetFileInfo(file_id, &file_info)) {
154 NOTREACHED(); 301 NOTREACHED();
155 return base::PLATFORM_FILE_ERROR_FAILED; 302 return base::PLATFORM_FILE_ERROR_FAILED;
156 } 303 }
157 if (file_info.is_directory()) 304 if (file_info.is_directory())
158 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; 305 return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
159 FilePath local_path = DataPathToLocalPath(context->src_origin_url(), 306 FilePath local_path = DataPathToLocalPath(context->src_origin_url(),
160 context->src_type(), file_info.data_path); 307 context->src_type(), file_info.data_path);
161 base::PlatformFileError error = underlying_file_util_->CreateOrOpen( 308 base::PlatformFileError error = underlying_file_util()->CreateOrOpen(
162 context, local_path, file_flags, file_handle, created); 309 context, local_path, file_flags, file_handle, created);
163 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) { 310 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) {
164 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. 311 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker.
165 // TODO(tzik): Delete database entry after ensuring the file lost. 312 // TODO(tzik): Delete database entry after ensuring the file lost.
166 context->file_system_context()->GetQuotaUtil(context->src_type())-> 313 context->file_system_context()->GetQuotaUtil(context->src_type())->
167 InvalidateUsageCache(context->src_origin_url(), 314 InvalidateUsageCache(context->src_origin_url(),
168 context->src_type()); 315 context->src_type());
169 LOG(WARNING) << "Lost a backing file."; 316 LOG(WARNING) << "Lost a backing file.";
170 error = base::PLATFORM_FILE_ERROR_FAILED; 317 error = base::PLATFORM_FILE_ERROR_FAILED;
171 } 318 }
172 return error; 319 return error;
173 } 320 }
174 321
175 PlatformFileError ObfuscatedFileSystemFileUtil::EnsureFileExists( 322 PlatformFileError ObfuscatedFileUtil::EnsureFileExists(
176 FileSystemOperationContext* context, 323 FileSystemOperationContext* context,
177 const FilePath& virtual_path, 324 const FilePath& virtual_path,
178 bool* created) { 325 bool* created) {
179 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 326 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
180 context->src_origin_url(), context->src_type(), true); 327 context->src_origin_url(), context->src_type(), true);
181 if (!db) 328 if (!db)
182 return base::PLATFORM_FILE_ERROR_FAILED; 329 return base::PLATFORM_FILE_ERROR_FAILED;
183 FileId file_id; 330 FileId file_id;
184 if (db->GetFileWithPath(virtual_path, &file_id)) { 331 if (db->GetFileWithPath(virtual_path, &file_id)) {
185 FileInfo file_info; 332 FileInfo file_info;
(...skipping 15 matching lines...) Expand all
201 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); 348 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value());
202 if (!AllocateQuotaForPath(context, 1, file_info.name.size())) 349 if (!AllocateQuotaForPath(context, 1, file_info.name.size()))
203 return base::PLATFORM_FILE_ERROR_NO_SPACE; 350 return base::PLATFORM_FILE_ERROR_NO_SPACE;
204 PlatformFileError error = CreateFile(context, context->src_origin_url(), 351 PlatformFileError error = CreateFile(context, context->src_origin_url(),
205 context->src_type(), FilePath(), &file_info, 0, NULL); 352 context->src_type(), FilePath(), &file_info, 0, NULL);
206 if (created && base::PLATFORM_FILE_OK == error) 353 if (created && base::PLATFORM_FILE_OK == error)
207 *created = true; 354 *created = true;
208 return error; 355 return error;
209 } 356 }
210 357
211 PlatformFileError ObfuscatedFileSystemFileUtil::GetLocalFilePath( 358 PlatformFileError ObfuscatedFileUtil::CreateDirectory(
212 FileSystemOperationContext* context, 359 FileSystemOperationContext* context,
213 const FilePath& virtual_path, 360 const FilePath& virtual_path,
214 FilePath* local_path) { 361 bool exclusive,
215 FilePath path = 362 bool recursive) {
216 GetLocalPath(context->src_origin_url(), context->src_type(), 363 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
217 virtual_path); 364 context->src_origin_url(), context->src_type(), true);
218 if (path.empty()) 365 if (!db)
366 return base::PLATFORM_FILE_ERROR_FAILED;
367 FileId file_id;
368 if (db->GetFileWithPath(virtual_path, &file_id)) {
369 FileInfo file_info;
370 if (exclusive)
371 return base::PLATFORM_FILE_ERROR_EXISTS;
372 if (!db->GetFileInfo(file_id, &file_info)) {
373 NOTREACHED();
374 return base::PLATFORM_FILE_ERROR_FAILED;
375 }
376 if (!file_info.is_directory())
377 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
378 return base::PLATFORM_FILE_OK;
379 }
380
381 std::vector<FilePath::StringType> components;
382 virtual_path.GetComponents(&components);
383 FileId parent_id = 0;
384 size_t index;
385 for (index = 0; index < components.size(); ++index) {
386 FilePath::StringType name = components[index];
387 if (name == FILE_PATH_LITERAL("/"))
388 continue;
389 if (!db->GetChildWithName(parent_id, name, &parent_id))
390 break;
391 }
392 if (!recursive && components.size() - index > 1)
219 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 393 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
220 394 for (; index < components.size(); ++index) {
221 *local_path = path; 395 FileInfo file_info;
396 file_info.name = components[index];
397 if (file_info.name == FILE_PATH_LITERAL("/"))
398 continue;
399 file_info.modification_time = base::Time::Now();
400 file_info.parent_id = parent_id;
401 if (!AllocateQuotaForPath(context, 1, file_info.name.size()))
402 return base::PLATFORM_FILE_ERROR_NO_SPACE;
403 if (!db->AddFileInfo(file_info, &parent_id)) {
404 NOTREACHED();
405 return base::PLATFORM_FILE_ERROR_FAILED;
406 }
407 UpdatePathQuotaUsage(context, context->src_origin_url(),
408 context->src_type(), 1, file_info.name.size());
409 }
222 return base::PLATFORM_FILE_OK; 410 return base::PLATFORM_FILE_OK;
223 } 411 }
224 412
225 PlatformFileError ObfuscatedFileSystemFileUtil::GetFileInfo( 413 PlatformFileError ObfuscatedFileUtil::GetFileInfo(
226 FileSystemOperationContext* context, 414 FileSystemOperationContext* context,
227 const FilePath& virtual_path, 415 const FilePath& virtual_path,
228 base::PlatformFileInfo* file_info, 416 base::PlatformFileInfo* file_info,
229 FilePath* platform_file_path) { 417 FilePath* platform_file_path) {
230 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 418 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
231 context->src_origin_url(), context->src_type(), false); 419 context->src_origin_url(), context->src_type(), false);
232 if (!db) 420 if (!db)
233 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 421 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
234 FileId file_id; 422 FileId file_id;
235 if (!db->GetFileWithPath(virtual_path, &file_id)) 423 if (!db->GetFileWithPath(virtual_path, &file_id))
236 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 424 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
237 FileInfo local_info; 425 FileInfo local_info;
238 return GetFileInfoInternal(db, context, file_id, 426 return GetFileInfoInternal(db, context, file_id,
239 &local_info, file_info, platform_file_path); 427 &local_info, file_info, platform_file_path);
240 } 428 }
241 429
242 PlatformFileError ObfuscatedFileSystemFileUtil::ReadDirectory( 430 PlatformFileError ObfuscatedFileUtil::ReadDirectory(
243 FileSystemOperationContext* context, 431 FileSystemOperationContext* context,
244 const FilePath& virtual_path, 432 const FilePath& virtual_path,
245 std::vector<base::FileUtilProxy::Entry>* entries) { 433 std::vector<base::FileUtilProxy::Entry>* entries) {
246 // TODO(kkanetkar): Implement directory read in multiple chunks. 434 // TODO(kkanetkar): Implement directory read in multiple chunks.
247 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 435 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
248 context->src_origin_url(), context->src_type(), false); 436 context->src_origin_url(), context->src_type(), false);
249 if (!db) { 437 if (!db) {
250 if (IsRootDirectory(virtual_path)) { 438 if (IsRootDirectory(virtual_path)) {
251 // It's the root directory and the database hasn't been initialized yet. 439 // It's the root directory and the database hasn't been initialized yet.
252 entries->clear(); 440 entries->clear();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 base::FileUtilProxy::Entry entry; 476 base::FileUtilProxy::Entry entry;
289 entry.name = file_info.name; 477 entry.name = file_info.name;
290 entry.is_directory = file_info.is_directory(); 478 entry.is_directory = file_info.is_directory();
291 entry.size = entry.is_directory ? 0 : platform_file_info.size; 479 entry.size = entry.is_directory ? 0 : platform_file_info.size;
292 entry.last_modified_time = platform_file_info.last_modified; 480 entry.last_modified_time = platform_file_info.last_modified;
293 entries->push_back(entry); 481 entries->push_back(entry);
294 } 482 }
295 return base::PLATFORM_FILE_OK; 483 return base::PLATFORM_FILE_OK;
296 } 484 }
297 485
298 PlatformFileError ObfuscatedFileSystemFileUtil::CreateDirectory( 486 FileSystemFileUtil::AbstractFileEnumerator*
487 ObfuscatedFileUtil::CreateFileEnumerator(
488 FileSystemOperationContext* context,
489 const FilePath& root_path) {
490 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
491 context->src_origin_url(), context->src_type(), false);
492 if (!db)
493 return new FileSystemFileUtil::EmptyFileEnumerator();
494 return new ObfuscatedFileEnumerator(
495 GetDirectoryForOriginAndType(context->src_origin_url(),
496 context->src_type(), false),
497 db,
498 context,
499 underlying_file_util(),
500 root_path);
501 }
502
503 PlatformFileError ObfuscatedFileUtil::GetLocalFilePath(
299 FileSystemOperationContext* context, 504 FileSystemOperationContext* context,
300 const FilePath& virtual_path, 505 const FilePath& virtual_path,
301 bool exclusive, 506 FilePath* local_path) {
302 bool recursive) { 507 FilePath path =
303 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 508 GetLocalPath(context->src_origin_url(), context->src_type(),
304 context->src_origin_url(), context->src_type(), true); 509 virtual_path);
305 if (!db) 510 if (path.empty())
306 return base::PLATFORM_FILE_ERROR_FAILED; 511 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
307 FileId file_id;
308 if (db->GetFileWithPath(virtual_path, &file_id)) {
309 FileInfo file_info;
310 if (exclusive)
311 return base::PLATFORM_FILE_ERROR_EXISTS;
312 if (!db->GetFileInfo(file_id, &file_info)) {
313 NOTREACHED();
314 return base::PLATFORM_FILE_ERROR_FAILED;
315 }
316 if (!file_info.is_directory())
317 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
318 return base::PLATFORM_FILE_OK;
319 }
320 512
321 std::vector<FilePath::StringType> components; 513 *local_path = path;
322 virtual_path.GetComponents(&components);
323 FileId parent_id = 0;
324 size_t index;
325 for (index = 0; index < components.size(); ++index) {
326 FilePath::StringType name = components[index];
327 if (name == FILE_PATH_LITERAL("/"))
328 continue;
329 if (!db->GetChildWithName(parent_id, name, &parent_id))
330 break;
331 }
332 if (!recursive && components.size() - index > 1)
333 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
334 for (; index < components.size(); ++index) {
335 FileInfo file_info;
336 file_info.name = components[index];
337 if (file_info.name == FILE_PATH_LITERAL("/"))
338 continue;
339 file_info.modification_time = base::Time::Now();
340 file_info.parent_id = parent_id;
341 if (!AllocateQuotaForPath(context, 1, file_info.name.size()))
342 return base::PLATFORM_FILE_ERROR_NO_SPACE;
343 if (!db->AddFileInfo(file_info, &parent_id)) {
344 NOTREACHED();
345 return base::PLATFORM_FILE_ERROR_FAILED;
346 }
347 UpdatePathQuotaUsage(context, context->src_origin_url(),
348 context->src_type(), 1, file_info.name.size());
349 }
350 return base::PLATFORM_FILE_OK; 514 return base::PLATFORM_FILE_OK;
351 } 515 }
352 516
353 PlatformFileError ObfuscatedFileSystemFileUtil::CopyOrMoveFile( 517 PlatformFileError ObfuscatedFileUtil::Touch(
518 FileSystemOperationContext* context,
519 const FilePath& virtual_path,
520 const base::Time& last_access_time,
521 const base::Time& last_modified_time) {
522 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
523 context->src_origin_url(), context->src_type(), false);
524 if (!db)
525 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
526 FileId file_id;
527 if (!db->GetFileWithPath(virtual_path, &file_id))
528 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
529
530 FileInfo file_info;
531 if (!db->GetFileInfo(file_id, &file_info)) {
532 NOTREACHED();
533 return base::PLATFORM_FILE_ERROR_FAILED;
534 }
535 if (file_info.is_directory()) {
536 file_info.modification_time = last_modified_time;
537 if (!db->UpdateFileInfo(file_id, file_info))
538 return base::PLATFORM_FILE_ERROR_FAILED;
539 return base::PLATFORM_FILE_OK;
540 }
541 FilePath data_path = DataPathToLocalPath(context->src_origin_url(),
542 context->src_type(), file_info.data_path);
543 return underlying_file_util()->Touch(
544 context, data_path, last_access_time, last_modified_time);
545 }
546
547 PlatformFileError ObfuscatedFileUtil::Truncate(
548 FileSystemOperationContext* context,
549 const FilePath& virtual_path,
550 int64 length) {
551 FilePath local_path =
552 GetLocalPath(context->src_origin_url(), context->src_type(),
553 virtual_path);
554 if (local_path.empty())
555 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
556 return underlying_file_util()->Truncate(
557 context, local_path, length);
558 }
559
560 bool ObfuscatedFileUtil::PathExists(
561 FileSystemOperationContext* context,
562 const FilePath& virtual_path) {
563 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
564 context->src_origin_url(), context->src_type(), false);
565 if (!db)
566 return false;
567 FileId file_id;
568 return db->GetFileWithPath(virtual_path, &file_id);
569 }
570
571 bool ObfuscatedFileUtil::DirectoryExists(
572 FileSystemOperationContext* context,
573 const FilePath& virtual_path) {
574 if (IsRootDirectory(virtual_path)) {
575 // It's questionable whether we should return true or false for the
576 // root directory of nonexistent origin, but here we return true
577 // as the current implementation of ReadDirectory always returns an empty
578 // array (rather than erroring out with NOT_FOUND_ERR even) for
579 // nonexistent origins.
580 // Note: if you're going to change this behavior please also consider
581 // changiing the ReadDirectory's behavior!
582 return true;
583 }
584 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
585 context->src_origin_url(), context->src_type(), false);
586 if (!db)
587 return false;
588 FileId file_id;
589 if (!db->GetFileWithPath(virtual_path, &file_id))
590 return false;
591 FileInfo file_info;
592 if (!db->GetFileInfo(file_id, &file_info)) {
593 NOTREACHED();
594 return false;
595 }
596 return file_info.is_directory();
597 }
598
599 bool ObfuscatedFileUtil::IsDirectoryEmpty(
600 FileSystemOperationContext* context,
601 const FilePath& virtual_path) {
602 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
603 context->src_origin_url(), context->src_type(), false);
604 if (!db)
605 return true; // Not a great answer, but it's what others do.
606 FileId file_id;
607 if (!db->GetFileWithPath(virtual_path, &file_id))
608 return true; // Ditto.
609 FileInfo file_info;
610 if (!db->GetFileInfo(file_id, &file_info)) {
611 DCHECK(!file_id);
612 // It's the root directory and the database hasn't been initialized yet.
613 return true;
614 }
615 if (!file_info.is_directory())
616 return true;
617 std::vector<FileId> children;
618 // TODO(ericu): This could easily be made faster with help from the database.
619 if (!db->ListChildren(file_id, &children))
620 return true;
621 return children.empty();
622 }
623
624 PlatformFileError ObfuscatedFileUtil::CopyOrMoveFile(
354 FileSystemOperationContext* context, 625 FileSystemOperationContext* context,
355 const FilePath& src_file_path, 626 const FilePath& src_file_path,
356 const FilePath& dest_file_path, 627 const FilePath& dest_file_path,
357 bool copy) { 628 bool copy) {
358 // Cross-filesystem copies and moves should be handled via CopyInForeignFile. 629 // Cross-filesystem copies and moves should be handled via CopyInForeignFile.
359 DCHECK(context->src_origin_url() == context->dest_origin_url()); 630 DCHECK(context->src_origin_url() == context->dest_origin_url());
360 DCHECK(context->src_type() == context->dest_type()); 631 DCHECK(context->src_type() == context->dest_type());
361 632
362 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 633 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
363 context->src_origin_url(), context->src_type(), true); 634 context->src_origin_url(), context->src_type(), true);
(...skipping 28 matching lines...) Expand all
392 * transaction: 663 * transaction:
393 * Remove source entry. 664 * Remove source entry.
394 * Point target entry to source entry's backing file. 665 * Point target entry to source entry's backing file.
395 * Delete target entry's old backing file 666 * Delete target entry's old backing file
396 * Move-without-overwrite 667 * Move-without-overwrite
397 * Just update metadata 668 * Just update metadata
398 */ 669 */
399 if (copy) { 670 if (copy) {
400 FilePath src_data_path = DataPathToLocalPath(context->src_origin_url(), 671 FilePath src_data_path = DataPathToLocalPath(context->src_origin_url(),
401 context->src_type(), src_file_info.data_path); 672 context->src_type(), src_file_info.data_path);
402 if (!underlying_file_util_->PathExists(context, src_data_path)) { 673 if (!underlying_file_util()->PathExists(context, src_data_path)) {
403 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. 674 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker.
404 context->file_system_context()->GetQuotaUtil(context->src_type())-> 675 context->file_system_context()->GetQuotaUtil(context->src_type())->
405 InvalidateUsageCache(context->src_origin_url(), 676 InvalidateUsageCache(context->src_origin_url(),
406 context->src_type()); 677 context->src_type());
407 LOG(WARNING) << "Lost a backing file."; 678 LOG(WARNING) << "Lost a backing file.";
408 return base::PLATFORM_FILE_ERROR_FAILED; 679 return base::PLATFORM_FILE_ERROR_FAILED;
409 } 680 }
410 681
411 if (overwrite) { 682 if (overwrite) {
412 FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(), 683 FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(),
413 context->src_type(), dest_file_info.data_path); 684 context->src_type(), dest_file_info.data_path);
414 return underlying_file_util_->CopyOrMoveFile(context, 685 return underlying_file_util()->CopyOrMoveFile(context,
415 src_data_path, dest_data_path, copy); 686 src_data_path, dest_data_path, copy);
416 } else { 687 } else {
417 FileId dest_parent_id; 688 FileId dest_parent_id;
418 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { 689 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) {
419 NOTREACHED(); // We shouldn't be called in this case. 690 NOTREACHED(); // We shouldn't be called in this case.
420 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 691 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
421 } 692 }
422 InitFileInfo(&dest_file_info, dest_parent_id, 693 InitFileInfo(&dest_file_info, dest_parent_id,
423 dest_file_path.BaseName().value()); 694 dest_file_path.BaseName().value());
424 if (!AllocateQuotaForPath(context, 1, dest_file_info.name.size())) 695 if (!AllocateQuotaForPath(context, 1, dest_file_info.name.size()))
425 return base::PLATFORM_FILE_ERROR_NO_SPACE; 696 return base::PLATFORM_FILE_ERROR_NO_SPACE;
426 return CreateFile(context, context->dest_origin_url(), 697 return CreateFile(context, context->dest_origin_url(),
427 context->dest_type(), src_data_path, &dest_file_info, 0, 698 context->dest_type(), src_data_path, &dest_file_info, 0,
428 NULL); 699 NULL);
429 } 700 }
430 } else { // It's a move. 701 } else { // It's a move.
431 if (overwrite) { 702 if (overwrite) {
432 AllocateQuotaForPath(context, -1, 703 AllocateQuotaForPath(context, -1,
433 -static_cast<int64>(src_file_info.name.size())); 704 -static_cast<int64>(src_file_info.name.size()));
434 if (!db->OverwritingMoveFile(src_file_id, dest_file_id)) 705 if (!db->OverwritingMoveFile(src_file_id, dest_file_id))
435 return base::PLATFORM_FILE_ERROR_FAILED; 706 return base::PLATFORM_FILE_ERROR_FAILED;
436 FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(), 707 FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(),
437 context->src_type(), dest_file_info.data_path); 708 context->src_type(), dest_file_info.data_path);
438 if (base::PLATFORM_FILE_OK != 709 if (base::PLATFORM_FILE_OK !=
439 underlying_file_util_->DeleteFile(context, dest_data_path)) 710 underlying_file_util()->DeleteFile(context, dest_data_path))
440 LOG(WARNING) << "Leaked a backing file."; 711 LOG(WARNING) << "Leaked a backing file.";
441 UpdatePathQuotaUsage(context, context->src_origin_url(), 712 UpdatePathQuotaUsage(context, context->src_origin_url(),
442 context->src_type(), -1, 713 context->src_type(), -1,
443 -static_cast<int64>(src_file_info.name.size())); 714 -static_cast<int64>(src_file_info.name.size()));
444 return base::PLATFORM_FILE_OK; 715 return base::PLATFORM_FILE_OK;
445 } else { 716 } else {
446 FileId dest_parent_id; 717 FileId dest_parent_id;
447 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { 718 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) {
448 NOTREACHED(); 719 NOTREACHED();
449 return base::PLATFORM_FILE_ERROR_FAILED; 720 return base::PLATFORM_FILE_ERROR_FAILED;
(...skipping 11 matching lines...) Expand all
461 context, context->src_origin_url(), context->src_type(), 0, 732 context, context->src_origin_url(), context->src_type(), 0,
462 static_cast<int64>(dest_file_path.BaseName().value().size()) - 733 static_cast<int64>(dest_file_path.BaseName().value().size()) -
463 static_cast<int64>(src_file_path.BaseName().value().size())); 734 static_cast<int64>(src_file_path.BaseName().value().size()));
464 return base::PLATFORM_FILE_OK; 735 return base::PLATFORM_FILE_OK;
465 } 736 }
466 } 737 }
467 NOTREACHED(); 738 NOTREACHED();
468 return base::PLATFORM_FILE_ERROR_FAILED; 739 return base::PLATFORM_FILE_ERROR_FAILED;
469 } 740 }
470 741
471 PlatformFileError ObfuscatedFileSystemFileUtil::CopyInForeignFile( 742 PlatformFileError ObfuscatedFileUtil::CopyInForeignFile(
472 FileSystemOperationContext* context, 743 FileSystemOperationContext* context,
473 const FilePath& src_file_path, 744 const FilePath& src_file_path,
474 const FilePath& dest_file_path) { 745 const FilePath& dest_file_path) {
475 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 746 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
476 context->dest_origin_url(), context->dest_type(), true); 747 context->dest_origin_url(), context->dest_type(), true);
477 if (!db) 748 if (!db)
478 return base::PLATFORM_FILE_ERROR_FAILED; 749 return base::PLATFORM_FILE_ERROR_FAILED;
479 FileId dest_file_id; 750 FileId dest_file_id;
480 bool overwrite = db->GetFileWithPath(dest_file_path, &dest_file_id); 751 bool overwrite = db->GetFileWithPath(dest_file_path, &dest_file_id);
481 FileInfo dest_file_info; 752 FileInfo dest_file_info;
482 if (overwrite) { 753 if (overwrite) {
483 if (!db->GetFileInfo(dest_file_id, &dest_file_info) || 754 if (!db->GetFileInfo(dest_file_id, &dest_file_info) ||
484 dest_file_info.is_directory()) { 755 dest_file_info.is_directory()) {
485 NOTREACHED(); 756 NOTREACHED();
486 return base::PLATFORM_FILE_ERROR_FAILED; 757 return base::PLATFORM_FILE_ERROR_FAILED;
487 } 758 }
488 FilePath dest_data_path = DataPathToLocalPath(context->dest_origin_url(), 759 FilePath dest_data_path = DataPathToLocalPath(context->dest_origin_url(),
489 context->dest_type(), dest_file_info.data_path); 760 context->dest_type(), dest_file_info.data_path);
490 return underlying_file_util_->CopyOrMoveFile(context, 761 return underlying_file_util()->CopyOrMoveFile(context,
491 src_file_path, dest_data_path, true /* copy */); 762 src_file_path, dest_data_path, true /* copy */);
492 } else { 763 } else {
493 FileId dest_parent_id; 764 FileId dest_parent_id;
494 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { 765 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) {
495 NOTREACHED(); // We shouldn't be called in this case. 766 NOTREACHED(); // We shouldn't be called in this case.
496 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 767 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
497 } 768 }
498 InitFileInfo(&dest_file_info, dest_parent_id, 769 InitFileInfo(&dest_file_info, dest_parent_id,
499 dest_file_path.BaseName().value()); 770 dest_file_path.BaseName().value());
500 if (!AllocateQuotaForPath(context, 1, dest_file_info.name.size())) 771 if (!AllocateQuotaForPath(context, 1, dest_file_info.name.size()))
501 return base::PLATFORM_FILE_ERROR_NO_SPACE; 772 return base::PLATFORM_FILE_ERROR_NO_SPACE;
502 return CreateFile(context, context->dest_origin_url(), 773 return CreateFile(context, context->dest_origin_url(),
503 context->dest_type(), src_file_path, &dest_file_info, 0, NULL); 774 context->dest_type(), src_file_path, &dest_file_info, 0, NULL);
504 } 775 }
505 return base::PLATFORM_FILE_ERROR_FAILED; 776 return base::PLATFORM_FILE_ERROR_FAILED;
506 } 777 }
507 778
508 PlatformFileError ObfuscatedFileSystemFileUtil::DeleteFile( 779 PlatformFileError ObfuscatedFileUtil::DeleteFile(
509 FileSystemOperationContext* context, 780 FileSystemOperationContext* context,
510 const FilePath& virtual_path) { 781 const FilePath& virtual_path) {
511 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 782 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
512 context->src_origin_url(), context->src_type(), true); 783 context->src_origin_url(), context->src_type(), true);
513 if (!db) 784 if (!db)
514 return base::PLATFORM_FILE_ERROR_FAILED; 785 return base::PLATFORM_FILE_ERROR_FAILED;
515 FileId file_id; 786 FileId file_id;
516 if (!db->GetFileWithPath(virtual_path, &file_id)) 787 if (!db->GetFileWithPath(virtual_path, &file_id))
517 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 788 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
518 FileInfo file_info; 789 FileInfo file_info;
519 if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { 790 if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) {
520 NOTREACHED(); 791 NOTREACHED();
521 return base::PLATFORM_FILE_ERROR_FAILED; 792 return base::PLATFORM_FILE_ERROR_FAILED;
522 } 793 }
523 if (!db->RemoveFileInfo(file_id)) { 794 if (!db->RemoveFileInfo(file_id)) {
524 NOTREACHED(); 795 NOTREACHED();
525 return base::PLATFORM_FILE_ERROR_FAILED; 796 return base::PLATFORM_FILE_ERROR_FAILED;
526 } 797 }
527 AllocateQuotaForPath(context, -1, -static_cast<int64>(file_info.name.size())); 798 AllocateQuotaForPath(context, -1, -static_cast<int64>(file_info.name.size()));
528 UpdatePathQuotaUsage(context, context->src_origin_url(), context->src_type(), 799 UpdatePathQuotaUsage(context, context->src_origin_url(), context->src_type(),
529 -1, -static_cast<int64>(file_info.name.size())); 800 -1, -static_cast<int64>(file_info.name.size()));
530 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), 801 FilePath data_path = DataPathToLocalPath(context->src_origin_url(),
531 context->src_type(), file_info.data_path); 802 context->src_type(), file_info.data_path);
532 if (base::PLATFORM_FILE_OK != 803 if (base::PLATFORM_FILE_OK !=
533 underlying_file_util_->DeleteFile(context, data_path)) 804 underlying_file_util()->DeleteFile(context, data_path))
534 LOG(WARNING) << "Leaked a backing file."; 805 LOG(WARNING) << "Leaked a backing file.";
535 return base::PLATFORM_FILE_OK; 806 return base::PLATFORM_FILE_OK;
536 } 807 }
537 808
538 PlatformFileError ObfuscatedFileSystemFileUtil::DeleteSingleDirectory( 809 PlatformFileError ObfuscatedFileUtil::DeleteSingleDirectory(
539 FileSystemOperationContext* context, 810 FileSystemOperationContext* context,
540 const FilePath& virtual_path) { 811 const FilePath& virtual_path) {
541 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 812 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
542 context->src_origin_url(), context->src_type(), true); 813 context->src_origin_url(), context->src_type(), true);
543 if (!db) 814 if (!db)
544 return base::PLATFORM_FILE_ERROR_FAILED; 815 return base::PLATFORM_FILE_ERROR_FAILED;
545 FileId file_id; 816 FileId file_id;
546 if (!db->GetFileWithPath(virtual_path, &file_id)) 817 if (!db->GetFileWithPath(virtual_path, &file_id))
547 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 818 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
548 FileInfo file_info; 819 FileInfo file_info;
549 if (!db->GetFileInfo(file_id, &file_info) || !file_info.is_directory()) { 820 if (!db->GetFileInfo(file_id, &file_info) || !file_info.is_directory()) {
550 NOTREACHED(); 821 NOTREACHED();
551 return base::PLATFORM_FILE_ERROR_FAILED; 822 return base::PLATFORM_FILE_ERROR_FAILED;
552 } 823 }
553 if (!db->RemoveFileInfo(file_id)) 824 if (!db->RemoveFileInfo(file_id))
554 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; 825 return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
555 AllocateQuotaForPath(context, -1, -static_cast<int64>(file_info.name.size())); 826 AllocateQuotaForPath(context, -1, -static_cast<int64>(file_info.name.size()));
556 UpdatePathQuotaUsage(context, context->src_origin_url(), context->src_type(), 827 UpdatePathQuotaUsage(context, context->src_origin_url(), context->src_type(),
557 -1, -static_cast<int64>(file_info.name.size())); 828 -1, -static_cast<int64>(file_info.name.size()));
558 return base::PLATFORM_FILE_OK; 829 return base::PLATFORM_FILE_OK;
559 } 830 }
560 831
561 PlatformFileError ObfuscatedFileSystemFileUtil::Touch( 832 FilePath ObfuscatedFileUtil::GetDirectoryForOriginAndType(
562 FileSystemOperationContext* context,
563 const FilePath& virtual_path,
564 const base::Time& last_access_time,
565 const base::Time& last_modified_time) {
566 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
567 context->src_origin_url(), context->src_type(), false);
568 if (!db)
569 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
570 FileId file_id;
571 if (!db->GetFileWithPath(virtual_path, &file_id))
572 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
573
574 FileInfo file_info;
575 if (!db->GetFileInfo(file_id, &file_info)) {
576 NOTREACHED();
577 return base::PLATFORM_FILE_ERROR_FAILED;
578 }
579 if (file_info.is_directory()) {
580 file_info.modification_time = last_modified_time;
581 if (!db->UpdateFileInfo(file_id, file_info))
582 return base::PLATFORM_FILE_ERROR_FAILED;
583 return base::PLATFORM_FILE_OK;
584 }
585 FilePath data_path = DataPathToLocalPath(context->src_origin_url(),
586 context->src_type(), file_info.data_path);
587 return underlying_file_util_->Touch(
588 context, data_path, last_access_time, last_modified_time);
589 }
590
591 PlatformFileError ObfuscatedFileSystemFileUtil::Truncate(
592 FileSystemOperationContext* context,
593 const FilePath& virtual_path,
594 int64 length) {
595 FilePath local_path =
596 GetLocalPath(context->src_origin_url(), context->src_type(),
597 virtual_path);
598 if (local_path.empty())
599 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
600 return underlying_file_util_->Truncate(
601 context, local_path, length);
602 }
603
604 bool ObfuscatedFileSystemFileUtil::PathExists(
605 FileSystemOperationContext* context,
606 const FilePath& virtual_path) {
607 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
608 context->src_origin_url(), context->src_type(), false);
609 if (!db)
610 return false;
611 FileId file_id;
612 return db->GetFileWithPath(virtual_path, &file_id);
613 }
614
615 bool ObfuscatedFileSystemFileUtil::DirectoryExists(
616 FileSystemOperationContext* context,
617 const FilePath& virtual_path) {
618 if (IsRootDirectory(virtual_path)) {
619 // It's questionable whether we should return true or false for the
620 // root directory of nonexistent origin, but here we return true
621 // as the current implementation of ReadDirectory always returns an empty
622 // array (rather than erroring out with NOT_FOUND_ERR even) for
623 // nonexistent origins.
624 // Note: if you're going to change this behavior please also consider
625 // changiing the ReadDirectory's behavior!
626 return true;
627 }
628 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
629 context->src_origin_url(), context->src_type(), false);
630 if (!db)
631 return false;
632 FileId file_id;
633 if (!db->GetFileWithPath(virtual_path, &file_id))
634 return false;
635 FileInfo file_info;
636 if (!db->GetFileInfo(file_id, &file_info)) {
637 NOTREACHED();
638 return false;
639 }
640 return file_info.is_directory();
641 }
642
643 bool ObfuscatedFileSystemFileUtil::IsDirectoryEmpty(
644 FileSystemOperationContext* context,
645 const FilePath& virtual_path) {
646 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
647 context->src_origin_url(), context->src_type(), false);
648 if (!db)
649 return true; // Not a great answer, but it's what others do.
650 FileId file_id;
651 if (!db->GetFileWithPath(virtual_path, &file_id))
652 return true; // Ditto.
653 FileInfo file_info;
654 if (!db->GetFileInfo(file_id, &file_info)) {
655 DCHECK(!file_id);
656 // It's the root directory and the database hasn't been initialized yet.
657 return true;
658 }
659 if (!file_info.is_directory())
660 return true;
661 std::vector<FileId> children;
662 // TODO(ericu): This could easily be made faster with help from the database.
663 if (!db->ListChildren(file_id, &children))
664 return true;
665 return children.empty();
666 }
667
668 class ObfuscatedFileSystemFileEnumerator
669 : public FileSystemFileUtil::AbstractFileEnumerator {
670 public:
671 ObfuscatedFileSystemFileEnumerator(
672 const FilePath& base_path,
673 FileSystemDirectoryDatabase* db,
674 FileSystemOperationContext* context,
675 FileSystemFileUtil* underlying_file_util,
676 const FilePath& virtual_root_path)
677 : base_path_(base_path),
678 db_(db),
679 context_(context),
680 underlying_file_util_(underlying_file_util) {
681 DCHECK(db_);
682 DCHECK(context_);
683 DCHECK(underlying_file_util_);
684
685 FileId file_id;
686 FileInfo file_info;
687 if (!db_->GetFileWithPath(virtual_root_path, &file_id))
688 return;
689 if (!db_->GetFileInfo(file_id, &file_info))
690 return;
691 if (!file_info.is_directory())
692 return;
693 FileRecord record = { file_id, file_info, virtual_root_path };
694 display_queue_.push(record);
695 Next(); // Enumerators don't include the directory itself.
696 }
697
698 ~ObfuscatedFileSystemFileEnumerator() {}
699
700 virtual FilePath Next() OVERRIDE {
701 ProcessRecurseQueue();
702 if (display_queue_.empty())
703 return FilePath();
704 current_ = display_queue_.front();
705 display_queue_.pop();
706 if (current_.file_info.is_directory())
707 recurse_queue_.push(current_);
708 return current_.file_path;
709 }
710
711 virtual int64 Size() OVERRIDE {
712 if (IsDirectory())
713 return 0;
714
715 base::PlatformFileInfo file_info;
716 FilePath platform_file_path;
717
718 FilePath local_path = base_path_.Append(current_.file_info.data_path);
719 base::PlatformFileError error = underlying_file_util_->GetFileInfo(
720 context_, local_path, &file_info, &platform_file_path);
721 if (error != base::PLATFORM_FILE_OK) {
722 LOG(WARNING) << "Lost a backing file.";
723 return 0;
724 }
725 return file_info.size;
726 }
727
728 virtual bool IsDirectory() OVERRIDE {
729 return current_.file_info.is_directory();
730 }
731
732 private:
733 typedef FileSystemDirectoryDatabase::FileId FileId;
734 typedef FileSystemDirectoryDatabase::FileInfo FileInfo;
735
736 struct FileRecord {
737 FileId file_id;
738 FileInfo file_info;
739 FilePath file_path;
740 };
741
742 void ProcessRecurseQueue() {
743 while (display_queue_.empty() && !recurse_queue_.empty()) {
744 FileRecord directory = recurse_queue_.front();
745 std::vector<FileId> children;
746 recurse_queue_.pop();
747 if (!db_->ListChildren(directory.file_id, &children))
748 return;
749 std::vector<FileId>::iterator iter;
750 for (iter = children.begin(); iter != children.end(); ++iter) {
751 FileRecord child;
752 child.file_id = *iter;
753 if (!db_->GetFileInfo(child.file_id, &child.file_info))
754 return;
755 child.file_path = directory.file_path.Append(child.file_info.name);
756 display_queue_.push(child);
757 }
758 }
759 }
760
761 std::queue<FileRecord> display_queue_;
762 std::queue<FileRecord> recurse_queue_;
763 FileRecord current_;
764 FilePath base_path_;
765 FileSystemDirectoryDatabase* db_;
766 FileSystemOperationContext* context_;
767 FileSystemFileUtil* underlying_file_util_;
768 };
769
770 class ObfuscatedFileSystemOriginEnumerator
771 : public ObfuscatedFileSystemFileUtil::AbstractOriginEnumerator {
772 public:
773 typedef FileSystemOriginDatabase::OriginRecord OriginRecord;
774 ObfuscatedFileSystemOriginEnumerator(
775 FileSystemOriginDatabase* origin_database,
776 const FilePath& base_path)
777 : base_path_(base_path) {
778 if (origin_database)
779 origin_database->ListAllOrigins(&origins_);
780 }
781
782 ~ObfuscatedFileSystemOriginEnumerator() {}
783
784 // Returns the next origin. Returns empty if there are no more origins.
785 virtual GURL Next() OVERRIDE {
786 OriginRecord record;
787 if (!origins_.empty()) {
788 record = origins_.back();
789 origins_.pop_back();
790 }
791 current_ = record;
792 return GetOriginURLFromIdentifier(record.origin);
793 }
794
795 // Returns the current origin's information.
796 virtual bool HasFileSystemType(FileSystemType type) const OVERRIDE {
797 if (current_.path.empty())
798 return false;
799 FilePath::StringType type_string =
800 ObfuscatedFileSystemFileUtil::GetDirectoryNameForType(type);
801 if (type_string.empty()) {
802 NOTREACHED();
803 return false;
804 }
805 FilePath path = base_path_.Append(current_.path).Append(type_string);
806 return file_util::DirectoryExists(path);
807 }
808
809 private:
810 std::vector<OriginRecord> origins_;
811 OriginRecord current_;
812 FilePath base_path_;
813 };
814
815 ObfuscatedFileSystemFileUtil::AbstractOriginEnumerator*
816 ObfuscatedFileSystemFileUtil::CreateOriginEnumerator() {
817 std::vector<FileSystemOriginDatabase::OriginRecord> origins;
818
819 InitOriginDatabase(false);
820 return new ObfuscatedFileSystemOriginEnumerator(
821 origin_database_.get(), file_system_directory_);
822 }
823
824 FileSystemFileUtil::AbstractFileEnumerator*
825 ObfuscatedFileSystemFileUtil::CreateFileEnumerator(
826 FileSystemOperationContext* context,
827 const FilePath& root_path) {
828 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
829 context->src_origin_url(), context->src_type(), false);
830 if (!db)
831 return new FileSystemFileUtil::EmptyFileEnumerator();
832 return new ObfuscatedFileSystemFileEnumerator(
833 GetDirectoryForOriginAndType(context->src_origin_url(),
834 context->src_type(), false),
835 db,
836 context,
837 underlying_file_util_.get(),
838 root_path);
839 }
840
841 PlatformFileError ObfuscatedFileSystemFileUtil::GetFileInfoInternal(
842 FileSystemDirectoryDatabase* db,
843 FileSystemOperationContext* context,
844 FileId file_id,
845 FileInfo* local_info,
846 base::PlatformFileInfo* file_info,
847 FilePath* platform_file_path) {
848 DCHECK(db);
849 DCHECK(context);
850 DCHECK(file_info);
851 DCHECK(platform_file_path);
852
853 if (!db->GetFileInfo(file_id, local_info)) {
854 NOTREACHED();
855 return base::PLATFORM_FILE_ERROR_FAILED;
856 }
857
858 if (local_info->is_directory()) {
859 file_info->is_directory = true;
860 file_info->is_symbolic_link = false;
861 file_info->last_modified = local_info->modification_time;
862 *platform_file_path = FilePath();
863 // We don't fill in ctime or atime.
864 return base::PLATFORM_FILE_OK;
865 }
866 if (local_info->data_path.empty())
867 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
868 FilePath data_path = DataPathToLocalPath(context->src_origin_url(),
869 context->src_type(), local_info->data_path);
870 return underlying_file_util_->GetFileInfo(
871 context, data_path, file_info, platform_file_path);
872 }
873
874 PlatformFileError ObfuscatedFileSystemFileUtil::CreateFile(
875 FileSystemOperationContext* context,
876 const GURL& origin_url, FileSystemType type, const FilePath& source_path,
877 FileInfo* file_info, int file_flags, PlatformFile* handle) {
878 if (handle)
879 *handle = base::kInvalidPlatformFileValue;
880 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
881 origin_url, type, true);
882 int64 number;
883 if (!db || !db->GetNextInteger(&number))
884 return base::PLATFORM_FILE_ERROR_FAILED;
885 // We use the third- and fourth-to-last digits as the directory.
886 int64 directory_number = number % 10000 / 100;
887 // TODO(ericu): local_path is an OS path; underlying_file_util_ isn't
888 // guaranteed to understand OS paths.
889 FilePath local_path =
890 GetDirectoryForOriginAndType(origin_url, type, false);
891 if (local_path.empty())
892 return base::PLATFORM_FILE_ERROR_FAILED;
893
894 local_path = local_path.AppendASCII(StringPrintf("%02" PRIu64,
895 directory_number));
896 PlatformFileError error;
897 error = underlying_file_util_->CreateDirectory(
898 context, local_path, false /* exclusive */, false /* recursive */);
899 if (base::PLATFORM_FILE_OK != error)
900 return error;
901 local_path = local_path.AppendASCII(StringPrintf("%08" PRIu64, number));
902 FilePath data_path = LocalPathToDataPath(origin_url, type, local_path);
903 if (data_path.empty())
904 return base::PLATFORM_FILE_ERROR_FAILED;
905 bool created = false;
906 if (!source_path.empty()) {
907 DCHECK(!file_flags);
908 DCHECK(!handle);
909 error = underlying_file_util_->CopyOrMoveFile(
910 context, source_path, local_path, true /* copy */);
911 created = true;
912 } else {
913 FilePath path;
914 underlying_file_util_->GetLocalFilePath(context, local_path, &path);
915 if (file_util::PathExists(path)) {
916 if (!file_util::Delete(path, true)) {
917 NOTREACHED();
918 return base::PLATFORM_FILE_ERROR_FAILED;
919 }
920 LOG(WARNING) << "A stray file detected";
921 context->file_system_context()->GetQuotaUtil(context->src_type())->
922 InvalidateUsageCache(context->src_origin_url(), context->src_type());
923 }
924
925 if (handle) {
926 error = underlying_file_util_->CreateOrOpen(
927 context, local_path, file_flags, handle, &created);
928 // If this succeeds, we must close handle on any subsequent error.
929 } else {
930 DCHECK(!file_flags); // file_flags is only used by CreateOrOpen.
931 error = underlying_file_util_->EnsureFileExists(
932 context, local_path, &created);
933 }
934 }
935 if (error != base::PLATFORM_FILE_OK)
936 return error;
937
938 if (!created) {
939 NOTREACHED();
940 if (handle) {
941 DCHECK_NE(base::kInvalidPlatformFileValue, *handle);
942 base::ClosePlatformFile(*handle);
943 underlying_file_util_->DeleteFile(context, local_path);
944 }
945 return base::PLATFORM_FILE_ERROR_FAILED;
946 }
947 file_info->data_path = data_path;
948 FileId file_id;
949 if (!db->AddFileInfo(*file_info, &file_id)) {
950 if (handle) {
951 DCHECK_NE(base::kInvalidPlatformFileValue, *handle);
952 base::ClosePlatformFile(*handle);
953 }
954 underlying_file_util_->DeleteFile(context, local_path);
955 return base::PLATFORM_FILE_ERROR_FAILED;
956 }
957 UpdatePathQuotaUsage(context, origin_url, type, 1, file_info->name.size());
958
959 return base::PLATFORM_FILE_OK;
960 }
961
962 FilePath ObfuscatedFileSystemFileUtil::GetLocalPath(
963 const GURL& origin_url,
964 FileSystemType type,
965 const FilePath& virtual_path) {
966 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
967 origin_url, type, false);
968 if (!db)
969 return FilePath();
970 FileId file_id;
971 if (!db->GetFileWithPath(virtual_path, &file_id))
972 return FilePath();
973 FileInfo file_info;
974 if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) {
975 NOTREACHED();
976 return FilePath(); // Directories have no local path.
977 }
978 return DataPathToLocalPath(origin_url, type, file_info.data_path);
979 }
980
981 FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOriginAndType(
982 const GURL& origin, FileSystemType type, bool create) { 833 const GURL& origin, FileSystemType type, bool create) {
983 FilePath origin_dir = GetDirectoryForOrigin(origin, create); 834 FilePath origin_dir = GetDirectoryForOrigin(origin, create);
984 if (origin_dir.empty()) 835 if (origin_dir.empty())
985 return FilePath(); 836 return FilePath();
986 FilePath::StringType type_string = GetDirectoryNameForType(type); 837 FilePath::StringType type_string = GetDirectoryNameForType(type);
987 if (type_string.empty()) { 838 if (type_string.empty()) {
988 LOG(WARNING) << "Unknown filesystem type requested:" << type; 839 LOG(WARNING) << "Unknown filesystem type requested:" << type;
989 return FilePath(); 840 return FilePath();
990 } 841 }
991 FilePath path = origin_dir.Append(type_string); 842 FilePath path = origin_dir.Append(type_string);
992 if (!file_util::DirectoryExists(path) && 843 if (!file_util::DirectoryExists(path) &&
993 (!create || !file_util::CreateDirectory(path))) 844 (!create || !file_util::CreateDirectory(path)))
994 return FilePath(); 845 return FilePath();
995 return path; 846 return path;
996 } 847 }
997 848
998 bool ObfuscatedFileSystemFileUtil::DeleteDirectoryForOriginAndType( 849 bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType(
999 const GURL& origin, FileSystemType type) { 850 const GURL& origin, FileSystemType type) {
1000 FilePath origin_type_path = GetDirectoryForOriginAndType(origin, type, false); 851 FilePath origin_type_path = GetDirectoryForOriginAndType(origin, type, false);
1001 if (!file_util::PathExists(origin_type_path)) 852 if (!file_util::PathExists(origin_type_path))
1002 return true; 853 return true;
1003 854
1004 // TODO(dmikurube): Consider the return value of DestroyDirectoryDatabase. 855 // TODO(dmikurube): Consider the return value of DestroyDirectoryDatabase.
1005 // We ignore its error now since 1) it doesn't matter the final result, and 856 // We ignore its error now since 1) it doesn't matter the final result, and
1006 // 2) it always returns false in Windows because of LevelDB's implementation. 857 // 2) it always returns false in Windows because of LevelDB's implementation.
1007 // Information about failure would be useful for debugging. 858 // Information about failure would be useful for debugging.
1008 DestroyDirectoryDatabase(origin, type); 859 DestroyDirectoryDatabase(origin, type);
1009 if (!file_util::Delete(origin_type_path, true /* recursive */)) 860 if (!file_util::Delete(origin_type_path, true /* recursive */))
1010 return false; 861 return false;
1011 862
1012 FilePath origin_path = origin_type_path.DirName(); 863 FilePath origin_path = origin_type_path.DirName();
1013 DCHECK_EQ(origin_path.value(), GetDirectoryForOrigin(origin, false).value()); 864 DCHECK_EQ(origin_path.value(), GetDirectoryForOrigin(origin, false).value());
1014 865
1015 // Delete the origin directory if the deleted one was the last remaining 866 // Delete the origin directory if the deleted one was the last remaining
1016 // type for the origin. 867 // type for the origin.
1017 if (file_util::Delete(origin_path, false /* recursive */)) { 868 if (file_util::Delete(origin_path, false /* recursive */)) {
1018 InitOriginDatabase(false); 869 InitOriginDatabase(false);
1019 if (origin_database_.get()) 870 if (origin_database_.get())
1020 origin_database_->RemovePathForOrigin(GetOriginIdentifierFromURL(origin)); 871 origin_database_->RemovePathForOrigin(GetOriginIdentifierFromURL(origin));
1021 } 872 }
1022 873
1023 // At this point we are sure we had successfully deleted the origin/type 874 // At this point we are sure we had successfully deleted the origin/type
1024 // directory, so just returning true here. 875 // directory, so just returning true here.
1025 return true; 876 return true;
1026 } 877 }
1027 878
1028 bool ObfuscatedFileSystemFileUtil::MigrateFromOldSandbox( 879 bool ObfuscatedFileUtil::MigrateFromOldSandbox(
1029 const GURL& origin_url, FileSystemType type, const FilePath& src_root) { 880 const GURL& origin_url, FileSystemType type, const FilePath& src_root) {
1030 if (!DestroyDirectoryDatabase(origin_url, type)) 881 if (!DestroyDirectoryDatabase(origin_url, type))
1031 return false; 882 return false;
1032 FilePath dest_root = GetDirectoryForOriginAndType(origin_url, type, true); 883 FilePath dest_root = GetDirectoryForOriginAndType(origin_url, type, true);
1033 if (dest_root.empty()) 884 if (dest_root.empty())
1034 return false; 885 return false;
1035 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 886 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
1036 origin_url, type, true); 887 origin_url, type, true);
1037 if (!db) 888 if (!db)
1038 return false; 889 return false;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1090 LOG(WARNING) << 941 LOG(WARNING) <<
1091 "The final step of a migration failed; I'll try to clean up."; 942 "The final step of a migration failed; I'll try to clean up.";
1092 db = NULL; 943 db = NULL;
1093 DestroyDirectoryDatabase(origin_url, type); 944 DestroyDirectoryDatabase(origin_url, type);
1094 return false; 945 return false;
1095 } 946 }
1096 return true; 947 return true;
1097 } 948 }
1098 949
1099 // static 950 // static
1100 FilePath::StringType ObfuscatedFileSystemFileUtil::GetDirectoryNameForType( 951 FilePath::StringType ObfuscatedFileUtil::GetDirectoryNameForType(
1101 FileSystemType type) { 952 FileSystemType type) {
1102 switch (type) { 953 switch (type) {
1103 case kFileSystemTypeTemporary: 954 case kFileSystemTypeTemporary:
1104 return kTemporaryDirectoryName; 955 return kTemporaryDirectoryName;
1105 case kFileSystemTypePersistent: 956 case kFileSystemTypePersistent:
1106 return kPersistentDirectoryName; 957 return kPersistentDirectoryName;
1107 case kFileSystemTypeUnknown: 958 case kFileSystemTypeUnknown:
1108 default: 959 default:
1109 return FilePath::StringType(); 960 return FilePath::StringType();
1110 } 961 }
1111 } 962 }
1112 963
1113 FilePath ObfuscatedFileSystemFileUtil::DataPathToLocalPath( 964 ObfuscatedFileUtil::AbstractOriginEnumerator*
965 ObfuscatedFileUtil::CreateOriginEnumerator() {
966 std::vector<FileSystemOriginDatabase::OriginRecord> origins;
967
968 InitOriginDatabase(false);
969 return new ObfuscatedOriginEnumerator(
970 origin_database_.get(), file_system_directory_);
971 }
972
973 bool ObfuscatedFileUtil::DestroyDirectoryDatabase(
974 const GURL& origin, FileSystemType type) {
975 std::string type_string =
976 FileSystemPathManager::GetFileSystemTypeString(type);
977 if (type_string.empty()) {
978 LOG(WARNING) << "Unknown filesystem type requested:" << type;
979 return true;
980 }
981 std::string key = GetOriginIdentifierFromURL(origin) + type_string;
982 DirectoryMap::iterator iter = directories_.find(key);
983 if (iter != directories_.end()) {
984 FileSystemDirectoryDatabase* database = iter->second;
985 directories_.erase(iter);
986 delete database;
987 }
988
989 FilePath path = GetDirectoryForOriginAndType(origin, type, false);
990 if (path.empty())
991 return true;
992 if (!file_util::DirectoryExists(path))
993 return true;
994 path = path.AppendASCII(kDirectoryDatabaseName);
995 return FileSystemDirectoryDatabase::DestroyDatabase(path);
996 }
997
998 // static
999 int64 ObfuscatedFileUtil::ComputeFilePathCost(const FilePath& path) {
1000 return GetPathQuotaUsage(1, path.BaseName().value().size());
1001 }
1002
1003 PlatformFileError ObfuscatedFileUtil::GetFileInfoInternal(
1004 FileSystemDirectoryDatabase* db,
1005 FileSystemOperationContext* context,
1006 FileId file_id,
1007 FileInfo* local_info,
1008 base::PlatformFileInfo* file_info,
1009 FilePath* platform_file_path) {
1010 DCHECK(db);
1011 DCHECK(context);
1012 DCHECK(file_info);
1013 DCHECK(platform_file_path);
1014
1015 if (!db->GetFileInfo(file_id, local_info)) {
1016 NOTREACHED();
1017 return base::PLATFORM_FILE_ERROR_FAILED;
1018 }
1019
1020 if (local_info->is_directory()) {
1021 file_info->is_directory = true;
1022 file_info->is_symbolic_link = false;
1023 file_info->last_modified = local_info->modification_time;
1024 *platform_file_path = FilePath();
1025 // We don't fill in ctime or atime.
1026 return base::PLATFORM_FILE_OK;
1027 }
1028 if (local_info->data_path.empty())
1029 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
1030 FilePath data_path = DataPathToLocalPath(context->src_origin_url(),
1031 context->src_type(), local_info->data_path);
1032 return underlying_file_util()->GetFileInfo(
1033 context, data_path, file_info, platform_file_path);
1034 }
1035
1036 PlatformFileError ObfuscatedFileUtil::CreateFile(
1037 FileSystemOperationContext* context,
1038 const GURL& origin_url, FileSystemType type, const FilePath& source_path,
1039 FileInfo* file_info, int file_flags, PlatformFile* handle) {
1040 if (handle)
1041 *handle = base::kInvalidPlatformFileValue;
1042 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
1043 origin_url, type, true);
1044 int64 number;
1045 if (!db || !db->GetNextInteger(&number))
1046 return base::PLATFORM_FILE_ERROR_FAILED;
1047 // We use the third- and fourth-to-last digits as the directory.
1048 int64 directory_number = number % 10000 / 100;
1049 // TODO(ericu): local_path is an OS path; underlying_file_util_ isn't
1050 // guaranteed to understand OS paths.
1051 FilePath local_path =
1052 GetDirectoryForOriginAndType(origin_url, type, false);
1053 if (local_path.empty())
1054 return base::PLATFORM_FILE_ERROR_FAILED;
1055
1056 local_path = local_path.AppendASCII(StringPrintf("%02" PRIu64,
1057 directory_number));
1058 PlatformFileError error;
1059 error = underlying_file_util()->CreateDirectory(
1060 context, local_path, false /* exclusive */, false /* recursive */);
1061 if (base::PLATFORM_FILE_OK != error)
1062 return error;
1063 local_path = local_path.AppendASCII(StringPrintf("%08" PRIu64, number));
1064 FilePath data_path = LocalPathToDataPath(origin_url, type, local_path);
1065 if (data_path.empty())
1066 return base::PLATFORM_FILE_ERROR_FAILED;
1067 bool created = false;
1068 if (!source_path.empty()) {
1069 DCHECK(!file_flags);
1070 DCHECK(!handle);
1071 error = underlying_file_util()->CopyOrMoveFile(
1072 context, source_path, local_path, true /* copy */);
1073 created = true;
1074 } else {
1075 FilePath path;
1076 underlying_file_util()->GetLocalFilePath(context, local_path, &path);
1077 if (file_util::PathExists(path)) {
1078 if (!file_util::Delete(path, true)) {
1079 NOTREACHED();
1080 return base::PLATFORM_FILE_ERROR_FAILED;
1081 }
1082 LOG(WARNING) << "A stray file detected";
1083 context->file_system_context()->GetQuotaUtil(context->src_type())->
1084 InvalidateUsageCache(context->src_origin_url(), context->src_type());
1085 }
1086
1087 if (handle) {
1088 error = underlying_file_util()->CreateOrOpen(
1089 context, local_path, file_flags, handle, &created);
1090 // If this succeeds, we must close handle on any subsequent error.
1091 } else {
1092 DCHECK(!file_flags); // file_flags is only used by CreateOrOpen.
1093 error = underlying_file_util()->EnsureFileExists(
1094 context, local_path, &created);
1095 }
1096 }
1097 if (error != base::PLATFORM_FILE_OK)
1098 return error;
1099
1100 if (!created) {
1101 NOTREACHED();
1102 if (handle) {
1103 DCHECK_NE(base::kInvalidPlatformFileValue, *handle);
1104 base::ClosePlatformFile(*handle);
1105 underlying_file_util()->DeleteFile(context, local_path);
1106 }
1107 return base::PLATFORM_FILE_ERROR_FAILED;
1108 }
1109 file_info->data_path = data_path;
1110 FileId file_id;
1111 if (!db->AddFileInfo(*file_info, &file_id)) {
1112 if (handle) {
1113 DCHECK_NE(base::kInvalidPlatformFileValue, *handle);
1114 base::ClosePlatformFile(*handle);
1115 }
1116 underlying_file_util()->DeleteFile(context, local_path);
1117 return base::PLATFORM_FILE_ERROR_FAILED;
1118 }
1119 UpdatePathQuotaUsage(context, origin_url, type, 1, file_info->name.size());
1120
1121 return base::PLATFORM_FILE_OK;
1122 }
1123
1124 FilePath ObfuscatedFileUtil::GetLocalPath(
1125 const GURL& origin_url,
1126 FileSystemType type,
1127 const FilePath& virtual_path) {
1128 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
1129 origin_url, type, false);
1130 if (!db)
1131 return FilePath();
1132 FileId file_id;
1133 if (!db->GetFileWithPath(virtual_path, &file_id))
1134 return FilePath();
1135 FileInfo file_info;
1136 if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) {
1137 NOTREACHED();
1138 return FilePath(); // Directories have no local path.
1139 }
1140 return DataPathToLocalPath(origin_url, type, file_info.data_path);
1141 }
1142
1143 FilePath ObfuscatedFileUtil::DataPathToLocalPath(
1114 const GURL& origin, FileSystemType type, const FilePath& data_path) { 1144 const GURL& origin, FileSystemType type, const FilePath& data_path) {
1115 FilePath root = GetDirectoryForOriginAndType(origin, type, false); 1145 FilePath root = GetDirectoryForOriginAndType(origin, type, false);
1116 if (root.empty()) 1146 if (root.empty())
1117 return root; 1147 return root;
1118 return root.Append(data_path); 1148 return root.Append(data_path);
1119 } 1149 }
1120 1150
1121 FilePath ObfuscatedFileSystemFileUtil::LocalPathToDataPath( 1151 FilePath ObfuscatedFileUtil::LocalPathToDataPath(
1122 const GURL& origin, FileSystemType type, const FilePath& local_path) { 1152 const GURL& origin, FileSystemType type, const FilePath& local_path) {
1123 FilePath root = GetDirectoryForOriginAndType(origin, type, false); 1153 FilePath root = GetDirectoryForOriginAndType(origin, type, false);
1124 if (root.empty()) 1154 if (root.empty())
1125 return root; 1155 return root;
1126 // This removes the root, including the trailing slash, leaving a relative 1156 // This removes the root, including the trailing slash, leaving a relative
1127 // path. 1157 // path.
1128 return FilePath(local_path.value().substr(root.value().length() + 1)); 1158 return FilePath(local_path.value().substr(root.value().length() + 1));
1129 } 1159 }
1130 1160
1131 // TODO: How to do the whole validation-without-creation thing? We may not have 1161 // TODO: How to do the whole validation-without-creation thing? We may not have
1132 // quota even to create the database. Ah, in that case don't even get here? 1162 // quota even to create the database. Ah, in that case don't even get here?
1133 // Still doesn't answer the quota issue, though. 1163 // Still doesn't answer the quota issue, though.
1134 FileSystemDirectoryDatabase* ObfuscatedFileSystemFileUtil::GetDirectoryDatabase( 1164 FileSystemDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase(
1135 const GURL& origin, FileSystemType type, bool create) { 1165 const GURL& origin, FileSystemType type, bool create) {
1136 std::string type_string = 1166 std::string type_string =
1137 FileSystemPathManager::GetFileSystemTypeString(type); 1167 FileSystemPathManager::GetFileSystemTypeString(type);
1138 if (type_string.empty()) { 1168 if (type_string.empty()) {
1139 LOG(WARNING) << "Unknown filesystem type requested:" << type; 1169 LOG(WARNING) << "Unknown filesystem type requested:" << type;
1140 return NULL; 1170 return NULL;
1141 } 1171 }
1142 std::string key = GetOriginIdentifierFromURL(origin) + type_string; 1172 std::string key = GetOriginIdentifierFromURL(origin) + type_string;
1143 DirectoryMap::iterator iter = directories_.find(key); 1173 DirectoryMap::iterator iter = directories_.find(key);
1144 if (iter != directories_.end()) { 1174 if (iter != directories_.end()) {
(...skipping 10 matching lines...) Expand all
1155 return NULL; 1185 return NULL;
1156 } 1186 }
1157 } 1187 }
1158 MarkUsed(); 1188 MarkUsed();
1159 path = path.AppendASCII(kDirectoryDatabaseName); 1189 path = path.AppendASCII(kDirectoryDatabaseName);
1160 FileSystemDirectoryDatabase* database = new FileSystemDirectoryDatabase(path); 1190 FileSystemDirectoryDatabase* database = new FileSystemDirectoryDatabase(path);
1161 directories_[key] = database; 1191 directories_[key] = database;
1162 return database; 1192 return database;
1163 } 1193 }
1164 1194
1165 FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOrigin( 1195 FilePath ObfuscatedFileUtil::GetDirectoryForOrigin(
1166 const GURL& origin, bool create) { 1196 const GURL& origin, bool create) {
1167 if (!InitOriginDatabase(create)) 1197 if (!InitOriginDatabase(create))
1168 return FilePath(); 1198 return FilePath();
1169 FilePath directory_name; 1199 FilePath directory_name;
1170 std::string id = GetOriginIdentifierFromURL(origin); 1200 std::string id = GetOriginIdentifierFromURL(origin);
1171 1201
1172 bool exists_in_db = origin_database_->HasOriginPath(id); 1202 bool exists_in_db = origin_database_->HasOriginPath(id);
1173 if (!exists_in_db && !create) 1203 if (!exists_in_db && !create)
1174 return FilePath(); 1204 return FilePath();
1175 if (!origin_database_->GetPathForOrigin(id, &directory_name)) 1205 if (!origin_database_->GetPathForOrigin(id, &directory_name))
1176 return FilePath(); 1206 return FilePath();
1177 1207
1178 FilePath path = file_system_directory_.Append(directory_name); 1208 FilePath path = file_system_directory_.Append(directory_name);
1179 bool exists_in_fs = file_util::DirectoryExists(path); 1209 bool exists_in_fs = file_util::DirectoryExists(path);
1180 if (!exists_in_db && exists_in_fs) { 1210 if (!exists_in_db && exists_in_fs) {
1181 if (!file_util::Delete(path, true)) 1211 if (!file_util::Delete(path, true))
1182 return FilePath(); 1212 return FilePath();
1183 exists_in_fs = false; 1213 exists_in_fs = false;
1184 } 1214 }
1185 1215
1186 if (!exists_in_fs) { 1216 if (!exists_in_fs) {
1187 if (!create || !file_util::CreateDirectory(path)) 1217 if (!create || !file_util::CreateDirectory(path))
1188 return FilePath(); 1218 return FilePath();
1189 } 1219 }
1190 1220
1191 return path; 1221 return path;
1192 } 1222 }
1193 1223
1194 void ObfuscatedFileSystemFileUtil::MarkUsed() { 1224 void ObfuscatedFileUtil::MarkUsed() {
1195 if (timer_.IsRunning()) 1225 if (timer_.IsRunning())
1196 timer_.Reset(); 1226 timer_.Reset();
1197 else 1227 else
1198 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kFlushDelaySeconds), 1228 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kFlushDelaySeconds),
1199 this, &ObfuscatedFileSystemFileUtil::DropDatabases); 1229 this, &ObfuscatedFileUtil::DropDatabases);
1200 } 1230 }
1201 1231
1202 void ObfuscatedFileSystemFileUtil::DropDatabases() { 1232 void ObfuscatedFileUtil::DropDatabases() {
1203 origin_database_.reset(); 1233 origin_database_.reset();
1204 STLDeleteContainerPairSecondPointers( 1234 STLDeleteContainerPairSecondPointers(
1205 directories_.begin(), directories_.end()); 1235 directories_.begin(), directories_.end());
1206 directories_.clear(); 1236 directories_.clear();
1207 } 1237 }
1208 1238
1209 // static 1239 bool ObfuscatedFileUtil::InitOriginDatabase(bool create) {
1210 int64 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(const FilePath& path) {
1211 return GetPathQuotaUsage(1, path.BaseName().value().size());
1212 }
1213
1214 bool ObfuscatedFileSystemFileUtil::DestroyDirectoryDatabase(
1215 const GURL& origin, FileSystemType type) {
1216 std::string type_string =
1217 FileSystemPathManager::GetFileSystemTypeString(type);
1218 if (type_string.empty()) {
1219 LOG(WARNING) << "Unknown filesystem type requested:" << type;
1220 return true;
1221 }
1222 std::string key = GetOriginIdentifierFromURL(origin) + type_string;
1223 DirectoryMap::iterator iter = directories_.find(key);
1224 if (iter != directories_.end()) {
1225 FileSystemDirectoryDatabase* database = iter->second;
1226 directories_.erase(iter);
1227 delete database;
1228 }
1229
1230 FilePath path = GetDirectoryForOriginAndType(origin, type, false);
1231 if (path.empty())
1232 return true;
1233 if (!file_util::DirectoryExists(path))
1234 return true;
1235 path = path.AppendASCII(kDirectoryDatabaseName);
1236 return FileSystemDirectoryDatabase::DestroyDatabase(path);
1237 }
1238
1239 bool ObfuscatedFileSystemFileUtil::InitOriginDatabase(bool create) {
1240 if (!origin_database_.get()) { 1240 if (!origin_database_.get()) {
1241 if (!create && !file_util::DirectoryExists(file_system_directory_)) 1241 if (!create && !file_util::DirectoryExists(file_system_directory_))
1242 return false; 1242 return false;
1243 if (!file_util::CreateDirectory(file_system_directory_)) { 1243 if (!file_util::CreateDirectory(file_system_directory_)) {
1244 LOG(WARNING) << "Failed to create FileSystem directory: " << 1244 LOG(WARNING) << "Failed to create FileSystem directory: " <<
1245 file_system_directory_.value(); 1245 file_system_directory_.value();
1246 return false; 1246 return false;
1247 } 1247 }
1248 origin_database_.reset( 1248 origin_database_.reset(
1249 new FileSystemOriginDatabase( 1249 new FileSystemOriginDatabase(
1250 file_system_directory_.AppendASCII(kOriginDatabaseName))); 1250 file_system_directory_.AppendASCII(kOriginDatabaseName)));
1251 } 1251 }
1252 return true; 1252 return true;
1253 } 1253 }
1254 1254
1255 } // namespace fileapi 1255 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/obfuscated_file_util.h ('k') | webkit/fileapi/obfuscated_file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698