| 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 <leveldb/db.h> | 7 #include <leveldb/db.h> |
| 8 #include <vector> | |
| 9 | 8 |
| 10 #include "base/message_loop_proxy.h" | 9 #include "base/message_loop_proxy.h" |
| 11 #include "base/platform_file.h" | 10 #include "base/platform_file.h" |
| 12 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
| 13 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 14 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 15 #include "base/sequenced_task_runner.h" | 14 #include "base/sequenced_task_runner.h" |
| 16 #include "base/tracked_objects.h" | 15 #include "base/tracked_objects.h" |
| 17 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 18 #include "chrome/browser/chromeos/gdata/gdata.pb.h" | 17 #include "chrome/browser/chromeos/gdata/gdata.pb.h" |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 | 246 |
| 248 void GDataDirectory::InitFromDocumentEntry(DocumentEntry* doc) { | 247 void GDataDirectory::InitFromDocumentEntry(DocumentEntry* doc) { |
| 249 GDataEntry::InitFromDocumentEntry(doc); | 248 GDataEntry::InitFromDocumentEntry(doc); |
| 250 | 249 |
| 251 const Link* upload_link = doc->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA); | 250 const Link* upload_link = doc->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA); |
| 252 if (upload_link) | 251 if (upload_link) |
| 253 upload_url_ = upload_link->href(); | 252 upload_url_ = upload_link->href(); |
| 254 } | 253 } |
| 255 | 254 |
| 256 void GDataDirectory::AddEntry(GDataEntry* entry) { | 255 void GDataDirectory::AddEntry(GDataEntry* entry) { |
| 256 DCHECK(!entry->parent()); |
| 257 |
| 257 // The entry name may have been changed due to prior name de-duplication. | 258 // The entry name may have been changed due to prior name de-duplication. |
| 258 // We need to first restore the file name based on the title before going | 259 // We need to first restore the file name based on the title before going |
| 259 // through name de-duplication again when it is added to another directory. | 260 // through name de-duplication again when it is added to another directory. |
| 260 entry->SetBaseNameFromTitle(); | 261 entry->SetBaseNameFromTitle(); |
| 261 | 262 |
| 262 // Do file name de-duplication - find files with the same name and | 263 // Do file name de-duplication - find files with the same name and |
| 263 // append a name modifier to the name. | 264 // append a name modifier to the name. |
| 264 int max_modifier = 1; | 265 int max_modifier = 1; |
| 265 FilePath full_file_name(entry->base_name()); | 266 FilePath full_file_name(entry->base_name()); |
| 266 const std::string extension = full_file_name.Extension(); | 267 const std::string extension = full_file_name.Extension(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 289 directory_service_->AddEntryToResourceMap(entry); | 290 directory_service_->AddEntryToResourceMap(entry); |
| 290 | 291 |
| 291 // Setup child and parent links. | 292 // Setup child and parent links. |
| 292 AddChild(entry); | 293 AddChild(entry); |
| 293 entry->SetParent(this); | 294 entry->SetParent(this); |
| 294 } | 295 } |
| 295 | 296 |
| 296 bool GDataDirectory::TakeOverEntries(GDataDirectory* dir) { | 297 bool GDataDirectory::TakeOverEntries(GDataDirectory* dir) { |
| 297 for (GDataFileCollection::iterator iter = dir->child_files_.begin(); | 298 for (GDataFileCollection::iterator iter = dir->child_files_.begin(); |
| 298 iter != dir->child_files_.end(); ++iter) { | 299 iter != dir->child_files_.end(); ++iter) { |
| 299 AddEntry(iter->second); | 300 GDataEntry* entry = iter->second; |
| 301 entry->SetParent(NULL); |
| 302 AddEntry(entry); |
| 300 } | 303 } |
| 301 dir->child_files_.clear(); | 304 dir->child_files_.clear(); |
| 302 | 305 |
| 303 for (GDataDirectoryCollection::iterator iter = | 306 for (GDataDirectoryCollection::iterator iter = |
| 304 dir->child_directories_.begin(); | 307 dir->child_directories_.begin(); |
| 305 iter != dir->child_directories_.end(); ++iter) { | 308 iter != dir->child_directories_.end(); ++iter) { |
| 306 AddEntry(iter->second); | 309 GDataEntry* entry = iter->second; |
| 310 entry->SetParent(NULL); |
| 311 AddEntry(entry); |
| 307 } | 312 } |
| 308 dir->child_directories_.clear(); | 313 dir->child_directories_.clear(); |
| 309 return true; | 314 return true; |
| 310 } | 315 } |
| 311 | 316 |
| 312 void GDataDirectory::RemoveEntry(GDataEntry* entry) { | 317 void GDataDirectory::RemoveEntry(GDataEntry* entry) { |
| 313 DCHECK(entry); | 318 DCHECK(entry); |
| 314 | 319 |
| 315 RemoveChild(entry); | 320 RemoveChild(entry); |
| 316 delete entry; | 321 delete entry; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 const std::string& base_name(entry->base_name()); | 353 const std::string& base_name(entry->base_name()); |
| 349 // entry must be present in this directory. | 354 // entry must be present in this directory. |
| 350 DCHECK_EQ(entry, FindChild(base_name)); | 355 DCHECK_EQ(entry, FindChild(base_name)); |
| 351 // Remove entry from resource map first. | 356 // Remove entry from resource map first. |
| 352 if (directory_service_) | 357 if (directory_service_) |
| 353 directory_service_->RemoveEntryFromResourceMap(entry); | 358 directory_service_->RemoveEntryFromResourceMap(entry); |
| 354 | 359 |
| 355 // Then delete it from tree. | 360 // Then delete it from tree. |
| 356 child_files_.erase(base_name); | 361 child_files_.erase(base_name); |
| 357 child_directories_.erase(base_name); | 362 child_directories_.erase(base_name); |
| 363 |
| 364 entry->SetParent(NULL); |
| 358 } | 365 } |
| 359 | 366 |
| 360 void GDataDirectory::RemoveChildren() { | 367 void GDataDirectory::RemoveChildren() { |
| 361 RemoveChildFiles(); | 368 RemoveChildFiles(); |
| 362 RemoveChildDirectories(); | 369 RemoveChildDirectories(); |
| 363 } | 370 } |
| 364 | 371 |
| 365 void GDataDirectory::RemoveChildFiles() { | 372 void GDataDirectory::RemoveChildFiles() { |
| 366 for (GDataFileCollection::const_iterator iter = child_files_.begin(); | 373 for (GDataFileCollection::const_iterator iter = child_files_.begin(); |
| 367 iter != child_files_.end(); ++iter) { | 374 iter != child_files_.end(); ++iter) { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 void GDataDirectoryService::ClearRoot() { | 563 void GDataDirectoryService::ClearRoot() { |
| 557 // Note that children have a reference to root_, | 564 // Note that children have a reference to root_, |
| 558 // so we need to delete them here. | 565 // so we need to delete them here. |
| 559 root_->RemoveChildren(); | 566 root_->RemoveChildren(); |
| 560 RemoveEntryFromResourceMap(root_.get()); | 567 RemoveEntryFromResourceMap(root_.get()); |
| 561 DCHECK(resource_map_.empty()); | 568 DCHECK(resource_map_.empty()); |
| 562 resource_map_.clear(); | 569 resource_map_.clear(); |
| 563 root_.reset(); | 570 root_.reset(); |
| 564 } | 571 } |
| 565 | 572 |
| 573 void GDataDirectoryService::AddEntryToDirectory( |
| 574 GDataDirectory* directory, |
| 575 GDataEntry* new_entry, |
| 576 const FileMoveCallback& callback) { |
| 577 DCHECK(directory); |
| 578 DCHECK(new_entry); |
| 579 DCHECK(!callback.is_null()); |
| 580 |
| 581 directory->AddEntry(new_entry); |
| 582 DVLOG(1) << "AddEntryToDirectory " << new_entry->GetFilePath().value(); |
| 583 base::MessageLoopProxy::current()->PostTask(FROM_HERE, |
| 584 base::Bind(callback, GDATA_FILE_OK, new_entry->GetFilePath())); |
| 585 } |
| 586 |
| 566 void GDataDirectoryService::MoveEntryToDirectory( | 587 void GDataDirectoryService::MoveEntryToDirectory( |
| 567 const FilePath& directory_path, | 588 const FilePath& directory_path, |
| 568 GDataEntry* entry, | 589 GDataEntry* entry, |
| 569 const FileMoveCallback& callback) { | 590 const FileMoveCallback& callback) { |
| 570 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 591 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 571 DCHECK(entry); | 592 DCHECK(entry); |
| 572 | 593 |
| 573 if (entry->parent()) | 594 if (entry->parent()) |
| 574 entry->parent()->RemoveChild(entry); | 595 entry->parent()->RemoveChild(entry); |
| 575 | 596 |
| 576 GDataEntry* destination = FindEntryByPathSync(directory_path); | 597 GDataEntry* destination = FindEntryByPathSync(directory_path); |
| 577 FilePath moved_file_path; | 598 FilePath moved_file_path; |
| 578 GDataFileError error = GDATA_FILE_ERROR_FAILED; | 599 GDataFileError error = GDATA_FILE_ERROR_FAILED; |
| 579 if (!destination) { | 600 if (!destination) { |
| 580 error = GDATA_FILE_ERROR_NOT_FOUND; | 601 error = GDATA_FILE_ERROR_NOT_FOUND; |
| 581 } else if (!destination->AsGDataDirectory()) { | 602 } else if (!destination->AsGDataDirectory()) { |
| 582 error = GDATA_FILE_ERROR_NOT_A_DIRECTORY; | 603 error = GDATA_FILE_ERROR_NOT_A_DIRECTORY; |
| 583 } else { | 604 } else { |
| 584 destination->AsGDataDirectory()->AddEntry(entry); | 605 destination->AsGDataDirectory()->AddEntry(entry); |
| 585 moved_file_path = entry->GetFilePath(); | 606 moved_file_path = entry->GetFilePath(); |
| 586 error = GDATA_FILE_OK; | 607 error = GDATA_FILE_OK; |
| 587 } | 608 } |
| 609 DVLOG(1) << "MoveEntryToDirectory " << moved_file_path.value(); |
| 588 if (!callback.is_null()) { | 610 if (!callback.is_null()) { |
| 589 base::MessageLoopProxy::current()->PostTask( | 611 base::MessageLoopProxy::current()->PostTask( |
| 590 FROM_HERE, base::Bind(callback, error, moved_file_path)); | 612 FROM_HERE, base::Bind(callback, error, moved_file_path)); |
| 591 } | 613 } |
| 592 } | 614 } |
| 593 | 615 |
| 616 void GDataDirectoryService::RemoveEntryFromParent( |
| 617 GDataEntry* entry, |
| 618 const FileMoveCallback& callback) { |
| 619 GDataDirectory* parent = entry->parent(); |
| 620 DCHECK(parent); |
| 621 DVLOG(1) << "RemoveEntryFromParent " << entry->GetFilePath().value(); |
| 622 |
| 623 parent->RemoveEntry(entry); |
| 624 if (!callback.is_null()) { |
| 625 base::MessageLoopProxy::current()->PostTask(FROM_HERE, |
| 626 base::Bind(callback, GDATA_FILE_OK, parent->GetFilePath())); |
| 627 } |
| 628 } |
| 629 |
| 594 void GDataDirectoryService::AddEntryToResourceMap(GDataEntry* entry) { | 630 void GDataDirectoryService::AddEntryToResourceMap(GDataEntry* entry) { |
| 595 // GDataFileSystem has already locked. | 631 // GDataFileSystem has already locked. |
| 596 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id(); | 632 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id(); |
| 597 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); | 633 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); |
| 598 } | 634 } |
| 599 | 635 |
| 600 void GDataDirectoryService::RemoveEntryFromResourceMap(GDataEntry* entry) { | 636 void GDataDirectoryService::RemoveEntryFromResourceMap(GDataEntry* entry) { |
| 601 // GDataFileSystem has already locked. | 637 // GDataFileSystem has already locked. |
| 602 resource_map_.erase(entry->resource_id()); | 638 resource_map_.erase(entry->resource_id()); |
| 603 } | 639 } |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 GDataDirectory* entry_parent = old_entry ? old_entry->parent() : NULL; | 763 GDataDirectory* entry_parent = old_entry ? old_entry->parent() : NULL; |
| 728 if (entry_parent) { | 764 if (entry_parent) { |
| 729 DCHECK_EQ(fresh_file->resource_id(), old_entry->resource_id()); | 765 DCHECK_EQ(fresh_file->resource_id(), old_entry->resource_id()); |
| 730 DCHECK(old_entry->AsGDataFile()); | 766 DCHECK(old_entry->AsGDataFile()); |
| 731 | 767 |
| 732 entry_parent->RemoveEntry(old_entry); | 768 entry_parent->RemoveEntry(old_entry); |
| 733 entry_parent->AddEntry(fresh_file.release()); | 769 entry_parent->AddEntry(fresh_file.release()); |
| 734 } | 770 } |
| 735 } | 771 } |
| 736 | 772 |
| 773 void GDataDirectoryService::RefreshDirectory( |
| 774 const std::string& directory_resource_id, |
| 775 const ResourceMap& file_map, |
| 776 const FileMoveCallback& callback) { |
| 777 DCHECK(!callback.is_null()); |
| 778 GetEntryByResourceIdAsync( |
| 779 directory_resource_id, |
| 780 base::Bind(&GDataDirectoryService::RefreshDirectoryInternal, |
| 781 file_map, |
| 782 callback)); |
| 783 } |
| 784 |
| 785 // static |
| 786 void GDataDirectoryService::RefreshDirectoryInternal( |
| 787 const ResourceMap& file_map, |
| 788 const FileMoveCallback& callback, |
| 789 GDataEntry* directory_entry) { |
| 790 DCHECK(!callback.is_null()); |
| 791 |
| 792 if (!directory_entry || !directory_entry->AsGDataDirectory()) { |
| 793 LOG(ERROR) << "RefreshDirectoryInternal: Failed to find directory"; |
| 794 return; |
| 795 } |
| 796 |
| 797 GDataDirectory* directory = directory_entry->AsGDataDirectory(); |
| 798 |
| 799 directory->RemoveChildFiles(); |
| 800 // Add files from file_map. |
| 801 for (ResourceMap::const_iterator it = file_map.begin(); |
| 802 it != file_map.end(); ++it) { |
| 803 scoped_ptr<GDataEntry> entry(it->second); |
| 804 // Skip if it's not a file (i.e. directory). |
| 805 if (!entry->AsGDataFile()) |
| 806 continue; |
| 807 directory->AddEntry(entry.release()); |
| 808 } |
| 809 |
| 810 callback.Run(GDATA_FILE_OK, directory->GetFilePath()); |
| 811 } |
| 812 |
| 737 void GDataDirectoryService::InitFromDB( | 813 void GDataDirectoryService::InitFromDB( |
| 738 const FilePath& db_path, | 814 const FilePath& db_path, |
| 739 base::SequencedTaskRunner* blocking_task_runner, | 815 base::SequencedTaskRunner* blocking_task_runner, |
| 740 const FileOperationCallback& callback) { | 816 const FileOperationCallback& callback) { |
| 741 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 742 DCHECK(!db_path.empty()); | 818 DCHECK(!db_path.empty()); |
| 743 DCHECK(blocking_task_runner); | 819 DCHECK(blocking_task_runner); |
| 744 | 820 |
| 745 if (directory_service_db_.get()) { | 821 if (directory_service_db_.get()) { |
| 746 if (!callback.is_null()) | 822 if (!callback.is_null()) |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1195 DCHECK(result.get()); | 1271 DCHECK(result.get()); |
| 1196 | 1272 |
| 1197 result->second.path = second_path; | 1273 result->second.path = second_path; |
| 1198 result->second.error = error; | 1274 result->second.error = error; |
| 1199 result->second.proto = entry_proto.Pass(); | 1275 result->second.proto = entry_proto.Pass(); |
| 1200 | 1276 |
| 1201 callback.Run(result.Pass()); | 1277 callback.Run(result.Pass()); |
| 1202 } | 1278 } |
| 1203 | 1279 |
| 1204 } // namespace gdata | 1280 } // namespace gdata |
| OLD | NEW |