OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/gdata/gdata_files.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_files.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
| 9 #include "base/message_loop_proxy.h" |
9 #include "base/platform_file.h" | 10 #include "base/platform_file.h" |
10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
11 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 13 #include "base/tracked_objects.h" |
12 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/chromeos/gdata/gdata.pb.h" | 15 #include "chrome/browser/chromeos/gdata/gdata.pb.h" |
14 #include "chrome/browser/chromeos/gdata/gdata_util.h" | 16 #include "chrome/browser/chromeos/gdata/gdata_util.h" |
15 #include "chrome/browser/chromeos/gdata/gdata_wapi_parser.h" | 17 #include "chrome/browser/chromeos/gdata/gdata_wapi_parser.h" |
16 #include "net/base/escape.h" | 18 #include "net/base/escape.h" |
17 | 19 |
18 namespace gdata { | 20 namespace gdata { |
19 namespace { | 21 namespace { |
20 | 22 |
21 const char kSlash[] = "/"; | 23 const char kSlash[] = "/"; |
22 const char kEscapedSlash[] = "\xE2\x88\x95"; | 24 const char kEscapedSlash[] = "\xE2\x88\x95"; |
23 | 25 |
24 // Extracts resource_id out of edit url. | 26 // Extracts resource_id out of edit url. |
25 std::string ExtractResourceId(const GURL& url) { | 27 std::string ExtractResourceId(const GURL& url) { |
26 return net::UnescapeURLComponent(url.ExtractFileName(), | 28 return net::UnescapeURLComponent(url.ExtractFileName(), |
27 net::UnescapeRule::URL_SPECIAL_CHARS); | 29 net::UnescapeRule::URL_SPECIAL_CHARS); |
28 } | 30 } |
29 | 31 |
30 // Replaces file entry |old_entry| with its fresh value |fresh_file|. | |
31 void RefreshFileInternal(scoped_ptr<GDataFile> fresh_file, | |
32 GDataEntry* old_entry) { | |
33 GDataDirectory* entry_parent = old_entry ? old_entry->parent() : NULL; | |
34 if (entry_parent) { | |
35 DCHECK_EQ(fresh_file->resource_id(), old_entry->resource_id()); | |
36 DCHECK(old_entry->AsGDataFile()); | |
37 | |
38 entry_parent->RemoveEntry(old_entry); | |
39 entry_parent->AddEntry(fresh_file.release()); | |
40 } | |
41 } | |
42 | |
43 // Returns true if |proto| is a valid proto as the root directory. | 32 // Returns true if |proto| is a valid proto as the root directory. |
44 // Used to reject incompatible proto. | 33 // Used to reject incompatible proto. |
45 bool IsValidRootDirectoryProto(const GDataDirectoryProto& proto) { | 34 bool IsValidRootDirectoryProto(const GDataDirectoryProto& proto) { |
46 const GDataEntryProto& entry_proto = proto.gdata_entry(); | 35 const GDataEntryProto& entry_proto = proto.gdata_entry(); |
47 // The title field for the root directory was originally empty, then | 36 // The title field for the root directory was originally empty, then |
48 // changed to "gdata", then changed to "drive". Discard the proto data if | 37 // changed to "gdata", then changed to "drive". Discard the proto data if |
49 // the older formats are detected. See crbug.com/128133 for details. | 38 // the older formats are detected. See crbug.com/128133 for details. |
50 if (entry_proto.title() != "drive") { | 39 if (entry_proto.title() != "drive") { |
51 LOG(ERROR) << "Incompatible proto detected (bad title): " | 40 LOG(ERROR) << "Incompatible proto detected (bad title): " |
52 << entry_proto.title(); | 41 << entry_proto.title(); |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 | 438 |
450 GDataDirectoryService::~GDataDirectoryService() { | 439 GDataDirectoryService::~GDataDirectoryService() { |
451 // Note that children have a reference to root_, | 440 // Note that children have a reference to root_, |
452 // so we need to delete them here. | 441 // so we need to delete them here. |
453 root_->RemoveChildren(); | 442 root_->RemoveChildren(); |
454 RemoveEntryFromResourceMap(root_.get()); | 443 RemoveEntryFromResourceMap(root_.get()); |
455 DCHECK(resource_map_.empty()); | 444 DCHECK(resource_map_.empty()); |
456 resource_map_.clear(); | 445 resource_map_.clear(); |
457 } | 446 } |
458 | 447 |
| 448 void GDataDirectoryService::AddEntryAt(const FilePath& path, |
| 449 GDataEntry* entry, |
| 450 const FileOperationCallback& callback) { |
| 451 GDataEntry* destination = FindEntryByPathSync(path); |
| 452 GDataFileError error = GDATA_FILE_ERROR_FAILED; |
| 453 if (!destination) { |
| 454 error = GDATA_FILE_ERROR_NOT_FOUND; |
| 455 } else if (!destination->AsGDataDirectory()) { |
| 456 error = GDATA_FILE_ERROR_NOT_A_DIRECTORY; |
| 457 } else { |
| 458 destination->AsGDataDirectory()->AddEntry(entry); |
| 459 error = GDATA_FILE_OK; |
| 460 } |
| 461 if (!callback.is_null()) { |
| 462 base::MessageLoopProxy::current()->PostTask( |
| 463 FROM_HERE, base::Bind(callback, error)); |
| 464 } |
| 465 } |
| 466 |
459 void GDataDirectoryService::AddEntryToResourceMap(GDataEntry* entry) { | 467 void GDataDirectoryService::AddEntryToResourceMap(GDataEntry* entry) { |
460 // GDataFileSystem has already locked. | 468 // GDataFileSystem has already locked. |
461 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id(); | 469 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id(); |
462 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); | 470 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); |
463 } | 471 } |
464 | 472 |
465 void GDataDirectoryService::RemoveEntryFromResourceMap(GDataEntry* entry) { | 473 void GDataDirectoryService::RemoveEntryFromResourceMap(GDataEntry* entry) { |
466 // GDataFileSystem has already locked. | 474 // GDataFileSystem has already locked. |
467 resource_map_.erase(entry->resource_id()); | 475 resource_map_.erase(entry->resource_id()); |
468 } | 476 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 const GetEntryByResourceIdCallback& callback) { | 526 const GetEntryByResourceIdCallback& callback) { |
519 GDataEntry* entry = GetEntryByResourceId(resource_id); | 527 GDataEntry* entry = GetEntryByResourceId(resource_id); |
520 callback.Run(entry); | 528 callback.Run(entry); |
521 } | 529 } |
522 | 530 |
523 void GDataDirectoryService::RefreshFile(scoped_ptr<GDataFile> fresh_file) { | 531 void GDataDirectoryService::RefreshFile(scoped_ptr<GDataFile> fresh_file) { |
524 DCHECK(fresh_file.get()); | 532 DCHECK(fresh_file.get()); |
525 | 533 |
526 // Need to get a reference here because Passed() could get evaluated first. | 534 // Need to get a reference here because Passed() could get evaluated first. |
527 const std::string& resource_id = fresh_file->resource_id(); | 535 const std::string& resource_id = fresh_file->resource_id(); |
528 GetEntryByResourceIdAsync(resource_id, | 536 GetEntryByResourceIdAsync( |
529 base::Bind(&RefreshFileInternal, base::Passed(&fresh_file))); | 537 resource_id, |
| 538 base::Bind(&GDataDirectoryService::RefreshFileInternal, |
| 539 base::Passed(&fresh_file))); |
| 540 } |
| 541 |
| 542 // static |
| 543 void GDataDirectoryService::RefreshFileInternal( |
| 544 scoped_ptr<GDataFile> fresh_file, |
| 545 GDataEntry* old_entry) { |
| 546 GDataDirectory* entry_parent = old_entry ? old_entry->parent() : NULL; |
| 547 if (entry_parent) { |
| 548 DCHECK_EQ(fresh_file->resource_id(), old_entry->resource_id()); |
| 549 DCHECK(old_entry->AsGDataFile()); |
| 550 |
| 551 entry_parent->RemoveEntry(old_entry); |
| 552 entry_parent->AddEntry(fresh_file.release()); |
| 553 } |
530 } | 554 } |
531 | 555 |
532 // Convert to/from proto. | 556 // Convert to/from proto. |
533 | 557 |
534 // static | 558 // static |
535 void GDataEntry::ConvertProtoToPlatformFileInfo( | 559 void GDataEntry::ConvertProtoToPlatformFileInfo( |
536 const PlatformFileInfoProto& proto, | 560 const PlatformFileInfoProto& proto, |
537 base::PlatformFileInfo* file_info) { | 561 base::PlatformFileInfo* file_info) { |
538 file_info->size = proto.size(); | 562 file_info->size = proto.size(); |
539 file_info->is_directory = proto.is_directory(); | 563 file_info->is_directory = proto.is_directory(); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 if (!root_->FromProto(proto.gdata_directory())) | 781 if (!root_->FromProto(proto.gdata_directory())) |
758 return false; | 782 return false; |
759 | 783 |
760 origin_ = FROM_CACHE; | 784 origin_ = FROM_CACHE; |
761 largest_changestamp_ = proto.largest_changestamp(); | 785 largest_changestamp_ = proto.largest_changestamp(); |
762 | 786 |
763 return true; | 787 return true; |
764 } | 788 } |
765 | 789 |
766 } // namespace gdata | 790 } // namespace gdata |
OLD | NEW |