| 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 |