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/drive/drive_resource_metadata.h" | 5 #include "chrome/browser/chromeos/drive/drive_resource_metadata.h" |
6 | 6 |
7 #include <leveldb/db.h> | 7 #include <leveldb/db.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 scoped_ptr<google_apis::DocumentEntry> doc_entry, | 239 scoped_ptr<google_apis::DocumentEntry> doc_entry, |
240 const FileMoveCallback& callback) { | 240 const FileMoveCallback& callback) { |
241 DCHECK(!directory_path.empty()); | 241 DCHECK(!directory_path.empty()); |
242 DCHECK(!callback.is_null()); | 242 DCHECK(!callback.is_null()); |
243 | 243 |
244 if (!doc_entry.get()) { | 244 if (!doc_entry.get()) { |
245 PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_FAILED); | 245 PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_FAILED); |
246 return; | 246 return; |
247 } | 247 } |
248 | 248 |
249 scoped_ptr<DriveEntry> new_entry = CreateDriveEntryFromProto( | |
250 ConvertDocumentEntryToDriveEntryProto(*doc_entry)); | |
251 if (!new_entry.get()) { | |
252 PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_FAILED); | |
253 return; | |
254 } | |
255 | |
256 DriveEntry* dir_entry = FindEntryByPathSync(directory_path); | 249 DriveEntry* dir_entry = FindEntryByPathSync(directory_path); |
257 if (!dir_entry) { | 250 if (!dir_entry) { |
258 PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_NOT_FOUND); | 251 PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_NOT_FOUND); |
259 return; | 252 return; |
260 } | 253 } |
261 | 254 |
262 DriveDirectory* directory = dir_entry->AsDriveDirectory(); | 255 DriveDirectory* directory = dir_entry->AsDriveDirectory(); |
263 if (!directory) { | 256 if (!directory) { |
264 PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_NOT_A_DIRECTORY); | 257 PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_NOT_A_DIRECTORY); |
265 return; | 258 return; |
266 } | 259 } |
267 | 260 |
268 DriveEntry* added_entry = new_entry.release(); | 261 AddEntryToDirectoryInternal( |
269 directory->AddEntry(added_entry); // Transfers ownership. | 262 directory, |
270 DVLOG(1) << "AddEntryToDirectory " << added_entry->GetFilePath().value(); | 263 ConvertDocumentEntryToDriveEntryProto(*doc_entry), |
271 base::MessageLoopProxy::current()->PostTask(FROM_HERE, | 264 callback); |
272 base::Bind(callback, DRIVE_FILE_OK, added_entry->GetFilePath())); | |
273 } | 265 } |
274 | 266 |
275 void DriveResourceMetadata::MoveEntryToDirectory( | 267 void DriveResourceMetadata::MoveEntryToDirectory( |
276 const FilePath& file_path, | 268 const FilePath& file_path, |
277 const FilePath& directory_path, | 269 const FilePath& directory_path, |
278 const FileMoveCallback& callback) { | 270 const FileMoveCallback& callback) { |
279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
280 DCHECK(!directory_path.empty()); | 272 DCHECK(!directory_path.empty()); |
281 DCHECK(!file_path.empty()); | 273 DCHECK(!file_path.empty()); |
282 DCHECK(!callback.is_null()); | 274 DCHECK(!callback.is_null()); |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 const GetEntryInfoWithFilePathCallback& callback) { | 503 const GetEntryInfoWithFilePathCallback& callback) { |
512 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
513 DCHECK(!callback.is_null()); | 505 DCHECK(!callback.is_null()); |
514 | 506 |
515 if (!doc_entry.get()) { | 507 if (!doc_entry.get()) { |
516 PostGetEntryInfoWithFilePathCallbackError( | 508 PostGetEntryInfoWithFilePathCallbackError( |
517 callback, DRIVE_FILE_ERROR_FAILED); | 509 callback, DRIVE_FILE_ERROR_FAILED); |
518 return; | 510 return; |
519 } | 511 } |
520 | 512 |
521 scoped_ptr<DriveEntry> drive_entry = CreateDriveEntryFromProto( | 513 RefreshEntryProto(ConvertDocumentEntryToDriveEntryProto( |
522 ConvertDocumentEntryToDriveEntryProto(*doc_entry)); | 514 *doc_entry), callback); |
| 515 } |
| 516 |
| 517 void DriveResourceMetadata::RefreshEntryProto( |
| 518 const DriveEntryProto& entry_proto, |
| 519 const GetEntryInfoWithFilePathCallback& callback) { |
| 520 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 521 DCHECK(!callback.is_null()); |
| 522 |
| 523 scoped_ptr<DriveEntry> drive_entry = CreateDriveEntryFromProto(entry_proto); |
523 if (!drive_entry.get()) { | 524 if (!drive_entry.get()) { |
524 PostGetEntryInfoWithFilePathCallbackError( | 525 PostGetEntryInfoWithFilePathCallbackError( |
525 callback, DRIVE_FILE_ERROR_FAILED); | 526 callback, DRIVE_FILE_ERROR_FAILED); |
526 return; | 527 return; |
527 } | 528 } |
528 | 529 |
529 if (!drive_entry->AsDriveFile()) { | 530 DriveEntry* old_entry = GetEntryByResourceId(drive_entry->resource_id()); |
530 // This is a directory, return the directory info instead. | 531 DriveDirectory* old_parent = old_entry ? old_entry->parent() : NULL; |
531 GetEntryInfoByResourceId(drive_entry->resource_id(), callback); | 532 DriveDirectory* new_parent = GetParent(entry_proto.parent_resource_id()); |
532 return; | 533 if (!old_parent || !new_parent) { |
533 } | 534 PostGetEntryInfoWithFilePathCallbackError(callback, |
534 scoped_ptr<DriveFile> fresh_file(drive_entry.release()->AsDriveFile()); | 535 DRIVE_FILE_ERROR_NOT_FOUND); |
535 | |
536 // Need to get a reference here because Passed() could get evaluated first. | |
537 const std::string& resource_id = fresh_file->resource_id(); | |
538 DVLOG(1) << "RefreshFile " << resource_id; | |
539 DriveEntry* old_entry = GetEntryByResourceId(resource_id); | |
540 DriveDirectory* entry_parent = old_entry ? old_entry->parent() : NULL; | |
541 | |
542 if (!entry_parent) { | |
543 PostGetEntryInfoWithFilePathCallbackError( | |
544 callback, DRIVE_FILE_ERROR_NOT_FOUND); | |
545 return; | 536 return; |
546 } | 537 } |
547 | 538 |
548 DCHECK_EQ(fresh_file->resource_id(), old_entry->resource_id()); | 539 // Move children over to the new directory from the existing directory. |
549 DCHECK(old_entry->AsDriveFile()); | 540 if (drive_entry->AsDriveDirectory() && old_entry->AsDriveDirectory()) { |
| 541 drive_entry->AsDriveDirectory()->TakeOverEntries( |
| 542 old_entry->AsDriveDirectory()); |
| 543 } |
550 | 544 |
551 entry_parent->RemoveEntry(old_entry); | 545 // Remove from the old parent and add to the new parent. |
552 DriveEntry* new_entry = fresh_file.release(); | 546 old_parent->RemoveEntry(old_entry); |
553 entry_parent->AddEntry(new_entry); | 547 DriveEntry* new_entry = drive_entry.release(); |
| 548 new_parent->AddEntry(new_entry); // Transfers ownership. |
554 | 549 |
555 scoped_ptr<DriveEntryProto> entry_proto(new DriveEntryProto); | 550 DVLOG(1) << "RefreshEntryProto " << new_entry->GetFilePath().value(); |
556 new_entry->ToProtoFull(entry_proto.get()); | 551 // Note that base_name is not the same for new_entry and entry_proto. |
| 552 scoped_ptr<DriveEntryProto> new_entry_proto(new DriveEntryProto); |
| 553 new_entry->ToProtoFull(new_entry_proto.get()); |
557 base::MessageLoopProxy::current()->PostTask( | 554 base::MessageLoopProxy::current()->PostTask( |
558 FROM_HERE, | 555 FROM_HERE, |
559 base::Bind(callback, | 556 base::Bind(callback, |
560 DRIVE_FILE_OK, | 557 DRIVE_FILE_OK, |
561 new_entry->GetFilePath(), | 558 new_entry->GetFilePath(), |
562 base::Passed(&entry_proto))); | 559 base::Passed(&new_entry_proto))); |
563 } | 560 } |
564 | 561 |
565 void DriveResourceMetadata::RefreshDirectory( | 562 void DriveResourceMetadata::RefreshDirectory( |
566 const std::string& directory_resource_id, | 563 const std::string& directory_resource_id, |
567 const DriveEntryProtoMap& entry_proto_map, | 564 const DriveEntryProtoMap& entry_proto_map, |
568 const FileMoveCallback& callback) { | 565 const FileMoveCallback& callback) { |
569 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 566 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
570 DCHECK(!callback.is_null()); | 567 DCHECK(!callback.is_null()); |
571 | 568 |
572 DriveEntry* directory_entry = GetEntryByResourceId(directory_resource_id); | 569 DriveEntry* directory_entry = GetEntryByResourceId(directory_resource_id); |
(...skipping 17 matching lines...) Expand all Loading... |
590 // Only refresh files. | 587 // Only refresh files. |
591 if (!entry_proto.file_info().is_directory()) | 588 if (!entry_proto.file_info().is_directory()) |
592 directory->AddEntry(CreateDriveEntryFromProto(entry_proto).release()); | 589 directory->AddEntry(CreateDriveEntryFromProto(entry_proto).release()); |
593 } | 590 } |
594 | 591 |
595 base::MessageLoopProxy::current()->PostTask( | 592 base::MessageLoopProxy::current()->PostTask( |
596 FROM_HERE, | 593 FROM_HERE, |
597 base::Bind(callback, DRIVE_FILE_OK, directory->GetFilePath())); | 594 base::Bind(callback, DRIVE_FILE_OK, directory->GetFilePath())); |
598 } | 595 } |
599 | 596 |
| 597 void DriveResourceMetadata::AddEntryToParent( |
| 598 const DriveEntryProto& entry_proto, |
| 599 const FileMoveCallback& callback) { |
| 600 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 601 DCHECK(!callback.is_null()); |
| 602 |
| 603 DriveDirectory* parent = GetParent(entry_proto.parent_resource_id()); |
| 604 if (!parent) { |
| 605 PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_NOT_FOUND); |
| 606 return; |
| 607 } |
| 608 AddEntryToDirectoryInternal(parent, entry_proto, callback); |
| 609 } |
| 610 |
| 611 void DriveResourceMetadata::AddEntryToDirectoryInternal( |
| 612 DriveDirectory* directory, |
| 613 const DriveEntryProto& entry_proto, |
| 614 const FileMoveCallback& callback) { |
| 615 scoped_ptr<DriveEntry> new_entry = CreateDriveEntryFromProto(entry_proto); |
| 616 if (!new_entry.get()) { |
| 617 PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_FAILED); |
| 618 return; |
| 619 } |
| 620 |
| 621 DriveEntry* added_entry = new_entry.release(); |
| 622 directory->AddEntry(added_entry); // Transfers ownership. |
| 623 DVLOG(1) << "AddEntryToDirectoryInternal" |
| 624 << added_entry->GetFilePath().value(); |
| 625 base::MessageLoopProxy::current()->PostTask(FROM_HERE, |
| 626 base::Bind(callback, DRIVE_FILE_OK, added_entry->GetFilePath())); |
| 627 } |
| 628 |
| 629 DriveDirectory* DriveResourceMetadata::GetParent( |
| 630 const std::string& parent_resource_id) { |
| 631 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 632 |
| 633 if (parent_resource_id.empty()) |
| 634 return root(); |
| 635 |
| 636 DriveEntry* entry = GetEntryByResourceId(parent_resource_id); |
| 637 return entry ? entry->AsDriveDirectory() : NULL; |
| 638 } |
| 639 |
| 640 void DriveResourceMetadata::GetChildDirectories( |
| 641 const std::string& resource_id, |
| 642 const GetChildDirectoriesCallback& changed_dirs_callback) { |
| 643 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 644 DCHECK(!changed_dirs_callback.is_null()); |
| 645 |
| 646 std::set<FilePath> changed_directories; |
| 647 DriveEntry* entry = GetEntryByResourceId(resource_id); |
| 648 if (entry && entry->AsDriveDirectory()) |
| 649 entry->AsDriveDirectory()->GetChildDirectoryPaths(&changed_directories); |
| 650 |
| 651 base::MessageLoopProxy::current()->PostTask( |
| 652 FROM_HERE, |
| 653 base::Bind(changed_dirs_callback, changed_directories)); |
| 654 } |
| 655 |
600 void DriveResourceMetadata::TakeOverEntries( | 656 void DriveResourceMetadata::TakeOverEntries( |
601 const std::string& source_resource_id, | 657 const std::string& source_resource_id, |
602 const std::string& destination_resource_id, | 658 const std::string& destination_resource_id, |
603 const FileMoveCallback& callback) { | 659 const FileMoveCallback& callback) { |
604 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 660 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
605 DCHECK(!callback.is_null()); | 661 DCHECK(!callback.is_null()); |
606 | 662 |
607 DriveEntry* source_entry = GetEntryByResourceId(source_resource_id); | 663 DriveEntry* source_entry = GetEntryByResourceId(source_resource_id); |
608 DriveEntry* destination_entry = GetEntryByResourceId(destination_resource_id); | 664 DriveEntry* destination_entry = GetEntryByResourceId(destination_resource_id); |
609 if (!source_entry || !destination_entry) { | 665 if (!source_entry || !destination_entry) { |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 | 883 |
828 loaded_ = true; | 884 loaded_ = true; |
829 largest_changestamp_ = proto.largest_changestamp(); | 885 largest_changestamp_ = proto.largest_changestamp(); |
830 | 886 |
831 return true; | 887 return true; |
832 } | 888 } |
833 | 889 |
834 scoped_ptr<DriveEntry> DriveResourceMetadata::CreateDriveEntryFromProto( | 890 scoped_ptr<DriveEntry> DriveResourceMetadata::CreateDriveEntryFromProto( |
835 const DriveEntryProto& entry_proto) { | 891 const DriveEntryProto& entry_proto) { |
836 scoped_ptr<DriveEntry> entry; | 892 scoped_ptr<DriveEntry> entry; |
| 893 // TODO(achuith): This method never fails. Add basic sanity checks for |
| 894 // resource_id, etc. |
837 if (entry_proto.file_info().is_directory()) { | 895 if (entry_proto.file_info().is_directory()) { |
838 entry = CreateDriveDirectory().Pass(); | 896 entry = CreateDriveDirectory().Pass(); |
839 // Call DriveEntry::FromProto instead of DriveDirectory::FromProto because | 897 // Call DriveEntry::FromProto instead of DriveDirectory::FromProto because |
840 // the proto does not include children. | 898 // the proto does not include children. |
841 entry->FromProto(entry_proto); | 899 entry->FromProto(entry_proto); |
842 } else { | 900 } else { |
843 scoped_ptr<DriveFile> file(CreateDriveFile()); | 901 scoped_ptr<DriveFile> file(CreateDriveFile()); |
844 // Call DriveFile::FromProto. | 902 // Call DriveFile::FromProto. |
845 file->FromProto(entry_proto); | 903 file->FromProto(entry_proto); |
846 entry.reset(file.release()); | 904 entry.reset(file.release()); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 DCHECK(result.get()); | 956 DCHECK(result.get()); |
899 | 957 |
900 result->second.path = second_path; | 958 result->second.path = second_path; |
901 result->second.error = error; | 959 result->second.error = error; |
902 result->second.proto = entry_proto.Pass(); | 960 result->second.proto = entry_proto.Pass(); |
903 | 961 |
904 callback.Run(result.Pass()); | 962 callback.Run(result.Pass()); |
905 } | 963 } |
906 | 964 |
907 } // namespace drive | 965 } // namespace drive |
OLD | NEW |